xref: /aosp_15_r20/external/musl/src/multibyte/c16rtomb.c (revision c9945492fdd68bbe62686c5b452b4dc1be3f8453)
1*c9945492SAndroid Build Coastguard Worker #include <uchar.h>
2*c9945492SAndroid Build Coastguard Worker #include <errno.h>
3*c9945492SAndroid Build Coastguard Worker #include <wchar.h>
4*c9945492SAndroid Build Coastguard Worker 
c16rtomb(char * restrict s,char16_t c16,mbstate_t * restrict ps)5*c9945492SAndroid Build Coastguard Worker size_t c16rtomb(char *restrict s, char16_t c16, mbstate_t *restrict ps)
6*c9945492SAndroid Build Coastguard Worker {
7*c9945492SAndroid Build Coastguard Worker 	static unsigned internal_state;
8*c9945492SAndroid Build Coastguard Worker 	if (!ps) ps = (void *)&internal_state;
9*c9945492SAndroid Build Coastguard Worker 	unsigned *x = (unsigned *)ps;
10*c9945492SAndroid Build Coastguard Worker 	wchar_t wc;
11*c9945492SAndroid Build Coastguard Worker 
12*c9945492SAndroid Build Coastguard Worker 	if (!s) {
13*c9945492SAndroid Build Coastguard Worker 		if (*x) goto ilseq;
14*c9945492SAndroid Build Coastguard Worker 		return 1;
15*c9945492SAndroid Build Coastguard Worker 	}
16*c9945492SAndroid Build Coastguard Worker 
17*c9945492SAndroid Build Coastguard Worker 	if (!*x && c16 - 0xd800u < 0x400) {
18*c9945492SAndroid Build Coastguard Worker 		*x = c16 - 0xd7c0 << 10;
19*c9945492SAndroid Build Coastguard Worker 		return 0;
20*c9945492SAndroid Build Coastguard Worker 	}
21*c9945492SAndroid Build Coastguard Worker 
22*c9945492SAndroid Build Coastguard Worker 	if (*x) {
23*c9945492SAndroid Build Coastguard Worker 		if (c16 - 0xdc00u >= 0x400) goto ilseq;
24*c9945492SAndroid Build Coastguard Worker 		else wc = *x + c16 - 0xdc00;
25*c9945492SAndroid Build Coastguard Worker 		*x = 0;
26*c9945492SAndroid Build Coastguard Worker 	} else {
27*c9945492SAndroid Build Coastguard Worker 		wc = c16;
28*c9945492SAndroid Build Coastguard Worker 	}
29*c9945492SAndroid Build Coastguard Worker 	return wcrtomb(s, wc, 0);
30*c9945492SAndroid Build Coastguard Worker 
31*c9945492SAndroid Build Coastguard Worker ilseq:
32*c9945492SAndroid Build Coastguard Worker 	*x = 0;
33*c9945492SAndroid Build Coastguard Worker 	errno = EILSEQ;
34*c9945492SAndroid Build Coastguard Worker 	return -1;
35*c9945492SAndroid Build Coastguard Worker }
36