| OLD | NEW |
| 1 #include "stdio_impl.h" | 1 #include "stdio_impl.h" |
| 2 #include <wchar.h> | 2 #include <wchar.h> |
| 3 #include <errno.h> | 3 #include <errno.h> |
| 4 #include <limits.h> | 4 #include <limits.h> |
| 5 #include <string.h> | 5 #include <string.h> |
| 6 | 6 |
| 7 struct cookie { | 7 struct cookie { |
| 8 » wchar_t **bufp; | 8 wchar_t** bufp; |
| 9 » size_t *sizep; | 9 size_t* sizep; |
| 10 » size_t pos; | 10 size_t pos; |
| 11 » wchar_t *buf; | 11 wchar_t* buf; |
| 12 » size_t len; | 12 size_t len; |
| 13 » size_t space; | 13 size_t space; |
| 14 » mbstate_t mbs; | 14 mbstate_t mbs; |
| 15 }; | 15 }; |
| 16 | 16 |
| 17 static off_t wms_seek(FILE *f, off_t off, int whence) | 17 static off_t wms_seek(FILE* f, off_t off, int whence) { |
| 18 { | 18 ssize_t base; |
| 19 » ssize_t base; | 19 struct cookie* c = f->cookie; |
| 20 » struct cookie *c = f->cookie; | 20 if (whence > 2U) { |
| 21 » if (whence>2U) { | 21 fail: |
| 22 fail: | 22 errno = EINVAL; |
| 23 » » errno = EINVAL; | 23 return -1; |
| 24 » » return -1; | 24 } |
| 25 » } | 25 base = (size_t[3]){0, c->pos, c->len}[whence]; |
| 26 » base = (size_t [3]){0, c->pos, c->len}[whence]; | 26 if (off < -base || off > SSIZE_MAX / 4 - base) |
| 27 » if (off < -base || off > SSIZE_MAX/4-base) goto fail; | 27 goto fail; |
| 28 » memset(&c->mbs, 0, sizeof c->mbs); | 28 memset(&c->mbs, 0, sizeof c->mbs); |
| 29 » return c->pos = base+off; | 29 return c->pos = base + off; |
| 30 } | 30 } |
| 31 | 31 |
| 32 static size_t wms_write(FILE *f, const unsigned char *buf, size_t len) | 32 static size_t wms_write(FILE* f, const unsigned char* buf, size_t len) { |
| 33 { | 33 struct cookie* c = f->cookie; |
| 34 » struct cookie *c = f->cookie; | 34 size_t len2; |
| 35 » size_t len2; | 35 wchar_t* newbuf; |
| 36 » wchar_t *newbuf; | 36 if (len + c->pos >= c->space) { |
| 37 » if (len + c->pos >= c->space) { | 37 len2 = 2 * c->space + 1 | c->pos + len + 1; |
| 38 » » len2 = 2*c->space+1 | c->pos+len+1; | 38 if (len2 > SSIZE_MAX / 4) |
| 39 » » if (len2 > SSIZE_MAX/4) return 0; | 39 return 0; |
| 40 » » newbuf = realloc(c->buf, len2*4); | 40 newbuf = realloc(c->buf, len2 * 4); |
| 41 » » if (!newbuf) return 0; | 41 if (!newbuf) |
| 42 » » *c->bufp = c->buf = newbuf; | 42 return 0; |
| 43 » » memset(c->buf + c->space, 0, 4*(len2 - c->space)); | 43 *c->bufp = c->buf = newbuf; |
| 44 » » c->space = len2; | 44 memset(c->buf + c->space, 0, 4 * (len2 - c->space)); |
| 45 » } | 45 c->space = len2; |
| 46 » | 46 } |
| 47 » len2 = mbsnrtowcs(c->buf+c->pos, (void *)&buf, len, c->space-c->pos, &c-
>mbs); | 47 |
| 48 » if (len2 == -1) return 0; | 48 len2 = |
| 49 » c->pos += len2; | 49 mbsnrtowcs(c->buf + c->pos, (void*)&buf, len, c->space - c->pos, &c->mbs); |
| 50 » if (c->pos >= c->len) c->len = c->pos; | 50 if (len2 == -1) |
| 51 » *c->sizep = c->pos; | 51 return 0; |
| 52 » return len; | 52 c->pos += len2; |
| 53 if (c->pos >= c->len) |
| 54 c->len = c->pos; |
| 55 *c->sizep = c->pos; |
| 56 return len; |
| 53 } | 57 } |
| 54 | 58 |
| 55 static int wms_close(FILE *f) | 59 static int wms_close(FILE* f) { |
| 56 { | 60 return 0; |
| 57 » return 0; | |
| 58 } | 61 } |
| 59 | 62 |
| 60 FILE *open_wmemstream(wchar_t **bufp, size_t *sizep) | 63 FILE* open_wmemstream(wchar_t** bufp, size_t* sizep) { |
| 61 { | 64 FILE* f; |
| 62 » FILE *f; | 65 struct cookie* c; |
| 63 » struct cookie *c; | 66 wchar_t* buf; |
| 64 » wchar_t *buf; | |
| 65 | 67 |
| 66 » if (!(f=malloc(sizeof *f + sizeof *c))) return 0; | 68 if (!(f = malloc(sizeof *f + sizeof *c))) |
| 67 » if (!(buf=malloc(sizeof *buf))) { | 69 return 0; |
| 68 » » free(f); | 70 if (!(buf = malloc(sizeof *buf))) { |
| 69 » » return 0; | 71 free(f); |
| 70 » } | 72 return 0; |
| 71 » memset(f, 0, sizeof *f + sizeof *c); | 73 } |
| 72 » f->cookie = c = (void *)(f+1); | 74 memset(f, 0, sizeof *f + sizeof *c); |
| 75 f->cookie = c = (void*)(f + 1); |
| 73 | 76 |
| 74 » c->bufp = bufp; | 77 c->bufp = bufp; |
| 75 » c->sizep = sizep; | 78 c->sizep = sizep; |
| 76 » c->pos = c->len = c->space = *sizep = 0; | 79 c->pos = c->len = c->space = *sizep = 0; |
| 77 » c->buf = *bufp = buf; | 80 c->buf = *bufp = buf; |
| 78 » *buf = 0; | 81 *buf = 0; |
| 79 | 82 |
| 80 » f->flags = F_NORD; | 83 f->flags = F_NORD; |
| 81 » f->fd = -1; | 84 f->fd = -1; |
| 82 » f->buf = (void *)(c+1); | 85 f->buf = (void*)(c + 1); |
| 83 » f->buf_size = 0; | 86 f->buf_size = 0; |
| 84 » f->lbf = EOF; | 87 f->lbf = EOF; |
| 85 » f->write = wms_write; | 88 f->write = wms_write; |
| 86 » f->seek = wms_seek; | 89 f->seek = wms_seek; |
| 87 » f->close = wms_close; | 90 f->close = wms_close; |
| 88 | 91 |
| 89 » if (!libc.threaded) f->lock = -1; | 92 if (!libc.threaded) |
| 93 f->lock = -1; |
| 90 | 94 |
| 91 » return __ofl_add(f); | 95 return __ofl_add(f); |
| 92 } | 96 } |
| OLD | NEW |