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