2 * UCW Library -- Fast Buffered I/O on Growing Buffers
4 * (c) 2006 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"
20 #define FB_GBUF(f) ((struct fb_gbuf *)(f)->is_fastbuf)
23 fbgrow_refill(struct fastbuf *b)
25 if (b->bstop != FB_GBUF(b)->last_written)
27 /* There was an intervening flush */
28 b->bstop = FB_GBUF(b)->last_written;
29 b->pos = b->bstop - b->buffer;
32 /* We are at the end */
37 fbgrow_spout(struct fastbuf *b)
39 if (b->bptr >= b->bufend)
41 uns len = b->bufend - b->buffer;
42 b->buffer = xrealloc(b->buffer, 2*len);
43 b->bufend = b->buffer + 2*len;
45 b->bptr = b->buffer + len;
50 fbgrow_seek(struct fastbuf *b, sh_off_t pos, int whence)
52 ASSERT(FB_GBUF(b)->last_written); /* Seeks allowed only in read mode */
53 sh_off_t len = FB_GBUF(b)->last_written - b->buffer;
54 if (whence == SEEK_END)
56 ASSERT(pos >= 0 && pos <= len);
57 b->bptr = b->buffer + pos;
58 b->bstop = FB_GBUF(b)->last_written;
64 fbgrow_close(struct fastbuf *b)
71 fbgrow_create(unsigned basic_size)
73 struct fastbuf *b = xmalloc_zero(sizeof(struct fb_gbuf));
74 b->buffer = xmalloc(basic_size);
75 b->bufend = b->buffer + basic_size;
76 b->bptr = b->bstop = b->buffer;
78 b->refill = fbgrow_refill;
79 b->spout = fbgrow_spout;
80 b->seek = fbgrow_seek;
81 b->close = fbgrow_close;
82 b->can_overwrite_buffer = 1;
87 fbgrow_reset(struct fastbuf *b)
89 b->bptr = b->bstop = b->buffer;
91 FB_GBUF(b)->last_written = NULL;
95 fbgrow_rewind(struct fastbuf *b)
97 if (!FB_GBUF(b)->last_written)
99 /* Last operation was a write, so remember the end position */
100 FB_GBUF(b)->last_written = b->bptr;
103 b->bstop = FB_GBUF(b)->last_written;
104 b->pos = b->bstop - b->buffer;
114 f = fbgrow_create(3);
115 for (uns i=0; i<5; i++)
118 bwrite(f, "12345", 5);
119 bwrite(f, "12345", 5);
120 printf("<%d>", (int)btell(f));
122 printf("<%d>", (int)btell(f));
124 printf("<%d>", (int)btell(f));
125 while ((t = bgetc(f)) >= 0)
127 printf("<%d>", (int)btell(f));
129 bseek(f, -1, SEEK_END);
130 printf("<%d>", (int)btell(f));
131 while ((t = bgetc(f)) >= 0)
133 printf("<%d>\n", (int)btell(f));