From adebf504bbdfcc3069288e710aeeaad727fdce69 Mon Sep 17 00:00:00 2001
From: Syping <schiedelrafael@keppe.org>
Date: Sun, 7 Nov 2021 20:32:06 +0100
Subject: [PATCH] Unicode: changed implementation selection

---
 CMakeLists.txt    | 39 ++++++++++++++++++++++-------------
 src/RagePhoto.cpp | 52 +++++++++++++++++++++++------------------------
 2 files changed, 51 insertions(+), 40 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b3998bb..c1c291a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -28,9 +28,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
 message("-- Testing codecvt")
 try_run(CODECVT_RUN CODECVT_COMPILE ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/tests/CodecvtTest.cpp)
 if (CODECVT_COMPILE AND CODECVT_RUN EQUAL 0)
-    list(APPEND LIBRAGEPHOTO_DEFINES
-        CODECVT_COMPATIBLE
-    )
+    set(CODECVT_COMPAT TRUE)
     message("-- Testing codecvt - yes")
 else()
     message("-- Testing codecvt - no")
@@ -39,23 +37,36 @@ endif()
 message("-- Testing iconv")
 try_run(ICONV_RUN ICONV_COMPILE ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/tests/IconvTest.cpp)
 if (ICONV_COMPILE AND ICONV_RUN EQUAL 0)
-    list(APPEND LIBRAGEPHOTO_DEFINES
-        ICONV_COMPATIBLE
-    )
+    set(ICONV_COMPAT TRUE)
     message("-- Testing iconv - yes")
 else()
     message("-- Testing iconv - no")
 endif()
 
-message("-- Testing wincvt")
-try_run(WINCVT_RUN WINCVT_COMPILE ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/tests/WincvtTest.cpp)
-if (WINCVT_COMPILE AND WINCVT_RUN EQUAL 0)
+if (WIN32)
+    message("-- Testing wincvt")
+    try_run(WINCVT_RUN WINCVT_COMPILE ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/tests/WincvtTest.cpp)
+    if (WINCVT_COMPILE AND WINCVT_RUN EQUAL 0)
+        set(WINCVT_COMPAT TRUE)
+        message("-- Testing wincvt - yes")
+    else()
+        message("-- Testing wincvt - no")
+    endif()
+endif()
+
+# Unicode implementation for RagePhoto
+if (WINCVT_COMPAT)
     list(APPEND LIBRAGEPHOTO_DEFINES
-        WINCVT_COMPATIBLE
+        UNICODE_WINCVT
+    )
+elseif (CODECVT_COMPAT)
+    list(APPEND LIBRAGEPHOTO_DEFINES
+        UNICODE_CODECVT
+    )
+elseif (ICONV_COMPAT)
+    list(APPEND LIBRAGEPHOTO_DEFINES
+        UNICODE_ICONV
     )
-    message("-- Testing wincvt - yes")
-else()
-    message("-- Testing wincvt - no")
 endif()
 
 # RagePhoto Source files
@@ -96,7 +107,7 @@ else()
     set(LIBRAGEPHOTO_API LIBRAGEPHOTO_C_NOAPI)
 endif()
 
