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