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