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