source:
azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbsrtowcs.c@
473
Last change on this file since 473 was 398, checked in by , 5 years ago | |
---|---|
|
|
File size: 2.0 KB |
Rev | Line | |
---|---|---|
[398] | 1 | #include <stdint.h> |
2 | #include <wchar.h> | |
3 | #include <errno.h> | |
4 | #include <string.h> | |
5 | #include <stdlib.h> | |
6 | #include "internal.h" | |
7 | ||
8 | size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbstate_t *restrict st) | |
9 | { | |
10 | const unsigned char *s = (const void *)*src; | |
11 | size_t wn0 = wn; | |
12 | unsigned c = 0; | |
13 | ||
14 | if (st && (c = *(unsigned *)st)) { | |
15 | if (ws) { | |
16 | *(unsigned *)st = 0; | |
17 | goto resume; | |
18 | } else { | |
19 | goto resume0; | |
20 | } | |
21 | } | |
22 | ||
23 | if (MB_CUR_MAX==1) { | |
24 | if (!ws) return strlen((const char *)s); | |
25 | for (;;) { | |
26 | if (!wn) { | |
27 | *src = (const void *)s; | |
28 | return wn0; | |
29 | } | |
30 | if (!*s) break; | |
31 | c = *s++; | |
32 | *ws++ = CODEUNIT(c); | |
33 | wn--; | |
34 | } | |
35 | *ws = 0; | |
36 | *src = 0; | |
37 | return wn0-wn; | |
38 | } | |
39 | ||
40 | if (!ws) for (;;) { | |
41 | if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) { | |
42 | while (!(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) { | |
43 | s += 4; | |
44 | wn -= 4; | |
45 | } | |
46 | } | |
47 | if (*s-1u < 0x7f) { | |
48 | s++; | |
49 | wn--; | |
50 | continue; | |
51 | } | |
52 | if (*s-SA > SB-SA) break; | |
53 | c = bittab[*s++-SA]; | |
54 | resume0: | |
55 | if (OOB(c,*s)) { s--; break; } | |
56 | s++; | |
57 | if (c&(1U<<25)) { | |
58 | if (*s-0x80u >= 0x40) { s-=2; break; } | |
59 | s++; | |
60 | if (c&(1U<<19)) { | |
61 | if (*s-0x80u >= 0x40) { s-=3; break; } | |
62 | s++; | |
63 | } | |
64 | } | |
65 | wn--; | |
66 | c = 0; | |
67 | } else for (;;) { | |
68 | if (!wn) { | |
69 | *src = (const void *)s; | |
70 | return wn0; | |
71 | } | |
72 | if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) { | |
73 | while (wn>=5 && !(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) { | |
74 | *ws++ = *s++; | |
75 | *ws++ = *s++; | |
76 | *ws++ = *s++; | |
77 | *ws++ = *s++; | |
78 | wn -= 4; | |
79 | } | |
80 | } | |
81 | if (*s-1u < 0x7f) { | |
82 | *ws++ = *s++; | |
83 | wn--; | |
84 | continue; | |
85 | } | |
86 | if (*s-SA > SB-SA) break; | |
87 | c = bittab[*s++-SA]; | |
88 | resume: | |
89 | if (OOB(c,*s)) { s--; break; } | |
90 | c = (c<<6) | *s++-0x80; | |
91 | if (c&(1U<<31)) { | |
92 | if (*s-0x80u >= 0x40) { s-=2; break; } | |
93 | c = (c<<6) | *s++-0x80; | |
94 | if (c&(1U<<31)) { | |
95 | if (*s-0x80u >= 0x40) { s-=3; break; } | |
96 | c = (c<<6) | *s++-0x80; | |
97 | } | |
98 | } | |
99 | *ws++ = c; | |
100 | wn--; | |
101 | c = 0; | |
102 | } | |
103 | ||
104 | if (!c && !*s) { | |
105 | if (ws) { | |
106 | *ws = 0; | |
107 | *src = 0; | |
108 | } | |
109 | return wn0-wn; | |
110 | } | |
111 | errno = EILSEQ; | |
112 | if (ws) *src = (const void *)s; | |
113 | return -1; | |
114 | } |
Note:
See TracBrowser
for help on using the repository browser.