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