#include #include "buffer.h" ssize_t buffer_seek(buffer* b,size_t len) { size_t leftinbuf = b->n - b->p; ssize_t r; if ((ssize_t)len < 0) return -1; // can't signal back how much we read, so error out r = (ssize_t)len; if (len <= leftinbuf) { b->p += len; return len; } else { // want to skip more than there was in the buffer len -= leftinbuf; b->p = 0; // clear buffer b->n = 0; /* change position in underlying file */ if (b->fd != -1 && len > b->a && lseek(b->fd, len, SEEK_CUR) != -1) return len; // either we have no fd or input is not seekable // call read repeatedly while (len > 0) { ssize_t r = buffer_feed(b); if (r < 0) return -1; if (r == 0) break; if ((size_t)r > len) { // awesome, we are done b->p = len; return r; } len -= r; b->p = b->n = 0; } return r; } }