2 * Sherlock Library -- Fast Buffered I/O on Memory Streams
4 * (c) 1997--2000 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"
19 struct msblock *first;
29 fbmem_refill(struct fastbuf *f)
31 struct memstream *s = f->lldata;
32 struct msblock *b = f->llpos;
40 else if (f->buffer == b->data && f->bstop < b->data + b->size)
42 f->bstop = b->data + b->size;
54 f->buffer = f->bptr = b->data;
55 f->bufend = f->bstop = b->data + b->size;
61 fbmem_spout(struct fastbuf *f)
63 struct memstream *s = f->lldata;
64 struct msblock *b = f->llpos;
69 b->size = f->bptr - b->data;
70 if (b->size < s->blocksize)
74 bb = xmalloc(sizeof(struct msblock) + s->blocksize);
81 f->buffer = f->bptr = f->bstop = bb->data;
82 f->bufend = bb->data + s->blocksize;
87 fbmem_seek(struct fastbuf *f, sh_off_t pos, int whence)
89 struct memstream *m = f->lldata;
93 /* FIXME: Milan's quick hack to allow SEEK_END */
94 if (whence == SEEK_END)
96 for (b=m->first; b; b=b->next)
104 if (whence != SEEK_SET)
105 die("fbmem_seek: only SEEK_SET supported");
106 for (b=m->first; b; b=b->next)
108 if ((unsigned) pos <= p + b->size) /* <=, because we need to be able to seek just after file end */
112 f->bptr = b->data + (pos - p);
113 f->bufend = f->bstop = b->data + b->size;
119 die("fbmem_seek to invalid offset");
123 fbmem_close(struct fastbuf *f)
125 struct memstream *m = f->lldata;
140 fbmem_create(unsigned blocksize)
142 struct fastbuf *f = xmalloc_zero(sizeof(struct fastbuf));
143 struct memstream *m = xmalloc_zero(sizeof(struct memstream));
145 m->blocksize = blocksize;
148 f->name = "<fbmem-write>";
150 f->spout = fbmem_spout;
151 f->close = fbmem_close;
156 fbmem_clone_read(struct fastbuf *b)
158 struct fastbuf *f = xmalloc_zero(sizeof(struct fastbuf));
159 struct memstream *s = b->lldata;
164 f->name = "<fbmem-read>";
166 f->refill = fbmem_refill;
167 f->seek = fbmem_seek;
168 f->close = fbmem_close;
176 struct fastbuf *w, *r;
180 r = fbmem_clone_read(w);
181 bwrite(w, "12345", 5);
182 bwrite(w, "12345", 5);
183 printf("<%d>", btell(w));
185 printf("<%d>", btell(w));
186 printf("<%d>", btell(r));
187 while ((t = bgetc(r)) >= 0)
189 printf("<%d>", btell(r));
190 bwrite(w, "12345", 5);
191 bwrite(w, "12345", 5);
192 printf("<%d>", btell(w));
195 printf("<!%d>", btell(r));
196 while ((t = bgetc(r)) >= 0)
199 printf("<!%d>", btell(r));
200 while ((t = bgetc(r)) >= 0)