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