X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Ffastbuf.c;h=be7e979015e0f797021cd9eb19c53ea68188f6de;hb=5a78c3505ae7fa76a061e26676450049ec5946d5;hp=1b89a813998d7db2aea31dd0789a09a138d17a75;hpb=3d2689a215b9041b1a5fe5577569771a55a73823;p=libucw.git diff --git a/lib/fastbuf.c b/lib/fastbuf.c index 1b89a813..be7e9790 100644 --- a/lib/fastbuf.c +++ b/lib/fastbuf.c @@ -1,7 +1,7 @@ /* - * Sherlock Library -- Fast Buffered I/O + * UCW Library -- Fast Buffered I/O * - * (c) 1997--2000 Martin Mares + * (c) 1997--2007 Martin Mares * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -10,6 +10,7 @@ #include "lib/lib.h" #include "lib/fastbuf.h" +#include #include void bclose(struct fastbuf *f) @@ -24,13 +25,10 @@ void bclose(struct fastbuf *f) void bflush(struct fastbuf *f) { - if (f->bptr != f->buffer) - { /* Have something to flush */ - if (f->bstop > f->buffer) /* Read data? */ - f->bptr = f->bstop = f->buffer; - else /* Write data... */ - f->spout(f); - } + if (f->bptr > f->bstop) + f->spout(f); + else if (f->bstop > f->buffer) + f->bptr = f->bstop = f->buffer; } inline void bsetpos(struct fastbuf *f, sh_off_t pos) @@ -41,7 +39,8 @@ inline void bsetpos(struct fastbuf *f, sh_off_t pos) else { bflush(f); - f->seek(f, pos, SEEK_SET); + if (!f->seek || !f->seek(f, pos, SEEK_SET)) + die("bsetpos: stream not seekable"); } } @@ -55,7 +54,8 @@ void bseek(struct fastbuf *f, sh_off_t pos, int whence) return bsetpos(f, btell(f) + pos); case SEEK_END: bflush(f); - f->seek(f, pos, SEEK_END); + if (!f->seek || !f->seek(f, pos, SEEK_END)) + die("bseek: stream not seekable"); break; default: die("bseek: invalid whence=%d", whence); @@ -67,7 +67,7 @@ int bgetc_slow(struct fastbuf *f) if (f->bptr < f->bstop) return *f->bptr++; if (!f->refill(f)) - return EOF; + return -1; return *f->bptr++; } @@ -76,7 +76,7 @@ int bpeekc_slow(struct fastbuf *f) if (f->bptr < f->bstop) return *f->bptr; if (!f->refill(f)) - return EOF; + return -1; return *f->bptr; } @@ -87,112 +87,6 @@ void bputc_slow(struct fastbuf *f, uns c) *f->bptr++ = c; } -int bgetw_slow(struct fastbuf *f) -{ - int w1, w2; - w1 = bgetc_slow(f); - if (w1 < 0) - return w1; - w2 = bgetc_slow(f); - if (w2 < 0) - return w2; -#ifdef CPU_BIG_ENDIAN - return (w1 << 8) | w2; -#else - return w1 | (w2 << 8); -#endif -} - -u32 bgetl_slow(struct fastbuf *f) -{ - u32 l = bgetc_slow(f); -#ifdef CPU_BIG_ENDIAN - l = (l << 8) | bgetc_slow(f); - l = (l << 8) | bgetc_slow(f); - return (l << 8) | bgetc_slow(f); -#else - l = (bgetc_slow(f) << 8) | l; - l = (bgetc_slow(f) << 16) | l; - return (bgetc_slow(f) << 24) | l; -#endif -} - -u64 bgetq_slow(struct fastbuf *f) -{ - u32 l, h; -#ifdef CPU_BIG_ENDIAN - h = bgetl_slow(f); - l = bgetl_slow(f); -#else - l = bgetl_slow(f); - h = bgetl_slow(f); -#endif - return ((u64) h << 32) | l; -} - -u64 bget5_slow(struct fastbuf *f) -{ - u32 l, h; -#ifdef CPU_BIG_ENDIAN - h = bgetc_slow(f); - l = bgetl_slow(f); -#else - l = bgetl_slow(f); - h = bgetc_slow(f); -#endif - return ((u64) h << 32) | l; -} - -void bputw_slow(struct fastbuf *f, uns w) -{ -#ifdef CPU_BIG_ENDIAN - bputc_slow(f, w >> 8); - bputc_slow(f, w); -#else - bputc_slow(f, w); - bputc_slow(f, w >> 8); -#endif -} - -void bputl_slow(struct fastbuf *f, u32 l) -{ -#ifdef CPU_BIG_ENDIAN - bputc_slow(f, l >> 24); - bputc_slow(f, l >> 16); - bputc_slow(f, l >> 8); - bputc_slow(f, l); -#else - bputc_slow(f, l); - bputc_slow(f, l >> 8); - bputc_slow(f, l >> 16); - bputc_slow(f, l >> 24); -#endif -} - -void bputq_slow(struct fastbuf *f, u64 q) -{ -#ifdef CPU_BIG_ENDIAN - bputl_slow(f, q >> 32); - bputl_slow(f, q); -#else - bputl_slow(f, q); - bputl_slow(f, q >> 32); -#endif -} - -void bput5_slow(struct fastbuf *f, u64 o) -{ - u32 hi = o >> 32; - u32 low = o; -#ifdef CPU_BIG_ENDIAN - bputc_slow(f, hi); - bputl_slow(f, low); -#else - bputl_slow(f, low); - bputc_slow(f, hi); -#endif -} - uns bread_slow(struct fastbuf *f, void *b, uns l, uns check) { uns total = 0; @@ -220,7 +114,7 @@ uns bread_slow(struct fastbuf *f, void *b, uns l, uns check) return total; } -void bwrite_slow(struct fastbuf *f, void *b, uns l) +void bwrite_slow(struct fastbuf *f, const void *b, uns l) { while (l) { @@ -240,76 +134,71 @@ void bwrite_slow(struct fastbuf *f, void *b, uns l) } } -byte * /* Non-standard */ -bgets(struct fastbuf *f, byte *b, uns l) +void +bbcopy_slow(struct fastbuf *f, struct fastbuf *t, uns l) { - byte *e = b + l - 1; - int k; - - k = bgetc(f); - if (k == EOF) - return NULL; - while (b < e) + while (l) { - if (k == '\n' || k == EOF) - { - *b = 0; - return b; - } - *b++ = k; - k = bgetc(f); - } - die("%s: Line too long", f->name); -} - -byte * -bgets0(struct fastbuf *f, byte *b, uns l) -{ - byte *e = b + l - 1; - int k; + byte *fptr, *tptr; + uns favail, tavail, n; - k = bgetc(f); - if (k == EOF) - return NULL; - while (b < e) - { - if (!k || k == EOF) + favail = bdirect_read_prepare(f, &fptr); + if (!favail) { - *b = 0; - return b; + if (l == ~0U) + return; + die("bbcopy: source exhausted"); } - *b++ = k; - k = bgetc(f); + tavail = bdirect_write_prepare(t, &tptr); + n = MIN(l, favail); + n = MIN(n, tavail); + memcpy(tptr, fptr, n); + bdirect_read_commit(f, fptr + n); + bdirect_write_commit(t, tptr + n); + if (l != ~0U) + l -= n; } - die("%s: Line too long", f->name); } int -bdirect_read_prepare(struct fastbuf *f, byte **buf) +bconfig(struct fastbuf *f, uns item, int value) { - if (f->bptr == f->bstop && !f->refill(f)) - return EOF; - *buf = f->bptr; - return f->bstop - f->bptr; + return f->config ? f->config(f, item, value) : -1; } void -bdirect_read_commit(struct fastbuf *f, byte *pos) +brewind(struct fastbuf *f) { - f->bptr = pos; + bflush(f); + bsetpos(f, 0); } int -bdirect_write_prepare(struct fastbuf *f, byte **buf) +bskip_slow(struct fastbuf *f, uns len) { - if (f->bptr == f->bufend) - f->spout(f); - *buf = f->bptr; - return f->bufend - f->bptr; + while (len) + { + byte *buf; + uns l = bdirect_read_prepare(f, &buf); + if (!l) + return 0; + l = MIN(l, len); + bdirect_read_commit(f, buf+l); + len -= l; + } + return 1; } -void -bdirect_write_commit(struct fastbuf *f, byte *pos) +sh_off_t +bfilesize(struct fastbuf *f) { - f->bptr = pos; + if (!f) + return 0; + sh_off_t pos = btell(f); + bflush(f); + if (!f->seek(f, 0, SEEK_END)) + return -1; + sh_off_t len = btell(f); + bsetpos(f, pos); + return len; }