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); } } }
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; }
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; } }
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; }
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; } }
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; }
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; }
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; }
static void test_Enclosing_Folder_and_Find_Folder(TestBatch *batch) { Folder *folder = (Folder*)RAMFolder_new(NULL); FileHandle *fh; Folder_MkDir(folder, &foo); Folder_MkDir(folder, &foo_bar); Folder_MkDir(folder, &foo_bar_baz); fh = Folder_Open_FileHandle(folder, &foo_bar_baz_boffo, FH_CREATE | FH_WRITE_ONLY); { Folder *encloser = Folder_Enclosing_Folder(folder, (CharBuf*)&nope); Folder *found = Folder_Find_Folder(folder, (CharBuf*)&nope); TEST_TRUE(batch, encloser == folder, "Enclosing_Folder() - non-existent entry yields parent"); TEST_TRUE(batch, found == NULL, "Find_Folder() - non-existent entry yields NULL"); } { Folder *encloser = Folder_Enclosing_Folder(folder, &foo_bar); Folder *found = Folder_Find_Folder(folder, &foo_bar); TEST_TRUE(batch, encloser && Folder_Is_A(encloser, FOLDER) && CB_Ends_With(Folder_Get_Path(encloser), &foo), "Enclosing_Folder() - find one directory down"); TEST_TRUE(batch, found && Folder_Is_A(found, FOLDER) && CB_Ends_With(Folder_Get_Path(found), &bar), "Find_Folder() - 'foo/bar'"); } { Folder *encloser = Folder_Enclosing_Folder(folder, &foo_bar_baz); Folder *found = Folder_Find_Folder(folder, &foo_bar_baz); TEST_TRUE(batch, encloser && Folder_Is_A(encloser, FOLDER) && CB_Ends_With(Folder_Get_Path(encloser), &bar), "Find two directories down"); TEST_TRUE(batch, found && Folder_Is_A(found, FOLDER) && CB_Ends_With(Folder_Get_Path(found), &baz), "Find_Folder() - 'foo/bar/baz'"); } { Folder *encloser = Folder_Enclosing_Folder(folder, &foo_bar_baz_boffo); Folder *found = Folder_Find_Folder(folder, &foo_bar_baz_boffo); TEST_TRUE(batch, encloser && Folder_Is_A(encloser, FOLDER) && CB_Ends_With(Folder_Get_Path(encloser), &baz), "Recurse to find a directory containing a real file"); TEST_TRUE(batch, found == NULL, "Find_Folder() - file instead of folder yields NULL"); } DECREF(fh); DECREF(folder); }