1 /* Licensed under BSD-MIT - see LICENSE file for details */
2 #include <ccan/rbuf/rbuf.h>
10 bool rbuf_open(struct rbuf *rbuf, const char *name, char *buf, size_t buf_max)
12 int fd = open(name, O_RDONLY);
14 rbuf_init(rbuf, fd, buf, buf_max);
20 static size_t rem(const struct rbuf *buf)
22 return buf->buf_end - (buf->start + buf->len);
25 size_t rbuf_good_size(int fd)
29 if (fstat(fd, &st) == 0 && st.st_blksize >= 4096)
34 static bool enlarge_buf(struct rbuf *buf, size_t len,
35 void *(*resize)(void *buf, size_t len))
43 len = rbuf_good_size(buf->fd);
44 new = resize(buf->buf, len);
47 buf->start += (new - buf->buf);
49 buf->buf_end = new + len;
53 static ssize_t get_more(struct rbuf *rbuf,
54 void *(*resize)(void *buf, size_t len))
58 if (rbuf->start + rbuf->len == rbuf->buf_end) {
59 if (!enlarge_buf(rbuf, (rbuf->buf_end - rbuf->buf) * 2, resize))
63 r = read(rbuf->fd, rbuf->start + rbuf->len, rem(rbuf));
71 void *rbuf_fill_all(struct rbuf *rbuf, void *(*resize)(void *buf, size_t len))
75 /* Move back to start of buffer if we're empty. */
77 rbuf->start = rbuf->buf;
79 while ((r = get_more(rbuf, resize)) != 0)
85 void *rbuf_fill(struct rbuf *rbuf, void *(*resize)(void *buf, size_t len))
88 rbuf->start = rbuf->buf;
89 if (get_more(rbuf, resize) < 0)
95 char *rbuf_read_str(struct rbuf *rbuf, char term,
96 void *(*resize)(void *buf, size_t len))
102 /* Move back to start of buffer if we're empty. */
104 rbuf->start = rbuf->buf;
106 while (!(p = memchr(rbuf->start + prev, term, rbuf->len - prev))) {
108 r = get_more(rbuf, resize);
111 /* EOF with no term. */
113 /* Nothing read at all? */
114 if (!rbuf->len && term) {
118 /* Put term after input (get_more made room). */
119 assert(rbuf->start + rbuf->len < rbuf->buf_end);
120 rbuf->start[rbuf->len] = '\0';
122 rbuf_consume(rbuf, rbuf->len);
128 rbuf_consume(rbuf, p + 1 - ret);