ref: f1a32c955360268a7bc901de057e6e451c979853
dir: /sys/src/libbio/brdline.c/
#include <u.h> #include <libc.h> #include <bio.h> void* Brdline(Biobufhdr *bp, int delim) { char *ip, *ep; int i, j; i = -bp->icount; if(i == 0) { /* * eof or other error */ if(bp->state != Bractive) { if(bp->state == Bracteof) bp->state = Bractive; bp->rdline = 0; bp->gbuf = bp->ebuf; return 0; } } /* * first try in remainder of buffer (gbuf doesn't change) */ ip = (char*)bp->ebuf - i; ep = memchr(ip, delim, i); if(ep) { j = (ep - ip) + 1; bp->rdline = j; bp->icount += j; return ip; } /* * copy data to beginning of buffer */ if(i < bp->bsize) memmove(bp->bbuf, ip, i); bp->gbuf = bp->bbuf; /* * append to buffer looking for the delim */ ip = (char*)bp->bbuf + i; while(i < bp->bsize) { j = bp->iof(bp, ip, bp->bsize-i); if(j < 0) Berror(bp, "read error: %r"); if(j <= 0) { /* * end of file with no delim */ memmove(bp->ebuf-i, bp->bbuf, i); bp->rdline = i; bp->icount = -i; bp->gbuf = bp->ebuf-i; return 0; } bp->offset += j; i += j; ep = memchr(ip, delim, j); if(ep) { /* * found in new piece * copy back up and reset everything */ ip = (char*)bp->ebuf - i; if(i < bp->bsize){ memmove(ip, bp->bbuf, i); bp->gbuf = (uchar*)ip; } j = (ep - (char*)bp->bbuf) + 1; bp->rdline = j; bp->icount = j - i; return ip; } ip += j; } /* * full buffer without finding */ bp->rdline = bp->bsize; bp->icount = -bp->bsize; bp->gbuf = bp->bbuf; return 0; } int Blinelen(Biobufhdr *bp) { return bp->rdline; }