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