2 * UCW Library -- Fast Buffered I/O
4 * (c) 1997--2007 Martin Mares <mj@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
11 #include "lib/fastbuf.h"
16 void bclose(struct fastbuf *f)
26 void bflush(struct fastbuf *f)
28 if (f->bptr > f->bstop)
30 else if (f->bstop > f->buffer)
31 f->bptr = f->bstop = f->buffer;
34 inline void bsetpos(struct fastbuf *f, sh_off_t pos)
36 /* We can optimize seeks only when reading */
37 if (pos >= f->pos - (f->bstop - f->buffer) && pos <= f->pos)
38 f->bptr = f->bstop + (pos - f->pos);
42 if (!f->seek || !f->seek(f, pos, SEEK_SET))
43 die("bsetpos: stream not seekable");
47 void bseek(struct fastbuf *f, sh_off_t pos, int whence)
52 return bsetpos(f, pos);
54 return bsetpos(f, btell(f) + pos);
57 if (!f->seek || !f->seek(f, pos, SEEK_END))
58 die("bseek: stream not seekable");
61 die("bseek: invalid whence=%d", whence);
65 int bgetc_slow(struct fastbuf *f)
67 if (f->bptr < f->bstop)
74 int bpeekc_slow(struct fastbuf *f)
76 if (f->bptr < f->bstop)
83 void bputc_slow(struct fastbuf *f, uns c)
85 if (f->bptr >= f->bufend)
90 uns bread_slow(struct fastbuf *f, void *b, uns l, uns check)
95 uns k = f->bstop - f->bptr;
100 k = f->bstop - f->bptr;
106 memcpy(b, f->bptr, k);
112 if (check && total && l)
113 die("breadb: short read");
117 void bwrite_slow(struct fastbuf *f, const void *b, uns l)
121 uns k = f->bufend - f->bptr;
126 k = f->bufend - f->bptr;
130 memcpy(f->bptr, b, k);
138 bbcopy_slow(struct fastbuf *f, struct fastbuf *t, uns l)
143 uns favail, tavail, n;
145 favail = bdirect_read_prepare(f, &fptr);
150 die("bbcopy: source exhausted");
152 tavail = bdirect_write_prepare(t, &tptr);
155 memcpy(tptr, fptr, n);
156 bdirect_read_commit(f, fptr + n);
157 bdirect_write_commit(t, tptr + n);
164 bconfig(struct fastbuf *f, uns item, int value)
166 return f->config ? f->config(f, item, value) : -1;
170 brewind(struct fastbuf *f)
177 bskip_slow(struct fastbuf *f, uns len)
182 uns l = bdirect_read_prepare(f, &buf);
186 bdirect_read_commit(f, buf+l);
193 bfilesize(struct fastbuf *f)
197 sh_off_t pos = btell(f);
199 if (!f->seek(f, 0, SEEK_END))
201 sh_off_t len = btell(f);