wcsrtombs.c raw

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