Exemplo n.º 1
0
static void
test_Seek_and_Tell(TestBatchRunner *runner) {
    int64_t     gb1      = INT64_C(0x40000000);
    int64_t     gb3      = gb1 * 3;
    int64_t     gb6      = gb1 * 6;
    int64_t     gb12     = gb1 * 12;
    FileHandle *fh       = (FileHandle*)MockFileHandle_new(NULL, gb12);
    InStream   *instream = InStream_open((Obj*)fh);
    InStreamIVARS *const ivars = InStream_IVARS(instream);

    InStream_Buf(instream, 10000);
    TEST_TRUE(runner, ivars->limit == ((char*)NULL) + 10000,
              "InStream_Buf sets limit");

    InStream_Seek(instream, gb6);
    TEST_TRUE(runner, InStream_Tell(instream) == gb6,
              "Tell after seek forwards outside buffer");
    TEST_TRUE(runner, ivars->buf == NULL,
              "Seek forwards outside buffer sets buf to NULL");
    TEST_TRUE(runner, ivars->limit == NULL,
              "Seek forwards outside buffer sets limit to NULL");
    TEST_TRUE(runner, FileWindow_IVARS(ivars->window)->offset == gb6,
              "Seek forwards outside buffer tracks pos in window offset");

    InStream_Buf(instream, (size_t)gb1);
    TEST_TRUE(runner, ivars->limit == ((char*)NULL) + gb1,
              "InStream_Buf sets limit");

    InStream_Seek(instream, gb6 + 10);
    TEST_TRUE(runner, InStream_Tell(instream) == gb6 + 10,
              "Tell after seek forwards within buffer");
    TEST_TRUE(runner, ivars->buf == ((char*)NULL) + 10,
              "Seek within buffer sets buf");
    TEST_TRUE(runner, ivars->limit == ((char*)NULL) + gb1,
              "Seek within buffer leaves limit alone");

    InStream_Seek(instream, gb6 + 1);
    TEST_TRUE(runner, InStream_Tell(instream) == gb6 + 1,
              "Tell after seek backwards within buffer");
    TEST_TRUE(runner, ivars->buf == ((char*)NULL) + 1,
              "Seek backwards within buffer sets buf");
    TEST_TRUE(runner, ivars->limit == ((char*)NULL) + gb1,
              "Seek backwards within buffer leaves limit alone");

    InStream_Seek(instream, gb3);
    TEST_TRUE(runner, InStream_Tell(instream) == gb3,
              "Tell after seek backwards outside buffer");
    TEST_TRUE(runner, ivars->buf == NULL,
              "Seek backwards outside buffer sets buf to NULL");
    TEST_TRUE(runner, ivars->limit == NULL,
              "Seek backwards outside buffer sets limit to NULL");
    TEST_TRUE(runner, FileWindow_IVARS(ivars->window)->offset == gb3,
              "Seek backwards outside buffer tracks pos in window offset");

    DECREF(instream);
    DECREF(fh);
}
Exemplo n.º 2
0
static void
test_refill(TestBatchRunner *runner) {
    RAMFile    *file      = RAMFile_new(NULL, false);
    OutStream  *outstream = OutStream_open((Obj*)file);
    InStream   *instream;
    char        scratch[5];
    InStreamIVARS *ivars;

    for (int32_t i = 0; i < 1023; i++) {
        OutStream_Write_U8(outstream, 'x');
    }
    OutStream_Write_U8(outstream, 'y');
    OutStream_Write_U8(outstream, 'z');
    OutStream_Close(outstream);

    instream = InStream_open((Obj*)file);
    ivars = InStream_IVARS(instream);
    InStream_Refill(instream);
    TEST_INT_EQ(runner, ivars->limit - ivars->buf, IO_STREAM_BUF_SIZE,
                "Refill");
    TEST_INT_EQ(runner, (long)InStream_Tell(instream), 0,
                "Correct file pos after standing-start Refill()");
    DECREF(instream);

    instream = InStream_open((Obj*)file);
    ivars = InStream_IVARS(instream);
    InStream_Fill(instream, 30);
    TEST_INT_EQ(runner, ivars->limit - ivars->buf, 30, "Fill()");
    TEST_INT_EQ(runner, (long)InStream_Tell(instream), 0,
                "Correct file pos after standing-start Fill()");
    DECREF(instream);

    instream = InStream_open((Obj*)file);
    ivars = InStream_IVARS(instream);
    InStream_Read_Bytes(instream, scratch, 5);
    TEST_INT_EQ(runner, ivars->limit - ivars->buf,
                IO_STREAM_BUF_SIZE - 5, "small read triggers refill");
    DECREF(instream);

    instream = InStream_open((Obj*)file);
    ivars = InStream_IVARS(instream);
    TEST_INT_EQ(runner, InStream_Read_U8(instream), 'x', "Read_U8");
    InStream_Seek(instream, 1023);
    TEST_INT_EQ(runner, (long)FileWindow_IVARS(ivars->window)->offset, 0,
                "no unnecessary refill on Seek");
    TEST_INT_EQ(runner, (long)InStream_Tell(instream), 1023, "Seek/Tell");
    TEST_INT_EQ(runner, InStream_Read_U8(instream), 'y',
                "correct data after in-buffer Seek()");
    TEST_INT_EQ(runner, InStream_Read_U8(instream), 'z', "automatic Refill");
    TEST_TRUE(runner, (FileWindow_IVARS(ivars->window)->offset != 0),
              "refilled");

    DECREF(instream);
    DECREF(outstream);
    DECREF(file);
}
Exemplo n.º 3
0
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';
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
static void
test_Buf(TestBatchRunner *runner) {
    RAMFile    *file      = RAMFile_new(NULL, false);
    OutStream  *outstream = OutStream_open((Obj*)file);
    size_t      size      = IO_STREAM_BUF_SIZE * 2 + 5;
    InStream   *instream;
    char       *buf;

    for (uint32_t i = 0; i < size; i++) {
        OutStream_Write_U8(outstream, 'a');
    }
    OutStream_Close(outstream);

    instream = InStream_open((Obj*)file);
    InStreamIVARS *const ivars = InStream_IVARS(instream);
    buf = InStream_Buf(instream, 5);
    TEST_INT_EQ(runner, ivars->limit - buf, IO_STREAM_BUF_SIZE,
                "Small request bumped up");

    buf += IO_STREAM_BUF_SIZE - 10; // 10 bytes left in buffer.
    InStream_Advance_Buf(instream, buf);

    buf = InStream_Buf(instream, 10);
    TEST_INT_EQ(runner, ivars->limit - buf, 10,
                "Exact request doesn't trigger refill");

    buf = InStream_Buf(instream, 11);
    TEST_INT_EQ(runner, ivars->limit - buf, IO_STREAM_BUF_SIZE,
                "Requesting over limit triggers refill");

    int64_t  expected = InStream_Length(instream) - InStream_Tell(instream);
    char    *buff     = InStream_Buf(instream, 100000);
    int64_t  got      = PTR_TO_I64(ivars->limit) - PTR_TO_I64(buff);
    TEST_TRUE(runner, got == expected,
              "Requests greater than file size get pared down");

    DECREF(instream);
    DECREF(outstream);
    DECREF(file);
}