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