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