diff options
Diffstat (limited to 'dynstr.c')
-rw-r--r-- | dynstr.c | 68 |
1 files changed, 68 insertions, 0 deletions
@@ -9,6 +9,9 @@ #include "dynstr.h" +#define DYNSTR_ERROR ((size_t) -1) + + struct Dynstr { const unsigned char *mem; size_t size; @@ -301,3 +304,68 @@ ssize_t dynstr_write(int fd, Dynstr *dynstr) return write(fd, dynstr->mem, dynstr->size); } + +static Dynstr *read_helper(size_t (*callback)(FILE *f, int fd, unsigned char *buf, + size_t size), + FILE *f, int fd, size_t size) +{ + unsigned char *buf; + unsigned char *p; + Dynstr *dynstr; + size_t n; + + buf = alloc(size); + if (buf == NULL) + return NULL; + + n = callback(f, fd, buf, size); + if (n == DYNSTR_ERROR) { + free(buf); + return NULL; + } + + if (n < size) { + p = realloc(buf, n); + if (p != NULL) + buf = p; + } + + dynstr = new(buf, n, false); + dynstr->dynamic = true; + return dynstr; +} + + +static size_t fread_callback(FILE *f, int fd, unsigned char *buf, size_t size) +{ + size_t n; + + n = fread(buf, 1, size, f); + if (n == 0 && ferror(f)) + return DYNSTR_ERROR; + return n; +} + + +static size_t read_callback(FILE *f, int fd, unsigned char *buf, size_t size) +{ + ssize_t n; + + n = read(fd, buf, size); + if (n == -1) + return DYNSTR_ERROR; + return n; +} + + +Dynstr *dynstr_fread(FILE *file, size_t size) +{ + return read_helper(fread_callback, file, -1, size); +} + + +Dynstr *dynstr_read(int file, size_t size) +{ + return read_helper(read_callback, NULL, file, size); +} + |