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