Exemplo n.º 1
0
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);
    }
}
Exemplo n.º 2
0
void
InStream_seek(InStream *self, int64_t target) {
    FileWindow *const window = self->window;
    int64_t virtual_window_top = window->offset - self->offset;
    int64_t virtual_window_end = virtual_window_top + window->len;

    if (target < 0) {
        THROW(ERR, "Can't Seek '%o' to negative target %i64", self->filename,
              target);
    }
    // Seek within window if possible.
    else if (target >= virtual_window_top
             && target <= virtual_window_end
            ) {
        self->buf = window->buf - window->offset + self->offset + target;
    }
    else if (target > self->len) {
        THROW(ERR, "Can't Seek '%o' past EOF (%i64 > %i64)", self->filename,
              target, self->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(self->file_handle, window);
        self->buf   = NULL;
        self->limit = NULL;
        FileWindow_Set_Offset(window, self->offset + target);
    }
}