clean up utf8 conversion wrapper a bit, to not rely on dead-code elimination in constant conditions
This commit is contained in:
parent
b3d7668e7a
commit
b4a6a14dfb
153
src/utf8.cpp
153
src/utf8.cpp
|
@ -40,67 +40,124 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace libtorrent
|
||||
{
|
||||
utf8_conv_result_t utf8_wchar(const std::string &utf8, std::wstring &wide)
|
||||
namespace
|
||||
{
|
||||
// ==== utf-8 -> wide ===
|
||||
template<int width>
|
||||
struct convert_to_wide
|
||||
{
|
||||
static utf8_conv_result_t convert(UTF8 const** src_start
|
||||
, UTF8 const* src_end
|
||||
, std::wstring& wide)
|
||||
{
|
||||
return source_illegal;
|
||||
}
|
||||
};
|
||||
|
||||
// ==== utf-8 -> utf-32 ===
|
||||
template<>
|
||||
struct convert_to_wide<4>
|
||||
{
|
||||
static utf8_conv_result_t convert(char const** src_start
|
||||
, char const* src_end
|
||||
, std::wstring& wide)
|
||||
{
|
||||
wchar_t const* dst_start = wide.c_str();
|
||||
int ret = ConvertUTF8toUTF32((UTF8 const**)src_start
|
||||
, (UTF8 const*)src_end
|
||||
, (UTF32**)&dst_start, (UTF32*)dst_start + wide.size()
|
||||
, lenientConversion);
|
||||
wide.resize(dst_start - wide.c_str());
|
||||
return (utf8_conv_result_t)ret;
|
||||
}
|
||||
};
|
||||
|
||||
// ==== utf-8 -> utf-16 ===
|
||||
template<>
|
||||
struct convert_to_wide<2>
|
||||
{
|
||||
static utf8_conv_result_t convert(char const** src_start
|
||||
, char const* src_end
|
||||
, std::wstring& wide)
|
||||
{
|
||||
wchar_t const* dst_start = wide.c_str();
|
||||
int ret = ConvertUTF8toUTF16((UTF8 const**)src_start
|
||||
, (UTF8 const*)src_end
|
||||
, (UTF16**)&dst_start, (UTF16*)dst_start + wide.size()
|
||||
, lenientConversion);
|
||||
wide.resize(dst_start - wide.c_str());
|
||||
return (utf8_conv_result_t)ret;
|
||||
}
|
||||
};
|
||||
|
||||
// ==== wide -> utf-8 ===
|
||||
template<int width>
|
||||
struct convert_from_wide
|
||||
{
|
||||
static utf8_conv_result_t convert(wchar_t const** src_start
|
||||
, wchar_t const* src_end
|
||||
, std::string& utf8)
|
||||
{
|
||||
return source_illegal;
|
||||
}
|
||||
};
|
||||
|
||||
// ==== utf-32 -> utf-8 ===
|
||||
template<>
|
||||
struct convert_from_wide<4>
|
||||
{
|
||||
static utf8_conv_result_t convert(wchar_t const** src_start
|
||||
, wchar_t const* src_end
|
||||
, std::string& utf8)
|
||||
{
|
||||
char const* dst_start = utf8.c_str();
|
||||
int ret = ConvertUTF32toUTF8((UTF32 const**)src_start
|
||||
, (UTF32 const*)src_end, (UTF8**)&dst_start
|
||||
, (UTF8*)dst_start + utf8.size()
|
||||
, lenientConversion);
|
||||
utf8.resize(dst_start - &utf8[0]);
|
||||
return (utf8_conv_result_t)ret;
|
||||
}
|
||||
};
|
||||
|
||||
// ==== utf-16 -> utf-8 ===
|
||||
template<>
|
||||
struct convert_from_wide<2>
|
||||
{
|
||||
static utf8_conv_result_t convert(wchar_t const** src_start
|
||||
, wchar_t const* src_end
|
||||
, std::string& utf8)
|
||||
{
|
||||
char const* dst_start = utf8.c_str();
|
||||
int ret = ConvertUTF16toUTF8((UTF16 const**)src_start
|
||||
, (UTF16 const*)src_end, (UTF8**)&dst_start
|
||||
, (UTF8*)dst_start + utf8.size()
|
||||
, lenientConversion);
|
||||
utf8.resize(dst_start - &utf8[0]);
|
||||
return (utf8_conv_result_t)ret;
|
||||
}
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
utf8_conv_result_t utf8_wchar(std::string const& utf8, std::wstring &wide)
|
||||
{
|
||||
// allocate space for worst-case
|
||||
wide.resize(utf8.size());
|
||||
wchar_t const* dst_start = wide.c_str();
|
||||
char const* src_start = utf8.c_str();
|
||||
ConversionResult ret;
|
||||
// TODO: 3 refactor this to use wchar_t as a template
|
||||
// it would cause less code to be generated without
|
||||
// relying on dead-code elimination and fix msvc constant
|
||||
// expression warning
|
||||
if (sizeof(wchar_t) == sizeof(UTF32))
|
||||
{
|
||||
ret = ConvertUTF8toUTF32((const UTF8**)&src_start, (const UTF8*)src_start
|
||||
+ utf8.size(), (UTF32**)&dst_start, (UTF32*)dst_start + wide.size()
|
||||
, lenientConversion);
|
||||
wide.resize(dst_start - wide.c_str());
|
||||
return (utf8_conv_result_t)ret;
|
||||
}
|
||||
else if (sizeof(wchar_t) == sizeof(UTF16))
|
||||
{
|
||||
ret = ConvertUTF8toUTF16((const UTF8**)&src_start, (const UTF8*)src_start
|
||||
+ utf8.size(), (UTF16**)&dst_start, (UTF16*)dst_start + wide.size()
|
||||
, lenientConversion);
|
||||
wide.resize(dst_start - wide.c_str());
|
||||
return (utf8_conv_result_t)ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
return source_illegal;
|
||||
}
|
||||
return convert_to_wide<sizeof(wchar_t)>::convert(
|
||||
&src_start, src_start + utf8.size(), wide);
|
||||
}
|
||||
|
||||
utf8_conv_result_t wchar_utf8(const std::wstring &wide, std::string &utf8)
|
||||
utf8_conv_result_t wchar_utf8(std::wstring const& wide, std::string &utf8)
|
||||
{
|
||||
// allocate space for worst-case
|
||||
utf8.resize(wide.size() * 6);
|
||||
if (wide.empty()) return conversion_ok;
|
||||
char* dst_start = &utf8[0];
|
||||
wchar_t const* src_start = wide.c_str();
|
||||
ConversionResult ret;
|
||||
if (sizeof(wchar_t) == sizeof(UTF32))
|
||||
{
|
||||
ret = ConvertUTF32toUTF8((const UTF32**)&src_start, (const UTF32*)src_start
|
||||
+ wide.size(), (UTF8**)&dst_start, (UTF8*)dst_start + utf8.size()
|
||||
, lenientConversion);
|
||||
utf8.resize(dst_start - &utf8[0]);
|
||||
return (utf8_conv_result_t)ret;
|
||||
}
|
||||
else if (sizeof(wchar_t) == sizeof(UTF16))
|
||||
{
|
||||
ret = ConvertUTF16toUTF8((const UTF16**)&src_start, (const UTF16*)src_start
|
||||
+ wide.size(), (UTF8**)&dst_start, (UTF8*)dst_start + utf8.size()
|
||||
, lenientConversion);
|
||||
utf8.resize(dst_start - &utf8[0]);
|
||||
return (utf8_conv_result_t)ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
return source_illegal;
|
||||
}
|
||||
return convert_from_wide<sizeof(wchar_t)>::convert(
|
||||
&src_start, src_start + wide.size(), utf8);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue