1 /*
2 FUNCTION
3 <<wcsrtombs>>, <<wcsnrtombs>>---convert a wide-character string to a character string
4 
5 INDEX
6 	wcsrtombs
7 INDEX
8 	_wcsrtombs_r
9 INDEX
10 	wcsnrtombs
11 INDEX
12 	_wcsnrtombs_r
13 
14 ANSI_SYNOPSIS
15 	#include <wchar.h>
16 	size_t wcsrtombs(char *__restrict <[dst]>,
17 			 const wchar_t **__restrict <[src]>, size_t <[len]>,
18 			 mbstate_t *__restrict <[ps]>);
19 
20 	#include <wchar.h>
21 	size_t _wcsrtombs_r(struct _reent *<[ptr]>, char *<[dst]>,
22 			    const wchar_t **<[src]>, size_t <[len]>,
23 			    mbstate_t *<[ps]>);
24 
25 	#include <wchar.h>
26 	size_t wcsnrtombs(char *__restrict <[dst]>,
27 			  const wchar_t **__restrict <[src]>,
28 			  size_t <[nwc]>, size_t <[len]>,
29 			  mbstate_t *__restrict <[ps]>);
30 
31 	#include <wchar.h>
32 	size_t _wcsnrtombs_r(struct _reent *<[ptr]>, char *<[dst]>,
33 			     const wchar_t **<[src]>, size_t <[nwc]>,
34 			     size_t <[len]>, mbstate_t *<[ps]>);
35 
36 TRAD_SYNOPSIS
37 	#include <wchar.h>
38 	size_t wcsrtombs(<[dst]>, <[src]>, <[len]>, <[ps]>)
39 	char *__restrict <[dst]>;
40 	const wchar_t **__restrict <[src]>;
41 	size_t <[len]>;
42 	mbstate_t *__restrict <[ps]>;
43 
44 	#include <wchar.h>
45 	size_t _wcsrtombs_r(<[ptr]>, <[dst]>, <[src]>, <[len]>, <[ps]>)
46 	struct _rent *<[ptr]>;
47 	char *<[dst]>;
48 	const wchar_t **<[src]>;
49 	size_t <[len]>;
50 	mbstate_t *<[ps]>;
51 
52 	#include <wchar.h>
53 	size_t wcsnrtombs(<[dst]>, <[src]>, <[nwc]>, <[len]>, <[ps]>)
54 	char *__restrict <[dst]>;
55 	const wchar_t **__restrict <[src]>;
56 	size_t <[nwc]>;
57 	size_t <[len]>;
58 	mbstate_t *__restrict <[ps]>;
59 
60 	#include <wchar.h>
61 	size_t _wcsnrtombs_r(<[ptr]>, <[dst]>, <[src]>, <[nwc]>, <[len]>, <[ps]>)
62 	struct _rent *<[ptr]>;
63 	char *<[dst]>;
64 	const wchar_t **<[src]>;
65 	size_t <[nwc]>;
66 	size_t <[len]>;
67 	mbstate_t *<[ps]>;
68 
69 DESCRIPTION
70 The <<wcsrtombs>> function converts a string of wide characters indirectly
71 pointed to by <[src]> to a corresponding multibyte character string stored in
72 the array pointed to by <[dst]>.  No more than <[len]> bytes are written to
73 <[dst]>.
74 
75 If <[dst]> is NULL, no characters are stored.
76 
77 If <[dst]> is not NULL, the pointer pointed to by <[src]> is updated to point
78 to the character after the one that conversion stopped at.  If conversion
79 stops because a null character is encountered, *<[src]> is set to NULL.
80 
81 The mbstate_t argument, <[ps]>, is used to keep track of the shift state.  If
82 it is NULL, <<wcsrtombs>> uses an internal, static mbstate_t object, which
83 is initialized to the initial conversion state at program startup.
84 
85 The <<wcsnrtombs>> function behaves identically to <<wcsrtombs>>, except that
86 conversion stops after reading at most <[nwc]> characters from the buffer
87 pointed to by <[src]>.
88 
89 RETURNS
90 The <<wcsrtombs>> and <<wcsnrtombs>> functions return the number of bytes
91 stored in the array pointed to by <[dst]> (not including any terminating
92 null), if successful, otherwise it returns (size_t)-1.
93 
94 PORTABILITY
95 <<wcsrtombs>> is defined by C99 standard.
96 <<wcsnrtombs>> is defined by the POSIX.1-2008 standard.
97 */
98 
99 #include <reent.h>
100 #include <newlib.h>
101 #include <wchar.h>
102 #include <stdlib.h>
103 #include <stdio.h>
104 #include <errno.h>
105 #include "local.h"
106 
107 size_t
108 _DEFUN (_wcsnrtombs_r, (r, dst, src, nwc, len, ps),
109 	struct _reent *r _AND
110 	char *dst _AND
111 	const wchar_t **src _AND
112 	size_t nwc _AND
113 	size_t len _AND
114 	mbstate_t *ps)
115 {
116   char *ptr = dst;
117   char buff[10];
118   wchar_t *pwcs;
119   size_t n;
120   int i;
121 
122 #ifdef _MB_CAPABLE
123   if (ps == NULL)
124     {
125       _REENT_CHECK_MISC(r);
126       ps = &(_REENT_WCSRTOMBS_STATE(r));
127     }
128 #endif
129 
130   /* If no dst pointer, treat len as maximum possible value. */
131   if (dst == NULL)
132     len = (size_t)-1;
133 
134   n = 0;
135   pwcs = (wchar_t *)(*src);
136 
137   while (n < len && nwc-- > 0)
138     {
139       int count = ps->__count;
140       wint_t wch = ps->__value.__wch;
141       int bytes = __wctomb (r, buff, *pwcs, __locale_charset (), ps);
142       if (bytes == -1)
143 	{
144 	  r->_errno = EILSEQ;
145 	  ps->__count = 0;
146 	  return (size_t)-1;
147 	}
148       if (n + bytes <= len)
149 	{
150           n += bytes;
151 	  if (dst)
152 	    {
153 	      for (i = 0; i < bytes; ++i)
154 	        *ptr++ = buff[i];
155 	      ++(*src);
156 	    }
157 	  if (*pwcs++ == 0x00)
158 	    {
159 	      if (dst)
160 	        *src = NULL;
161 	      ps->__count = 0;
162 	      return n - 1;
163 	    }
164 	}
165       else
166 	{
167 	  /* not enough room, we must back up state to before __wctomb call */
168 	  ps->__count = count;
169 	  ps->__value.__wch = wch;
170           len = 0;
171 	}
172     }
173 
174   return n;
175 }
176 
177 #ifndef _REENT_ONLY
178 size_t
179 _DEFUN (wcsnrtombs, (dst, src, nwc, len, ps),
180 	char *__restrict dst _AND
181 	const wchar_t **__restrict src _AND
182 	size_t nwc _AND
183 	size_t len _AND
184 	mbstate_t *__restrict ps)
185 {
186   return _wcsnrtombs_r (_REENT, dst, src, nwc, len, ps);
187 }
188 #endif /* !_REENT_ONLY */
189