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; } }
bool CFReader_Local_Delete_IMP(CompoundFileReader *self, String *name) { CompoundFileReaderIVARS *const ivars = CFReader_IVARS(self); Hash *record = (Hash*)Hash_Delete(ivars->records, name); DECREF(record); if (record == NULL) { return Folder_Local_Delete(ivars->real_folder, name); } else { // Once the number of virtual files falls to 0, remove the compound // files. if (Hash_Get_Size(ivars->records) == 0) { String *cf_file = (String*)SSTR_WRAP_UTF8("cf.dat", 6); if (!Folder_Delete(ivars->real_folder, cf_file)) { return false; } String *cfmeta_file = (String*)SSTR_WRAP_UTF8("cfmeta.json", 11); if (!Folder_Delete(ivars->real_folder, cfmeta_file)) { return false; } } return true; } }
bool_t CFReader_local_delete(CompoundFileReader *self, const CharBuf *name) { Hash *record = (Hash*)Hash_Delete(self->records, (Obj*)name); DECREF(record); if (record == NULL) { return Folder_Local_Delete(self->real_folder, name); } else { // Once the number of virtual files falls to 0, remove the compound // files. if (Hash_Get_Size(self->records) == 0) { CharBuf *cf_file = (CharBuf*)ZCB_WRAP_STR("cf.dat", 6); if (!Folder_Delete(self->real_folder, cf_file)) { return false; } CharBuf *cfmeta_file = (CharBuf*)ZCB_WRAP_STR("cfmeta.json", 11); if (!Folder_Delete(self->real_folder, cfmeta_file)) { return false; } } return true; } }
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; } }