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--;)
98 bdirect_read_commit(f, src);
106 bdirect_read_commit(f, src);
107 src_len = bdirect_read_prepare(f, &src);
113 bb_do_grow(bb, len + 1);
115 buf_len = bb->len - len;
123 return buf - bb->ptr;
127 bgets_mp(struct mempool *mp, struct fastbuf *f)
130 uns src_len = bdirect_read_prepare(f, &src);
133 #define BLOCK_SIZE 4096
136 byte data[BLOCK_SIZE];
138 uns sum = 0, buf_len = BLOCK_SIZE;
139 struct block *new_block = alloca(sizeof(struct block));
140 byte *buf = new_block->data;
143 uns cnt = MIN(src_len, buf_len);
144 for (uns i = cnt; i--;)
148 bdirect_read_commit(f, src);
155 bdirect_read_commit(f, src);
156 src_len = bdirect_read_prepare(f, &src);
162 new_block->prev = blocks;
164 sum += buf_len = BLOCK_SIZE;
165 buf = new_block->data;
172 uns len = buf - new_block->data;
173 byte *result = mp_alloc(mp, sum + len + 1) + sum;
175 memcpy(result, new_block->data, len);
178 result -= BLOCK_SIZE;
179 memcpy(result, blocks->data, BLOCK_SIZE);
180 blocks = blocks->prev;
187 bgets_stk_step(struct fastbuf *f, byte *old_buf, byte *buf, uns len)
192 memcpy(buf, old_buf, len);
198 if (k == '\n' || k < 0)
206 bgets0(struct fastbuf *f, byte *b, uns l)
210 uns src_len = bdirect_read_prepare(f, &src);
215 uns cnt = MIN(l, src_len);
216 for (uns i = cnt; i--;)
221 bdirect_read_commit(f, src);
226 if (unlikely(cnt == l))
227 die("%s: Line too long", f->name);
229 bdirect_read_commit(f, src);
230 src_len = bdirect_read_prepare(f, &src);