From: <man...@us...> - 2013-11-14 18:31:20
|
Revision: 3215 http://sourceforge.net/p/modplug/code/3215 Author: manxorist Date: 2013-11-14 18:31:11 +0000 (Thu, 14 Nov 2013) Log Message: ----------- [Ref] Add string encoding functions with shorter syntax which are easier to type. Modified Paths: -------------- trunk/OpenMPT/common/mptPathString.h trunk/OpenMPT/common/mptString.cpp trunk/OpenMPT/common/mptString.h trunk/OpenMPT/mptrack/Settings.cpp trunk/OpenMPT/mptrack/Settings.h Modified: trunk/OpenMPT/common/mptPathString.h =================================================================== --- trunk/OpenMPT/common/mptPathString.h 2013-11-14 17:31:14 UTC (rev 3214) +++ trunk/OpenMPT/common/mptPathString.h 2013-11-14 18:31:11 UTC (rev 3215) @@ -115,29 +115,29 @@ #if defined(WIN32) // conversions - MPT_DEPRECATED_PATH std::string ToLocale() const { return mpt::String::Encode(path, mpt::CharsetLocale); } - std::string ToUTF8() const { return mpt::String::Encode(path, mpt::CharsetUTF8); } + MPT_DEPRECATED_PATH std::string ToLocale() const { return mpt::ToLocale(path); } + std::string ToUTF8() const { return mpt::To(mpt::CharsetUTF8, path); } std::wstring ToWide() const { return path; } - MPT_DEPRECATED_PATH static PathString FromLocale(const std::string &path) { return PathString(mpt::String::Decode(path, mpt::CharsetLocale)); } - static PathString FromUTF8(const std::string &path) { return PathString(mpt::String::Decode(path, mpt::CharsetUTF8)); } + MPT_DEPRECATED_PATH static PathString FromLocale(const std::string &path) { return PathString(mpt::ToWide(mpt::CharsetLocale, path)); } + static PathString FromUTF8(const std::string &path) { return PathString(mpt::ToWide(mpt::CharsetUTF8, path)); } static PathString FromWide(const std::wstring &path) { return PathString(path); } RawPathString AsNative() const { return path; } static PathString FromNative(const RawPathString &path) { return PathString(path); } #if defined(_MFC_VER) // CString TCHAR, so this is CHAR or WCHAR, depending on UNICODE - MPT_DEPRECATED_PATH CString ToCString() const { return mpt::String::ToCString(path); } - MPT_DEPRECATED_PATH static PathString FromCString(const CString &path) { return PathString(mpt::String::FromCString(path)); } + MPT_DEPRECATED_PATH CString ToCString() const { return mpt::ToCString(path); } + MPT_DEPRECATED_PATH static PathString FromCString(const CString &path) { return PathString(mpt::ToWide(path)); } #endif #else // !WIN32 // conversions std::string ToLocale() const { return path; } - std::string ToUTF8() const { return mpt::String::Convert(path, mpt::CharsetLocale, mpt::CharsetUTF8); } - std::wstring ToWide() const { return mpt::String::Decode(path, mpt::CharsetLocale); } + std::string ToUTF8() const { return mpt::To(mpt::CharsetUTF8, mpt::CharsetLocale, path); } + std::wstring ToWide() const { return mpt::ToWide(mpt::CharsetLocale, path); } static PathString FromLocale(const std::string &path) { return PathString(path); } - static PathString FromUTF8(const std::string &path) { return PathString(mpt::String::Convert(path, mpt::CharsetUTF8, mpt::CharsetLocale)); } - static PathString FromWide(const std::wstring &path) { return PathString(mpt::String::Encode(path, mpt::CharsetLocale)); } + static PathString FromUTF8(const std::string &path) { return PathString(mpt::To(mpt::CharsetLocale, mpt::CharsetUTF8, path)); } + static PathString FromWide(const std::wstring &path) { return PathString(mpt::To(mpt::CharsetLocale, path)); } RawPathString AsNative() const { return path; } static PathString FromNative(const RawPathString &path) { return PathString(path); } Modified: trunk/OpenMPT/common/mptString.cpp =================================================================== --- trunk/OpenMPT/common/mptString.cpp 2013-11-14 17:31:14 UTC (rev 3214) +++ trunk/OpenMPT/common/mptString.cpp 2013-11-14 18:31:11 UTC (rev 3215) @@ -105,18 +105,21 @@ #endif // WIN32 -std::string Encode(const std::wstring &src, Charset charset) +// templated on 8bit strings because of type-safe variants +template<typename Tdststring> +Tdststring EncodeImpl(Charset charset, const std::wstring &src) { + STATIC_ASSERT(sizeof(typename Tdststring::value_type) == sizeof(char)); #if defined(WIN32) const UINT codepage = CharsetToCodepage(charset); int required_size = WideCharToMultiByte(codepage, 0, src.c_str(), -1, nullptr, 0, nullptr, nullptr); if(required_size <= 0) { - return std::string(); + return Tdststring(); } std::vector<CHAR> encoded_string(required_size); WideCharToMultiByte(codepage, 0, src.c_str(), -1, &encoded_string[0], required_size, nullptr, nullptr); - return &encoded_string[0]; + return reinterpret_cast<const typename Tdststring::value_type*>(&encoded_string[0]); #else // !WIN32 iconv_t conv = iconv_t(); conv = iconv_open(CharsetToStringTranslit(charset), "wchar_t"); @@ -148,27 +151,30 @@ { iconv_close(conv); conv = iconv_t(); - return std::string(); + return Tdststring(); } } iconv_close(conv); conv = iconv_t(); - return &encoded_string[0]; + return reinterpret_cast<const typename Tdststring::value_type*>(&encoded_string[0]); #endif // WIN32 } -std::wstring Decode(const std::string &src, Charset charset) +// templated on 8bit strings because of type-safe variants +template<typename Tsrcstring> +std::wstring DecodeImpl(Charset charset, const Tsrcstring &src) { + STATIC_ASSERT(sizeof(typename Tsrcstring::value_type) == sizeof(char)); #if defined(WIN32) const UINT codepage = CharsetToCodepage(charset); - int required_size = MultiByteToWideChar(codepage, 0, src.c_str(), -1, nullptr, 0); + int required_size = MultiByteToWideChar(codepage, 0, reinterpret_cast<const char*>(src.c_str()), -1, nullptr, 0); if(required_size <= 0) { return std::wstring(); } std::vector<WCHAR> decoded_string(required_size); - MultiByteToWideChar(codepage, 0, src.c_str(), -1, &decoded_string[0], required_size); + MultiByteToWideChar(codepage, 0, reinterpret_cast<const char*>(src.c_str()), -1, &decoded_string[0], required_size); return &decoded_string[0]; #else // !WIN32 iconv_t conv = iconv_t(); @@ -177,7 +183,7 @@ { throw std::runtime_error("iconv conversion not working"); } - std::vector<char> encoded_string(src.c_str(), src.c_str() + src.length() + 1); + std::vector<char> encoded_string(reinterpret_cast<const char*>(src.c_str()), reinterpret_cast<const char*>(src.c_str()) + src.length() + 1); std::vector<wchar_t> wide_string(encoded_string.size() * 8); // large enough char * inbuf = &encoded_string[0]; size_t inbytesleft = encoded_string.size(); @@ -215,10 +221,18 @@ } -std::string Convert(const std::string &src, Charset from, Charset to) +// templated on 8bit strings because of type-safe variants +template<typename Tdststring, typename Tsrcstring> +Tdststring ConvertImpl(Charset to, Charset from, const Tsrcstring &src) { + STATIC_ASSERT(sizeof(typename Tdststring::value_type) == sizeof(char)); + STATIC_ASSERT(sizeof(typename Tsrcstring::value_type) == sizeof(char)); + if(to == from) + { + return Tdststring(reinterpret_cast<const typename Tdststring::value_type*>(&*src.begin()), reinterpret_cast<const typename Tdststring::value_type*>(&*src.end())); + } #if defined(WIN32) - return Encode(Decode(src, from), to); + return EncodeImpl<Tdststring>(to, DecodeImpl(from, src)); #else // !WIN32 iconv_t conv = iconv_t(); conv = iconv_open(CharsetToStringTranslit(to), CharsetToString(from)); @@ -230,7 +244,7 @@ throw std::runtime_error("iconv conversion not working"); } } - std::vector<char> src_string(src.c_str(), src.c_str() + src.length() + 1); + std::vector<char> src_string(reinterpret_cast<const char*>(src.c_str()), reinterpret_cast<const char*>(src.c_str()) + src.length() + 1); std::vector<char> dst_string(src_string.size() * 8); // large enough char * inbuf = &src_string[0]; size_t inbytesleft = src_string.size(); @@ -250,16 +264,34 @@ { iconv_close(conv); conv = iconv_t(); - return std::string(); + return Tdststring(); } } iconv_close(conv); conv = iconv_t(); - return &dst_string[0]; + return reinterpret_cast<const typename Tdststring::value_type*>(&dst_string[0]); #endif // WIN32 } +std::string Encode(const std::wstring &src, Charset to) +{ + return EncodeImpl<std::string>(to, src); +} + + +std::wstring Decode(const std::string &src, Charset from) +{ + return DecodeImpl(from, src); +} + + +std::string Convert(const std::string &src, Charset from, Charset to) +{ + return ConvertImpl<std::string>(to, from, src); +} + + #if defined(_MFC_VER) CString ToCString(const std::string &src, Charset charset) @@ -301,10 +333,83 @@ #endif -} } // namespace mpt::String +} // namespace String +std::wstring ToWide(Charset from, const std::string &str) +{ + return String::DecodeImpl(from, str); +} +std::string ToLocale(const std::wstring &str) +{ + return String::EncodeImpl<std::string>(CharsetLocale, str); +} +std::string ToLocale(Charset from, const std::string &str) +{ + return String::ConvertImpl<std::string>(CharsetLocale, from, str); +} + +std::string To(Charset to, const std::wstring &str) +{ + return String::EncodeImpl<std::string>(to, str); +} +std::string To(Charset to, Charset from, const std::string &str) +{ + return String::ConvertImpl<std::string>(to, from, str); +} + + +#if defined(_MFC_VER) + +CString ToCString(const std::wstring &str) +{ + #ifdef UNICODE + return str.c_str(); + #else + return ToLocale(str).c_str(); + #endif +} +CString ToCString(Charset from, const std::string &str) +{ + #ifdef UNICODE + return ToWide(from, str).c_str(); + #else + return ToLocale(from, str).c_str(); + #endif +} +std::wstring ToWide(const CString &str) +{ + #ifdef UNICODE + return str.GetString(); + #else + return ToWide(CharsetLocale, str.GetString()); + #endif +} +std::string ToLocale(const CString &str) +{ + #ifdef UNICODE + return ToLocale(str.GetString()); + #else + return str.GetString(); + #endif +} +std::string To(Charset to, const CString &str) +{ + #ifdef UNICODE + return To(to, str.GetString()); + #else + return To(to, CharsetLocale, str.GetString()); + #endif +} + +#endif + + +} // namespace mpt + + + namespace mpt { Modified: trunk/OpenMPT/common/mptString.h =================================================================== --- trunk/OpenMPT/common/mptString.h 2013-11-14 17:31:14 UTC (rev 3214) +++ trunk/OpenMPT/common/mptString.h 2013-11-14 18:31:11 UTC (rev 3215) @@ -151,17 +151,38 @@ }; +static inline std::wstring ToWide(const std::wstring &str) { return str; } + +std::wstring ToWide(Charset from, const std::string &str); + +std::string ToLocale(const std::wstring &str); +std::string ToLocale(Charset from, const std::string &str); + +std::string To(Charset to, const std::wstring &str); +std::string To(Charset to, Charset from, const std::string &str); + +#if defined(_MFC_VER) +static inline CString ToCString(const CString &str) { return str; } +CString ToCString(const std::wstring &str); +CString ToCString(Charset from, const std::string &str); +std::wstring ToWide(const CString &str); +std::string ToLocale(const CString &str); +std::string To(Charset to, const CString &str); +#endif + + + namespace String { // Encode a wide unicode string into the specified encoding. // Invalid unicode code points, or code points not representable are silently substituted. // The wide encoding is UTF-16 or UTF-32, based on sizeof(wchar_t). -std::string Encode(const std::wstring &src, Charset charset); +std::string Encode(const std::wstring &src, Charset to); // Decode a 8-bit or multi-byte encoded string from the specified charset into a wide unicode string. // Invalid char sequences are silently substituted. // The wide encoding is UTF-16 or UTF-32, based on sizeof(wchar_t). -std::wstring Decode(const std::string &src, Charset charset); +std::wstring Decode(const std::string &src, Charset from); // Convert from one 8-bit charset to another. // This is semantically equivalent to Encode(Decode(src, from), to). Modified: trunk/OpenMPT/mptrack/Settings.cpp =================================================================== --- trunk/OpenMPT/mptrack/Settings.cpp 2013-11-14 17:31:14 UTC (rev 3214) +++ trunk/OpenMPT/mptrack/Settings.cpp 2013-11-14 18:31:11 UTC (rev 3215) @@ -113,7 +113,7 @@ } if(HasTypeTag() && !GetTypeTag().empty()) { - result += L":" + mpt::String::Decode(GetTypeTag(), mpt::CharsetASCII); + result += L":" + mpt::ToWide(mpt::CharsetASCII, GetTypeTag()); } return result; } @@ -375,7 +375,7 @@ { ::WritePrivateProfileStringW(GetSection(path).c_str(), GetKey(path).c_str(), val.c_str(), filename.AsNative().c_str()); - if(mpt::String::Decode(mpt::String::Encode(val, mpt::CharsetLocale), mpt::CharsetLocale) != val) + if(mpt::ToWide(mpt::CharsetLocale, mpt::ToLocale(val)) != val) // explicit round-trip { // Value is not representable in ANSI CP. // Now check if the string got stored correctly. @@ -471,7 +471,7 @@ } const mpt::PathString backupFilename = filename + mpt::PathString::FromWide(backupTag.empty() ? L".ansi.bak" : L".ansi." + backupTag + L".bak"); CopyFileW(filename.AsNative().c_str(), backupFilename.AsNative().c_str(), FALSE); - WriteFileUTF16LE(filename, mpt::String::Decode(std::string(&data[0], &data[0] + data.size()), mpt::CharsetLocale)); + WriteFileUTF16LE(filename, mpt::ToWide(mpt::CharsetLocale, std::string(&data[0], &data[0] + data.size()))); } SettingValue IniFileSettingsBackend::ReadSetting(const SettingPath &path, const SettingValue &def) const Modified: trunk/OpenMPT/mptrack/Settings.h =================================================================== --- trunk/OpenMPT/mptrack/Settings.h 2013-11-14 17:31:14 UTC (rev 3214) +++ trunk/OpenMPT/mptrack/Settings.h 2013-11-14 18:31:11 UTC (rev 3215) @@ -121,13 +121,13 @@ { Init(); type = SettingTypeString; - valueString = mpt::String::Decode(val, mpt::CharsetLocale); + valueString = mpt::ToWide(mpt::CharsetLocale, val); } SettingValue(const std::string &val) { Init(); type = SettingTypeString; - valueString = mpt::String::Decode(val, mpt::CharsetLocale); + valueString = mpt::ToWide(mpt::CharsetLocale, val); } SettingValue(const wchar_t *val) { @@ -173,14 +173,14 @@ Init(); type = SettingTypeString; typeTag = typeTag_; - valueString = mpt::String::Decode(val, mpt::CharsetLocale); + valueString = mpt::ToWide(mpt::CharsetLocale, val); } SettingValue(const std::string &val, const std::string &typeTag_) { Init(); type = SettingTypeString; typeTag = typeTag_; - valueString = mpt::String::Decode(val, mpt::CharsetLocale); + valueString = mpt::ToWide(mpt::CharsetLocale, val); } SettingValue(const wchar_t *val, const std::string &typeTag_) { @@ -238,7 +238,7 @@ operator std::string () const { ASSERT(type == SettingTypeString); - return mpt::String::Encode(valueString, mpt::CharsetLocale); + return mpt::ToLocale(valueString); } operator std::wstring () const { @@ -293,8 +293,8 @@ // You may use the SettingValue(value, typeTag) constructor in ToSettingValue // and check the typeTag FromSettingsValue to implement runtime type-checking for custom types. -template<> inline SettingValue ToSettingValue(const CString &val) { return SettingValue(std::basic_string<TCHAR>(val.GetString())); } -template<> inline CString FromSettingValue(const SettingValue &val) { return CString(val.as<std::basic_string<TCHAR> >().c_str()); } +template<> inline SettingValue ToSettingValue(const CString &val) { return SettingValue(mpt::ToWide(val)); } +template<> inline CString FromSettingValue(const SettingValue &val) { return mpt::ToCString(val.as<std::wstring>()); } template<> inline SettingValue ToSettingValue(const mpt::PathString &val) { return SettingValue(val.AsNative()); } template<> inline mpt::PathString FromSettingValue(const SettingValue &val) { return mpt::PathString::FromNative(val); } @@ -402,8 +402,8 @@ return; } SettingPath(const std::string §ion_, const std::string &key_) - : section(mpt::String::Decode(section_, mpt::CharsetLocale)) - , key(mpt::String::Decode(key_, mpt::CharsetLocale)) + : section(mpt::ToWide(mpt::CharsetLocale, section_)) + , key(mpt::ToWide(mpt::CharsetLocale, key_)) { return; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |