xref: /inferno-os/libbio/bgetc.c (revision d0e1d143ef6f03c75c008c7ec648859dd260cbab)
1 #include	"lib9.h"
2 #include	<bio.h>
3 
4 int
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 		if(i < 0)
30 			bp->state = Binactive;
31 		return Beof;
32 	}
33 	if(i < bp->bsize) {
34 		memmove(bp->ebuf-i-Bungetsize, bp->bbuf-Bungetsize, i+Bungetsize);
35 		bp->gbuf = bp->ebuf-i;
36 	}
37 	bp->icount = -i;
38 	bp->offset += i;
39 	goto loop;
40 }
41 
42 int
43 Bungetc(Biobuf *bp)
44 {
45 
46 	if(bp->state == Bracteof)
47 		bp->state = Bractive;
48 	if(bp->state != Bractive)
49 		return Beof;
50 	bp->icount--;
51 	return 1;
52 }
53