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