30 #ifndef _LOCALE_CONV_H 31 #define _LOCALE_CONV_H 1 33 #if __cplusplus < 201103L 43 namespace std _GLIBCXX_VISIBILITY(default)
45 _GLIBCXX_BEGIN_NAMESPACE_VERSION
52 template<
typename _OutStr,
typename _InChar,
typename _Codecvt,
53 typename _State,
typename _Fn>
55 __do_str_codecvt(
const _InChar* __first,
const _InChar* __last,
56 _OutStr& __outstr,
const _Codecvt& __cvt, _State& __state,
57 size_t& __count, _Fn __fn)
59 if (__first == __last)
66 size_t __outchars = 0;
67 auto __next = __first;
68 const auto __maxlen = __cvt.max_length() + 1;
70 codecvt_base::result __result;
73 __outstr.resize(__outstr.size() + (__last - __next) * __maxlen);
74 auto __outnext = &__outstr.front() + __outchars;
75 auto const __outlast = &__outstr.back() + 1;
76 __result = (__cvt.*__fn)(__state, __next, __last, __next,
77 __outnext, __outlast, __outnext);
78 __outchars = __outnext - &__outstr.front();
80 while (__result == codecvt_base::partial && __next != __last
81 && (__outstr.size() - __outchars) < __maxlen);
83 if (__result == codecvt_base::error)
85 __count = __next - __first;
89 if (__result == codecvt_base::noconv)
91 __outstr.assign(__first, __last);
92 __count = __last - __first;
96 __outstr.resize(__outchars);
97 __count = __next - __first;
104 template<
typename _CharT,
typename _Traits,
typename _Alloc,
typename _State>
106 __str_codecvt_in(
const char* __first,
const char* __last,
107 basic_string<_CharT, _Traits, _Alloc>& __outstr,
108 const codecvt<_CharT, char, _State>& __cvt,
109 _State& __state,
size_t& __count)
111 using _Codecvt = codecvt<_CharT, char, _State>;
113 = codecvt_base::result
114 (_Codecvt::*)(_State&,
const char*,
const char*,
const char*&,
115 _CharT*, _CharT*, _CharT*&)
const;
117 return __do_str_codecvt(__first, __last, __outstr, __cvt, __state,
121 template<
typename _CharT,
typename _Traits,
typename _Alloc,
typename _State>
123 __str_codecvt_in(
const char* __first,
const char* __last,
124 basic_string<_CharT, _Traits, _Alloc>& __outstr,
125 const codecvt<_CharT, char, _State>& __cvt)
129 return __str_codecvt_in(__first, __last, __outstr, __cvt, __state, __n);
133 template<
typename _CharT,
typename _Traits,
typename _Alloc,
typename _State>
135 __str_codecvt_out(
const _CharT* __first,
const _CharT* __last,
136 basic_string<char, _Traits, _Alloc>& __outstr,
137 const codecvt<_CharT, char, _State>& __cvt,
138 _State& __state,
size_t& __count)
140 using _Codecvt = codecvt<_CharT, char, _State>;
142 = codecvt_base::result
143 (_Codecvt::*)(_State&,
const _CharT*,
const _CharT*,
const _CharT*&,
144 char*,
char*,
char*&)
const;
146 return __do_str_codecvt(__first, __last, __outstr, __cvt, __state,
150 template<
typename _CharT,
typename _Traits,
typename _Alloc,
typename _State>
152 __str_codecvt_out(
const _CharT* __first,
const _CharT* __last,
153 basic_string<char, _Traits, _Alloc>& __outstr,
154 const codecvt<_CharT, char, _State>& __cvt)
158 return __str_codecvt_out(__first, __last, __outstr, __cvt, __state, __n);
161 #ifdef _GLIBCXX_USE_WCHAR_T 163 _GLIBCXX_BEGIN_NAMESPACE_CXX11
166 template<
typename _Codecvt,
typename _Elem = wchar_t,
167 typename _Wide_alloc = allocator<_Elem>,
168 typename _Byte_alloc = allocator<char>>
174 typedef typename _Codecvt::state_type state_type;
175 typedef typename wide_string::traits_type::int_type int_type;
187 __throw_logic_error(
"wstring_convert");
199 : _M_cvt(__pcvt), _M_state(__state), _M_with_cvtstate(true)
202 __throw_logic_error(
"wstring_convert");
212 const wide_string& __wide_err = wide_string())
213 : _M_cvt(new _Codecvt),
214 _M_byte_err_string(__byte_err), _M_wide_err_string(__wide_err),
215 _M_with_strings(true)
218 __throw_logic_error(
"wstring_convert");
232 char __bytes[2] = { __byte };
243 auto __ptr = __str.
data();
250 if (!_M_with_cvtstate)
251 _M_state = state_type();
253 if (__str_codecvt_in(__first, __last, __out, *_M_cvt, _M_state,
257 return _M_wide_err_string;
258 __throw_range_error(
"wstring_convert::from_bytes");
266 _Elem __wchars[2] = { __wchar };
267 return to_bytes(__wchars, __wchars+1);
273 return to_bytes(__ptr, __ptr+wide_string::traits_type::length(__ptr));
279 auto __ptr = __wstr.
data();
284 to_bytes(
const _Elem* __first,
const _Elem* __last)
286 if (!_M_with_cvtstate)
287 _M_state = state_type();
289 if (__str_codecvt_out(__first, __last, __out, *_M_cvt, _M_state,
293 return _M_byte_err_string;
294 __throw_range_error(
"wstring_convert::to_bytes");
304 state_type
state()
const {
return _M_state; }
308 byte_string _M_byte_err_string;
309 wide_string _M_wide_err_string;
310 state_type _M_state = state_type();
312 bool _M_with_cvtstate =
false;
313 bool _M_with_strings =
false;
316 _GLIBCXX_END_NAMESPACE_CXX11
319 template<
typename _Codecvt,
typename _Elem = wchar_t,
326 typedef typename _Codecvt::state_type state_type;
338 state_type __state = state_type())
339 : _M_buf(__bytebuf), _M_cvt(__pcvt), _M_state(__state)
342 __throw_logic_error(
"wbuffer_convert");
344 _M_always_noconv = _M_cvt->always_noconv();
348 this->setp(_M_put_area, _M_put_area + _S_buffer_length);
349 this->setg(_M_get_area + _S_putback_length,
350 _M_get_area + _S_putback_length,
351 _M_get_area + _S_putback_length);
362 streambuf* rdbuf()
const noexcept {
return _M_buf; }
367 auto __prev = _M_buf;
373 state_type
state() const noexcept {
return _M_state; }
378 {
return _M_buf && _M_conv_put() && !_M_buf->pubsync() ? 0 : -1; }
383 if (!_M_buf || !_M_conv_put())
385 else if (!_Tr::eq_int_type(__out, _Tr::eof()))
386 return this->sputc(__out);
387 return _Tr::not_eof(__out);
396 if (this->gptr() < this->egptr() || (_M_buf && _M_conv_get()))
397 return _Tr::to_int_type(*this->gptr());
405 if (!_M_buf || __n == 0)
410 auto __nn = std::min<streamsize>(this->epptr() - this->pptr(),
412 _Tr::copy(this->pptr(), __s + __done, __nn);
415 }
while (__done < __n && _M_conv_put());
424 const streamsize __pb1 = this->gptr() - this->eback();
428 _Tr::move(_M_get_area + _S_putback_length - __npb,
429 this->gptr() - __npb, __npb);
431 streamsize __nbytes =
sizeof(_M_get_buf) - _M_unconv;
432 __nbytes =
std::min(__nbytes, _M_buf->in_avail());
435 __nbytes = _M_buf->sgetn(_M_get_buf + _M_unconv, __nbytes);
438 __nbytes += _M_unconv;
442 _Elem* __outbuf = _M_get_area + _S_putback_length;
443 _Elem* __outnext = __outbuf;
444 const char* __bnext = _M_get_buf;
446 codecvt_base::result __result;
447 if (_M_always_noconv)
448 __result = codecvt_base::noconv;
451 _Elem* __outend = _M_get_area + _S_buffer_length;
453 __result = _M_cvt->in(_M_state,
454 __bnext, __bnext + __nbytes, __bnext,
455 __outbuf, __outend, __outnext);
458 if (__result == codecvt_base::noconv)
461 auto __get_buf =
reinterpret_cast<const _Elem*
>(_M_get_buf);
462 _Tr::copy(__outbuf, __get_buf, __nbytes);
467 if ((_M_unconv = _M_get_buf + __nbytes - __bnext))
470 this->setg(__outbuf, __outbuf, __outnext);
472 return __result != codecvt_base::error;
483 if (_M_buf->sputn(__p, __n) < __n)
492 _Elem*
const __first = this->pbase();
493 const _Elem*
const __last = this->pptr();
494 const streamsize __pending = __last - __first;
496 if (_M_always_noconv)
497 return _M_put(__first, __pending);
499 char __outbuf[2 * _S_buffer_length];
501 const _Elem* __next = __first;
502 const _Elem* __start;
506 char* __outnext = __outbuf;
507 char*
const __outlast = __outbuf +
sizeof(__outbuf);
508 auto __result = _M_cvt->out(_M_state, __next, __last, __next,
509 __outnext, __outlast, __outnext);
510 if (__result == codecvt_base::error)
512 else if (__result == codecvt_base::noconv)
513 return _M_put(__next, __pending);
515 if (!_M_put(__outbuf, __outnext - __outbuf))
518 while (__next != __last && __next != __start);
520 if (__next != __last)
521 _Tr::move(__first, __next, __last - __next);
523 this->pbump(__first - __next);
524 return __next != __first;
531 static const streamsize _S_buffer_length = 32;
532 static const streamsize _S_putback_length = 3;
533 _Elem _M_put_area[_S_buffer_length];
534 _Elem _M_get_area[_S_buffer_length];
536 char _M_get_buf[_S_buffer_length-_S_putback_length];
537 bool _M_always_noconv;
540 #endif // _GLIBCXX_USE_WCHAR_T 544 _GLIBCXX_END_NAMESPACE_VERSION
547 #endif // __cplusplus wstring_convert(_Codecvt *__pcvt=new _Codecvt())
wbuffer_convert(streambuf *__bytebuf=0, _Codecvt *__pcvt=new _Codecvt, state_type __state=state_type())
byte_string to_bytes(const wide_string &__wstr)
Convert to bytes.
result in(state_type &__state, const extern_type *__from, const extern_type *__from_end, const extern_type *&__from_next, intern_type *__to, intern_type *__to_end, intern_type *&__to_next) const
Convert from external to internal character set.
traits_type::int_type int_type
state_type state() const
The final conversion state of the last conversion.
result out(state_type &__state, const intern_type *__from, const intern_type *__from_end, const intern_type *&__from_next, extern_type *__to, extern_type *__to_end, extern_type *&__to_next) const
Convert from internal to external character set.
const _CharT * data() const noexcept
Return const pointer to contents.
Managing sequences of characters and character-like objects.
byte_string to_bytes(const _Elem *__ptr)
Convert to bytes.
_Wide_streambuf::int_type underflow()
Fetches more data from the controlled sequence.
size_type size() const noexcept
Returns the number of characters in the string, not including any null-termination.
wide_string from_bytes(const char *__ptr)
Convert from bytes.
byte_string to_bytes(const _Elem *__first, const _Elem *__last)
Convert to bytes.
wide_string from_bytes(const byte_string &__str)
Convert from bytes.
byte_string to_bytes(_Elem __wchar)
Convert to bytes.
wstring_convert(_Codecvt *__pcvt, state_type __state)
wide_string from_bytes(char __byte)
Convert from bytes.
ISO C++ entities toplevel namespace is std.
Basis for explicit traits specializations.
_GLIBCXX14_CONSTEXPR const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
allocator_type get_allocator() const noexcept
Return copy of allocator used to construct this string.
size_t converted() const noexcept
The number of elements successfully converted in the last conversion.
The actual work of input and output (interface).
int sync()
Synchronizes the buffer arrays with the controlled sequences.
wide_string from_bytes(const char *__first, const char *__last)
Convert from bytes.
wstring_convert(const byte_string &__byte_err, const wide_string &__wide_err=wide_string())
ptrdiff_t streamsize
Integral type for I/O operation counts and buffer sizes.
state_type state() const noexcept
The conversion state following the last conversion.