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