1 #include "lib9.h" 2 #include <bio.h> 3 4 vlong 5 Bseek(Biobuf *bp, vlong offset, int base) 6 { 7 vlong n, d; 8 9 switch(bp->state) { 10 default: 11 fprint(2, "Bseek: unknown state %d\n", bp->state); 12 return Beof; 13 14 case Bracteof: 15 bp->state = Bractive; 16 bp->icount = 0; 17 bp->gbuf = bp->ebuf; 18 19 case Bractive: 20 n = offset; 21 if(base == 1) { 22 n += Boffset(bp); 23 base = 0; 24 } 25 26 /* 27 * try to seek within buffer 28 */ 29 if(base == 0) { 30 /* 31 * if d is too large for an int, icount may wrap, 32 * so we need to ensure that icount hasn't wrapped 33 * and points within the buffer's valid data. 34 */ 35 d = n - Boffset(bp); 36 bp->icount += d; 37 if(d <= bp->bsize && bp->icount <= 0 && 38 bp->ebuf - bp->gbuf >= -bp->icount) 39 return n; 40 } 41 42 /* 43 * reset the buffer 44 */ 45 n = seek(bp->fid, n, base); 46 bp->icount = 0; 47 bp->gbuf = bp->ebuf; 48 break; 49 50 case Bwactive: 51 Bflush(bp); 52 n = seek(bp->fid, offset, base); 53 break; 54 } 55 bp->offset = n; 56 return n; 57 } 58