static void test_Mimic_and_Clone(TestBatchRunner *runner) { String *wanted = S_get_str("foo"); CharBuf *wanted_cb = S_get_cb("foo"); CharBuf *got = S_get_cb("bar"); CB_Mimic(got, (Obj*)wanted); TEST_TRUE(runner, S_cb_equals(got, wanted), "Mimic String"); DECREF(got); got = S_get_cb("bar"); CB_Mimic(got, (Obj*)wanted_cb); TEST_TRUE(runner, S_cb_equals(got, wanted), "Mimic CharBuf"); DECREF(got); got = S_get_cb("bar"); CB_Mimic_Utf8(got, "foo", 3); TEST_TRUE(runner, S_cb_equals(got, wanted), "Mimic_Utf8"); DECREF(got); got = CB_Clone(wanted_cb); TEST_TRUE(runner, S_cb_equals(got, wanted), "Clone"); DECREF(got); DECREF(wanted); DECREF(wanted_cb); }
void TextTermStepper_Set_Value_IMP(TextTermStepper *self, Obj *value) { TextTermStepperIVARS *const ivars = TextTermStepper_IVARS(self); CERTIFY(value, STRING); CB_Mimic((CharBuf*)ivars->value, value); // Invalidate string. DECREF(ivars->string); ivars->string = NULL; }
void TextTermStepper_Write_Key_Frame_IMP(TextTermStepper *self, OutStream *outstream, Obj *value) { TextTermStepperIVARS *const ivars = TextTermStepper_IVARS(self); CharBuf *charbuf = (CharBuf*)ivars->value; CB_Mimic(charbuf, value); const char *buf = CB_Get_Ptr8(charbuf); size_t size = CB_Get_Size(charbuf); OutStream_Write_C32(outstream, size); OutStream_Write_Bytes(outstream, buf, size); // Invalidate string. DECREF(ivars->string); ivars->string = NULL; }
bool_t CFReaderDH_next(CFReaderDirHandle *self) { if (self->elems) { self->tick++; if (self->tick < (int32_t)VA_Get_Size(self->elems)) { CharBuf *path = (CharBuf*)CERTIFY( VA_Fetch(self->elems, self->tick), CHARBUF); CB_Mimic(self->entry, (Obj*)path); return true; } else { self->tick--; return false; } } return false; }
InStream* InStream_reopen(InStream *self, const CharBuf *filename, int64_t offset, int64_t len) { if (!self->file_handle) { THROW(ERR, "Can't Reopen() closed InStream %o", self->filename); } if (offset + len > FH_Length(self->file_handle)) { THROW(ERR, "Offset + length too large (%i64 + %i64 > %i64)", offset, len, FH_Length(self->file_handle)); } InStream *twin = (InStream*)VTable_Make_Obj(self->vtable); InStream_do_open(twin, (Obj*)self->file_handle); if (filename != NULL) { CB_Mimic(twin->filename, (Obj*)filename); } twin->offset = offset; twin->len = len; InStream_Seek(twin, 0); return twin; }
static void test_Mimic_and_Clone(TestBatch *batch) { CharBuf *wanted = S_get_cb("foo"); CharBuf *got = S_get_cb("bar"); CB_Mimic(got, (Obj*)wanted); TEST_TRUE(batch, CB_Equals(wanted, (Obj*)got), "Mimic"); DECREF(got); got = S_get_cb("bar"); CB_Mimic_Str(got, "foo", 3); TEST_TRUE(batch, CB_Equals(wanted, (Obj*)got), "Mimic_Str"); DECREF(got); got = CB_Clone(wanted); TEST_TRUE(batch, CB_Equals(wanted, (Obj*)got), "Clone"); DECREF(got); DECREF(wanted); }
InStream* InStream_reopen(InStream *self, const CharBuf *filename, int64_t offset, int64_t len) { InStreamIVARS *const ivars = InStream_IVARS(self); if (!ivars->file_handle) { THROW(ERR, "Can't Reopen() closed InStream %o", ivars->filename); } if (offset + len > FH_Length(ivars->file_handle)) { THROW(ERR, "Offset + length too large (%i64 + %i64 > %i64)", offset, len, FH_Length(ivars->file_handle)); } VTable *vtable = InStream_Get_VTable(self); InStream *other = (InStream*)VTable_Make_Obj(vtable); InStreamIVARS *const ovars = InStream_IVARS(other); InStream_do_open(other, (Obj*)ivars->file_handle); if (filename != NULL) { CB_Mimic(ovars->filename, (Obj*)filename); } ovars->offset = offset; ovars->len = len; InStream_Seek(other, 0); return other; }
void TextTermStepper_write_delta(TextTermStepper *self, OutStream *outstream, Obj *value) { CharBuf *new_value = (CharBuf*)CERTIFY(value, CHARBUF); CharBuf *last_value = (CharBuf*)self->value; char *new_text = (char*)CB_Get_Ptr8(new_value); size_t new_size = CB_Get_Size(new_value); char *last_text = (char*)CB_Get_Ptr8(last_value); size_t last_size = CB_Get_Size(last_value); // Count how many bytes the strings share at the top. const int32_t overlap = StrHelp_overlap(last_text, new_text, last_size, new_size); const char *const diff_start_str = new_text + overlap; const size_t diff_len = new_size - overlap; // Write number of common bytes and common bytes. OutStream_Write_C32(outstream, overlap); OutStream_Write_String(outstream, diff_start_str, diff_len); // Update value. CB_Mimic((CharBuf*)self->value, value); }
void S_try_open_elements(void *context) { struct try_open_elements_context *args = (struct try_open_elements_context*)context; PolyReader *self = args->self; PolyReaderIVARS *const ivars = PolyReader_IVARS(self); VArray *files = Snapshot_List(ivars->snapshot); Folder *folder = PolyReader_Get_Folder(self); uint32_t num_segs = 0; uint64_t latest_schema_gen = 0; CharBuf *schema_file = NULL; // Find schema file, count segments. for (uint32_t i = 0, max = VA_Get_Size(files); i < max; i++) { CharBuf *entry = (CharBuf*)VA_Fetch(files, i); if (Seg_valid_seg_name(entry)) { num_segs++; } else if (CB_Starts_With_Str(entry, "schema_", 7) && CB_Ends_With_Str(entry, ".json", 5) ) { uint64_t gen = IxFileNames_extract_gen(entry); if (gen > latest_schema_gen) { latest_schema_gen = gen; if (!schema_file) { schema_file = CB_Clone(entry); } else { CB_Mimic(schema_file, (Obj*)entry); } } } } // Read Schema. if (!schema_file) { DECREF(files); THROW(ERR, "Can't find a schema file."); } else { Hash *dump = (Hash*)Json_slurp_json(folder, schema_file); if (dump) { // read file successfully DECREF(ivars->schema); ivars->schema = (Schema*)CERTIFY( VTable_Load_Obj(SCHEMA, (Obj*)dump), SCHEMA); DECREF(dump); DECREF(schema_file); schema_file = NULL; } else { CharBuf *mess = MAKE_MESS("Failed to parse %o", schema_file); DECREF(schema_file); DECREF(files); Err_throw_mess(ERR, mess); } } VArray *segments = VA_new(num_segs); for (uint32_t i = 0, max = VA_Get_Size(files); i < max; i++) { CharBuf *entry = (CharBuf*)VA_Fetch(files, i); // Create a Segment for each segmeta. if (Seg_valid_seg_name(entry)) { int64_t seg_num = IxFileNames_extract_gen(entry); Segment *segment = Seg_new(seg_num); // Bail if reading the file fails (probably because it's been // deleted and a new snapshot file has been written so we need to // retry). if (Seg_Read_File(segment, folder)) { VA_Push(segments, (Obj*)segment); } else { CharBuf *mess = MAKE_MESS("Failed to read %o", entry); DECREF(segment); DECREF(segments); DECREF(files); Err_throw_mess(ERR, mess); } } } // Sort the segments by age. VA_Sort(segments, NULL, NULL); // Open individual SegReaders. struct try_open_segreader_context seg_context; seg_context.schema = PolyReader_Get_Schema(self); seg_context.folder = folder; seg_context.snapshot = PolyReader_Get_Snapshot(self); seg_context.segments = segments; seg_context.result = NULL; args->seg_readers = VA_new(num_segs); Err *error = NULL; for (uint32_t seg_tick = 0; seg_tick < num_segs; seg_tick++) { seg_context.seg_tick = seg_tick; error = Err_trap(S_try_open_segreader, &seg_context); if (error) { break; } VA_Push(args->seg_readers, (Obj*)seg_context.result); seg_context.result = NULL; } DECREF(segments); DECREF(files); if (error) { DECREF(args->seg_readers); args->seg_readers = NULL; RETHROW(error); } }
void FH_set_path(FileHandle *self, const CharBuf *path) { CB_Mimic(self->path, (Obj*)path); }