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