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