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