예제 #1
0
파일: ram_store.c 프로젝트: Bira/ferret
static void ram_close_i(Store *store)
{
    Hash *ht = store->dir.ht;
    int i;
    for (i = 0; i <= ht->mask; i++) {
        RAMFile *rf = (RAMFile *)ht->table[i].value;
        if (rf) {
            DEREF(rf);
        }
    }
    h_destroy(store->dir.ht);
    store_destroy(store);
}
예제 #2
0
static void cmpd_close_i(Store *store)
{
    CompoundStore *cmpd = store->dir.cmpd;
    if (cmpd->stream == NULL) {
        RAISE(IO_ERROR, "Tried to close already closed compound store");
    }

    h_destroy(cmpd->entries);

    is_close(cmpd->stream);
    cmpd->stream = NULL;
    free(store->dir.cmpd);
    store_destroy(store);
}
예제 #3
0
Store *open_cmpd_store(Store *store, const char *name)
{
    int count, i;
    off_t offset;
    char *fname;
    FileEntry *entry = NULL;
    Store *new_store = NULL;
    CompoundStore *volatile cmpd = NULL;
    InStream *volatile is = NULL;

    TRY
        cmpd = ALLOC_AND_ZERO(CompoundStore);

        cmpd->store       = store;
        cmpd->name        = name;
        cmpd->entries     = h_new_str(&free, &free);
        is = cmpd->stream = store->open_input(store, cmpd->name);

        /* read the directory and init files */
        count = is_read_vint(is);
        entry = NULL;
        for (i = 0; i < count; i++) {
            offset = (off_t)is_read_i64(is);
            fname = is_read_string(is);

            if (entry != NULL) {
                /* set length of the previous entry */
                entry->length = offset - entry->offset;
            }

            entry = ALLOC(FileEntry);
            entry->offset = offset;
            h_set(cmpd->entries, fname, entry);
        }
    XCATCHALL
        if (is) is_close(is);
        if (cmpd->entries) h_destroy(cmpd->entries);
        free(cmpd);
    XENDTRY

    /* set the length of the final entry */
    if (entry != NULL) {
        entry->length = is_length(is) - entry->offset;
    }

    new_store               = store_new();
    new_store->dir.cmpd     = cmpd;
    new_store->touch        = &cmpd_touch;
    new_store->exists       = &cmpd_exists;
    new_store->remove       = &cmpd_remove;
    new_store->rename       = &cmpd_rename;
    new_store->count        = &cmpd_count;
    new_store->clear        = &cmpd_clear;
    new_store->length       = &cmpd_length;
    new_store->each         = &cmpd_each;
    new_store->close_i      = &cmpd_close_i;
    new_store->new_output   = &cmpd_new_output;
    new_store->open_input   = &cmpd_open_input;
    new_store->open_lock_i  = &cmpd_open_lock_i;
    new_store->close_lock_i = &cmpd_close_lock_i;

    return new_store;
}