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"
16 char * /* Non-standard */
17 bgets(struct fastbuf *f, char *b, uns l)
21 uns src_len = bdirect_read_prepare(f, &src);
26 uns cnt = MIN(l, src_len);
27 for (uns i = cnt; i--;)
32 bdirect_read_commit(f, src);
37 if (unlikely(cnt == l))
38 die("%s: Line too long", f->name);
40 bdirect_read_commit(f, src);
41 src_len = bdirect_read_prepare(f, &src);
50 bgets_nodie(struct fastbuf *f, char *b, uns l)
53 byte *src, *start = b;
54 uns src_len = bdirect_read_prepare(f, &src);
59 uns cnt = MIN(l, src_len);
60 for (uns i = cnt; i--;)
65 bdirect_read_commit(f, src);
70 bdirect_read_commit(f, src);
74 src_len = bdirect_read_prepare(f, &src);
79 return b - (char *)start;
83 bgets_bb(struct fastbuf *f, struct bb_t *bb, uns limit)
87 uns src_len = bdirect_read_prepare(f, &src);
92 uns len = 0, buf_len = MIN(bb->len, limit);
95 uns cnt = MIN(src_len, buf_len);
96 for (uns i = cnt; i--;)
101 bdirect_read_commit(f, src);
109 bdirect_read_commit(f, src);
110 src_len = bdirect_read_prepare(f, &src);
116 if (unlikely(len == limit))
117 die("%s: Line too long", f->name);
118 bb_do_grow(bb, len + 1);
120 buf_len = MIN(bb->len, limit) - len;
128 return buf - bb->ptr;
132 bgets_mp(struct fastbuf *f, struct mempool *mp)
135 uns src_len = bdirect_read_prepare(f, &src);
138 #define BLOCK_SIZE (4096 - sizeof(void *))
141 byte data[BLOCK_SIZE];
143 uns sum = 0, buf_len = BLOCK_SIZE, cnt;
144 struct block first_block, *new_block = &first_block;
145 byte *buf = new_block->data;
148 cnt = MIN(src_len, buf_len);
149 for (uns i = cnt; i--;)
154 bdirect_read_commit(f, src);
161 bdirect_read_commit(f, src);
162 src_len = bdirect_read_prepare(f, &src);
168 new_block->prev = blocks;
170 sum += buf_len = BLOCK_SIZE;
171 new_block = alloca(sizeof(struct block));
172 buf = new_block->data;
179 uns len = buf - new_block->data;
180 byte *result = mp_alloc(mp, sum + len + 1) + sum;
182 memcpy(result, new_block->data, len);
185 result -= BLOCK_SIZE;
186 memcpy(result, blocks->data, BLOCK_SIZE);
187 blocks = blocks->prev;
194 bgets_stk_init(struct bgets_stk_struct *s)
196 s->src_len = bdirect_read_prepare(s->f, &s->src);
210 bgets_stk_step(struct bgets_stk_struct *s)
212 byte *buf = s->cur_buf;
213 uns buf_len = s->cur_len;
216 memcpy( s->cur_buf, s->old_buf, s->old_len);
218 buf_len -= s->old_len;
222 uns cnt = MIN(s->src_len, buf_len);
223 for (uns i = cnt; i--;)
228 bdirect_read_commit(s->f, s->src);
233 if (cnt == s->src_len)
235 bdirect_read_commit(s->f, s->src);
236 s->src_len = bdirect_read_prepare(s->f, &s->src);
242 s->old_len = s->cur_len;
243 s->old_buf = s->cur_buf;
257 bgets0(struct fastbuf *f, char *b, uns l)
261 uns src_len = bdirect_read_prepare(f, &src);
266 uns cnt = MIN(l, src_len);
267 for (uns i = cnt; i--;)
272 bdirect_read_commit(f, src);
277 if (unlikely(cnt == l))
278 die("%s: Line too long", f->name);
280 bdirect_read_commit(f, src);
281 src_len = bdirect_read_prepare(f, &src);