xref: /plan9/sys/src/libbio/brdline.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include	<u.h>
23e12c5d1SDavid du Colombier #include	<libc.h>
33e12c5d1SDavid du Colombier #include	<bio.h>
43e12c5d1SDavid du Colombier 
53e12c5d1SDavid du Colombier void*
Brdline(Biobufhdr * bp,int delim)63e12c5d1SDavid du Colombier Brdline(Biobufhdr *bp, int delim)
73e12c5d1SDavid du Colombier {
83e12c5d1SDavid du Colombier 	char *ip, *ep;
93e12c5d1SDavid du Colombier 	int i, j;
103e12c5d1SDavid du Colombier 
113e12c5d1SDavid du Colombier 	i = -bp->icount;
123e12c5d1SDavid du Colombier 	if(i == 0) {
133e12c5d1SDavid du Colombier 		/*
143e12c5d1SDavid du Colombier 		 * eof or other error
153e12c5d1SDavid du Colombier 		 */
163e12c5d1SDavid du Colombier 		if(bp->state != Bractive) {
173e12c5d1SDavid du Colombier 			if(bp->state == Bracteof)
183e12c5d1SDavid du Colombier 				bp->state = Bractive;
193e12c5d1SDavid du Colombier 			bp->rdline = 0;
20*219b2ee8SDavid du Colombier 			bp->gbuf = bp->ebuf;
213e12c5d1SDavid du Colombier 			return 0;
223e12c5d1SDavid du Colombier 		}
233e12c5d1SDavid du Colombier 	}
243e12c5d1SDavid du Colombier 
253e12c5d1SDavid du Colombier 	/*
26*219b2ee8SDavid du Colombier 	 * first try in remainder of buffer (gbuf doesn't change)
273e12c5d1SDavid du Colombier 	 */
283e12c5d1SDavid du Colombier 	ip = (char*)bp->ebuf - i;
293e12c5d1SDavid du Colombier 	ep = memchr(ip, delim, i);
303e12c5d1SDavid du Colombier 	if(ep) {
313e12c5d1SDavid du Colombier 		j = (ep - ip) + 1;
323e12c5d1SDavid du Colombier 		bp->rdline = j;
333e12c5d1SDavid du Colombier 		bp->icount += j;
343e12c5d1SDavid du Colombier 		return ip;
353e12c5d1SDavid du Colombier 	}
363e12c5d1SDavid du Colombier 
373e12c5d1SDavid du Colombier 	/*
383e12c5d1SDavid du Colombier 	 * copy data to beginning of buffer
393e12c5d1SDavid du Colombier 	 */
403e12c5d1SDavid du Colombier 	if(i < bp->bsize)
413e12c5d1SDavid du Colombier 		memmove(bp->bbuf, ip, i);
42*219b2ee8SDavid du Colombier 	bp->gbuf = bp->bbuf;
433e12c5d1SDavid du Colombier 
443e12c5d1SDavid du Colombier 	/*
453e12c5d1SDavid du Colombier 	 * append to buffer looking for the delim
463e12c5d1SDavid du Colombier 	 */
473e12c5d1SDavid du Colombier 	ip = (char*)bp->bbuf + i;
483e12c5d1SDavid du Colombier 	while(i < bp->bsize) {
493e12c5d1SDavid du Colombier 		j = read(bp->fid, ip, bp->bsize-i);
503e12c5d1SDavid du Colombier 		if(j <= 0) {
513e12c5d1SDavid du Colombier 			/*
523e12c5d1SDavid du Colombier 			 * end of file with no delim
533e12c5d1SDavid du Colombier 			 */
543e12c5d1SDavid du Colombier 			memmove(bp->ebuf-i, bp->bbuf, i);
553e12c5d1SDavid du Colombier 			bp->rdline = i;
563e12c5d1SDavid du Colombier 			bp->icount = -i;
57*219b2ee8SDavid du Colombier 			bp->gbuf = bp->ebuf-i;
583e12c5d1SDavid du Colombier 			return 0;
593e12c5d1SDavid du Colombier 		}
603e12c5d1SDavid du Colombier 		bp->offset += j;
613e12c5d1SDavid du Colombier 		i += j;
623e12c5d1SDavid du Colombier 		ep = memchr(ip, delim, j);
633e12c5d1SDavid du Colombier 		if(ep) {
643e12c5d1SDavid du Colombier 			/*
653e12c5d1SDavid du Colombier 			 * found in new piece
663e12c5d1SDavid du Colombier 			 * copy back up and reset everything
673e12c5d1SDavid du Colombier 			 */
683e12c5d1SDavid du Colombier 			ip = (char*)bp->ebuf - i;
69*219b2ee8SDavid du Colombier 			if(i < bp->bsize){
703e12c5d1SDavid du Colombier 				memmove(ip, bp->bbuf, i);
71*219b2ee8SDavid du Colombier 				bp->gbuf = (uchar*)ip;
72*219b2ee8SDavid du Colombier 			}
733e12c5d1SDavid du Colombier 			j = (ep - (char*)bp->bbuf) + 1;
743e12c5d1SDavid du Colombier 			bp->rdline = j;
753e12c5d1SDavid du Colombier 			bp->icount = j - i;
763e12c5d1SDavid du Colombier 			return ip;
773e12c5d1SDavid du Colombier 		}
783e12c5d1SDavid du Colombier 		ip += j;
793e12c5d1SDavid du Colombier 	}
803e12c5d1SDavid du Colombier 
813e12c5d1SDavid du Colombier 	/*
823e12c5d1SDavid du Colombier 	 * full buffer without finding
833e12c5d1SDavid du Colombier 	 */
843e12c5d1SDavid du Colombier 	bp->rdline = bp->bsize;
853e12c5d1SDavid du Colombier 	bp->icount = -bp->bsize;
86*219b2ee8SDavid du Colombier 	bp->gbuf = bp->bbuf;
873e12c5d1SDavid du Colombier 	return 0;
883e12c5d1SDavid du Colombier }
893e12c5d1SDavid du Colombier 
903e12c5d1SDavid du Colombier int
Blinelen(Biobufhdr * bp)913e12c5d1SDavid du Colombier Blinelen(Biobufhdr *bp)
923e12c5d1SDavid du Colombier {
933e12c5d1SDavid du Colombier 
943e12c5d1SDavid du Colombier 	return bp->rdline;
953e12c5d1SDavid du Colombier }
96