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