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 size_t(-1): 1413 frm_nxt = frm; 1414 return error; 1415 case size_t(-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 size_t(-1): 1519 case size_t(-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 #pragma clang diagnostic ignored "-Wmissing-field-initializers" 4551 4552 template <> 4553 string 4554 __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct) 4555 { 4556 tm t = {0}; 4557 t.tm_sec = 59; 4558 t.tm_min = 55; 4559 t.tm_hour = 23; 4560 t.tm_mday = 31; 4561 t.tm_mon = 11; 4562 t.tm_year = 161; 4563 t.tm_wday = 6; 4564 t.tm_yday = 364; 4565 t.tm_isdst = -1; 4566 char buf[100]; 4567 char f[3] = {0}; 4568 f[0] = '%'; 4569 f[1] = fmt; 4570 size_t n = strftime_l(buf, 100, f, &t, __loc_); 4571 char* bb = buf; 4572 char* be = buf + n; 4573 string result; 4574 while (bb != be) 4575 { 4576 if (ct.is(ctype_base::space, *bb)) 4577 { 4578 result.push_back(' '); 4579 for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb) 4580 ; 4581 continue; 4582 } 4583 char* w = bb; 4584 ios_base::iostate err = ios_base::goodbit; 4585 ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14, 4586 ct, err, false) 4587 - this->__weeks_; 4588 if (i < 14) 4589 { 4590 result.push_back('%'); 4591 if (i < 7) 4592 result.push_back('A'); 4593 else 4594 result.push_back('a'); 4595 bb = w; 4596 continue; 4597 } 4598 w = bb; 4599 i = __scan_keyword(w, be, this->__months_, this->__months_+24, 4600 ct, err, false) 4601 - this->__months_; 4602 if (i < 24) 4603 { 4604 result.push_back('%'); 4605 if (i < 12) 4606 result.push_back('B'); 4607 else 4608 result.push_back('b'); 4609 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0])) 4610 result.back() = 'm'; 4611 bb = w; 4612 continue; 4613 } 4614 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) 4615 { 4616 w = bb; 4617 i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2, 4618 ct, err, false) - this->__am_pm_; 4619 if (i < 2) 4620 { 4621 result.push_back('%'); 4622 result.push_back('p'); 4623 bb = w; 4624 continue; 4625 } 4626 } 4627 w = bb; 4628 if (ct.is(ctype_base::digit, *bb)) 4629 { 4630 switch(__get_up_to_n_digits(bb, be, err, ct, 4)) 4631 { 4632 case 6: 4633 result.push_back('%'); 4634 result.push_back('w'); 4635 break; 4636 case 7: 4637 result.push_back('%'); 4638 result.push_back('u'); 4639 break; 4640 case 11: 4641 result.push_back('%'); 4642 result.push_back('I'); 4643 break; 4644 case 12: 4645 result.push_back('%'); 4646 result.push_back('m'); 4647 break; 4648 case 23: 4649 result.push_back('%'); 4650 result.push_back('H'); 4651 break; 4652 case 31: 4653 result.push_back('%'); 4654 result.push_back('d'); 4655 break; 4656 case 55: 4657 result.push_back('%'); 4658 result.push_back('M'); 4659 break; 4660 case 59: 4661 result.push_back('%'); 4662 result.push_back('S'); 4663 break; 4664 case 61: 4665 result.push_back('%'); 4666 result.push_back('y'); 4667 break; 4668 case 364: 4669 result.push_back('%'); 4670 result.push_back('j'); 4671 break; 4672 case 2061: 4673 result.push_back('%'); 4674 result.push_back('Y'); 4675 break; 4676 default: 4677 for (; w != bb; ++w) 4678 result.push_back(*w); 4679 break; 4680 } 4681 continue; 4682 } 4683 if (*bb == '%') 4684 { 4685 result.push_back('%'); 4686 result.push_back('%'); 4687 ++bb; 4688 continue; 4689 } 4690 result.push_back(*bb); 4691 ++bb; 4692 } 4693 return result; 4694 } 4695 4696 #pragma clang diagnostic ignored "-Wmissing-braces" 4697 4698 template <> 4699 wstring 4700 __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct) 4701 { 4702 tm t = {0}; 4703 t.tm_sec = 59; 4704 t.tm_min = 55; 4705 t.tm_hour = 23; 4706 t.tm_mday = 31; 4707 t.tm_mon = 11; 4708 t.tm_year = 161; 4709 t.tm_wday = 6; 4710 t.tm_yday = 364; 4711 t.tm_isdst = -1; 4712 char buf[100]; 4713 char f[3] = {0}; 4714 f[0] = '%'; 4715 f[1] = fmt; 4716 strftime_l(buf, 100, f, &t, __loc_); 4717 wchar_t wbuf[100]; 4718 wchar_t* wbb = wbuf; 4719 mbstate_t mb = {0}; 4720 const char* bb = buf; 4721 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4722 size_t j = mbsrtowcs_l( wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); 4723 #else 4724 size_t j = __mbsrtowcs_l( wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); 4725 #endif 4726 if (j == size_t(-1)) 4727 __throw_runtime_error("locale not supported"); 4728 wchar_t* wbe = wbb + j; 4729 wstring result; 4730 while (wbb != wbe) 4731 { 4732 if (ct.is(ctype_base::space, *wbb)) 4733 { 4734 result.push_back(L' '); 4735 for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb) 4736 ; 4737 continue; 4738 } 4739 wchar_t* w = wbb; 4740 ios_base::iostate err = ios_base::goodbit; 4741 ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14, 4742 ct, err, false) 4743 - this->__weeks_; 4744 if (i < 14) 4745 { 4746 result.push_back(L'%'); 4747 if (i < 7) 4748 result.push_back(L'A'); 4749 else 4750 result.push_back(L'a'); 4751 wbb = w; 4752 continue; 4753 } 4754 w = wbb; 4755 i = __scan_keyword(w, wbe, this->__months_, this->__months_+24, 4756 ct, err, false) 4757 - this->__months_; 4758 if (i < 24) 4759 { 4760 result.push_back(L'%'); 4761 if (i < 12) 4762 result.push_back(L'B'); 4763 else 4764 result.push_back(L'b'); 4765 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0])) 4766 result.back() = L'm'; 4767 wbb = w; 4768 continue; 4769 } 4770 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) 4771 { 4772 w = wbb; 4773 i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2, 4774 ct, err, false) - this->__am_pm_; 4775 if (i < 2) 4776 { 4777 result.push_back(L'%'); 4778 result.push_back(L'p'); 4779 wbb = w; 4780 continue; 4781 } 4782 } 4783 w = wbb; 4784 if (ct.is(ctype_base::digit, *wbb)) 4785 { 4786 switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4)) 4787 { 4788 case 6: 4789 result.push_back(L'%'); 4790 result.push_back(L'w'); 4791 break; 4792 case 7: 4793 result.push_back(L'%'); 4794 result.push_back(L'u'); 4795 break; 4796 case 11: 4797 result.push_back(L'%'); 4798 result.push_back(L'I'); 4799 break; 4800 case 12: 4801 result.push_back(L'%'); 4802 result.push_back(L'm'); 4803 break; 4804 case 23: 4805 result.push_back(L'%'); 4806 result.push_back(L'H'); 4807 break; 4808 case 31: 4809 result.push_back(L'%'); 4810 result.push_back(L'd'); 4811 break; 4812 case 55: 4813 result.push_back(L'%'); 4814 result.push_back(L'M'); 4815 break; 4816 case 59: 4817 result.push_back(L'%'); 4818 result.push_back(L'S'); 4819 break; 4820 case 61: 4821 result.push_back(L'%'); 4822 result.push_back(L'y'); 4823 break; 4824 case 364: 4825 result.push_back(L'%'); 4826 result.push_back(L'j'); 4827 break; 4828 case 2061: 4829 result.push_back(L'%'); 4830 result.push_back(L'Y'); 4831 break; 4832 default: 4833 for (; w != wbb; ++w) 4834 result.push_back(*w); 4835 break; 4836 } 4837 continue; 4838 } 4839 if (ct.narrow(*wbb, 0) == '%') 4840 { 4841 result.push_back(L'%'); 4842 result.push_back(L'%'); 4843 ++wbb; 4844 continue; 4845 } 4846 result.push_back(*wbb); 4847 ++wbb; 4848 } 4849 return result; 4850 } 4851 4852 template <> 4853 void 4854 __time_get_storage<char>::init(const ctype<char>& ct) 4855 { 4856 tm t; 4857 char buf[100]; 4858 // __weeks_ 4859 for (int i = 0; i < 7; ++i) 4860 { 4861 t.tm_wday = i; 4862 strftime_l(buf, 100, "%A", &t, __loc_); 4863 __weeks_[i] = buf; 4864 strftime_l(buf, 100, "%a", &t, __loc_); 4865 __weeks_[i+7] = buf; 4866 } 4867 // __months_ 4868 for (int i = 0; i < 12; ++i) 4869 { 4870 t.tm_mon = i; 4871 strftime_l(buf, 100, "%B", &t, __loc_); 4872 __months_[i] = buf; 4873 strftime_l(buf, 100, "%b", &t, __loc_); 4874 __months_[i+12] = buf; 4875 } 4876 // __am_pm_ 4877 t.tm_hour = 1; 4878 strftime_l(buf, 100, "%p", &t, __loc_); 4879 __am_pm_[0] = buf; 4880 t.tm_hour = 13; 4881 strftime_l(buf, 100, "%p", &t, __loc_); 4882 __am_pm_[1] = buf; 4883 __c_ = __analyze('c', ct); 4884 __r_ = __analyze('r', ct); 4885 __x_ = __analyze('x', ct); 4886 __X_ = __analyze('X', ct); 4887 } 4888 4889 template <> 4890 void 4891 __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) 4892 { 4893 tm t = {0}; 4894 char buf[100]; 4895 size_t be; 4896 wchar_t wbuf[100]; 4897 wchar_t* wbe; 4898 mbstate_t mb = {0}; 4899 // __weeks_ 4900 for (int i = 0; i < 7; ++i) 4901 { 4902 t.tm_wday = i; 4903 be = strftime_l(buf, 100, "%A", &t, __loc_); 4904 mb = mbstate_t(); 4905 const char* bb = buf; 4906 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4907 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); 4908 #else 4909 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); 4910 #endif 4911 if (j == size_t(-1)) 4912 __throw_runtime_error("locale not supported"); 4913 wbe = wbuf + j; 4914 __weeks_[i].assign(wbuf, wbe); 4915 be = strftime_l(buf, 100, "%a", &t, __loc_); 4916 mb = mbstate_t(); 4917 bb = buf; 4918 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4919 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); 4920 #else 4921 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); 4922 #endif 4923 if (j == size_t(-1)) 4924 __throw_runtime_error("locale not supported"); 4925 wbe = wbuf + j; 4926 __weeks_[i+7].assign(wbuf, wbe); 4927 } 4928 // __months_ 4929 for (int i = 0; i < 12; ++i) 4930 { 4931 t.tm_mon = i; 4932 be = strftime_l(buf, 100, "%B", &t, __loc_); 4933 mb = mbstate_t(); 4934 const char* bb = buf; 4935 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4936 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); 4937 #else 4938 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); 4939 #endif 4940 if (j == size_t(-1)) 4941 __throw_runtime_error("locale not supported"); 4942 wbe = wbuf + j; 4943 __months_[i].assign(wbuf, wbe); 4944 be = strftime_l(buf, 100, "%b", &t, __loc_); 4945 mb = mbstate_t(); 4946 bb = buf; 4947 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4948 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); 4949 #else 4950 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); 4951 #endif 4952 if (j == size_t(-1)) 4953 __throw_runtime_error("locale not supported"); 4954 wbe = wbuf + j; 4955 __months_[i+12].assign(wbuf, wbe); 4956 } 4957 // __am_pm_ 4958 t.tm_hour = 1; 4959 be = strftime_l(buf, 100, "%p", &t, __loc_); 4960 mb = mbstate_t(); 4961 const char* bb = buf; 4962 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4963 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); 4964 #else 4965 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); 4966 #endif 4967 if (j == size_t(-1)) 4968 __throw_runtime_error("locale not supported"); 4969 wbe = wbuf + j; 4970 __am_pm_[0].assign(wbuf, wbe); 4971 t.tm_hour = 13; 4972 be = strftime_l(buf, 100, "%p", &t, __loc_); 4973 mb = mbstate_t(); 4974 bb = buf; 4975 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4976 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); 4977 #else 4978 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); 4979 #endif 4980 if (j == size_t(-1)) 4981 __throw_runtime_error("locale not supported"); 4982 wbe = wbuf + j; 4983 __am_pm_[1].assign(wbuf, wbe); 4984 __c_ = __analyze('c', ct); 4985 __r_ = __analyze('r', ct); 4986 __x_ = __analyze('x', ct); 4987 __X_ = __analyze('X', ct); 4988 } 4989 4990 template <class CharT> 4991 struct _LIBCPP_HIDDEN __time_get_temp 4992 : public ctype_byname<CharT> 4993 { 4994 explicit __time_get_temp(const char* nm) 4995 : ctype_byname<CharT>(nm, 1) {} 4996 explicit __time_get_temp(const string& nm) 4997 : ctype_byname<CharT>(nm, 1) {} 4998 }; 4999 5000 template <> 5001 __time_get_storage<char>::__time_get_storage(const char* __nm) 5002 : __time_get(__nm) 5003 { 5004 const __time_get_temp<char> ct(__nm); 5005 init(ct); 5006 } 5007 5008 template <> 5009 __time_get_storage<char>::__time_get_storage(const string& __nm) 5010 : __time_get(__nm) 5011 { 5012 const __time_get_temp<char> ct(__nm); 5013 init(ct); 5014 } 5015 5016 template <> 5017 __time_get_storage<wchar_t>::__time_get_storage(const char* __nm) 5018 : __time_get(__nm) 5019 { 5020 const __time_get_temp<wchar_t> ct(__nm); 5021 init(ct); 5022 } 5023 5024 template <> 5025 __time_get_storage<wchar_t>::__time_get_storage(const string& __nm) 5026 : __time_get(__nm) 5027 { 5028 const __time_get_temp<wchar_t> ct(__nm); 5029 init(ct); 5030 } 5031 5032 template <> 5033 time_base::dateorder 5034 __time_get_storage<char>::__do_date_order() const 5035 { 5036 unsigned i; 5037 for (i = 0; i < __x_.size(); ++i) 5038 if (__x_[i] == '%') 5039 break; 5040 ++i; 5041 switch (__x_[i]) 5042 { 5043 case 'y': 5044 case 'Y': 5045 for (++i; i < __x_.size(); ++i) 5046 if (__x_[i] == '%') 5047 break; 5048 if (i == __x_.size()) 5049 break; 5050 ++i; 5051 switch (__x_[i]) 5052 { 5053 case 'm': 5054 for (++i; i < __x_.size(); ++i) 5055 if (__x_[i] == '%') 5056 break; 5057 if (i == __x_.size()) 5058 break; 5059 ++i; 5060 if (__x_[i] == 'd') 5061 return time_base::ymd; 5062 break; 5063 case 'd': 5064 for (++i; i < __x_.size(); ++i) 5065 if (__x_[i] == '%') 5066 break; 5067 if (i == __x_.size()) 5068 break; 5069 ++i; 5070 if (__x_[i] == 'm') 5071 return time_base::ydm; 5072 break; 5073 } 5074 break; 5075 case 'm': 5076 for (++i; i < __x_.size(); ++i) 5077 if (__x_[i] == '%') 5078 break; 5079 if (i == __x_.size()) 5080 break; 5081 ++i; 5082 if (__x_[i] == 'd') 5083 { 5084 for (++i; i < __x_.size(); ++i) 5085 if (__x_[i] == '%') 5086 break; 5087 if (i == __x_.size()) 5088 break; 5089 ++i; 5090 if (__x_[i] == 'y' || __x_[i] == 'Y') 5091 return time_base::mdy; 5092 break; 5093 } 5094 break; 5095 case 'd': 5096 for (++i; i < __x_.size(); ++i) 5097 if (__x_[i] == '%') 5098 break; 5099 if (i == __x_.size()) 5100 break; 5101 ++i; 5102 if (__x_[i] == 'm') 5103 { 5104 for (++i; i < __x_.size(); ++i) 5105 if (__x_[i] == '%') 5106 break; 5107 if (i == __x_.size()) 5108 break; 5109 ++i; 5110 if (__x_[i] == 'y' || __x_[i] == 'Y') 5111 return time_base::dmy; 5112 break; 5113 } 5114 break; 5115 } 5116 return time_base::no_order; 5117 } 5118 5119 template <> 5120 time_base::dateorder 5121 __time_get_storage<wchar_t>::__do_date_order() const 5122 { 5123 unsigned i; 5124 for (i = 0; i < __x_.size(); ++i) 5125 if (__x_[i] == L'%') 5126 break; 5127 ++i; 5128 switch (__x_[i]) 5129 { 5130 case L'y': 5131 case L'Y': 5132 for (++i; i < __x_.size(); ++i) 5133 if (__x_[i] == L'%') 5134 break; 5135 if (i == __x_.size()) 5136 break; 5137 ++i; 5138 switch (__x_[i]) 5139 { 5140 case L'm': 5141 for (++i; i < __x_.size(); ++i) 5142 if (__x_[i] == L'%') 5143 break; 5144 if (i == __x_.size()) 5145 break; 5146 ++i; 5147 if (__x_[i] == L'd') 5148 return time_base::ymd; 5149 break; 5150 case L'd': 5151 for (++i; i < __x_.size(); ++i) 5152 if (__x_[i] == L'%') 5153 break; 5154 if (i == __x_.size()) 5155 break; 5156 ++i; 5157 if (__x_[i] == L'm') 5158 return time_base::ydm; 5159 break; 5160 } 5161 break; 5162 case L'm': 5163 for (++i; i < __x_.size(); ++i) 5164 if (__x_[i] == L'%') 5165 break; 5166 if (i == __x_.size()) 5167 break; 5168 ++i; 5169 if (__x_[i] == L'd') 5170 { 5171 for (++i; i < __x_.size(); ++i) 5172 if (__x_[i] == L'%') 5173 break; 5174 if (i == __x_.size()) 5175 break; 5176 ++i; 5177 if (__x_[i] == L'y' || __x_[i] == L'Y') 5178 return time_base::mdy; 5179 break; 5180 } 5181 break; 5182 case L'd': 5183 for (++i; i < __x_.size(); ++i) 5184 if (__x_[i] == L'%') 5185 break; 5186 if (i == __x_.size()) 5187 break; 5188 ++i; 5189 if (__x_[i] == L'm') 5190 { 5191 for (++i; i < __x_.size(); ++i) 5192 if (__x_[i] == L'%') 5193 break; 5194 if (i == __x_.size()) 5195 break; 5196 ++i; 5197 if (__x_[i] == L'y' || __x_[i] == L'Y') 5198 return time_base::dmy; 5199 break; 5200 } 5201 break; 5202 } 5203 return time_base::no_order; 5204 } 5205 5206 // time_put 5207 5208 __time_put::__time_put(const char* nm) 5209 : __loc_(newlocale(LC_ALL_MASK, nm, 0)) 5210 { 5211 #ifndef _LIBCPP_NO_EXCEPTIONS 5212 if (__loc_ == 0) 5213 throw runtime_error("time_put_byname" 5214 " failed to construct for " + string(nm)); 5215 #endif // _LIBCPP_NO_EXCEPTIONS 5216 } 5217 5218 __time_put::__time_put(const string& nm) 5219 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) 5220 { 5221 #ifndef _LIBCPP_NO_EXCEPTIONS 5222 if (__loc_ == 0) 5223 throw runtime_error("time_put_byname" 5224 " failed to construct for " + nm); 5225 #endif // _LIBCPP_NO_EXCEPTIONS 5226 } 5227 5228 __time_put::~__time_put() 5229 { 5230 if (__loc_) 5231 freelocale(__loc_); 5232 } 5233 5234 void 5235 __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm, 5236 char __fmt, char __mod) const 5237 { 5238 char fmt[] = {'%', __fmt, __mod, 0}; 5239 if (__mod != 0) 5240 swap(fmt[1], fmt[2]); 5241 size_t n = strftime_l(__nb, static_cast<size_t>(__ne-__nb), fmt, __tm, __loc_); 5242 __ne = __nb + n; 5243 } 5244 5245 void 5246 __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, 5247 char __fmt, char __mod) const 5248 { 5249 char __nar[100]; 5250 char* __ne = __nar + 100; 5251 __do_put(__nar, __ne, __tm, __fmt, __mod); 5252 mbstate_t mb = {0}; 5253 const char* __nb = __nar; 5254 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5255 size_t j = mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_); 5256 #else 5257 size_t j = __mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_); 5258 #endif 5259 if (j == size_t(-1)) 5260 __throw_runtime_error("locale not supported"); 5261 __we = __wb + j; 5262 } 5263 5264 // moneypunct_byname 5265 5266 static 5267 void 5268 __init_pat(money_base::pattern& pat, char cs_precedes, char sep_by_space, char sign_posn) 5269 { 5270 const char sign = static_cast<char>(money_base::sign); 5271 const char space = static_cast<char>(money_base::space); 5272 const char none = static_cast<char>(money_base::none); 5273 const char symbol = static_cast<char>(money_base::symbol); 5274 const char value = static_cast<char>(money_base::value); 5275 switch (cs_precedes) 5276 { 5277 case 0: 5278 switch (sign_posn) 5279 { 5280 case 0: 5281 pat.field[0] = sign; 5282 pat.field[1] = value; 5283 pat.field[3] = symbol; 5284 switch (sep_by_space) 5285 { 5286 case 0: 5287 pat.field[2] = none; 5288 return; 5289 case 1: 5290 case 2: 5291 pat.field[2] = space; 5292 return; 5293 default: 5294 break; 5295 } 5296 break; 5297 case 1: 5298 pat.field[0] = sign; 5299 pat.field[3] = symbol; 5300 switch (sep_by_space) 5301 { 5302 case 0: 5303 pat.field[1] = value; 5304 pat.field[2] = none; 5305 return; 5306 case 1: 5307 pat.field[1] = value; 5308 pat.field[2] = space; 5309 return; 5310 case 2: 5311 pat.field[1] = space; 5312 pat.field[2] = value; 5313 return; 5314 default: 5315 break; 5316 } 5317 break; 5318 case 2: 5319 pat.field[0] = value; 5320 pat.field[3] = sign; 5321 switch (sep_by_space) 5322 { 5323 case 0: 5324 pat.field[1] = none; 5325 pat.field[2] = symbol; 5326 return; 5327 case 1: 5328 pat.field[1] = space; 5329 pat.field[2] = symbol; 5330 return; 5331 case 2: 5332 pat.field[1] = symbol; 5333 pat.field[2] = space; 5334 return; 5335 default: 5336 break; 5337 } 5338 break; 5339 case 3: 5340 pat.field[0] = value; 5341 pat.field[3] = symbol; 5342 switch (sep_by_space) 5343 { 5344 case 0: 5345 pat.field[1] = none; 5346 pat.field[2] = sign; 5347 return; 5348 case 1: 5349 pat.field[1] = space; 5350 pat.field[2] = sign; 5351 return; 5352 case 2: 5353 pat.field[1] = sign; 5354 pat.field[2] = space; 5355 return; 5356 default: 5357 break; 5358 } 5359 break; 5360 case 4: 5361 pat.field[0] = value; 5362 pat.field[3] = sign; 5363 switch (sep_by_space) 5364 { 5365 case 0: 5366 pat.field[1] = none; 5367 pat.field[2] = symbol; 5368 return; 5369 case 1: 5370 pat.field[1] = space; 5371 pat.field[2] = symbol; 5372 return; 5373 case 2: 5374 pat.field[1] = symbol; 5375 pat.field[2] = space; 5376 return; 5377 default: 5378 break; 5379 } 5380 break; 5381 default: 5382 break; 5383 } 5384 break; 5385 case 1: 5386 switch (sign_posn) 5387 { 5388 case 0: 5389 pat.field[0] = sign; 5390 pat.field[1] = symbol; 5391 pat.field[3] = value; 5392 switch (sep_by_space) 5393 { 5394 case 0: 5395 pat.field[2] = none; 5396 return; 5397 case 1: 5398 case 2: 5399 pat.field[2] = space; 5400 return; 5401 default: 5402 break; 5403 } 5404 break; 5405 case 1: 5406 pat.field[0] = sign; 5407 pat.field[3] = value; 5408 switch (sep_by_space) 5409 { 5410 case 0: 5411 pat.field[1] = symbol; 5412 pat.field[2] = none; 5413 return; 5414 case 1: 5415 pat.field[1] = symbol; 5416 pat.field[2] = space; 5417 return; 5418 case 2: 5419 pat.field[1] = space; 5420 pat.field[2] = symbol; 5421 return; 5422 default: 5423 break; 5424 } 5425 break; 5426 case 2: 5427 pat.field[0] = symbol; 5428 pat.field[3] = sign; 5429 switch (sep_by_space) 5430 { 5431 case 0: 5432 pat.field[1] = none; 5433 pat.field[2] = value; 5434 return; 5435 case 1: 5436 pat.field[1] = space; 5437 pat.field[2] = value; 5438 return; 5439 case 2: 5440 pat.field[1] = value; 5441 pat.field[2] = space; 5442 return; 5443 default: 5444 break; 5445 } 5446 break; 5447 case 3: 5448 pat.field[0] = sign; 5449 pat.field[3] = value; 5450 switch (sep_by_space) 5451 { 5452 case 0: 5453 pat.field[1] = symbol; 5454 pat.field[2] = none; 5455 return; 5456 case 1: 5457 pat.field[1] = symbol; 5458 pat.field[2] = space; 5459 return; 5460 case 2: 5461 pat.field[1] = space; 5462 pat.field[2] = symbol; 5463 return; 5464 default: 5465 break; 5466 } 5467 break; 5468 case 4: 5469 pat.field[0] = symbol; 5470 pat.field[3] = value; 5471 switch (sep_by_space) 5472 { 5473 case 0: 5474 pat.field[1] = sign; 5475 pat.field[2] = none; 5476 return; 5477 case 1: 5478 pat.field[1] = sign; 5479 pat.field[2] = space; 5480 return; 5481 case 2: 5482 pat.field[1] = space; 5483 pat.field[2] = sign; 5484 return; 5485 default: 5486 break; 5487 } 5488 break; 5489 default: 5490 break; 5491 } 5492 break; 5493 default: 5494 break; 5495 } 5496 pat.field[0] = symbol; 5497 pat.field[1] = sign; 5498 pat.field[2] = none; 5499 pat.field[3] = value; 5500 } 5501 5502 template<> 5503 void 5504 moneypunct_byname<char, false>::init(const char* nm) 5505 { 5506 typedef moneypunct<char, false> base; 5507 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 5508 #ifndef _LIBCPP_NO_EXCEPTIONS 5509 if (loc == 0) 5510 throw runtime_error("moneypunct_byname" 5511 " failed to construct for " + string(nm)); 5512 #endif // _LIBCPP_NO_EXCEPTIONS 5513 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5514 lconv* lc = localeconv_l(loc.get()); 5515 #else 5516 lconv* lc = __localeconv_l(loc.get()); 5517 #endif 5518 if (*lc->mon_decimal_point) 5519 __decimal_point_ = *lc->mon_decimal_point; 5520 else 5521 __decimal_point_ = base::do_decimal_point(); 5522 if (*lc->mon_thousands_sep) 5523 __thousands_sep_ = *lc->mon_thousands_sep; 5524 else 5525 __thousands_sep_ = base::do_thousands_sep(); 5526 __grouping_ = lc->mon_grouping; 5527 __curr_symbol_ = lc->currency_symbol; 5528 if (lc->frac_digits != CHAR_MAX) 5529 __frac_digits_ = lc->frac_digits; 5530 else 5531 __frac_digits_ = base::do_frac_digits(); 5532 if (lc->p_sign_posn == 0) 5533 __positive_sign_ = "()"; 5534 else 5535 __positive_sign_ = lc->positive_sign; 5536 if (lc->n_sign_posn == 0) 5537 __negative_sign_ = "()"; 5538 else 5539 __negative_sign_ = lc->negative_sign; 5540 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn); 5541 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn); 5542 } 5543 5544 template<> 5545 void 5546 moneypunct_byname<char, true>::init(const char* nm) 5547 { 5548 typedef moneypunct<char, true> base; 5549 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 5550 #ifndef _LIBCPP_NO_EXCEPTIONS 5551 if (loc == 0) 5552 throw runtime_error("moneypunct_byname" 5553 " failed to construct for " + string(nm)); 5554 #endif // _LIBCPP_NO_EXCEPTIONS 5555 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5556 lconv* lc = localeconv_l(loc.get()); 5557 #else 5558 lconv* lc = __localeconv_l(loc.get()); 5559 #endif 5560 if (*lc->mon_decimal_point) 5561 __decimal_point_ = *lc->mon_decimal_point; 5562 else 5563 __decimal_point_ = base::do_decimal_point(); 5564 if (*lc->mon_thousands_sep) 5565 __thousands_sep_ = *lc->mon_thousands_sep; 5566 else 5567 __thousands_sep_ = base::do_thousands_sep(); 5568 __grouping_ = lc->mon_grouping; 5569 __curr_symbol_ = lc->int_curr_symbol; 5570 if (lc->int_frac_digits != CHAR_MAX) 5571 __frac_digits_ = lc->int_frac_digits; 5572 else 5573 __frac_digits_ = base::do_frac_digits(); 5574 #if _WIN32 5575 if (lc->p_sign_posn == 0) 5576 #else // _WIN32 5577 if (lc->int_p_sign_posn == 0) 5578 #endif //_WIN32 5579 __positive_sign_ = "()"; 5580 else 5581 __positive_sign_ = lc->positive_sign; 5582 #if _WIN32 5583 if(lc->n_sign_posn == 0) 5584 #else // _WIN32 5585 if (lc->int_n_sign_posn == 0) 5586 #endif // _WIN32 5587 __negative_sign_ = "()"; 5588 else 5589 __negative_sign_ = lc->negative_sign; 5590 #if _WIN32 5591 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn); 5592 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn); 5593 #else 5594 __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn); 5595 __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn); 5596 #endif // _WIN32 5597 } 5598 5599 template<> 5600 void 5601 moneypunct_byname<wchar_t, false>::init(const char* nm) 5602 { 5603 typedef moneypunct<wchar_t, false> base; 5604 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 5605 #ifndef _LIBCPP_NO_EXCEPTIONS 5606 if (loc == 0) 5607 throw runtime_error("moneypunct_byname" 5608 " failed to construct for " + string(nm)); 5609 #endif // _LIBCPP_NO_EXCEPTIONS 5610 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5611 lconv* lc = localeconv_l(loc.get()); 5612 #else 5613 lconv* lc = __localeconv_l(loc.get()); 5614 #endif 5615 if (*lc->mon_decimal_point) 5616 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point); 5617 else 5618 __decimal_point_ = base::do_decimal_point(); 5619 if (*lc->mon_thousands_sep) 5620 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep); 5621 else 5622 __thousands_sep_ = base::do_thousands_sep(); 5623 __grouping_ = lc->mon_grouping; 5624 wchar_t wbuf[100]; 5625 mbstate_t mb = {0}; 5626 const char* bb = lc->currency_symbol; 5627 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5628 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); 5629 #else 5630 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); 5631 #endif 5632 if (j == size_t(-1)) 5633 __throw_runtime_error("locale not supported"); 5634 wchar_t* wbe = wbuf + j; 5635 __curr_symbol_.assign(wbuf, wbe); 5636 if (lc->frac_digits != CHAR_MAX) 5637 __frac_digits_ = lc->frac_digits; 5638 else 5639 __frac_digits_ = base::do_frac_digits(); 5640 if (lc->p_sign_posn == 0) 5641 __positive_sign_ = L"()"; 5642 else 5643 { 5644 mb = mbstate_t(); 5645 bb = lc->positive_sign; 5646 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5647 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); 5648 #else 5649 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); 5650 #endif 5651 if (j == size_t(-1)) 5652 __throw_runtime_error("locale not supported"); 5653 wbe = wbuf + j; 5654 __positive_sign_.assign(wbuf, wbe); 5655 } 5656 if (lc->n_sign_posn == 0) 5657 __negative_sign_ = L"()"; 5658 else 5659 { 5660 mb = mbstate_t(); 5661 bb = lc->negative_sign; 5662 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5663 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); 5664 #else 5665 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); 5666 #endif 5667 if (j == size_t(-1)) 5668 __throw_runtime_error("locale not supported"); 5669 wbe = wbuf + j; 5670 __negative_sign_.assign(wbuf, wbe); 5671 } 5672 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn); 5673 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn); 5674 } 5675 5676 template<> 5677 void 5678 moneypunct_byname<wchar_t, true>::init(const char* nm) 5679 { 5680 typedef moneypunct<wchar_t, true> base; 5681 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 5682 #ifndef _LIBCPP_NO_EXCEPTIONS 5683 if (loc == 0) 5684 throw runtime_error("moneypunct_byname" 5685 " failed to construct for " + string(nm)); 5686 #endif // _LIBCPP_NO_EXCEPTIONS 5687 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5688 lconv* lc = localeconv_l(loc.get()); 5689 #else 5690 lconv* lc = __localeconv_l(loc.get()); 5691 #endif 5692 if (*lc->mon_decimal_point) 5693 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point); 5694 else 5695 __decimal_point_ = base::do_decimal_point(); 5696 if (*lc->mon_thousands_sep) 5697 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep); 5698 else 5699 __thousands_sep_ = base::do_thousands_sep(); 5700 __grouping_ = lc->mon_grouping; 5701 wchar_t wbuf[100]; 5702 mbstate_t mb = {0}; 5703 const char* bb = lc->int_curr_symbol; 5704 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5705 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); 5706 #else 5707 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); 5708 #endif 5709 if (j == size_t(-1)) 5710 __throw_runtime_error("locale not supported"); 5711 wchar_t* wbe = wbuf + j; 5712 __curr_symbol_.assign(wbuf, wbe); 5713 if (lc->int_frac_digits != CHAR_MAX) 5714 __frac_digits_ = lc->int_frac_digits; 5715 else 5716 __frac_digits_ = base::do_frac_digits(); 5717 #if _WIN32 5718 if (lc->p_sign_posn == 0) 5719 #else // _WIN32 5720 if (lc->int_p_sign_posn == 0) 5721 #endif // _WIN32 5722 __positive_sign_ = L"()"; 5723 else 5724 { 5725 mb = mbstate_t(); 5726 bb = lc->positive_sign; 5727 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5728 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); 5729 #else 5730 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); 5731 #endif 5732 if (j == size_t(-1)) 5733 __throw_runtime_error("locale not supported"); 5734 wbe = wbuf + j; 5735 __positive_sign_.assign(wbuf, wbe); 5736 } 5737 #if _WIN32 5738 if (lc->n_sign_posn == 0) 5739 #else // _WIN32 5740 if (lc->int_n_sign_posn == 0) 5741 #endif // _WIN32 5742 __negative_sign_ = L"()"; 5743 else 5744 { 5745 mb = mbstate_t(); 5746 bb = lc->negative_sign; 5747 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5748 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); 5749 #else 5750 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); 5751 #endif 5752 if (j == size_t(-1)) 5753 __throw_runtime_error("locale not supported"); 5754 wbe = wbuf + j; 5755 __negative_sign_.assign(wbuf, wbe); 5756 } 5757 #if _WIN32 5758 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn); 5759 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn); 5760 #else // _WIN32 5761 __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn); 5762 __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn); 5763 #endif // _WIN32 5764 } 5765 5766 void __do_nothing(void*) {} 5767 5768 void __throw_runtime_error(const char* msg) 5769 { 5770 #ifndef _LIBCPP_NO_EXCEPTIONS 5771 throw runtime_error(msg); 5772 #endif 5773 } 5774 5775 template class collate<char>; 5776 template class collate<wchar_t>; 5777 5778 template class num_get<char>; 5779 template class num_get<wchar_t>; 5780 5781 template struct __num_get<char>; 5782 template struct __num_get<wchar_t>; 5783 5784 template class num_put<char>; 5785 template class num_put<wchar_t>; 5786 5787 template struct __num_put<char>; 5788 template struct __num_put<wchar_t>; 5789 5790 template class time_get<char>; 5791 template class time_get<wchar_t>; 5792 5793 template class time_get_byname<char>; 5794 template class time_get_byname<wchar_t>; 5795 5796 template class time_put<char>; 5797 template class time_put<wchar_t>; 5798 5799 template class time_put_byname<char>; 5800 template class time_put_byname<wchar_t>; 5801 5802 template class moneypunct<char, false>; 5803 template class moneypunct<char, true>; 5804 template class moneypunct<wchar_t, false>; 5805 template class moneypunct<wchar_t, true>; 5806 5807 template class moneypunct_byname<char, false>; 5808 template class moneypunct_byname<char, true>; 5809 template class moneypunct_byname<wchar_t, false>; 5810 template class moneypunct_byname<wchar_t, true>; 5811 5812 template class money_get<char>; 5813 template class money_get<wchar_t>; 5814 5815 template class __money_get<char>; 5816 template class __money_get<wchar_t>; 5817 5818 template class money_put<char>; 5819 template class money_put<wchar_t>; 5820 5821 template class __money_put<char>; 5822 template class __money_put<wchar_t>; 5823 5824 template class messages<char>; 5825 template class messages<wchar_t>; 5826 5827 template class messages_byname<char>; 5828 template class messages_byname<wchar_t>; 5829 5830 template class codecvt_byname<char, char, mbstate_t>; 5831 template class codecvt_byname<wchar_t, char, mbstate_t>; 5832 template class codecvt_byname<char16_t, char, mbstate_t>; 5833 template class codecvt_byname<char32_t, char, mbstate_t>; 5834 5835 template class __vector_base_common<true>; 5836 5837 _LIBCPP_END_NAMESPACE_STD 5838