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 <ucw/fastbuf.h>
13 #include <ucw/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 bthrow(f, "toolong", "%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 bthrow(f, "toolong", "%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 bgets0(struct fastbuf *f, char *b, uns l)
198 uns src_len = bdirect_read_prepare(f, &src);
203 uns cnt = MIN(l, src_len);
204 for (uns i = cnt; i--;)
209 bdirect_read_commit(f, src);
214 if (unlikely(cnt == l))
215 bthrow(f, "toolong", "%s: Line too long", f->name);
217 bdirect_read_commit(f, src);
218 src_len = bdirect_read_prepare(f, &src);