static void test_Consolidate(TestBatchRunner *runner) { Folder *folder = S_folder_with_contents(); FileHandle *fh; // Fake up detritus from failed consolidation. fh = Folder_Open_FileHandle(folder, cf_file, FH_CREATE | FH_WRITE_ONLY | FH_EXCLUSIVE); DECREF(fh); fh = Folder_Open_FileHandle(folder, cfmeta_temp, FH_CREATE | FH_WRITE_ONLY | FH_EXCLUSIVE); DECREF(fh); CompoundFileWriter *cf_writer = CFWriter_new(folder); CFWriter_Consolidate(cf_writer); PASS(runner, "Consolidate completes despite leftover files"); DECREF(cf_writer); TEST_TRUE(runner, Folder_Exists(folder, cf_file), "cf.dat file written"); TEST_TRUE(runner, Folder_Exists(folder, cfmeta_file), "cfmeta.json file written"); TEST_FALSE(runner, Folder_Exists(folder, foo), "original file zapped"); TEST_FALSE(runner, Folder_Exists(folder, cfmeta_temp), "detritus from failed consolidation zapped"); DECREF(folder); }
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 test_offsets(TestBatchRunner *runner) { Folder *folder = S_folder_with_contents(); CompoundFileWriter *cf_writer = CFWriter_new(folder); Hash *cf_metadata; Hash *files; CFWriter_Consolidate(cf_writer); cf_metadata = (Hash*)CERTIFY( Json_slurp_json(folder, cfmeta_file), HASH); files = (Hash*)CERTIFY( Hash_Fetch_Utf8(cf_metadata, "files", 5), HASH); bool offsets_ok = true; TEST_TRUE(runner, Hash_Get_Size(files) > 0, "Multiple files"); HashIterator *iter = HashIter_new(files); while (HashIter_Next(iter)) { String *file = HashIter_Get_Key(iter); Hash *stats = (Hash*)CERTIFY(HashIter_Get_Value(iter), HASH); Obj *offset = CERTIFY(Hash_Fetch_Utf8(stats, "offset", 6), OBJ); int64_t offs = Obj_To_I64(offset); if (offs % 8 != 0) { offsets_ok = false; FAIL(runner, "Offset %" PRId64 " for %s not a multiple of 8", offset, Str_Get_Ptr8(file)); break; } } DECREF(iter); if (offsets_ok) { PASS(runner, "All offsets are multiples of 8"); } DECREF(cf_metadata); DECREF(cf_writer); DECREF(folder); }