-# RagePhoto Configures + Target + Install
+# RagePhoto Configures + Target + Installs
 configure_file(src/ragephoto.pc.in pkgconfig/ragephoto.pc @ONLY)
 configure_file(src/libragephoto_global.h.in include/libragephoto_global.h @ONLY)
 list(APPEND RAGEPHOTO_HEADERS
diff --git a/src/RagePhoto.cpp b/src/RagePhoto.cpp
index 6fc4178..eae1b08 100644
--- a/src/RagePhoto.cpp
+++ b/src/RagePhoto.cpp
@@ -27,13 +27,13 @@
 #include <chrono>
 #endif
 
-#if defined WINCVT_COMPATIBLE
-#include <stringapiset.h>
-#elif defined CODECVT_COMPATIBLE
+#if defined UNICODE_CODECVT
 #include <codecvt>
 #include <locale>
-#elif defined ICONV_COMPATIBLE
+#elif defined UNICODE_ICONV
 #include <iconv.h>
+#elif defined UNICODE_WINCVT
+#include <stringapiset.h>
 #endif
 
 RagePhoto::RagePhoto()
@@ -87,7 +87,7 @@ bool RagePhoto::load(const char *data, size_t length)
     m_data.photoFormat = charToUInt32LE(uInt32Buffer);
 #endif
     if (m_data.photoFormat == PhotoFormat::GTA5 || m_data.photoFormat == PhotoFormat::RDR2) {
-#if defined WINCVT_COMPATIBLE || defined CODECVT_COMPATIBLE || defined ICONV_COMPATIBLE
+#if defined UNICODE_ICONV || defined UNICODE_CODECVT || defined UNICODE_WINCVT
         char photoHeader[256];
         size = readBuffer(data, photoHeader, &pos, 256, length);
         if (size != 256) {
@@ -95,22 +95,14 @@ bool RagePhoto::load(const char *data, size_t length)
             return false;
         }
 
-#if defined WINCVT_COMPATIBLE
-        char photoHeader_string[256];
-        const int converted = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast<wchar_t*>(photoHeader), -1, photoHeader_string, 256, NULL, NULL);
-        if (converted == 0) {
-            m_data.error = static_cast<uint8_t>(Error::UnicodeHeaderError); // 5
-            return false;
-        }
-        m_data.header = std::string(photoHeader_string);
-#elif defined CODECVT_COMPATIBLE
+#if defined UNICODE_CODECVT
         std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> convert;
         m_data.header = convert.to_bytes(reinterpret_cast<char16_t*>(photoHeader));
         if (convert.converted() == 0) {
             m_data.error = static_cast<uint8_t>(Error::UnicodeHeaderError); // 5
             return false;
         }
-#elif defined ICONV_COMPATIBLE
+#elif defined UNICODE_ICONV
         iconv_t iconv_in = iconv_open("UTF-8", "UTF-16LE");
         if (iconv_in == (iconv_t)-1) {
             m_data.error = static_cast<uint8_t>(Error::UnicodeInitError); // 4
@@ -128,6 +120,14 @@ bool RagePhoto::load(const char *data, size_t length)
             return false;
         }
         m_data.header = std::string(photoHeader_string);
+#elif defined UNICODE_WINCVT
+        char photoHeader_string[256];
+        const int converted = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast<wchar_t*>(photoHeader), -1, photoHeader_string, 256, NULL, NULL);
+        if (converted == 0) {
+            m_data.error = static_cast<uint8_t>(Error::UnicodeHeaderError); // 5
+            return false;
+        }
+        m_data.header = std::string(photoHeader_string);
 #endif
 
         size = readBuffer(data, uInt32Buffer, &pos, 4, length);
@@ -479,16 +479,8 @@ const char* RagePhoto::version()
 bool RagePhoto::save(char *data, uint32_t photoFormat)
 {
     if (photoFormat == PhotoFormat::GTA5 || photoFormat == PhotoFormat::RDR2) {
-#if defined WINCVT_COMPATIBLE || defined CODECVT_COMPATIBLE || defined ICONV_COMPATIBLE
-#if defined WINCVT_COMPATIBLE
-        char photoHeader[256]{};
-        const int converted = MultiByteToWideChar(CP_UTF8, 0, m_data.header.data(), m_data.header.size(), reinterpret_cast<wchar_t*>(photoHeader), 256 / sizeof(wchar_t));
-        if (converted == 0) {
-            m_data.error = static_cast<uint8_t>(Error::UnicodeHeaderError); // 5
-            return false;
-        }
-        const size_t photoHeader_size = 256;
-#elif defined CODECVT_COMPATIBLE
+#if defined UNICODE_ICONV || defined UNICODE_CODECVT || defined UNICODE_WINCVT
+#if defined UNICODE_CODECVT
         std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> convert;
         std::u16string photoHeader_string = convert.from_bytes(m_data.header);
         if (convert.converted() == 0) {
@@ -501,7 +493,7 @@ bool RagePhoto::save(char *data, uint32_t photoFormat)
             return false;
         }
         const char *photoHeader = reinterpret_cast<const char*>(photoHeader_string.data());
-#elif defined ICONV_COMPATIBLE
+#elif defined UNICODE_ICONV
         iconv_t iconv_in = iconv_open("UTF-16LE", "UTF-8");
         if (iconv_in == (iconv_t)-1) {
             m_data.error = static_cast<uint8_t>(Error::UnicodeInitError); // 4
@@ -521,6 +513,14 @@ bool RagePhoto::save(char *data, uint32_t photoFormat)
             return false;
         }
         const size_t photoHeader_size = 256;
+#elif defined UNICODE_WINCVT
+        char photoHeader[256]{};
+        const int converted = MultiByteToWideChar(CP_UTF8, 0, m_data.header.data(), m_data.header.size(), reinterpret_cast<wchar_t*>(photoHeader), 256 / sizeof(wchar_t));
+        if (converted == 0) {
+            m_data.error = static_cast<uint8_t>(Error::UnicodeHeaderError); // 5
+            return false;
+        }
+        const size_t photoHeader_size = 256;
 #endif
 
         if (m_data.photoSize > m_data.photoBuffer) {