2 * Sherlock Library -- Fast Buffered I/O
4 * (c) 1997--2004 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"
15 void bclose(struct fastbuf *f)
25 void bflush(struct fastbuf *f)
27 if (f->bptr > f->bstop)
29 else if (f->bstop > f->buffer)
30 f->bptr = f->bstop = f->buffer;
33 inline void bsetpos(struct fastbuf *f, sh_off_t pos)
35 /* We can optimize seeks only when reading */
36 if (pos >= f->pos - (f->bstop - f->buffer) && pos <= f->pos)
37 f->bptr = f->bstop + (pos - f->pos);
41 f->seek(f, pos, SEEK_SET);
45 void bseek(struct fastbuf *f, sh_off_t pos, int whence)
50 return bsetpos(f, pos);
52 return bsetpos(f, btell(f) + pos);
55 f->seek(f, pos, SEEK_END);
58 die("bseek: invalid whence=%d", whence);
62 int bgetc_slow(struct fastbuf *f)
64 if (f->bptr < f->bstop)
71 int bpeekc_slow(struct fastbuf *f)
73 if (f->bptr < f->bstop)
80 void bputc_slow(struct fastbuf *f, uns c)
82 if (f->bptr >= f->bufend)
87 int bgetw_slow(struct fastbuf *f)
97 return (w1 << 8) | w2;
99 return w1 | (w2 << 8);
103 u32 bgetl_slow(struct fastbuf *f)
105 u32 l = bgetc_slow(f);
106 #ifdef CPU_BIG_ENDIAN
107 l = (l << 8) | bgetc_slow(f);
108 l = (l << 8) | bgetc_slow(f);
109 return (l << 8) | bgetc_slow(f);
111 l = (bgetc_slow(f) << 8) | l;
112 l = (bgetc_slow(f) << 16) | l;
113 return (bgetc_slow(f) << 24) | l;
117 u64 bgetq_slow(struct fastbuf *f)
120 #ifdef CPU_BIG_ENDIAN
127 return ((u64) h << 32) | l;
130 u64 bget5_slow(struct fastbuf *f)
133 #ifdef CPU_BIG_ENDIAN
140 return ((u64) h << 32) | l;
143 void bputw_slow(struct fastbuf *f, uns w)
145 #ifdef CPU_BIG_ENDIAN
146 bputc_slow(f, w >> 8);
150 bputc_slow(f, w >> 8);
154 void bputl_slow(struct fastbuf *f, u32 l)
156 #ifdef CPU_BIG_ENDIAN
157 bputc_slow(f, l >> 24);
158 bputc_slow(f, l >> 16);
159 bputc_slow(f, l >> 8);
163 bputc_slow(f, l >> 8);
164 bputc_slow(f, l >> 16);
165 bputc_slow(f, l >> 24);
169 void bputq_slow(struct fastbuf *f, u64 q)
171 #ifdef CPU_BIG_ENDIAN
172 bputl_slow(f, q >> 32);
176 bputl_slow(f, q >> 32);
180 void bput5_slow(struct fastbuf *f, u64 o)
184 #ifdef CPU_BIG_ENDIAN
193 uns bread_slow(struct fastbuf *f, void *b, uns l, uns check)
198 uns k = f->bstop - f->bptr;
203 k = f->bstop - f->bptr;
209 memcpy(b, f->bptr, k);
215 if (check && total && l)
216 die("breadb: short read");
220 void bwrite_slow(struct fastbuf *f, void *b, uns l)
224 uns k = f->bufend - f->bptr;
229 k = f->bufend - f->bptr;
233 memcpy(f->bptr, b, k);
240 byte * /* Non-standard */
241 bgets(struct fastbuf *f, byte *b, uns l)
251 if (k == '\n' || k < 0)
259 die("%s: Line too long", f->name);
263 bgets_nodie(struct fastbuf *f, byte *b, uns l)
274 if (k == '\n' || k < 0)
286 bgets0(struct fastbuf *f, byte *b, uns l)
304 die("%s: Line too long", f->name);
308 bbcopy_slow(struct fastbuf *f, struct fastbuf *t, uns l)
313 uns favail, tavail, n;
315 favail = bdirect_read_prepare(f, &fptr);
320 die("bbcopy: source exhausted");
322 tavail = bdirect_write_prepare(t, &tptr);
325 memcpy(tptr, fptr, n);
326 bdirect_read_commit(f, fptr + n);
327 bdirect_write_commit(t, tptr + n);
334 bconfig(struct fastbuf *f, uns item, int value)
336 return f->config ? f->config(f, item, value) : -1;
340 brewind(struct fastbuf *f)
347 bskip_slow(struct fastbuf *f, uns len)
352 uns l = bdirect_read_prepare(f, &buf);
356 bdirect_read_commit(f, buf+l);
363 bfilesize(struct fastbuf *f)
367 sh_off_t pos = btell(f);
368 bseek(f, 0, SEEK_END);
369 sh_off_t len = btell(f);