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; // 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<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; }