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