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, uns limit)
86 uns src_len = bdirect_read_prepare(f, &src);
91 uns len = 0, buf_len = MIN(bb->len, limit);
94 uns cnt = MIN(src_len, buf_len);
95 for (uns i = cnt; i--;)
100 bdirect_read_commit(f, src);
108 bdirect_read_commit(f, src);
109 src_len = bdirect_read_prepare(f, &src);
115 if (unlikely(len == limit))
116 die("%s: Line too long", f->name);
117 bb_do_grow(bb, len + 1);
119 buf_len = MIN(bb->len, limit) - len;
127 return buf - bb->ptr;
131 bgets_mp(struct fastbuf *f, struct mempool *mp)
134 uns src_len = bdirect_read_prepare(f, &src);
137 #define BLOCK_SIZE (4096 - sizeof(void *))
140 byte data[BLOCK_SIZE];
142 uns sum = 0, buf_len = BLOCK_SIZE, cnt;
143 struct block first_block, *new_block = &first_block;
144 byte *buf = new_block->data;
147 cnt = MIN(src_len, buf_len);
148 for (uns i = cnt; i--;)
153 bdirect_read_commit(f, src);
160 bdirect_read_commit(f, src);
161 src_len = bdirect_read_prepare(f, &src);
167 new_block->prev = blocks;
169 sum += buf_len = BLOCK_SIZE;
170 new_block = alloca(sizeof(struct block));
171 buf = new_block->data;
178 uns len = buf - new_block->data;
179 byte *result = mp_alloc(mp, sum + len + 1) + sum;
181 memcpy(result, new_block->data, len);
184 result -= BLOCK_SIZE;
185 memcpy(result, blocks->data, BLOCK_SIZE);
186 blocks = blocks->prev;
193 bgets_stk_init(struct bgets_stk_struct *s)
195 s->src_len = bdirect_read_prepare(s->f, &s->src);
209 bgets_stk_step(struct bgets_stk_struct *s)
211 byte *buf = s->cur_buf;
212 uns buf_len = s->cur_len;
215 memcpy( s->cur_buf, s->old_buf, s->old_len);
217 buf_len -= s->old_len;
221 uns cnt = MIN(s->src_len, buf_len);
222 for (uns i = cnt; i--;)
227 bdirect_read_commit(s->f, s->src);
232 if (cnt == s->src_len)
234 bdirect_read_commit(s->f, s->src);
235 s->src_len = bdirect_read_prepare(s->f, &s->src);
241 s->old_len = s->cur_len;
242 s->old_buf = s->cur_buf;
256 bgets0(struct fastbuf *f, byte *b, uns l)
260 uns src_len = bdirect_read_prepare(f, &src);
265 uns cnt = MIN(l, src_len);
266 for (uns i = cnt; i--;)
271 bdirect_read_commit(f, src);
276 if (unlikely(cnt == l))
277 die("%s: Line too long", f->name);
279 bdirect_read_commit(f, src);
280 src_len = bdirect_read_prepare(f, &src);