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