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