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 "ucw/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, ucw_off_t pos, int whence)
52 ASSERT(FB_GBUF(b)->last_written); /* Seeks allowed only in read mode */
53 ucw_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;
88 fbgrow_reset(struct fastbuf *b)
90 b->bptr = b->bstop = b->buffer;
92 FB_GBUF(b)->last_written = NULL;
96 fbgrow_rewind(struct fastbuf *b)
98 if (!FB_GBUF(b)->last_written)
100 /* Last operation was a write, so remember the end position */
101 FB_GBUF(b)->last_written = b->bptr;
104 b->bstop = FB_GBUF(b)->last_written;
105 b->pos = b->bstop - b->buffer;
115 f = fbgrow_create(3);
116 for (uns i=0; i<5; i++)
119 bwrite(f, "12345", 5);
120 bwrite(f, "12345", 5);
121 printf("<%d>", (int)btell(f));
123 printf("<%d>", (int)btell(f));
125 printf("<%d>", (int)btell(f));
126 while ((t = bgetc(f)) != ~0U)
128 printf("<%d>", (int)btell(f));
130 bseek(f, -1, SEEK_END);
131 printf("<%d>", (int)btell(f));
132 while ((t = bgetc(f)) != ~0U)
134 printf("<%d>\n", (int)btell(f));