示例#1
0
static void
test_Window(TestBatchRunner *runner) {
    String *test_filename = SSTR_WRAP_C("_fstest");
    FSFileHandle *fh;
    FileWindow *window = FileWindow_new();
    uint32_t i;

    S_remove(test_filename);
    fh = FSFH_open(test_filename,
                   FH_CREATE | FH_WRITE_ONLY | FH_EXCLUSIVE);
    for (i = 0; i < 1024; i++) {
        FSFH_Write(fh, "foo ", 4);
    }
    if (!FSFH_Close(fh)) { RETHROW(INCREF(Err_get_error())); }

    // Reopen for reading.
    DECREF(fh);
    fh = FSFH_open(test_filename, FH_READ_ONLY);
    if (!fh) { RETHROW(INCREF(Err_get_error())); }

    Err_set_error(NULL);
    TEST_FALSE(runner, FSFH_Window(fh, window, -1, 4),
               "Window() with a negative offset returns false");
    TEST_TRUE(runner, Err_get_error() != NULL,
              "Window() with a negative offset sets error");

    Err_set_error(NULL);
    TEST_FALSE(runner, FSFH_Window(fh, window, 4000, 1000),
               "Window() past EOF returns false");
    TEST_TRUE(runner, Err_get_error() != NULL,
              "Window() past EOF sets error");

    TEST_TRUE(runner, FSFH_Window(fh, window, 1021, 2),
              "Window() returns true");
    const char *buf = FileWindow_Get_Buf(window);
    int64_t offset = FileWindow_Get_Offset(window);
    TEST_TRUE(runner,
              strncmp(buf - offset + 1021, "oo", 2) == 0,
              "Window()");

    TEST_TRUE(runner, FSFH_Release_Window(fh, window),
              "Release_Window() returns true");
    TEST_TRUE(runner, FileWindow_Get_Buf(window) == NULL,
              "Release_Window() resets buf");
    TEST_INT_EQ(runner, FileWindow_Get_Offset(window), 0,
                "Release_Window() resets offset");
    TEST_INT_EQ(runner, FileWindow_Get_Len(window), 0,
                "Release_Window() resets len");

    DECREF(window);
    DECREF(fh);
    S_remove(test_filename);
}
示例#2
0
文件: InStream.c 项目: theory/lucy
static INLINE int64_t
SI_tell(InStream *self) {
    InStreamIVARS *const ivars = InStream_IVARS(self);
    char *fw_buf = FileWindow_Get_Buf(ivars->window);
    int64_t pos_in_buf = PTR_TO_I64(ivars->buf) - PTR_TO_I64(fw_buf);
    return pos_in_buf + FileWindow_Get_Offset(ivars->window) - ivars->offset;
}
示例#3
0
文件: InStream.c 项目: theory/lucy
void
InStream_seek(InStream *self, int64_t target) {
    InStreamIVARS *const ivars = InStream_IVARS(self);
    FileWindow *const window = ivars->window;
    char    *fw_buf    = FileWindow_Get_Buf(window);
    int64_t  fw_offset = FileWindow_Get_Offset(window);
    int64_t  fw_len    = FileWindow_Get_Len(window);
    int64_t  virtual_window_top = fw_offset - ivars->offset;
    int64_t  virtual_window_end = virtual_window_top + fw_len;

    if (target < 0) {
        THROW(ERR, "Can't Seek '%o' to negative target %i64", ivars->filename,
              target);
    }
    // Seek within window if possible.
    else if (target >= virtual_window_top
             && target <= virtual_window_end
            ) {
        ivars->buf = fw_buf - fw_offset + ivars->offset + target;
    }
    else if (target > ivars->len) {
        THROW(ERR, "Can't Seek '%o' past EOF (%i64 > %i64)", ivars->filename,
              target, ivars->len);
    }
    else {
        // Target is outside window.  Set all buffer and limit variables to
        // NULL to trigger refill on the next read.  Store the file position
        // in the FileWindow's offset.
        FH_Release_Window(ivars->file_handle, window);
        ivars->buf   = NULL;
        ivars->limit = NULL;
        FileWindow_Set_Offset(window, ivars->offset + target);
    }
}
示例#4
0
文件: InStream.c 项目: theory/lucy
static void
S_fill(InStream *self, int64_t amount) {
    InStreamIVARS *const ivars     = InStream_IVARS(self);
    FileWindow *const window       = ivars->window;
    const int64_t virtual_file_pos = SI_tell(self);
    const int64_t real_file_pos    = virtual_file_pos + ivars->offset;
    const int64_t remaining        = ivars->len - virtual_file_pos;

    // Throw an error if the requested amount would take us beyond EOF.
    if (amount > remaining) {
        THROW(ERR,  "Read past EOF of %o (pos: %u64 len: %u64 request: %u64)",
              ivars->filename, virtual_file_pos, ivars->len, amount);
    }

    // Make the request.
    if (FH_Window(ivars->file_handle, window, real_file_pos, amount)) {
        char    *fw_buf    = FileWindow_Get_Buf(window);
        int64_t  fw_offset = FileWindow_Get_Offset(window);
        int64_t  fw_len    = FileWindow_Get_Len(window);
        char *const window_limit = fw_buf + fw_len;
        ivars->buf = fw_buf
                     - fw_offset          // theoretical start of real file
                     + ivars->offset      // top of virtual file
                     + virtual_file_pos;  // position within virtual file
        ivars->limit = window_limit - ivars->buf > remaining
                       ? ivars->buf + remaining
                       : window_limit;
    }
    else {
        Err *error = Err_get_error();
        CB_catf(Err_Get_Mess(error), " (%o)", ivars->filename);
        RETHROW(INCREF(error));
    }
}