]> pd.if.org Git - pdclib/blob - functions/uchar/mbrtoc16.c
PDCLib includes with quotes, not <>.
[pdclib] / functions / uchar / mbrtoc16.c
1 /* size_t mbrtoc16( char16_t *, const char *, size_t, mbstate_t * )\r
2 \r
3    This file is part of the Public Domain C Library (PDCLib).\r
4    Permission is granted to use, modify, and / or redistribute at will.\r
5 */\r
6 \r
7 #ifndef REGTEST\r
8 #include <uchar.h>\r
9 #include <errno.h>\r
10 #include <stdint.h>\r
11 #include <assert.h>\r
12 #include "_PDCLIB_encoding.h"\r
13 #include "_PDCLIB_locale.h"\r
14 \r
15 size_t mbrtoc16_l(\r
16     char16_t    *restrict   pc16,\r
17     const char  *restrict   s, \r
18     size_t                  n,\r
19     mbstate_t   *restrict   ps,\r
20     locale_t     restrict   l\r
21 )\r
22 {\r
23     size_t dstlen = 1;\r
24     size_t nr = n;\r
25 \r
26     if(!l->_Codec->__mbstoc16s) {\r
27         // No UTF-16 support in codec. Must synthesize on top of UCS-4 support.\r
28 \r
29         if(ps->_Surrogate) {\r
30             // If a pending surrogate is stored in the state\r
31             *pc16 = ps->_Surrogate;\r
32             ps->_Surrogate = 0;\r
33             return (size_t) -3;\r
34         }\r
35 \r
36         char32_t c32;\r
37         size_t res = mbrtoc32_l(&c32, s, n, ps, l);\r
38         if(res != (size_t) -1) {\r
39             // Conversion was successful. Check for surrogates\r
40             if(c32 <= 0xFFFF) {\r
41                 // BMP char\r
42                 *pc16 = c32;\r
43             } else {\r
44                 // Supplementary char\r
45                 *pc16 = 0xD800 | (c32 >> 10);\r
46                 ps->_Surrogate = 0xDC00 | (c32 & 0x3FF);\r
47             }\r
48         }\r
49         return res;\r
50     } else if(l->_Codec->__mbstoc16s(&pc16, &dstlen, &s, &nr, ps)) {\r
51         // Successful conversion\r
52         if(dstlen == 0) {\r
53             // A character was output\r
54             if(nr == n) {\r
55                 // The output character resulted entirely from stored state\r
56                 return (size_t) -3;\r
57             } else if(pc16[-1] == 0) {\r
58                 // Was null character\r
59                 return 0;\r
60             } else {\r
61                 // Count of processed characters\r
62                 return n - nr;\r
63             }\r
64         } else {\r
65             assert(nr == 0 && "Must have processed whole input");\r
66             return (size_t) -2;\r
67         }\r
68     } else {\r
69         // Failed conversion\r
70         errno = EILSEQ;\r
71         return (size_t) -1;\r
72     }\r
73 }\r
74 \r
75 size_t mbrtoc16(\r
76     char16_t    *restrict   pc16,\r
77     const char  *restrict   s, \r
78     size_t                  n,\r
79     mbstate_t   *restrict   ps\r
80 )\r
81 {\r
82     return mbrtoc16_l(pc16, s, n, ps, _PDCLIB_threadlocale());\r
83 }\r
84 \r
85 #endif\r
86 \r
87 #ifdef TEST\r
88 #include "_PDCLIB_test.h"\r
89 \r
90 int main( void )\r
91 {\r
92     TESTCASE( NO_TESTDRIVER );\r
93     return TEST_RESULTS;\r
94 }\r
95 #endif\r