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); }
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<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) detail::unique_ptr<Byte[]> out_buf(new Byte[out_buf_size]); #else detail::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; // Zero initialized typename codecvt_type::state_type state; std::memset(&state, 0, sizeof(state)); 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; }
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 = codecvt.max_length() * internal_str_size; boost::scoped_array<Byte> out_buf(new Byte[out_buf_size]); 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; }