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 |