2 * Sherlock Library -- Fast Buffered I/O
4 * (c) 1997--2000 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->buffer)
29 { /* Have something to flush */
30 if (f->bstop > f->buffer) /* Read data? */
32 f->bptr = f->bstop = f->buffer;
35 else /* Write data... */
40 inline void bsetpos(struct fastbuf *f, sh_off_t pos)
42 if (pos >= f->pos && (pos <= f->pos + (f->bptr - f->buffer) || pos <= f->pos + (f->bstop - f->buffer)))
43 f->bptr = f->buffer + (pos - f->pos);
47 f->seek(f, pos, SEEK_SET);
51 void bseek(struct fastbuf *f, sh_off_t pos, int whence)
56 return bsetpos(f, pos);
58 return bsetpos(f, btell(f) + pos);
61 f->seek(f, pos, SEEK_END);
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 int bgetw_slow(struct fastbuf *f)
102 #ifdef CPU_BIG_ENDIAN
103 return (w1 << 8) | w2;
105 return w1 | (w2 << 8);
109 u32 bgetl_slow(struct fastbuf *f)
111 u32 l = bgetc_slow(f);
112 #ifdef CPU_BIG_ENDIAN
113 l = (l << 8) | bgetc_slow(f);
114 l = (l << 8) | bgetc_slow(f);
115 return (l << 8) | bgetc_slow(f);
117 l = (bgetc_slow(f) << 8) | l;
118 l = (bgetc_slow(f) << 16) | l;
119 return (bgetc_slow(f) << 24) | l;
123 u64 bgetq_slow(struct fastbuf *f)
126 #ifdef CPU_BIG_ENDIAN
133 return ((u64) h << 32) | l;
136 u64 bget5_slow(struct fastbuf *f)
139 #ifdef CPU_BIG_ENDIAN
146 return ((u64) h << 32) | l;
149 void bputw_slow(struct fastbuf *f, uns w)
151 #ifdef CPU_BIG_ENDIAN
152 bputc_slow(f, w >> 8);
156 bputc_slow(f, w >> 8);
160 void bputl_slow(struct fastbuf *f, u32 l)
162 #ifdef CPU_BIG_ENDIAN
163 bputc_slow(f, l >> 24);
164 bputc_slow(f, l >> 16);
165 bputc_slow(f, l >> 8);
169 bputc_slow(f, l >> 8);
170 bputc_slow(f, l >> 16);
171 bputc_slow(f, l >> 24);
175 void bputq_slow(struct fastbuf *f, u64 q)
177 #ifdef CPU_BIG_ENDIAN
178 bputl_slow(f, q >> 32);
182 bputl_slow(f, q >> 32);
186 void bput5_slow(struct fastbuf *f, u64 o)
190 #ifdef CPU_BIG_ENDIAN
199 uns bread_slow(struct fastbuf *f, void *b, uns l, uns check)
204 uns k = f->bstop - f->bptr;
209 k = f->bstop - f->bptr;
215 memcpy(b, f->bptr, k);
221 if (check && total && l)
222 die("breadb: short read");
226 void bwrite_slow(struct fastbuf *f, void *b, uns l)
230 uns k = f->bufend - f->bptr;
235 k = f->bufend - f->bptr;
239 memcpy(f->bptr, b, k);
246 byte * /* Non-standard */
247 bgets(struct fastbuf *f, byte *b, uns l)
257 if (k == '\n' || k == EOF)
265 die("%s: Line too long", f->name);
269 bgets0(struct fastbuf *f, byte *b, uns l)
287 die("%s: Line too long", f->name);
291 bdirect_read_prepare(struct fastbuf *f, byte **buf)
295 if (f->bptr == f->bstop && !f->refill(f))
298 len = f->bstop - f->bptr;
303 bdirect_read_commit(struct fastbuf *f, byte *pos)
309 bdirect_write_prepare(struct fastbuf *f, byte **buf)
311 if (f->bptr == f->bufend)
314 return f->bufend - f->bptr;
318 bdirect_write_commit(struct fastbuf *f, byte *pos)