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