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