2 * Copyright (c) 2011 Venkatesh Srinivas,
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 struct memstream_cookie {
41 sync_pub_cookie(struct memstream_cookie *cp)
43 *cp->pub_buf = cp->head;
44 *cp->pub_size = cp->tail;
48 memstream_writefn(void *cookie, const char *buf, int len)
50 struct memstream_cookie *c;
55 /* Write is contained within valid region */
56 if (c->pos + len < c->tail) {
57 bcopy(buf, &c->head[c->pos], len);
62 /* Write results in resizing buffer */
63 reqsize = c->pos + len + 1;
64 c->head = reallocf(c->head, reqsize);
65 if (c->head == NULL) {
70 bcopy(buf, &c->head[c->pos], len);
72 c->tail = c->pos + len;
74 c->head[c->tail] = '\0';
82 memstream_seekfn(void *cookie, fpos_t pos, int whence)
84 struct memstream_cookie *c;
88 /* XXX: Should validate SEEK_SET and SEEK_CUR positions */
89 /* XXX: What to do wrt SEEK_END? Is it relative to tail? to pos? */
108 memstream_closefn(void *cookie)
110 struct memstream_cookie *c;
120 open_memstream(char **bufp, size_t *sizep)
123 struct memstream_cookie *c;
126 if (bufp == NULL || sizep == NULL) {
131 c = malloc(sizeof(struct memstream_cookie));