xref: /inferno-os/libbio/bgetc.c (revision 72335078034e3cd7edcb1739556b405a3e1e9bf8)
1 #include	"lib9.h"
2 #include	<bio.h>
3 
4 int
Bgetc(Biobuf * bp)5 Bgetc(Biobuf *bp)
6 {
7 	int i;
8 
9 loop:
10 	i = bp->icount;
11 	if(i != 0) {
12 		bp->icount = i+1;
13 		return bp->ebuf[i];
14 	}
15 	if(bp->state != Bractive) {
16 		if(bp->state == Bracteof)
17 			bp->state = Bractive;
18 		return Beof;
19 	}
20 	/*
21 	 * get next buffer, try to keep Bungetsize
22 	 * characters pre-catenated from the previous
23 	 * buffer to allow that many ungets.
24 	 */
25 	memmove(bp->bbuf-Bungetsize, bp->ebuf-Bungetsize, Bungetsize);
26 	i = read(bp->fid, bp->bbuf, bp->bsize);
27 	bp->gbuf = bp->bbuf;
28 	if(i <= 0) {
29 		bp->state = Bracteof;
30 		if(i < 0)
31 			bp->state = Binactive;
32 		return Beof;
33 	}
34 	if(i < bp->bsize) {
35 		memmove(bp->ebuf-i-Bungetsize, bp->bbuf-Bungetsize, i+Bungetsize);
36 		bp->gbuf = bp->ebuf-i;
37 	}
38 	bp->icount = -i;
39 	bp->offset += i;
40 	goto loop;
41 }
42 
43 int
Bungetc(Biobuf * bp)44 Bungetc(Biobuf *bp)
45 {
46 
47 	if(bp->state == Bracteof)
48 		bp->state = Bractive;
49 	if(bp->state != Bractive)
50 		return Beof;
51 	bp->icount--;
52 	return 1;
53 }
54