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