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