Blob


1 #include "lib9.h"
2 #include <bio.h>
4 static char*
5 badd(char *p, int *np, char *data, int ndata, int delim, int nulldelim)
6 {
7 int n;
9 n = *np;
10 p = realloc(p, n+ndata+1);
11 if(p){
12 memmove(p+n, data, ndata);
13 n += ndata;
14 if(n>0 && nulldelim && p[n-1]==delim)
15 p[--n] = '\0';
16 else
17 p[n] = '\0';
18 *np = n;
19 }
20 return p;
21 }
23 char*
24 Brdstr(Biobuf *bp, int delim, int nulldelim)
25 {
26 char *ip, *ep, *p;
27 int i, j;
29 i = -bp->icount;
30 bp->rdline = 0;
31 if(i == 0) {
32 /*
33 * eof or other error
34 */
35 if(bp->state != Bractive) {
36 if(bp->state == Bracteof)
37 bp->state = Bractive;
38 bp->gbuf = bp->ebuf;
39 return nil;
40 }
41 }
43 /*
44 * first try in remainder of buffer (gbuf doesn't change)
45 */
46 ip = (char*)bp->ebuf - i;
47 ep = memchr(ip, delim, i);
48 if(ep) {
49 j = (ep - ip) + 1;
50 bp->icount += j;
51 return badd(nil, &bp->rdline, ip, j, delim, nulldelim);
52 }
54 /*
55 * copy data to beginning of buffer
56 */
57 if(i < bp->bsize)
58 memmove(bp->bbuf, ip, i);
59 bp->gbuf = bp->bbuf;
61 /*
62 * append to buffer looking for the delim
63 */
64 p = nil;
65 for(;;){
66 ip = (char*)bp->bbuf + i;
67 while(i < bp->bsize) {
68 j = read(bp->fid, ip, bp->bsize-i);
69 if(j <= 0 && i == 0)
70 return p;
71 if(j <= 0 && i > 0){
72 /*
73 * end of file but no delim. pretend we got a delim
74 * by making the delim \0 and smashing it with nulldelim.
75 */
76 j = 1;
77 ep = ip;
78 delim = '\0';
79 nulldelim = 1;
80 *ep = delim; /* there will be room for this */
81 }else{
82 bp->offset += j;
83 ep = memchr(ip, delim, j);
84 }
85 i += j;
86 if(ep) {
87 /*
88 * found in new piece
89 * copy back up and reset everything
90 */
91 ip = (char*)bp->ebuf - i;
92 if(i < bp->bsize){
93 memmove(ip, bp->bbuf, i);
94 bp->gbuf = (unsigned char*)ip;
95 }
96 j = (ep - (char*)bp->bbuf) + 1;
97 bp->icount = j - i;
98 return badd(p, &bp->rdline, ip, j, delim, nulldelim);
99 }
100 ip += j;
103 /*
104 * full buffer without finding; add to user string and continue
105 */
106 p = badd(p, &bp->rdline, (char*)bp->bbuf, bp->bsize, 0, 0);
107 i = 0;
108 bp->icount = 0;
109 bp->gbuf = bp->ebuf;