diff options
author | Jaromir Wysoglad | 2019-08-14 01:42:31 +0200 |
---|---|---|
committer | Filippos Karapetis | 2019-08-24 18:12:45 +0300 |
commit | a0564bc564559abf87165331a42d22b89c998dce (patch) | |
tree | 45bf88c653e4e772d96167e51f3d72af386ed18d | |
parent | 3513972e92a4a4653c30de34eb5be9488bf2ff6a (diff) | |
download | scummvm-rg350-a0564bc564559abf87165331a42d22b89c998dce.tar.gz scummvm-rg350-a0564bc564559abf87165331a42d22b89c998dce.tar.bz2 scummvm-rg350-a0564bc564559abf87165331a42d22b89c998dce.zip |
COMMON: Resolve endianity in Encoding
-rw-r--r-- | common/encoding.cpp | 37 | ||||
-rw-r--r-- | common/encoding.h | 2 |
2 files changed, 29 insertions, 10 deletions
diff --git a/common/encoding.cpp b/common/encoding.cpp index d121e13dbe..66d2381ac7 100644 --- a/common/encoding.cpp +++ b/common/encoding.cpp @@ -39,10 +39,22 @@ Encoding::~Encoding() { deinitIconv(_iconvHandle); } +String Encoding::addUtfEndianness(const String &str) { + if (str.equalsIgnoreCase("utf-16") || str.equalsIgnoreCase("utf-32")) { +#ifdef SCUMM_BIG_ENDIAN + return str + "BE"; +#else + return str + "LE"; +#endif + } else + return String(str); +} + iconv_t Encoding::initIconv(const String &to, const String &from) { #ifdef USE_ICONV - String toTranslit = to + "//TRANSLIT"; - return iconv_open(toTranslit.c_str(), from.c_str()); + String toTranslit = addUtfEndianness(to) + "//TRANSLIT"; + return iconv_open(toTranslit.c_str(), + addUtfEndianness(from).c_str()); #else return 0; #endif // USE_ICONV @@ -157,11 +169,12 @@ char *Encoding::conversion(iconv_t iconvHandle, const String &to, const String & debug("Iconv is not available"); #endif // USE_ICONV if (result == nullptr) - result = g_system->convertEncoding(to.c_str(), from.c_str(), string, length); + result = g_system->convertEncoding(addUtfEndianness(to).c_str(), + addUtfEndianness(from).c_str(), string, length); if (result == nullptr) { debug("Could not convert from %s to %s using backend specific conversion", from.c_str(), to.c_str()); - result = convertTransManMapping(to.c_str(), from.c_str(), string, length); + result = convertTransManMapping(addUtfEndianness(to).c_str(), addUtfEndianness(from).c_str(), string, length); } return result; @@ -262,14 +275,18 @@ char *Encoding::convertTransManMapping(const char *to, const char *from, const c partialResult[i] = mapping[(unsigned char) string[i]] & 0x7FFFFFFF; } } -#ifdef SCUMM_BIG_ENDIAN - char *finalResult = convert(to, "UTF-32BE", (char *) partialResult, strlen(string) * 4); -#else - char *finalResult = convert(to, "UTF-32LE", (char *) partialResult, strlen(string) * 4); -#endif // SCUMM_BIG_ENDIAN + char *finalResult = convert(to, "UTF-32", (char *) partialResult, strlen(string) * 4); free(partialResult); return finalResult; - } else if (currentCharset.equalsIgnoreCase(to) && String(from).equalsIgnoreCase("utf-32")) { + } else if (currentCharset.equalsIgnoreCase(to) && String(from).hasPrefixIgnoreCase("utf-32")) { + // We accept only the machine endianness +#ifdef SCUMM_BIG_ENDIAN + if (String(from).hasSuffixIgnoreCase("LE")) + return nullptr; +#else + if (String(from).hasSuffixIgnoreCase("BE")) + return nullptr; +#endif // We can do reverse mapping const uint32 *mapping = TransMan.getCharsetMapping(); const uint32 *src = (const uint32 *) string; diff --git a/common/encoding.h b/common/encoding.h index 014000d5ae..309e0f8a37 100644 --- a/common/encoding.h +++ b/common/encoding.h @@ -221,6 +221,8 @@ class Encoding { * @param iconvHandle Handle that should be deinited */ static void deinitIconv(iconv_t iconvHandle); + + static String addUtfEndianness(const String &str); }; } |