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