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