1 #include "lib9.h"
2 #include <bio.h>
3
4 vlong
Bseek(Biobuf * bp,vlong offset,int base)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