19#include "YapIOConfig.h"
31#if !HAVE_OPEN_MEMSTREAM && !_WIN32
34#error Sorry, not ported to your platform yet
37FILE *open_memstream(
char **buf,
size_t *len);
39#define INITIAL_ALLOC 64
49typedef struct data data;
55static int mem_write(
void *c,
const char *buf,
int n) {
57 char *cbuf = *cookie->buf;
60 if ((ssize_t)(cookie->pos + n) < 0) {
68 if (cookie->allocated <= cookie->pos + n) {
69 size_t newsize = cookie->allocated * 3 / 2;
70 if (newsize < cookie->pos + n + 1)
71 newsize = cookie->pos + n + 1;
72 cbuf = realloc(cbuf, newsize);
76 cookie->allocated = newsize;
80 if (cookie->eof < cookie->pos)
81 memset(cbuf + cookie->eof,
'\0', cookie->pos - cookie->eof);
82 memmove(cbuf + cookie->pos, buf, n);
87 if (cookie->eof < cookie->pos)
88 cookie->eof = cookie->pos;
90 cookie->c = cbuf[cookie->pos];
91 cbuf[cookie->pos] =
'\0';
92 *cookie->len = cookie->pos;
96static fpos_t mem_seek(
void *c, fpos_t pos,
int whence) {
100 if (whence == SEEK_CUR)
101 offset = cookie->pos;
102 else if (whence == SEEK_END)
103 offset = cookie->eof;
107 }
else if ((
size_t)offset != offset) {
111 if (cookie->pos < cookie->eof) {
112 (*cookie->buf)[cookie->pos] = cookie->c;
115 cookie->pos = offset;
116 if (cookie->pos < cookie->eof) {
117 cookie->c = (*cookie->buf)[cookie->pos];
118 (*cookie->buf)[cookie->pos] =
'\0';
119 *cookie->len = cookie->pos;
121 *cookie->len = cookie->eof;
126static int mem_close(
void *c) {
131 buf = realloc(*cookie->buf, *cookie->len + 1);
138FILE *open_memstream(
char **buf,
size_t *len) {
146 if (!(cookie = malloc(
sizeof *cookie)))
148 if (!(*buf = malloc(INITIAL_ALLOC))) {
156 f = funopen(cookie, NULL, mem_write, mem_seek, mem_close);
158 int saved_errno = errno;
167 cookie->allocated = INITIAL_ALLOC;