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