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