void to_bytes_step(const std::codecvt<CvtTypes...> & cvt, typename make_to_bytes_context<std::codecvt<CvtTypes...>>::type & ctx) { ctx.res = cvt.out(ctx.state, ctx.from_beg, ctx.from_end, ctx.from_stopped, ctx.to_beg, ctx.to_end, ctx.to_stopped); if (ctx.res == std::codecvt_base::partial) { //output extern_char buffer contains cvt.max_length or more - input is partial ctx.is_partial_input = (ctx.to_stopped - ctx.to_end >= cvt.max_length()); } }
const std::basic_string<CharType> in( const std::basic_string<Byte>& external_str, const std::codecvt<CharType, Byte, mbstate_t>& codecvt) { typedef std::basic_string<CharType> wstring; typedef std::basic_string<Byte> string; typedef std::codecvt<CharType, Byte, mbstate_t> codecvt_type; typename string::size_type external_str_size = external_str.length(); const Byte* first_external = external_str.data(); const Byte* last_external = first_external + external_str_size; const Byte* next_external = last_external; wstring internal_str; // Zero initialized typename codecvt_type::state_type state; std::memset(&state, 0, sizeof(state)); typename wstring::size_type out_buf_size = static_cast<typename wstring::size_type>( codecvt.length(state, first_external, last_external, internal_str.max_size())); #if defined(MA_USE_CXX11_STDLIB_MEMORY) detail::unique_ptr<CharType[]> out_buf(new CharType[out_buf_size]); #else detail::scoped_array<CharType> out_buf(new CharType[out_buf_size]); #endif CharType* first_internal = out_buf.get(); CharType* last_internal = first_internal + out_buf_size; CharType* next_internal = first_internal; typename codecvt_type::result r = codecvt.in(state, first_external, last_external, next_external, first_internal, last_internal, next_internal); if (codecvt_type::ok == r) { internal_str.assign(first_internal, last_internal); } else if (codecvt_type::noconv == r) { internal_str.assign(reinterpret_cast<const CharType*>(first_external), reinterpret_cast<const CharType*>(last_external)); } else { boost::throw_exception(bad_conversion()); } return internal_str; }
void from_bytes_step(const std::codecvt<CvtTypes...> & cvt, typename make_from_bytes_context<std::codecvt<CvtTypes...>>::type & ctx) { ctx.res = cvt.in(ctx.state, ctx.from_beg, ctx.from_end, ctx.from_stopped, ctx.to_beg, ctx.to_end, ctx.to_stopped); if (ctx.res == std::codecvt_base::partial) { // cvt.length returns 0 on intern_char non empty buffer, // it can't convert from input - input is partial ctx.is_partial_input = cvt.length(ctx.state, ctx.from_stopped, ctx.from_end, 1) == 0; } }
const std::basic_string<Byte> out( const std::basic_string<CharType>& internal_str, const std::codecvt<CharType, Byte, mbstate_t>& codecvt) { typedef std::basic_string<CharType> wstring; typedef std::basic_string<Byte> string; typedef std::codecvt<CharType, Byte, mbstate_t> codecvt_type; string external_str; typename wstring::size_type internal_str_size = internal_str.length(); typename wstring::size_type out_buf_size = static_cast<typename wstring::size_type>(codecvt.max_length()) * internal_str_size; #if defined(MA_USE_CXX11_STDLIB_MEMORY) std::unique_ptr<Byte[]> out_buf(new Byte[out_buf_size]); #else boost::scoped_array<Byte> out_buf(new Byte[out_buf_size]); #endif const CharType* first_internal = internal_str.data(); const CharType* last_internal = first_internal + internal_str_size; const CharType* next_internal = first_internal; Byte* first_external = out_buf.get(); Byte* last_external = first_external + out_buf_size; Byte* next_external = first_external; typename codecvt_type::state_type state(0); typename codecvt_type::result r = codecvt.out(state, first_internal, last_internal, next_internal, first_external, last_external, next_external); if (codecvt_type::ok == r) { external_str.assign(first_external, next_external); } else if (codecvt_type::noconv == r) { external_str.assign(reinterpret_cast<const Byte*>(first_internal), reinterpret_cast<const Byte*>(last_internal)); } else { boost::throw_exception(bad_conversion()); } return external_str; }
void test_length (internT /* dummy */, int line, const std::mbstate_t *pstate, const std::codecvt<internT, char, std::mbstate_t> &cvt, const char *from, std::size_t nchars, int maxi, int result) { static const std::mbstate_t initial_state = std::mbstate_t (); const char* const tname = rw_any_t (internT ()).type_name (); std::mbstate_t state = pstate ? *pstate : initial_state; if (std::size_t (-1) == nchars) nchars = std::strlen (from); const int res = cvt.length (state, from, from + nchars, maxi); rw_assert (res == result, 0, line, "line %d: codecvt<%s, char, mbstate_t>::length(" "state, from=%{*s}, from + %zu, %d) == %d, got %d", __LINE__, tname, sizeof *from, from, nchars, maxi, result, res); rw_assert (!pstate || 0 == std::memcmp (pstate, &state, sizeof state), 0, line, "line %d: codecvt<%s, char, mbstate_t>::length(" "state, from=%{*s}, from + %zu, %d) unexpected state", __LINE__, tname, from, nchars, maxi); }
const std::basic_string<CharType> in( const std::basic_string<Byte>& external_str, const std::codecvt<CharType, Byte, mbstate_t>& codecvt) { typedef std::basic_string<CharType> wstring; typedef std::basic_string<Byte> string; typedef std::codecvt<CharType, Byte, mbstate_t> codecvt_type; typename string::size_type external_str_size = external_str.length(); const Byte* first_external = external_str.data(); const Byte* last_external = first_external + external_str_size; const Byte* next_external = last_external; wstring internal_str; typename codecvt_type::state_type state(0); typename wstring::size_type out_buf_size = codecvt.length(state, first_external, last_external, internal_str.max_size()); boost::scoped_array<CharType> out_buf(new CharType[out_buf_size]); CharType* first_internal = out_buf.get(); CharType* last_internal = first_internal + out_buf_size; CharType* next_internal = first_internal; typename codecvt_type::result r = codecvt.in(state, first_external, last_external, next_external, first_internal, last_internal, next_internal); if (codecvt_type::ok != r) { boost::throw_exception(bad_conversion()); } else if (codecvt_type::noconv == r) { internal_str.assign(reinterpret_cast<const CharType*>(first_external), reinterpret_cast<const CharType*>(last_external)); } else { internal_str.assign(first_internal, last_internal); } return internal_str; }
inline std::codecvt_base::result convert( std::codecvt< LocalCharT, char, std::mbstate_t > const& fac, std::mbstate_t& state, const LocalCharT*& pSrcBegin, const LocalCharT* pSrcEnd, char*& pDstBegin, char* pDstEnd) { return fac.out(state, pSrcBegin, pSrcEnd, pSrcBegin, pDstBegin, pDstEnd, pDstBegin); }