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