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 if (whence != SEEK_SET)
94 die("fbmem_seek: only SEEK_SET supported");
95 for (b=m->first; b; b=b->next)
97 if ((unsigned) pos <= p + b->size) /* <=, because we need to be able to seek just after file end */
101 f->bptr = b->data + (pos - p);
102 f->bufend = f->bstop = b->data + b->size;
108 die("fbmem_seek to invalid offset");
112 fbmem_close(struct fastbuf *f)
114 struct memstream *m = f->lldata;
129 fbmem_create(unsigned blocksize)
131 struct fastbuf *f = xmalloc_zero(sizeof(struct fastbuf));
132 struct memstream *m = xmalloc_zero(sizeof(struct memstream));
134 m->blocksize = blocksize;
137 f->name = "<fbmem-write>";
139 f->spout = fbmem_spout;
140 f->close = fbmem_close;
145 fbmem_clone_read(struct fastbuf *b)
147 struct fastbuf *f = xmalloc_zero(sizeof(struct fastbuf));
148 struct memstream *s = b->lldata;
153 f->name = "<fbmem-read>";
155 f->refill = fbmem_refill;
156 f->seek = fbmem_seek;
157 f->close = fbmem_close;
165 struct fastbuf *w, *r;
169 r = fbmem_clone_read(w);
170 bwrite(w, "12345", 5);
171 bwrite(w, "12345", 5);
172 printf("<%d>", btell(w));
174 printf("<%d>", btell(w));
175 printf("<%d>", btell(r));
176 while ((t = bgetc(r)) >= 0)
178 printf("<%d>", btell(r));
179 bwrite(w, "12345", 5);
180 bwrite(w, "12345", 5);
181 printf("<%d>", btell(w));
184 printf("<!%d>", btell(r));
185 while ((t = bgetc(r)) >= 0)
188 printf("<!%d>", btell(r));
189 while ((t = bgetc(r)) >= 0)