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