1#include <uchar.h>
2#include <wchar.h>
3
4size_t mbrtoc16(char16_t* restrict pc16, const char* restrict s, size_t n, mbstate_t* restrict ps) {
5    static unsigned internal_state;
6    if (!ps)
7        ps = (void*)&internal_state;
8    unsigned* pending = (unsigned*)ps;
9
10    if (!s)
11        return mbrtoc16(0, "", 1, ps);
12
13    /* mbrtowc states for partial UTF-8 characters have the high bit set;
14     * we use nonzero states without high bit for pending surrogates. */
15    if ((int)*pending > 0) {
16        if (pc16)
17            *pc16 = *pending;
18        *pending = 0;
19        return -3;
20    }
21
22    wchar_t wc;
23    size_t ret = mbrtowc(&wc, s, n, ps);
24    if (ret <= 4) {
25        if (wc >= 0x10000) {
26            *pending = (wc & 0x3ff) + 0xdc00;
27            wc = 0xd7c0 + (wc >> 10);
28        }
29        if (pc16)
30            *pc16 = wc;
31    }
32    return ret;
33}
34