You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

40 lines
910 B
C

#include <unistd.h>
#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;
}
}