xref: /inferno-os/libbio/brdline.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 #include	"lib9.h"
2 #include	<bio.h>
3 
4 void*
Brdline(Biobuf * bp,int delim)5 Brdline(Biobuf *bp, int delim)
6 {
7 	char *ip, *ep;
8 	int i, j;
9 
10 	i = -bp->icount;
11 	if(i == 0) {
12 		/*
13 		 * eof or other error
14 		 */
15 		if(bp->state != Bractive) {
16 			if(bp->state == Bracteof)
17 				bp->state = Bractive;
18 			bp->rdline = 0;
19 			bp->gbuf = bp->ebuf;
20 			return 0;
21 		}
22 	}
23 
24 	/*
25 	 * first try in remainder of buffer (gbuf doesn't change)
26 	 */
27 	ip = (char*)bp->ebuf - i;
28 	ep = memchr(ip, delim, i);
29 	if(ep) {
30 		j = (ep - ip) + 1;
31 		bp->rdline = j;
32 		bp->icount += j;
33 		return ip;
34 	}
35 
36 	/*
37 	 * copy data to beginning of buffer
38 	 */
39 	if(i < bp->bsize)
40 		memmove(bp->bbuf, ip, i);
41 	bp->gbuf = bp->bbuf;
42 
43 	/*
44 	 * append to buffer looking for the delim
45 	 */
46 	ip = (char*)bp->bbuf + i;
47 	while(i < bp->bsize) {
48 		j = read(bp->fid, ip, bp->bsize-i);
49 		if(j <= 0) {
50 			/*
51 			 * end of file with no delim
52 			 */
53 			memmove(bp->ebuf-i, bp->bbuf, i);
54 			bp->rdline = i;
55 			bp->icount = -i;
56 			bp->gbuf = bp->ebuf-i;
57 			return 0;
58 		}
59 		bp->offset += j;
60 		i += j;
61 		ep = memchr(ip, delim, j);
62 		if(ep) {
63 			/*
64 			 * found in new piece
65 			 * copy back up and reset everything
66 			 */
67 			ip = (char*)bp->ebuf - i;
68 			if(i < bp->bsize){
69 				memmove(ip, bp->bbuf, i);
70 				bp->gbuf = (uchar*)ip;
71 			}
72 			j = (ep - (char*)bp->bbuf) + 1;
73 			bp->rdline = j;
74 			bp->icount = j - i;
75 			return ip;
76 		}
77 		ip += j;
78 	}
79 
80 	/*
81 	 * full buffer without finding
82 	 */
83 	bp->rdline = bp->bsize;
84 	bp->icount = -bp->bsize;
85 	bp->gbuf = bp->bbuf;
86 	return 0;
87 }
88 
89 int
Blinelen(Biobuf * bp)90 Blinelen(Biobuf *bp)
91 {
92 
93 	return bp->rdline;
94 }
95