1 /* c16rtomb( char *, char16_t, mbstate_t * )
\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
13 #include "_PDCLIB_encoding.h"
\r
14 #include "_PDCLIB_locale.h"
\r
19 mbstate_t *restrict ps,
\r
23 const char16_t *restrict psrc = &c16;
\r
24 char buf[s ? 0 : MB_CUR_MAX];
\r
27 if(!l->_Codec->__c16stombs) {
\r
28 // Codec doesn't support direct conversion - translate via UCS-4
\r
29 if(ps->_Surrogate == 0) {
\r
30 // No pending surrogate
\r
31 if((c16 & 0xF800) == 0xD800) {
\r
33 if((c16 & 0x0400) == 0) {
\r
34 // 0xD800 -> 0xDBFF leading surrogate
\r
35 ps->_Surrogate = c16;
\r
38 // Return 0 - we haven't output anything yet
\r
40 /* STD: ISO/IEC 9899:2011 is very implcifit about this being
\r
41 * the correct return value. N1040, from which the
\r
42 * function was adopted, is explicit about 0 being a
\r
47 // 0xDC00 -> 0xDFFF trailing surrogate
\r
52 // BMP range - UTF16 == UCS-4, pass through to c32rtomb_l
\r
53 return c32rtomb_l(s, c16, ps, l);
\r
56 // We have a stored surrogate
\r
57 if((c16 & 0xFC00) == 0xDC00) {
\r
58 // Trailing surrogate
\r
59 char32_t c32 = (ps->_Surrogate & 0x3FF) << 10 | (c16 & 0x3FF);
\r
61 return c32rtomb_l(s, c32, ps, l);
\r
63 // Not a trailing surrogate - encoding error
\r
70 // Codec supports direct conversion
\r
72 size_t dstsz = MB_CUR_MAX;
\r
73 size_t dstrem = dstsz;
\r
75 if(l->_Codec->__c16stombs(&s, &dstrem, &psrc, &srcsz, ps)) {
\r
76 // Successful conversion
\r
77 return dstsz - dstrem;
\r
88 mbstate_t *restrict ps
\r
91 return c16rtomb_l(s, c16, ps, _PDCLIB_threadlocale());
\r
97 #include "_PDCLIB_test.h"
\r
101 TESTCASE( NO_TESTDRIVER );
\r
102 return TEST_RESULTS;
\r