1570af302Sopenharmony_ci#include <uchar.h> 2570af302Sopenharmony_ci#include <wchar.h> 3570af302Sopenharmony_ci 4570af302Sopenharmony_cisize_t mbrtoc16(char16_t *restrict pc16, const char *restrict s, size_t n, mbstate_t *restrict ps) 5570af302Sopenharmony_ci{ 6570af302Sopenharmony_ci static unsigned internal_state; 7570af302Sopenharmony_ci if (!ps) ps = (void *)&internal_state; 8570af302Sopenharmony_ci unsigned *pending = (unsigned *)ps; 9570af302Sopenharmony_ci 10570af302Sopenharmony_ci if (!s) return mbrtoc16(0, "", 1, ps); 11570af302Sopenharmony_ci 12570af302Sopenharmony_ci /* mbrtowc states for partial UTF-8 characters have the high bit set; 13570af302Sopenharmony_ci * we use nonzero states without high bit for pending surrogates. */ 14570af302Sopenharmony_ci if ((int)*pending > 0) { 15570af302Sopenharmony_ci if (pc16) *pc16 = *pending; 16570af302Sopenharmony_ci *pending = 0; 17570af302Sopenharmony_ci return -3; 18570af302Sopenharmony_ci } 19570af302Sopenharmony_ci 20570af302Sopenharmony_ci wchar_t wc; 21570af302Sopenharmony_ci size_t ret = mbrtowc(&wc, s, n, ps); 22570af302Sopenharmony_ci if (ret <= 4) { 23570af302Sopenharmony_ci if (wc >= 0x10000) { 24570af302Sopenharmony_ci *pending = (wc & 0x3ff) + 0xdc00; 25570af302Sopenharmony_ci wc = 0xd7c0 + (wc >> 10); 26570af302Sopenharmony_ci } 27570af302Sopenharmony_ci if (pc16) *pc16 = wc; 28570af302Sopenharmony_ci } 29570af302Sopenharmony_ci return ret; 30570af302Sopenharmony_ci} 31