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