9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

brdline.c (1519B)


      1 #include	"lib9.h"
      2 #include	<bio.h>
      3 
      4 void*
      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 = (unsigned char*)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
     90 Blinelen(Biobuf *bp)
     91 {
     92 
     93 	return bp->rdline;
     94 }