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,
11 void *(*expandfn)(struct membuf *, void *, size_t))
13 int fd = open(name, O_RDONLY);
15 rbuf_init(rbuf, fd, buf, buf_max, expandfn);
21 size_t rbuf_good_size(int fd)
25 if (fstat(fd, &st) == 0 && st.st_blksize >= 4096)
30 static ssize_t get_more(struct rbuf *rbuf)
34 /* This is so we only call rbuf_good_size once. */
35 if (tcon_unwrap(&rbuf->m)->max_elems == 0)
36 membuf_prepare_space(&rbuf->m, rbuf_good_size(rbuf->fd));
37 else /* membuf doubles internally, so just ask for anything. */
38 membuf_prepare_space(&rbuf->m, 1);
40 /* This happens if realloc fails (errno already ENOMEM) */
41 if (!membuf_num_space(&rbuf->m))
44 r = read(rbuf->fd, membuf_space(&rbuf->m), membuf_num_space(&rbuf->m));
48 membuf_add(&rbuf->m, r);
52 void *rbuf_fill_all(struct rbuf *rbuf)
56 while ((r = get_more(rbuf)) != 0)
59 return rbuf_start(rbuf);
62 void *rbuf_fill(struct rbuf *rbuf)
64 if (!rbuf_len(rbuf)) {
65 if (get_more(rbuf) < 0)
68 return rbuf_start(rbuf);
71 char *rbuf_read_str(struct rbuf *rbuf, char term)
77 while (!(p = memchr(membuf_elems(&rbuf->m) + prev,
79 membuf_num_elems(&rbuf->m) - prev))) {
84 /* EOF with no term. */
87 size_t len = rbuf_len(rbuf);
89 /* Nothing read at all? */
95 /* Put term after input (get_more made room). */
96 assert(membuf_num_space(&rbuf->m) > 0);
97 ret = membuf_consume(&rbuf->m, len);
103 return membuf_consume(&rbuf->m, p + 1 - (char *)rbuf_start(rbuf));