1 : // xlocale internal header (from <locale>)
2 : #pragma once
3 : #ifndef _XLOCALE_
4 : #define _XLOCALE_
5 : #ifndef RC_INVOKED
6 : #include <climits>
7 : #include <cstring>
8 : #include <stdexcept>
9 : #include <typeinfo>
10 : #include <xdebug>
11 : #include <xlocinfo>
12 :
13 : #ifdef _MSC_VER
14 : #pragma pack(push,_CRT_PACKING)
15 : #pragma warning(push,3)
16 : #pragma warning(disable:4412)
17 : #endif /* _MSC_VER */
18 :
19 : _STD_BEGIN
20 :
21 : // TEMPLATE CLASS _Locbase
22 : template<class _Dummy>
23 : class _Locbase
24 : { // define templatized category constants, instantiate on demand
25 : public:
26 : _PGLOBAL static const int collate = _M_COLLATE;
27 : _PGLOBAL static const int ctype = _M_CTYPE;
28 : _PGLOBAL static const int monetary = _M_MONETARY;
29 : _PGLOBAL static const int numeric = _M_NUMERIC;
30 : _PGLOBAL static const int time = _M_TIME;
31 : _PGLOBAL static const int messages = _M_MESSAGES;
32 : _PGLOBAL static const int all = _M_ALL;
33 : _PGLOBAL static const int none = 0;
34 : };
35 :
36 : template<class _Dummy>
37 : const int _Locbase<_Dummy>::collate;
38 : template<class _Dummy>
39 : const int _Locbase<_Dummy>::ctype;
40 : template<class _Dummy>
41 : const int _Locbase<_Dummy>::monetary;
42 : template<class _Dummy>
43 : const int _Locbase<_Dummy>::numeric;
44 : template<class _Dummy>
45 : const int _Locbase<_Dummy>::time;
46 : template<class _Dummy>
47 : const int _Locbase<_Dummy>::messages;
48 : template<class _Dummy>
49 : const int _Locbase<_Dummy>::all;
50 : template<class _Dummy>
51 : const int _Locbase<_Dummy>::none;
52 :
53 : // CLASS locale
54 : class locale;
55 : template<class _Facet>
56 : const _Facet& __CRTDECL use_facet(const locale&);
57 :
58 : // warning 4412 is benign here
59 : #pragma warning(push)
60 : #pragma warning(disable:4412)
61 : class _CRTIMP2_PURE locale
62 : : public _Locbase<int>
63 : { // nonmutable collection of facets that describe a locale
64 : public:
65 : typedef int category;
66 :
67 : // CLASS id
68 : class _CRTIMP2_PURE id
69 : { // identifier stamp, unique for each distinct kind of facet
70 : public:
71 : __CLR_OR_THIS_CALL id(size_t _Val = 0)
72 : : _Id(_Val)
73 9 : { // construct with specified stamp value
74 9 : }
75 :
76 : __CLR_OR_THIS_CALL operator size_t()
77 10 : { // get stamp, with lazy allocation
78 10 : if (_Id == 0)
79 : { // still zero, allocate stamp
80 10 : _BEGIN_LOCK(_LOCK_LOCALE)
81 10 : if (_Id == 0)
82 10 : _Id = ++_Id_cnt;
83 10 : _END_LOCK()
84 : }
85 10 : return (_Id);
86 10 : }
87 :
88 : private:
89 : __CLR_OR_THIS_CALL id(const id&); // not defined
90 : id& __CLR_OR_THIS_CALL operator=(const id&); // not defined
91 :
92 : size_t _Id; // the identifier stamp
93 : static _MRTIMP2_NPURE int& __cdecl _Id_cnt_func();
94 : #ifdef _M_CEE_PURE
95 : static int& _Id_cnt; // static source of unique stamps
96 : #else
97 : __PURE_APPDOMAIN_GLOBAL static int _Id_cnt; // static source of unique stamps
98 : #endif
99 : };
100 :
101 : class _Locimp;
102 :
103 : // class facet
104 : class facet
105 : { // base class for all locale facets, performs reference counting
106 : friend class locale;
107 : friend class _Locimp;
108 :
109 : public:
110 : _CRTIMP2_PURE static size_t __CLRCALL_OR_CDECL _Getcat(const facet ** = 0,
111 : const locale * = 0)
112 : { // get category value, or -1 if no corresponding C category
113 : return ((size_t)(-1));
114 : }
115 :
116 : _CRTIMP2_PURE void __CLR_OR_THIS_CALL _Incref()
117 10 : { // safely increment the reference count
118 10 : _BEGIN_LOCK(_LOCK_LOCALE)
119 10 : if (_Refs < (size_t)(-1))
120 10 : ++_Refs;
121 10 : _END_LOCK()
122 10 : }
123 :
124 : _CRTIMP2_PURE facet *__CLR_OR_THIS_CALL _Decref()
125 10 : { // safely decrement the reference count, return this when dead
126 10 : _BEGIN_LOCK(_LOCK_LOCALE)
127 10 : if (0 < _Refs && _Refs < (size_t)(-1))
128 10 : --_Refs;
129 10 : return (_Refs == 0 ? this : 0);
130 : _END_LOCK()
131 10 : }
132 :
133 : void __CLR_OR_THIS_CALL _Register()
134 10 : {
135 : #if defined(_M_CEE)
136 : facet_Register_m(this);
137 : #else
138 10 : facet_Register(this);
139 : #endif
140 10 : }
141 :
142 : #if defined(_DEBUG) && !defined(_M_X64)
143 : _CRTIMP2_PURE void * __CLRCALL_OR_CDECL operator new(size_t _Size)
144 : { // replace operator new
145 : return (operator new(_Size, std::_DebugHeapTag_func(),
146 : __FILE__, __LINE__));
147 : }
148 :
149 : _CRTIMP2_PURE void * __CLRCALL_OR_CDECL operator new(size_t _Size,
150 : const std::_DebugHeapTag_t& _Tag, _In_opt_z_ char *_File, int _Line)
151 10 : { // replace debugging operator new
152 10 : return (::operator new(_Size, _Tag, _File, _Line));
153 10 : }
154 :
155 : _CRTIMP2_PURE void __CLRCALL_OR_CDECL operator delete(void *_Ptr,
156 : const std::_DebugHeapTag_t&, _In_opt_z_ char *, int)
157 0 : { // replace debugging operator delete
158 0 : operator delete(_Ptr);
159 0 : }
160 :
161 : _CRTIMP2_PURE void __CLRCALL_OR_CDECL operator delete(void *_Ptr)
162 0 : { // replace operator delete
163 0 : std::_DebugHeapDelete((facet*)_Ptr);
164 0 : }
165 : #endif /* defined(_DEBUG) */
166 :
167 :
168 : // _PROTECTED:
169 : _CRTIMP2_PURE virtual __CLR_OR_THIS_CALL ~facet()
170 10 : { // destroy the object
171 10 : }
172 :
173 : protected:
174 : _CRTIMP2_PURE explicit __CLR_OR_THIS_CALL facet(size_t _Initrefs = 0)
175 : : _Refs(_Initrefs)
176 10 : { // construct with initial reference count
177 10 : }
178 :
179 : private:
180 : #if defined(_M_CEE)
181 : static void __CLRCALL_OR_CDECL facet_Register_m(facet *); // queue up lazy facet for destruction
182 : #else
183 : static void __CLRCALL_OR_CDECL facet_Register(facet *); // queue up lazy facet for destruction
184 : #endif
185 :
186 : __CLR_OR_THIS_CALL facet(const facet&); // not defined
187 : facet& __CLR_OR_THIS_CALL operator=(const facet&); // not defined
188 :
189 : size_t _Refs; // the reference count
190 : };
191 :
192 : #pragma warning(push)
193 : #pragma warning(disable:4275)
194 : // CLASS _Locimp
195 : class _CRTIMP2_PURE _Locimp
196 : : public facet
197 : { // reference-counted actual implementation of a locale
198 : _PROTECTED:
199 : __CLR_OR_THIS_CALL ~_Locimp()
200 : {
201 : _Locimp_dtor(this);
202 : }
203 :
204 : private:
205 : static _MRTIMP2_NPURE void __cdecl _Locimp_dtor(_Locimp *); // destoy the object
206 : static void _Locimp_ctor(_Locimp *,const _Locimp&); // copy a _Locimp
207 : static _MRTIMP2_NPURE void __cdecl _Locimp_Addfac(_Locimp *,facet *, size_t); // add a facet
208 : friend class locale;
209 :
210 : __CLR_OR_THIS_CALL _Locimp(bool _Transparent = false)
211 : : locale::facet(1), _Facetvec(0), _Facetcount(0),
212 : _Catmask(none), _Xparent(_Transparent), _Name("*")
213 : { }
214 :
215 : __CLR_OR_THIS_CALL _Locimp(const _Locimp& _Right)
216 : : locale::facet(1), _Facetvec(0), _Facetcount(_Right._Facetcount),
217 : _Catmask(_Right._Catmask), _Xparent(_Right._Xparent), _Name(_Right._Name)
218 : {
219 : _Locimp_ctor(this, _Right);
220 : }
221 :
222 : void __CLR_OR_THIS_CALL _Addfac(facet *_Pfacet, size_t _Id)
223 : {
224 : _Locimp_Addfac(this, _Pfacet, _Id);
225 : }
226 :
227 : static _Locimp * _Makeloc(const _Locinfo&,
228 : category, _Locimp *, const locale *); // make essential facets
229 :
230 : static void _Makewloc(const _Locinfo&,
231 : category, _Locimp *, const locale *); // make wchar_t facets
232 :
233 : #ifdef _NATIVE_WCHAR_T_DEFINED
234 : static void _Makeushloc(const _Locinfo&,
235 : category, _Locimp *, const locale *); // make ushort facets
236 : #endif /* _NATIVE_WCHAR_T_DEFINED */
237 :
238 : static void _Makexloc(const _Locinfo&,
239 : category, _Locimp *, const locale *); // make remaining facets
240 :
241 : facet **_Facetvec; // pointer to vector of facets
242 : size_t _Facetcount; // size of vector of facets
243 : category _Catmask; // mask describing implemented categories
244 : bool _Xparent; // true if locale is transparent
245 : _STRING_CRT _Name; // locale name, or "*" if not known
246 :
247 : static _MRTIMP2_NPURE _Locimp *& __cdecl _Clocptr_func(); // pointer to "C" locale object
248 : #ifdef _M_CEE_PURE
249 : static _Locimp *&_Clocptr; // pointer to "C" locale object
250 : #else
251 : __PURE_APPDOMAIN_GLOBAL static _Locimp *_Clocptr; // pointer to "C" locale object
252 : #endif
253 : private:
254 : _Locimp& __CLR_OR_THIS_CALL operator=(const _Locimp&); // not defined
255 :
256 : };
257 : #pragma warning(pop)
258 :
259 : _DEPRECATED locale& __CLR_OR_THIS_CALL _Addfac(facet *_Fac, size_t _Id,
260 : size_t _Catmask)
261 : {
262 : if (1 < this->_Ptr->_Refs)
263 : { // shared, make private copy before altering
264 : this->_Ptr->_Decref();
265 : this->_Ptr = _NEW_CRT _Locimp(*this->_Ptr);
266 : }
267 : this->_Ptr->_Addfac(_Fac, _Id);
268 :
269 : if (_Catmask != 0)
270 : this->_Ptr->_Name = "*";
271 : return (*this);
272 : }
273 :
274 :
275 : template<class _Elem,
276 : class _Traits,
277 : class _Alloc>
278 : bool __CLR_OR_THIS_CALL operator()(const basic_string<_Elem, _Traits, _Alloc>& _Left,
279 : const basic_string<_Elem, _Traits, _Alloc>& _Right) const
280 : { // compare _Left and _Right strings using collate facet in locale
281 : const std::collate<_Elem>& _Coll_fac =
282 : std::use_facet<std::collate<_Elem> >(*this);
283 :
284 : return (_Coll_fac.compare(_Left.c_str(), _Left.c_str() + _Left.size(),
285 : _Right.c_str(), _Right.c_str() + _Right.size()) < 0);
286 : }
287 :
288 : template<class _Facet>
289 : locale __CLR_OR_THIS_CALL combine(const locale& _Loc) const
290 : { // combine two locales
291 : _Facet *_Facptr;
292 :
293 : _TRY_BEGIN
294 : _Facptr = (_Facet *)&std::use_facet<_Facet>(_Loc);
295 : _CATCH_ALL
296 : _THROW(runtime_error, "locale::combine facet missing");
297 : _CATCH_END
298 :
299 : _Locimp *_Newimp = _NEW_CRT _Locimp(*_Ptr);
300 : _Newimp->_Addfac(_Facptr, _Facet::id);
301 : _Newimp->_Catmask = 0;
302 : _Newimp->_Name = "*";
303 : return (locale(_Newimp));
304 : }
305 :
306 : template<class _Facet>
307 : __CLR_OR_THIS_CALL locale(const locale& _Loc, const _Facet *_Facptr)
308 : : _Ptr(_NEW_CRT _Locimp(*_Loc._Ptr))
309 : { // construct from _Loc, replacing facet with *_Facptr
310 : if (_Facptr != 0)
311 : { // replace facet
312 : _Ptr->_Addfac((_Facet *)_Facptr, _Facet::id);
313 : if (_Facet::_Getcat() != (size_t)(-1))
314 : { // no C category
315 : _Ptr->_Catmask = 0;
316 : _Ptr->_Name = "*";
317 : }
318 : }
319 : }
320 :
321 :
322 : __CLR_OR_THIS_CALL locale() _THROW0()
323 : : _Ptr(_Init())
324 10 : { // construct from current locale
325 10 : _Getgloballocale()->_Incref();
326 10 : }
327 :
328 : __CLR_OR_THIS_CALL locale(_Uninitialized)
329 : { // defer construction
330 : }
331 :
332 : __CLR_OR_THIS_CALL locale(const locale& _Right) _THROW0()
333 : : _Ptr(_Right._Ptr)
334 10 : { // construct by copying
335 10 : _Ptr->_Incref();
336 10 : }
337 :
338 : __CLR_OR_THIS_CALL locale(const locale& _Loc, const locale& _Other,
339 : category _Cat) // construct from locale and category in another locale
340 : : _Ptr(_NEW_CRT _Locimp(*_Loc._Ptr))
341 : { // construct a locale by copying named facets
342 : _TRY_BEGIN
343 : _BEGIN_LOCINFO(_Lobj(_Loc._Ptr->_Catmask, _Loc._Ptr->_Name.c_str()))
344 : _Locimp::_Makeloc(_Lobj._Addcats(_Cat & _Other._Ptr->_Catmask,
345 : _Other._Ptr->_Name.c_str()), _Cat, _Ptr, &_Other);
346 : _END_LOCINFO()
347 : _CATCH_ALL
348 : _DELETE_CRT(_Ptr->_Decref());
349 : _RERAISE;
350 : _CATCH_END
351 : }
352 :
353 : explicit __CLR_OR_THIS_CALL locale(const char *_Locname,
354 : category _Cat = all) // construct from named locale for category
355 : : _Ptr(_NEW_CRT _Locimp)
356 : { // construct a locale with named facets
357 : _TRY_BEGIN
358 : _Init();
359 : _BEGIN_LOCINFO(_Lobj(_Cat, _Locname))
360 : if (_Lobj._Getname().compare("*") == 0)
361 : _THROW(runtime_error, "bad locale name");
362 : _Locimp::_Makeloc(_Lobj, _Cat, _Ptr, 0);
363 : _END_LOCINFO()
364 : _CATCH_ALL
365 : _DELETE_CRT(_Ptr->_Decref());
366 : _RERAISE;
367 : _CATCH_END
368 : }
369 :
370 : __CLR_OR_THIS_CALL locale(const locale& _Loc, const char * _Locname,
371 : category _Cat) // construct from locale and category in named locale
372 : : _Ptr(_NEW_CRT _Locimp(*_Loc._Ptr))
373 : { // construct a locale by copying, replacing named facets
374 : _TRY_BEGIN
375 : _BEGIN_LOCINFO(_Lobj(_Loc._Ptr->_Catmask, _Loc._Ptr->_Name.c_str()))
376 : bool _Hadname = _Lobj._Getname().compare("*") != 0;
377 : _Lobj._Addcats(_Cat, _Locname);
378 :
379 : if (_Hadname && _Lobj._Getname().compare("*") == 0)
380 : _THROW(runtime_error, "bad locale name");
381 : _Locimp::_Makeloc(_Lobj, _Cat, _Ptr, 0);
382 : _END_LOCINFO()
383 : _CATCH_ALL
384 : _DELETE_CRT(_Ptr->_Decref());
385 : _RERAISE;
386 : _CATCH_END
387 : }
388 :
389 : __CLR_OR_THIS_CALL ~locale() _THROW0()
390 10 : { // destroy the object
391 10 : if (_Ptr != 0)
392 10 : _DELETE_CRT(_Ptr->_Decref());
393 10 : }
394 :
395 : locale& __CLR_OR_THIS_CALL operator=(const locale& _Right) _THROW0()
396 : { // assign a locale
397 : if (_Ptr != _Right._Ptr)
398 : { // different implementation, point at new one
399 : _DELETE_CRT(_Ptr->_Decref());
400 : _Ptr = _Right._Ptr;
401 : _Ptr->_Incref();
402 : }
403 : return (*this);
404 : }
405 :
406 : string __CLR_OR_THIS_CALL name() const
407 10 : { // return locale name
408 10 : return (_Ptr->_Name);
409 10 : }
410 :
411 : const facet *__CLR_OR_THIS_CALL _Getfacet(size_t _Id) const // get facet by id
412 10 : { // look up a facet in locale object
413 : const facet *_Facptr = _Id < _Ptr->_Facetcount
414 10 : ? _Ptr->_Facetvec[_Id] : 0; // null if id off end
415 10 : if (_Facptr != 0 || !_Ptr->_Xparent)
416 10 : return (_Facptr); // found facet or not transparent, return pointer
417 : else
418 : { // look in current locale
419 0 : locale::_Locimp *_Ptr = _Getgloballocale();
420 : return (_Id < _Ptr->_Facetcount
421 : ? _Ptr->_Facetvec[_Id] // get from current locale
422 0 : : 0); // no entry in current locale
423 : }
424 10 : }
425 :
426 :
427 : bool __CLR_OR_THIS_CALL operator==(const locale& _Loc) const
428 : { // compare locales for equality
429 : return (_Ptr == _Loc._Ptr
430 : || name().compare("*") != 0 && name().compare(_Loc.name()) == 0);
431 : }
432 :
433 : bool __CLR_OR_THIS_CALL operator!=(const locale& _Right) const
434 : { // test for locale inequality
435 : return (!(*this == _Right));
436 : }
437 :
438 : static _MRTIMP2_NPURE const locale& __cdecl classic(); // return classic "C" locale
439 :
440 : static _MRTIMP2_NPURE locale __cdecl global(const locale&); // return current locale
441 :
442 : static _MRTIMP2_NPURE locale __cdecl empty(); // return empty (transparent) locale
443 :
444 : private:
445 : locale(_Locimp *_Ptrimp)
446 : : _Ptr(_Ptrimp)
447 : { // construct from _Locimp pointer
448 : }
449 :
450 : static _MRTIMP2_NPURE _Locimp *__cdecl _Getgloballocale();
451 : static _MRTIMP2_NPURE _Locimp *__cdecl _Init(); // initialize locale
452 : static _MRTIMP2_NPURE void __cdecl _Setgloballocale(void *);
453 :
454 : _Locimp *_Ptr; // pointer to locale implementation object
455 : };
456 : #pragma warning(pop)
457 :
458 : // SUPPORT TEMPLATES
459 : template<class _Facet>
460 : struct _Facetptr
461 : { // store pointer to lazy facet for use_facet
462 : __PURE_APPDOMAIN_GLOBAL static const locale::facet *_Psave;
463 : };
464 :
465 : template<class _Facet>
466 : __PURE_APPDOMAIN_GLOBAL const locale::facet *_Facetptr<_Facet>::_Psave = 0;
467 :
468 : template<class _Facet> inline _DEPRECATED
469 : locale _Addfac(locale _Loc, const _Facet *_Facptr)
470 : { // add facet to locale -- retained
471 : size_t _Cat = _Facet::_Getcat(0, 0);
472 : locale _Newloc = _Loc._Addfac((_Facet *)_Facptr, _Facet::id, _Cat);
473 :
474 : return (_Newloc);
475 : }
476 :
477 : #define _ADDFAC(loc, pfac) locale(loc, pfac) /* add facet to locale */
478 :
479 : #define _USE(loc, fac) \
480 : use_facet<fac >(loc) /* get facet reference from locale */
481 :
482 : template<class _Facet> inline
483 : const _Facet& __CRTDECL use_facet(const locale& _Loc)
484 :
485 :
486 28 : { // get facet reference from locale
487 28 : _BEGIN_LOCK(_LOCK_LOCALE) // the thread lock, make get atomic
488 : const locale::facet *_Psave =
489 28 : _Facetptr<_Facet>::_Psave; // static pointer to lazy facet
490 :
491 28 : size_t _Id = _Facet::id;
492 28 : const locale::facet *_Pf = _Loc._Getfacet(_Id);
493 :
494 28 : if (_Pf != 0)
495 : ; // got facet from locale
496 28 : else if (_Psave != 0)
497 28 : _Pf = _Psave; // lazy facet already allocated
498 28 : else if (_Facet::_Getcat(&_Psave, &_Loc) == (size_t)(-1))
499 :
500 : #if _HAS_EXCEPTIONS
501 0 : _THROW_NCEE(bad_cast, _EMPTY_ARGUMENT); // lazy disallowed
502 :
503 : #else /* _HAS_EXCEPTIONS */
504 : abort(); // lazy disallowed
505 : #endif /* _HAS_EXCEPTIONS */
506 :
507 0 : else
508 : { // queue up lazy facet for destruction
509 28 : _Pf = _Psave;
510 28 : _Facetptr<_Facet>::_Psave = _Psave;
511 :
512 28 : locale::facet *_Pfmod = (_Facet *)_Psave;
513 28 : _Pfmod->_Incref();
514 28 : _Pfmod->_Register();
515 : }
516 :
517 28 : return ((const _Facet&)(*_Pf)); // should be dynamic_cast
518 : _END_LOCK()
519 28 : }
520 :
521 : template<class _Facet> inline _DEPRECATED
522 : const _Facet& __CRTDECL use_facet(const locale& _Loc, const _Facet *,
523 : bool = false)
524 : { // get facet reference from locale -- retained, 2/3 arg versions
525 : return use_facet<_Facet>(_Loc);
526 : }
527 :
528 : // TEMPLATE FUNCTION _Getloctxt
529 : template<class _Elem,
530 : class _InIt> inline
531 : int __CRTDECL _Getloctxt(_InIt& _First, _InIt& _Last, size_t _Numfields,
532 : const _Elem *_Ptr)
533 : { // find field at _Ptr that matches longest in [_First, _Last)
534 : for (size_t _Off = 0; _Ptr[_Off] != (_Elem)0; ++_Off)
535 : if (_Ptr[_Off] == _Ptr[0])
536 : ++_Numfields; // add fields with leading mark to initial count
537 : string _Str(_Numfields, '\0'); // one column counter for each field
538 :
539 : int _Ans = -2; // no candidates so far
540 : for (size_t _Column = 1; ; ++_Column, ++_First, _Ans = -1)
541 : { // test each element against all viable fields
542 : bool _Prefix = false; // seen at least one valid prefix
543 : size_t _Off = 0; // offset into fields
544 : size_t _Field = 0; // current field number
545 :
546 : for (; _Field < _Numfields; ++_Field)
547 : { // test element at _Column in field _Field
548 : for (; _Ptr[_Off] != (_Elem)0 && _Ptr[_Off] != _Ptr[0]; ++_Off)
549 : ; // find beginning of field
550 :
551 : if (_Str[_Field] != '\0')
552 : _Off += _Str[_Field]; // skip tested columns in field
553 : else if (_Ptr[_Off += _Column] == _Ptr[0]
554 : || _Ptr[_Off] == (_Elem)0)
555 : { // matched all of field, save as possible answer
556 : _Str[_Field] = (char)(_Column < 127
557 : ? _Column : 127); // save skip count if small enough
558 : _Ans = (int)_Field; // save answer
559 : }
560 : else if (_First == _Last || _Ptr[_Off] != *_First)
561 : _Str[_Field] = (char)(_Column < 127
562 : ? _Column : 127); // no match, just save skip count
563 : else
564 : _Prefix = true; // still a valid prefix
565 : }
566 :
567 : if (!_Prefix || _First == _Last)
568 : break; // no pending prefixes or no input, give up
569 : }
570 : return (_Ans); // return field number or negative value on failure
571 : }
572 :
573 : // TEMPLATE FUNCTION _Maklocbyte
574 : #define _MAKLOCBYTE(Elem, chr, cvt) \
575 : _Maklocbyte((_Elem)chr, cvt) /* convert Elem to char */
576 :
577 : template<class _Elem> inline
578 : char __CRTDECL _Maklocbyte(_Elem _Char,
579 : const _Locinfo::_Cvtvec&)
580 : { // convert _Elem to char using _Cvtvec
581 : return ((char)(unsigned char)_Char);
582 : }
583 :
584 : template<> inline
585 : char __CRTDECL _Maklocbyte(wchar_t _Char,
586 : const _Locinfo::_Cvtvec& _Cvt)
587 : { // convert wchar_t to char using _Cvtvec
588 : char _Byte = '\0';
589 : _Mbstinit(_Mbst1);
590 : _Wcrtomb(&_Byte, _Char, &_Mbst1, &_Cvt);
591 : return (_Byte);
592 : }
593 :
594 :
595 : // TEMPLATE FUNCTION _Maklocchr
596 : #define _MAKLOCCHR(Elem, chr, cvt) \
597 : _Maklocchr(chr, (Elem *)0, cvt) /* convert char to Elem */
598 :
599 : template<class _Elem> inline
600 : _Elem __CRTDECL _Maklocchr(char _Byte, _Elem *,
601 : const _Locinfo::_Cvtvec&)
602 9 : { // convert char to _Elem using _Cvtvec
603 9 : return ((_Elem)(unsigned char)_Byte);
604 9 : }
605 :
606 : template<> inline
607 : wchar_t __CRTDECL _Maklocchr(char _Byte, _In_opt_z_ wchar_t *,
608 : const _Locinfo::_Cvtvec& _Cvt)
609 : { // convert char to wchar_t using _Cvtvec
610 : wchar_t _Wc = L'\0';
611 : _Mbstinit(_Mbst1);
612 : _Mbrtowc(&_Wc, &_Byte, 1, &_Mbst1, &_Cvt);
613 : return (_Wc);
614 : }
615 :
616 :
617 : // TEMPLATE FUNCTION _Maklocstr
618 : #define _MAKLOCSTR(_Elem, _Str, _Cvt) \
619 : _Maklocstr(_Str, (_Elem *)0, _Cvt) // convert C string to _Elem sequence
620 :
621 : template<class _Elem> inline
622 : _Elem *__CRTDECL _Maklocstr(const char *_Ptr, _Elem *,
623 : const _Locinfo::_Cvtvec&)
624 9 : { // convert C string to _Elem sequence using _Cvtvec
625 9 : size_t _Count = ::strlen(_Ptr) + 1;
626 9 : _Elem *_Ptrdest = _NEW_CRT _Elem[_Count];
627 :
628 : #pragma warning(push)
629 : #pragma warning(disable: 6011)
630 : /* prefast noise */
631 9 : for (_Elem *_Ptrnext = _Ptrdest; 0 < _Count; --_Count, ++_Ptrnext, ++_Ptr)
632 9 : *_Ptrnext = (_Elem)(unsigned char)*_Ptr;
633 9 : return (_Ptrdest);
634 : #pragma warning(pop)
635 9 : }
636 :
637 : template<> inline
638 : wchar_t *__CRTDECL _Maklocstr(const char *_Ptr, _In_opt_z_ wchar_t *,
639 : const _Locinfo::_Cvtvec& _Cvt)
640 : { // convert C string to wchar_t sequence using _Cvtvec
641 : size_t _Count, _Count1;
642 : size_t _Wchars;
643 : const char *_Ptr1;
644 : int _Bytes;
645 : wchar_t _Wc;
646 : _Mbstinit(_Mbst1);
647 :
648 : _Count1 = ::strlen(_Ptr) + 1;
649 : for (_Count = _Count1, _Wchars = 0, _Ptr1 = _Ptr; 0 < _Count;
650 : _Count -= _Bytes, _Ptr1 += _Bytes, ++_Wchars)
651 : if ((_Bytes = _Mbrtowc(&_Wc, _Ptr1, _Count, &_Mbst1, &_Cvt)) <= 0)
652 : break;
653 : ++_Wchars; // count terminating nul
654 :
655 : wchar_t *_Ptrdest = _NEW_CRT wchar_t[_Wchars];
656 : wchar_t *_Ptrnext = _Ptrdest;
657 : _Mbstinit(_Mbst2);
658 : #pragma warning(push)
659 : #pragma warning(disable: 6011)
660 : /* prefast noise */
661 : for (; 0 < _Wchars;
662 : _Count -= _Bytes, _Ptr += _Bytes, --_Wchars, ++_Ptrnext)
663 : if ((_Bytes = _Mbrtowc(_Ptrnext, _Ptr, _Count1, &_Mbst2, &_Cvt)) <= 0)
664 : break;
665 : *_Ptrnext = L'\0';
666 : #pragma warning(pop)
667 : return (_Ptrdest);
668 : }
669 :
670 :
671 : #pragma warning(push)
672 : #pragma warning(disable:4275)
673 : // STRUCT codecvt_base
674 : class _CRTIMP2_PURE codecvt_base
675 : : public locale::facet
676 : { // base class for codecvt
677 : public:
678 : enum
679 : { // constants for different parse states
680 : ok, partial, error, noconv};
681 : typedef int result;
682 :
683 : __CLR_OR_THIS_CALL codecvt_base(size_t _Refs = 0)
684 : : locale::facet(_Refs)
685 : { // default constructor
686 : }
687 :
688 : bool __CLR_OR_THIS_CALL always_noconv() const _THROW0()
689 : { // return true if conversions never change input (from codecvt)
690 : return (do_always_noconv());
691 : }
692 :
693 : int __CLR_OR_THIS_CALL max_length() const _THROW0()
694 : { // return maximum length required for a conversion (from codecvt)
695 : return (do_max_length());
696 : }
697 :
698 : int __CLR_OR_THIS_CALL encoding() const _THROW0()
699 : { // return length of code sequence (from codecvt)
700 : return (do_encoding());
701 : }
702 :
703 : __CLR_OR_THIS_CALL ~codecvt_base()
704 : { // destroy the object
705 : }
706 :
707 : protected:
708 : virtual bool __CLR_OR_THIS_CALL do_always_noconv() const _THROW0()
709 : { // return true if conversions never change input (from codecvt)
710 : return (true);
711 : }
712 :
713 : virtual int __CLR_OR_THIS_CALL do_max_length() const _THROW0()
714 : { // return maximum length required for a conversion (from codecvt)
715 : return (1);
716 : }
717 :
718 : virtual int __CLR_OR_THIS_CALL do_encoding() const _THROW0()
719 : { // return length of code sequence (from codecvt)
720 : return (1); // -1 ==> state dependent, 0 ==> varying length
721 : }
722 : };
723 : #pragma warning(pop)
724 :
725 : // TEMPLATE CLASS codecvt
726 : template<class _Elem,
727 : class _Byte,
728 : class _Statype>
729 : class codecvt
730 : : public codecvt_base
731 : { // facet for converting between _Elem and char (_Byte) sequences
732 : public:
733 : typedef _Elem intern_type;
734 : typedef _Byte extern_type;
735 : typedef _Statype state_type;
736 :
737 : result __CLR_OR_THIS_CALL in(_Statype& _State,
738 : const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1,
739 : _Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const
740 : { // convert bytes [_First1, _Last1) to [_First2, _Last)
741 : return (do_in(_State,
742 : _First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
743 : }
744 :
745 : result __CLR_OR_THIS_CALL out(_Statype& _State,
746 : const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1,
747 : _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
748 : { // convert [_First1, _Last1) to bytes [_First2, _Last2)
749 : return (do_out(_State,
750 : _First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
751 : }
752 :
753 : result __CLR_OR_THIS_CALL unshift(_Statype& _State,
754 : _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
755 : { // generate bytes to return to default shift state
756 : return (do_unshift(_State, _First2, _Last2, _Mid2));
757 : }
758 :
759 : int __CLR_OR_THIS_CALL length(const _Statype& _State, const _Byte *_First1,
760 : const _Byte *_Last1, size_t _Count) const
761 : { // return min(_Count, converted length of bytes [_First1, _Last1))
762 : return (do_length(_State, _First1, _Last1, _Count));
763 : }
764 :
765 : __PURE_APPDOMAIN_GLOBAL static locale::id id; // unique facet id
766 :
767 : explicit __CLR_OR_THIS_CALL codecvt(size_t _Refs = 0)
768 : : codecvt_base(_Refs)
769 : { // construct from current locale
770 : _BEGIN_LOCINFO(_Lobj)
771 : _Init(_Lobj);
772 : _END_LOCINFO()
773 : }
774 :
775 : __CLR_OR_THIS_CALL codecvt(const _Locinfo& _Lobj, size_t _Refs = 0)
776 : : codecvt_base(_Refs)
777 : { // construct from specified locale
778 : _Init(_Lobj);
779 : }
780 :
781 : static size_t __CLRCALL_OR_CDECL _Getcat(const locale::facet **_Ppf = 0,
782 : const locale *_Ploc = 0)
783 : { // return locale category mask and construct standard facet
784 : if (_Ppf != 0 && *_Ppf == 0)
785 : *_Ppf = _NEW_CRT codecvt<_Elem, _Byte, _Statype>(
786 : _Locinfo(_Ploc->name()));
787 : return (_X_CTYPE);
788 : }
789 :
790 : _PROTECTED:
791 : virtual __CLR_OR_THIS_CALL ~codecvt()
792 : { // destroy the object
793 : }
794 :
795 : protected:
796 : void __CLR_OR_THIS_CALL _Init(const _Locinfo&)
797 : { // initialize from _Locinfo object
798 : }
799 :
800 : virtual result __CLR_OR_THIS_CALL do_in(_Statype&,
801 : const _Byte *_First1, const _Byte *, const _Byte *& _Mid1,
802 : _Elem *_First2, _Elem *, _Elem *& _Mid2) const
803 : { // convert bytes [_First1, _Last1) to [_First2, _Last)
804 : _Mid1 = _First1, _Mid2 = _First2;
805 : return (noconv); // convert nothing
806 : }
807 :
808 : virtual result __CLR_OR_THIS_CALL do_out(_Statype&,
809 : const _Elem *_First1, const _Elem *, const _Elem *& _Mid1,
810 : _Byte *_First2, _Byte *, _Byte *& _Mid2) const
811 : { // convert [_First1, _Last1) to bytes [_First2, _Last)
812 : _Mid1 = _First1, _Mid2 = _First2;
813 : return (noconv); // convert nothing
814 : }
815 :
816 : virtual result __CLR_OR_THIS_CALL do_unshift(_Statype&,
817 : _Byte *_First2, _Byte *, _Byte *&_Mid2) const
818 : { // generate bytes to return to default shift state
819 : _Mid2 = _First2;
820 : return (noconv); // convert nothing
821 : }
822 :
823 : virtual int __CLR_OR_THIS_CALL do_length(const _Statype&, const _Byte *_First1,
824 : const _Byte *_Last1, size_t _Count) const
825 : { // return min(_Count, converted length of bytes [_First1, _Last1))
826 : return ((int)(_Count < (size_t)(_Last1 - _First1)
827 : ? _Count : _Last1 - _First1)); // assume 1-to-1 conversion
828 : }
829 : };
830 :
831 : // STATIC codecvt::id OBJECT
832 : template<class _Elem,
833 : class _Byte,
834 : class _Statype>
835 : __PURE_APPDOMAIN_GLOBAL locale::id codecvt<_Elem, _Byte, _Statype>::id;
836 :
837 : // CLASS codecvt<wchar_t, char, _Mbstatet>
838 : template<> class _CRTIMP2_PURE codecvt<wchar_t, char, _Mbstatet>
839 : : public codecvt_base
840 : { // facet for converting between wchar_t and char (_Byte) sequences
841 : public:
842 : typedef wchar_t _Elem;
843 : typedef char _Byte;
844 : typedef _Mbstatet _Statype;
845 : typedef _Elem intern_type;
846 : typedef _Byte extern_type;
847 : typedef _Statype state_type;
848 :
849 : result __CLR_OR_THIS_CALL in(_Statype& _State,
850 : const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1,
851 : _Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const
852 : { // convert bytes [_First1, _Last1) to [_First2, _Last)
853 : return (do_in(_State,
854 : _First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
855 : }
856 :
857 : result __CLR_OR_THIS_CALL out(_Statype& _State,
858 : const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1,
859 : _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
860 : { // convert [_First1, _Last1) to bytes [_First2, _Last)
861 : return (do_out(_State,
862 : _First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
863 : }
864 :
865 : result __CLR_OR_THIS_CALL unshift(_Statype& _State,
866 : _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
867 : { // generate bytes to return to default shift state
868 : return (do_unshift(_State,
869 : _First2, _Last2, _Mid2));
870 : }
871 :
872 : int __CLR_OR_THIS_CALL length(const _Statype& _State, const _Byte *_First1,
873 : const _Byte *_Last1, size_t _Count) const
874 : { // return min(_Count, converted length of bytes [_First1, _Last1))
875 : return (do_length(_State, _First1, _Last1, _Count));
876 : }
877 :
878 : static _MRTIMP2_NPURE locale::id& __cdecl _Id_func();
879 : #ifdef _M_CEE_PURE
880 : static locale::id& id; // unique facet id
881 : #else
882 : __PURE_APPDOMAIN_GLOBAL static locale::id id; // unique facet id
883 : #endif
884 :
885 : explicit __CLR_OR_THIS_CALL codecvt(size_t _Refs = 0)
886 : : codecvt_base(_Refs)
887 : { // construct from current locale
888 : _BEGIN_LOCINFO(_Lobj)
889 : _Init(_Lobj);
890 : _END_LOCINFO()
891 : }
892 :
893 : __CLR_OR_THIS_CALL codecvt(const _Locinfo& _Lobj, size_t _Refs = 0)
894 : : codecvt_base(_Refs)
895 : { // construct from specified locale
896 : _Init(_Lobj);
897 : }
898 :
899 : static size_t __CLRCALL_OR_CDECL _Getcat(const locale::facet **_Ppf = 0,
900 : const locale *_Ploc = 0)
901 : { // return locale category mask and construct standard facet
902 : if (_Ppf != 0 && *_Ppf == 0)
903 : *_Ppf = _NEW_CRT codecvt<_Elem, _Byte, _Statype>(
904 : _Locinfo(_Ploc->name()));
905 : return (_X_CTYPE);
906 : }
907 :
908 : _PROTECTED:
909 : virtual __CLR_OR_THIS_CALL ~codecvt()
910 : { // destroy the object
911 : }
912 :
913 : protected:
914 : void __CLR_OR_THIS_CALL _Init(const _Locinfo& _Lobj)
915 : { // initialize from _Lobj
916 : _Cvt = _Lobj._Getcvt();
917 : }
918 :
919 : virtual result __CLR_OR_THIS_CALL do_in(_Statype& _State,
920 : const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1,
921 : _Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const
922 : { // convert bytes [_First1, _Last1) to [_First2, _Last)
923 : _DEBUG_RANGE(_First1, _Last1);
924 : _DEBUG_RANGE(_First2, _Last2);
925 : _Mid1 = _First1, _Mid2 = _First2;
926 : result _Ans = _Mid1 == _Last1 ? ok : partial;
927 : int _Bytes;
928 :
929 : while (_Mid1 != _Last1 && _Mid2 != _Last2)
930 : switch (_Bytes = _Mbrtowc(_Mid2, _Mid1, _Last1 - _Mid1,
931 : &_State, &_Cvt))
932 : { // test result of locale-specific mbrtowc call
933 : case -2: // partial conversion
934 : _Mid1 = _Last1;
935 : return (_Ans);
936 :
937 : case -1: // failed conversion
938 : return (error);
939 :
940 : case 0: // may have converted null character
941 : if (*_Mid2 == (_Elem)0)
942 : _Bytes = (int)::strlen(_Mid1) + 1;
943 : // fall through
944 :
945 : default: // converted _Bytes bytes to a wchar_t
946 : if (_Bytes == -3)
947 : _Bytes = 0; // wchar_t generated from state info
948 : _Mid1 += _Bytes;
949 : ++_Mid2;
950 : _Ans = ok;
951 : }
952 : return (_Ans);
953 : }
954 :
955 : virtual result __CLR_OR_THIS_CALL do_out(_Statype& _State,
956 : const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1,
957 : _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
958 : { // convert [_First1, _Last1) to bytes [_First2, _Last)
959 : _DEBUG_RANGE(_First1, _Last1);
960 : _DEBUG_RANGE(_First2, _Last2);
961 : _Mid1 = _First1, _Mid2 = _First2;
962 : result _Ans = _Mid1 == _Last1 ? ok : partial;
963 : int _Bytes;
964 :
965 : while (_Mid1 != _Last1 && _Mid2 != _Last2)
966 : if ((int)MB_CUR_MAX <= _Last2 - _Mid2)
967 : if ((_Bytes = _Wcrtomb(_Mid2, *_Mid1,
968 : &_State, &_Cvt)) < 0)
969 : return (error); // locale-specific wcrtomb failed
970 : else
971 : ++_Mid1, _Mid2 += _Bytes, _Ans = ok;
972 : else
973 : { // destination possibly too small, convert into buffer
974 : _Byte _Buf[MB_LEN_MAX];
975 : _Statype _Stsave = _State;
976 :
977 : if ((_Bytes = _Wcrtomb(_Buf, *_Mid1,
978 : &_State, &_Cvt)) < 0)
979 : return (error); // locale-specific wcrtomb failed
980 : else if (_Last2 - _Mid2 < _Bytes)
981 : { // converted too many, roll back and return previous
982 : _State = _Stsave;
983 : return (_Ans);
984 : }
985 : else
986 : { // copy converted bytes from buffer
987 : _CRT_SECURE_MEMCPY(_Mid2, _Last2 - _Mid2, _Buf, _Bytes);
988 : ++_Mid1, _Mid2 += _Bytes, _Ans = ok;
989 : }
990 : }
991 : return (_Ans);
992 : }
993 :
994 : virtual result __CLR_OR_THIS_CALL do_unshift(_Statype& _State,
995 : _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
996 : { // generate bytes to return to default shift state
997 : _DEBUG_RANGE(_First2, _Last2);
998 : _Mid2 = _First2;
999 : result _Ans = ok;
1000 : int _Bytes;
1001 : _Byte _Buf[MB_LEN_MAX];
1002 : _Statype _Stsave = _State;
1003 :
1004 : if ((_Bytes = _Wcrtomb(_Buf, L'\0', &_State, &_Cvt)) <= 0)
1005 : _Ans = error; // locale-specific wcrtomb failed
1006 : else if (_Last2 - _Mid2 < --_Bytes)
1007 : { // converted too many, roll back and return
1008 : _State = _Stsave;
1009 : _Ans = partial;
1010 : }
1011 : else if (0 < _Bytes)
1012 : { // copy converted bytes from buffer
1013 : _CRT_SECURE_MEMCPY(_Mid2, _Last2 - _Mid2, _Buf, _Bytes);
1014 : _Mid2 += _Bytes;
1015 : }
1016 : return (_Ans);
1017 : }
1018 :
1019 : virtual int __CLR_OR_THIS_CALL do_length(const _Statype& _State, const _Byte *_First1,
1020 : const _Byte *_Last1, size_t _Count) const
1021 : { // return min(_Count, converted length of bytes [_First1, _Last1))
1022 :
1023 : #if _HAS_STRICT_CONFORMANCE
1024 : return ((int)(_Count < (size_t)(_Last1 - _First1)
1025 : ? _Count : _Last1 - _First1)); // assume 1-to-1 conversion
1026 :
1027 : #else /* _HAS_STRICT_CONFORMANCE */
1028 : _DEBUG_RANGE(_First1, _Last1);
1029 : int _Wchars;
1030 : const _Byte *_Mid1;
1031 : _Statype _Mystate = _State;
1032 :
1033 : for (_Wchars = 0, _Mid1 = _First1;
1034 : (size_t)_Wchars < _Count && _Mid1 != _Last1; )
1035 : { // convert another wchar_t
1036 : int _Bytes;
1037 : _Elem _Ch;
1038 :
1039 : switch (_Bytes = _Mbrtowc(&_Ch, _Mid1, _Last1 - _Mid1,
1040 : &_Mystate, &_Cvt))
1041 : { // test result of locale-specific mbrtowc call
1042 : case -2: // partial conversion
1043 : return (_Wchars);
1044 :
1045 : case -1: // failed conversion
1046 : return (_Wchars);
1047 :
1048 : case 0: // may have converted null character
1049 : if (_Ch == (_Elem)0)
1050 : _Bytes = (int)::strlen(_Mid1) + 1;
1051 : // fall through
1052 :
1053 : default: // converted _Bytes bytes to a wchar_t
1054 : if (_Bytes == -3)
1055 : _Bytes = 0; // wchar_t generated from state info
1056 : _Mid1 += _Bytes;
1057 : ++_Wchars;
1058 : }
1059 : }
1060 : return (_Wchars);
1061 : #endif /* _HAS_STRICT_CONFORMANCE */
1062 : }
1063 :
1064 : virtual bool __CLR_OR_THIS_CALL do_always_noconv() const _THROW0()
1065 : { // return true if conversions never change input
1066 : return (false);
1067 : }
1068 :
1069 : virtual int __CLR_OR_THIS_CALL do_max_length() const _THROW0()
1070 : { // return maximum length required for a conversion (from codecvt)
1071 : return (MB_LEN_MAX);
1072 : }
1073 :
1074 : private:
1075 : _Locinfo::_Cvtvec _Cvt; // locale info passed to _Mbrtowc, _Wcrtomb
1076 : };
1077 :
1078 : #ifdef _NATIVE_WCHAR_T_DEFINED
1079 : // CLASS codecvt<unsigned short, char, _Mbstatet>
1080 : template<> class _CRTIMP2_PURE codecvt<unsigned short, char, _Mbstatet>
1081 : : public codecvt_base
1082 : { // facet for converting between unsigned short and char sequences
1083 : public:
1084 : typedef unsigned short _Elem;
1085 : typedef char _Byte;
1086 : typedef _Mbstatet _Statype;
1087 : typedef _Elem intern_type;
1088 : typedef _Byte extern_type;
1089 : typedef _Statype state_type;
1090 :
1091 : result __CLR_OR_THIS_CALL in(_Statype& _State,
1092 : const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1,
1093 : _Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const
1094 : { // convert bytes [_First1, _Last1) to [_First2, _Last)
1095 : return (do_in(_State,
1096 : _First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
1097 : }
1098 :
1099 : result __CLR_OR_THIS_CALL out(_Statype& _State,
1100 : const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1,
1101 : _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
1102 : { // convert [_First1, _Last1) to bytes [_First2, _Last)
1103 : return (do_out(_State,
1104 : _First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
1105 : }
1106 :
1107 : result __CLR_OR_THIS_CALL unshift(_Statype& _State,
1108 : _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
1109 : { // generate bytes to return to default shift state
1110 : return (do_unshift(_State,
1111 : _First2, _Last2, _Mid2));
1112 : }
1113 :
1114 : int __CLR_OR_THIS_CALL length(const _Statype& _State, const _Byte *_First1,
1115 : const _Byte *_Last1, size_t _Count) const
1116 : { // return min(_Count, converted length of bytes [_First1, _Last1))
1117 : return (do_length(_State, _First1, _Last1, _Count));
1118 : }
1119 :
1120 : static _MRTIMP2_NPURE locale::id& __cdecl _Id_func();
1121 : #ifdef _M_CEE_PURE
1122 : static locale::id& id; // unique facet id
1123 : #else
1124 : __PURE_APPDOMAIN_GLOBAL static locale::id id; // unique facet id
1125 : #endif
1126 :
1127 : explicit __CLR_OR_THIS_CALL codecvt(size_t _Refs = 0)
1128 : : codecvt_base(_Refs)
1129 : { // construct from current locale
1130 : _BEGIN_LOCINFO(_Lobj)
1131 : _Init(_Lobj);
1132 : _END_LOCINFO()
1133 : }
1134 :
1135 : __CLR_OR_THIS_CALL codecvt(const _Locinfo& _Lobj, size_t _Refs = 0)
1136 : : codecvt_base(_Refs)
1137 : { // construct from specified locale
1138 : _Init(_Lobj);
1139 : }
1140 :
1141 : static size_t __CLRCALL_OR_CDECL _Getcat(const locale::facet **_Ppf = 0,
1142 : const locale *_Ploc = 0)
1143 : { // return locale category mask and construct standard facet
1144 : if (_Ppf != 0 && *_Ppf == 0)
1145 : *_Ppf = _NEW_CRT codecvt<_Elem, _Byte, _Statype>(
1146 : _Locinfo(_Ploc->name()));
1147 : return (_X_CTYPE);
1148 : }
1149 :
1150 : _PROTECTED:
1151 : virtual __CLR_OR_THIS_CALL ~codecvt()
1152 : { // destroy the object
1153 : }
1154 :
1155 : protected:
1156 : __CLR_OR_THIS_CALL codecvt(const char *_Locname, size_t _Refs = 0)
1157 : : codecvt_base(_Refs)
1158 : { // construct from specified locale
1159 : _BEGIN_LOCINFO(_Lobj(_Locname))
1160 : _Init(_Lobj);
1161 : _END_LOCINFO()
1162 : }
1163 :
1164 : void __CLR_OR_THIS_CALL _Init(const _Locinfo& _Lobj)
1165 : { // initialize from _Lobj
1166 : _Cvt = _Lobj._Getcvt();
1167 : }
1168 :
1169 : virtual result __CLR_OR_THIS_CALL do_in(_Statype& _State,
1170 : const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1,
1171 : _Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const
1172 : { // convert bytes [_First1, _Last1) to [_First2, _Last)
1173 : _DEBUG_RANGE(_First1, _Last1);
1174 : _DEBUG_RANGE(_First2, _Last2);
1175 : _Mid1 = _First1, _Mid2 = _First2;
1176 : result _Ans = _Mid1 == _Last1 ? ok : partial;
1177 : int _Bytes;
1178 :
1179 : while (_Mid1 != _Last1 && _Mid2 != _Last2)
1180 : switch (_Bytes = _Mbrtowc((wchar_t *)_Mid2, _Mid1, _Last1 - _Mid1,
1181 : &_State, &_Cvt))
1182 : { // test result of locale-specific mbrtowc call
1183 : case -2: // partial conversion
1184 : _Mid1 = _Last1;
1185 : return (_Ans);
1186 :
1187 : case -1: // failed conversion
1188 : return (error);
1189 :
1190 : case 0: // may have converted null character
1191 : if (*_Mid2 == (_Elem)0)
1192 : _Bytes = (int)::strlen(_Mid1) + 1;
1193 : // fall through
1194 :
1195 : default: // converted _Bytes bytes to an unsigned short
1196 : if (_Bytes == -3)
1197 : _Bytes = 0; // wchar_t generated from state info
1198 : _Mid1 += _Bytes;
1199 : ++_Mid2;
1200 : _Ans = ok;
1201 : }
1202 : return (_Ans);
1203 : }
1204 :
1205 : virtual result __CLR_OR_THIS_CALL do_out(_Statype& _State,
1206 : const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1,
1207 : _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
1208 : { // convert [_First1, _Last1) to bytes [_First2, _Last)
1209 : _DEBUG_RANGE(_First1, _Last1);
1210 : _DEBUG_RANGE(_First2, _Last2);
1211 : _Mid1 = _First1, _Mid2 = _First2;
1212 : result _Ans = _Mid1 == _Last1 ? ok : partial;
1213 : int _Bytes;
1214 :
1215 : while (_Mid1 != _Last1 && _Mid2 != _Last2)
1216 : if (MB_LEN_MAX <= _Last2 - _Mid2)
1217 : if ((_Bytes = _Wcrtomb(_Mid2, *_Mid1,
1218 : &_State, &_Cvt)) < 0)
1219 : return (error); // locale-specific wcrtomb failed
1220 : else
1221 : ++_Mid1, _Mid2 += _Bytes, _Ans = ok;
1222 : else
1223 : { // destination possibly too small, convert into buffer
1224 : _Byte _Buf[MB_LEN_MAX];
1225 : _Statype _Stsave = _State;
1226 :
1227 : if ((_Bytes = _Wcrtomb(_Buf, *_Mid1,
1228 : &_State, &_Cvt)) < 0)
1229 : return (error); // locale-specific wcrtomb failed
1230 : else if (_Last2 - _Mid2 < _Bytes)
1231 : { // converted too many, roll back and return previous
1232 : _State = _Stsave;
1233 : return (_Ans);
1234 : }
1235 : else
1236 : { // copy converted bytes from buffer
1237 : _CRT_SECURE_MEMCPY(_Mid2, _Last2 - _Mid2, _Buf, _Bytes);
1238 : ++_Mid1, _Mid2 += _Bytes, _Ans = ok;
1239 : }
1240 : }
1241 : return (_Ans);
1242 : }
1243 :
1244 : virtual result __CLR_OR_THIS_CALL do_unshift(_Statype& _State,
1245 : _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
1246 : { // generate bytes to return to default shift state
1247 : _DEBUG_RANGE(_First2, _Last2);
1248 : _Mid2 = _First2;
1249 : result _Ans = ok;
1250 : int _Bytes;
1251 : _Byte _Buf[MB_LEN_MAX];
1252 : _Statype _Stsave = _State;
1253 :
1254 : if ((_Bytes = _Wcrtomb(_Buf, L'\0', &_State, &_Cvt)) <= 0)
1255 : _Ans = error; // locale-specific wcrtomb failed
1256 : else if (_Last2 - _Mid2 < --_Bytes)
1257 : { // converted too many, roll back and return
1258 : _State = _Stsave;
1259 : _Ans = partial;
1260 : }
1261 : else if (0 < _Bytes)
1262 : { // copy converted bytes from buffer
1263 : _CRT_SECURE_MEMCPY(_Mid2, _Last2 - _Mid2, _Buf, _Bytes);
1264 : _Mid2 += _Bytes;
1265 : }
1266 : return (_Ans);
1267 : }
1268 :
1269 : virtual int __CLR_OR_THIS_CALL do_length(const _Statype& _State, const _Byte *_First1,
1270 : const _Byte *_Last1, size_t _Count) const
1271 : { // return min(_Count, converted length of bytes [_First1, _Last1))
1272 : _DEBUG_RANGE(_First1, _Last1);
1273 : int _Wchars;
1274 : const _Byte *_Mid1;
1275 : _Statype _Mystate = _State;
1276 :
1277 : for (_Wchars = 0, _Mid1 = _First1;
1278 : (size_t)_Wchars < _Count && _Mid1 != _Last1; )
1279 : { // convert another unsigned char
1280 : int _Bytes;
1281 : _Elem _Ch;
1282 :
1283 : switch (_Bytes = _Mbrtowc((wchar_t *)&_Ch, _Mid1, _Last1 - _Mid1,
1284 : &_Mystate, &_Cvt))
1285 : { // test result of locale-specific mbrtowc call
1286 : case -2: // partial conversion
1287 : return (_Wchars);
1288 :
1289 : case -1: // failed conversion
1290 : return (_Wchars);
1291 :
1292 : case 0: // may have converted null character
1293 : if (_Ch == (_Elem)0)
1294 : _Bytes = (int)::strlen(_Mid1) + 1;
1295 : // fall through
1296 :
1297 : default: // converted _Bytes bytes to an unsigned char
1298 : if (_Bytes == -3)
1299 : _Bytes = 0; // wchar_t generated from state info
1300 : _Mid1 += _Bytes;
1301 : ++_Wchars;
1302 : }
1303 : }
1304 : return (_Wchars);
1305 : }
1306 :
1307 : virtual bool __CLR_OR_THIS_CALL do_always_noconv() const _THROW0()
1308 : { // return true if conversions never change input
1309 : return (false);
1310 : }
1311 :
1312 : virtual int __CLR_OR_THIS_CALL do_max_length() const _THROW0()
1313 : { // return maximum length required for a conversion (from codecvt)
1314 : return (MB_LEN_MAX);
1315 : }
1316 :
1317 : private:
1318 : _Locinfo::_Cvtvec _Cvt; // locale info passed to _Mbrtowc, _Wcrtomb
1319 : };
1320 : #endif /* _NATIVE_WCHAR_T_DEFINED */
1321 :
1322 : // TEMPLATE CLASS codecvt_byname
1323 : template<class _Elem,
1324 : class _Byte,
1325 : class _Statype>
1326 : class codecvt_byname
1327 : : public codecvt<_Elem, _Byte, _Statype>
1328 : { // codecvt for named locale
1329 : public:
1330 : explicit __CLR_OR_THIS_CALL codecvt_byname(const char *_Locname, size_t _Refs = 0)
1331 : : codecvt<_Elem, _Byte, _Statype>(_Locname, _Refs)
1332 : { // construct for named locale
1333 : }
1334 :
1335 : _PROTECTED:
1336 : virtual __CLR_OR_THIS_CALL ~codecvt_byname()
1337 : { // destroy the object
1338 : }
1339 : };
1340 :
1341 : #pragma warning(push)
1342 : #pragma warning(disable:4275)
1343 : // STRUCT ctype_base
1344 : struct _CRTIMP2_PURE ctype_base
1345 : : public locale::facet
1346 : { // base for ctype
1347 : enum
1348 : { // constants for character classifications
1349 : alnum = _DI|_LO|_UP|_XA, alpha = _LO|_UP|_XA,
1350 : cntrl = _BB, digit = _DI, graph = _DI|_LO|_PU|_UP|_XA,
1351 : lower = _LO, print = _DI|_LO|_PU|_SP|_UP|_XA|_XD,
1352 : punct = _PU, space = _CN|_SP|_XS, upper = _UP,
1353 : xdigit = _XD};
1354 : typedef short mask; // to match <ctype.h>
1355 :
1356 : __CLR_OR_THIS_CALL ctype_base(size_t _Refs = 0)
1357 : : locale::facet(_Refs)
1358 10 : { // default constructor
1359 10 : }
1360 :
1361 : __CLR_OR_THIS_CALL ~ctype_base()
1362 10 : { // destroy the object
1363 10 : }
1364 :
1365 : _PROTECTED:
1366 : static void __CLRCALL_OR_CDECL _Xran()
1367 : { // report an out_of_range error
1368 : _THROW(out_of_range, "out_of_range in ctype<T>");
1369 : }
1370 : };
1371 : #pragma warning(pop)
1372 :
1373 : // TEMPLATE CLASS ctype
1374 : template<class _Elem>
1375 : class ctype
1376 : : public ctype_base
1377 : { // facet for classifying elements, converting cases
1378 : public:
1379 : typedef _Elem char_type;
1380 :
1381 : bool __CLR_OR_THIS_CALL is(mask _Maskval, _Elem _Ch) const
1382 : { // test if element fits any mask classifications
1383 : return (do_is(_Maskval, _Ch));
1384 : }
1385 :
1386 : const _Elem *__CLR_OR_THIS_CALL is(const _Elem *_First, const _Elem *_Last,
1387 : mask *_Dest) const
1388 : { // get mask sequence for elements in [_First, _Last)
1389 : return (do_is(_First, _Last, _Dest));
1390 : }
1391 :
1392 : const _Elem *__CLR_OR_THIS_CALL scan_is(mask _Maskval, const _Elem *_First,
1393 : const _Elem *_Last) const
1394 : { // find first in [_First, _Last) that fits mask classification
1395 : return (do_scan_is(_Maskval, _First, _Last));
1396 : }
1397 :
1398 : const _Elem *__CLR_OR_THIS_CALL scan_not(mask _Maskval, const _Elem *_First,
1399 : const _Elem *_Last) const
1400 : { // find first in [_First, _Last) not fitting mask classification
1401 : return (do_scan_not(_Maskval, _First, _Last));
1402 : }
1403 :
1404 : _Elem __CLR_OR_THIS_CALL tolower(_Elem _Ch) const
1405 : { // convert element to lower case
1406 : return (do_tolower(_Ch));
1407 : }
1408 :
1409 : const _Elem *__CLR_OR_THIS_CALL tolower(_Elem *_First, const _Elem *_Last) const
1410 : { // convert [_First, _Last) in place to lower case
1411 : return (do_tolower(_First, _Last));
1412 : }
1413 :
1414 : _Elem __CLR_OR_THIS_CALL toupper(_Elem _Ch) const
1415 : { // convert element to upper case
1416 : return (do_toupper(_Ch));
1417 : }
1418 :
1419 : const _Elem *__CLR_OR_THIS_CALL toupper(_Elem *_First, const _Elem *_Last) const
1420 : { // convert [_First, _Last) in place to upper case
1421 : return (do_toupper(_First, _Last));
1422 : }
1423 :
1424 : _Elem __CLR_OR_THIS_CALL widen(char _Byte) const
1425 : { // widen char
1426 : return (do_widen(_Byte));
1427 : }
1428 :
1429 : _SCL_INSECURE_DEPRECATE
1430 : const char *__CLR_OR_THIS_CALL widen(const char *_First, const char *_Last,
1431 : _Elem *_Dest) const
1432 : { // widen chars in [_First, _Last)
1433 : #pragma warning(push)
1434 : #pragma warning(disable:4996)
1435 : return (do_widen(_First, _Last, _Dest));
1436 : #pragma warning(pop)
1437 : }
1438 :
1439 : const char *__CLR_OR_THIS_CALL _Widen_s(const char *_First, const char *_Last,
1440 : _Elem *_Dest, size_t _Dest_size) const
1441 : { // widen chars in [_First, _Last)
1442 : return (_Do_widen_s(_First, _Last, _Dest, _Dest_size));
1443 : }
1444 :
1445 : char __CLR_OR_THIS_CALL narrow(_Elem _Ch, char _Dflt = '\0') const
1446 : { // narrow element to char
1447 : return (do_narrow(_Ch, _Dflt));
1448 : }
1449 :
1450 : _SCL_INSECURE_DEPRECATE
1451 : const _Elem *__CLR_OR_THIS_CALL narrow(const _Elem *_First, const _Elem *_Last,
1452 : char _Dflt, _Out_cap_x_(_Last-_First) char *_Dest) const
1453 : { // narrow elements in [_First, _Last) to chars
1454 : // assume there is enough space in the destination buffer
1455 : #pragma warning(push)
1456 : #pragma warning(disable:4996)
1457 : return (do_narrow(_First, _Last, _Dflt, _Dest));
1458 : #pragma warning(pop)
1459 : }
1460 :
1461 : const _Elem *__CLR_OR_THIS_CALL _Narrow_s(const _Elem *_First, const _Elem *_Last,
1462 : char _Dflt, _Out_cap_(_Dest_size) _Post_count_x_( _Last-_First) char *_Dest, size_t _Dest_size) const
1463 : { // narrow elements in [_First, _Last) to chars
1464 : return (_Do_narrow_s(_First, _Last, _Dflt, _Dest, _Dest_size));
1465 : }
1466 :
1467 : __PURE_APPDOMAIN_GLOBAL static locale::id id; // unique facet id
1468 :
1469 : explicit __CLR_OR_THIS_CALL ctype(size_t _Refs = 0)
1470 : : ctype_base(_Refs)
1471 : { // construct from current locale
1472 : _BEGIN_LOCINFO(_Lobj)
1473 : _Init(_Lobj);
1474 : _END_LOCINFO()
1475 : }
1476 :
1477 : __CLR_OR_THIS_CALL ctype(const _Locinfo& _Lobj, size_t _Refs = 0)
1478 : : ctype_base(_Refs)
1479 : { // construct from specified locale
1480 : _Init(_Lobj);
1481 : }
1482 :
1483 : static size_t __CLRCALL_OR_CDECL _Getcat(const locale::facet **_Ppf = 0,
1484 : const locale *_Ploc = 0)
1485 : { // return locale category mask and construct standard facet
1486 : if (_Ppf != 0 && *_Ppf == 0)
1487 : *_Ppf = _NEW_CRT ctype<_Elem>(
1488 : _Locinfo(_Ploc->name()));
1489 : return (_X_CTYPE);
1490 : }
1491 :
1492 : _PROTECTED:
1493 : virtual __CLR_OR_THIS_CALL ~ctype()
1494 : { // destroy the object
1495 : if (_Ctype._Delfl)
1496 : free((void *)_Ctype._Table);
1497 : }
1498 :
1499 : protected:
1500 : void __CLR_OR_THIS_CALL _Init(const _Locinfo& _Lobj)
1501 : { // initialize from _Lobj
1502 : _Ctype = _Lobj._Getctype();
1503 : }
1504 :
1505 : virtual bool __CLR_OR_THIS_CALL do_is(mask _Maskval, _Elem _Ch) const
1506 : { // test if element fits any mask classifications
1507 : return ((_Ctype._Table[(unsigned char)narrow(_Ch)]
1508 : & _Maskval) != 0);
1509 : }
1510 :
1511 : virtual const _Elem *__CLR_OR_THIS_CALL do_is(const _Elem *_First, const _Elem *_Last,
1512 : mask *_Dest) const
1513 : { // get mask sequence for elements in [_First, _Last)
1514 : _DEBUG_RANGE(_First, _Last);
1515 : _DEBUG_POINTER(_Dest);
1516 : for (; _First != _Last; ++_First, ++_Dest)
1517 : *_Dest = _Ctype._Table[(unsigned char)narrow(*_First)];
1518 : return (_First);
1519 : }
1520 :
1521 : virtual const _Elem *__CLR_OR_THIS_CALL do_scan_is(mask _Maskval,
1522 : const _Elem *_First, const _Elem *_Last) const
1523 : { // find first in [_First, _Last) that fits mask classification
1524 : _DEBUG_RANGE(_First, _Last);
1525 : for (; _First != _Last && !is(_Maskval, *_First); ++_First)
1526 : ;
1527 : return (_First);
1528 : }
1529 :
1530 : virtual const _Elem *__CLR_OR_THIS_CALL do_scan_not(mask _Maskval,
1531 : const _Elem *_First, const _Elem *_Last) const
1532 : { // find first in [_First, _Last) not fitting mask classification
1533 : _DEBUG_RANGE(_First, _Last);
1534 : for (; _First != _Last && is(_Maskval, *_First); ++_First)
1535 : ;
1536 : return (_First);
1537 : }
1538 :
1539 : virtual _Elem __CLR_OR_THIS_CALL do_tolower(_Elem _Ch) const
1540 : { // convert element to lower case
1541 : unsigned char _Byte = (unsigned char)narrow(_Ch, '\0');
1542 : if (_Byte == '\0')
1543 : return (_Ch);
1544 : else
1545 : return (widen((char)_Tolower(_Byte, &_Ctype)));
1546 : }
1547 :
1548 : virtual const _Elem *__CLR_OR_THIS_CALL do_tolower(_Elem *_First, const _Elem *_Last) const
1549 : { // convert [_First, _Last) in place to lower case
1550 : _DEBUG_RANGE((const _Elem *)_First, _Last);
1551 : for (; _First != _Last; ++_First)
1552 : { // convert *_First to lower case
1553 : unsigned char _Byte = (unsigned char)narrow(*_First, '\0');
1554 : if (_Byte != '\0')
1555 : *_First = (widen((char)_Tolower(_Byte, &_Ctype)));
1556 : }
1557 : return ((const _Elem *)_First);
1558 : }
1559 :
1560 : virtual _Elem __CLR_OR_THIS_CALL do_toupper(_Elem _Ch) const
1561 : { // convert element to upper case
1562 : unsigned char _Byte = (unsigned char)narrow(_Ch, '\0');
1563 : if (_Byte == '\0')
1564 : return (_Ch);
1565 : else
1566 : return (widen((char)_Toupper(_Byte, &_Ctype)));
1567 : }
1568 :
1569 : virtual const _Elem *__CLR_OR_THIS_CALL do_toupper(_Elem *_First, const _Elem *_Last) const
1570 : { // convert [_First, _Last) in place to upper case
1571 : _DEBUG_RANGE((const _Elem *)_First, _Last);
1572 : for (; _First != _Last; ++_First)
1573 : { // convert *_First to upper case
1574 : unsigned char _Byte = (unsigned char)narrow(*_First, '\0');
1575 : if (_Byte != '\0')
1576 : *_First = (widen((char)_Toupper(_Byte, &_Ctype)));
1577 : }
1578 : return ((const _Elem *)_First);
1579 : }
1580 :
1581 : virtual _Elem __CLR_OR_THIS_CALL do_widen(char _Byte) const
1582 : { // widen char
1583 : return (_MAKLOCCHR(_Elem, _Byte, _Cvt));
1584 : }
1585 :
1586 : _SCL_INSECURE_DEPRECATE
1587 : virtual const char *__CLR_OR_THIS_CALL do_widen(const char *_First,
1588 : const char *_Last, _Elem *_Dest) const
1589 : { // widen chars in [_First, _Last)
1590 : // assume there is enough space in _Dest
1591 : return _Do_widen_s(_First, _Last, _Dest, _Last - _First);
1592 : }
1593 :
1594 : virtual const char *__CLR_OR_THIS_CALL _Do_widen_s(const char *_First,
1595 : const char *_Last, _Elem *_Dest, size_t _Dest_size) const
1596 : { // widen chars in [_First, _Last)
1597 : _DEBUG_RANGE(_First, _Last);
1598 : _DEBUG_POINTER(_Dest);
1599 : _SCL_SECURE_ALWAYS_VALIDATE_RANGE(_Dest_size >= (size_t)(_Last - _First));
1600 : for (; _First != _Last; ++_First, ++_Dest)
1601 : *_Dest = _MAKLOCCHR(_Elem, *_First, _Cvt);
1602 : return (_First);
1603 : }
1604 :
1605 : char __CLR_OR_THIS_CALL _Donarrow(_Elem _Ch, char _Dflt) const
1606 : { // narrow element to char
1607 : char _Byte;
1608 : if (_Ch == (_Elem)0)
1609 : return ('\0');
1610 : else if ((_Byte = _MAKLOCBYTE(_Elem, _Ch, _Cvt)) == '\0')
1611 : return (_Dflt);
1612 : else
1613 : return (_Byte);
1614 : }
1615 :
1616 : virtual char __CLR_OR_THIS_CALL do_narrow(_Elem _Ch, char _Dflt) const
1617 : { // narrow element to char
1618 : return (_Donarrow(_Ch, _Dflt));
1619 : }
1620 :
1621 : _SCL_INSECURE_DEPRECATE
1622 : virtual const _Elem *__CLR_OR_THIS_CALL do_narrow(const _Elem *_First,
1623 : const _Elem *_Last, char _Dflt, _Out_cap_x_(_Last-_First) char *_Dest) const
1624 : { // narrow elements in [_First, _Last) to chars
1625 : // assume there is enough space in _Dest
1626 : return _Do_narrow_s(_First, _Last, _Dflt, _Dest, _Last - _First);
1627 : }
1628 :
1629 : virtual const _Elem *__CLR_OR_THIS_CALL _Do_narrow_s(const _Elem *_First,
1630 : const _Elem *_Last, char _Dflt,
1631 : _Out_cap_(_Dest_size) _Post_count_x_( _Last-_First) char *_Dest,
1632 : size_t _Dest_size) const
1633 : { // narrow elements in [_First, _Last) to chars
1634 : _DEBUG_RANGE(_First, _Last);
1635 : _DEBUG_POINTER(_Dest);
1636 : _SCL_SECURE_ALWAYS_VALIDATE_RANGE(_Dest_size >= (size_t)(_Last - _First));
1637 : for (; _First != _Last; ++_First, ++_Dest)
1638 : *_Dest = _Donarrow(*_First, _Dflt);
1639 : return (_First);
1640 : }
1641 :
1642 : private:
1643 : _Locinfo::_Ctypevec _Ctype; // locale info passed to _Tolower, etc.
1644 : _Locinfo::_Cvtvec _Cvt; // conversion information
1645 : };
1646 :
1647 : // STATIC ctype::id OBJECT
1648 : template<class _Elem>
1649 : __PURE_APPDOMAIN_GLOBAL locale::id ctype<_Elem>::id;
1650 :
1651 : // CLASS ctype<char>
1652 : template<> class _CRTIMP2_PURE ctype<char>
1653 : : public ctype_base
1654 : { // facet for classifying char elements, converting cases
1655 : typedef ctype<char> _Myt;
1656 :
1657 : public:
1658 : typedef char _Elem;
1659 : typedef _Elem char_type;
1660 :
1661 : bool __CLR_OR_THIS_CALL is(mask _Maskval, _Elem _Ch) const
1662 : { // test if element fits any mask classifications
1663 : return ((_Ctype._Table[(unsigned char)_Ch] & _Maskval) != 0);
1664 : }
1665 :
1666 : const _Elem *__CLR_OR_THIS_CALL is(const _Elem *_First,
1667 : const _Elem *_Last, mask *_Dest) const
1668 : { // get mask sequence for elements in [_First, _Last)
1669 : _DEBUG_RANGE(_First, _Last);
1670 : _DEBUG_POINTER(_Dest);
1671 : for (; _First != _Last; ++_First, ++_Dest)
1672 : *_Dest = _Ctype._Table[(unsigned char)*_First];
1673 : return (_First);
1674 : }
1675 :
1676 : const _Elem *__CLR_OR_THIS_CALL scan_is(mask _Maskval,
1677 : const _Elem *_First, const _Elem *_Last) const
1678 : { // find first in [_First, _Last) that fits mask classification
1679 : _DEBUG_RANGE(_First, _Last);
1680 : for (; _First != _Last && !is(_Maskval, *_First); ++_First)
1681 : ;
1682 : return (_First);
1683 : }
1684 :
1685 : const _Elem *__CLR_OR_THIS_CALL scan_not(mask _Maskval,
1686 : const _Elem *_First, const _Elem *_Last) const
1687 : { // find first in [_First, _Last) not fitting mask classification
1688 : _DEBUG_RANGE(_First, _Last);
1689 : for (; _First != _Last && is(_Maskval, *_First); ++_First)
1690 : ;
1691 : return (_First);
1692 : }
1693 :
1694 : _Elem __CLR_OR_THIS_CALL tolower(_Elem _Ch) const
1695 : { // convert element to lower case
1696 : return (do_tolower(_Ch));
1697 : }
1698 :
1699 : const _Elem *__CLR_OR_THIS_CALL tolower(_Elem *_First, const _Elem *_Last) const
1700 : { // convert [_First, _Last) in place to lower case
1701 : return (do_tolower(_First, _Last));
1702 : }
1703 :
1704 : _Elem __CLR_OR_THIS_CALL toupper(_Elem _Ch) const
1705 : { // convert element to upper case
1706 : return (do_toupper(_Ch));
1707 : }
1708 :
1709 : const _Elem *__CLR_OR_THIS_CALL toupper(_Elem *_First, const _Elem *_Last) const
1710 : { // convert [_First, _Last) in place to upper case
1711 : return (do_toupper(_First, _Last));
1712 : }
1713 :
1714 : _Elem __CLR_OR_THIS_CALL widen(char _Byte) const
1715 10 : { // widen char
1716 10 : return (do_widen(_Byte));
1717 10 : }
1718 :
1719 : _SCL_INSECURE_DEPRECATE
1720 : const _Elem *__CLR_OR_THIS_CALL widen(const char *_First, const char *_Last,
1721 : _Elem *_Dest) const
1722 : { // widen chars in [_First, _Last)
1723 : // assume there is enough space in _Dest
1724 : #pragma warning(push)
1725 : #pragma warning(disable:4996)
1726 : return (do_widen(_First, _Last, _Dest));
1727 : #pragma warning(pop)
1728 : }
1729 :
1730 : const _Elem *__CLR_OR_THIS_CALL _Widen_s(const char *_First, const char *_Last,
1731 : _Elem *_Dest, size_t _Dest_size) const
1732 : { // widen chars in [_First, _Last)
1733 : return (_Do_widen_s(_First, _Last, _Dest, _Dest_size));
1734 : }
1735 :
1736 : _Elem __CLR_OR_THIS_CALL narrow(_Elem _Ch, char _Dflt = '\0') const
1737 : { // narrow element to char
1738 : return (do_narrow(_Ch, _Dflt));
1739 : }
1740 :
1741 : _SCL_INSECURE_DEPRECATE
1742 : const _Elem *__CLR_OR_THIS_CALL narrow(const _Elem *_First, const _Elem *_Last,
1743 : char _Dflt, _Out_cap_x_(_Last-_First) char *_Dest) const
1744 : { // narrow elements in [_First, _Last) to chars
1745 : // assume there is enough space in _Dest
1746 : #pragma warning(push)
1747 : #pragma warning(disable:4996)
1748 : return (do_narrow(_First, _Last, _Dflt, _Dest));
1749 : #pragma warning(pop)
1750 : }
1751 :
1752 : const _Elem *__CLR_OR_THIS_CALL _Narrow_s(const _Elem *_First, const _Elem *_Last,
1753 : char _Dflt, _Out_cap_(_Dest_size) _Post_count_x_( _Last-_First) char *_Dest,
1754 : size_t _Dest_size) const
1755 : { // narrow elements in [_First, _Last) to chars
1756 : return (_Do_narrow_s(_First, _Last, _Dflt, _Dest, _Dest_size));
1757 : }
1758 :
1759 : static _MRTIMP2_NPURE locale::id& __cdecl _Id_func();
1760 : #ifdef _M_CEE_PURE
1761 : static locale::id& id; // unique facet id
1762 : #else
1763 : __PURE_APPDOMAIN_GLOBAL static locale::id id; // unique facet id
1764 : #endif
1765 :
1766 : explicit __CLR_OR_THIS_CALL ctype(const mask *_Table = 0,
1767 : bool _Deletetable = false,
1768 : size_t _Refs = 0)
1769 : : ctype_base(_Refs)
1770 : { // construct with specified table and delete flag for table
1771 : _BEGIN_LOCINFO(_Lobj)
1772 : _Init(_Lobj);
1773 : _END_LOCINFO()
1774 : if (_Table != 0)
1775 : { // replace existing char to mask table
1776 : _Tidy();
1777 : _Ctype._Table = _Table;
1778 : _Ctype._Delfl = _Deletetable ? -1 : 0;
1779 : }
1780 : }
1781 :
1782 : __CLR_OR_THIS_CALL ctype(const _Locinfo& _Lobj, size_t _Refs = 0)
1783 : : ctype_base(_Refs)
1784 10 : { // construct from current locale
1785 10 : _Init(_Lobj);
1786 10 : }
1787 :
1788 : static size_t __CLRCALL_OR_CDECL _Getcat(const locale::facet **_Ppf = 0,
1789 : const locale *_Ploc = 0)
1790 10 : { // return locale category mask and construct standard facet
1791 10 : if (_Ppf != 0 && *_Ppf == 0)
1792 : *_Ppf = _NEW_CRT ctype<_Elem>(
1793 10 : _Locinfo(_Ploc->name()));
1794 10 : return (_X_CTYPE);
1795 10 : }
1796 :
1797 : _PGLOBAL static const size_t table_size = 1 << 8/*CHAR_BIT*/; // size of _Ctype._Table (char to mask)
1798 :
1799 : _PROTECTED:
1800 : virtual __CLR_OR_THIS_CALL ~ctype()
1801 10 : { // destroy the object
1802 10 : _Tidy();
1803 10 : }
1804 :
1805 : protected:
1806 : void __CLR_OR_THIS_CALL _Init(const _Locinfo& _Lobj)
1807 10 : { // initialize from _Lobj
1808 10 : _Ctype = _Lobj._Getctype();
1809 10 : }
1810 :
1811 : void __CLR_OR_THIS_CALL _Tidy()
1812 10 : { // free any allocated storage
1813 10 : if (0 < _Ctype._Delfl)
1814 10 : free((void *)_Ctype._Table);
1815 0 : else if (_Ctype._Delfl < 0)
1816 0 : delete[] (void *)_Ctype._Table;
1817 10 : }
1818 :
1819 : virtual _Elem __CLR_OR_THIS_CALL do_tolower(_Elem _Ch) const
1820 0 : { // convert element to lower case
1821 0 : return ((_Elem)_Tolower((unsigned char)_Ch, &_Ctype));
1822 0 : }
1823 :
1824 : virtual const _Elem *__CLR_OR_THIS_CALL do_tolower(_Elem *_First,
1825 : const _Elem *_Last) const
1826 0 : { // convert [_First, _Last) in place to lower case
1827 0 : _DEBUG_RANGE((const _Elem *)_First, _Last);
1828 0 : for (; _First != _Last; ++_First)
1829 0 : *_First = (_Elem)_Tolower((unsigned char)*_First, &_Ctype);
1830 0 : return ((const _Elem *)_First);
1831 0 : }
1832 :
1833 : virtual _Elem __CLR_OR_THIS_CALL do_toupper(_Elem _Ch) const
1834 0 : { // convert element to upper case
1835 0 : return ((_Elem)_Toupper((unsigned char)_Ch, &_Ctype));
1836 0 : }
1837 :
1838 : virtual const _Elem *__CLR_OR_THIS_CALL do_toupper(_Elem *_First,
1839 : const _Elem *_Last) const
1840 0 : { // convert [_First, _Last) in place to upper case
1841 0 : _DEBUG_RANGE((const _Elem *)_First, _Last);
1842 0 : for (; _First != _Last; ++_First)
1843 0 : *_First = (_Elem)_Toupper((unsigned char)*_First, &_Ctype);
1844 0 : return ((const _Elem *)_First);
1845 0 : }
1846 :
1847 : virtual _Elem __CLR_OR_THIS_CALL do_widen(char _Byte) const
1848 10 : { // widen char
1849 10 : return (_Byte);
1850 10 : }
1851 :
1852 : _SCL_INSECURE_DEPRECATE
1853 : virtual const _Elem *__CLR_OR_THIS_CALL do_widen(const char *_First,
1854 : const char *_Last, _Elem *_Dest) const
1855 0 : { // widen chars in [_First, _Last)
1856 : // assume there is enough space in _Dest
1857 0 : return _Do_widen_s(_First, _Last, _Dest, _Last - _First);
1858 0 : }
1859 :
1860 : virtual const _Elem *__CLR_OR_THIS_CALL _Do_widen_s(const char *_First,
1861 : const char *_Last, _Elem *_Dest, size_t _Dest_size) const
1862 0 : { // widen chars in [_First, _Last)
1863 0 : _DEBUG_RANGE(_First, _Last);
1864 0 : _DEBUG_POINTER(_Dest);
1865 0 : _SCL_SECURE_ALWAYS_VALIDATE_RANGE(_Dest_size >= (size_t)(_Last - _First));
1866 0 : _CRT_SECURE_MEMCPY(_Dest, _Dest_size, _First, _Last - _First);
1867 0 : return (_Last);
1868 0 : }
1869 :
1870 : virtual _Elem __CLR_OR_THIS_CALL do_narrow(_Elem _Ch, char) const
1871 0 : { // narrow char
1872 0 : return (_Ch);
1873 0 : }
1874 :
1875 : _SCL_INSECURE_DEPRECATE
1876 : virtual const _Elem *__CLR_OR_THIS_CALL do_narrow(const _Elem *_First,
1877 : const _Elem *_Last, char _Dflt,
1878 : _Out_cap_x_(_Last-_First) char *_Dest) const
1879 0 : { // narrow elements in [_First, _Last) to chars
1880 : // assume there is enough space in _Dest
1881 0 : return _Do_narrow_s(_First, _Last, _Dflt, _Dest, _Last - _First);
1882 0 : }
1883 :
1884 : virtual const _Elem *__CLR_OR_THIS_CALL _Do_narrow_s(const _Elem *_First,
1885 : const _Elem *_Last, char, _Out_cap_(_Dest_size) _Post_count_x_( _Last-_First) char *_Dest,
1886 : size_t _Dest_size) const
1887 0 : { // narrow elements in [_First, _Last) to chars
1888 0 : _DEBUG_RANGE(_First, _Last);
1889 0 : _DEBUG_POINTER(_Dest);
1890 0 : _SCL_SECURE_ALWAYS_VALIDATE_RANGE(_Dest_size >= (size_t)(_Last - _First));
1891 0 : _CRT_SECURE_MEMCPY(_Dest, _Dest_size, _First, _Last - _First);
1892 0 : return (_Last);
1893 0 : }
1894 :
1895 : const mask *__CLR_OR_THIS_CALL table() const _THROW0()
1896 : { // return address of char to mask table
1897 : return (_Ctype._Table);
1898 : }
1899 :
1900 : static const mask *__CLRCALL_OR_CDECL classic_table() _THROW0()
1901 : { // return address of char to mask table for "C" locale
1902 : const _Myt& _Ctype_fac = _USE(locale::classic(), _Myt);
1903 : return (_Ctype_fac.table());
1904 : }
1905 :
1906 : private:
1907 : _Locinfo::_Ctypevec _Ctype; // information
1908 : };
1909 :
1910 : // CLASS ctype<wchar_t>
1911 : template<> class _CRTIMP2_PURE ctype<wchar_t>
1912 : : public ctype_base
1913 : { // facet for classifying wchar_t elements, converting cases
1914 : typedef ctype<wchar_t> _Myt;
1915 :
1916 : public:
1917 : typedef wchar_t _Elem;
1918 : typedef _Elem char_type;
1919 :
1920 : bool __CLR_OR_THIS_CALL is(mask _Maskval, _Elem _Ch) const
1921 : { // test if element fits any mask classifications
1922 : return (do_is(_Maskval, _Ch));
1923 : }
1924 :
1925 : const _Elem *__CLR_OR_THIS_CALL is(const _Elem *_First, const _Elem *_Last,
1926 : mask *_Dest) const
1927 : { // get mask sequence for elements in [_First, _Last)
1928 : return (do_is(_First, _Last, _Dest));
1929 : }
1930 :
1931 : const _Elem *__CLR_OR_THIS_CALL scan_is(mask _Maskval, const _Elem *_First,
1932 : const _Elem *_Last) const
1933 : { // find first in [_First, _Last) that fits mask classification
1934 : return (do_scan_is(_Maskval, _First, _Last));
1935 : }
1936 :
1937 : const _Elem *__CLR_OR_THIS_CALL scan_not(mask _Maskval, const _Elem *_First,
1938 : const _Elem *_Last) const
1939 : { // find first in [_First, _Last) not fitting mask classification
1940 : return (do_scan_not(_Maskval, _First, _Last));
1941 : }
1942 :
1943 : _Elem __CLR_OR_THIS_CALL tolower(_Elem _Ch) const
1944 : { // convert element to lower case
1945 : return (do_tolower(_Ch));
1946 : }
1947 :
1948 : const _Elem *__CLR_OR_THIS_CALL tolower(_Elem *_First, const _Elem *_Last) const
1949 : { // convert [_First, _Last) in place to lower case
1950 : return (do_tolower(_First, _Last));
1951 : }
1952 :
1953 : _Elem __CLR_OR_THIS_CALL toupper(_Elem _Ch) const
1954 : { // convert element to upper case
1955 : return (do_toupper(_Ch));
1956 : }
1957 :
1958 : const _Elem *__CLR_OR_THIS_CALL toupper(_Elem *_First, const _Elem *_Last) const
1959 : { // convert [_First, _Last) in place to upper case
1960 : return (do_toupper(_First, _Last));
1961 : }
1962 :
1963 : _Elem __CLR_OR_THIS_CALL widen(char _Byte) const
1964 : { // widen char
1965 : return (do_widen(_Byte));
1966 : }
1967 :
1968 : _SCL_INSECURE_DEPRECATE
1969 : const char *__CLR_OR_THIS_CALL widen(const char *_First, const char *_Last,
1970 : _Elem *_Dest) const
1971 : { // widen chars in [_First, _Last)
1972 : // assume there is enough space in _Dest
1973 : #pragma warning(push)
1974 : #pragma warning(disable:4996)
1975 : return (do_widen(_First, _Last, _Dest));
1976 : #pragma warning(pop)
1977 : }
1978 :
1979 : const char *__CLR_OR_THIS_CALL _Widen_s(const char *_First, const char *_Last,
1980 : _Elem *_Dest, size_t _Dest_size) const
1981 : { // widen chars in [_First, _Last)
1982 : return (_Do_widen_s(_First, _Last, _Dest, _Dest_size));
1983 : }
1984 :
1985 : char __CLR_OR_THIS_CALL narrow(_Elem _Ch, char _Dflt = '\0') const
1986 : { // narrow element to char
1987 : return (do_narrow(_Ch, _Dflt));
1988 : }
1989 :
1990 : _SCL_INSECURE_DEPRECATE
1991 : const _Elem *__CLR_OR_THIS_CALL narrow(const _Elem *_First, const _Elem *_Last,
1992 : char _Dflt, _Out_cap_x_(_Last-_First) char *_Dest) const
1993 : { // narrow elements in [_First, _Last) to chars
1994 : // assume there is enough space in _Dest
1995 : #pragma warning(push)
1996 : #pragma warning(disable:4996)
1997 : return (do_narrow(_First, _Last, _Dflt, _Dest));
1998 : #pragma warning(pop)
1999 : }
2000 :
2001 : const _Elem *__CLR_OR_THIS_CALL _Narrow_s(const _Elem *_First, const _Elem *_Last,
2002 : char _Dflt, _Out_cap_(_Dest_size) _Post_count_x_( _Last-_First) char *_Dest,
2003 : size_t _Dest_size) const
2004 : { // narrow elements in [_First, _Last) to chars
2005 : return (_Do_narrow_s(_First, _Last, _Dflt, _Dest, _Dest_size));
2006 : }
2007 :
2008 : static _MRTIMP2_NPURE locale::id& __cdecl _Id_func();
2009 : #ifdef _M_CEE_PURE
2010 : static locale::id& id; // unique facet id
2011 : #else
2012 : __PURE_APPDOMAIN_GLOBAL static locale::id id; // unique facet id
2013 : #endif
2014 :
2015 : explicit __CLR_OR_THIS_CALL ctype(size_t _Refs = 0)
2016 : : ctype_base(_Refs)
2017 : { // construct from current locale
2018 : _BEGIN_LOCINFO(_Lobj)
2019 : _Init(_Lobj);
2020 : _END_LOCINFO()
2021 : }
2022 :
2023 : __CLR_OR_THIS_CALL ctype(const _Locinfo& _Lobj, size_t _Refs = 0)
2024 : : ctype_base(_Refs)
2025 : { // construct from specified locale
2026 : _Init(_Lobj);
2027 : }
2028 :
2029 : static size_t __CLRCALL_OR_CDECL _Getcat(const locale::facet **_Ppf = 0,
2030 : const locale *_Ploc = 0)
2031 : { // return locale category mask and construct standard facet
2032 : if (_Ppf != 0 && *_Ppf == 0)
2033 : *_Ppf = _NEW_CRT ctype<_Elem>(
2034 : _Locinfo(_Ploc->name()));
2035 : return (_X_CTYPE);
2036 : }
2037 :
2038 : _PROTECTED:
2039 : virtual __CLR_OR_THIS_CALL ~ctype()
2040 : { // destroy the object
2041 : if (_Ctype._Delfl)
2042 : free((void *)_Ctype._Table);
2043 : }
2044 :
2045 : protected:
2046 : void __CLR_OR_THIS_CALL _Init(const _Locinfo& _Lobj)
2047 : { // initialize from _Lobj
2048 : _Ctype = _Lobj._Getctype();
2049 : _Cvt = _Lobj._Getcvt();
2050 : }
2051 :
2052 : virtual bool __CLR_OR_THIS_CALL do_is(mask _Maskval, _Elem _Ch) const
2053 : { // test if element fits any mask classifications
2054 : return ((::_Getwctype(_Ch, &_Ctype) & _Maskval) != 0);
2055 : }
2056 :
2057 : virtual const wchar_t *__CLR_OR_THIS_CALL do_is(const _Elem *_First,
2058 : const _Elem *_Last, mask *_Dest) const
2059 : { // get mask sequence for elements in [_First, _Last)
2060 : _DEBUG_RANGE(_First, _Last);
2061 : _DEBUG_POINTER(_Dest);
2062 : return (::_Getwctypes(_First, _Last, _Dest, &_Ctype));
2063 : }
2064 :
2065 : virtual const _Elem *__CLR_OR_THIS_CALL do_scan_is(mask _Maskval,
2066 : const _Elem *_First, const _Elem *_Last) const
2067 : { // find first in [_First, _Last) that fits mask classification
2068 : _DEBUG_RANGE(_First, _Last);
2069 : for (; _First != _Last && !is(_Maskval, *_First); ++_First)
2070 : ;
2071 : return (_First);
2072 : }
2073 :
2074 : virtual const _Elem *__CLR_OR_THIS_CALL do_scan_not(mask _Maskval,
2075 : const _Elem *_First, const _Elem *_Last) const
2076 : { // find first in [_First, _Last) not fitting mask classification
2077 : _DEBUG_RANGE(_First, _Last);
2078 : for (; _First != _Last && is(_Maskval, *_First); ++_First)
2079 : ;
2080 : return (_First);
2081 : }
2082 :
2083 : virtual _Elem __CLR_OR_THIS_CALL do_tolower(_Elem _Ch) const
2084 : { // convert element to lower case
2085 : return (_Towlower(_Ch, &_Ctype));
2086 : }
2087 :
2088 : virtual const _Elem *__CLR_OR_THIS_CALL do_tolower(_Elem *_First,
2089 : const _Elem *_Last) const
2090 : { // convert [_First, _Last) in place to lower case
2091 : _DEBUG_RANGE((const _Elem *)_First, _Last);
2092 : for (; _First != _Last; ++_First)
2093 : *_First = _Towlower(*_First, &_Ctype);
2094 : return ((const _Elem *)_First);
2095 : }
2096 :
2097 : virtual _Elem __CLR_OR_THIS_CALL do_toupper(_Elem _Ch) const
2098 : { // convert element to upper case
2099 : return (_Towupper(_Ch, &_Ctype));
2100 : }
2101 :
2102 : virtual const _Elem *__CLR_OR_THIS_CALL do_toupper(_Elem *_First,
2103 : const _Elem *_Last) const
2104 : { // convert [_First, _Last) in place to upper case
2105 : _DEBUG_RANGE((const _Elem *)_First, _Last);
2106 : for (; _First != _Last; ++_First)
2107 : *_First = _Towupper(*_First, &_Ctype);
2108 : return ((const _Elem *)_First);
2109 : }
2110 :
2111 : _Elem __CLR_OR_THIS_CALL _Dowiden(char _Byte) const
2112 : { // widen char
2113 : _Mbstinit(_Mbst);
2114 : wchar_t _Wc;
2115 : return (_Mbrtowc(&_Wc, &_Byte, 1, &_Mbst, &_Cvt) < 0
2116 : ? (wchar_t)WEOF : _Wc);
2117 : }
2118 :
2119 : virtual _Elem __CLR_OR_THIS_CALL do_widen(char _Byte) const
2120 : { // widen char
2121 : return (_Dowiden(_Byte));
2122 : }
2123 :
2124 : _SCL_INSECURE_DEPRECATE
2125 : virtual const char *__CLR_OR_THIS_CALL do_widen(const char *_First,
2126 : const char *_Last, _Elem *_Dest) const
2127 : { // widen chars in [_First, _Last)
2128 : // assume there is enough space in _Dest
2129 : return _Do_widen_s(_First, _Last, _Dest, _Last - _First);
2130 : }
2131 :
2132 : virtual const char *__CLR_OR_THIS_CALL _Do_widen_s(const char *_First,
2133 : const char *_Last, _Elem *_Dest, size_t _Dest_size) const
2134 : { // widen chars in [_First, _Last)
2135 : _DEBUG_RANGE(_First, _Last);
2136 : _DEBUG_POINTER(_Dest);
2137 : _SCL_SECURE_ALWAYS_VALIDATE_RANGE(_Dest_size >= (size_t)(_Last - _First));
2138 : for (; _First != _Last; ++_First, ++_Dest)
2139 : *_Dest = _Dowiden(*_First);
2140 : return (_First);
2141 : }
2142 :
2143 : char __CLR_OR_THIS_CALL _Donarrow(_Elem _Ch, char _Dflt) const
2144 : { // narrow element to char
2145 : char _Buf[MB_LEN_MAX];
2146 : _Mbstinit(_Mbst);
2147 : return (_Wcrtomb(_Buf, _Ch, &_Mbst, &_Cvt) != 1
2148 : ? _Dflt : _Buf[0]);
2149 : }
2150 :
2151 : virtual char __CLR_OR_THIS_CALL do_narrow(_Elem _Ch, char _Dflt) const
2152 : { // narrow element to char
2153 : return (_Donarrow(_Ch, _Dflt));
2154 : }
2155 :
2156 : _SCL_INSECURE_DEPRECATE
2157 : virtual const _Elem *__CLR_OR_THIS_CALL do_narrow(const _Elem *_First,
2158 : const _Elem *_Last, char _Dflt,
2159 : _Out_cap_x_(_Last-_First) char *_Dest) const
2160 : { // narrow elements in [_First, _Last) to chars
2161 : // assume there is enough space in _Dest
2162 : return _Do_narrow_s(_First, _Last, _Dflt, _Dest, _Last - _First);
2163 : }
2164 :
2165 : virtual const _Elem *__CLR_OR_THIS_CALL _Do_narrow_s(const _Elem *_First,
2166 : const _Elem *_Last, char _Dflt,
2167 : _Out_cap_(_Dest_size) _Post_count_x_( _Last-_First) char *_Dest,
2168 : size_t _Dest_size) const
2169 : { // narrow elements in [_First, _Last) to chars
2170 : _DEBUG_RANGE(_First, _Last);
2171 : _DEBUG_POINTER(_Dest);
2172 : _SCL_SECURE_ALWAYS_VALIDATE_RANGE(_Dest_size >= (size_t)(_Last - _First));
2173 : for (; _First != _Last; ++_First, ++_Dest)
2174 : *_Dest = _Donarrow(*_First, _Dflt);
2175 : return (_First);
2176 : }
2177 :
2178 : private:
2179 : _Locinfo::_Ctypevec _Ctype; // locale info passed to _Tolower, etc.
2180 : _Locinfo::_Cvtvec _Cvt; // conversion information
2181 : };
2182 :
2183 : #ifdef _NATIVE_WCHAR_T_DEFINED
2184 : // CLASS ctype<unsigned short>
2185 : template<> class _CRTIMP2_PURE ctype<unsigned short>
2186 : : public ctype_base
2187 : { // facet for classifying unsigned short elements, converting cases
2188 : typedef ctype<unsigned short> _Myt;
2189 :
2190 : public:
2191 : typedef unsigned short _Elem;
2192 : typedef _Elem char_type;
2193 :
2194 : bool __CLR_OR_THIS_CALL is(mask _Maskval, _Elem _Ch) const
2195 : { // test if element fits any mask classifications
2196 : return (do_is(_Maskval, _Ch));
2197 : }
2198 :
2199 : const _Elem *__CLR_OR_THIS_CALL is(const _Elem *_First, const _Elem *_Last,
2200 : mask *_Dest) const
2201 : { // get mask sequence for elements in [_First, _Last)
2202 : return (do_is(_First, _Last, _Dest));
2203 : }
2204 :
2205 : const _Elem *__CLR_OR_THIS_CALL scan_is(mask _Maskval, const _Elem *_First,
2206 : const _Elem *_Last) const
2207 : { // find first in [_First, _Last) that fits mask classification
2208 : return (do_scan_is(_Maskval, _First, _Last));
2209 : }
2210 :
2211 : const _Elem *__CLR_OR_THIS_CALL scan_not(mask _Maskval, const _Elem *_First,
2212 : const _Elem *_Last) const
2213 : { // find first in [_First, _Last) not fitting mask classification
2214 : return (do_scan_not(_Maskval, _First, _Last));
2215 : }
2216 :
2217 : _Elem __CLR_OR_THIS_CALL tolower(_Elem _Ch) const
2218 : { // convert element to lower case
2219 : return (do_tolower(_Ch));
2220 : }
2221 :
2222 : const _Elem *__CLR_OR_THIS_CALL tolower(_Elem *_First, const _Elem *_Last) const
2223 : { // convert [_First, _Last) in place to lower case
2224 : return (do_tolower(_First, _Last));
2225 : }
2226 :
2227 : _Elem __CLR_OR_THIS_CALL toupper(_Elem _Ch) const
2228 : { // convert element to upper case
2229 : return (do_toupper(_Ch));
2230 : }
2231 :
2232 : const _Elem *__CLR_OR_THIS_CALL toupper(_Elem *_First, const _Elem *_Last) const
2233 : { // convert [_First, _Last) in place to upper case
2234 : return (do_toupper(_First, _Last));
2235 : }
2236 :
2237 : _Elem __CLR_OR_THIS_CALL widen(char _Byte) const
2238 : { // widen char
2239 : return (do_widen(_Byte));
2240 : }
2241 :
2242 : _SCL_INSECURE_DEPRECATE
2243 : const char *__CLR_OR_THIS_CALL widen(const char *_First, const char *_Last,
2244 : _Elem *_Dest) const
2245 : { // widen chars in [_First, _Last)
2246 : // assume there is enough space in _Dest
2247 : #pragma warning(push)
2248 : #pragma warning(disable:4996)
2249 : return (do_widen(_First, _Last, _Dest));
2250 : #pragma warning(pop)
2251 : }
2252 :
2253 : const char *__CLR_OR_THIS_CALL _Widen_s(const char *_First, const char *_Last,
2254 : _Elem *_Dest, size_t _Dest_size) const
2255 : { // widen chars in [_First, _Last)
2256 : return (_Do_widen_s(_First, _Last, _Dest, _Dest_size));
2257 : }
2258 :
2259 : char __CLR_OR_THIS_CALL narrow(_Elem _Ch, char _Dflt = '\0') const
2260 : { // narrow element to char
2261 : return (do_narrow(_Ch, _Dflt));
2262 : }
2263 :
2264 : _SCL_INSECURE_DEPRECATE
2265 : const _Elem *__CLR_OR_THIS_CALL narrow(const _Elem *_First, const _Elem *_Last,
2266 : char _Dflt, _Out_cap_x_(_Last-_First) char *_Dest) const
2267 : { // narrow elements in [_First, _Last) to chars
2268 : // assume there is enough space in _Dest
2269 : #pragma warning(push)
2270 : #pragma warning(disable:4996)
2271 : return (do_narrow(_First, _Last, _Dflt, _Dest));
2272 : #pragma warning(pop)
2273 : }
2274 :
2275 : const _Elem *__CLR_OR_THIS_CALL _Narrow_s(const _Elem *_First, const _Elem *_Last,
2276 : char _Dflt, _Out_cap_(_Dest_size) _Post_count_x_( _Last-_First) char *_Dest,
2277 : size_t _Dest_size) const
2278 : { // narrow elements in [_First, _Last) to chars
2279 : return (_Do_narrow_s(_First, _Last, _Dflt, _Dest, _Dest_size));
2280 : }
2281 :
2282 : static _MRTIMP2_NPURE locale::id& __cdecl _Id_func();
2283 : #ifdef _M_CEE_PURE
2284 : static locale::id& id; // unique facet id
2285 : #else
2286 : __PURE_APPDOMAIN_GLOBAL static locale::id id; // unique facet id
2287 : #endif
2288 :
2289 : explicit __CLR_OR_THIS_CALL ctype(size_t _Refs = 0)
2290 : : ctype_base(_Refs)
2291 : { // construct from current locale
2292 : _BEGIN_LOCINFO(_Lobj)
2293 : _Init(_Lobj);
2294 : _END_LOCINFO()
2295 : }
2296 :
2297 : __CLR_OR_THIS_CALL ctype(const _Locinfo& _Lobj, size_t _Refs = 0)
2298 : : ctype_base(_Refs)
2299 : { // construct from specified locale
2300 : _Init(_Lobj);
2301 : }
2302 :
2303 : static size_t __CLRCALL_OR_CDECL _Getcat(const locale::facet **_Ppf = 0,
2304 : const locale *_Ploc = 0)
2305 : { // return locale category mask and construct standard facet
2306 : if (_Ppf != 0 && *_Ppf == 0)
2307 : *_Ppf = _NEW_CRT ctype<_Elem>(
2308 : _Locinfo(_Ploc->name()));
2309 : return (_X_CTYPE);
2310 : }
2311 :
2312 : _PROTECTED:
2313 : virtual __CLR_OR_THIS_CALL ~ctype()
2314 : { // destroy the object
2315 : if (_Ctype._Delfl)
2316 : free((void *)_Ctype._Table);
2317 : }
2318 :
2319 : protected:
2320 : __CLR_OR_THIS_CALL ctype(const char *_Locname, size_t _Refs = 0)
2321 : : ctype_base(_Refs)
2322 : { // construct from specified locale
2323 : _BEGIN_LOCINFO(_Lobj(_Locname))
2324 : _Init(_Lobj);
2325 : _END_LOCINFO()
2326 : }
2327 :
2328 : void __CLR_OR_THIS_CALL _Init(const _Locinfo& _Lobj)
2329 : { // initialize from _Lobj
2330 : _Ctype = _Lobj._Getctype();
2331 : _Cvt = _Lobj._Getcvt();
2332 : }
2333 :
2334 : virtual bool __CLR_OR_THIS_CALL do_is(mask _Maskval, _Elem _Ch) const
2335 : { // test if element fits any mask classifications
2336 : return ((::_Getwctype(_Ch, &_Ctype) & _Maskval) != 0);
2337 : }
2338 :
2339 : virtual const _Elem *__CLR_OR_THIS_CALL do_is(const _Elem *_First,
2340 : const _Elem *_Last, mask *_Dest) const
2341 : { // get mask sequence for elements in [_First, _Last)
2342 : _DEBUG_RANGE(_First, _Last);
2343 : _DEBUG_POINTER(_Dest);
2344 : return ((const _Elem *)::_Getwctypes((const wchar_t *)_First,
2345 : (const wchar_t *)_Last, _Dest, &_Ctype));
2346 : }
2347 :
2348 : virtual const _Elem *__CLR_OR_THIS_CALL do_scan_is(mask _Maskval,
2349 : const _Elem *_First, const _Elem *_Last) const
2350 : { // find first in [_First, _Last) that fits mask classification
2351 : _DEBUG_RANGE(_First, _Last);
2352 : for (; _First != _Last && !is(_Maskval, *_First); ++_First)
2353 : ;
2354 : return (_First);
2355 : }
2356 :
2357 : virtual const _Elem *__CLR_OR_THIS_CALL do_scan_not(mask _Maskval,
2358 : const _Elem *_First, const _Elem *_Last) const
2359 : { // find first in [_First, _Last) not fitting mask classification
2360 : _DEBUG_RANGE(_First, _Last);
2361 : for (; _First != _Last && is(_Maskval, *_First); ++_First)
2362 : ;
2363 : return (_First);
2364 : }
2365 :
2366 : virtual _Elem __CLR_OR_THIS_CALL do_tolower(_Elem _Ch) const
2367 : { // convert element to lower case
2368 : return (_Towlower(_Ch, &_Ctype));
2369 : }
2370 :
2371 : virtual const _Elem *__CLR_OR_THIS_CALL do_tolower(_Elem *_First,
2372 : const _Elem *_Last) const
2373 : { // convert [_First, _Last) in place to lower case
2374 : _DEBUG_RANGE((const _Elem *)_First, _Last);
2375 : for (; _First != _Last; ++_First)
2376 : *_First = _Towlower(*_First, &_Ctype);
2377 : return ((const _Elem *)_First);
2378 : }
2379 :
2380 : virtual _Elem __CLR_OR_THIS_CALL do_toupper(_Elem _Ch) const
2381 : { // convert element to upper case
2382 : return (_Towupper(_Ch, &_Ctype));
2383 : }
2384 :
2385 : virtual const _Elem *__CLR_OR_THIS_CALL do_toupper(_Elem *_First,
2386 : const _Elem *_Last) const
2387 : { // convert [_First, _Last) in place to upper case
2388 : _DEBUG_RANGE((const _Elem *)_First, _Last);
2389 : for (; _First != _Last; ++_First)
2390 : *_First = _Towupper(*_First, &_Ctype);
2391 : return ((const _Elem *)_First);
2392 : }
2393 :
2394 : _Elem __CLR_OR_THIS_CALL _Dowiden(char _Byte) const
2395 : { // widen char
2396 : _Mbstinit(_Mbst);
2397 : unsigned short _Wc;
2398 : return (_Mbrtowc((wchar_t *)&_Wc, &_Byte, 1, &_Mbst, &_Cvt) < 0
2399 : ? (unsigned short)WEOF : _Wc);
2400 : }
2401 :
2402 : virtual _Elem __CLR_OR_THIS_CALL do_widen(char _Byte) const
2403 : { // widen char
2404 : return (_Dowiden(_Byte));
2405 : }
2406 :
2407 : _SCL_INSECURE_DEPRECATE
2408 : virtual const char *__CLR_OR_THIS_CALL do_widen(const char *_First,
2409 : const char *_Last, _Elem *_Dest) const
2410 : { // widen chars in [_First, _Last)
2411 : // assume there is enough space in _Dest
2412 : return _Do_widen_s(_First, _Last, _Dest, _Last - _First);
2413 : }
2414 :
2415 : virtual const char *__CLR_OR_THIS_CALL _Do_widen_s(const char *_First,
2416 : const char *_Last, _Elem *_Dest, size_t _Dest_size) const
2417 : { // widen chars in [_First, _Last)
2418 : _DEBUG_RANGE(_First, _Last);
2419 : _DEBUG_POINTER(_Dest);
2420 : _SCL_SECURE_ALWAYS_VALIDATE_RANGE(_Dest_size >= (size_t)(_Last - _First));
2421 : for (; _First != _Last; ++_First, ++_Dest)
2422 : *_Dest = _Dowiden(*_First);
2423 : return (_First);
2424 : }
2425 :
2426 : char __CLR_OR_THIS_CALL _Donarrow(_Elem _Ch, char _Dflt) const
2427 : { // narrow element to char
2428 : char _Buf[MB_LEN_MAX];
2429 : _Mbstinit(_Mbst);
2430 : return (_Wcrtomb(_Buf, _Ch, &_Mbst, &_Cvt) != 1
2431 : ? _Dflt : _Buf[0]);
2432 : }
2433 :
2434 : virtual char __CLR_OR_THIS_CALL do_narrow(_Elem _Ch, char _Dflt) const
2435 : { // narrow element to char
2436 : return (_Donarrow(_Ch, _Dflt));
2437 : }
2438 :
2439 : _SCL_INSECURE_DEPRECATE
2440 : virtual const _Elem *__CLR_OR_THIS_CALL do_narrow(const _Elem *_First,
2441 : const _Elem *_Last, char _Dflt, _Out_cap_x_(_Last-_First) char *_Dest) const
2442 : { // narrow elements in [_First, _Last) to chars
2443 : // assume there is enough space in _Dest
2444 : return _Do_narrow_s(_First, _Last, _Dflt, _Dest, _Last - _First);
2445 : }
2446 :
2447 : virtual const _Elem *__CLR_OR_THIS_CALL _Do_narrow_s(const _Elem *_First,
2448 : const _Elem *_Last, char _Dflt,
2449 : _Out_cap_(_Dest_size) _Post_count_x_( _Last-_First) char *_Dest,
2450 : size_t _Dest_size) const
2451 : { // narrow elements in [_First, _Last) to chars
2452 : _DEBUG_RANGE(_First, _Last);
2453 : _DEBUG_POINTER(_Dest);
2454 : _SCL_SECURE_ALWAYS_VALIDATE_RANGE(_Dest_size >= (size_t)(_Last - _First));
2455 : for (; _First != _Last; ++_First, ++_Dest)
2456 : *_Dest = _Donarrow(*_First, _Dflt);
2457 : return (_First);
2458 : }
2459 :
2460 : private:
2461 : _Locinfo::_Ctypevec _Ctype; // locale info passed to _Tolower, etc.
2462 : _Locinfo::_Cvtvec _Cvt; // conversion information
2463 : };
2464 : #endif /* _NATIVE_WCHAR_T_DEFINED */
2465 :
2466 : // TEMPLATE CLASS ctype_byname
2467 : template<class _Elem>
2468 : class ctype_byname
2469 : : public ctype<_Elem>
2470 : { // ctype for named locale
2471 : public:
2472 : explicit __CLR_OR_THIS_CALL ctype_byname(const char *_Locname, size_t _Refs = 0)
2473 : : ctype<_Elem>(_Locname, _Refs)
2474 : { // construct from named locale
2475 : }
2476 :
2477 : _PROTECTED:
2478 : virtual __CLR_OR_THIS_CALL ~ctype_byname()
2479 : { // destroy the object
2480 : }
2481 : };
2482 :
2483 : // TEMPLATE CLASS ctype_byname<char>
2484 : template<> class ctype_byname<char>
2485 : : public ctype<char>
2486 : { // ctype_byname<char> for named locale
2487 : public:
2488 : explicit __CLR_OR_THIS_CALL ctype_byname(const char *_Locname, size_t _Refs = 0)
2489 : : ctype<char>(_Locname, _Refs)
2490 : { // construct from named locale
2491 : }
2492 :
2493 : _PROTECTED:
2494 : virtual __CLR_OR_THIS_CALL ~ctype_byname()
2495 : { // destroy the object
2496 : }
2497 : };
2498 :
2499 : #if defined(_DLL_CPPLIB) && !defined(_M_CEE_PURE)
2500 :
2501 : template class _CRTIMP2_PURE codecvt<char, char, _Mbstatet>;
2502 :
2503 : #endif /* _DLL_CPPLIB */
2504 : _STD_END
2505 :
2506 : #ifdef _MSC_VER
2507 : #pragma warning(pop)
2508 : #pragma pack(pop)
2509 : #endif /* _MSC_VER */
2510 :
2511 : #endif /* RC_INVOKED */
2512 : #endif /* _XLOCALE_ */
2513 :
2514 : /*
2515 : * Copyright (c) 1992-2007 by P.J. Plauger. ALL RIGHTS RESERVED.
2516 : * Consult your license regarding permissions and restrictions.
2517 : V5.03:0009 */
|