From 2668e862ad13dfb955249939f2b61aaee05c949c Mon Sep 17 00:00:00 2001 From: Pavel Charvat Date: Tue, 13 May 2014 09:44:38 +0200 Subject: [PATCH] Null fastbuf: Implemented a new "/dev/null"-like fastbuf. --- ucw/Makefile | 11 ++++--- ucw/fastbuf.h | 20 ++++++++++++ ucw/fb-null.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++ ucw/fb-null.t | 3 ++ 4 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 ucw/fb-null.c create mode 100644 ucw/fb-null.t diff --git a/ucw/Makefile b/ucw/Makefile index c098ce2f..5a13a35c 100644 --- a/ucw/Makefile +++ b/ucw/Makefile @@ -17,7 +17,7 @@ LIBUCW_MODS= \ conf-context conf-alloc conf-dump conf-input conf-intr conf-journal conf-parse conf-section conf-getopt \ ipaccess \ fastbuf ff-binary ff-string ff-printf ff-unicode ff-varint ff-stkstring \ - fb-file fb-mem fb-temp tempfile fb-mmap fb-limfd fb-buffer fb-grow fb-pool fb-atomic fb-param fb-socket fb-multi \ + fb-file fb-mem fb-temp tempfile fb-mmap fb-limfd fb-buffer fb-grow fb-pool fb-atomic fb-param fb-socket fb-multi fb-null \ char-cat char-upper char-lower unicode varint stkstring \ wildmatch regex \ prime primetable random \ @@ -137,9 +137,10 @@ $(o)/ucw/opt-test: $(o)/ucw/opt-test.o $(LIBUCW) TESTS+=$(addprefix $(o)/ucw/,regex.test unicode.test hash-test.test mempool.test stkstring.test \ slists.test bbuf.test kmp-test.test getopt.test ff-unicode.test eltpool.test \ - fb-socket.test trie-test.test string.test sha1.test asort-test.test binheap-test.test \ - redblack-test.test fb-file.test fb-grow.test fb-pool.test fb-atomic.test \ - fb-limfd.test fb-temp.test fb-mem.test fb-buffer.test fb-mmap.test fb-multi.test url.test strtonum-test.test \ + trie-test.test string.test sha1.test asort-test.test binheap-test.test \ + fb-file.test fb-socket.test fb-grow.test fb-pool.test fb-atomic.test fb-limfd.test fb-temp.test \ + fb-mem.test fb-buffer.test fb-mmap.test fb-multi.test fb-null.test \ + redblack-test.test url.test strtonum-test.test \ gary.test time.test crc.test signames.test md5.test bitops.test opt.test) $(o)/ucw/varint.test: $(o)/ucw/varint-t @@ -164,7 +165,7 @@ $(o)/ucw/binheap-test.test: $(o)/ucw/binheap-test $(o)/ucw/redblack-test.test: $(o)/ucw/redblack-test $(o)/ucw/strtonum-test.test: $(o)/ucw/strtonum-test $(addprefix $(o)/ucw/fb-,file.test grow.test pool.test socket.test atomic.test \ - limfd.test temp.test mem.test buffer.test mmap.test multi.test): %.test: %-t + limfd.test temp.test mem.test buffer.test mmap.test multi.test null.test): %.test: %-t $(o)/ucw/url.test: $(o)/ucw/url-t $(o)/ucw/gary.test: $(o)/ucw/gary-t $(o)/ucw/time.test: $(o)/ucw/time-conf-t diff --git a/ucw/fastbuf.h b/ucw/fastbuf.h index d2904433..0fa48a43 100644 --- a/ucw/fastbuf.h +++ b/ucw/fastbuf.h @@ -3,6 +3,7 @@ * * (c) 1997--2011 Martin Mares * (c) 2004 Robert Spalek + * (c) 2014 Pavel Charvat * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -542,6 +543,25 @@ static inline void fbatomic_commit(struct fastbuf *b) fbatomic_internal_write(b); } +/*** === Null fastbufs ***/ + +/** + * Creates a new "/dev/null"-like fastbuf. + * Any read attempt returns an EOF, any write attempt is silently ignored. + **/ +struct fastbuf *fbnull_open(uns bufsize); + +/** + * Can be used by any back-end to switch it to the null mode. + * You need to provide at least one byte long buffer for writing. + **/ +void fbnull_start(struct fastbuf *b, byte *buf, uns bufsize); + +/** + * Checks whether a fastbuf has been switched to the null mode. + **/ +bool fbnull_test(struct fastbuf *b); + /*** * === Fastbufs atop other fastbufs [[fbmulti]] * diff --git a/ucw/fb-null.c b/ucw/fb-null.c new file mode 100644 index 00000000..6f0a40a2 --- /dev/null +++ b/ucw/fb-null.c @@ -0,0 +1,84 @@ +/* + * UCW Library -- Null fastbuf + * + * (c) 2014 Pavel Charvat + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + +#include +#include + +#include + +static void fbnull_close(struct fastbuf *b) +{ + xfree(b); +} + +struct fastbuf *fbnull_open(uns bufsize) +{ + struct fastbuf *b = xmalloc(sizeof(*b) + bufsize); + bzero(b, sizeof(*b)); + b->close = fbnull_close; + fbnull_start(b, (byte *)(b + 1), bufsize); + return b; +} + +static int fbnull_refill(struct fastbuf *b UNUSED) +{ + return 0; +} + +static void fbnull_spout(struct fastbuf *b) +{ + b->pos += b->bptr - b->bstop; + b->bptr = b->bstop; +} + +static int fbnull_seek(struct fastbuf *b, ucw_off_t pos, int whence) +{ + b->pos = (whence == SEEK_END) ? 0 : pos; + b->bptr = b->bstop; + return 1; +} + +void fbnull_start(struct fastbuf *b, byte *buf, uns bufsize) +{ + ASSERT(buf && bufsize); + b->pos = btell(b); + b->buffer = b->bptr = b->bstop = buf; + b->bufend = buf + bufsize; + b->refill = fbnull_refill; + b->spout = fbnull_spout; + b->seek = fbnull_seek; + b->can_overwrite_buffer = 2; +} + +bool fbnull_test(struct fastbuf *b) +{ + return b->refill == fbnull_refill; +} + +#ifdef TEST +int main(void) +{ + struct fastbuf *b = fbnull_open(7); + for (uns i = 0; i < 100; i++) + { + if (btell(b) != i * 10) + ASSERT(0); + if (bgetc(b) >= 0) + ASSERT(0); + bputs(b, "0123456789"); + bflush(b); + } + if (bfilesize(b) != 0) + ASSERT(0); + if (btell(b) != 100 * 10) + ASSERT(0); + bclose(b); + return 0; +} +#endif diff --git a/ucw/fb-null.t b/ucw/fb-null.t new file mode 100644 index 00000000..c5be1563 --- /dev/null +++ b/ucw/fb-null.t @@ -0,0 +1,3 @@ +# Tests for fb-null.c + +Run: ../obj/ucw/fb-null-t -- 2.39.2