From: Pavel Charvat Date: Thu, 18 May 2006 07:49:02 +0000 (+0200) Subject: Some fixes and changes from yesterday. X-Git-Tag: holmes-import~641^2~9 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=5a3a31413e9a65287c5e0bb8cf5ac3cdf93e74ee;p=libucw.git Some fixes and changes from yesterday. All bgets* should work now. byte *bgets_mp(fastbuf, mempool) byte *bgets_stk(fastbuf) uns bgets_bb(fastbuf, bbuf) Behavior is similar to bgets (returns NULL/zero at EOF). bgets_bb returns length in bytes including zero byte. --- diff --git a/lib/fastbuf.h b/lib/fastbuf.h index bc7ef7eb..d822ef6e 100644 --- a/lib/fastbuf.h +++ b/lib/fastbuf.h @@ -323,10 +323,16 @@ byte *bgets0(struct fastbuf *f, byte *b, uns l); struct mempool; uns bgets_bb(struct fastbuf *f, bb_t *b); -byte *bgets_mp(struct mempool *mp, struct fastbuf *f); -int bgets_stk_step(struct fastbuf *f, byte *old_buf, byte *buf, uns len); -#define bgets_stk(f) ({ struct fastbuf *_fb = (f); uns _l = 256; byte *_b, *_p = NULL; \ - while (bgets_stk_step(_fb, _p, _b = alloca(_l), _l)) _p = _b, _l *= 2; _b; }) +byte *bgets_mp(struct fastbuf *f, struct mempool *mp); + +struct bgets_stk_struct { + struct fastbuf *f; + byte *old_buf, *cur_buf, *src; + uns old_len, cur_len, src_len; +}; +void bgets_stk_init(struct bgets_stk_struct *s); +void bgets_stk_step(struct bgets_stk_struct *s); +#define bgets_stk(fb) ({ struct bgets_stk_struct _s; _s.f = (fb); for (bgets_stk_init(&_s); _s.cur_len; _s.cur_buf = alloca(_s.cur_len), bgets_stk_step(&_s)); _s.cur_buf; }) static inline void bputs(struct fastbuf *f, byte *b) diff --git a/lib/ff-string.c b/lib/ff-string.c index bb43ab85..c0b85da1 100644 --- a/lib/ff-string.c +++ b/lib/ff-string.c @@ -93,12 +93,13 @@ bgets_bb(struct fastbuf *f, bb_t *bb) uns cnt = MIN(src_len, buf_len); for (uns i = cnt; i--;) { - if (*src == '\n') + byte v = *src++; + if (v == '\n') { bdirect_read_commit(f, src); goto exit; } - *buf++ = *src++; + *buf++ = v; } len += cnt; if (cnt == src_len) @@ -124,31 +125,32 @@ exit: } byte * -bgets_mp(struct mempool *mp, struct fastbuf *f) +bgets_mp(struct fastbuf *f, struct mempool *mp) { byte *src; uns src_len = bdirect_read_prepare(f, &src); if (!src_len) return NULL; -#define BLOCK_SIZE 4096 +#define BLOCK_SIZE (4096 - sizeof(void *)) struct block { struct block *prev; byte data[BLOCK_SIZE]; } *blocks = NULL; - uns sum = 0, buf_len = BLOCK_SIZE; - struct block *new_block = alloca(sizeof(struct block)); + uns sum = 0, buf_len = BLOCK_SIZE, cnt; + struct block first_block, *new_block = &first_block; byte *buf = new_block->data; do { - uns cnt = MIN(src_len, buf_len); + cnt = MIN(src_len, buf_len); for (uns i = cnt; i--;) { - if (*src == '\n') + byte v = *src++; + if (v == '\n') { bdirect_read_commit(f, src); goto exit; } - *buf++ = *src++; + *buf++ = v; } if (cnt == src_len) { @@ -162,6 +164,7 @@ bgets_mp(struct mempool *mp, struct fastbuf *f) new_block->prev = blocks; blocks = new_block; sum += buf_len = BLOCK_SIZE; + new_block = alloca(sizeof(struct block)); buf = new_block->data; } else @@ -183,23 +186,67 @@ exit: ; #undef BLOCK_SIZE } -int -bgets_stk_step(struct fastbuf *f, byte *old_buf, byte *buf, uns len) +void +bgets_stk_init(struct bgets_stk_struct *s) { - if (old_buf) + s->src_len = bdirect_read_prepare(s->f, &s->src); + if (!s->src_len) { - len = len >> 1; - memcpy(buf, old_buf, len); - buf += len; + s->cur_buf = NULL; + s->cur_len = 0; } - while (len--) + else { - int k = bgetc(f); - if (k == '\n' || k < 0) - return *buf = 0; - *buf++ = k; + s->old_buf = NULL; + s->cur_len = 256; + } +} + +void +bgets_stk_step(struct bgets_stk_struct *s) +{ + byte *buf = s->cur_buf; + uns buf_len = s->cur_len; + if (s->old_buf) + { + memcpy( s->cur_buf, s->old_buf, s->old_len); + buf += s->old_len; + buf_len -= s->old_len; + } + do + { + uns cnt = MIN(s->src_len, buf_len); + for (uns i = cnt; i--;) + { + byte v = *s->src++; + if (v == '\n') + { + bdirect_read_commit(s->f, s->src); + goto exit; + } + *buf++ = v; + } + if (cnt == s->src_len) + { + bdirect_read_commit(s->f, s->src); + s->src_len = bdirect_read_prepare(s->f, &s->src); + } + else + s->src_len -= cnt; + if (cnt == buf_len) + { + s->old_len = s->cur_len; + s->old_buf = s->cur_buf; + s->cur_len *= 2; + return; + } + else + buf_len -= cnt; } - return 1; + while (s->src_len); +exit: + *buf = 0; + s->cur_len = 0; } byte *