Exemple #1
0
bool_t
RAMFolder_hard_link(RAMFolder *self, const CharBuf *from, const CharBuf *to)
{
    Folder        *from_folder = RAMFolder_Enclosing_Folder(self, from);
    Folder        *to_folder   = RAMFolder_Enclosing_Folder(self, to);
    ZombieCharBuf *from_name   = IxFileNames_local_part(from, ZCB_BLANK());
    ZombieCharBuf *to_name     = IxFileNames_local_part(to, ZCB_BLANK());
    bool_t         result      = S_rename_or_hard_link(self, from, to, 
        from_folder, to_folder, from_name, to_name, OP_HARD_LINK);
    if (!result) { ERR_ADD_FRAME(Err_get_error()); }
    return result;
}
Exemple #2
0
void
Folder_consolidate(Folder *self, const CharBuf *path) {
    Folder *folder = Folder_Find_Folder(self, path);
    Folder *enclosing_folder = Folder_Enclosing_Folder(self, path);
    if (!folder) {
        THROW(ERR, "Can't consolidate %o", path);
    }
    else if (Folder_Is_A(folder, COMPOUNDFILEREADER)) {
        THROW(ERR, "Can't consolidate %o twice", path);
    }
    else {
        CompoundFileWriter *cf_writer = CFWriter_new(folder);
        CFWriter_Consolidate(cf_writer);
        DECREF(cf_writer);
        if (CB_Get_Size(path)) {
            ZombieCharBuf *name = IxFileNames_local_part(path, ZCB_BLANK());
            CompoundFileReader *cf_reader = CFReader_open(folder);
            if (!cf_reader) {
                RETHROW(INCREF(Err_get_error()));
            }
            Hash_Store(enclosing_folder->entries, (Obj*)name,
                       (Obj*)cf_reader);
        }
    }
}
static void
S_test_local_part(TestBatchRunner *runner, const char *source,
                  const char *wanted, const char *test_name) {
    StackString *source_str = SSTR_WRAP_UTF8(source, strlen(source));
    String *got = IxFileNames_local_part((String*)source_str);
    TEST_TRUE(runner, Str_Equals_Utf8(got, wanted, strlen(wanted)), test_name);
    DECREF(got);
}
Exemple #4
0
bool
Folder_is_directory(Folder *self, const CharBuf *path) {
    Folder *enclosing_folder = Folder_Enclosing_Folder(self, path);
    bool retval = false;
    if (enclosing_folder) {
        ZombieCharBuf *name = IxFileNames_local_part(path, ZCB_BLANK());
        if (Folder_Local_Is_Directory(enclosing_folder, (CharBuf*)name)) {
            retval = true;
        }
    }
    return retval;
}
Exemple #5
0
bool
Folder_delete(Folder *self, const CharBuf *path) {
    Folder *enclosing_folder = Folder_Enclosing_Folder(self, path);
    if (enclosing_folder) {
        ZombieCharBuf *name = IxFileNames_local_part(path, ZCB_BLANK());
        bool result = Folder_Local_Delete(enclosing_folder, (CharBuf*)name);
        return result;
    }
    else {
        return false;
    }
}
Exemple #6
0
bool_t
Folder_exists(Folder *self, const CharBuf *path) {
    Folder *enclosing_folder = Folder_Enclosing_Folder(self, path);
    bool_t retval = false;
    if (enclosing_folder) {
        ZombieCharBuf *name = IxFileNames_local_part(path, ZCB_BLANK());
        if (Folder_Local_Exists(enclosing_folder, (CharBuf*)name)) {
            retval = true;
        }
    }
    return retval;
}
Exemple #7
0
bool_t
Folder_delete_tree(Folder *self, const CharBuf *path) {
    Folder *enclosing_folder = Folder_Enclosing_Folder(self, path);

    // Don't allow Folder to delete itself.
    if (!path || !CB_Get_Size(path)) {
        return false;
    }

    if (enclosing_folder) {
        ZombieCharBuf *local = IxFileNames_local_part(path, ZCB_BLANK());
        if (Folder_Local_Is_Directory(enclosing_folder, (CharBuf*)local)) {
            Folder *inner_folder
                = Folder_Local_Find_Folder(enclosing_folder, (CharBuf*)local);
            DirHandle *dh = Folder_Local_Open_Dir(inner_folder);
            if (dh) {
                VArray *files = VA_new(20);
                VArray *dirs  = VA_new(20);
                CharBuf *entry = DH_Get_Entry(dh);
                while (DH_Next(dh)) {
                    VA_Push(files, (Obj*)CB_Clone(entry));
                    if (DH_Entry_Is_Dir(dh) && !DH_Entry_Is_Symlink(dh)) {
                        VA_Push(dirs, (Obj*)CB_Clone(entry));
                    }
                }
                for (uint32_t i = 0, max = VA_Get_Size(dirs); i < max; i++) {
                    CharBuf *name = (CharBuf*)VA_Fetch(files, i);
                    bool_t success = Folder_Delete_Tree(inner_folder, name);
                    if (!success && Folder_Local_Exists(inner_folder, name)) {
                        break;
                    }
                }
                for (uint32_t i = 0, max = VA_Get_Size(files); i < max; i++) {
                    CharBuf *name = (CharBuf*)VA_Fetch(files, i);
                    bool_t success = Folder_Local_Delete(inner_folder, name);
                    if (!success && Folder_Local_Exists(inner_folder, name)) {
                        break;
                    }
                }
                DECREF(dirs);
                DECREF(files);
                DECREF(dh);
            }
        }
        return Folder_Local_Delete(enclosing_folder, (CharBuf*)local);
    }
    else {
        // Return failure if the entry wasn't there in the first place.
        return false;
    }
}
Exemple #8
0
InStream*
Folder_open_in(Folder *self, const CharBuf *path) {
    Folder *enclosing_folder = Folder_Enclosing_Folder(self, path);
    InStream *instream = NULL;

    if (enclosing_folder) {
        ZombieCharBuf *name = IxFileNames_local_part(path, ZCB_BLANK());
        instream = Folder_Local_Open_In(enclosing_folder, (CharBuf*)name);
        if (!instream) {
            ERR_ADD_FRAME(Err_get_error());
        }
    }
    else {
        Err_set_error(Err_new(CB_newf("Invalid path: '%o'", path)));
    }

    return instream;
}
Exemple #9
0
FileHandle*
Folder_open_filehandle(Folder *self, const CharBuf *path, uint32_t flags) {
    Folder *enclosing_folder = Folder_Enclosing_Folder(self, path);
    FileHandle *fh = NULL;

    if (enclosing_folder) {
        ZombieCharBuf *name = IxFileNames_local_part(path, ZCB_BLANK());
        fh = Folder_Local_Open_FileHandle(enclosing_folder,
                                          (CharBuf*)name, flags);
        if (!fh) {
            ERR_ADD_FRAME(Err_get_error());
        }
    }
    else {
        Err_set_error(Err_new(CB_newf("Invalid path: '%o'", path)));
    }

    return fh;
}
Exemple #10
0
bool
Folder_mkdir(Folder *self, const CharBuf *path) {
    Folder *enclosing_folder = Folder_Enclosing_Folder(self, path);
    bool result = false;

    if (!CB_Get_Size(path)) {
        Err_set_error(Err_new(CB_newf("Invalid path: '%o'", path)));
    }
    else if (!enclosing_folder) {
        Err_set_error(Err_new(CB_newf("Can't recursively create dir %o",
                                      path)));
    }
    else {
        ZombieCharBuf *name = IxFileNames_local_part(path, ZCB_BLANK());
        result = Folder_Local_MkDir(enclosing_folder, (CharBuf*)name);
        if (!result) {
            ERR_ADD_FRAME(Err_get_error());
        }
    }

    return result;
}
Exemple #11
0
CompoundFileReader*
CFReader_do_open(CompoundFileReader *self, Folder *folder) {
    CompoundFileReaderIVARS *const ivars = CFReader_IVARS(self);
    String *cfmeta_file = (String*)SSTR_WRAP_UTF8("cfmeta.json", 11);
    Hash *metadata = (Hash*)Json_slurp_json((Folder*)folder, cfmeta_file);
    Err *error = NULL;

    Folder_init((Folder*)self, Folder_Get_Path(folder));

    // Parse metadata file.
    if (!metadata || !Hash_Is_A(metadata, HASH)) {
        error = Err_new(Str_newf("Can't read '%o' in '%o'", cfmeta_file,
                                 Folder_Get_Path(folder)));
    }
    else {
        Obj *format = Hash_Fetch_Utf8(metadata, "format", 6);
        ivars->format = format ? (int32_t)Obj_To_I64(format) : 0;
        ivars->records = (Hash*)INCREF(Hash_Fetch_Utf8(metadata, "files", 5));
        if (ivars->format < 1) {
            error = Err_new(Str_newf("Corrupt %o file: Missing or invalid 'format'",
                                     cfmeta_file));
        }
        else if (ivars->format > CFWriter_current_file_format) {
            error = Err_new(Str_newf("Unsupported compound file format: %i32 "
                                     "(current = %i32", ivars->format,
                                     CFWriter_current_file_format));
        }
        else if (!ivars->records) {
            error = Err_new(Str_newf("Corrupt %o file: missing 'files' key",
                                     cfmeta_file));
        }
    }
    DECREF(metadata);
    if (error) {
        Err_set_error(error);
        DECREF(self);
        return NULL;
    }

    // Open an instream which we'll clone over and over.
    String *cf_file = (String*)SSTR_WRAP_UTF8("cf.dat", 6);
    ivars->instream = Folder_Open_In(folder, cf_file);
    if (!ivars->instream) {
        ERR_ADD_FRAME(Err_get_error());
        DECREF(self);
        return NULL;
    }

    // Assign.
    ivars->real_folder = (Folder*)INCREF(folder);

    // Strip directory name from filepaths for old format.
    if (ivars->format == 1) {
        Vector *files = Hash_Keys(ivars->records);
        String *folder_name = IxFileNames_local_part(Folder_Get_Path(folder));
        size_t folder_name_len = Str_Length(folder_name);

        for (uint32_t i = 0, max = Vec_Get_Size(files); i < max; i++) {
            String *orig = (String*)Vec_Fetch(files, i);
            if (Str_Starts_With(orig, folder_name)) {
                Obj *record = Hash_Delete(ivars->records, orig);
                size_t offset = folder_name_len + sizeof(CHY_DIR_SEP) - 1;
                size_t len    = Str_Length(orig) - offset;
                String *filename = Str_SubString(orig, offset, len);
                Hash_Store(ivars->records, filename, (Obj*)record);
                DECREF(filename);
            }
        }

        DECREF(folder_name);
        DECREF(files);
    }

    return self;
}
Exemple #12
0
CompoundFileReader*
CFReader_do_open(CompoundFileReader *self, Folder *folder) {
    CharBuf *cfmeta_file = (CharBuf*)ZCB_WRAP_STR("cfmeta.json", 11);
    Hash *metadata = (Hash*)Json_slurp_json((Folder*)folder, cfmeta_file);
    Err *error = NULL;

    Folder_init((Folder*)self, Folder_Get_Path(folder));

    // Parse metadata file.
    if (!metadata || !Hash_Is_A(metadata, HASH)) {
        error = Err_new(CB_newf("Can't read '%o' in '%o'", cfmeta_file,
                                Folder_Get_Path(folder)));
    }
    else {
        Obj *format = Hash_Fetch_Str(metadata, "format", 6);
        self->format = format ? (int32_t)Obj_To_I64(format) : 0;
        self->records = (Hash*)INCREF(Hash_Fetch_Str(metadata, "files", 5));
        if (self->format < 1) {
            error = Err_new(CB_newf("Corrupt %o file: Missing or invalid 'format'",
                                    cfmeta_file));
        }
        else if (self->format > CFWriter_current_file_format) {
            error = Err_new(CB_newf("Unsupported compound file format: %i32 "
                                    "(current = %i32", self->format,
                                    CFWriter_current_file_format));
        }
        else if (!self->records) {
            error = Err_new(CB_newf("Corrupt %o file: missing 'files' key",
                                    cfmeta_file));
        }
    }
    DECREF(metadata);
    if (error) {
        Err_set_error(error);
        DECREF(self);
        return NULL;
    }

    // Open an instream which we'll clone over and over.
    CharBuf *cf_file = (CharBuf*)ZCB_WRAP_STR("cf.dat", 6);
    self->instream = Folder_Open_In(folder, cf_file);
    if (!self->instream) {
        ERR_ADD_FRAME(Err_get_error());
        DECREF(self);
        return NULL;
    }

    // Assign.
    self->real_folder = (Folder*)INCREF(folder);

    // Strip directory name from filepaths for old format.
    if (self->format == 1) {
        VArray *files = Hash_Keys(self->records);
        ZombieCharBuf *filename = ZCB_BLANK();
        ZombieCharBuf *folder_name
            = IxFileNames_local_part(Folder_Get_Path(folder), ZCB_BLANK());
        size_t folder_name_len = ZCB_Length(folder_name);

        for (uint32_t i = 0, max = VA_Get_Size(files); i < max; i++) {
            CharBuf *orig = (CharBuf*)VA_Fetch(files, i);
            if (CB_Starts_With(orig, (CharBuf*)folder_name)) {
                Obj *record = Hash_Delete(self->records, (Obj*)orig);
                ZCB_Assign(filename, orig);
                ZCB_Nip(filename, folder_name_len + sizeof(DIR_SEP) - 1);
                Hash_Store(self->records, (Obj*)filename, (Obj*)record);
            }
        }

        DECREF(files);
    }

    return self;
}