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