]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libbio/brdline.c
mkpaqfs(8): allow setting compression level
[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 = bp->iof(bp, ip, bp->bsize-i);
50                 if(j < 0)
51                         Berror(bp, "read error: %r");
52                 if(j <= 0) {
53                         /*
54                          * end of file with no delim
55                          */
56                         memmove(bp->ebuf-i, bp->bbuf, i);
57                         bp->rdline = i;
58                         bp->icount = -i;
59                         bp->gbuf = bp->ebuf-i;
60                         return 0;
61                 }
62                 bp->offset += j;
63                 i += j;
64                 ep = memchr(ip, delim, j);
65                 if(ep) {
66                         /*
67                          * found in new piece
68                          * copy back up and reset everything
69                          */
70                         ip = (char*)bp->ebuf - i;
71                         if(i < bp->bsize){
72                                 memmove(ip, bp->bbuf, i);
73                                 bp->gbuf = (uchar*)ip;
74                         }
75                         j = (ep - (char*)bp->bbuf) + 1;
76                         bp->rdline = j;
77                         bp->icount = j - i;
78                         return ip;
79                 }
80                 ip += j;
81         }
82
83         /*
84          * full buffer without finding
85          */
86         bp->rdline = bp->bsize;
87         bp->icount = -bp->bsize;
88         bp->gbuf = bp->bbuf;
89         return 0;
90 }
91
92 int
93 Blinelen(Biobufhdr *bp)
94 {
95
96         return bp->rdline;
97 }