xref: /aosp_15_r20/external/musl/src/multibyte/wcsrtombs.c (revision c9945492fdd68bbe62686c5b452b4dc1be3f8453)
1*c9945492SAndroid Build Coastguard Worker #include <wchar.h>
2*c9945492SAndroid Build Coastguard Worker 
wcsrtombs(char * restrict s,const wchar_t ** restrict ws,size_t n,mbstate_t * restrict st)3*c9945492SAndroid Build Coastguard Worker size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstate_t *restrict st)
4*c9945492SAndroid Build Coastguard Worker {
5*c9945492SAndroid Build Coastguard Worker 	const wchar_t *ws2;
6*c9945492SAndroid Build Coastguard Worker 	char buf[4];
7*c9945492SAndroid Build Coastguard Worker 	size_t N = n, l;
8*c9945492SAndroid Build Coastguard Worker 	if (!s) {
9*c9945492SAndroid Build Coastguard Worker 		for (n=0, ws2=*ws; *ws2; ws2++) {
10*c9945492SAndroid Build Coastguard Worker 			if (*ws2 >= 0x80u) {
11*c9945492SAndroid Build Coastguard Worker 				l = wcrtomb(buf, *ws2, 0);
12*c9945492SAndroid Build Coastguard Worker 				if (!(l+1)) return -1;
13*c9945492SAndroid Build Coastguard Worker 				n += l;
14*c9945492SAndroid Build Coastguard Worker 			} else n++;
15*c9945492SAndroid Build Coastguard Worker 		}
16*c9945492SAndroid Build Coastguard Worker 		return n;
17*c9945492SAndroid Build Coastguard Worker 	}
18*c9945492SAndroid Build Coastguard Worker 	while (n>=4) {
19*c9945492SAndroid Build Coastguard Worker 		if (**ws-1u >= 0x7fu) {
20*c9945492SAndroid Build Coastguard Worker 			if (!**ws) {
21*c9945492SAndroid Build Coastguard Worker 				*s = 0;
22*c9945492SAndroid Build Coastguard Worker 				*ws = 0;
23*c9945492SAndroid Build Coastguard Worker 				return N-n;
24*c9945492SAndroid Build Coastguard Worker 			}
25*c9945492SAndroid Build Coastguard Worker 			l = wcrtomb(s, **ws, 0);
26*c9945492SAndroid Build Coastguard Worker 			if (!(l+1)) return -1;
27*c9945492SAndroid Build Coastguard Worker 			s += l;
28*c9945492SAndroid Build Coastguard Worker 			n -= l;
29*c9945492SAndroid Build Coastguard Worker 		} else {
30*c9945492SAndroid Build Coastguard Worker 			*s++ = **ws;
31*c9945492SAndroid Build Coastguard Worker 			n--;
32*c9945492SAndroid Build Coastguard Worker 		}
33*c9945492SAndroid Build Coastguard Worker 		(*ws)++;
34*c9945492SAndroid Build Coastguard Worker 	}
35*c9945492SAndroid Build Coastguard Worker 	while (n) {
36*c9945492SAndroid Build Coastguard Worker 		if (**ws-1u >= 0x7fu) {
37*c9945492SAndroid Build Coastguard Worker 			if (!**ws) {
38*c9945492SAndroid Build Coastguard Worker 				*s = 0;
39*c9945492SAndroid Build Coastguard Worker 				*ws = 0;
40*c9945492SAndroid Build Coastguard Worker 				return N-n;
41*c9945492SAndroid Build Coastguard Worker 			}
42*c9945492SAndroid Build Coastguard Worker 			l = wcrtomb(buf, **ws, 0);
43*c9945492SAndroid Build Coastguard Worker 			if (!(l+1)) return -1;
44*c9945492SAndroid Build Coastguard Worker 			if (l>n) return N-n;
45*c9945492SAndroid Build Coastguard Worker 			wcrtomb(s, **ws, 0);
46*c9945492SAndroid Build Coastguard Worker 			s += l;
47*c9945492SAndroid Build Coastguard Worker 			n -= l;
48*c9945492SAndroid Build Coastguard Worker 		} else {
49*c9945492SAndroid Build Coastguard Worker 			*s++ = **ws;
50*c9945492SAndroid Build Coastguard Worker 			n--;
51*c9945492SAndroid Build Coastguard Worker 		}
52*c9945492SAndroid Build Coastguard Worker 		(*ws)++;
53*c9945492SAndroid Build Coastguard Worker 	}
54*c9945492SAndroid Build Coastguard Worker 	return N;
55*c9945492SAndroid Build Coastguard Worker }
56