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