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