2 * UCW Library -- Fast Buffered I/O: Strings
4 * (c) 1997--2006 Martin Mares <mj@ucw.cz>
5 * (c) 2006 Pavel Charvat <pchar@ucw.cz>
7 * This software may be freely distributed and used according to the terms
8 * of the GNU Lesser General Public License.
12 #include "lib/fastbuf.h"
13 #include "lib/mempool.h"
15 byte * /* Non-standard */
16 bgets(struct fastbuf *f, byte *b, uns l)
20 uns src_len = bdirect_read_prepare(f, &src);
25 uns cnt = MIN(l, src_len);
26 for (uns i = cnt; i--;)
31 bdirect_read_commit(f, src);
36 if (unlikely(cnt == l))
37 die("%s: Line too long", f->name);
39 bdirect_read_commit(f, src);
40 src_len = bdirect_read_prepare(f, &src);
49 bgets_nodie(struct fastbuf *f, byte *b, uns l)
52 byte *src, *start = b;
53 uns src_len = bdirect_read_prepare(f, &src);
58 uns cnt = MIN(l, src_len);
59 for (uns i = cnt; i--;)
64 bdirect_read_commit(f, src);
69 bdirect_read_commit(f, src);
73 src_len = bdirect_read_prepare(f, &src);
82 bgets_bb(struct fastbuf *f, bb_t *bb)
85 uns src_len = bdirect_read_prepare(f, &src);
90 uns len = 0, buf_len = bb->len;
93 uns cnt = MIN(src_len, buf_len);
94 for (uns i = cnt; i--;)
99 bdirect_read_commit(f, src);
107 bdirect_read_commit(f, src);
108 src_len = bdirect_read_prepare(f, &src);
114 bb_do_grow(bb, len + 1);
116 buf_len = bb->len - len;
124 return buf - bb->ptr;
128 bgets_mp(struct fastbuf *f, struct mempool *mp)
131 uns src_len = bdirect_read_prepare(f, &src);
134 #define BLOCK_SIZE (4096 - sizeof(void *))
137 byte data[BLOCK_SIZE];
139 uns sum = 0, buf_len = BLOCK_SIZE, cnt;
140 struct block first_block, *new_block = &first_block;
141 byte *buf = new_block->data;
144 cnt = MIN(src_len, buf_len);
145 for (uns i = cnt; i--;)
150 bdirect_read_commit(f, src);
157 bdirect_read_commit(f, src);
158 src_len = bdirect_read_prepare(f, &src);
164 new_block->prev = blocks;
166 sum += buf_len = BLOCK_SIZE;
167 new_block = alloca(sizeof(struct block));
168 buf = new_block->data;
175 uns len = buf - new_block->data;
176 byte *result = mp_alloc(mp, sum + len + 1) + sum;
178 memcpy(result, new_block->data, len);
181 result -= BLOCK_SIZE;
182 memcpy(result, blocks->data, BLOCK_SIZE);
183 blocks = blocks->prev;
190 bgets_stk_init(struct bgets_stk_struct *s)
192 s->src_len = bdirect_read_prepare(s->f, &s->src);
206 bgets_stk_step(struct bgets_stk_struct *s)
208 byte *buf = s->cur_buf;
209 uns buf_len = s->cur_len;
212 memcpy( s->cur_buf, s->old_buf, s->old_len);
214 buf_len -= s->old_len;
218 uns cnt = MIN(s->src_len, buf_len);
219 for (uns i = cnt; i--;)
224 bdirect_read_commit(s->f, s->src);
229 if (cnt == s->src_len)
231 bdirect_read_commit(s->f, s->src);
232 s->src_len = bdirect_read_prepare(s->f, &s->src);
238 s->old_len = s->cur_len;
239 s->old_buf = s->cur_buf;
253 bgets0(struct fastbuf *f, byte *b, uns l)
257 uns src_len = bdirect_read_prepare(f, &src);
262 uns cnt = MIN(l, src_len);
263 for (uns i = cnt; i--;)
268 bdirect_read_commit(f, src);
273 if (unlikely(cnt == l))
274 die("%s: Line too long", f->name);
276 bdirect_read_commit(f, src);
277 src_len = bdirect_read_prepare(f, &src);