Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
codecvt.cpp
Go to the documentation of this file.
1
29#define _RWSTD_LIB_SRC
30
31#include <rw/_defs.h>
32
33
34// working around a Compaq C++ bug (see PR #26778)
35#if __DECCXX_VER >= 60300000 && __DECCXX_VER < 60400000
36
37# include <stdarg.h>
38_USING (std::va_list);
39
40// override autoconfigured macro whose value is incorrect
41// if <unistd.h> is #included before <iconv.h>
42# include <unistd.h>
43# define _RWSTD_NO_ICONV_CONST_CHAR
44
45#endif // Compaq C++ 6.3
46
47#include <limits.h>
48#include <locale.h>
49#include <string.h> // for memcmp()
50#include <errno.h>
51#include <wchar.h> // for mbsinit()
52
53#if defined (__SUNPRO_CC) && __SUNPRO_CC <= 0x540 \
54 && (defined (__SunOS_5_8) || defined (__SunOS_5_9))
55 // working around SunOS/SunPro header dependencies (see PR #26255)
56# undef _TIME_T
57#endif // SunPro <= 5.4 && SunOS 5.{8,9}
58
59#include <loc/_codecvt.h>
60#include <loc/_locale.h>
61#include <loc/_localedef.h>
62
63#include "setlocale.h"
64#include "use_facet.h"
65
66
67// _RWSTD_MBSTATE_T macro might expand to char* (on AIX)
69
70
72
73static inline int
74__rw_mbsinit (const StateT *ps)
75{
76#ifndef _RWSTD_NO_MBSINIT
77
78 return ::mbsinit (ps);
79
80#else // if defined (_RWSTD_NO_MBSINIT)
81
82 // commented out to work around an HP aCC 1.21 bug
83 /* static */ const StateT state = StateT ();
84 return !ps || 0 == memcmp (ps, &state, sizeof state);
85
86#endif // _RWSTD_NO_MBSINIT
87
88}
89
90
91} // namespace __rw
92
93
95
96
97_RW::__rw_facet_id codecvt<char, char, _RWSTD_MBSTATE_T>::id;
98
99
100codecvt<char, char, _RWSTD_MBSTATE_T>::
101codecvt (size_t refs /* = 0 */)
102 : _RW::__rw_facet (refs), _C_always_noconv (-1)
103{
104 // empty
105}
106
107
108// outlined to avoid generating a vtable in each translation unit
109// that uses the class
110/* virtual */ codecvt<char, char, _RWSTD_MBSTATE_T>::
111~codecvt ()
112{
113 // no-op
114}
115
116
117/* virtual */ codecvt_base::result
118codecvt<char, char, _RWSTD_MBSTATE_T>::
119do_out (state_type &state,
120 const intern_type *from,
121 const intern_type *from_end,
122 const intern_type *&from_next,
123 extern_type *to,
124 extern_type *to_end,
125 extern_type *&to_next) const
126{
127 // verify that both ranges are valid
128 _RWSTD_ASSERT (from <= from_end);
129 _RWSTD_ASSERT (to <= to_end);
130 _RWSTD_ASSERT (from && from_end || !from && !from_end);
131 _RWSTD_ASSERT (to && to_end || !to && !to_end);
132
133 // next pointers must always be set before returning, even on error
134 from_next = from;
135 to_next = to;
136
137#ifdef _RWSTDDEBUG
138
139 // verify that the conversion state is valid
140 const int mbstate_valid = _RW::__rw_mbsinit (&state);
141
142 _RWSTD_ASSERT (0 != mbstate_valid);
143
144#else // if !defined (_RWSTDDEBUG)
145
146 _RWSTD_UNUSED (state);
147
148#endif // _RWSTDDEBUG
149
150 // be prepared to handle an overridden do_always_noconv()
151 // that returns false (highly unlikely but possible)
152 if (always_noconv ())
153 return noconv;
154
155 const _RWSTD_SIZE_T nfrom = from_end - from;
156 const _RWSTD_SIZE_T nto = to_end - to;
157
158 const _RWSTD_SIZE_T nconv = nfrom < nto ? nfrom : nto;
159
160 // use memmove() in case ranges overlap
161 memmove (to, from, nconv);
162
163 from_next += nconv;
164 to_next += nconv;
165
166 // Table 53, and lwg issue 382: do_out() returns partial
167 // if not all source characters could be converted (e.g.,
168 // because the destination range is full)
169 return nto < nfrom ? partial : ok;
170}
171
172
173/* virtual */ codecvt_base::result
174codecvt<char, char, _RWSTD_MBSTATE_T>::
175do_in (state_type &state,
176 const extern_type *from,
177 const extern_type *from_end,
178 const extern_type *&from_next,
179 intern_type *to,
180 intern_type *to_end,
181 intern_type *&to_next) const
182{
183 // verify that both ranges are valid
184 _RWSTD_ASSERT (from <= from_end);
185 _RWSTD_ASSERT (to <= to_end);
186 _RWSTD_ASSERT (from && from_end || !from && !from_end);
187 _RWSTD_ASSERT (to && to_end || !to && !to_end);
188
189 typedef codecvt<char, char, _RWSTD_MBSTATE_T> This;
190
191 // call do_out() above (avoid calling overridden do_out(), if any)
192 return This::do_out (state,
193 from, from_end, from_next,
194 to, to_end, to_next);
195}
196
197
198/* virtual */ codecvt_base::result
199codecvt<char, char, _RWSTD_MBSTATE_T>::
200do_unshift (state_type &state,
201 extern_type *to,
202 extern_type *to_end,
203 extern_type *&to_next) const
204{
205 // verify that the range is valid
206 _RWSTD_ASSERT (to <= to_end);
207 _RWSTD_ASSERT (to && to_end || !to && !to_end);
208
209 _RWSTD_UNUSED (to_end);
210
211 // next pointer must always be set before returning, even on error
212 to_next = to;
213
214 const int mbstate_valid = _RW::__rw_mbsinit (&state);
215 _RWSTD_ASSERT (mbstate_valid);
216
217 return mbstate_valid ? noconv : error;
218}
219
220
221/* virtual */ int
222codecvt<char, char, _RWSTD_MBSTATE_T>::
223do_encoding () const _THROWS (())
224{
225 return 1; // 1 external char converts to a single internal char
226}
227
228
229/* virtual */ bool
230codecvt<char, char, _RWSTD_MBSTATE_T>::
231do_always_noconv () const _THROWS (())
232{
233 return true; // conversion never necessary
234}
235
236
237// signature follows lwg issue 75
238/* virtual */ int
239codecvt<char, char, _RWSTD_MBSTATE_T>::
240do_length (state_type &state,
241 const extern_type *from,
242 const extern_type *from_end,
243 _RWSTD_SIZE_T imax) const
244{
245 // 22.2.1.5.2, p9 - preconditions
246 _RWSTD_ASSERT (from <= from_end);
247
248 // verify that the range is valid
249 _RWSTD_ASSERT (from && from_end || !from && !from_end);
250
251 const int mbstate_valid = _RW::__rw_mbsinit (&state);
252 _RWSTD_ASSERT (mbstate_valid);
253
254 if (!mbstate_valid)
255 return 0;
256
257 // 22.2.1.5.2, p10
258 const _RWSTD_SIZE_T len = from_end - from;
259 return int (len < imax ? len : imax);
260}
261
262
263/* virtual */ int
264codecvt<char, char, _RWSTD_MBSTATE_T>::
265do_max_length () const _THROWS (())
266{
267 return 1; // 22.2.1.5.2, p11
268}
269
270
271codecvt_byname<char, char, _RWSTD_MBSTATE_T>::
272codecvt_byname (const char *name, size_t ref)
273 : codecvt <intern_type, extern_type, state_type> (ref)
274{
275 _C_set_name (name, _C_namebuf, sizeof _C_namebuf);
276}
277
278
279// outlined to avoid generating a vtable in each translation unit
280// that uses the class
281/* virtual */ codecvt_byname<char, char, _RWSTD_MBSTATE_T>::
282~codecvt_byname ()
283{
284 // no-op
285}
286
287
288} // namespace std
289
290#define TARGS_C <char, char, _RWSTD_MBSTATE_T>
291
292_RWSTD_DEFINE_FACET_FACTORY (static, codecvt, TARGS_C, codecvt);
294
#define len
Definition 17.names.cpp:488
#define _THROWS()
#define _RWSTD_UNUSED(arg)
Definition _defs.h:972
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _USING(name)
Definition _defs.h:568
#define _RWSTD_MBSTATE_T
Definition _mbstate.h:199
const char * name
Definition codecvt1.cpp:72
Definition json.h:5363
_RWSTD_MBSTATE_T StateT
Definition codecvt.cpp:68
#define TARGS_C
Definition codecvt.cpp:290
#define _RWSTD_SPECIALIZE_USE_FACET(fid)
Definition use_facet.h:129
#define _RWSTD_DEFINE_FACET_FACTORY(Linkage, Facet, TArgs, fid)
Definition use_facet.h:52