static void test_Clone_and_Reopen(TestBatchRunner *runner) { String *foo = SSTR_WRAP_C("foo"); String *bar = SSTR_WRAP_C("bar"); RAMFile *file = RAMFile_new(NULL, false); OutStream *outstream = OutStream_open((Obj*)file); RAMFileHandle *fh; InStream *instream; InStream *clone; InStream *reopened; for (uint8_t i = 0; i < 26; i++) { OutStream_Write_U8(outstream, 'a' + i); } OutStream_Close(outstream); fh = RAMFH_open(foo, FH_READ_ONLY, file); instream = InStream_open((Obj*)fh); InStream_Seek(instream, 1); TEST_TRUE(runner, Str_Equals(InStream_Get_Filename(instream), (Obj*)foo), "Get_Filename"); clone = InStream_Clone(instream); TEST_TRUE(runner, Str_Equals(InStream_Get_Filename(clone), (Obj*)foo), "Clones have same filename"); TEST_TRUE(runner, InStream_Length(instream) == InStream_Length(clone), "Clones have same length"); TEST_TRUE(runner, InStream_Read_U8(instream) == InStream_Read_U8(clone), "Clones start at same file position"); reopened = InStream_Reopen(instream, bar, 25, 1); TEST_TRUE(runner, Str_Equals(InStream_Get_Filename(reopened), (Obj*)bar), "Reopened InStreams take new filename"); TEST_TRUE(runner, InStream_Read_U8(reopened) == 'z', "Reopened stream starts at supplied offset"); TEST_TRUE(runner, InStream_Length(reopened) == 1, "Reopened stream uses supplied length"); TEST_TRUE(runner, InStream_Tell(reopened) == 1, "Tell() uses supplied offset for reopened stream"); InStream_Seek(reopened, 0); TEST_TRUE(runner, InStream_Read_U8(reopened) == 'z', "Seek() uses supplied offset for reopened stream"); DECREF(reopened); DECREF(clone); DECREF(instream); DECREF(outstream); DECREF(fh); DECREF(file); }
static void test_Local_Open_In(TestBatchRunner *runner) { Folder *real_folder = S_folder_with_contents(); CompoundFileReader *cf_reader = CFReader_open(real_folder); InStream *instream; instream = CFReader_Local_Open_In(cf_reader, foo); TEST_TRUE(runner, instream != NULL, "Local_Open_In for virtual file"); TEST_TRUE(runner, Str_Starts_With(InStream_Get_Filename(instream), CFReader_Get_Path(cf_reader)), "InStream's path includes directory"); DECREF(instream); OutStream *outstream = CFReader_Open_Out(cf_reader, baz); OutStream_Write_Bytes(outstream, "baz", 3); OutStream_Close(outstream); DECREF(outstream); instream = CFReader_Local_Open_In(cf_reader, baz); TEST_TRUE(runner, instream != NULL, "Local_Open_In pass-through for real file"); DECREF(instream); Err_set_error(NULL); instream = CFReader_Local_Open_In(cf_reader, stuff); TEST_TRUE(runner, instream == NULL, "Local_Open_In for non-existent file returns NULL"); TEST_TRUE(runner, Err_get_error() != NULL, "Local_Open_In for non-existent file sets global error"); DECREF(cf_reader); DECREF(real_folder); }
void TextTermStepper_read_key_frame(TextTermStepper *self, InStream *instream) { const uint32_t text_len = InStream_Read_C32(instream); CharBuf *value; char *ptr; // Allocate space. if (self->value == NULL) { self->value = (Obj*)CB_new(text_len); } value = (CharBuf*)self->value; ptr = CB_Grow(value, text_len); // Set the value text. InStream_Read_Bytes(instream, ptr, text_len); CB_Set_Size(value, text_len); if (!StrHelp_utf8_valid(ptr, text_len)) { THROW(ERR, "Invalid UTF-8 sequence in '%o' at byte %i64", InStream_Get_Filename(instream), InStream_Tell(instream) - text_len); } // Null-terminate. ptr[text_len] = '\0'; }
void TextTermStepper_Read_Delta_IMP(TextTermStepper *self, InStream *instream) { TextTermStepperIVARS *const ivars = TextTermStepper_IVARS(self); const uint32_t text_overlap = InStream_Read_C32(instream); const uint32_t finish_chars_len = InStream_Read_C32(instream); const uint32_t total_text_len = text_overlap + finish_chars_len; // Allocate space. CharBuf *charbuf = (CharBuf*)ivars->value; char *ptr = CB_Grow(charbuf, total_text_len); // Set the value text. InStream_Read_Bytes(instream, ptr + text_overlap, finish_chars_len); CB_Set_Size(charbuf, total_text_len); if (!StrHelp_utf8_valid(ptr, total_text_len)) { THROW(ERR, "Invalid UTF-8 sequence in '%o' at byte %i64", InStream_Get_Filename(instream), InStream_Tell(instream) - finish_chars_len); } // Null-terminate. ptr[total_text_len] = '\0'; // Invalidate string. DECREF(ivars->string); ivars->string = NULL; }
static void S_fresh_flip(PostingPool *self, InStream *lex_temp_in, InStream *post_temp_in) { PostingPoolIVARS *const ivars = PostPool_IVARS(self); if (ivars->flipped) { THROW(ERR, "Can't Flip twice"); } ivars->flipped = true; // Sort RawPostings in buffer, if any. PostPool_Sort_Buffer(self); // Bail if never flushed. if (ivars->lex_end == 0) { return; } // Get a Lexicon. String *lex_alias = Str_newf("%o-%i64-to-%i64", InStream_Get_Filename(lex_temp_in), ivars->lex_start, ivars->lex_end); InStream *lex_temp_in_dupe = InStream_Reopen( lex_temp_in, lex_alias, ivars->lex_start, ivars->lex_end - ivars->lex_start); ivars->lexicon = (Lexicon*)RawLex_new( ivars->schema, ivars->field, lex_temp_in_dupe, 0, ivars->lex_end - ivars->lex_start); DECREF(lex_alias); DECREF(lex_temp_in_dupe); // Get a PostingList. String *post_alias = Str_newf("%o-%i64-to-%i64", InStream_Get_Filename(post_temp_in), ivars->post_start, ivars->post_end); InStream *post_temp_in_dupe = InStream_Reopen(post_temp_in, post_alias, ivars->post_start, ivars->post_end - ivars->post_start); ivars->plist = (PostingList*)RawPList_new(ivars->schema, ivars->field, post_temp_in_dupe, 0, ivars->post_end - ivars->post_start); DECREF(post_alias); DECREF(post_temp_in_dupe); }
static void S_read_entry(LexIndex *self) { TermInfo *tinfo = self->tinfo; i64_t offset = (i64_t)Math_decode_bigend_u64(self->offsets + self->tick); char *data = self->data + offset; size_t size = Math_decode_c32(&data); ViewCB_Assign_Str(self->term, data, size); data += size; tinfo->doc_freq = Math_decode_c32(&data); tinfo->post_filepos = Math_decode_c64(&data); tinfo->skip_filepos = tinfo->doc_freq >= self->skip_interval ? Math_decode_c64(&data) : 0; tinfo->lex_filepos = Math_decode_c64(&data); /* Don't allow buffer overruns. */ if (data > self->limit) { THROW("Buffer overrun in lexicon index for %o", InStream_Get_Filename(self->ix_in)); } }