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