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; } }
CFReaderDirHandle* CFReaderDH_init(CFReaderDirHandle *self, CompoundFileReader *cf_reader) { DH_init((DirHandle*)self, CFReader_Get_Path(cf_reader)); self->cf_reader = (CompoundFileReader*)INCREF(cf_reader); self->elems = Hash_Keys(self->cf_reader->records); self->tick = -1; // Accumulate entries from real Folder. DirHandle *dh = Folder_Local_Open_Dir(self->cf_reader->real_folder); CharBuf *entry = DH_Get_Entry(dh); while (DH_Next(dh)) { VA_Push(self->elems, (Obj*)CB_Clone(entry)); } DECREF(dh); return self; }
VArray* Folder_list(Folder *self, const CharBuf *path) { Folder *local_folder = Folder_Find_Folder(self, path); VArray *list = NULL; DirHandle *dh = Folder_Local_Open_Dir(local_folder); if (dh) { CharBuf *entry = DH_Get_Entry(dh); list = VA_new(32); while (DH_Next(dh)) { VA_Push(list, (Obj*)CB_Clone(entry)); } DECREF(dh); } else { ERR_ADD_FRAME(Err_get_error()); } return list; }
CFReaderDirHandle* CFReaderDH_init(CFReaderDirHandle *self, CompoundFileReader *cf_reader) { DH_init((DirHandle*)self, CFReader_Get_Path(cf_reader)); CFReaderDirHandleIVARS *const ivars = CFReaderDH_IVARS(self); ivars->cf_reader = (CompoundFileReader*)INCREF(cf_reader); Hash *cf_records = CFReader_IVARS(ivars->cf_reader)->records; ivars->elems = Hash_Keys(cf_records); ivars->tick = -1; // Accumulate entries from real Folder. Folder *real_folder = CFReader_Get_Real_Folder(ivars->cf_reader); DirHandle *dh = Folder_Local_Open_Dir(real_folder); while (DH_Next(dh)) { String *entry = DH_Get_Entry(dh); Vec_Push(ivars->elems, (Obj*)Str_Clone(entry)); DECREF(entry); } DECREF(dh); return self; }
DirHandle* Folder_open_dir(Folder *self, const CharBuf *path) { DirHandle *dh = NULL; Folder *folder; if (path) { folder = Folder_Find_Folder(self, path); } else { ZombieCharBuf *empty = ZCB_BLANK(); folder = Folder_Find_Folder(self, (CharBuf*)empty); } if (!folder) { Err_set_error(Err_new(CB_newf("Invalid path: '%o'", path))); } else { dh = Folder_Local_Open_Dir(folder); if (!dh) { ERR_ADD_FRAME(Err_get_error()); } } return dh; }