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