]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libbio/bread.c
bio: add support for custom I/O handler via Biofn
[plan9front.git] / sys / src / libbio / bread.c
1 #include        <u.h>
2 #include        <libc.h>
3 #include        <bio.h>
4
5 long
6 Bread(Biobufhdr *bp, void *ap, long count)
7 {
8         long c;
9         uchar *p;
10         int i, n, ic;
11
12         p = ap;
13         c = count;
14         ic = bp->icount;
15
16         while(c > 0) {
17                 n = -ic;
18                 if(n > c)
19                         n = c;
20                 if(n == 0) {
21                         if(bp->state != Bractive)
22                                 break;
23                         i = bp->iof(bp, bp->bbuf, bp->bsize);
24                         if(i <= 0) {
25                                 bp->state = Bracteof;
26                                 if(i < 0) {
27                                         Berror(bp, "read error: %r");
28                                         bp->state = Binactive;
29                                 }
30                                 break;
31                         }
32                         bp->gbuf = bp->bbuf;
33                         bp->offset += i;
34                         if(i < bp->bsize) {
35                                 memmove(bp->ebuf-i, bp->bbuf, i);
36                                 bp->gbuf = bp->ebuf-i;
37                         }
38                         ic = -i;
39                         continue;
40                 }
41                 memmove(p, bp->ebuf+ic, n);
42                 c -= n;
43                 ic += n;
44                 p += n;
45         }
46         bp->icount = ic;
47         if(count == c && bp->state == Binactive)
48                 return -1;
49         return count-c;
50 }