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