summaryrefslogtreecommitdiff
path: root/src/multibyte/wcsnrtombs.c
blob: 95e25e708dd9d93b2617a72ca5eb428a40138e18 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <wchar.h>
#include <limits.h>
#include <string.h>

size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, size_t n, mbstate_t *restrict st)
{
	const wchar_t *ws = *wcs;
	size_t cnt = 0;
	if (!dst) n=0;
	while (ws && wn) {
		char tmp[MB_LEN_MAX];
		size_t l = wcrtomb(n<MB_LEN_MAX ? tmp : dst, *ws, 0);
		if (l==-1) {
			cnt = -1;
			break;
		}
		if (dst) {
			if (n<MB_LEN_MAX) {
				if (l>n) break;
				memcpy(dst, tmp, l);
			}
			dst += l;
			n -= l;
		}
		if (!*ws) {
			ws = 0;
			break;
		}
		ws++;
		wn--;
		cnt += l;
	}
	if (dst) *wcs = ws;
	return cnt;
}