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