X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Frbuf%2Frbuf.c;h=d8d658d37a3923454324dfe06a3d4bac777b91d0;hb=fedf515165bfafaf4fb98252ecda1abe050c8da5;hp=0e210a9e38dac592b09df10b505978a7f16c2b25;hpb=44b37ee8aeb185f6837378fef17d887bda6ff89b;p=ccan diff --git a/ccan/rbuf/rbuf.c b/ccan/rbuf/rbuf.c index 0e210a9e..d8d658d3 100644 --- a/ccan/rbuf/rbuf.c +++ b/ccan/rbuf/rbuf.c @@ -7,21 +7,17 @@ #include #include -bool rbuf_open(struct rbuf *rbuf, const char *name, char *buf, size_t buf_max) +bool rbuf_open(struct rbuf *rbuf, const char *name, char *buf, size_t buf_max, + void *(*expandfn)(struct membuf *, void *, size_t)) { int fd = open(name, O_RDONLY); if (fd >= 0) { - rbuf_init(rbuf, fd, buf, buf_max); + rbuf_init(rbuf, fd, buf, buf_max, expandfn); return true; } return false; } -static size_t rem(const struct rbuf *buf) -{ - return buf->buf_end - (buf->start + buf->len); -} - size_t rbuf_good_size(int fd) { struct stat st; @@ -31,100 +27,78 @@ size_t rbuf_good_size(int fd) return 4096; } -static bool enlarge_buf(struct rbuf *buf, size_t len, - void *(*resize)(void *buf, size_t len)) +static ssize_t get_more(struct rbuf *rbuf) { - char *new; - if (!resize) { - errno = ENOMEM; - return false; - } - if (!len) - len = rbuf_good_size(buf->fd); - new = resize(buf->buf, len); - if (!new) - return false; - buf->start += (new - buf->buf); - buf->buf = new; - buf->buf_end = new + len; - return true; -} + ssize_t r; -static ssize_t get_more(struct rbuf *rbuf, - void *(*resize)(void *buf, size_t len)) -{ - size_t r; + /* This is so we only call rbuf_good_size once. */ + if (tcon_unwrap(&rbuf->m)->max_elems == 0) + membuf_prepare_space(&rbuf->m, rbuf_good_size(rbuf->fd)); + else /* membuf doubles internally, so just ask for anything. */ + membuf_prepare_space(&rbuf->m, 1); - if (rbuf->start + rbuf->len == rbuf->buf_end) { - if (!enlarge_buf(rbuf, (rbuf->buf_end - rbuf->buf) * 2, resize)) - return -1; - } + /* This happens if realloc fails (errno already ENOMEM) */ + if (!membuf_num_space(&rbuf->m)) + return -1; - r = read(rbuf->fd, rbuf->start + rbuf->len, rem(rbuf)); + r = read(rbuf->fd, membuf_space(&rbuf->m), membuf_num_space(&rbuf->m)); if (r <= 0) return r; - rbuf->len += r; + membuf_add(&rbuf->m, r); return r; } -void *rbuf_fill_all(struct rbuf *rbuf, void *(*resize)(void *buf, size_t len)) +void *rbuf_fill_all(struct rbuf *rbuf) { ssize_t r; - /* Move back to start of buffer if we're empty. */ - if (!rbuf->len) - rbuf->start = rbuf->buf; - - while ((r = get_more(rbuf, resize)) != 0) + while ((r = get_more(rbuf)) != 0) if (r < 0) return NULL; - return rbuf->start; + return rbuf_start(rbuf); } -void *rbuf_fill(struct rbuf *rbuf, void *(*resize)(void *buf, size_t len)) +void *rbuf_fill(struct rbuf *rbuf) { - if (!rbuf->len) { - rbuf->start = rbuf->buf; - if (get_more(rbuf, resize) < 0) + if (!rbuf_len(rbuf)) { + if (get_more(rbuf) < 0) return NULL; } - return rbuf->start; + return rbuf_start(rbuf); } -char *rbuf_read_str(struct rbuf *rbuf, char term, - void *(*resize)(void *buf, size_t len)) +char *rbuf_read_str(struct rbuf *rbuf, char term) { - char *p, *ret; + char *p; ssize_t r = 0; size_t prev = 0; - /* Move back to start of buffer if we're empty. */ - if (!rbuf->len) - rbuf->start = rbuf->buf; - - while (!(p = memchr(rbuf->start + prev, term, rbuf->len - prev))) { + while (!(p = memchr(membuf_elems(&rbuf->m) + prev, + term, + membuf_num_elems(&rbuf->m) - prev))) { prev += r; - r = get_more(rbuf, resize); + r = get_more(rbuf); if (r < 0) return NULL; /* EOF with no term. */ if (r == 0) { + char *ret; + size_t len = rbuf_len(rbuf); + /* Nothing read at all? */ - if (!rbuf->len && term) { + if (!len && term) { errno = 0; return NULL; } + /* Put term after input (get_more made room). */ - assert(rbuf->start + rbuf->len < rbuf->buf_end); - rbuf->start[rbuf->len] = '\0'; - ret = rbuf->start; - rbuf_consume(rbuf, rbuf->len); + assert(membuf_num_space(&rbuf->m) > 0); + ret = membuf_consume(&rbuf->m, len); + ret[len] = '\0'; return ret; } } *p = '\0'; - ret = rbuf->start; - rbuf_consume(rbuf, p + 1 - ret); - return ret; + return membuf_consume(&rbuf->m, p + 1 - (char *)rbuf_start(rbuf)); }