]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libbio/brdline.c
Import sources from 2011-03-30 iso image
[plan9front.git] / sys / src / libbio / brdline.c
1 #include        <u.h>
2 #include        <libc.h>
3 #include        <bio.h>
4
5 void*
6 Brdline(Biobufhdr *bp, int delim)
7 {
8         char *ip, *ep;
9         int i, j;
10
11         i = -bp->icount;
12         if(i == 0) {
13                 /*
14                  * eof or other error
15                  */
16                 if(bp->state != Bractive) {
17                         if(bp->state == Bracteof)
18                                 bp->state = Bractive;
19                         bp->rdline = 0;
20                         bp->gbuf = bp->ebuf;
21                         return 0;
22                 }
23         }
24
25         /*
26          * first try in remainder of buffer (gbuf doesn't change)
27          */
28         ip = (char*)bp->ebuf - i;
29         ep = memchr(ip, delim, i);
30         if(ep) {
31                 j = (ep - ip) + 1;
32                 bp->rdline = j;
33                 bp->icount += j;
34                 return ip;
35         }
36
37         /*
38          * copy data to beginning of buffer
39          */
40         if(i < bp->bsize)
41                 memmove(bp->bbuf, ip, i);
42         bp->gbuf = bp->bbuf;
43
44         /*
45          * append to buffer looking for the delim
46          */
47         ip = (char*)bp->bbuf + i;
48         while(i < bp->bsize) {
49                 j = read(bp->fid, ip, bp->bsize-i);
50                 if(j <= 0) {
51                         /*
52                          * end of file with no delim
53                          */
54                         memmove(bp->ebuf-i, bp->bbuf, i);
55                         bp->rdline = i;
56                         bp->icount = -i;
57                         bp->gbuf = bp->ebuf-i;
58                         return 0;
59                 }
60                 bp->offset += j;
61                 i += j;
62                 ep = memchr(ip, delim, j);
63                 if(ep) {
64                         /*
65                          * found in new piece
66                          * copy back up and reset everything
67                          */
68                         ip = (char*)bp->ebuf - i;
69                         if(i < bp->bsize){
70                                 memmove(ip, bp->bbuf, i);
71                                 bp->gbuf = (uchar*)ip;
72                         }
73                         j = (ep - (char*)bp->bbuf) + 1;
74                         bp->rdline = j;
75                         bp->icount = j - i;
76                         return ip;
77                 }
78                 ip += j;
79         }
80
81         /*
82          * full buffer without finding
83          */
84         bp->rdline = bp->bsize;
85         bp->icount = -bp->bsize;
86         bp->gbuf = bp->bbuf;
87         return 0;
88 }
89
90 int
91 Blinelen(Biobufhdr *bp)
92 {
93
94         return bp->rdline;
95 }