1 //===------------------------- locale.cpp ---------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
11
12 // On Solaris, we need to define something to make the C99 parts of localeconv
13 // visible.
14 #ifdef __sun__
15 #define _LCONV_C99
16 #endif
17
18 #include "string"
19 #include "locale"
20 #include "codecvt"
21 #include "vector"
22 #include "algorithm"
23 #include "typeinfo"
24 #ifndef _LIBCPP_NO_EXCEPTIONS
25 # include "type_traits"
26 #endif
27 #include "clocale"
28 #include "cstring"
29 #include "cwctype"
30 #include "__sso_allocator"
31 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
32 #include <support/win32/locale_win32.h>
33 #elif !defined(__ANDROID__)
34 #include <langinfo.h>
35 #endif
36 #include <stdlib.h>
37 #include <stdio.h>
38
39 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
40 // lots of noise in the build log, but no bugs that I know of.
41 #if defined(__clang__)
42 #pragma clang diagnostic ignored "-Wsign-conversion"
43 #endif
44
45 _LIBCPP_BEGIN_NAMESPACE_STD
46
47 #ifdef __cloc_defined
__cloc()48 locale_t __cloc() {
49 // In theory this could create a race condition. In practice
50 // the race condition is non-fatal since it will just create
51 // a little resource leak. Better approach would be appreciated.
52 static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
53 return result;
54 }
55 #endif // __cloc_defined
56
57 namespace {
58
59 struct release
60 {
operator ()__anonfcb933b90111::release61 void operator()(locale::facet* p) {p->__release_shared();}
62 };
63
64 template <class T, class A0>
65 inline
66 T&
make(A0 a0)67 make(A0 a0)
68 {
69 static typename aligned_storage<sizeof(T)>::type buf;
70 ::new (&buf) T(a0);
71 return *reinterpret_cast<T*>(&buf);
72 }
73
74 template <class T, class A0, class A1>
75 inline
76 T&
make(A0 a0,A1 a1)77 make(A0 a0, A1 a1)
78 {
79 static typename aligned_storage<sizeof(T)>::type buf;
80 ::new (&buf) T(a0, a1);
81 return *reinterpret_cast<T*>(&buf);
82 }
83
84 template <class T, class A0, class A1, class A2>
85 inline
86 T&
make(A0 a0,A1 a1,A2 a2)87 make(A0 a0, A1 a1, A2 a2)
88 {
89 static typename aligned_storage<sizeof(T)>::type buf;
90 ::new (&buf) T(a0, a1, a2);
91 return *reinterpret_cast<T*>(&buf);
92 }
93
94 template <typename T, size_t N>
95 inline
96 _LIBCPP_CONSTEXPR
97 size_t
countof(const T (&)[N])98 countof(const T (&)[N])
99 {
100 return N;
101 }
102
103 template <typename T>
104 inline
105 _LIBCPP_CONSTEXPR
106 size_t
countof(const T * const begin,const T * const end)107 countof(const T * const begin, const T * const end)
108 {
109 return static_cast<size_t>(end - begin);
110 }
111
112 }
113
114 #if defined(_AIX)
115 // Set priority to INT_MIN + 256 + 150
116 # pragma priority ( -2147483242 )
117 #endif
118
119 const locale::category locale::none;
120 const locale::category locale::collate;
121 const locale::category locale::ctype;
122 const locale::category locale::monetary;
123 const locale::category locale::numeric;
124 const locale::category locale::time;
125 const locale::category locale::messages;
126 const locale::category locale::all;
127
128 #if defined(__clang__)
129 #pragma clang diagnostic push
130 #pragma clang diagnostic ignored "-Wpadded"
131 #endif
132
133 class _LIBCPP_HIDDEN locale::__imp
134 : public facet
135 {
136 enum {N = 28};
137 #if defined(_LIBCPP_MSVC)
138 // FIXME: MSVC doesn't support aligned parameters by value.
139 // I can't get the __sso_allocator to work here
140 // for MSVC I think for this reason.
141 vector<facet*> facets_;
142 #else
143 vector<facet*, __sso_allocator<facet*, N> > facets_;
144 #endif
145 string name_;
146 public:
147 explicit __imp(size_t refs = 0);
148 explicit __imp(const string& name, size_t refs = 0);
149 __imp(const __imp&);
150 __imp(const __imp&, const string&, locale::category c);
151 __imp(const __imp& other, const __imp& one, locale::category c);
152 __imp(const __imp&, facet* f, long id);
153 ~__imp();
154
name() const155 const string& name() const {return name_;}
has_facet(long id) const156 bool has_facet(long id) const
157 {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
158 const locale::facet* use_facet(long id) const;
159
160 static const locale& make_classic();
161 static locale& make_global();
162 private:
163 void install(facet* f, long id);
install(F * f)164 template <class F> void install(F* f) {install(f, f->id.__get());}
165 template <class F> void install_from(const __imp& other);
166 };
167
168 #if defined(__clang__)
169 #pragma clang diagnostic pop
170 #endif
171
__imp(size_t refs)172 locale::__imp::__imp(size_t refs)
173 : facet(refs),
174 facets_(N),
175 name_("C")
176 {
177 facets_.clear();
178 install(&make<_VSTD::collate<char> >(1u));
179 install(&make<_VSTD::collate<wchar_t> >(1u));
180 install(&make<_VSTD::ctype<char> >(nullptr, false, 1u));
181 install(&make<_VSTD::ctype<wchar_t> >(1u));
182 install(&make<codecvt<char, char, mbstate_t> >(1u));
183 install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
184 install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
185 install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
186 install(&make<numpunct<char> >(1u));
187 install(&make<numpunct<wchar_t> >(1u));
188 install(&make<num_get<char> >(1u));
189 install(&make<num_get<wchar_t> >(1u));
190 install(&make<num_put<char> >(1u));
191 install(&make<num_put<wchar_t> >(1u));
192 install(&make<moneypunct<char, false> >(1u));
193 install(&make<moneypunct<char, true> >(1u));
194 install(&make<moneypunct<wchar_t, false> >(1u));
195 install(&make<moneypunct<wchar_t, true> >(1u));
196 install(&make<money_get<char> >(1u));
197 install(&make<money_get<wchar_t> >(1u));
198 install(&make<money_put<char> >(1u));
199 install(&make<money_put<wchar_t> >(1u));
200 install(&make<time_get<char> >(1u));
201 install(&make<time_get<wchar_t> >(1u));
202 install(&make<time_put<char> >(1u));
203 install(&make<time_put<wchar_t> >(1u));
204 install(&make<_VSTD::messages<char> >(1u));
205 install(&make<_VSTD::messages<wchar_t> >(1u));
206 }
207
__imp(const string & name,size_t refs)208 locale::__imp::__imp(const string& name, size_t refs)
209 : facet(refs),
210 facets_(N),
211 name_(name)
212 {
213 #ifndef _LIBCPP_NO_EXCEPTIONS
214 try
215 {
216 #endif // _LIBCPP_NO_EXCEPTIONS
217 facets_ = locale::classic().__locale_->facets_;
218 for (unsigned i = 0; i < facets_.size(); ++i)
219 if (facets_[i])
220 facets_[i]->__add_shared();
221 install(new collate_byname<char>(name_));
222 install(new collate_byname<wchar_t>(name_));
223 install(new ctype_byname<char>(name_));
224 install(new ctype_byname<wchar_t>(name_));
225 install(new codecvt_byname<char, char, mbstate_t>(name_));
226 install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
227 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
228 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
229 install(new numpunct_byname<char>(name_));
230 install(new numpunct_byname<wchar_t>(name_));
231 install(new moneypunct_byname<char, false>(name_));
232 install(new moneypunct_byname<char, true>(name_));
233 install(new moneypunct_byname<wchar_t, false>(name_));
234 install(new moneypunct_byname<wchar_t, true>(name_));
235 install(new time_get_byname<char>(name_));
236 install(new time_get_byname<wchar_t>(name_));
237 install(new time_put_byname<char>(name_));
238 install(new time_put_byname<wchar_t>(name_));
239 install(new messages_byname<char>(name_));
240 install(new messages_byname<wchar_t>(name_));
241 #ifndef _LIBCPP_NO_EXCEPTIONS
242 }
243 catch (...)
244 {
245 for (unsigned i = 0; i < facets_.size(); ++i)
246 if (facets_[i])
247 facets_[i]->__release_shared();
248 throw;
249 }
250 #endif // _LIBCPP_NO_EXCEPTIONS
251 }
252
253 // NOTE avoid the `base class should be explicitly initialized in the
254 // copy constructor` warning emitted by GCC
255 #if defined(__clang__) || _GNUC_VER >= 406
256 #pragma GCC diagnostic push
257 #pragma GCC diagnostic ignored "-Wextra"
258 #endif
259
__imp(const __imp & other)260 locale::__imp::__imp(const __imp& other)
261 : facets_(max<size_t>(N, other.facets_.size())),
262 name_(other.name_)
263 {
264 facets_ = other.facets_;
265 for (unsigned i = 0; i < facets_.size(); ++i)
266 if (facets_[i])
267 facets_[i]->__add_shared();
268 }
269
270 #if defined(__clang__) || _GNUC_VER >= 406
271 #pragma GCC diagnostic pop
272 #endif
273
__imp(const __imp & other,const string & name,locale::category c)274 locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
275 : facets_(N),
276 name_("*")
277 {
278 facets_ = other.facets_;
279 for (unsigned i = 0; i < facets_.size(); ++i)
280 if (facets_[i])
281 facets_[i]->__add_shared();
282 #ifndef _LIBCPP_NO_EXCEPTIONS
283 try
284 {
285 #endif // _LIBCPP_NO_EXCEPTIONS
286 if (c & locale::collate)
287 {
288 install(new collate_byname<char>(name));
289 install(new collate_byname<wchar_t>(name));
290 }
291 if (c & locale::ctype)
292 {
293 install(new ctype_byname<char>(name));
294 install(new ctype_byname<wchar_t>(name));
295 install(new codecvt_byname<char, char, mbstate_t>(name));
296 install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
297 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
298 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
299 }
300 if (c & locale::monetary)
301 {
302 install(new moneypunct_byname<char, false>(name));
303 install(new moneypunct_byname<char, true>(name));
304 install(new moneypunct_byname<wchar_t, false>(name));
305 install(new moneypunct_byname<wchar_t, true>(name));
306 }
307 if (c & locale::numeric)
308 {
309 install(new numpunct_byname<char>(name));
310 install(new numpunct_byname<wchar_t>(name));
311 }
312 if (c & locale::time)
313 {
314 install(new time_get_byname<char>(name));
315 install(new time_get_byname<wchar_t>(name));
316 install(new time_put_byname<char>(name));
317 install(new time_put_byname<wchar_t>(name));
318 }
319 if (c & locale::messages)
320 {
321 install(new messages_byname<char>(name));
322 install(new messages_byname<wchar_t>(name));
323 }
324 #ifndef _LIBCPP_NO_EXCEPTIONS
325 }
326 catch (...)
327 {
328 for (unsigned i = 0; i < facets_.size(); ++i)
329 if (facets_[i])
330 facets_[i]->__release_shared();
331 throw;
332 }
333 #endif // _LIBCPP_NO_EXCEPTIONS
334 }
335
336 template<class F>
337 inline
338 void
install_from(const locale::__imp & one)339 locale::__imp::install_from(const locale::__imp& one)
340 {
341 long id = F::id.__get();
342 install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
343 }
344
__imp(const __imp & other,const __imp & one,locale::category c)345 locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
346 : facets_(N),
347 name_("*")
348 {
349 facets_ = other.facets_;
350 for (unsigned i = 0; i < facets_.size(); ++i)
351 if (facets_[i])
352 facets_[i]->__add_shared();
353 #ifndef _LIBCPP_NO_EXCEPTIONS
354 try
355 {
356 #endif // _LIBCPP_NO_EXCEPTIONS
357 if (c & locale::collate)
358 {
359 install_from<_VSTD::collate<char> >(one);
360 install_from<_VSTD::collate<wchar_t> >(one);
361 }
362 if (c & locale::ctype)
363 {
364 install_from<_VSTD::ctype<char> >(one);
365 install_from<_VSTD::ctype<wchar_t> >(one);
366 install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
367 install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
368 install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
369 install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
370 }
371 if (c & locale::monetary)
372 {
373 install_from<moneypunct<char, false> >(one);
374 install_from<moneypunct<char, true> >(one);
375 install_from<moneypunct<wchar_t, false> >(one);
376 install_from<moneypunct<wchar_t, true> >(one);
377 install_from<money_get<char> >(one);
378 install_from<money_get<wchar_t> >(one);
379 install_from<money_put<char> >(one);
380 install_from<money_put<wchar_t> >(one);
381 }
382 if (c & locale::numeric)
383 {
384 install_from<numpunct<char> >(one);
385 install_from<numpunct<wchar_t> >(one);
386 install_from<num_get<char> >(one);
387 install_from<num_get<wchar_t> >(one);
388 install_from<num_put<char> >(one);
389 install_from<num_put<wchar_t> >(one);
390 }
391 if (c & locale::time)
392 {
393 install_from<time_get<char> >(one);
394 install_from<time_get<wchar_t> >(one);
395 install_from<time_put<char> >(one);
396 install_from<time_put<wchar_t> >(one);
397 }
398 if (c & locale::messages)
399 {
400 install_from<_VSTD::messages<char> >(one);
401 install_from<_VSTD::messages<wchar_t> >(one);
402 }
403 #ifndef _LIBCPP_NO_EXCEPTIONS
404 }
405 catch (...)
406 {
407 for (unsigned i = 0; i < facets_.size(); ++i)
408 if (facets_[i])
409 facets_[i]->__release_shared();
410 throw;
411 }
412 #endif // _LIBCPP_NO_EXCEPTIONS
413 }
414
__imp(const __imp & other,facet * f,long id)415 locale::__imp::__imp(const __imp& other, facet* f, long id)
416 : facets_(max<size_t>(N, other.facets_.size()+1)),
417 name_("*")
418 {
419 f->__add_shared();
420 unique_ptr<facet, release> hold(f);
421 facets_ = other.facets_;
422 for (unsigned i = 0; i < other.facets_.size(); ++i)
423 if (facets_[i])
424 facets_[i]->__add_shared();
425 install(hold.get(), id);
426 }
427
~__imp()428 locale::__imp::~__imp()
429 {
430 for (unsigned i = 0; i < facets_.size(); ++i)
431 if (facets_[i])
432 facets_[i]->__release_shared();
433 }
434
435 void
install(facet * f,long id)436 locale::__imp::install(facet* f, long id)
437 {
438 f->__add_shared();
439 unique_ptr<facet, release> hold(f);
440 if (static_cast<size_t>(id) >= facets_.size())
441 facets_.resize(static_cast<size_t>(id+1));
442 if (facets_[static_cast<size_t>(id)])
443 facets_[static_cast<size_t>(id)]->__release_shared();
444 facets_[static_cast<size_t>(id)] = hold.release();
445 }
446
447 const locale::facet*
use_facet(long id) const448 locale::__imp::use_facet(long id) const
449 {
450 #ifndef _LIBCPP_NO_EXCEPTIONS
451 if (!has_facet(id))
452 throw bad_cast();
453 #endif // _LIBCPP_NO_EXCEPTIONS
454 return facets_[static_cast<size_t>(id)];
455 }
456
457 // locale
458
459 const locale&
make_classic()460 locale::__imp::make_classic()
461 {
462 // only one thread can get in here and it only gets in once
463 static aligned_storage<sizeof(locale)>::type buf;
464 locale* c = reinterpret_cast<locale*>(&buf);
465 c->__locale_ = &make<__imp>(1u);
466 return *c;
467 }
468
469 const locale&
classic()470 locale::classic()
471 {
472 static const locale& c = __imp::make_classic();
473 return c;
474 }
475
476 locale&
make_global()477 locale::__imp::make_global()
478 {
479 // only one thread can get in here and it only gets in once
480 static aligned_storage<sizeof(locale)>::type buf;
481 ::new (&buf) locale(locale::classic());
482 return *reinterpret_cast<locale*>(&buf);
483 }
484
485 locale&
__global()486 locale::__global()
487 {
488 static locale& g = __imp::make_global();
489 return g;
490 }
491
locale()492 locale::locale() _NOEXCEPT
493 : __locale_(__global().__locale_)
494 {
495 __locale_->__add_shared();
496 }
497
locale(const locale & l)498 locale::locale(const locale& l) _NOEXCEPT
499 : __locale_(l.__locale_)
500 {
501 __locale_->__add_shared();
502 }
503
~locale()504 locale::~locale()
505 {
506 __locale_->__release_shared();
507 }
508
509 const locale&
operator =(const locale & other)510 locale::operator=(const locale& other) _NOEXCEPT
511 {
512 other.__locale_->__add_shared();
513 __locale_->__release_shared();
514 __locale_ = other.__locale_;
515 return *this;
516 }
517
locale(const char * name)518 locale::locale(const char* name)
519 #ifndef _LIBCPP_NO_EXCEPTIONS
520 : __locale_(name ? new __imp(name)
521 : throw runtime_error("locale constructed with null"))
522 #else // _LIBCPP_NO_EXCEPTIONS
523 : __locale_(new __imp(name))
524 #endif
525 {
526 __locale_->__add_shared();
527 }
528
locale(const string & name)529 locale::locale(const string& name)
530 : __locale_(new __imp(name))
531 {
532 __locale_->__add_shared();
533 }
534
locale(const locale & other,const char * name,category c)535 locale::locale(const locale& other, const char* name, category c)
536 #ifndef _LIBCPP_NO_EXCEPTIONS
537 : __locale_(name ? new __imp(*other.__locale_, name, c)
538 : throw runtime_error("locale constructed with null"))
539 #else // _LIBCPP_NO_EXCEPTIONS
540 : __locale_(new __imp(*other.__locale_, name, c))
541 #endif
542 {
543 __locale_->__add_shared();
544 }
545
locale(const locale & other,const string & name,category c)546 locale::locale(const locale& other, const string& name, category c)
547 : __locale_(new __imp(*other.__locale_, name, c))
548 {
549 __locale_->__add_shared();
550 }
551
locale(const locale & other,const locale & one,category c)552 locale::locale(const locale& other, const locale& one, category c)
553 : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
554 {
555 __locale_->__add_shared();
556 }
557
558 string
name() const559 locale::name() const
560 {
561 return __locale_->name();
562 }
563
564 void
__install_ctor(const locale & other,facet * f,long id)565 locale::__install_ctor(const locale& other, facet* f, long id)
566 {
567 if (f)
568 __locale_ = new __imp(*other.__locale_, f, id);
569 else
570 __locale_ = other.__locale_;
571 __locale_->__add_shared();
572 }
573
574 locale
global(const locale & loc)575 locale::global(const locale& loc)
576 {
577 locale& g = __global();
578 locale r = g;
579 g = loc;
580 if (g.name() != "*")
581 setlocale(LC_ALL, g.name().c_str());
582 return r;
583 }
584
585 bool
has_facet(id & x) const586 locale::has_facet(id& x) const
587 {
588 return __locale_->has_facet(x.__get());
589 }
590
591 const locale::facet*
use_facet(id & x) const592 locale::use_facet(id& x) const
593 {
594 return __locale_->use_facet(x.__get());
595 }
596
597 bool
operator ==(const locale & y) const598 locale::operator==(const locale& y) const
599 {
600 return (__locale_ == y.__locale_)
601 || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
602 }
603
604 // locale::facet
605
~facet()606 locale::facet::~facet()
607 {
608 }
609
610 void
__on_zero_shared()611 locale::facet::__on_zero_shared() _NOEXCEPT
612 {
613 delete this;
614 }
615
616 // locale::id
617
618 int32_t locale::id::__next_id = 0;
619
620 namespace
621 {
622
623 class __fake_bind
624 {
625 locale::id* id_;
626 void (locale::id::* pmf_)();
627 public:
__fake_bind(void (locale::id::* pmf)(),locale::id * id)628 __fake_bind(void (locale::id::* pmf)(), locale::id* id)
629 : id_(id), pmf_(pmf) {}
630
operator ()() const631 void operator()() const
632 {
633 (id_->*pmf_)();
634 }
635 };
636
637 }
638
639 long
__get()640 locale::id::__get()
641 {
642 call_once(__flag_, __fake_bind(&locale::id::__init, this));
643 return __id_ - 1;
644 }
645
646 void
__init()647 locale::id::__init()
648 {
649 __id_ = __sync_add_and_fetch(&__next_id, 1);
650 }
651
652 // template <> class collate_byname<char>
653
collate_byname(const char * n,size_t refs)654 collate_byname<char>::collate_byname(const char* n, size_t refs)
655 : collate<char>(refs),
656 __l(newlocale(LC_ALL_MASK, n, 0))
657 {
658 #ifndef _LIBCPP_NO_EXCEPTIONS
659 if (__l == 0)
660 throw runtime_error("collate_byname<char>::collate_byname"
661 " failed to construct for " + string(n));
662 #endif // _LIBCPP_NO_EXCEPTIONS
663 }
664
collate_byname(const string & name,size_t refs)665 collate_byname<char>::collate_byname(const string& name, size_t refs)
666 : collate<char>(refs),
667 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
668 {
669 #ifndef _LIBCPP_NO_EXCEPTIONS
670 if (__l == 0)
671 throw runtime_error("collate_byname<char>::collate_byname"
672 " failed to construct for " + name);
673 #endif // _LIBCPP_NO_EXCEPTIONS
674 }
675
~collate_byname()676 collate_byname<char>::~collate_byname()
677 {
678 freelocale(__l);
679 }
680
681 int
do_compare(const char_type * __lo1,const char_type * __hi1,const char_type * __lo2,const char_type * __hi2) const682 collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
683 const char_type* __lo2, const char_type* __hi2) const
684 {
685 string_type lhs(__lo1, __hi1);
686 string_type rhs(__lo2, __hi2);
687 int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l);
688 if (r < 0)
689 return -1;
690 if (r > 0)
691 return 1;
692 return r;
693 }
694
695 collate_byname<char>::string_type
do_transform(const char_type * lo,const char_type * hi) const696 collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
697 {
698 const string_type in(lo, hi);
699 string_type out(strxfrm_l(0, in.c_str(), 0, __l), char());
700 strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l);
701 return out;
702 }
703
704 // template <> class collate_byname<wchar_t>
705
collate_byname(const char * n,size_t refs)706 collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
707 : collate<wchar_t>(refs),
708 __l(newlocale(LC_ALL_MASK, n, 0))
709 {
710 #ifndef _LIBCPP_NO_EXCEPTIONS
711 if (__l == 0)
712 throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
713 " failed to construct for " + string(n));
714 #endif // _LIBCPP_NO_EXCEPTIONS
715 }
716
collate_byname(const string & name,size_t refs)717 collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
718 : collate<wchar_t>(refs),
719 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
720 {
721 #ifndef _LIBCPP_NO_EXCEPTIONS
722 if (__l == 0)
723 throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
724 " failed to construct for " + name);
725 #endif // _LIBCPP_NO_EXCEPTIONS
726 }
727
~collate_byname()728 collate_byname<wchar_t>::~collate_byname()
729 {
730 freelocale(__l);
731 }
732
733 int
do_compare(const char_type * __lo1,const char_type * __hi1,const char_type * __lo2,const char_type * __hi2) const734 collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
735 const char_type* __lo2, const char_type* __hi2) const
736 {
737 string_type lhs(__lo1, __hi1);
738 string_type rhs(__lo2, __hi2);
739 int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l);
740 if (r < 0)
741 return -1;
742 if (r > 0)
743 return 1;
744 return r;
745 }
746
747 collate_byname<wchar_t>::string_type
do_transform(const char_type * lo,const char_type * hi) const748 collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
749 {
750 const string_type in(lo, hi);
751 string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t());
752 wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l);
753 return out;
754 }
755
756 // template <> class ctype<wchar_t>;
757
758 const ctype_base::mask ctype_base::space;
759 const ctype_base::mask ctype_base::print;
760 const ctype_base::mask ctype_base::cntrl;
761 const ctype_base::mask ctype_base::upper;
762 const ctype_base::mask ctype_base::lower;
763 const ctype_base::mask ctype_base::alpha;
764 const ctype_base::mask ctype_base::digit;
765 const ctype_base::mask ctype_base::punct;
766 const ctype_base::mask ctype_base::xdigit;
767 const ctype_base::mask ctype_base::blank;
768 const ctype_base::mask ctype_base::alnum;
769 const ctype_base::mask ctype_base::graph;
770
771 locale::id ctype<wchar_t>::id;
772
~ctype()773 ctype<wchar_t>::~ctype()
774 {
775 }
776
777 bool
do_is(mask m,char_type c) const778 ctype<wchar_t>::do_is(mask m, char_type c) const
779 {
780 return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
781 }
782
783 const wchar_t*
do_is(const char_type * low,const char_type * high,mask * vec) const784 ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
785 {
786 for (; low != high; ++low, ++vec)
787 *vec = static_cast<mask>(isascii(*low) ?
788 ctype<char>::classic_table()[*low] : 0);
789 return low;
790 }
791
792 const wchar_t*
do_scan_is(mask m,const char_type * low,const char_type * high) const793 ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
794 {
795 for (; low != high; ++low)
796 if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
797 break;
798 return low;
799 }
800
801 const wchar_t*
do_scan_not(mask m,const char_type * low,const char_type * high) const802 ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
803 {
804 for (; low != high; ++low)
805 if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
806 break;
807 return low;
808 }
809
810 wchar_t
do_toupper(char_type c) const811 ctype<wchar_t>::do_toupper(char_type c) const
812 {
813 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
814 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
815 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
816 return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
817 #else
818 return (isascii(c) && iswlower_l(c, __cloc())) ? c-L'a'+L'A' : c;
819 #endif
820 }
821
822 const wchar_t*
do_toupper(char_type * low,const char_type * high) const823 ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
824 {
825 for (; low != high; ++low)
826 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
827 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
828 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
829 *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
830 : *low;
831 #else
832 *low = (isascii(*low) && islower_l(*low, __cloc())) ? (*low-L'a'+L'A') : *low;
833 #endif
834 return low;
835 }
836
837 wchar_t
do_tolower(char_type c) const838 ctype<wchar_t>::do_tolower(char_type c) const
839 {
840 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
841 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
842 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
843 return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
844 #else
845 return (isascii(c) && isupper_l(c, __cloc())) ? c-L'A'+'a' : c;
846 #endif
847 }
848
849 const wchar_t*
do_tolower(char_type * low,const char_type * high) const850 ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
851 {
852 for (; low != high; ++low)
853 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
854 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
855 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
856 *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
857 : *low;
858 #else
859 *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-L'A'+L'a' : *low;
860 #endif
861 return low;
862 }
863
864 wchar_t
do_widen(char c) const865 ctype<wchar_t>::do_widen(char c) const
866 {
867 return c;
868 }
869
870 const char*
do_widen(const char * low,const char * high,char_type * dest) const871 ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
872 {
873 for (; low != high; ++low, ++dest)
874 *dest = *low;
875 return low;
876 }
877
878 char
do_narrow(char_type c,char dfault) const879 ctype<wchar_t>::do_narrow(char_type c, char dfault) const
880 {
881 if (isascii(c))
882 return static_cast<char>(c);
883 return dfault;
884 }
885
886 const wchar_t*
do_narrow(const char_type * low,const char_type * high,char dfault,char * dest) const887 ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
888 {
889 for (; low != high; ++low, ++dest)
890 if (isascii(*low))
891 *dest = static_cast<char>(*low);
892 else
893 *dest = dfault;
894 return low;
895 }
896
897 // template <> class ctype<char>;
898
899 locale::id ctype<char>::id;
900
ctype(const mask * tab,bool del,size_t refs)901 ctype<char>::ctype(const mask* tab, bool del, size_t refs)
902 : locale::facet(refs),
903 __tab_(tab),
904 __del_(del)
905 {
906 if (__tab_ == 0)
907 __tab_ = classic_table();
908 }
909
~ctype()910 ctype<char>::~ctype()
911 {
912 if (__tab_ && __del_)
913 delete [] __tab_;
914 }
915
916 char
do_toupper(char_type c) const917 ctype<char>::do_toupper(char_type c) const
918 {
919 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
920 return isascii(c) ?
921 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
922 #elif defined(__NetBSD__)
923 return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
924 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
925 return isascii(c) ?
926 static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
927 #else
928 return (isascii(c) && islower_l(c, __cloc())) ? c-'a'+'A' : c;
929 #endif
930 }
931
932 const char*
do_toupper(char_type * low,const char_type * high) const933 ctype<char>::do_toupper(char_type* low, const char_type* high) const
934 {
935 for (; low != high; ++low)
936 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
937 *low = isascii(*low) ?
938 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
939 #elif defined(__NetBSD__)
940 *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
941 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
942 *low = isascii(*low) ?
943 static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
944 #else
945 *low = (isascii(*low) && islower_l(*low, __cloc())) ? *low-'a'+'A' : *low;
946 #endif
947 return low;
948 }
949
950 char
do_tolower(char_type c) const951 ctype<char>::do_tolower(char_type c) const
952 {
953 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
954 return isascii(c) ?
955 static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
956 #elif defined(__NetBSD__)
957 return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
958 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
959 return isascii(c) ?
960 static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
961 #else
962 return (isascii(c) && isupper_l(c, __cloc())) ? c-'A'+'a' : c;
963 #endif
964 }
965
966 const char*
do_tolower(char_type * low,const char_type * high) const967 ctype<char>::do_tolower(char_type* low, const char_type* high) const
968 {
969 for (; low != high; ++low)
970 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
971 *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
972 #elif defined(__NetBSD__)
973 *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
974 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
975 *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
976 #else
977 *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-'A'+'a' : *low;
978 #endif
979 return low;
980 }
981
982 char
do_widen(char c) const983 ctype<char>::do_widen(char c) const
984 {
985 return c;
986 }
987
988 const char*
do_widen(const char * low,const char * high,char_type * dest) const989 ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
990 {
991 for (; low != high; ++low, ++dest)
992 *dest = *low;
993 return low;
994 }
995
996 char
do_narrow(char_type c,char dfault) const997 ctype<char>::do_narrow(char_type c, char dfault) const
998 {
999 if (isascii(c))
1000 return static_cast<char>(c);
1001 return dfault;
1002 }
1003
1004 const char*
do_narrow(const char_type * low,const char_type * high,char dfault,char * dest) const1005 ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1006 {
1007 for (; low != high; ++low, ++dest)
1008 if (isascii(*low))
1009 *dest = *low;
1010 else
1011 *dest = dfault;
1012 return low;
1013 }
1014
1015 #ifdef __EMSCRIPTEN__
1016 extern "C" const unsigned short ** __ctype_b_loc();
1017 extern "C" const int ** __ctype_tolower_loc();
1018 extern "C" const int ** __ctype_toupper_loc();
1019 #endif
1020
1021 const ctype<char>::mask*
classic_table()1022 ctype<char>::classic_table() _NOEXCEPT
1023 {
1024 #if defined(__APPLE__) || defined(__FreeBSD__)
1025 return _DefaultRuneLocale.__runetype;
1026 #elif defined(__NetBSD__)
1027 return _C_ctype_tab_ + 1;
1028 #elif defined(__GLIBC__)
1029 return __cloc()->__ctype_b;
1030 #elif __sun__
1031 return __ctype_mask;
1032 #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
1033 return _ctype+1; // internal ctype mask table defined in msvcrt.dll
1034 // This is assumed to be safe, which is a nonsense assumption because we're
1035 // going to end up dereferencing it later...
1036 #elif defined(__EMSCRIPTEN__)
1037 return *__ctype_b_loc();
1038 #elif defined(_AIX)
1039 return (const unsigned int *)__lc_ctype_ptr->obj->mask;
1040 #elif defined(__ANDROID__)
1041 return _ctype_ + 1;
1042 #else
1043 // Platform not supported: abort so the person doing the port knows what to
1044 // fix
1045 # warning ctype<char>::classic_table() is not implemented
1046 printf("ctype<char>::classic_table() is not implemented\n");
1047 abort();
1048 return NULL;
1049 #endif
1050 }
1051
1052 #if defined(__GLIBC__)
1053 const int*
__classic_lower_table()1054 ctype<char>::__classic_lower_table() _NOEXCEPT
1055 {
1056 return __cloc()->__ctype_tolower;
1057 }
1058
1059 const int*
__classic_upper_table()1060 ctype<char>::__classic_upper_table() _NOEXCEPT
1061 {
1062 return __cloc()->__ctype_toupper;
1063 }
1064 #elif __NetBSD__
1065 const short*
__classic_lower_table()1066 ctype<char>::__classic_lower_table() _NOEXCEPT
1067 {
1068 return _C_tolower_tab_ + 1;
1069 }
1070
1071 const short*
__classic_upper_table()1072 ctype<char>::__classic_upper_table() _NOEXCEPT
1073 {
1074 return _C_toupper_tab_ + 1;
1075 }
1076
1077 #elif defined(__EMSCRIPTEN__)
1078 const int*
__classic_lower_table()1079 ctype<char>::__classic_lower_table() _NOEXCEPT
1080 {
1081 return *__ctype_tolower_loc();
1082 }
1083
1084 const int*
__classic_upper_table()1085 ctype<char>::__classic_upper_table() _NOEXCEPT
1086 {
1087 return *__ctype_toupper_loc();
1088 }
1089 #endif // __GLIBC__ || __EMSCRIPTEN__ || __NETBSD__
1090
1091 // template <> class ctype_byname<char>
1092
ctype_byname(const char * name,size_t refs)1093 ctype_byname<char>::ctype_byname(const char* name, size_t refs)
1094 : ctype<char>(0, false, refs),
1095 __l(newlocale(LC_ALL_MASK, name, 0))
1096 {
1097 #ifndef _LIBCPP_NO_EXCEPTIONS
1098 if (__l == 0)
1099 throw runtime_error("ctype_byname<char>::ctype_byname"
1100 " failed to construct for " + string(name));
1101 #endif // _LIBCPP_NO_EXCEPTIONS
1102 }
1103
ctype_byname(const string & name,size_t refs)1104 ctype_byname<char>::ctype_byname(const string& name, size_t refs)
1105 : ctype<char>(0, false, refs),
1106 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1107 {
1108 #ifndef _LIBCPP_NO_EXCEPTIONS
1109 if (__l == 0)
1110 throw runtime_error("ctype_byname<char>::ctype_byname"
1111 " failed to construct for " + name);
1112 #endif // _LIBCPP_NO_EXCEPTIONS
1113 }
1114
~ctype_byname()1115 ctype_byname<char>::~ctype_byname()
1116 {
1117 freelocale(__l);
1118 }
1119
1120 char
do_toupper(char_type c) const1121 ctype_byname<char>::do_toupper(char_type c) const
1122 {
1123 return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l));
1124 }
1125
1126 const char*
do_toupper(char_type * low,const char_type * high) const1127 ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
1128 {
1129 for (; low != high; ++low)
1130 *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l));
1131 return low;
1132 }
1133
1134 char
do_tolower(char_type c) const1135 ctype_byname<char>::do_tolower(char_type c) const
1136 {
1137 return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l));
1138 }
1139
1140 const char*
do_tolower(char_type * low,const char_type * high) const1141 ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
1142 {
1143 for (; low != high; ++low)
1144 *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l));
1145 return low;
1146 }
1147
1148 // template <> class ctype_byname<wchar_t>
1149
ctype_byname(const char * name,size_t refs)1150 ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
1151 : ctype<wchar_t>(refs),
1152 __l(newlocale(LC_ALL_MASK, name, 0))
1153 {
1154 #ifndef _LIBCPP_NO_EXCEPTIONS
1155 if (__l == 0)
1156 throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
1157 " failed to construct for " + string(name));
1158 #endif // _LIBCPP_NO_EXCEPTIONS
1159 }
1160
ctype_byname(const string & name,size_t refs)1161 ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
1162 : ctype<wchar_t>(refs),
1163 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1164 {
1165 #ifndef _LIBCPP_NO_EXCEPTIONS
1166 if (__l == 0)
1167 throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
1168 " failed to construct for " + name);
1169 #endif // _LIBCPP_NO_EXCEPTIONS
1170 }
1171
~ctype_byname()1172 ctype_byname<wchar_t>::~ctype_byname()
1173 {
1174 freelocale(__l);
1175 }
1176
1177 bool
do_is(mask m,char_type c) const1178 ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1179 {
1180 #ifdef _LIBCPP_WCTYPE_IS_MASK
1181 return static_cast<bool>(iswctype_l(c, m, __l));
1182 #else
1183 bool result = false;
1184 wint_t ch = static_cast<wint_t>(c);
1185 if (m & space) result |= (iswspace_l(ch, __l) != 0);
1186 if (m & print) result |= (iswprint_l(ch, __l) != 0);
1187 if (m & cntrl) result |= (iswcntrl_l(ch, __l) != 0);
1188 if (m & upper) result |= (iswupper_l(ch, __l) != 0);
1189 if (m & lower) result |= (iswlower_l(ch, __l) != 0);
1190 if (m & alpha) result |= (iswalpha_l(ch, __l) != 0);
1191 if (m & digit) result |= (iswdigit_l(ch, __l) != 0);
1192 if (m & punct) result |= (iswpunct_l(ch, __l) != 0);
1193 if (m & xdigit) result |= (iswxdigit_l(ch, __l) != 0);
1194 if (m & blank) result |= (iswblank_l(ch, __l) != 0);
1195 return result;
1196 #endif
1197 }
1198
1199 const wchar_t*
do_is(const char_type * low,const char_type * high,mask * vec) const1200 ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1201 {
1202 for (; low != high; ++low, ++vec)
1203 {
1204 if (isascii(*low))
1205 *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
1206 else
1207 {
1208 *vec = 0;
1209 wint_t ch = static_cast<wint_t>(*low);
1210 if (iswspace_l(ch, __l))
1211 *vec |= space;
1212 if (iswprint_l(ch, __l))
1213 *vec |= print;
1214 if (iswcntrl_l(ch, __l))
1215 *vec |= cntrl;
1216 if (iswupper_l(ch, __l))
1217 *vec |= upper;
1218 if (iswlower_l(ch, __l))
1219 *vec |= lower;
1220 if (iswalpha_l(ch, __l))
1221 *vec |= alpha;
1222 if (iswdigit_l(ch, __l))
1223 *vec |= digit;
1224 if (iswpunct_l(ch, __l))
1225 *vec |= punct;
1226 if (iswxdigit_l(ch, __l))
1227 *vec |= xdigit;
1228 }
1229 }
1230 return low;
1231 }
1232
1233 const wchar_t*
do_scan_is(mask m,const char_type * low,const char_type * high) const1234 ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1235 {
1236 for (; low != high; ++low)
1237 {
1238 #ifdef _LIBCPP_WCTYPE_IS_MASK
1239 if (iswctype_l(*low, m, __l))
1240 break;
1241 #else
1242 wint_t ch = static_cast<wint_t>(*low);
1243 if (m & space && iswspace_l(ch, __l)) break;
1244 if (m & print && iswprint_l(ch, __l)) break;
1245 if (m & cntrl && iswcntrl_l(ch, __l)) break;
1246 if (m & upper && iswupper_l(ch, __l)) break;
1247 if (m & lower && iswlower_l(ch, __l)) break;
1248 if (m & alpha && iswalpha_l(ch, __l)) break;
1249 if (m & digit && iswdigit_l(ch, __l)) break;
1250 if (m & punct && iswpunct_l(ch, __l)) break;
1251 if (m & xdigit && iswxdigit_l(ch, __l)) break;
1252 if (m & blank && iswblank_l(ch, __l)) break;
1253 #endif
1254 }
1255 return low;
1256 }
1257
1258 const wchar_t*
do_scan_not(mask m,const char_type * low,const char_type * high) const1259 ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1260 {
1261 for (; low != high; ++low)
1262 {
1263 #ifdef _LIBCPP_WCTYPE_IS_MASK
1264 if (!iswctype_l(*low, m, __l))
1265 break;
1266 #else
1267 wint_t ch = static_cast<wint_t>(*low);
1268 if (m & space && iswspace_l(ch, __l)) continue;
1269 if (m & print && iswprint_l(ch, __l)) continue;
1270 if (m & cntrl && iswcntrl_l(ch, __l)) continue;
1271 if (m & upper && iswupper_l(ch, __l)) continue;
1272 if (m & lower && iswlower_l(ch, __l)) continue;
1273 if (m & alpha && iswalpha_l(ch, __l)) continue;
1274 if (m & digit && iswdigit_l(ch, __l)) continue;
1275 if (m & punct && iswpunct_l(ch, __l)) continue;
1276 if (m & xdigit && iswxdigit_l(ch, __l)) continue;
1277 if (m & blank && iswblank_l(ch, __l)) continue;
1278 break;
1279 #endif
1280 }
1281 return low;
1282 }
1283
1284 wchar_t
do_toupper(char_type c) const1285 ctype_byname<wchar_t>::do_toupper(char_type c) const
1286 {
1287 return towupper_l(c, __l);
1288 }
1289
1290 const wchar_t*
do_toupper(char_type * low,const char_type * high) const1291 ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1292 {
1293 for (; low != high; ++low)
1294 *low = towupper_l(*low, __l);
1295 return low;
1296 }
1297
1298 wchar_t
do_tolower(char_type c) const1299 ctype_byname<wchar_t>::do_tolower(char_type c) const
1300 {
1301 return towlower_l(c, __l);
1302 }
1303
1304 const wchar_t*
do_tolower(char_type * low,const char_type * high) const1305 ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1306 {
1307 for (; low != high; ++low)
1308 *low = towlower_l(*low, __l);
1309 return low;
1310 }
1311
1312 wchar_t
do_widen(char c) const1313 ctype_byname<wchar_t>::do_widen(char c) const
1314 {
1315 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1316 return btowc_l(c, __l);
1317 #else
1318 return __btowc_l(c, __l);
1319 #endif
1320 }
1321
1322 const char*
do_widen(const char * low,const char * high,char_type * dest) const1323 ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1324 {
1325 for (; low != high; ++low, ++dest)
1326 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1327 *dest = btowc_l(*low, __l);
1328 #else
1329 *dest = __btowc_l(*low, __l);
1330 #endif
1331 return low;
1332 }
1333
1334 char
do_narrow(char_type c,char dfault) const1335 ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1336 {
1337 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1338 int r = wctob_l(c, __l);
1339 #else
1340 int r = __wctob_l(c, __l);
1341 #endif
1342 return r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
1343 }
1344
1345 const wchar_t*
do_narrow(const char_type * low,const char_type * high,char dfault,char * dest) const1346 ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1347 {
1348 for (; low != high; ++low, ++dest)
1349 {
1350 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1351 int r = wctob_l(*low, __l);
1352 #else
1353 int r = __wctob_l(*low, __l);
1354 #endif
1355 *dest = r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
1356 }
1357 return low;
1358 }
1359
1360 // template <> class codecvt<char, char, mbstate_t>
1361
1362 locale::id codecvt<char, char, mbstate_t>::id;
1363
~codecvt()1364 codecvt<char, char, mbstate_t>::~codecvt()
1365 {
1366 }
1367
1368 codecvt<char, char, mbstate_t>::result
do_out(state_type &,const intern_type * frm,const intern_type *,const intern_type * & frm_nxt,extern_type * to,extern_type *,extern_type * & to_nxt) const1369 codecvt<char, char, mbstate_t>::do_out(state_type&,
1370 const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
1371 extern_type* to, extern_type*, extern_type*& to_nxt) const
1372 {
1373 frm_nxt = frm;
1374 to_nxt = to;
1375 return noconv;
1376 }
1377
1378 codecvt<char, char, mbstate_t>::result
do_in(state_type &,const extern_type * frm,const extern_type *,const extern_type * & frm_nxt,intern_type * to,intern_type *,intern_type * & to_nxt) const1379 codecvt<char, char, mbstate_t>::do_in(state_type&,
1380 const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
1381 intern_type* to, intern_type*, intern_type*& to_nxt) const
1382 {
1383 frm_nxt = frm;
1384 to_nxt = to;
1385 return noconv;
1386 }
1387
1388 codecvt<char, char, mbstate_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const1389 codecvt<char, char, mbstate_t>::do_unshift(state_type&,
1390 extern_type* to, extern_type*, extern_type*& to_nxt) const
1391 {
1392 to_nxt = to;
1393 return noconv;
1394 }
1395
1396 int
do_encoding() const1397 codecvt<char, char, mbstate_t>::do_encoding() const _NOEXCEPT
1398 {
1399 return 1;
1400 }
1401
1402 bool
do_always_noconv() const1403 codecvt<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
1404 {
1405 return true;
1406 }
1407
1408 int
do_length(state_type &,const extern_type * frm,const extern_type * end,size_t mx) const1409 codecvt<char, char, mbstate_t>::do_length(state_type&,
1410 const extern_type* frm, const extern_type* end, size_t mx) const
1411 {
1412 return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
1413 }
1414
1415 int
do_max_length() const1416 codecvt<char, char, mbstate_t>::do_max_length() const _NOEXCEPT
1417 {
1418 return 1;
1419 }
1420
1421 // template <> class codecvt<wchar_t, char, mbstate_t>
1422
1423 locale::id codecvt<wchar_t, char, mbstate_t>::id;
1424
codecvt(size_t refs)1425 codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1426 : locale::facet(refs),
1427 __l(_LIBCPP_GET_C_LOCALE)
1428 {
1429 }
1430
codecvt(const char * nm,size_t refs)1431 codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1432 : locale::facet(refs),
1433 __l(newlocale(LC_ALL_MASK, nm, 0))
1434 {
1435 #ifndef _LIBCPP_NO_EXCEPTIONS
1436 if (__l == 0)
1437 throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1438 " failed to construct for " + string(nm));
1439 #endif // _LIBCPP_NO_EXCEPTIONS
1440 }
1441
~codecvt()1442 codecvt<wchar_t, char, mbstate_t>::~codecvt()
1443 {
1444 if (__l != _LIBCPP_GET_C_LOCALE)
1445 freelocale(__l);
1446 }
1447
1448 codecvt<wchar_t, char, mbstate_t>::result
do_out(state_type & st,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const1449 codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
1450 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
1451 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1452 {
1453 // look for first internal null in frm
1454 const intern_type* fend = frm;
1455 for (; fend != frm_end; ++fend)
1456 if (*fend == 0)
1457 break;
1458 // loop over all null-terminated sequences in frm
1459 to_nxt = to;
1460 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1461 {
1462 // save state in case it is needed to recover to_nxt on error
1463 mbstate_t save_state = st;
1464 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1465 size_t n = wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1466 static_cast<size_t>(to_end-to), &st, __l);
1467 #else
1468 size_t n = __wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1469 #endif
1470 if (n == size_t(-1))
1471 {
1472 // need to recover to_nxt
1473 for (to_nxt = to; frm != frm_nxt; ++frm)
1474 {
1475 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1476 n = wcrtomb_l(to_nxt, *frm, &save_state, __l);
1477 #else
1478 n = __wcrtomb_l(to_nxt, *frm, &save_state, __l);
1479 #endif
1480 if (n == size_t(-1))
1481 break;
1482 to_nxt += n;
1483 }
1484 frm_nxt = frm;
1485 return error;
1486 }
1487 if (n == 0)
1488 return partial;
1489 to_nxt += n;
1490 if (to_nxt == to_end)
1491 break;
1492 if (fend != frm_end) // set up next null terminated sequence
1493 {
1494 // Try to write the terminating null
1495 extern_type tmp[MB_LEN_MAX];
1496 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1497 n = wcrtomb_l(tmp, intern_type(), &st, __l);
1498 #else
1499 n = __wcrtomb_l(tmp, intern_type(), &st, __l);
1500 #endif
1501 if (n == size_t(-1)) // on error
1502 return error;
1503 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1504 return partial;
1505 for (extern_type* p = tmp; n; --n) // write it
1506 *to_nxt++ = *p++;
1507 ++frm_nxt;
1508 // look for next null in frm
1509 for (fend = frm_nxt; fend != frm_end; ++fend)
1510 if (*fend == 0)
1511 break;
1512 }
1513 }
1514 return frm_nxt == frm_end ? ok : partial;
1515 }
1516
1517 codecvt<wchar_t, char, mbstate_t>::result
do_in(state_type & st,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const1518 codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
1519 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
1520 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1521 {
1522 // look for first internal null in frm
1523 const extern_type* fend = frm;
1524 for (; fend != frm_end; ++fend)
1525 if (*fend == 0)
1526 break;
1527 // loop over all null-terminated sequences in frm
1528 to_nxt = to;
1529 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1530 {
1531 // save state in case it is needed to recover to_nxt on error
1532 mbstate_t save_state = st;
1533 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1534 size_t n = mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1535 static_cast<size_t>(to_end-to), &st, __l);
1536 #else
1537 size_t n = __mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1538 #endif
1539 if (n == size_t(-1))
1540 {
1541 // need to recover to_nxt
1542 for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1543 {
1544 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1545 n = mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
1546 &save_state, __l);
1547 #else
1548 n = __mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l);
1549 #endif
1550 switch (n)
1551 {
1552 case 0:
1553 ++frm;
1554 break;
1555 case size_t(-1):
1556 frm_nxt = frm;
1557 return error;
1558 case size_t(-2):
1559 frm_nxt = frm;
1560 return partial;
1561 default:
1562 frm += n;
1563 break;
1564 }
1565 }
1566 frm_nxt = frm;
1567 return frm_nxt == frm_end ? ok : partial;
1568 }
1569 if (n == 0)
1570 return error;
1571 to_nxt += n;
1572 if (to_nxt == to_end)
1573 break;
1574 if (fend != frm_end) // set up next null terminated sequence
1575 {
1576 // Try to write the terminating null
1577 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1578 n = mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1579 #else
1580 n = __mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1581 #endif
1582 if (n != 0) // on error
1583 return error;
1584 ++to_nxt;
1585 ++frm_nxt;
1586 // look for next null in frm
1587 for (fend = frm_nxt; fend != frm_end; ++fend)
1588 if (*fend == 0)
1589 break;
1590 }
1591 }
1592 return frm_nxt == frm_end ? ok : partial;
1593 }
1594
1595 codecvt<wchar_t, char, mbstate_t>::result
do_unshift(state_type & st,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const1596 codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1597 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1598 {
1599 to_nxt = to;
1600 extern_type tmp[MB_LEN_MAX];
1601 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1602 size_t n = wcrtomb_l(tmp, intern_type(), &st, __l);
1603 #else
1604 size_t n = __wcrtomb_l(tmp, intern_type(), &st, __l);
1605 #endif
1606 if (n == size_t(-1) || n == 0) // on error
1607 return error;
1608 --n;
1609 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1610 return partial;
1611 for (extern_type* p = tmp; n; --n) // write it
1612 *to_nxt++ = *p++;
1613 return ok;
1614 }
1615
1616 int
do_encoding() const1617 codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
1618 {
1619 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1620 if (mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) == 0)
1621 #else
1622 if (__mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) == 0)
1623 #endif
1624 {
1625 // stateless encoding
1626 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1627 if (__l == 0 || MB_CUR_MAX_L(__l) == 1) // there are no known constant length encodings
1628 #else
1629 if (__l == 0 || __mb_cur_max_l(__l) == 1) // there are no known constant length encodings
1630 #endif
1631 return 1; // which take more than 1 char to form a wchar_t
1632 return 0;
1633 }
1634 return -1;
1635 }
1636
1637 bool
do_always_noconv() const1638 codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
1639 {
1640 return false;
1641 }
1642
1643 int
do_length(state_type & st,const extern_type * frm,const extern_type * frm_end,size_t mx) const1644 codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1645 const extern_type* frm, const extern_type* frm_end, size_t mx) const
1646 {
1647 int nbytes = 0;
1648 for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1649 {
1650 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1651 size_t n = mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l);
1652 #else
1653 size_t n = __mbrlen_l(frm, frm_end-frm, &st, __l);
1654 #endif
1655 switch (n)
1656 {
1657 case 0:
1658 ++nbytes;
1659 ++frm;
1660 break;
1661 case size_t(-1):
1662 case size_t(-2):
1663 return nbytes;
1664 default:
1665 nbytes += n;
1666 frm += n;
1667 break;
1668 }
1669 }
1670 return nbytes;
1671 }
1672
1673 int
do_max_length() const1674 codecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
1675 {
1676 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1677 return __l == 0 ? 1 : static_cast<int>( MB_CUR_MAX_L(__l));
1678 #else
1679 return __l == 0 ? 1 : static_cast<int>(__mb_cur_max_l(__l));
1680 #endif
1681 }
1682
1683 // Valid UTF ranges
1684 // UTF-32 UTF-16 UTF-8 # of code points
1685 // first second first second third fourth
1686 // 000000 - 00007F 0000 - 007F 00 - 7F 127
1687 // 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1688 // 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1689 // 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1690 // 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1691 // 00D800 - 00DFFF invalid
1692 // 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1693 // 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1694 // 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1695 // 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1696
1697 static
1698 codecvt_base::result
utf16_to_utf8(const uint16_t * frm,const uint16_t * frm_end,const uint16_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))1699 utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1700 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1701 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1702 {
1703 frm_nxt = frm;
1704 to_nxt = to;
1705 if (mode & generate_header)
1706 {
1707 if (to_end-to_nxt < 3)
1708 return codecvt_base::partial;
1709 *to_nxt++ = static_cast<uint8_t>(0xEF);
1710 *to_nxt++ = static_cast<uint8_t>(0xBB);
1711 *to_nxt++ = static_cast<uint8_t>(0xBF);
1712 }
1713 for (; frm_nxt < frm_end; ++frm_nxt)
1714 {
1715 uint16_t wc1 = *frm_nxt;
1716 if (wc1 > Maxcode)
1717 return codecvt_base::error;
1718 if (wc1 < 0x0080)
1719 {
1720 if (to_end-to_nxt < 1)
1721 return codecvt_base::partial;
1722 *to_nxt++ = static_cast<uint8_t>(wc1);
1723 }
1724 else if (wc1 < 0x0800)
1725 {
1726 if (to_end-to_nxt < 2)
1727 return codecvt_base::partial;
1728 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1729 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1730 }
1731 else if (wc1 < 0xD800)
1732 {
1733 if (to_end-to_nxt < 3)
1734 return codecvt_base::partial;
1735 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1736 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1737 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1738 }
1739 else if (wc1 < 0xDC00)
1740 {
1741 if (frm_end-frm_nxt < 2)
1742 return codecvt_base::partial;
1743 uint16_t wc2 = frm_nxt[1];
1744 if ((wc2 & 0xFC00) != 0xDC00)
1745 return codecvt_base::error;
1746 if (to_end-to_nxt < 4)
1747 return codecvt_base::partial;
1748 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1749 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1750 return codecvt_base::error;
1751 ++frm_nxt;
1752 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1753 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1754 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1755 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1756 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1757 }
1758 else if (wc1 < 0xE000)
1759 {
1760 return codecvt_base::error;
1761 }
1762 else
1763 {
1764 if (to_end-to_nxt < 3)
1765 return codecvt_base::partial;
1766 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1767 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1768 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1769 }
1770 }
1771 return codecvt_base::ok;
1772 }
1773
1774 static
1775 codecvt_base::result
utf16_to_utf8(const uint32_t * frm,const uint32_t * frm_end,const uint32_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))1776 utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1777 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1778 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1779 {
1780 frm_nxt = frm;
1781 to_nxt = to;
1782 if (mode & generate_header)
1783 {
1784 if (to_end-to_nxt < 3)
1785 return codecvt_base::partial;
1786 *to_nxt++ = static_cast<uint8_t>(0xEF);
1787 *to_nxt++ = static_cast<uint8_t>(0xBB);
1788 *to_nxt++ = static_cast<uint8_t>(0xBF);
1789 }
1790 for (; frm_nxt < frm_end; ++frm_nxt)
1791 {
1792 uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1793 if (wc1 > Maxcode)
1794 return codecvt_base::error;
1795 if (wc1 < 0x0080)
1796 {
1797 if (to_end-to_nxt < 1)
1798 return codecvt_base::partial;
1799 *to_nxt++ = static_cast<uint8_t>(wc1);
1800 }
1801 else if (wc1 < 0x0800)
1802 {
1803 if (to_end-to_nxt < 2)
1804 return codecvt_base::partial;
1805 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1806 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1807 }
1808 else if (wc1 < 0xD800)
1809 {
1810 if (to_end-to_nxt < 3)
1811 return codecvt_base::partial;
1812 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1813 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1814 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1815 }
1816 else if (wc1 < 0xDC00)
1817 {
1818 if (frm_end-frm_nxt < 2)
1819 return codecvt_base::partial;
1820 uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1821 if ((wc2 & 0xFC00) != 0xDC00)
1822 return codecvt_base::error;
1823 if (to_end-to_nxt < 4)
1824 return codecvt_base::partial;
1825 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1826 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1827 return codecvt_base::error;
1828 ++frm_nxt;
1829 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1830 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1831 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1832 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1833 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1834 }
1835 else if (wc1 < 0xE000)
1836 {
1837 return codecvt_base::error;
1838 }
1839 else
1840 {
1841 if (to_end-to_nxt < 3)
1842 return codecvt_base::partial;
1843 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1844 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1845 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1846 }
1847 }
1848 return codecvt_base::ok;
1849 }
1850
1851 static
1852 codecvt_base::result
utf8_to_utf16(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint16_t * to,uint16_t * to_end,uint16_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))1853 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1854 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1855 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1856 {
1857 frm_nxt = frm;
1858 to_nxt = to;
1859 if (mode & consume_header)
1860 {
1861 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1862 frm_nxt[2] == 0xBF)
1863 frm_nxt += 3;
1864 }
1865 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1866 {
1867 uint8_t c1 = *frm_nxt;
1868 if (c1 > Maxcode)
1869 return codecvt_base::error;
1870 if (c1 < 0x80)
1871 {
1872 *to_nxt = static_cast<uint16_t>(c1);
1873 ++frm_nxt;
1874 }
1875 else if (c1 < 0xC2)
1876 {
1877 return codecvt_base::error;
1878 }
1879 else if (c1 < 0xE0)
1880 {
1881 if (frm_end-frm_nxt < 2)
1882 return codecvt_base::partial;
1883 uint8_t c2 = frm_nxt[1];
1884 if ((c2 & 0xC0) != 0x80)
1885 return codecvt_base::error;
1886 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1887 if (t > Maxcode)
1888 return codecvt_base::error;
1889 *to_nxt = t;
1890 frm_nxt += 2;
1891 }
1892 else if (c1 < 0xF0)
1893 {
1894 if (frm_end-frm_nxt < 3)
1895 return codecvt_base::partial;
1896 uint8_t c2 = frm_nxt[1];
1897 uint8_t c3 = frm_nxt[2];
1898 switch (c1)
1899 {
1900 case 0xE0:
1901 if ((c2 & 0xE0) != 0xA0)
1902 return codecvt_base::error;
1903 break;
1904 case 0xED:
1905 if ((c2 & 0xE0) != 0x80)
1906 return codecvt_base::error;
1907 break;
1908 default:
1909 if ((c2 & 0xC0) != 0x80)
1910 return codecvt_base::error;
1911 break;
1912 }
1913 if ((c3 & 0xC0) != 0x80)
1914 return codecvt_base::error;
1915 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1916 | ((c2 & 0x3F) << 6)
1917 | (c3 & 0x3F));
1918 if (t > Maxcode)
1919 return codecvt_base::error;
1920 *to_nxt = t;
1921 frm_nxt += 3;
1922 }
1923 else if (c1 < 0xF5)
1924 {
1925 if (frm_end-frm_nxt < 4)
1926 return codecvt_base::partial;
1927 uint8_t c2 = frm_nxt[1];
1928 uint8_t c3 = frm_nxt[2];
1929 uint8_t c4 = frm_nxt[3];
1930 switch (c1)
1931 {
1932 case 0xF0:
1933 if (!(0x90 <= c2 && c2 <= 0xBF))
1934 return codecvt_base::error;
1935 break;
1936 case 0xF4:
1937 if ((c2 & 0xF0) != 0x80)
1938 return codecvt_base::error;
1939 break;
1940 default:
1941 if ((c2 & 0xC0) != 0x80)
1942 return codecvt_base::error;
1943 break;
1944 }
1945 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1946 return codecvt_base::error;
1947 if (to_end-to_nxt < 2)
1948 return codecvt_base::partial;
1949 if ((((c1 & 7UL) << 18) +
1950 ((c2 & 0x3FUL) << 12) +
1951 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
1952 return codecvt_base::error;
1953 *to_nxt = static_cast<uint16_t>(
1954 0xD800
1955 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1956 | ((c2 & 0x0F) << 2)
1957 | ((c3 & 0x30) >> 4));
1958 *++to_nxt = static_cast<uint16_t>(
1959 0xDC00
1960 | ((c3 & 0x0F) << 6)
1961 | (c4 & 0x3F));
1962 frm_nxt += 4;
1963 }
1964 else
1965 {
1966 return codecvt_base::error;
1967 }
1968 }
1969 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1970 }
1971
1972 static
1973 codecvt_base::result
utf8_to_utf16(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint32_t * to,uint32_t * to_end,uint32_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))1974 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1975 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
1976 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1977 {
1978 frm_nxt = frm;
1979 to_nxt = to;
1980 if (mode & consume_header)
1981 {
1982 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1983 frm_nxt[2] == 0xBF)
1984 frm_nxt += 3;
1985 }
1986 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1987 {
1988 uint8_t c1 = *frm_nxt;
1989 if (c1 > Maxcode)
1990 return codecvt_base::error;
1991 if (c1 < 0x80)
1992 {
1993 *to_nxt = static_cast<uint32_t>(c1);
1994 ++frm_nxt;
1995 }
1996 else if (c1 < 0xC2)
1997 {
1998 return codecvt_base::error;
1999 }
2000 else if (c1 < 0xE0)
2001 {
2002 if (frm_end-frm_nxt < 2)
2003 return codecvt_base::partial;
2004 uint8_t c2 = frm_nxt[1];
2005 if ((c2 & 0xC0) != 0x80)
2006 return codecvt_base::error;
2007 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2008 if (t > Maxcode)
2009 return codecvt_base::error;
2010 *to_nxt = static_cast<uint32_t>(t);
2011 frm_nxt += 2;
2012 }
2013 else if (c1 < 0xF0)
2014 {
2015 if (frm_end-frm_nxt < 3)
2016 return codecvt_base::partial;
2017 uint8_t c2 = frm_nxt[1];
2018 uint8_t c3 = frm_nxt[2];
2019 switch (c1)
2020 {
2021 case 0xE0:
2022 if ((c2 & 0xE0) != 0xA0)
2023 return codecvt_base::error;
2024 break;
2025 case 0xED:
2026 if ((c2 & 0xE0) != 0x80)
2027 return codecvt_base::error;
2028 break;
2029 default:
2030 if ((c2 & 0xC0) != 0x80)
2031 return codecvt_base::error;
2032 break;
2033 }
2034 if ((c3 & 0xC0) != 0x80)
2035 return codecvt_base::error;
2036 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2037 | ((c2 & 0x3F) << 6)
2038 | (c3 & 0x3F));
2039 if (t > Maxcode)
2040 return codecvt_base::error;
2041 *to_nxt = static_cast<uint32_t>(t);
2042 frm_nxt += 3;
2043 }
2044 else if (c1 < 0xF5)
2045 {
2046 if (frm_end-frm_nxt < 4)
2047 return codecvt_base::partial;
2048 uint8_t c2 = frm_nxt[1];
2049 uint8_t c3 = frm_nxt[2];
2050 uint8_t c4 = frm_nxt[3];
2051 switch (c1)
2052 {
2053 case 0xF0:
2054 if (!(0x90 <= c2 && c2 <= 0xBF))
2055 return codecvt_base::error;
2056 break;
2057 case 0xF4:
2058 if ((c2 & 0xF0) != 0x80)
2059 return codecvt_base::error;
2060 break;
2061 default:
2062 if ((c2 & 0xC0) != 0x80)
2063 return codecvt_base::error;
2064 break;
2065 }
2066 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2067 return codecvt_base::error;
2068 if (to_end-to_nxt < 2)
2069 return codecvt_base::partial;
2070 if ((((c1 & 7UL) << 18) +
2071 ((c2 & 0x3FUL) << 12) +
2072 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2073 return codecvt_base::error;
2074 *to_nxt = static_cast<uint32_t>(
2075 0xD800
2076 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2077 | ((c2 & 0x0F) << 2)
2078 | ((c3 & 0x30) >> 4));
2079 *++to_nxt = static_cast<uint32_t>(
2080 0xDC00
2081 | ((c3 & 0x0F) << 6)
2082 | (c4 & 0x3F));
2083 frm_nxt += 4;
2084 }
2085 else
2086 {
2087 return codecvt_base::error;
2088 }
2089 }
2090 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2091 }
2092
2093 static
2094 int
utf8_to_utf16_length(const uint8_t * frm,const uint8_t * frm_end,size_t mx,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2095 utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
2096 size_t mx, unsigned long Maxcode = 0x10FFFF,
2097 codecvt_mode mode = codecvt_mode(0))
2098 {
2099 const uint8_t* frm_nxt = frm;
2100 if (mode & consume_header)
2101 {
2102 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2103 frm_nxt[2] == 0xBF)
2104 frm_nxt += 3;
2105 }
2106 for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
2107 {
2108 uint8_t c1 = *frm_nxt;
2109 if (c1 > Maxcode)
2110 break;
2111 if (c1 < 0x80)
2112 {
2113 ++frm_nxt;
2114 }
2115 else if (c1 < 0xC2)
2116 {
2117 break;
2118 }
2119 else if (c1 < 0xE0)
2120 {
2121 if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
2122 break;
2123 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
2124 if (t > Maxcode)
2125 break;
2126 frm_nxt += 2;
2127 }
2128 else if (c1 < 0xF0)
2129 {
2130 if (frm_end-frm_nxt < 3)
2131 break;
2132 uint8_t c2 = frm_nxt[1];
2133 uint8_t c3 = frm_nxt[2];
2134 switch (c1)
2135 {
2136 case 0xE0:
2137 if ((c2 & 0xE0) != 0xA0)
2138 return static_cast<int>(frm_nxt - frm);
2139 break;
2140 case 0xED:
2141 if ((c2 & 0xE0) != 0x80)
2142 return static_cast<int>(frm_nxt - frm);
2143 break;
2144 default:
2145 if ((c2 & 0xC0) != 0x80)
2146 return static_cast<int>(frm_nxt - frm);
2147 break;
2148 }
2149 if ((c3 & 0xC0) != 0x80)
2150 break;
2151 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2152 break;
2153 frm_nxt += 3;
2154 }
2155 else if (c1 < 0xF5)
2156 {
2157 if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
2158 break;
2159 uint8_t c2 = frm_nxt[1];
2160 uint8_t c3 = frm_nxt[2];
2161 uint8_t c4 = frm_nxt[3];
2162 switch (c1)
2163 {
2164 case 0xF0:
2165 if (!(0x90 <= c2 && c2 <= 0xBF))
2166 return static_cast<int>(frm_nxt - frm);
2167 break;
2168 case 0xF4:
2169 if ((c2 & 0xF0) != 0x80)
2170 return static_cast<int>(frm_nxt - frm);
2171 break;
2172 default:
2173 if ((c2 & 0xC0) != 0x80)
2174 return static_cast<int>(frm_nxt - frm);
2175 break;
2176 }
2177 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2178 break;
2179 if ((((c1 & 7UL) << 18) +
2180 ((c2 & 0x3FUL) << 12) +
2181 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2182 break;
2183 ++nchar16_t;
2184 frm_nxt += 4;
2185 }
2186 else
2187 {
2188 break;
2189 }
2190 }
2191 return static_cast<int>(frm_nxt - frm);
2192 }
2193
2194 static
2195 codecvt_base::result
ucs4_to_utf8(const uint32_t * frm,const uint32_t * frm_end,const uint32_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2196 ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2197 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2198 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2199 {
2200 frm_nxt = frm;
2201 to_nxt = to;
2202 if (mode & generate_header)
2203 {
2204 if (to_end-to_nxt < 3)
2205 return codecvt_base::partial;
2206 *to_nxt++ = static_cast<uint8_t>(0xEF);
2207 *to_nxt++ = static_cast<uint8_t>(0xBB);
2208 *to_nxt++ = static_cast<uint8_t>(0xBF);
2209 }
2210 for (; frm_nxt < frm_end; ++frm_nxt)
2211 {
2212 uint32_t wc = *frm_nxt;
2213 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2214 return codecvt_base::error;
2215 if (wc < 0x000080)
2216 {
2217 if (to_end-to_nxt < 1)
2218 return codecvt_base::partial;
2219 *to_nxt++ = static_cast<uint8_t>(wc);
2220 }
2221 else if (wc < 0x000800)
2222 {
2223 if (to_end-to_nxt < 2)
2224 return codecvt_base::partial;
2225 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2226 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2227 }
2228 else if (wc < 0x010000)
2229 {
2230 if (to_end-to_nxt < 3)
2231 return codecvt_base::partial;
2232 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2233 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2234 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2235 }
2236 else // if (wc < 0x110000)
2237 {
2238 if (to_end-to_nxt < 4)
2239 return codecvt_base::partial;
2240 *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
2241 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2242 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2243 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
2244 }
2245 }
2246 return codecvt_base::ok;
2247 }
2248
2249 static
2250 codecvt_base::result
utf8_to_ucs4(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint32_t * to,uint32_t * to_end,uint32_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2251 utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2252 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2253 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2254 {
2255 frm_nxt = frm;
2256 to_nxt = to;
2257 if (mode & consume_header)
2258 {
2259 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2260 frm_nxt[2] == 0xBF)
2261 frm_nxt += 3;
2262 }
2263 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2264 {
2265 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2266 if (c1 < 0x80)
2267 {
2268 if (c1 > Maxcode)
2269 return codecvt_base::error;
2270 *to_nxt = static_cast<uint32_t>(c1);
2271 ++frm_nxt;
2272 }
2273 else if (c1 < 0xC2)
2274 {
2275 return codecvt_base::error;
2276 }
2277 else if (c1 < 0xE0)
2278 {
2279 if (frm_end-frm_nxt < 2)
2280 return codecvt_base::partial;
2281 uint8_t c2 = frm_nxt[1];
2282 if ((c2 & 0xC0) != 0x80)
2283 return codecvt_base::error;
2284 uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2285 | (c2 & 0x3F));
2286 if (t > Maxcode)
2287 return codecvt_base::error;
2288 *to_nxt = t;
2289 frm_nxt += 2;
2290 }
2291 else if (c1 < 0xF0)
2292 {
2293 if (frm_end-frm_nxt < 3)
2294 return codecvt_base::partial;
2295 uint8_t c2 = frm_nxt[1];
2296 uint8_t c3 = frm_nxt[2];
2297 switch (c1)
2298 {
2299 case 0xE0:
2300 if ((c2 & 0xE0) != 0xA0)
2301 return codecvt_base::error;
2302 break;
2303 case 0xED:
2304 if ((c2 & 0xE0) != 0x80)
2305 return codecvt_base::error;
2306 break;
2307 default:
2308 if ((c2 & 0xC0) != 0x80)
2309 return codecvt_base::error;
2310 break;
2311 }
2312 if ((c3 & 0xC0) != 0x80)
2313 return codecvt_base::error;
2314 uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2315 | ((c2 & 0x3F) << 6)
2316 | (c3 & 0x3F));
2317 if (t > Maxcode)
2318 return codecvt_base::error;
2319 *to_nxt = t;
2320 frm_nxt += 3;
2321 }
2322 else if (c1 < 0xF5)
2323 {
2324 if (frm_end-frm_nxt < 4)
2325 return codecvt_base::partial;
2326 uint8_t c2 = frm_nxt[1];
2327 uint8_t c3 = frm_nxt[2];
2328 uint8_t c4 = frm_nxt[3];
2329 switch (c1)
2330 {
2331 case 0xF0:
2332 if (!(0x90 <= c2 && c2 <= 0xBF))
2333 return codecvt_base::error;
2334 break;
2335 case 0xF4:
2336 if ((c2 & 0xF0) != 0x80)
2337 return codecvt_base::error;
2338 break;
2339 default:
2340 if ((c2 & 0xC0) != 0x80)
2341 return codecvt_base::error;
2342 break;
2343 }
2344 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2345 return codecvt_base::error;
2346 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2347 | ((c2 & 0x3F) << 12)
2348 | ((c3 & 0x3F) << 6)
2349 | (c4 & 0x3F));
2350 if (t > Maxcode)
2351 return codecvt_base::error;
2352 *to_nxt = t;
2353 frm_nxt += 4;
2354 }
2355 else
2356 {
2357 return codecvt_base::error;
2358 }
2359 }
2360 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2361 }
2362
2363 static
2364 int
utf8_to_ucs4_length(const uint8_t * frm,const uint8_t * frm_end,size_t mx,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2365 utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2366 size_t mx, unsigned long Maxcode = 0x10FFFF,
2367 codecvt_mode mode = codecvt_mode(0))
2368 {
2369 const uint8_t* frm_nxt = frm;
2370 if (mode & consume_header)
2371 {
2372 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2373 frm_nxt[2] == 0xBF)
2374 frm_nxt += 3;
2375 }
2376 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2377 {
2378 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2379 if (c1 < 0x80)
2380 {
2381 if (c1 > Maxcode)
2382 break;
2383 ++frm_nxt;
2384 }
2385 else if (c1 < 0xC2)
2386 {
2387 break;
2388 }
2389 else if (c1 < 0xE0)
2390 {
2391 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2392 break;
2393 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2394 break;
2395 frm_nxt += 2;
2396 }
2397 else if (c1 < 0xF0)
2398 {
2399 if (frm_end-frm_nxt < 3)
2400 break;
2401 uint8_t c2 = frm_nxt[1];
2402 uint8_t c3 = frm_nxt[2];
2403 switch (c1)
2404 {
2405 case 0xE0:
2406 if ((c2 & 0xE0) != 0xA0)
2407 return static_cast<int>(frm_nxt - frm);
2408 break;
2409 case 0xED:
2410 if ((c2 & 0xE0) != 0x80)
2411 return static_cast<int>(frm_nxt - frm);
2412 break;
2413 default:
2414 if ((c2 & 0xC0) != 0x80)
2415 return static_cast<int>(frm_nxt - frm);
2416 break;
2417 }
2418 if ((c3 & 0xC0) != 0x80)
2419 break;
2420 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2421 break;
2422 frm_nxt += 3;
2423 }
2424 else if (c1 < 0xF5)
2425 {
2426 if (frm_end-frm_nxt < 4)
2427 break;
2428 uint8_t c2 = frm_nxt[1];
2429 uint8_t c3 = frm_nxt[2];
2430 uint8_t c4 = frm_nxt[3];
2431 switch (c1)
2432 {
2433 case 0xF0:
2434 if (!(0x90 <= c2 && c2 <= 0xBF))
2435 return static_cast<int>(frm_nxt - frm);
2436 break;
2437 case 0xF4:
2438 if ((c2 & 0xF0) != 0x80)
2439 return static_cast<int>(frm_nxt - frm);
2440 break;
2441 default:
2442 if ((c2 & 0xC0) != 0x80)
2443 return static_cast<int>(frm_nxt - frm);
2444 break;
2445 }
2446 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2447 break;
2448 if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
2449 ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode)
2450 break;
2451 frm_nxt += 4;
2452 }
2453 else
2454 {
2455 break;
2456 }
2457 }
2458 return static_cast<int>(frm_nxt - frm);
2459 }
2460
2461 static
2462 codecvt_base::result
ucs2_to_utf8(const uint16_t * frm,const uint16_t * frm_end,const uint16_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2463 ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2464 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2465 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2466 {
2467 frm_nxt = frm;
2468 to_nxt = to;
2469 if (mode & generate_header)
2470 {
2471 if (to_end-to_nxt < 3)
2472 return codecvt_base::partial;
2473 *to_nxt++ = static_cast<uint8_t>(0xEF);
2474 *to_nxt++ = static_cast<uint8_t>(0xBB);
2475 *to_nxt++ = static_cast<uint8_t>(0xBF);
2476 }
2477 for (; frm_nxt < frm_end; ++frm_nxt)
2478 {
2479 uint16_t wc = *frm_nxt;
2480 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2481 return codecvt_base::error;
2482 if (wc < 0x0080)
2483 {
2484 if (to_end-to_nxt < 1)
2485 return codecvt_base::partial;
2486 *to_nxt++ = static_cast<uint8_t>(wc);
2487 }
2488 else if (wc < 0x0800)
2489 {
2490 if (to_end-to_nxt < 2)
2491 return codecvt_base::partial;
2492 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2493 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2494 }
2495 else // if (wc <= 0xFFFF)
2496 {
2497 if (to_end-to_nxt < 3)
2498 return codecvt_base::partial;
2499 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2500 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2501 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2502 }
2503 }
2504 return codecvt_base::ok;
2505 }
2506
2507 static
2508 codecvt_base::result
utf8_to_ucs2(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint16_t * to,uint16_t * to_end,uint16_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2509 utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2510 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2511 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2512 {
2513 frm_nxt = frm;
2514 to_nxt = to;
2515 if (mode & consume_header)
2516 {
2517 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2518 frm_nxt[2] == 0xBF)
2519 frm_nxt += 3;
2520 }
2521 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2522 {
2523 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2524 if (c1 < 0x80)
2525 {
2526 if (c1 > Maxcode)
2527 return codecvt_base::error;
2528 *to_nxt = static_cast<uint16_t>(c1);
2529 ++frm_nxt;
2530 }
2531 else if (c1 < 0xC2)
2532 {
2533 return codecvt_base::error;
2534 }
2535 else if (c1 < 0xE0)
2536 {
2537 if (frm_end-frm_nxt < 2)
2538 return codecvt_base::partial;
2539 uint8_t c2 = frm_nxt[1];
2540 if ((c2 & 0xC0) != 0x80)
2541 return codecvt_base::error;
2542 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2543 | (c2 & 0x3F));
2544 if (t > Maxcode)
2545 return codecvt_base::error;
2546 *to_nxt = t;
2547 frm_nxt += 2;
2548 }
2549 else if (c1 < 0xF0)
2550 {
2551 if (frm_end-frm_nxt < 3)
2552 return codecvt_base::partial;
2553 uint8_t c2 = frm_nxt[1];
2554 uint8_t c3 = frm_nxt[2];
2555 switch (c1)
2556 {
2557 case 0xE0:
2558 if ((c2 & 0xE0) != 0xA0)
2559 return codecvt_base::error;
2560 break;
2561 case 0xED:
2562 if ((c2 & 0xE0) != 0x80)
2563 return codecvt_base::error;
2564 break;
2565 default:
2566 if ((c2 & 0xC0) != 0x80)
2567 return codecvt_base::error;
2568 break;
2569 }
2570 if ((c3 & 0xC0) != 0x80)
2571 return codecvt_base::error;
2572 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2573 | ((c2 & 0x3F) << 6)
2574 | (c3 & 0x3F));
2575 if (t > Maxcode)
2576 return codecvt_base::error;
2577 *to_nxt = t;
2578 frm_nxt += 3;
2579 }
2580 else
2581 {
2582 return codecvt_base::error;
2583 }
2584 }
2585 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2586 }
2587
2588 static
2589 int
utf8_to_ucs2_length(const uint8_t * frm,const uint8_t * frm_end,size_t mx,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2590 utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2591 size_t mx, unsigned long Maxcode = 0x10FFFF,
2592 codecvt_mode mode = codecvt_mode(0))
2593 {
2594 const uint8_t* frm_nxt = frm;
2595 if (mode & consume_header)
2596 {
2597 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2598 frm_nxt[2] == 0xBF)
2599 frm_nxt += 3;
2600 }
2601 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2602 {
2603 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2604 if (c1 < 0x80)
2605 {
2606 if (c1 > Maxcode)
2607 break;
2608 ++frm_nxt;
2609 }
2610 else if (c1 < 0xC2)
2611 {
2612 break;
2613 }
2614 else if (c1 < 0xE0)
2615 {
2616 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2617 break;
2618 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2619 break;
2620 frm_nxt += 2;
2621 }
2622 else if (c1 < 0xF0)
2623 {
2624 if (frm_end-frm_nxt < 3)
2625 break;
2626 uint8_t c2 = frm_nxt[1];
2627 uint8_t c3 = frm_nxt[2];
2628 switch (c1)
2629 {
2630 case 0xE0:
2631 if ((c2 & 0xE0) != 0xA0)
2632 return static_cast<int>(frm_nxt - frm);
2633 break;
2634 case 0xED:
2635 if ((c2 & 0xE0) != 0x80)
2636 return static_cast<int>(frm_nxt - frm);
2637 break;
2638 default:
2639 if ((c2 & 0xC0) != 0x80)
2640 return static_cast<int>(frm_nxt - frm);
2641 break;
2642 }
2643 if ((c3 & 0xC0) != 0x80)
2644 break;
2645 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2646 break;
2647 frm_nxt += 3;
2648 }
2649 else
2650 {
2651 break;
2652 }
2653 }
2654 return static_cast<int>(frm_nxt - frm);
2655 }
2656
2657 static
2658 codecvt_base::result
ucs4_to_utf16be(const uint32_t * frm,const uint32_t * frm_end,const uint32_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2659 ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2660 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2661 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2662 {
2663 frm_nxt = frm;
2664 to_nxt = to;
2665 if (mode & generate_header)
2666 {
2667 if (to_end-to_nxt < 2)
2668 return codecvt_base::partial;
2669 *to_nxt++ = static_cast<uint8_t>(0xFE);
2670 *to_nxt++ = static_cast<uint8_t>(0xFF);
2671 }
2672 for (; frm_nxt < frm_end; ++frm_nxt)
2673 {
2674 uint32_t wc = *frm_nxt;
2675 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2676 return codecvt_base::error;
2677 if (wc < 0x010000)
2678 {
2679 if (to_end-to_nxt < 2)
2680 return codecvt_base::partial;
2681 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2682 *to_nxt++ = static_cast<uint8_t>(wc);
2683 }
2684 else
2685 {
2686 if (to_end-to_nxt < 4)
2687 return codecvt_base::partial;
2688 uint16_t t = static_cast<uint16_t>(
2689 0xD800
2690 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2691 | ((wc & 0x00FC00) >> 10));
2692 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2693 *to_nxt++ = static_cast<uint8_t>(t);
2694 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2695 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2696 *to_nxt++ = static_cast<uint8_t>(t);
2697 }
2698 }
2699 return codecvt_base::ok;
2700 }
2701
2702 static
2703 codecvt_base::result
utf16be_to_ucs4(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint32_t * to,uint32_t * to_end,uint32_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2704 utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2705 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2706 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2707 {
2708 frm_nxt = frm;
2709 to_nxt = to;
2710 if (mode & consume_header)
2711 {
2712 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2713 frm_nxt += 2;
2714 }
2715 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2716 {
2717 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2718 if ((c1 & 0xFC00) == 0xDC00)
2719 return codecvt_base::error;
2720 if ((c1 & 0xFC00) != 0xD800)
2721 {
2722 if (c1 > Maxcode)
2723 return codecvt_base::error;
2724 *to_nxt = static_cast<uint32_t>(c1);
2725 frm_nxt += 2;
2726 }
2727 else
2728 {
2729 if (frm_end-frm_nxt < 4)
2730 return codecvt_base::partial;
2731 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2732 if ((c2 & 0xFC00) != 0xDC00)
2733 return codecvt_base::error;
2734 uint32_t t = static_cast<uint32_t>(
2735 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2736 | ((c1 & 0x003F) << 10)
2737 | (c2 & 0x03FF));
2738 if (t > Maxcode)
2739 return codecvt_base::error;
2740 *to_nxt = t;
2741 frm_nxt += 4;
2742 }
2743 }
2744 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2745 }
2746
2747 static
2748 int
utf16be_to_ucs4_length(const uint8_t * frm,const uint8_t * frm_end,size_t mx,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2749 utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2750 size_t mx, unsigned long Maxcode = 0x10FFFF,
2751 codecvt_mode mode = codecvt_mode(0))
2752 {
2753 const uint8_t* frm_nxt = frm;
2754 if (mode & consume_header)
2755 {
2756 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2757 frm_nxt += 2;
2758 }
2759 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2760 {
2761 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2762 if ((c1 & 0xFC00) == 0xDC00)
2763 break;
2764 if ((c1 & 0xFC00) != 0xD800)
2765 {
2766 if (c1 > Maxcode)
2767 break;
2768 frm_nxt += 2;
2769 }
2770 else
2771 {
2772 if (frm_end-frm_nxt < 4)
2773 break;
2774 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2775 if ((c2 & 0xFC00) != 0xDC00)
2776 break;
2777 uint32_t t = static_cast<uint32_t>(
2778 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2779 | ((c1 & 0x003F) << 10)
2780 | (c2 & 0x03FF));
2781 if (t > Maxcode)
2782 break;
2783 frm_nxt += 4;
2784 }
2785 }
2786 return static_cast<int>(frm_nxt - frm);
2787 }
2788
2789 static
2790 codecvt_base::result
ucs4_to_utf16le(const uint32_t * frm,const uint32_t * frm_end,const uint32_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2791 ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2792 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2793 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2794 {
2795 frm_nxt = frm;
2796 to_nxt = to;
2797 if (mode & generate_header)
2798 {
2799 if (to_end-to_nxt < 2)
2800 return codecvt_base::partial;
2801 *to_nxt++ = static_cast<uint8_t>(0xFF);
2802 *to_nxt++ = static_cast<uint8_t>(0xFE);
2803 }
2804 for (; frm_nxt < frm_end; ++frm_nxt)
2805 {
2806 uint32_t wc = *frm_nxt;
2807 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2808 return codecvt_base::error;
2809 if (wc < 0x010000)
2810 {
2811 if (to_end-to_nxt < 2)
2812 return codecvt_base::partial;
2813 *to_nxt++ = static_cast<uint8_t>(wc);
2814 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2815 }
2816 else
2817 {
2818 if (to_end-to_nxt < 4)
2819 return codecvt_base::partial;
2820 uint16_t t = static_cast<uint16_t>(
2821 0xD800
2822 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2823 | ((wc & 0x00FC00) >> 10));
2824 *to_nxt++ = static_cast<uint8_t>(t);
2825 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2826 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2827 *to_nxt++ = static_cast<uint8_t>(t);
2828 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2829 }
2830 }
2831 return codecvt_base::ok;
2832 }
2833
2834 static
2835 codecvt_base::result
utf16le_to_ucs4(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint32_t * to,uint32_t * to_end,uint32_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2836 utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2837 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2838 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2839 {
2840 frm_nxt = frm;
2841 to_nxt = to;
2842 if (mode & consume_header)
2843 {
2844 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2845 frm_nxt += 2;
2846 }
2847 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2848 {
2849 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2850 if ((c1 & 0xFC00) == 0xDC00)
2851 return codecvt_base::error;
2852 if ((c1 & 0xFC00) != 0xD800)
2853 {
2854 if (c1 > Maxcode)
2855 return codecvt_base::error;
2856 *to_nxt = static_cast<uint32_t>(c1);
2857 frm_nxt += 2;
2858 }
2859 else
2860 {
2861 if (frm_end-frm_nxt < 4)
2862 return codecvt_base::partial;
2863 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2864 if ((c2 & 0xFC00) != 0xDC00)
2865 return codecvt_base::error;
2866 uint32_t t = static_cast<uint32_t>(
2867 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2868 | ((c1 & 0x003F) << 10)
2869 | (c2 & 0x03FF));
2870 if (t > Maxcode)
2871 return codecvt_base::error;
2872 *to_nxt = t;
2873 frm_nxt += 4;
2874 }
2875 }
2876 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2877 }
2878
2879 static
2880 int
utf16le_to_ucs4_length(const uint8_t * frm,const uint8_t * frm_end,size_t mx,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2881 utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2882 size_t mx, unsigned long Maxcode = 0x10FFFF,
2883 codecvt_mode mode = codecvt_mode(0))
2884 {
2885 const uint8_t* frm_nxt = frm;
2886 if (mode & consume_header)
2887 {
2888 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2889 frm_nxt += 2;
2890 }
2891 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2892 {
2893 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2894 if ((c1 & 0xFC00) == 0xDC00)
2895 break;
2896 if ((c1 & 0xFC00) != 0xD800)
2897 {
2898 if (c1 > Maxcode)
2899 break;
2900 frm_nxt += 2;
2901 }
2902 else
2903 {
2904 if (frm_end-frm_nxt < 4)
2905 break;
2906 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2907 if ((c2 & 0xFC00) != 0xDC00)
2908 break;
2909 uint32_t t = static_cast<uint32_t>(
2910 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2911 | ((c1 & 0x003F) << 10)
2912 | (c2 & 0x03FF));
2913 if (t > Maxcode)
2914 break;
2915 frm_nxt += 4;
2916 }
2917 }
2918 return static_cast<int>(frm_nxt - frm);
2919 }
2920
2921 static
2922 codecvt_base::result
ucs2_to_utf16be(const uint16_t * frm,const uint16_t * frm_end,const uint16_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2923 ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2924 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2925 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2926 {
2927 frm_nxt = frm;
2928 to_nxt = to;
2929 if (mode & generate_header)
2930 {
2931 if (to_end-to_nxt < 2)
2932 return codecvt_base::partial;
2933 *to_nxt++ = static_cast<uint8_t>(0xFE);
2934 *to_nxt++ = static_cast<uint8_t>(0xFF);
2935 }
2936 for (; frm_nxt < frm_end; ++frm_nxt)
2937 {
2938 uint16_t wc = *frm_nxt;
2939 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2940 return codecvt_base::error;
2941 if (to_end-to_nxt < 2)
2942 return codecvt_base::partial;
2943 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2944 *to_nxt++ = static_cast<uint8_t>(wc);
2945 }
2946 return codecvt_base::ok;
2947 }
2948
2949 static
2950 codecvt_base::result
utf16be_to_ucs2(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint16_t * to,uint16_t * to_end,uint16_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2951 utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2952 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2953 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2954 {
2955 frm_nxt = frm;
2956 to_nxt = to;
2957 if (mode & consume_header)
2958 {
2959 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2960 frm_nxt += 2;
2961 }
2962 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2963 {
2964 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2965 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2966 return codecvt_base::error;
2967 *to_nxt = c1;
2968 frm_nxt += 2;
2969 }
2970 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2971 }
2972
2973 static
2974 int
utf16be_to_ucs2_length(const uint8_t * frm,const uint8_t * frm_end,size_t mx,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2975 utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2976 size_t mx, unsigned long Maxcode = 0x10FFFF,
2977 codecvt_mode mode = codecvt_mode(0))
2978 {
2979 const uint8_t* frm_nxt = frm;
2980 if (mode & consume_header)
2981 {
2982 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2983 frm_nxt += 2;
2984 }
2985 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
2986 {
2987 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2988 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2989 break;
2990 frm_nxt += 2;
2991 }
2992 return static_cast<int>(frm_nxt - frm);
2993 }
2994
2995 static
2996 codecvt_base::result
ucs2_to_utf16le(const uint16_t * frm,const uint16_t * frm_end,const uint16_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))2997 ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2998 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2999 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3000 {
3001 frm_nxt = frm;
3002 to_nxt = to;
3003 if (mode & generate_header)
3004 {
3005 if (to_end-to_nxt < 2)
3006 return codecvt_base::partial;
3007 *to_nxt++ = static_cast<uint8_t>(0xFF);
3008 *to_nxt++ = static_cast<uint8_t>(0xFE);
3009 }
3010 for (; frm_nxt < frm_end; ++frm_nxt)
3011 {
3012 uint16_t wc = *frm_nxt;
3013 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3014 return codecvt_base::error;
3015 if (to_end-to_nxt < 2)
3016 return codecvt_base::partial;
3017 *to_nxt++ = static_cast<uint8_t>(wc);
3018 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3019 }
3020 return codecvt_base::ok;
3021 }
3022
3023 static
3024 codecvt_base::result
utf16le_to_ucs2(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint16_t * to,uint16_t * to_end,uint16_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))3025 utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3026 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3027 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3028 {
3029 frm_nxt = frm;
3030 to_nxt = to;
3031 if (mode & consume_header)
3032 {
3033 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3034 frm_nxt += 2;
3035 }
3036 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3037 {
3038 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3039 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3040 return codecvt_base::error;
3041 *to_nxt = c1;
3042 frm_nxt += 2;
3043 }
3044 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3045 }
3046
3047 static
3048 int
utf16le_to_ucs2_length(const uint8_t * frm,const uint8_t * frm_end,size_t mx,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))3049 utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3050 size_t mx, unsigned long Maxcode = 0x10FFFF,
3051 codecvt_mode mode = codecvt_mode(0))
3052 {
3053 const uint8_t* frm_nxt = frm;
3054 frm_nxt = frm;
3055 if (mode & consume_header)
3056 {
3057 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3058 frm_nxt += 2;
3059 }
3060 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3061 {
3062 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3063 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3064 break;
3065 frm_nxt += 2;
3066 }
3067 return static_cast<int>(frm_nxt - frm);
3068 }
3069
3070 // template <> class codecvt<char16_t, char, mbstate_t>
3071
3072 locale::id codecvt<char16_t, char, mbstate_t>::id;
3073
~codecvt()3074 codecvt<char16_t, char, mbstate_t>::~codecvt()
3075 {
3076 }
3077
3078 codecvt<char16_t, char, mbstate_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const3079 codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
3080 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3081 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3082 {
3083 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3084 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3085 const uint16_t* _frm_nxt = _frm;
3086 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3087 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3088 uint8_t* _to_nxt = _to;
3089 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3090 frm_nxt = frm + (_frm_nxt - _frm);
3091 to_nxt = to + (_to_nxt - _to);
3092 return r;
3093 }
3094
3095 codecvt<char16_t, char, mbstate_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const3096 codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
3097 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3098 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3099 {
3100 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3101 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3102 const uint8_t* _frm_nxt = _frm;
3103 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3104 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3105 uint16_t* _to_nxt = _to;
3106 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3107 frm_nxt = frm + (_frm_nxt - _frm);
3108 to_nxt = to + (_to_nxt - _to);
3109 return r;
3110 }
3111
3112 codecvt<char16_t, char, mbstate_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const3113 codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
3114 extern_type* to, extern_type*, extern_type*& to_nxt) const
3115 {
3116 to_nxt = to;
3117 return noconv;
3118 }
3119
3120 int
do_encoding() const3121 codecvt<char16_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
3122 {
3123 return 0;
3124 }
3125
3126 bool
do_always_noconv() const3127 codecvt<char16_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
3128 {
3129 return false;
3130 }
3131
3132 int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const3133 codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
3134 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3135 {
3136 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3137 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3138 return utf8_to_utf16_length(_frm, _frm_end, mx);
3139 }
3140
3141 int
do_max_length() const3142 codecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
3143 {
3144 return 4;
3145 }
3146
3147 // template <> class codecvt<char32_t, char, mbstate_t>
3148
3149 locale::id codecvt<char32_t, char, mbstate_t>::id;
3150
~codecvt()3151 codecvt<char32_t, char, mbstate_t>::~codecvt()
3152 {
3153 }
3154
3155 codecvt<char32_t, char, mbstate_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const3156 codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
3157 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3158 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3159 {
3160 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3161 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3162 const uint32_t* _frm_nxt = _frm;
3163 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3164 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3165 uint8_t* _to_nxt = _to;
3166 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3167 frm_nxt = frm + (_frm_nxt - _frm);
3168 to_nxt = to + (_to_nxt - _to);
3169 return r;
3170 }
3171
3172 codecvt<char32_t, char, mbstate_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const3173 codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
3174 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3175 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3176 {
3177 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3178 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3179 const uint8_t* _frm_nxt = _frm;
3180 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3181 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3182 uint32_t* _to_nxt = _to;
3183 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3184 frm_nxt = frm + (_frm_nxt - _frm);
3185 to_nxt = to + (_to_nxt - _to);
3186 return r;
3187 }
3188
3189 codecvt<char32_t, char, mbstate_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const3190 codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3191 extern_type* to, extern_type*, extern_type*& to_nxt) const
3192 {
3193 to_nxt = to;
3194 return noconv;
3195 }
3196
3197 int
do_encoding() const3198 codecvt<char32_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
3199 {
3200 return 0;
3201 }
3202
3203 bool
do_always_noconv() const3204 codecvt<char32_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
3205 {
3206 return false;
3207 }
3208
3209 int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const3210 codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3211 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3212 {
3213 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3214 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3215 return utf8_to_ucs4_length(_frm, _frm_end, mx);
3216 }
3217
3218 int
do_max_length() const3219 codecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
3220 {
3221 return 4;
3222 }
3223
3224 // __codecvt_utf8<wchar_t>
3225
3226 __codecvt_utf8<wchar_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const3227 __codecvt_utf8<wchar_t>::do_out(state_type&,
3228 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3229 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3230 {
3231 #if _WIN32
3232 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3233 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3234 const uint16_t* _frm_nxt = _frm;
3235 #else
3236 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3237 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3238 const uint32_t* _frm_nxt = _frm;
3239 #endif
3240 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3241 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3242 uint8_t* _to_nxt = _to;
3243 #if _WIN32
3244 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3245 _Maxcode_, _Mode_);
3246 #else
3247 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3248 _Maxcode_, _Mode_);
3249 #endif
3250 frm_nxt = frm + (_frm_nxt - _frm);
3251 to_nxt = to + (_to_nxt - _to);
3252 return r;
3253 }
3254
3255 __codecvt_utf8<wchar_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const3256 __codecvt_utf8<wchar_t>::do_in(state_type&,
3257 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3258 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3259 {
3260 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3261 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3262 const uint8_t* _frm_nxt = _frm;
3263 #if _WIN32
3264 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3265 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3266 uint16_t* _to_nxt = _to;
3267 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3268 _Maxcode_, _Mode_);
3269 #else
3270 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3271 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3272 uint32_t* _to_nxt = _to;
3273 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3274 _Maxcode_, _Mode_);
3275 #endif
3276 frm_nxt = frm + (_frm_nxt - _frm);
3277 to_nxt = to + (_to_nxt - _to);
3278 return r;
3279 }
3280
3281 __codecvt_utf8<wchar_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const3282 __codecvt_utf8<wchar_t>::do_unshift(state_type&,
3283 extern_type* to, extern_type*, extern_type*& to_nxt) const
3284 {
3285 to_nxt = to;
3286 return noconv;
3287 }
3288
3289 int
do_encoding() const3290 __codecvt_utf8<wchar_t>::do_encoding() const _NOEXCEPT
3291 {
3292 return 0;
3293 }
3294
3295 bool
do_always_noconv() const3296 __codecvt_utf8<wchar_t>::do_always_noconv() const _NOEXCEPT
3297 {
3298 return false;
3299 }
3300
3301 int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const3302 __codecvt_utf8<wchar_t>::do_length(state_type&,
3303 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3304 {
3305 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3306 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3307 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3308 }
3309
3310 int
do_max_length() const3311 __codecvt_utf8<wchar_t>::do_max_length() const _NOEXCEPT
3312 {
3313 if (_Mode_ & consume_header)
3314 return 7;
3315 return 4;
3316 }
3317
3318 // __codecvt_utf8<char16_t>
3319
3320 __codecvt_utf8<char16_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const3321 __codecvt_utf8<char16_t>::do_out(state_type&,
3322 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3323 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3324 {
3325 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3326 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3327 const uint16_t* _frm_nxt = _frm;
3328 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3329 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3330 uint8_t* _to_nxt = _to;
3331 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3332 _Maxcode_, _Mode_);
3333 frm_nxt = frm + (_frm_nxt - _frm);
3334 to_nxt = to + (_to_nxt - _to);
3335 return r;
3336 }
3337
3338 __codecvt_utf8<char16_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const3339 __codecvt_utf8<char16_t>::do_in(state_type&,
3340 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3341 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3342 {
3343 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3344 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3345 const uint8_t* _frm_nxt = _frm;
3346 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3347 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3348 uint16_t* _to_nxt = _to;
3349 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3350 _Maxcode_, _Mode_);
3351 frm_nxt = frm + (_frm_nxt - _frm);
3352 to_nxt = to + (_to_nxt - _to);
3353 return r;
3354 }
3355
3356 __codecvt_utf8<char16_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const3357 __codecvt_utf8<char16_t>::do_unshift(state_type&,
3358 extern_type* to, extern_type*, extern_type*& to_nxt) const
3359 {
3360 to_nxt = to;
3361 return noconv;
3362 }
3363
3364 int
do_encoding() const3365 __codecvt_utf8<char16_t>::do_encoding() const _NOEXCEPT
3366 {
3367 return 0;
3368 }
3369
3370 bool
do_always_noconv() const3371 __codecvt_utf8<char16_t>::do_always_noconv() const _NOEXCEPT
3372 {
3373 return false;
3374 }
3375
3376 int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const3377 __codecvt_utf8<char16_t>::do_length(state_type&,
3378 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3379 {
3380 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3381 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3382 return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3383 }
3384
3385 int
do_max_length() const3386 __codecvt_utf8<char16_t>::do_max_length() const _NOEXCEPT
3387 {
3388 if (_Mode_ & consume_header)
3389 return 6;
3390 return 3;
3391 }
3392
3393 // __codecvt_utf8<char32_t>
3394
3395 __codecvt_utf8<char32_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const3396 __codecvt_utf8<char32_t>::do_out(state_type&,
3397 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3398 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3399 {
3400 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3401 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3402 const uint32_t* _frm_nxt = _frm;
3403 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3404 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3405 uint8_t* _to_nxt = _to;
3406 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3407 _Maxcode_, _Mode_);
3408 frm_nxt = frm + (_frm_nxt - _frm);
3409 to_nxt = to + (_to_nxt - _to);
3410 return r;
3411 }
3412
3413 __codecvt_utf8<char32_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const3414 __codecvt_utf8<char32_t>::do_in(state_type&,
3415 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3416 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3417 {
3418 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3419 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3420 const uint8_t* _frm_nxt = _frm;
3421 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3422 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3423 uint32_t* _to_nxt = _to;
3424 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3425 _Maxcode_, _Mode_);
3426 frm_nxt = frm + (_frm_nxt - _frm);
3427 to_nxt = to + (_to_nxt - _to);
3428 return r;
3429 }
3430
3431 __codecvt_utf8<char32_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const3432 __codecvt_utf8<char32_t>::do_unshift(state_type&,
3433 extern_type* to, extern_type*, extern_type*& to_nxt) const
3434 {
3435 to_nxt = to;
3436 return noconv;
3437 }
3438
3439 int
do_encoding() const3440 __codecvt_utf8<char32_t>::do_encoding() const _NOEXCEPT
3441 {
3442 return 0;
3443 }
3444
3445 bool
do_always_noconv() const3446 __codecvt_utf8<char32_t>::do_always_noconv() const _NOEXCEPT
3447 {
3448 return false;
3449 }
3450
3451 int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const3452 __codecvt_utf8<char32_t>::do_length(state_type&,
3453 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3454 {
3455 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3456 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3457 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3458 }
3459
3460 int
do_max_length() const3461 __codecvt_utf8<char32_t>::do_max_length() const _NOEXCEPT
3462 {
3463 if (_Mode_ & consume_header)
3464 return 7;
3465 return 4;
3466 }
3467
3468 // __codecvt_utf16<wchar_t, false>
3469
3470 __codecvt_utf16<wchar_t, false>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const3471 __codecvt_utf16<wchar_t, false>::do_out(state_type&,
3472 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3473 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3474 {
3475 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3476 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3477 const uint32_t* _frm_nxt = _frm;
3478 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3479 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3480 uint8_t* _to_nxt = _to;
3481 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3482 _Maxcode_, _Mode_);
3483 frm_nxt = frm + (_frm_nxt - _frm);
3484 to_nxt = to + (_to_nxt - _to);
3485 return r;
3486 }
3487
3488 __codecvt_utf16<wchar_t, false>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const3489 __codecvt_utf16<wchar_t, false>::do_in(state_type&,
3490 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3491 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3492 {
3493 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3494 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3495 const uint8_t* _frm_nxt = _frm;
3496 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3497 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3498 uint32_t* _to_nxt = _to;
3499 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3500 _Maxcode_, _Mode_);
3501 frm_nxt = frm + (_frm_nxt - _frm);
3502 to_nxt = to + (_to_nxt - _to);
3503 return r;
3504 }
3505
3506 __codecvt_utf16<wchar_t, false>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const3507 __codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3508 extern_type* to, extern_type*, extern_type*& to_nxt) const
3509 {
3510 to_nxt = to;
3511 return noconv;
3512 }
3513
3514 int
do_encoding() const3515 __codecvt_utf16<wchar_t, false>::do_encoding() const _NOEXCEPT
3516 {
3517 return 0;
3518 }
3519
3520 bool
do_always_noconv() const3521 __codecvt_utf16<wchar_t, false>::do_always_noconv() const _NOEXCEPT
3522 {
3523 return false;
3524 }
3525
3526 int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const3527 __codecvt_utf16<wchar_t, false>::do_length(state_type&,
3528 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3529 {
3530 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3531 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3532 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3533 }
3534
3535 int
do_max_length() const3536 __codecvt_utf16<wchar_t, false>::do_max_length() const _NOEXCEPT
3537 {
3538 if (_Mode_ & consume_header)
3539 return 6;
3540 return 4;
3541 }
3542
3543 // __codecvt_utf16<wchar_t, true>
3544
3545 __codecvt_utf16<wchar_t, true>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const3546 __codecvt_utf16<wchar_t, true>::do_out(state_type&,
3547 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3548 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3549 {
3550 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3551 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3552 const uint32_t* _frm_nxt = _frm;
3553 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3554 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3555 uint8_t* _to_nxt = _to;
3556 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3557 _Maxcode_, _Mode_);
3558 frm_nxt = frm + (_frm_nxt - _frm);
3559 to_nxt = to + (_to_nxt - _to);
3560 return r;
3561 }
3562
3563 __codecvt_utf16<wchar_t, true>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const3564 __codecvt_utf16<wchar_t, true>::do_in(state_type&,
3565 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3566 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3567 {
3568 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3569 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3570 const uint8_t* _frm_nxt = _frm;
3571 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3572 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3573 uint32_t* _to_nxt = _to;
3574 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3575 _Maxcode_, _Mode_);
3576 frm_nxt = frm + (_frm_nxt - _frm);
3577 to_nxt = to + (_to_nxt - _to);
3578 return r;
3579 }
3580
3581 __codecvt_utf16<wchar_t, true>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const3582 __codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3583 extern_type* to, extern_type*, extern_type*& to_nxt) const
3584 {
3585 to_nxt = to;
3586 return noconv;
3587 }
3588
3589 int
do_encoding() const3590 __codecvt_utf16<wchar_t, true>::do_encoding() const _NOEXCEPT
3591 {
3592 return 0;
3593 }
3594
3595 bool
do_always_noconv() const3596 __codecvt_utf16<wchar_t, true>::do_always_noconv() const _NOEXCEPT
3597 {
3598 return false;
3599 }
3600
3601 int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const3602 __codecvt_utf16<wchar_t, true>::do_length(state_type&,
3603 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3604 {
3605 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3606 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3607 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3608 }
3609
3610 int
do_max_length() const3611 __codecvt_utf16<wchar_t, true>::do_max_length() const _NOEXCEPT
3612 {
3613 if (_Mode_ & consume_header)
3614 return 6;
3615 return 4;
3616 }
3617
3618 // __codecvt_utf16<char16_t, false>
3619
3620 __codecvt_utf16<char16_t, false>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const3621 __codecvt_utf16<char16_t, false>::do_out(state_type&,
3622 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3623 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3624 {
3625 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3626 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3627 const uint16_t* _frm_nxt = _frm;
3628 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3629 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3630 uint8_t* _to_nxt = _to;
3631 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3632 _Maxcode_, _Mode_);
3633 frm_nxt = frm + (_frm_nxt - _frm);
3634 to_nxt = to + (_to_nxt - _to);
3635 return r;
3636 }
3637
3638 __codecvt_utf16<char16_t, false>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const3639 __codecvt_utf16<char16_t, false>::do_in(state_type&,
3640 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3641 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3642 {
3643 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3644 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3645 const uint8_t* _frm_nxt = _frm;
3646 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3647 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3648 uint16_t* _to_nxt = _to;
3649 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3650 _Maxcode_, _Mode_);
3651 frm_nxt = frm + (_frm_nxt - _frm);
3652 to_nxt = to + (_to_nxt - _to);
3653 return r;
3654 }
3655
3656 __codecvt_utf16<char16_t, false>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const3657 __codecvt_utf16<char16_t, false>::do_unshift(state_type&,
3658 extern_type* to, extern_type*, extern_type*& to_nxt) const
3659 {
3660 to_nxt = to;
3661 return noconv;
3662 }
3663
3664 int
do_encoding() const3665 __codecvt_utf16<char16_t, false>::do_encoding() const _NOEXCEPT
3666 {
3667 return 0;
3668 }
3669
3670 bool
do_always_noconv() const3671 __codecvt_utf16<char16_t, false>::do_always_noconv() const _NOEXCEPT
3672 {
3673 return false;
3674 }
3675
3676 int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const3677 __codecvt_utf16<char16_t, false>::do_length(state_type&,
3678 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3679 {
3680 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3681 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3682 return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3683 }
3684
3685 int
do_max_length() const3686 __codecvt_utf16<char16_t, false>::do_max_length() const _NOEXCEPT
3687 {
3688 if (_Mode_ & consume_header)
3689 return 4;
3690 return 2;
3691 }
3692
3693 // __codecvt_utf16<char16_t, true>
3694
3695 __codecvt_utf16<char16_t, true>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const3696 __codecvt_utf16<char16_t, true>::do_out(state_type&,
3697 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3698 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3699 {
3700 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3701 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3702 const uint16_t* _frm_nxt = _frm;
3703 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3704 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3705 uint8_t* _to_nxt = _to;
3706 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3707 _Maxcode_, _Mode_);
3708 frm_nxt = frm + (_frm_nxt - _frm);
3709 to_nxt = to + (_to_nxt - _to);
3710 return r;
3711 }
3712
3713 __codecvt_utf16<char16_t, true>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const3714 __codecvt_utf16<char16_t, true>::do_in(state_type&,
3715 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3716 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3717 {
3718 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3719 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3720 const uint8_t* _frm_nxt = _frm;
3721 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3722 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3723 uint16_t* _to_nxt = _to;
3724 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3725 _Maxcode_, _Mode_);
3726 frm_nxt = frm + (_frm_nxt - _frm);
3727 to_nxt = to + (_to_nxt - _to);
3728 return r;
3729 }
3730
3731 __codecvt_utf16<char16_t, true>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const3732 __codecvt_utf16<char16_t, true>::do_unshift(state_type&,
3733 extern_type* to, extern_type*, extern_type*& to_nxt) const
3734 {
3735 to_nxt = to;
3736 return noconv;
3737 }
3738
3739 int
do_encoding() const3740 __codecvt_utf16<char16_t, true>::do_encoding() const _NOEXCEPT
3741 {
3742 return 0;
3743 }
3744
3745 bool
do_always_noconv() const3746 __codecvt_utf16<char16_t, true>::do_always_noconv() const _NOEXCEPT
3747 {
3748 return false;
3749 }
3750
3751 int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const3752 __codecvt_utf16<char16_t, true>::do_length(state_type&,
3753 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3754 {
3755 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3756 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3757 return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3758 }
3759
3760 int
do_max_length() const3761 __codecvt_utf16<char16_t, true>::do_max_length() const _NOEXCEPT
3762 {
3763 if (_Mode_ & consume_header)
3764 return 4;
3765 return 2;
3766 }
3767
3768 // __codecvt_utf16<char32_t, false>
3769
3770 __codecvt_utf16<char32_t, false>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const3771 __codecvt_utf16<char32_t, false>::do_out(state_type&,
3772 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3773 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3774 {
3775 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3776 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3777 const uint32_t* _frm_nxt = _frm;
3778 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3779 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3780 uint8_t* _to_nxt = _to;
3781 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3782 _Maxcode_, _Mode_);
3783 frm_nxt = frm + (_frm_nxt - _frm);
3784 to_nxt = to + (_to_nxt - _to);
3785 return r;
3786 }
3787
3788 __codecvt_utf16<char32_t, false>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const3789 __codecvt_utf16<char32_t, false>::do_in(state_type&,
3790 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3791 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3792 {
3793 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3794 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3795 const uint8_t* _frm_nxt = _frm;
3796 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3797 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3798 uint32_t* _to_nxt = _to;
3799 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3800 _Maxcode_, _Mode_);
3801 frm_nxt = frm + (_frm_nxt - _frm);
3802 to_nxt = to + (_to_nxt - _to);
3803 return r;
3804 }
3805
3806 __codecvt_utf16<char32_t, false>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const3807 __codecvt_utf16<char32_t, false>::do_unshift(state_type&,
3808 extern_type* to, extern_type*, extern_type*& to_nxt) const
3809 {
3810 to_nxt = to;
3811 return noconv;
3812 }
3813
3814 int
do_encoding() const3815 __codecvt_utf16<char32_t, false>::do_encoding() const _NOEXCEPT
3816 {
3817 return 0;
3818 }
3819
3820 bool
do_always_noconv() const3821 __codecvt_utf16<char32_t, false>::do_always_noconv() const _NOEXCEPT
3822 {
3823 return false;
3824 }
3825
3826 int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const3827 __codecvt_utf16<char32_t, false>::do_length(state_type&,
3828 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3829 {
3830 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3831 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3832 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3833 }
3834
3835 int
do_max_length() const3836 __codecvt_utf16<char32_t, false>::do_max_length() const _NOEXCEPT
3837 {
3838 if (_Mode_ & consume_header)
3839 return 6;
3840 return 4;
3841 }
3842
3843 // __codecvt_utf16<char32_t, true>
3844
3845 __codecvt_utf16<char32_t, true>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const3846 __codecvt_utf16<char32_t, true>::do_out(state_type&,
3847 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3848 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3849 {
3850 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3851 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3852 const uint32_t* _frm_nxt = _frm;
3853 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3854 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3855 uint8_t* _to_nxt = _to;
3856 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3857 _Maxcode_, _Mode_);
3858 frm_nxt = frm + (_frm_nxt - _frm);
3859 to_nxt = to + (_to_nxt - _to);
3860 return r;
3861 }
3862
3863 __codecvt_utf16<char32_t, true>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const3864 __codecvt_utf16<char32_t, true>::do_in(state_type&,
3865 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3866 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3867 {
3868 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3869 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3870 const uint8_t* _frm_nxt = _frm;
3871 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3872 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3873 uint32_t* _to_nxt = _to;
3874 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3875 _Maxcode_, _Mode_);
3876 frm_nxt = frm + (_frm_nxt - _frm);
3877 to_nxt = to + (_to_nxt - _to);
3878 return r;
3879 }
3880
3881 __codecvt_utf16<char32_t, true>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const3882 __codecvt_utf16<char32_t, true>::do_unshift(state_type&,
3883 extern_type* to, extern_type*, extern_type*& to_nxt) const
3884 {
3885 to_nxt = to;
3886 return noconv;
3887 }
3888
3889 int
do_encoding() const3890 __codecvt_utf16<char32_t, true>::do_encoding() const _NOEXCEPT
3891 {
3892 return 0;
3893 }
3894
3895 bool
do_always_noconv() const3896 __codecvt_utf16<char32_t, true>::do_always_noconv() const _NOEXCEPT
3897 {
3898 return false;
3899 }
3900
3901 int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const3902 __codecvt_utf16<char32_t, true>::do_length(state_type&,
3903 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3904 {
3905 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3906 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3907 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3908 }
3909
3910 int
do_max_length() const3911 __codecvt_utf16<char32_t, true>::do_max_length() const _NOEXCEPT
3912 {
3913 if (_Mode_ & consume_header)
3914 return 6;
3915 return 4;
3916 }
3917
3918 // __codecvt_utf8_utf16<wchar_t>
3919
3920 __codecvt_utf8_utf16<wchar_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const3921 __codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
3922 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3923 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3924 {
3925 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3926 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3927 const uint32_t* _frm_nxt = _frm;
3928 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3929 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3930 uint8_t* _to_nxt = _to;
3931 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3932 _Maxcode_, _Mode_);
3933 frm_nxt = frm + (_frm_nxt - _frm);
3934 to_nxt = to + (_to_nxt - _to);
3935 return r;
3936 }
3937
3938 __codecvt_utf8_utf16<wchar_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const3939 __codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
3940 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3941 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3942 {
3943 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3944 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3945 const uint8_t* _frm_nxt = _frm;
3946 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3947 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3948 uint32_t* _to_nxt = _to;
3949 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3950 _Maxcode_, _Mode_);
3951 frm_nxt = frm + (_frm_nxt - _frm);
3952 to_nxt = to + (_to_nxt - _to);
3953 return r;
3954 }
3955
3956 __codecvt_utf8_utf16<wchar_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const3957 __codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
3958 extern_type* to, extern_type*, extern_type*& to_nxt) const
3959 {
3960 to_nxt = to;
3961 return noconv;
3962 }
3963
3964 int
do_encoding() const3965 __codecvt_utf8_utf16<wchar_t>::do_encoding() const _NOEXCEPT
3966 {
3967 return 0;
3968 }
3969
3970 bool
do_always_noconv() const3971 __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const _NOEXCEPT
3972 {
3973 return false;
3974 }
3975
3976 int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const3977 __codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
3978 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3979 {
3980 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3981 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3982 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3983 }
3984
3985 int
do_max_length() const3986 __codecvt_utf8_utf16<wchar_t>::do_max_length() const _NOEXCEPT
3987 {
3988 if (_Mode_ & consume_header)
3989 return 7;
3990 return 4;
3991 }
3992
3993 // __codecvt_utf8_utf16<char16_t>
3994
3995 __codecvt_utf8_utf16<char16_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const3996 __codecvt_utf8_utf16<char16_t>::do_out(state_type&,
3997 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3998 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3999 {
4000 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4001 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4002 const uint16_t* _frm_nxt = _frm;
4003 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4004 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4005 uint8_t* _to_nxt = _to;
4006 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4007 _Maxcode_, _Mode_);
4008 frm_nxt = frm + (_frm_nxt - _frm);
4009 to_nxt = to + (_to_nxt - _to);
4010 return r;
4011 }
4012
4013 __codecvt_utf8_utf16<char16_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const4014 __codecvt_utf8_utf16<char16_t>::do_in(state_type&,
4015 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4016 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4017 {
4018 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4019 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4020 const uint8_t* _frm_nxt = _frm;
4021 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4022 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4023 uint16_t* _to_nxt = _to;
4024 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4025 _Maxcode_, _Mode_);
4026 frm_nxt = frm + (_frm_nxt - _frm);
4027 to_nxt = to + (_to_nxt - _to);
4028 return r;
4029 }
4030
4031 __codecvt_utf8_utf16<char16_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const4032 __codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
4033 extern_type* to, extern_type*, extern_type*& to_nxt) const
4034 {
4035 to_nxt = to;
4036 return noconv;
4037 }
4038
4039 int
do_encoding() const4040 __codecvt_utf8_utf16<char16_t>::do_encoding() const _NOEXCEPT
4041 {
4042 return 0;
4043 }
4044
4045 bool
do_always_noconv() const4046 __codecvt_utf8_utf16<char16_t>::do_always_noconv() const _NOEXCEPT
4047 {
4048 return false;
4049 }
4050
4051 int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const4052 __codecvt_utf8_utf16<char16_t>::do_length(state_type&,
4053 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4054 {
4055 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4056 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4057 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4058 }
4059
4060 int
do_max_length() const4061 __codecvt_utf8_utf16<char16_t>::do_max_length() const _NOEXCEPT
4062 {
4063 if (_Mode_ & consume_header)
4064 return 7;
4065 return 4;
4066 }
4067
4068 // __codecvt_utf8_utf16<char32_t>
4069
4070 __codecvt_utf8_utf16<char32_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const4071 __codecvt_utf8_utf16<char32_t>::do_out(state_type&,
4072 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4073 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4074 {
4075 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4076 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4077 const uint32_t* _frm_nxt = _frm;
4078 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4079 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4080 uint8_t* _to_nxt = _to;
4081 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4082 _Maxcode_, _Mode_);
4083 frm_nxt = frm + (_frm_nxt - _frm);
4084 to_nxt = to + (_to_nxt - _to);
4085 return r;
4086 }
4087
4088 __codecvt_utf8_utf16<char32_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const4089 __codecvt_utf8_utf16<char32_t>::do_in(state_type&,
4090 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4091 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4092 {
4093 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4094 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4095 const uint8_t* _frm_nxt = _frm;
4096 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4097 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4098 uint32_t* _to_nxt = _to;
4099 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4100 _Maxcode_, _Mode_);
4101 frm_nxt = frm + (_frm_nxt - _frm);
4102 to_nxt = to + (_to_nxt - _to);
4103 return r;
4104 }
4105
4106 __codecvt_utf8_utf16<char32_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const4107 __codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
4108 extern_type* to, extern_type*, extern_type*& to_nxt) const
4109 {
4110 to_nxt = to;
4111 return noconv;
4112 }
4113
4114 int
do_encoding() const4115 __codecvt_utf8_utf16<char32_t>::do_encoding() const _NOEXCEPT
4116 {
4117 return 0;
4118 }
4119
4120 bool
do_always_noconv() const4121 __codecvt_utf8_utf16<char32_t>::do_always_noconv() const _NOEXCEPT
4122 {
4123 return false;
4124 }
4125
4126 int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const4127 __codecvt_utf8_utf16<char32_t>::do_length(state_type&,
4128 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4129 {
4130 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4131 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4132 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4133 }
4134
4135 int
do_max_length() const4136 __codecvt_utf8_utf16<char32_t>::do_max_length() const _NOEXCEPT
4137 {
4138 if (_Mode_ & consume_header)
4139 return 7;
4140 return 4;
4141 }
4142
4143 // __narrow_to_utf8<16>
4144
~__narrow_to_utf8()4145 __narrow_to_utf8<16>::~__narrow_to_utf8()
4146 {
4147 }
4148
4149 // __narrow_to_utf8<32>
4150
~__narrow_to_utf8()4151 __narrow_to_utf8<32>::~__narrow_to_utf8()
4152 {
4153 }
4154
4155 // __widen_from_utf8<16>
4156
~__widen_from_utf8()4157 __widen_from_utf8<16>::~__widen_from_utf8()
4158 {
4159 }
4160
4161 // __widen_from_utf8<32>
4162
~__widen_from_utf8()4163 __widen_from_utf8<32>::~__widen_from_utf8()
4164 {
4165 }
4166
4167 // numpunct<char> && numpunct<wchar_t>
4168
4169 locale::id numpunct< char >::id;
4170 locale::id numpunct<wchar_t>::id;
4171
numpunct(size_t refs)4172 numpunct<char>::numpunct(size_t refs)
4173 : locale::facet(refs),
4174 __decimal_point_('.'),
4175 __thousands_sep_(',')
4176 {
4177 }
4178
numpunct(size_t refs)4179 numpunct<wchar_t>::numpunct(size_t refs)
4180 : locale::facet(refs),
4181 __decimal_point_(L'.'),
4182 __thousands_sep_(L',')
4183 {
4184 }
4185
~numpunct()4186 numpunct<char>::~numpunct()
4187 {
4188 }
4189
~numpunct()4190 numpunct<wchar_t>::~numpunct()
4191 {
4192 }
4193
do_decimal_point() const4194 char numpunct< char >::do_decimal_point() const {return __decimal_point_;}
do_decimal_point() const4195 wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
4196
do_thousands_sep() const4197 char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;}
do_thousands_sep() const4198 wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
4199
do_grouping() const4200 string numpunct< char >::do_grouping() const {return __grouping_;}
do_grouping() const4201 string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
4202
do_truename() const4203 string numpunct< char >::do_truename() const {return "true";}
do_truename() const4204 wstring numpunct<wchar_t>::do_truename() const {return L"true";}
4205
do_falsename() const4206 string numpunct< char >::do_falsename() const {return "false";}
do_falsename() const4207 wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
4208
4209 // numpunct_byname<char>
4210
numpunct_byname(const char * nm,size_t refs)4211 numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4212 : numpunct<char>(refs)
4213 {
4214 __init(nm);
4215 }
4216
numpunct_byname(const string & nm,size_t refs)4217 numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4218 : numpunct<char>(refs)
4219 {
4220 __init(nm.c_str());
4221 }
4222
~numpunct_byname()4223 numpunct_byname<char>::~numpunct_byname()
4224 {
4225 }
4226
4227 void
__init(const char * nm)4228 numpunct_byname<char>::__init(const char* nm)
4229 {
4230 if (strcmp(nm, "C") != 0)
4231 {
4232 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
4233 #ifndef _LIBCPP_NO_EXCEPTIONS
4234 if (loc == nullptr)
4235 throw runtime_error("numpunct_byname<char>::numpunct_byname"
4236 " failed to construct for " + string(nm));
4237 #endif // _LIBCPP_NO_EXCEPTIONS
4238 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
4239 lconv* lc = localeconv_l(loc.get());
4240 #else
4241 lconv* lc = __localeconv_l(loc.get());
4242 #endif
4243 if (*lc->decimal_point)
4244 __decimal_point_ = *lc->decimal_point;
4245 if (*lc->thousands_sep)
4246 __thousands_sep_ = *lc->thousands_sep;
4247 __grouping_ = lc->grouping;
4248 // localization for truename and falsename is not available
4249 }
4250 }
4251
4252 // numpunct_byname<wchar_t>
4253
numpunct_byname(const char * nm,size_t refs)4254 numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4255 : numpunct<wchar_t>(refs)
4256 {
4257 __init(nm);
4258 }
4259
numpunct_byname(const string & nm,size_t refs)4260 numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4261 : numpunct<wchar_t>(refs)
4262 {
4263 __init(nm.c_str());
4264 }
4265
~numpunct_byname()4266 numpunct_byname<wchar_t>::~numpunct_byname()
4267 {
4268 }
4269
4270 void
__init(const char * nm)4271 numpunct_byname<wchar_t>::__init(const char* nm)
4272 {
4273 if (strcmp(nm, "C") != 0)
4274 {
4275 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
4276 #ifndef _LIBCPP_NO_EXCEPTIONS
4277 if (loc == nullptr)
4278 throw runtime_error("numpunct_byname<char>::numpunct_byname"
4279 " failed to construct for " + string(nm));
4280 #endif // _LIBCPP_NO_EXCEPTIONS
4281 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
4282 lconv* lc = localeconv_l(loc.get());
4283 #else
4284 lconv* lc = __localeconv_l(loc.get());
4285 #endif
4286 if (*lc->decimal_point)
4287 __decimal_point_ = *lc->decimal_point;
4288 if (*lc->thousands_sep)
4289 __thousands_sep_ = *lc->thousands_sep;
4290 __grouping_ = lc->grouping;
4291 // locallization for truename and falsename is not available
4292 }
4293 }
4294
4295 // num_get helpers
4296
4297 int
__get_base(ios_base & iob)4298 __num_get_base::__get_base(ios_base& iob)
4299 {
4300 ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4301 if (__basefield == ios_base::oct)
4302 return 8;
4303 else if (__basefield == ios_base::hex)
4304 return 16;
4305 else if (__basefield == 0)
4306 return 0;
4307 return 10;
4308 }
4309
4310 const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4311
4312 void
__check_grouping(const string & __grouping,unsigned * __g,unsigned * __g_end,ios_base::iostate & __err)4313 __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4314 ios_base::iostate& __err)
4315 {
4316 if (__grouping.size() != 0)
4317 {
4318 reverse(__g, __g_end);
4319 const char* __ig = __grouping.data();
4320 const char* __eg = __ig + __grouping.size();
4321 for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4322 {
4323 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4324 {
4325 if (static_cast<unsigned>(*__ig) != *__r)
4326 {
4327 __err = ios_base::failbit;
4328 return;
4329 }
4330 }
4331 if (__eg - __ig > 1)
4332 ++__ig;
4333 }
4334 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4335 {
4336 if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
4337 __err = ios_base::failbit;
4338 }
4339 }
4340 }
4341
4342 void
__format_int(char * __fmtp,const char * __len,bool __signd,ios_base::fmtflags __flags)4343 __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4344 ios_base::fmtflags __flags)
4345 {
4346 if (__flags & ios_base::showpos)
4347 *__fmtp++ = '+';
4348 if (__flags & ios_base::showbase)
4349 *__fmtp++ = '#';
4350 while(*__len)
4351 *__fmtp++ = *__len++;
4352 if ((__flags & ios_base::basefield) == ios_base::oct)
4353 *__fmtp = 'o';
4354 else if ((__flags & ios_base::basefield) == ios_base::hex)
4355 {
4356 if (__flags & ios_base::uppercase)
4357 *__fmtp = 'X';
4358 else
4359 *__fmtp = 'x';
4360 }
4361 else if (__signd)
4362 *__fmtp = 'd';
4363 else
4364 *__fmtp = 'u';
4365 }
4366
4367 bool
__format_float(char * __fmtp,const char * __len,ios_base::fmtflags __flags)4368 __num_put_base::__format_float(char* __fmtp, const char* __len,
4369 ios_base::fmtflags __flags)
4370 {
4371 bool specify_precision = true;
4372 if (__flags & ios_base::showpos)
4373 *__fmtp++ = '+';
4374 if (__flags & ios_base::showpoint)
4375 *__fmtp++ = '#';
4376 ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4377 bool uppercase = (__flags & ios_base::uppercase) != 0;
4378 if (floatfield == (ios_base::fixed | ios_base::scientific))
4379 specify_precision = false;
4380 else
4381 {
4382 *__fmtp++ = '.';
4383 *__fmtp++ = '*';
4384 }
4385 while(*__len)
4386 *__fmtp++ = *__len++;
4387 if (floatfield == ios_base::fixed)
4388 {
4389 if (uppercase)
4390 *__fmtp = 'F';
4391 else
4392 *__fmtp = 'f';
4393 }
4394 else if (floatfield == ios_base::scientific)
4395 {
4396 if (uppercase)
4397 *__fmtp = 'E';
4398 else
4399 *__fmtp = 'e';
4400 }
4401 else if (floatfield == (ios_base::fixed | ios_base::scientific))
4402 {
4403 if (uppercase)
4404 *__fmtp = 'A';
4405 else
4406 *__fmtp = 'a';
4407 }
4408 else
4409 {
4410 if (uppercase)
4411 *__fmtp = 'G';
4412 else
4413 *__fmtp = 'g';
4414 }
4415 return specify_precision;
4416 }
4417
4418 char*
__identify_padding(char * __nb,char * __ne,const ios_base & __iob)4419 __num_put_base::__identify_padding(char* __nb, char* __ne,
4420 const ios_base& __iob)
4421 {
4422 switch (__iob.flags() & ios_base::adjustfield)
4423 {
4424 case ios_base::internal:
4425 if (__nb[0] == '-' || __nb[0] == '+')
4426 return __nb+1;
4427 if (__ne - __nb >= 2 && __nb[0] == '0'
4428 && (__nb[1] == 'x' || __nb[1] == 'X'))
4429 return __nb+2;
4430 break;
4431 case ios_base::left:
4432 return __ne;
4433 case ios_base::right:
4434 default:
4435 break;
4436 }
4437 return __nb;
4438 }
4439
4440 // time_get
4441
4442 static
4443 string*
init_weeks()4444 init_weeks()
4445 {
4446 static string weeks[14];
4447 weeks[0] = "Sunday";
4448 weeks[1] = "Monday";
4449 weeks[2] = "Tuesday";
4450 weeks[3] = "Wednesday";
4451 weeks[4] = "Thursday";
4452 weeks[5] = "Friday";
4453 weeks[6] = "Saturday";
4454 weeks[7] = "Sun";
4455 weeks[8] = "Mon";
4456 weeks[9] = "Tue";
4457 weeks[10] = "Wed";
4458 weeks[11] = "Thu";
4459 weeks[12] = "Fri";
4460 weeks[13] = "Sat";
4461 return weeks;
4462 }
4463
4464 static
4465 wstring*
init_wweeks()4466 init_wweeks()
4467 {
4468 static wstring weeks[14];
4469 weeks[0] = L"Sunday";
4470 weeks[1] = L"Monday";
4471 weeks[2] = L"Tuesday";
4472 weeks[3] = L"Wednesday";
4473 weeks[4] = L"Thursday";
4474 weeks[5] = L"Friday";
4475 weeks[6] = L"Saturday";
4476 weeks[7] = L"Sun";
4477 weeks[8] = L"Mon";
4478 weeks[9] = L"Tue";
4479 weeks[10] = L"Wed";
4480 weeks[11] = L"Thu";
4481 weeks[12] = L"Fri";
4482 weeks[13] = L"Sat";
4483 return weeks;
4484 }
4485
4486 template <>
4487 const string*
__weeks() const4488 __time_get_c_storage<char>::__weeks() const
4489 {
4490 static const string* weeks = init_weeks();
4491 return weeks;
4492 }
4493
4494 template <>
4495 const wstring*
__weeks() const4496 __time_get_c_storage<wchar_t>::__weeks() const
4497 {
4498 static const wstring* weeks = init_wweeks();
4499 return weeks;
4500 }
4501
4502 static
4503 string*
init_months()4504 init_months()
4505 {
4506 static string months[24];
4507 months[0] = "January";
4508 months[1] = "February";
4509 months[2] = "March";
4510 months[3] = "April";
4511 months[4] = "May";
4512 months[5] = "June";
4513 months[6] = "July";
4514 months[7] = "August";
4515 months[8] = "September";
4516 months[9] = "October";
4517 months[10] = "November";
4518 months[11] = "December";
4519 months[12] = "Jan";
4520 months[13] = "Feb";
4521 months[14] = "Mar";
4522 months[15] = "Apr";
4523 months[16] = "May";
4524 months[17] = "Jun";
4525 months[18] = "Jul";
4526 months[19] = "Aug";
4527 months[20] = "Sep";
4528 months[21] = "Oct";
4529 months[22] = "Nov";
4530 months[23] = "Dec";
4531 return months;
4532 }
4533
4534 static
4535 wstring*
init_wmonths()4536 init_wmonths()
4537 {
4538 static wstring months[24];
4539 months[0] = L"January";
4540 months[1] = L"February";
4541 months[2] = L"March";
4542 months[3] = L"April";
4543 months[4] = L"May";
4544 months[5] = L"June";
4545 months[6] = L"July";
4546 months[7] = L"August";
4547 months[8] = L"September";
4548 months[9] = L"October";
4549 months[10] = L"November";
4550 months[11] = L"December";
4551 months[12] = L"Jan";
4552 months[13] = L"Feb";
4553 months[14] = L"Mar";
4554 months[15] = L"Apr";
4555 months[16] = L"May";
4556 months[17] = L"Jun";
4557 months[18] = L"Jul";
4558 months[19] = L"Aug";
4559 months[20] = L"Sep";
4560 months[21] = L"Oct";
4561 months[22] = L"Nov";
4562 months[23] = L"Dec";
4563 return months;
4564 }
4565
4566 template <>
4567 const string*
__months() const4568 __time_get_c_storage<char>::__months() const
4569 {
4570 static const string* months = init_months();
4571 return months;
4572 }
4573
4574 template <>
4575 const wstring*
__months() const4576 __time_get_c_storage<wchar_t>::__months() const
4577 {
4578 static const wstring* months = init_wmonths();
4579 return months;
4580 }
4581
4582 static
4583 string*
init_am_pm()4584 init_am_pm()
4585 {
4586 static string am_pm[24];
4587 am_pm[0] = "AM";
4588 am_pm[1] = "PM";
4589 return am_pm;
4590 }
4591
4592 static
4593 wstring*
init_wam_pm()4594 init_wam_pm()
4595 {
4596 static wstring am_pm[24];
4597 am_pm[0] = L"AM";
4598 am_pm[1] = L"PM";
4599 return am_pm;
4600 }
4601
4602 template <>
4603 const string*
__am_pm() const4604 __time_get_c_storage<char>::__am_pm() const
4605 {
4606 static const string* am_pm = init_am_pm();
4607 return am_pm;
4608 }
4609
4610 template <>
4611 const wstring*
__am_pm() const4612 __time_get_c_storage<wchar_t>::__am_pm() const
4613 {
4614 static const wstring* am_pm = init_wam_pm();
4615 return am_pm;
4616 }
4617
4618 template <>
4619 const string&
__x() const4620 __time_get_c_storage<char>::__x() const
4621 {
4622 static string s("%m/%d/%y");
4623 return s;
4624 }
4625
4626 template <>
4627 const wstring&
__x() const4628 __time_get_c_storage<wchar_t>::__x() const
4629 {
4630 static wstring s(L"%m/%d/%y");
4631 return s;
4632 }
4633
4634 template <>
4635 const string&
__X() const4636 __time_get_c_storage<char>::__X() const
4637 {
4638 static string s("%H:%M:%S");
4639 return s;
4640 }
4641
4642 template <>
4643 const wstring&
__X() const4644 __time_get_c_storage<wchar_t>::__X() const
4645 {
4646 static wstring s(L"%H:%M:%S");
4647 return s;
4648 }
4649
4650 template <>
4651 const string&
__c() const4652 __time_get_c_storage<char>::__c() const
4653 {
4654 static string s("%a %b %d %H:%M:%S %Y");
4655 return s;
4656 }
4657
4658 template <>
4659 const wstring&
__c() const4660 __time_get_c_storage<wchar_t>::__c() const
4661 {
4662 static wstring s(L"%a %b %d %H:%M:%S %Y");
4663 return s;
4664 }
4665
4666 template <>
4667 const string&
__r() const4668 __time_get_c_storage<char>::__r() const
4669 {
4670 static string s("%I:%M:%S %p");
4671 return s;
4672 }
4673
4674 template <>
4675 const wstring&
__r() const4676 __time_get_c_storage<wchar_t>::__r() const
4677 {
4678 static wstring s(L"%I:%M:%S %p");
4679 return s;
4680 }
4681
4682 // time_get_byname
4683
__time_get(const char * nm)4684 __time_get::__time_get(const char* nm)
4685 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
4686 {
4687 #ifndef _LIBCPP_NO_EXCEPTIONS
4688 if (__loc_ == 0)
4689 throw runtime_error("time_get_byname"
4690 " failed to construct for " + string(nm));
4691 #endif // _LIBCPP_NO_EXCEPTIONS
4692 }
4693
__time_get(const string & nm)4694 __time_get::__time_get(const string& nm)
4695 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
4696 {
4697 #ifndef _LIBCPP_NO_EXCEPTIONS
4698 if (__loc_ == 0)
4699 throw runtime_error("time_get_byname"
4700 " failed to construct for " + nm);
4701 #endif // _LIBCPP_NO_EXCEPTIONS
4702 }
4703
~__time_get()4704 __time_get::~__time_get()
4705 {
4706 freelocale(__loc_);
4707 }
4708 #if defined(__clang__)
4709 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
4710 #endif
4711 #if defined(__GNUG__)
4712 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
4713 #endif
4714
4715 template <>
4716 string
__analyze(char fmt,const ctype<char> & ct)4717 __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
4718 {
4719 tm t = {0};
4720 t.tm_sec = 59;
4721 t.tm_min = 55;
4722 t.tm_hour = 23;
4723 t.tm_mday = 31;
4724 t.tm_mon = 11;
4725 t.tm_year = 161;
4726 t.tm_wday = 6;
4727 t.tm_yday = 364;
4728 t.tm_isdst = -1;
4729 char buf[100];
4730 char f[3] = {0};
4731 f[0] = '%';
4732 f[1] = fmt;
4733 size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);
4734 char* bb = buf;
4735 char* be = buf + n;
4736 string result;
4737 while (bb != be)
4738 {
4739 if (ct.is(ctype_base::space, *bb))
4740 {
4741 result.push_back(' ');
4742 for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
4743 ;
4744 continue;
4745 }
4746 char* w = bb;
4747 ios_base::iostate err = ios_base::goodbit;
4748 ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
4749 ct, err, false)
4750 - this->__weeks_;
4751 if (i < 14)
4752 {
4753 result.push_back('%');
4754 if (i < 7)
4755 result.push_back('A');
4756 else
4757 result.push_back('a');
4758 bb = w;
4759 continue;
4760 }
4761 w = bb;
4762 i = __scan_keyword(w, be, this->__months_, this->__months_+24,
4763 ct, err, false)
4764 - this->__months_;
4765 if (i < 24)
4766 {
4767 result.push_back('%');
4768 if (i < 12)
4769 result.push_back('B');
4770 else
4771 result.push_back('b');
4772 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4773 result.back() = 'm';
4774 bb = w;
4775 continue;
4776 }
4777 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4778 {
4779 w = bb;
4780 i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
4781 ct, err, false) - this->__am_pm_;
4782 if (i < 2)
4783 {
4784 result.push_back('%');
4785 result.push_back('p');
4786 bb = w;
4787 continue;
4788 }
4789 }
4790 w = bb;
4791 if (ct.is(ctype_base::digit, *bb))
4792 {
4793 switch(__get_up_to_n_digits(bb, be, err, ct, 4))
4794 {
4795 case 6:
4796 result.push_back('%');
4797 result.push_back('w');
4798 break;
4799 case 7:
4800 result.push_back('%');
4801 result.push_back('u');
4802 break;
4803 case 11:
4804 result.push_back('%');
4805 result.push_back('I');
4806 break;
4807 case 12:
4808 result.push_back('%');
4809 result.push_back('m');
4810 break;
4811 case 23:
4812 result.push_back('%');
4813 result.push_back('H');
4814 break;
4815 case 31:
4816 result.push_back('%');
4817 result.push_back('d');
4818 break;
4819 case 55:
4820 result.push_back('%');
4821 result.push_back('M');
4822 break;
4823 case 59:
4824 result.push_back('%');
4825 result.push_back('S');
4826 break;
4827 case 61:
4828 result.push_back('%');
4829 result.push_back('y');
4830 break;
4831 case 364:
4832 result.push_back('%');
4833 result.push_back('j');
4834 break;
4835 case 2061:
4836 result.push_back('%');
4837 result.push_back('Y');
4838 break;
4839 default:
4840 for (; w != bb; ++w)
4841 result.push_back(*w);
4842 break;
4843 }
4844 continue;
4845 }
4846 if (*bb == '%')
4847 {
4848 result.push_back('%');
4849 result.push_back('%');
4850 ++bb;
4851 continue;
4852 }
4853 result.push_back(*bb);
4854 ++bb;
4855 }
4856 return result;
4857 }
4858
4859 #if defined(__clang__)
4860 #pragma clang diagnostic ignored "-Wmissing-braces"
4861 #endif
4862
4863 template <>
4864 wstring
__analyze(char fmt,const ctype<wchar_t> & ct)4865 __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
4866 {
4867 tm t = {0};
4868 t.tm_sec = 59;
4869 t.tm_min = 55;
4870 t.tm_hour = 23;
4871 t.tm_mday = 31;
4872 t.tm_mon = 11;
4873 t.tm_year = 161;
4874 t.tm_wday = 6;
4875 t.tm_yday = 364;
4876 t.tm_isdst = -1;
4877 char buf[100];
4878 char f[3] = {0};
4879 f[0] = '%';
4880 f[1] = fmt;
4881 strftime_l(buf, countof(buf), f, &t, __loc_);
4882 wchar_t wbuf[100];
4883 wchar_t* wbb = wbuf;
4884 mbstate_t mb = {0};
4885 const char* bb = buf;
4886 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
4887 size_t j = mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
4888 #else
4889 size_t j = __mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
4890 #endif
4891 if (j == size_t(-1))
4892 __throw_runtime_error("locale not supported");
4893 wchar_t* wbe = wbb + j;
4894 wstring result;
4895 while (wbb != wbe)
4896 {
4897 if (ct.is(ctype_base::space, *wbb))
4898 {
4899 result.push_back(L' ');
4900 for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
4901 ;
4902 continue;
4903 }
4904 wchar_t* w = wbb;
4905 ios_base::iostate err = ios_base::goodbit;
4906 ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
4907 ct, err, false)
4908 - this->__weeks_;
4909 if (i < 14)
4910 {
4911 result.push_back(L'%');
4912 if (i < 7)
4913 result.push_back(L'A');
4914 else
4915 result.push_back(L'a');
4916 wbb = w;
4917 continue;
4918 }
4919 w = wbb;
4920 i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
4921 ct, err, false)
4922 - this->__months_;
4923 if (i < 24)
4924 {
4925 result.push_back(L'%');
4926 if (i < 12)
4927 result.push_back(L'B');
4928 else
4929 result.push_back(L'b');
4930 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4931 result.back() = L'm';
4932 wbb = w;
4933 continue;
4934 }
4935 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4936 {
4937 w = wbb;
4938 i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
4939 ct, err, false) - this->__am_pm_;
4940 if (i < 2)
4941 {
4942 result.push_back(L'%');
4943 result.push_back(L'p');
4944 wbb = w;
4945 continue;
4946 }
4947 }
4948 w = wbb;
4949 if (ct.is(ctype_base::digit, *wbb))
4950 {
4951 switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
4952 {
4953 case 6:
4954 result.push_back(L'%');
4955 result.push_back(L'w');
4956 break;
4957 case 7:
4958 result.push_back(L'%');
4959 result.push_back(L'u');
4960 break;
4961 case 11:
4962 result.push_back(L'%');
4963 result.push_back(L'I');
4964 break;
4965 case 12:
4966 result.push_back(L'%');
4967 result.push_back(L'm');
4968 break;
4969 case 23:
4970 result.push_back(L'%');
4971 result.push_back(L'H');
4972 break;
4973 case 31:
4974 result.push_back(L'%');
4975 result.push_back(L'd');
4976 break;
4977 case 55:
4978 result.push_back(L'%');
4979 result.push_back(L'M');
4980 break;
4981 case 59:
4982 result.push_back(L'%');
4983 result.push_back(L'S');
4984 break;
4985 case 61:
4986 result.push_back(L'%');
4987 result.push_back(L'y');
4988 break;
4989 case 364:
4990 result.push_back(L'%');
4991 result.push_back(L'j');
4992 break;
4993 case 2061:
4994 result.push_back(L'%');
4995 result.push_back(L'Y');
4996 break;
4997 default:
4998 for (; w != wbb; ++w)
4999 result.push_back(*w);
5000 break;
5001 }
5002 continue;
5003 }
5004 if (ct.narrow(*wbb, 0) == '%')
5005 {
5006 result.push_back(L'%');
5007 result.push_back(L'%');
5008 ++wbb;
5009 continue;
5010 }
5011 result.push_back(*wbb);
5012 ++wbb;
5013 }
5014 return result;
5015 }
5016
5017 template <>
5018 void
init(const ctype<char> & ct)5019 __time_get_storage<char>::init(const ctype<char>& ct)
5020 {
5021 tm t = {0};
5022 char buf[100];
5023 // __weeks_
5024 for (int i = 0; i < 7; ++i)
5025 {
5026 t.tm_wday = i;
5027 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5028 __weeks_[i] = buf;
5029 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5030 __weeks_[i+7] = buf;
5031 }
5032 // __months_
5033 for (int i = 0; i < 12; ++i)
5034 {
5035 t.tm_mon = i;
5036 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5037 __months_[i] = buf;
5038 strftime_l(buf, countof(buf), "%b", &t, __loc_);
5039 __months_[i+12] = buf;
5040 }
5041 // __am_pm_
5042 t.tm_hour = 1;
5043 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5044 __am_pm_[0] = buf;
5045 t.tm_hour = 13;
5046 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5047 __am_pm_[1] = buf;
5048 __c_ = __analyze('c', ct);
5049 __r_ = __analyze('r', ct);
5050 __x_ = __analyze('x', ct);
5051 __X_ = __analyze('X', ct);
5052 }
5053
5054 template <>
5055 void
init(const ctype<wchar_t> & ct)5056 __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
5057 {
5058 tm t = {0};
5059 char buf[100];
5060 wchar_t wbuf[100];
5061 wchar_t* wbe;
5062 mbstate_t mb = {0};
5063 // __weeks_
5064 for (int i = 0; i < 7; ++i)
5065 {
5066 t.tm_wday = i;
5067 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5068 mb = mbstate_t();
5069 const char* bb = buf;
5070 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5071 size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5072 #else
5073 size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5074 #endif
5075 if (j == size_t(-1))
5076 __throw_runtime_error("locale not supported");
5077 wbe = wbuf + j;
5078 __weeks_[i].assign(wbuf, wbe);
5079 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5080 mb = mbstate_t();
5081 bb = buf;
5082 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5083 j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5084 #else
5085 j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5086 #endif
5087 if (j == size_t(-1))
5088 __throw_runtime_error("locale not supported");
5089 wbe = wbuf + j;
5090 __weeks_[i+7].assign(wbuf, wbe);
5091 }
5092 // __months_
5093 for (int i = 0; i < 12; ++i)
5094 {
5095 t.tm_mon = i;
5096 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5097 mb = mbstate_t();
5098 const char* bb = buf;
5099 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5100 size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5101 #else
5102 size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5103 #endif
5104 if (j == size_t(-1))
5105 __throw_runtime_error("locale not supported");
5106 wbe = wbuf + j;
5107 __months_[i].assign(wbuf, wbe);
5108 strftime_l(buf, countof(buf), "%b", &t, __loc_);
5109 mb = mbstate_t();
5110 bb = buf;
5111 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5112 j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5113 #else
5114 j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5115 #endif
5116 if (j == size_t(-1))
5117 __throw_runtime_error("locale not supported");
5118 wbe = wbuf + j;
5119 __months_[i+12].assign(wbuf, wbe);
5120 }
5121 // __am_pm_
5122 t.tm_hour = 1;
5123 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5124 mb = mbstate_t();
5125 const char* bb = buf;
5126 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5127 size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5128 #else
5129 size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5130 #endif
5131 if (j == size_t(-1))
5132 __throw_runtime_error("locale not supported");
5133 wbe = wbuf + j;
5134 __am_pm_[0].assign(wbuf, wbe);
5135 t.tm_hour = 13;
5136 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5137 mb = mbstate_t();
5138 bb = buf;
5139 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5140 j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5141 #else
5142 j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5143 #endif
5144 if (j == size_t(-1))
5145 __throw_runtime_error("locale not supported");
5146 wbe = wbuf + j;
5147 __am_pm_[1].assign(wbuf, wbe);
5148 __c_ = __analyze('c', ct);
5149 __r_ = __analyze('r', ct);
5150 __x_ = __analyze('x', ct);
5151 __X_ = __analyze('X', ct);
5152 }
5153
5154 template <class CharT>
5155 struct _LIBCPP_HIDDEN __time_get_temp
5156 : public ctype_byname<CharT>
5157 {
__time_get_temp__time_get_temp5158 explicit __time_get_temp(const char* nm)
5159 : ctype_byname<CharT>(nm, 1) {}
__time_get_temp__time_get_temp5160 explicit __time_get_temp(const string& nm)
5161 : ctype_byname<CharT>(nm, 1) {}
5162 };
5163
5164 template <>
__time_get_storage(const char * __nm)5165 __time_get_storage<char>::__time_get_storage(const char* __nm)
5166 : __time_get(__nm)
5167 {
5168 const __time_get_temp<char> ct(__nm);
5169 init(ct);
5170 }
5171
5172 template <>
__time_get_storage(const string & __nm)5173 __time_get_storage<char>::__time_get_storage(const string& __nm)
5174 : __time_get(__nm)
5175 {
5176 const __time_get_temp<char> ct(__nm);
5177 init(ct);
5178 }
5179
5180 template <>
__time_get_storage(const char * __nm)5181 __time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5182 : __time_get(__nm)
5183 {
5184 const __time_get_temp<wchar_t> ct(__nm);
5185 init(ct);
5186 }
5187
5188 template <>
__time_get_storage(const string & __nm)5189 __time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5190 : __time_get(__nm)
5191 {
5192 const __time_get_temp<wchar_t> ct(__nm);
5193 init(ct);
5194 }
5195
5196 template <>
5197 time_base::dateorder
__do_date_order() const5198 __time_get_storage<char>::__do_date_order() const
5199 {
5200 unsigned i;
5201 for (i = 0; i < __x_.size(); ++i)
5202 if (__x_[i] == '%')
5203 break;
5204 ++i;
5205 switch (__x_[i])
5206 {
5207 case 'y':
5208 case 'Y':
5209 for (++i; i < __x_.size(); ++i)
5210 if (__x_[i] == '%')
5211 break;
5212 if (i == __x_.size())
5213 break;
5214 ++i;
5215 switch (__x_[i])
5216 {
5217 case 'm':
5218 for (++i; i < __x_.size(); ++i)
5219 if (__x_[i] == '%')
5220 break;
5221 if (i == __x_.size())
5222 break;
5223 ++i;
5224 if (__x_[i] == 'd')
5225 return time_base::ymd;
5226 break;
5227 case 'd':
5228 for (++i; i < __x_.size(); ++i)
5229 if (__x_[i] == '%')
5230 break;
5231 if (i == __x_.size())
5232 break;
5233 ++i;
5234 if (__x_[i] == 'm')
5235 return time_base::ydm;
5236 break;
5237 }
5238 break;
5239 case 'm':
5240 for (++i; i < __x_.size(); ++i)
5241 if (__x_[i] == '%')
5242 break;
5243 if (i == __x_.size())
5244 break;
5245 ++i;
5246 if (__x_[i] == 'd')
5247 {
5248 for (++i; i < __x_.size(); ++i)
5249 if (__x_[i] == '%')
5250 break;
5251 if (i == __x_.size())
5252 break;
5253 ++i;
5254 if (__x_[i] == 'y' || __x_[i] == 'Y')
5255 return time_base::mdy;
5256 break;
5257 }
5258 break;
5259 case 'd':
5260 for (++i; i < __x_.size(); ++i)
5261 if (__x_[i] == '%')
5262 break;
5263 if (i == __x_.size())
5264 break;
5265 ++i;
5266 if (__x_[i] == 'm')
5267 {
5268 for (++i; i < __x_.size(); ++i)
5269 if (__x_[i] == '%')
5270 break;
5271 if (i == __x_.size())
5272 break;
5273 ++i;
5274 if (__x_[i] == 'y' || __x_[i] == 'Y')
5275 return time_base::dmy;
5276 break;
5277 }
5278 break;
5279 }
5280 return time_base::no_order;
5281 }
5282
5283 template <>
5284 time_base::dateorder
__do_date_order() const5285 __time_get_storage<wchar_t>::__do_date_order() const
5286 {
5287 unsigned i;
5288 for (i = 0; i < __x_.size(); ++i)
5289 if (__x_[i] == L'%')
5290 break;
5291 ++i;
5292 switch (__x_[i])
5293 {
5294 case L'y':
5295 case L'Y':
5296 for (++i; i < __x_.size(); ++i)
5297 if (__x_[i] == L'%')
5298 break;
5299 if (i == __x_.size())
5300 break;
5301 ++i;
5302 switch (__x_[i])
5303 {
5304 case L'm':
5305 for (++i; i < __x_.size(); ++i)
5306 if (__x_[i] == L'%')
5307 break;
5308 if (i == __x_.size())
5309 break;
5310 ++i;
5311 if (__x_[i] == L'd')
5312 return time_base::ymd;
5313 break;
5314 case L'd':
5315 for (++i; i < __x_.size(); ++i)
5316 if (__x_[i] == L'%')
5317 break;
5318 if (i == __x_.size())
5319 break;
5320 ++i;
5321 if (__x_[i] == L'm')
5322 return time_base::ydm;
5323 break;
5324 }
5325 break;
5326 case L'm':
5327 for (++i; i < __x_.size(); ++i)
5328 if (__x_[i] == L'%')
5329 break;
5330 if (i == __x_.size())
5331 break;
5332 ++i;
5333 if (__x_[i] == L'd')
5334 {
5335 for (++i; i < __x_.size(); ++i)
5336 if (__x_[i] == L'%')
5337 break;
5338 if (i == __x_.size())
5339 break;
5340 ++i;
5341 if (__x_[i] == L'y' || __x_[i] == L'Y')
5342 return time_base::mdy;
5343 break;
5344 }
5345 break;
5346 case L'd':
5347 for (++i; i < __x_.size(); ++i)
5348 if (__x_[i] == L'%')
5349 break;
5350 if (i == __x_.size())
5351 break;
5352 ++i;
5353 if (__x_[i] == L'm')
5354 {
5355 for (++i; i < __x_.size(); ++i)
5356 if (__x_[i] == L'%')
5357 break;
5358 if (i == __x_.size())
5359 break;
5360 ++i;
5361 if (__x_[i] == L'y' || __x_[i] == L'Y')
5362 return time_base::dmy;
5363 break;
5364 }
5365 break;
5366 }
5367 return time_base::no_order;
5368 }
5369
5370 // time_put
5371
__time_put(const char * nm)5372 __time_put::__time_put(const char* nm)
5373 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5374 {
5375 #ifndef _LIBCPP_NO_EXCEPTIONS
5376 if (__loc_ == 0)
5377 throw runtime_error("time_put_byname"
5378 " failed to construct for " + string(nm));
5379 #endif // _LIBCPP_NO_EXCEPTIONS
5380 }
5381
__time_put(const string & nm)5382 __time_put::__time_put(const string& nm)
5383 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5384 {
5385 #ifndef _LIBCPP_NO_EXCEPTIONS
5386 if (__loc_ == 0)
5387 throw runtime_error("time_put_byname"
5388 " failed to construct for " + nm);
5389 #endif // _LIBCPP_NO_EXCEPTIONS
5390 }
5391
~__time_put()5392 __time_put::~__time_put()
5393 {
5394 if (__loc_ != _LIBCPP_GET_C_LOCALE)
5395 freelocale(__loc_);
5396 }
5397
5398 void
__do_put(char * __nb,char * & __ne,const tm * __tm,char __fmt,char __mod) const5399 __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5400 char __fmt, char __mod) const
5401 {
5402 char fmt[] = {'%', __fmt, __mod, 0};
5403 if (__mod != 0)
5404 swap(fmt[1], fmt[2]);
5405 size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
5406 __ne = __nb + n;
5407 }
5408
5409 void
__do_put(wchar_t * __wb,wchar_t * & __we,const tm * __tm,char __fmt,char __mod) const5410 __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5411 char __fmt, char __mod) const
5412 {
5413 char __nar[100];
5414 char* __ne = __nar + 100;
5415 __do_put(__nar, __ne, __tm, __fmt, __mod);
5416 mbstate_t mb = {0};
5417 const char* __nb = __nar;
5418 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5419 size_t j = mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
5420 #else
5421 size_t j = __mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
5422 #endif
5423 if (j == size_t(-1))
5424 __throw_runtime_error("locale not supported");
5425 __we = __wb + j;
5426 }
5427
5428 // moneypunct_byname
5429
5430 template <class charT>
5431 static
5432 void
__init_pat(money_base::pattern & pat,basic_string<charT> & __curr_symbol_,bool intl,char cs_precedes,char sep_by_space,char sign_posn,charT space_char)5433 __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
5434 bool intl, char cs_precedes, char sep_by_space, char sign_posn,
5435 charT space_char)
5436 {
5437 const char sign = static_cast<char>(money_base::sign);
5438 const char space = static_cast<char>(money_base::space);
5439 const char none = static_cast<char>(money_base::none);
5440 const char symbol = static_cast<char>(money_base::symbol);
5441 const char value = static_cast<char>(money_base::value);
5442 const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
5443
5444 // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5445 // function'. "Space between sign and symbol or value" means that
5446 // if the sign is adjacent to the symbol, there's a space between
5447 // them, and otherwise there's a space between the sign and value.
5448 //
5449 // C11's localeconv specifies that the fourth character of an
5450 // international curr_symbol is used to separate the sign and
5451 // value when sep_by_space says to do so. C++ can't represent
5452 // that, so we just use a space. When sep_by_space says to
5453 // separate the symbol and value-or-sign with a space, we rearrange the
5454 // curr_symbol to put its spacing character on the correct side of
5455 // the symbol.
5456 //
5457 // We also need to avoid adding an extra space between the sign
5458 // and value when the currency symbol is suppressed (by not
5459 // setting showbase). We match glibc's strfmon by interpreting
5460 // sep_by_space==1 as "omit the space when the currency symbol is
5461 // absent".
5462 //
5463 // Users who want to get this right should use ICU instead.
5464
5465 switch (cs_precedes)
5466 {
5467 case 0: // value before curr_symbol
5468 if (symbol_contains_sep) {
5469 // Move the separator to before the symbol, to place it
5470 // between the value and symbol.
5471 rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,
5472 __curr_symbol_.end());
5473 }
5474 switch (sign_posn)
5475 {
5476 case 0: // Parentheses surround the quantity and currency symbol.
5477 pat.field[0] = sign;
5478 pat.field[1] = value;
5479 pat.field[2] = none; // Any space appears in the symbol.
5480 pat.field[3] = symbol;
5481 switch (sep_by_space)
5482 {
5483 case 0: // No space separates the currency symbol and value.
5484 // This case may have changed between C99 and C11;
5485 // assume the currency symbol matches the intention.
5486 case 2: // Space between sign and currency or value.
5487 // The "sign" is two parentheses, so no space here either.
5488 return;
5489 case 1: // Space between currency-and-sign or currency and value.
5490 if (!symbol_contains_sep) {
5491 // We insert the space into the symbol instead of
5492 // setting pat.field[2]=space so that when
5493 // showbase is not set, the space goes away too.
5494 __curr_symbol_.insert(0, 1, space_char);
5495 }
5496 return;
5497 default:
5498 break;
5499 }
5500 break;
5501 case 1: // The sign string precedes the quantity and currency symbol.
5502 pat.field[0] = sign;
5503 pat.field[3] = symbol;
5504 switch (sep_by_space)
5505 {
5506 case 0: // No space separates the currency symbol and value.
5507 pat.field[1] = value;
5508 pat.field[2] = none;
5509 return;
5510 case 1: // Space between currency-and-sign or currency and value.
5511 pat.field[1] = value;
5512 pat.field[2] = none;
5513 if (!symbol_contains_sep) {
5514 // We insert the space into the symbol instead of
5515 // setting pat.field[2]=space so that when
5516 // showbase is not set, the space goes away too.
5517 __curr_symbol_.insert(0, 1, space_char);
5518 }
5519 return;
5520 case 2: // Space between sign and currency or value.
5521 pat.field[1] = space;
5522 pat.field[2] = value;
5523 if (symbol_contains_sep) {
5524 // Remove the separator from the symbol, since it
5525 // has already appeared after the sign.
5526 __curr_symbol_.erase(__curr_symbol_.begin());
5527 }
5528 return;
5529 default:
5530 break;
5531 }
5532 break;
5533 case 2: // The sign string succeeds the quantity and currency symbol.
5534 pat.field[0] = value;
5535 pat.field[3] = sign;
5536 switch (sep_by_space)
5537 {
5538 case 0: // No space separates the currency symbol and value.
5539 pat.field[1] = none;
5540 pat.field[2] = symbol;
5541 return;
5542 case 1: // Space between currency-and-sign or currency and value.
5543 if (!symbol_contains_sep) {
5544 // We insert the space into the symbol instead of
5545 // setting pat.field[1]=space so that when
5546 // showbase is not set, the space goes away too.
5547 __curr_symbol_.insert(0, 1, space_char);
5548 }
5549 pat.field[1] = none;
5550 pat.field[2] = symbol;
5551 return;
5552 case 2: // Space between sign and currency or value.
5553 pat.field[1] = symbol;
5554 pat.field[2] = space;
5555 if (symbol_contains_sep) {
5556 // Remove the separator from the symbol, since it
5557 // should not be removed if showbase is absent.
5558 __curr_symbol_.erase(__curr_symbol_.begin());
5559 }
5560 return;
5561 default:
5562 break;
5563 }
5564 break;
5565 case 3: // The sign string immediately precedes the currency symbol.
5566 pat.field[0] = value;
5567 pat.field[3] = symbol;
5568 switch (sep_by_space)
5569 {
5570 case 0: // No space separates the currency symbol and value.
5571 pat.field[1] = none;
5572 pat.field[2] = sign;
5573 return;
5574 case 1: // Space between currency-and-sign or currency and value.
5575 pat.field[1] = space;
5576 pat.field[2] = sign;
5577 if (symbol_contains_sep) {
5578 // Remove the separator from the symbol, since it
5579 // has already appeared before the sign.
5580 __curr_symbol_.erase(__curr_symbol_.begin());
5581 }
5582 return;
5583 case 2: // Space between sign and currency or value.
5584 pat.field[1] = sign;
5585 pat.field[2] = none;
5586 if (!symbol_contains_sep) {
5587 // We insert the space into the symbol instead of
5588 // setting pat.field[2]=space so that when
5589 // showbase is not set, the space goes away too.
5590 __curr_symbol_.insert(0, 1, space_char);
5591 }
5592 return;
5593 default:
5594 break;
5595 }
5596 break;
5597 case 4: // The sign string immediately succeeds the currency symbol.
5598 pat.field[0] = value;
5599 pat.field[3] = sign;
5600 switch (sep_by_space)
5601 {
5602 case 0: // No space separates the currency symbol and value.
5603 pat.field[1] = none;
5604 pat.field[2] = symbol;
5605 return;
5606 case 1: // Space between currency-and-sign or currency and value.
5607 pat.field[1] = none;
5608 pat.field[2] = symbol;
5609 if (!symbol_contains_sep) {
5610 // We insert the space into the symbol instead of
5611 // setting pat.field[1]=space so that when
5612 // showbase is not set, the space goes away too.
5613 __curr_symbol_.insert(0, 1, space_char);
5614 }
5615 return;
5616 case 2: // Space between sign and currency or value.
5617 pat.field[1] = symbol;
5618 pat.field[2] = space;
5619 if (symbol_contains_sep) {
5620 // Remove the separator from the symbol, since it
5621 // should not disappear when showbase is absent.
5622 __curr_symbol_.erase(__curr_symbol_.begin());
5623 }
5624 return;
5625 default:
5626 break;
5627 }
5628 break;
5629 default:
5630 break;
5631 }
5632 break;
5633 case 1: // curr_symbol before value
5634 switch (sign_posn)
5635 {
5636 case 0: // Parentheses surround the quantity and currency symbol.
5637 pat.field[0] = sign;
5638 pat.field[1] = symbol;
5639 pat.field[2] = none; // Any space appears in the symbol.
5640 pat.field[3] = value;
5641 switch (sep_by_space)
5642 {
5643 case 0: // No space separates the currency symbol and value.
5644 // This case may have changed between C99 and C11;
5645 // assume the currency symbol matches the intention.
5646 case 2: // Space between sign and currency or value.
5647 // The "sign" is two parentheses, so no space here either.
5648 return;
5649 case 1: // Space between currency-and-sign or currency and value.
5650 if (!symbol_contains_sep) {
5651 // We insert the space into the symbol instead of
5652 // setting pat.field[2]=space so that when
5653 // showbase is not set, the space goes away too.
5654 __curr_symbol_.insert(0, 1, space_char);
5655 }
5656 return;
5657 default:
5658 break;
5659 }
5660 break;
5661 case 1: // The sign string precedes the quantity and currency symbol.
5662 pat.field[0] = sign;
5663 pat.field[3] = value;
5664 switch (sep_by_space)
5665 {
5666 case 0: // No space separates the currency symbol and value.
5667 pat.field[1] = symbol;
5668 pat.field[2] = none;
5669 return;
5670 case 1: // Space between currency-and-sign or currency and value.
5671 pat.field[1] = symbol;
5672 pat.field[2] = none;
5673 if (!symbol_contains_sep) {
5674 // We insert the space into the symbol instead of
5675 // setting pat.field[2]=space so that when
5676 // showbase is not set, the space goes away too.
5677 __curr_symbol_.push_back(space_char);
5678 }
5679 return;
5680 case 2: // Space between sign and currency or value.
5681 pat.field[1] = space;
5682 pat.field[2] = symbol;
5683 if (symbol_contains_sep) {
5684 // Remove the separator from the symbol, since it
5685 // has already appeared after the sign.
5686 __curr_symbol_.pop_back();
5687 }
5688 return;
5689 default:
5690 break;
5691 }
5692 break;
5693 case 2: // The sign string succeeds the quantity and currency symbol.
5694 pat.field[0] = symbol;
5695 pat.field[3] = sign;
5696 switch (sep_by_space)
5697 {
5698 case 0: // No space separates the currency symbol and value.
5699 pat.field[1] = none;
5700 pat.field[2] = value;
5701 return;
5702 case 1: // Space between currency-and-sign or currency and value.
5703 pat.field[1] = none;
5704 pat.field[2] = value;
5705 if (!symbol_contains_sep) {
5706 // We insert the space into the symbol instead of
5707 // setting pat.field[1]=space so that when
5708 // showbase is not set, the space goes away too.
5709 __curr_symbol_.push_back(space_char);
5710 }
5711 return;
5712 case 2: // Space between sign and currency or value.
5713 pat.field[1] = value;
5714 pat.field[2] = space;
5715 if (symbol_contains_sep) {
5716 // Remove the separator from the symbol, since it
5717 // will appear before the sign.
5718 __curr_symbol_.pop_back();
5719 }
5720 return;
5721 default:
5722 break;
5723 }
5724 break;
5725 case 3: // The sign string immediately precedes the currency symbol.
5726 pat.field[0] = sign;
5727 pat.field[3] = value;
5728 switch (sep_by_space)
5729 {
5730 case 0: // No space separates the currency symbol and value.
5731 pat.field[1] = symbol;
5732 pat.field[2] = none;
5733 return;
5734 case 1: // Space between currency-and-sign or currency and value.
5735 pat.field[1] = symbol;
5736 pat.field[2] = none;
5737 if (!symbol_contains_sep) {
5738 // We insert the space into the symbol instead of
5739 // setting pat.field[2]=space so that when
5740 // showbase is not set, the space goes away too.
5741 __curr_symbol_.push_back(space_char);
5742 }
5743 return;
5744 case 2: // Space between sign and currency or value.
5745 pat.field[1] = space;
5746 pat.field[2] = symbol;
5747 if (symbol_contains_sep) {
5748 // Remove the separator from the symbol, since it
5749 // has already appeared after the sign.
5750 __curr_symbol_.pop_back();
5751 }
5752 return;
5753 default:
5754 break;
5755 }
5756 break;
5757 case 4: // The sign string immediately succeeds the currency symbol.
5758 pat.field[0] = symbol;
5759 pat.field[3] = value;
5760 switch (sep_by_space)
5761 {
5762 case 0: // No space separates the currency symbol and value.
5763 pat.field[1] = sign;
5764 pat.field[2] = none;
5765 return;
5766 case 1: // Space between currency-and-sign or currency and value.
5767 pat.field[1] = sign;
5768 pat.field[2] = space;
5769 if (symbol_contains_sep) {
5770 // Remove the separator from the symbol, since it
5771 // should not disappear when showbase is absent.
5772 __curr_symbol_.pop_back();
5773 }
5774 return;
5775 case 2: // Space between sign and currency or value.
5776 pat.field[1] = none;
5777 pat.field[2] = sign;
5778 if (!symbol_contains_sep) {
5779 // We insert the space into the symbol instead of
5780 // setting pat.field[1]=space so that when
5781 // showbase is not set, the space goes away too.
5782 __curr_symbol_.push_back(space_char);
5783 }
5784 return;
5785 default:
5786 break;
5787 }
5788 break;
5789 default:
5790 break;
5791 }
5792 break;
5793 default:
5794 break;
5795 }
5796 pat.field[0] = symbol;
5797 pat.field[1] = sign;
5798 pat.field[2] = none;
5799 pat.field[3] = value;
5800 }
5801
5802 template<>
5803 void
init(const char * nm)5804 moneypunct_byname<char, false>::init(const char* nm)
5805 {
5806 typedef moneypunct<char, false> base;
5807 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5808 #ifndef _LIBCPP_NO_EXCEPTIONS
5809 if (loc == nullptr)
5810 throw runtime_error("moneypunct_byname"
5811 " failed to construct for " + string(nm));
5812 #endif // _LIBCPP_NO_EXCEPTIONS
5813 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5814 lconv* lc = localeconv_l(loc.get());
5815 #else
5816 lconv* lc = __localeconv_l(loc.get());
5817 #endif
5818 if (*lc->mon_decimal_point)
5819 __decimal_point_ = *lc->mon_decimal_point;
5820 else
5821 __decimal_point_ = base::do_decimal_point();
5822 if (*lc->mon_thousands_sep)
5823 __thousands_sep_ = *lc->mon_thousands_sep;
5824 else
5825 __thousands_sep_ = base::do_thousands_sep();
5826 __grouping_ = lc->mon_grouping;
5827 __curr_symbol_ = lc->currency_symbol;
5828 if (lc->frac_digits != CHAR_MAX)
5829 __frac_digits_ = lc->frac_digits;
5830 else
5831 __frac_digits_ = base::do_frac_digits();
5832 if (lc->p_sign_posn == 0)
5833 __positive_sign_ = "()";
5834 else
5835 __positive_sign_ = lc->positive_sign;
5836 if (lc->n_sign_posn == 0)
5837 __negative_sign_ = "()";
5838 else
5839 __negative_sign_ = lc->negative_sign;
5840 // Assume the positive and negative formats will want spaces in
5841 // the same places in curr_symbol since there's no way to
5842 // represent anything else.
5843 string_type __dummy_curr_symbol = __curr_symbol_;
5844 __init_pat(__pos_format_, __dummy_curr_symbol, false,
5845 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5846 __init_pat(__neg_format_, __curr_symbol_, false,
5847 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5848 }
5849
5850 template<>
5851 void
init(const char * nm)5852 moneypunct_byname<char, true>::init(const char* nm)
5853 {
5854 typedef moneypunct<char, true> base;
5855 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5856 #ifndef _LIBCPP_NO_EXCEPTIONS
5857 if (loc == nullptr)
5858 throw runtime_error("moneypunct_byname"
5859 " failed to construct for " + string(nm));
5860 #endif // _LIBCPP_NO_EXCEPTIONS
5861 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5862 lconv* lc = localeconv_l(loc.get());
5863 #else
5864 lconv* lc = __localeconv_l(loc.get());
5865 #endif
5866 if (*lc->mon_decimal_point)
5867 __decimal_point_ = *lc->mon_decimal_point;
5868 else
5869 __decimal_point_ = base::do_decimal_point();
5870 if (*lc->mon_thousands_sep)
5871 __thousands_sep_ = *lc->mon_thousands_sep;
5872 else
5873 __thousands_sep_ = base::do_thousands_sep();
5874 __grouping_ = lc->mon_grouping;
5875 __curr_symbol_ = lc->int_curr_symbol;
5876 if (lc->int_frac_digits != CHAR_MAX)
5877 __frac_digits_ = lc->int_frac_digits;
5878 else
5879 __frac_digits_ = base::do_frac_digits();
5880 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5881 if (lc->p_sign_posn == 0)
5882 #else // _LIBCPP_MSVCRT
5883 if (lc->int_p_sign_posn == 0)
5884 #endif // !_LIBCPP_MSVCRT
5885 __positive_sign_ = "()";
5886 else
5887 __positive_sign_ = lc->positive_sign;
5888 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5889 if(lc->n_sign_posn == 0)
5890 #else // _LIBCPP_MSVCRT
5891 if (lc->int_n_sign_posn == 0)
5892 #endif // !_LIBCPP_MSVCRT
5893 __negative_sign_ = "()";
5894 else
5895 __negative_sign_ = lc->negative_sign;
5896 // Assume the positive and negative formats will want spaces in
5897 // the same places in curr_symbol since there's no way to
5898 // represent anything else.
5899 string_type __dummy_curr_symbol = __curr_symbol_;
5900 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5901 __init_pat(__pos_format_, __dummy_curr_symbol, true,
5902 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5903 __init_pat(__neg_format_, __curr_symbol_, true,
5904 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5905 #else // _LIBCPP_MSVCRT
5906 __init_pat(__pos_format_, __dummy_curr_symbol, true,
5907 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
5908 lc->int_p_sign_posn, ' ');
5909 __init_pat(__neg_format_, __curr_symbol_, true,
5910 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
5911 lc->int_n_sign_posn, ' ');
5912 #endif // !_LIBCPP_MSVCRT
5913 }
5914
5915 template<>
5916 void
init(const char * nm)5917 moneypunct_byname<wchar_t, false>::init(const char* nm)
5918 {
5919 typedef moneypunct<wchar_t, false> base;
5920 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5921 #ifndef _LIBCPP_NO_EXCEPTIONS
5922 if (loc == nullptr)
5923 throw runtime_error("moneypunct_byname"
5924 " failed to construct for " + string(nm));
5925 #endif // _LIBCPP_NO_EXCEPTIONS
5926 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5927 lconv* lc = localeconv_l(loc.get());
5928 #else
5929 lconv* lc = __localeconv_l(loc.get());
5930 #endif
5931 if (*lc->mon_decimal_point)
5932 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
5933 else
5934 __decimal_point_ = base::do_decimal_point();
5935 if (*lc->mon_thousands_sep)
5936 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
5937 else
5938 __thousands_sep_ = base::do_thousands_sep();
5939 __grouping_ = lc->mon_grouping;
5940 wchar_t wbuf[100];
5941 mbstate_t mb = {0};
5942 const char* bb = lc->currency_symbol;
5943 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5944 size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5945 #else
5946 size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5947 #endif
5948 if (j == size_t(-1))
5949 __throw_runtime_error("locale not supported");
5950 wchar_t* wbe = wbuf + j;
5951 __curr_symbol_.assign(wbuf, wbe);
5952 if (lc->frac_digits != CHAR_MAX)
5953 __frac_digits_ = lc->frac_digits;
5954 else
5955 __frac_digits_ = base::do_frac_digits();
5956 if (lc->p_sign_posn == 0)
5957 __positive_sign_ = L"()";
5958 else
5959 {
5960 mb = mbstate_t();
5961 bb = lc->positive_sign;
5962 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5963 j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5964 #else
5965 j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5966 #endif
5967 if (j == size_t(-1))
5968 __throw_runtime_error("locale not supported");
5969 wbe = wbuf + j;
5970 __positive_sign_.assign(wbuf, wbe);
5971 }
5972 if (lc->n_sign_posn == 0)
5973 __negative_sign_ = L"()";
5974 else
5975 {
5976 mb = mbstate_t();
5977 bb = lc->negative_sign;
5978 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5979 j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5980 #else
5981 j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5982 #endif
5983 if (j == size_t(-1))
5984 __throw_runtime_error("locale not supported");
5985 wbe = wbuf + j;
5986 __negative_sign_.assign(wbuf, wbe);
5987 }
5988 // Assume the positive and negative formats will want spaces in
5989 // the same places in curr_symbol since there's no way to
5990 // represent anything else.
5991 string_type __dummy_curr_symbol = __curr_symbol_;
5992 __init_pat(__pos_format_, __dummy_curr_symbol, false,
5993 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
5994 __init_pat(__neg_format_, __curr_symbol_, false,
5995 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
5996 }
5997
5998 template<>
5999 void
init(const char * nm)6000 moneypunct_byname<wchar_t, true>::init(const char* nm)
6001 {
6002 typedef moneypunct<wchar_t, true> base;
6003 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
6004 #ifndef _LIBCPP_NO_EXCEPTIONS
6005 if (loc == nullptr)
6006 throw runtime_error("moneypunct_byname"
6007 " failed to construct for " + string(nm));
6008 #endif // _LIBCPP_NO_EXCEPTIONS
6009 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
6010 lconv* lc = localeconv_l(loc.get());
6011 #else
6012 lconv* lc = __localeconv_l(loc.get());
6013 #endif
6014 if (*lc->mon_decimal_point)
6015 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
6016 else
6017 __decimal_point_ = base::do_decimal_point();
6018 if (*lc->mon_thousands_sep)
6019 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
6020 else
6021 __thousands_sep_ = base::do_thousands_sep();
6022 __grouping_ = lc->mon_grouping;
6023 wchar_t wbuf[100];
6024 mbstate_t mb = {0};
6025 const char* bb = lc->int_curr_symbol;
6026 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
6027 size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6028 #else
6029 size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6030 #endif
6031 if (j == size_t(-1))
6032 __throw_runtime_error("locale not supported");
6033 wchar_t* wbe = wbuf + j;
6034 __curr_symbol_.assign(wbuf, wbe);
6035 if (lc->int_frac_digits != CHAR_MAX)
6036 __frac_digits_ = lc->int_frac_digits;
6037 else
6038 __frac_digits_ = base::do_frac_digits();
6039 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6040 if (lc->p_sign_posn == 0)
6041 #else // _LIBCPP_MSVCRT
6042 if (lc->int_p_sign_posn == 0)
6043 #endif // !_LIBCPP_MSVCRT
6044 __positive_sign_ = L"()";
6045 else
6046 {
6047 mb = mbstate_t();
6048 bb = lc->positive_sign;
6049 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
6050 j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6051 #else
6052 j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6053 #endif
6054 if (j == size_t(-1))
6055 __throw_runtime_error("locale not supported");
6056 wbe = wbuf + j;
6057 __positive_sign_.assign(wbuf, wbe);
6058 }
6059 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6060 if (lc->n_sign_posn == 0)
6061 #else // _LIBCPP_MSVCRT
6062 if (lc->int_n_sign_posn == 0)
6063 #endif // !_LIBCPP_MSVCRT
6064 __negative_sign_ = L"()";
6065 else
6066 {
6067 mb = mbstate_t();
6068 bb = lc->negative_sign;
6069 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
6070 j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6071 #else
6072 j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6073 #endif
6074 if (j == size_t(-1))
6075 __throw_runtime_error("locale not supported");
6076 wbe = wbuf + j;
6077 __negative_sign_.assign(wbuf, wbe);
6078 }
6079 // Assume the positive and negative formats will want spaces in
6080 // the same places in curr_symbol since there's no way to
6081 // represent anything else.
6082 string_type __dummy_curr_symbol = __curr_symbol_;
6083 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6084 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6085 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6086 __init_pat(__neg_format_, __curr_symbol_, true,
6087 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6088 #else // _LIBCPP_MSVCRT
6089 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6090 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6091 lc->int_p_sign_posn, L' ');
6092 __init_pat(__neg_format_, __curr_symbol_, true,
6093 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6094 lc->int_n_sign_posn, L' ');
6095 #endif // !_LIBCPP_MSVCRT
6096 }
6097
__do_nothing(void *)6098 void __do_nothing(void*) {}
6099
__throw_runtime_error(const char * msg)6100 void __throw_runtime_error(const char* msg)
6101 {
6102 #ifndef _LIBCPP_NO_EXCEPTIONS
6103 throw runtime_error(msg);
6104 #else
6105 (void)msg;
6106 #endif
6107 }
6108
6109 template class collate<char>;
6110 template class collate<wchar_t>;
6111
6112 template class num_get<char>;
6113 template class num_get<wchar_t>;
6114
6115 template struct __num_get<char>;
6116 template struct __num_get<wchar_t>;
6117
6118 template class num_put<char>;
6119 template class num_put<wchar_t>;
6120
6121 template struct __num_put<char>;
6122 template struct __num_put<wchar_t>;
6123
6124 template class time_get<char>;
6125 template class time_get<wchar_t>;
6126
6127 template class time_get_byname<char>;
6128 template class time_get_byname<wchar_t>;
6129
6130 template class time_put<char>;
6131 template class time_put<wchar_t>;
6132
6133 template class time_put_byname<char>;
6134 template class time_put_byname<wchar_t>;
6135
6136 template class moneypunct<char, false>;
6137 template class moneypunct<char, true>;
6138 template class moneypunct<wchar_t, false>;
6139 template class moneypunct<wchar_t, true>;
6140
6141 template class moneypunct_byname<char, false>;
6142 template class moneypunct_byname<char, true>;
6143 template class moneypunct_byname<wchar_t, false>;
6144 template class moneypunct_byname<wchar_t, true>;
6145
6146 template class money_get<char>;
6147 template class money_get<wchar_t>;
6148
6149 template class __money_get<char>;
6150 template class __money_get<wchar_t>;
6151
6152 template class money_put<char>;
6153 template class money_put<wchar_t>;
6154
6155 template class __money_put<char>;
6156 template class __money_put<wchar_t>;
6157
6158 template class messages<char>;
6159 template class messages<wchar_t>;
6160
6161 template class messages_byname<char>;
6162 template class messages_byname<wchar_t>;
6163
6164 template class codecvt_byname<char, char, mbstate_t>;
6165 template class codecvt_byname<wchar_t, char, mbstate_t>;
6166 template class codecvt_byname<char16_t, char, mbstate_t>;
6167 template class codecvt_byname<char32_t, char, mbstate_t>;
6168
6169 template class __vector_base_common<true>;
6170
6171 _LIBCPP_END_NAMESPACE_STD
6172