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