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 "ucw/fastbuf.h"
12 #include "ucw/respool.h"
17 void bclose(struct fastbuf *f)
29 void bflush(struct fastbuf *f)
31 if (f->bptr > f->bstop)
33 else if (f->bstop > f->buffer)
34 f->bptr = f->bstop = f->buffer;
37 inline void bsetpos(struct fastbuf *f, ucw_off_t pos)
39 /* We can optimize seeks only when reading */
40 if (pos >= f->pos - (f->bstop - f->buffer) && pos <= f->pos)
41 f->bptr = f->bstop + (pos - f->pos);
45 if (!f->seek || !f->seek(f, pos, SEEK_SET))
46 die("bsetpos: stream not seekable");
50 void bseek(struct fastbuf *f, ucw_off_t pos, int whence)
55 return bsetpos(f, pos);
57 return bsetpos(f, btell(f) + pos);
60 if (!f->seek || !f->seek(f, pos, SEEK_END))
61 die("bseek: stream not seekable");
64 die("bseek: invalid whence=%d", whence);
68 int bgetc_slow(struct fastbuf *f)
70 if (f->bptr < f->bstop)
77 int bpeekc_slow(struct fastbuf *f)
79 if (f->bptr < f->bstop)
86 void bputc_slow(struct fastbuf *f, uns c)
88 if (f->bptr >= f->bufend)
93 uns bread_slow(struct fastbuf *f, void *b, uns l, uns check)
98 uns k = f->bstop - f->bptr;
103 k = f->bstop - f->bptr;
109 memcpy(b, f->bptr, k);
115 if (check && total && l)
116 die("breadb: short read");
120 void bwrite_slow(struct fastbuf *f, const void *b, uns l)
124 uns k = f->bufend - f->bptr;
129 k = f->bufend - f->bptr;
133 memcpy(f->bptr, b, k);
141 bbcopy_slow(struct fastbuf *f, struct fastbuf *t, uns l)
146 uns favail, tavail, n;
148 favail = bdirect_read_prepare(f, &fptr);
153 die("bbcopy: source exhausted");
155 tavail = bdirect_write_prepare(t, &tptr);
158 memcpy(tptr, fptr, n);
159 bdirect_read_commit(f, fptr + n);
160 bdirect_write_commit(t, tptr + n);
167 bconfig(struct fastbuf *f, uns item, int value)
169 return f->config ? f->config(f, item, value) : -1;
173 brewind(struct fastbuf *f)
180 bskip_slow(struct fastbuf *f, uns len)
185 uns l = bdirect_read_prepare(f, &buf);
189 bdirect_read_commit(f, buf+l);
196 bfilesize(struct fastbuf *f)
200 ucw_off_t pos = btell(f);
202 if (!f->seek(f, 0, SEEK_END))
204 ucw_off_t len = btell(f);
212 fb_res_detach(struct resource *r)
214 struct fastbuf *f = r->priv;
219 fb_res_free(struct resource *r)
221 struct fastbuf *f = r->priv;
227 fb_res_dump(struct resource *r)
229 struct fastbuf *f = r->priv;
230 printf(" name=%s", f->name);
233 static const struct res_class fb_res_class = {
235 .detach = fb_res_detach,
241 fb_tie(struct fastbuf *f)
243 f->res = res_new(&fb_res_class, f);