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