#include #include #include #include #include "stdio-util.h" typedef struct allocblk ALLOCBLK; typedef struct rstrblk RSTRBLK; struct allocblk { char **bufp; int *lenp; char *buf; int len; } ; struct rstrblk { const char *buf; int len; off_t ptr; }; static int alloc_w(void *av, const char *b, int l) { ALLOCBLK *a; a = av; a->buf = realloc(a->buf,a->len+l); bcopy(b,a->buf+a->len,l); a->len += l; return(l); } static int alloc_c(void *av) { ALLOCBLK *a; a = av; *a->bufp = a->buf; *a->lenp = a->len; free(a); return(0); } FILE *fopen_alloc(char **bufp, int *lenp) { FILE *f; ALLOCBLK *a; a = malloc(sizeof(ALLOCBLK)); if (a == 0) return(0); a->bufp = bufp; a->lenp = lenp; a->buf = 0; a->len = 0; f = funopen(a,0,&alloc_w,0,&alloc_c); if (f == 0) free(a); return(f); } static int rstr_r(void *bv, char *buf, int len) { RSTRBLK *b; int n; b = bv; if (b->ptr < 0) { errno = EINVAL; return(-1); } else if (b->ptr >= b->len) { return(0); } n = b->len - b->ptr; if (n > len) n = len; bcopy(b->buf+b->ptr,buf,n); b->ptr += n; return(n); } static fpos_t rstr_s(void *bv, fpos_t loc, int whence) { RSTRBLK *b; b = bv; switch (whence) { case SEEK_SET: b->ptr = loc; break; case SEEK_CUR: b->ptr += loc; break; case SEEK_END: b->ptr = b->len + loc; break; default: errno = EINVAL; return(-1); break; } return(b->ptr); } static int rstr_c(void *bv) { free(bv); return(0); } FILE *fopen_rstr(const char *s, int l) { RSTRBLK *b; FILE *f; b = malloc(sizeof(RSTRBLK)); if (b == 0) return(0); if (l < 0) l = strlen(s); b->buf = s; b->len = l; b->ptr = 0; f = funopen(b,&rstr_r,0,&rstr_s,&rstr_c); if (f == 0) free(b); return(f); }