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