X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Ffastbuf.h;h=777630c8b92d146c265cb4455d50a0bbe77fc312;hb=d1bd9f9a0c3d8286cdd85a5d413b59206ebc2fe1;hp=2ed05341dbcaa42b7268b09abd83de112024aba6;hpb=657ffd8da81aa31f2085324faac9a9a7b215bd68;p=libucw.git diff --git a/lib/fastbuf.h b/lib/fastbuf.h index 2ed05341..777630c8 100644 --- a/lib/fastbuf.h +++ b/lib/fastbuf.h @@ -2,6 +2,7 @@ * Sherlock Library -- Fast Buffered I/O * * (c) 1997--2004 Martin Mares + * (c) 2004 Robert Spalek * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -50,6 +51,17 @@ * as after the data you've read. * - The spout/refill hooks can change not only bptr and bstop, but also * the location of the buffer; fb-mem.c takes advantage of it. + * - In some cases, the user of the bdirect interface can be allowed to modify + * the data in the buffer to avoid unnecessary copying. If the back-end + * allows such modifications, it can set can_overwrite_buffer accordingly: + * * 0 if no modification is allowed, + * * 1 if the user can modify the buffer on the condition that + * the modifications will be undone before calling the next + * fastbuf operation + * * 2 if the user is allowed to overwrite the data in the buffer + * if bdirect_read_commit_modified() is called afterwards. + * In this case, the back-end must be prepared for trimming + * of the buffer which is done by the commit function. */ struct fastbuf { @@ -63,14 +75,16 @@ struct fastbuf { void (*seek)(struct fastbuf *, sh_off_t, int); /* Slow path for bseek(), buffer already flushed */ void (*close)(struct fastbuf *); /* Close the stream */ int (*config)(struct fastbuf *, uns, int); /* Configure the stream */ + int can_overwrite_buffer; /* Can the buffer be altered? (see discussion above) 0=never, 1=temporarily, 2=permanently */ }; /* FastIO on standard files (specify buffer size 0 to enable mmaping) */ -struct fastbuf *bopen(byte *name, uns mode, uns buffer); -struct fastbuf *bopen_tmp(uns buffer); -struct fastbuf *bfdopen(int fd, uns buffer); -struct fastbuf *bfdopen_shared(int fd, uns buffer); +struct fastbuf *bopen(byte *name, uns mode, uns buflen); +struct fastbuf *bopen_tmp(uns buflen); +struct fastbuf *bfdopen(int fd, uns buflen); +struct fastbuf *bfdopen_shared(int fd, uns buflen); +void bfilesync(struct fastbuf *b); /* FastIO on in-memory streams */ @@ -87,7 +101,7 @@ struct fastbuf *bopen_limited_fd(int fd, uns bufsize, uns limit); /* FastIO on static buffers */ -void fbbuf_init_read(struct fastbuf *f, byte *buffer, uns size); +void fbbuf_init_read(struct fastbuf *f, byte *buffer, uns size, uns can_overwrite); void fbbuf_init_write(struct fastbuf *f, byte *buffer, uns size); static inline uns fbbuf_count_written(struct fastbuf *f) @@ -108,6 +122,8 @@ void bflush(struct fastbuf *f); void bseek(struct fastbuf *f, sh_off_t pos, int whence); void bsetpos(struct fastbuf *f, sh_off_t pos); void brewind(struct fastbuf *f); +int bskip(struct fastbuf *f, uns len); +sh_off_t bfilesize(struct fastbuf *f); static inline sh_off_t btell(struct fastbuf *f) { @@ -140,11 +156,23 @@ static inline void bputc(struct fastbuf *f, uns c) bputc_slow(f, c); } +static inline uns +bavailr(struct fastbuf *f) +{ + return f->bstop - f->bptr; +} + +static inline uns +bavailw(struct fastbuf *f) +{ + return f->bufend - f->bptr; +} + int bgetw_slow(struct fastbuf *f); static inline int bgetw(struct fastbuf *f) { int w; - if (f->bptr + 2 <= f->bstop) + if (bavailr(f) >= 2) { w = GET_U16(f->bptr); f->bptr += 2; @@ -158,7 +186,7 @@ u32 bgetl_slow(struct fastbuf *f); static inline u32 bgetl(struct fastbuf *f) { u32 l; - if (f->bptr + 4 <= f->bstop) + if (bavailr(f) >= 4) { l = GET_U32(f->bptr); f->bptr += 4; @@ -172,7 +200,7 @@ u64 bgetq_slow(struct fastbuf *f); static inline u64 bgetq(struct fastbuf *f) { u64 l; - if (f->bptr + 8 <= f->bstop) + if (bavailr(f) >= 8) { l = GET_U64(f->bptr); f->bptr += 8; @@ -186,7 +214,7 @@ u64 bget5_slow(struct fastbuf *f); static inline u64 bget5(struct fastbuf *f) { u64 l; - if (f->bptr + 5 <= f->bstop) + if (bavailr(f) >= 5) { l = GET_U40(f->bptr); f->bptr += 5; @@ -199,7 +227,7 @@ static inline u64 bget5(struct fastbuf *f) void bputw_slow(struct fastbuf *f, uns w); static inline void bputw(struct fastbuf *f, uns w) { - if (f->bptr + 2 <= f->bufend) + if (bavailw(f) >= 2) { PUT_U16(f->bptr, w); f->bptr += 2; @@ -211,7 +239,7 @@ static inline void bputw(struct fastbuf *f, uns w) void bputl_slow(struct fastbuf *f, u32 l); static inline void bputl(struct fastbuf *f, u32 l) { - if (f->bptr + 4 <= f->bufend) + if (bavailw(f) >= 4) { PUT_U32(f->bptr, l); f->bptr += 4; @@ -223,7 +251,7 @@ static inline void bputl(struct fastbuf *f, u32 l) void bputq_slow(struct fastbuf *f, u64 l); static inline void bputq(struct fastbuf *f, u64 l) { - if (f->bptr + 8 <= f->bufend) + if (bavailw(f) >= 8) { PUT_U64(f->bptr, l); f->bptr += 8; @@ -235,7 +263,7 @@ static inline void bputq(struct fastbuf *f, u64 l) void bput5_slow(struct fastbuf *f, u64 l); static inline void bput5(struct fastbuf *f, u64 l) { - if (f->bptr + 5 <= f->bufend) + if (bavailw(f) >= 5) { PUT_U40(f->bptr, l); f->bptr += 5; @@ -247,7 +275,7 @@ static inline void bput5(struct fastbuf *f, u64 l) uns bread_slow(struct fastbuf *f, void *b, uns l, uns check); static inline uns bread(struct fastbuf *f, void *b, uns l) { - if (f->bptr + l <= f->bstop) + if (bavailr(f) >= l) { memcpy(b, f->bptr, l); f->bptr += l; @@ -259,7 +287,7 @@ static inline uns bread(struct fastbuf *f, void *b, uns l) static inline uns breadb(struct fastbuf *f, void *b, uns l) { - if (f->bptr + l <= f->bstop) + if (bavailr(f) >= l) { memcpy(b, f->bptr, l); f->bptr += l; @@ -272,7 +300,7 @@ static inline uns breadb(struct fastbuf *f, void *b, uns l) void bwrite_slow(struct fastbuf *f, void *b, uns l); static inline void bwrite(struct fastbuf *f, void *b, uns l) { - if (f->bptr + l <= f->bufend) + if (bavailw(f) >= l) { memcpy(f->bptr, b, l); f->bptr += l; @@ -308,8 +336,7 @@ void bbcopy_slow(struct fastbuf *f, struct fastbuf *t, uns l); static inline void bbcopy(struct fastbuf *f, struct fastbuf *t, uns l) { - if (f->bptr + l <= f->bstop && - t->bptr + l <= t->bufend) + if (bavailr(f) >= l && bavailw(t) >= l) { memcpy(t->bptr, f->bptr, l); t->bptr += l; @@ -337,7 +364,7 @@ bdirect_read_prepare(struct fastbuf *f, byte **buf) if (f->bptr == f->bstop && !f->refill(f)) return 0; *buf = f->bptr; - return f->bstop - f->bptr; + return bavailr(f); } static inline void @@ -346,13 +373,20 @@ bdirect_read_commit(struct fastbuf *f, byte *pos) f->bptr = pos; } +static inline void +bdirect_read_commit_modified(struct fastbuf *f, byte *pos) +{ + f->bptr = pos; + f->buffer = pos; /* Avoid seeking backwards in the buffer */ +} + static inline uns bdirect_write_prepare(struct fastbuf *f, byte **buf) { if (f->bptr == f->bufend) f->spout(f); *buf = f->bptr; - return f->bufend - f->bptr; + return bavailw(f); } static inline void