2 * This is free and unencumbered software released into the public domain.
4 * Anyone is free to copy, modify, publish, use, compile, sell, or
5 * distribute this software, either in source code form or as a compiled
6 * binary, for any purpose, commercial or non-commercial, and by any
9 * In jurisdictions that recognize copyright laws, the author or authors
10 * of this software dedicate any and all copyright interest in the
11 * software to the public domain. We make this dedication for the benefit
12 * of the public at large and to the detriment of our heirs and
13 * successors. We intend this dedication to be an overt act of
14 * relinquishment in perpetuity of all present and future rights to this
15 * software under copyright law.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
41 buf_init(struct buffer *buf)
43 const size_t cap = BIO_CHUNK;
45 memset(buf, 0, sizeof(*buf));
46 if ((buf->buf = malloc(cap)) == NULL)
53 buf_grow(struct buffer *buf)
58 newcap = buf->cap + BIO_CHUNK;
59 t = realloc(buf->buf, newcap);
68 buf_write(struct buffer *buf, const void *d, size_t len)
70 while (buf->len + len > buf->cap) {
71 if (buf_grow(buf) == -1)
74 memcpy(buf->buf + buf->len, d, len);
80 buf_has_line(struct buffer *buf, const char *nl)
82 return (memmem(buf->buf, buf->len, nl, strlen(nl)) != NULL);
86 buf_drain(struct buffer *buf, size_t l)
93 memmove(buf->buf, buf->buf + l, buf->len - l);
98 buf_drain_line(struct buffer *buf, const char *nl)
104 if ((endln = memmem(buf->buf, buf->len, nl, nlen)) == NULL)
106 buf_drain(buf, endln + nlen - buf->buf);
110 buf_free(struct buffer *buf)
113 memset(buf, 0, sizeof(*buf));
117 bufio_init(struct bufio *bio)
119 memset(bio, 0, sizeof(*bio));
122 if (buf_init(&bio->wbuf) == -1)
124 if (buf_init(&bio->rbuf) == -1) {
125 buf_free(&bio->wbuf);
132 bufio_free(struct bufio *bio)
137 buf_free(&bio->rbuf);
138 buf_free(&bio->wbuf);
142 bufio_reset(struct bufio *bio)
145 return (bufio_init(bio));
149 bufio_set_fd(struct bufio *bio, int fd)
155 bufio_set_chunked(struct bufio *bio, int chunked)
157 bio->chunked = chunked;
161 bufio_pollev(struct bufio *bio)
166 if (bio->wbuf.len != 0)
173 bufio_read(struct bufio *bio)
175 struct buffer *rbuf = &bio->rbuf;
178 assert(rbuf->cap >= rbuf->len);
179 if (rbuf->cap - rbuf->len < BIO_CHUNK) {
180 if (buf_grow(rbuf) == -1)
184 r = read(bio->fd, rbuf->buf + rbuf->len, rbuf->cap - rbuf->len);
192 bufio_drain(struct bufio *bio, void *d, size_t len)
194 struct buffer *rbuf = &bio->rbuf;
198 memcpy(d, rbuf->buf, len);
199 buf_drain(rbuf, len);
204 bufio_write(struct bufio *bio)
206 struct buffer *wbuf = &bio->wbuf;
209 w = write(bio->fd, wbuf->buf, wbuf->len);
217 bufio_append(struct bufio *bio, const void *d, size_t len)
219 struct buffer *wbuf = &bio->wbuf;
224 while (wbuf->cap - wbuf->len < len) {
225 if (buf_grow(wbuf) == -1)
229 memcpy(wbuf->buf + wbuf->len, d, len);
235 bufio_compose(struct bufio *bio, const void *d, size_t len)
241 r = snprintf(n, sizeof(n), "%zx\r\n", len);
242 if (r < 0 || (size_t)r >= sizeof(n))
244 if (bufio_append(bio, n, r) == -1)
248 if (bufio_append(bio, d, len) == -1)
252 return bufio_append(bio, "\r\n", 2);
258 bufio_compose_str(struct bufio *bio, const char *str)
260 return (bufio_compose(bio, str, strlen(str)));
264 bufio_compose_fmt(struct bufio *bio, const char *fmt, ...)
271 r = vasprintf(&str, fmt, ap);
276 r = bufio_compose(bio, str, r);