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