aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorJaromir Wysoglad2019-08-14 01:42:31 +0200
committerFilippos Karapetis2019-08-24 18:12:45 +0300
commita0564bc564559abf87165331a42d22b89c998dce (patch)
tree45bf88c653e4e772d96167e51f3d72af386ed18d /common
parent3513972e92a4a4653c30de34eb5be9488bf2ff6a (diff)
downloadscummvm-rg350-a0564bc564559abf87165331a42d22b89c998dce.tar.gz
scummvm-rg350-a0564bc564559abf87165331a42d22b89c998dce.tar.bz2
scummvm-rg350-a0564bc564559abf87165331a42d22b89c998dce.zip
COMMON: Resolve endianity in Encoding
Diffstat (limited to 'common')
-rw-r--r--common/encoding.cpp37
-rw-r--r--common/encoding.h2
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);
};
}