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