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