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