1 /* Copyright (c) 2009 Corinna Vinschen <corinna@vinschen.de> */
2 /*
3 FUNCTION
4 <<mbsrtowcs>>, <<mbsnrtowcs>>---convert a character string to a wide-character string
5
6 INDEX
7 mbsrtowcs
8 INDEX
9 _mbsrtowcs_r
10 INDEX
11 mbsnrtowcs
12 INDEX
13 _mbsnrtowcs_r
14
15 SYNOPSIS
16 #include <wchar.h>
17 size_t mbsrtowcs(wchar_t *__restrict <[dst]>,
18 const char **__restrict <[src]>,
19 size_t <[len]>,
20 mbstate_t *__restrict <[ps]>);
21
22 #include <wchar.h>
23 size_t mbsnrtowcs(wchar_t *__ restrict <[dst]>,
24 const char **__restrict <[src]>, size_t <[nms]>,
25 size_t <[len]>, mbstate_t *__restrict <[ps]>);
26
27
28 DESCRIPTION
29 The <<mbsrtowcs>> function converts a sequence of multibyte characters
30 pointed to indirectly by <[src]> into a sequence of corresponding wide
31 characters and stores at most <[len]> of them in the wchar_t array pointed
32 to by <[dst]>, until it encounters a terminating null character ('\0').
33
34 If <[dst]> is NULL, no characters are stored.
35
36 If <[dst]> is not NULL, the pointer pointed to by <[src]> is updated to point
37 to the character after the one that conversion stopped at. If conversion
38 stops because a null character is encountered, *<[src]> is set to NULL.
39
40 The mbstate_t argument, <[ps]>, is used to keep track of the shift state. If
41 it is NULL, <<mbsrtowcs>> uses an internal, static mbstate_t object, which
42 is initialized to the initial conversion state at program startup.
43
44 The <<mbsnrtowcs>> function behaves identically to <<mbsrtowcs>>, except that
45 conversion stops after reading at most <[nms]> bytes from the buffer pointed
46 to by <[src]>.
47
48 RETURNS
49 The <<mbsrtowcs>> and <<mbsnrtowcs>> functions return the number of wide
50 characters stored in the array pointed to by <[dst]> if successful, otherwise
51 it returns (size_t)-1.
52
53 PORTABILITY
54 <<mbsrtowcs>> is defined by the C99 standard.
55 <<mbsnrtowcs>> is defined by the POSIX.1-2008 standard.
56 */
57
58 #include <newlib.h>
59 #include <wchar.h>
60 #include <stdlib.h>
61 #include <stdio.h>
62 #include <errno.h>
63
64 size_t
mbsnrtowcs(wchar_t * dst,const char ** src,size_t nms,size_t len,mbstate_t * ps)65 mbsnrtowcs (
66 wchar_t *dst,
67 const char **src,
68 size_t nms,
69 size_t len,
70 mbstate_t *ps)
71 {
72 wchar_t *ptr = dst;
73 const char *tmp_src;
74 size_t max;
75 size_t count = 0;
76 int bytes;
77
78 #ifdef _MB_CAPABLE
79 if (ps == NULL)
80 {
81 static NEWLIB_THREAD_LOCAL mbstate_t _mbsrtowcs_state;
82 ps = &_mbsrtowcs_state;
83 }
84 #endif
85
86 if (dst == NULL)
87 {
88 /* Ignore original len value and do not alter src pointer if the
89 dst pointer is NULL. */
90 len = (size_t)-1;
91 tmp_src = *src;
92 src = &tmp_src;
93 }
94
95 max = len;
96 while (len > 0)
97 {
98 bytes = mbrtowc (ptr, *src, nms, ps);
99 if (bytes > 0)
100 {
101 *src += bytes;
102 nms -= bytes;
103 ++count;
104 ptr = (dst == NULL) ? NULL : ptr + 1;
105 --len;
106 }
107 else if (bytes == -2)
108 {
109 *src += nms;
110 return count;
111 }
112 else if (bytes == 0)
113 {
114 *src = NULL;
115 return count;
116 }
117 else
118 {
119 ps->__count = 0;
120 _REENT_ERRNO(r) = EILSEQ;
121 return (size_t)-1;
122 }
123 }
124
125 return (size_t)max;
126 }
127