ref: dfca0be219074f8473683256b1b9ca986ec37c43
dir: /sys/src/libbio/bseek.c/
#include <u.h> #include <libc.h> #include <bio.h> vlong Bseek(Biobufhdr *bp, vlong offset, int base) { vlong n, d; switch(bp->state) { default: abort(); case Bracteof: bp->state = Bractive; bp->icount = 0; bp->gbuf = bp->ebuf; case Bractive: n = offset; if(base == 1) { n += Boffset(bp); base = 0; } /* * try to seek within buffer */ if(base == 0) { /* * if d is too large for an int, icount may wrap, * so we need to ensure that icount hasn't wrapped * and points within the buffer's valid data. */ d = n - Boffset(bp); bp->icount += d; if(d <= bp->bsize && bp->icount <= 0 && bp->ebuf - bp->gbuf >= -bp->icount) return n; } /* * reset the buffer */ n = seek(bp->fid, n, base); bp->icount = 0; bp->gbuf = bp->ebuf; break; case Bwactive: Bflush(bp); n = seek(bp->fid, offset, base); break; } bp->offset = n; return n; }