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