summaryrefslogtreecommitdiffstats
path: root/core/windows.c
diff options
context:
space:
mode:
authorGravatar Lubomir I. Ivanov <neolit123@gmail.com>2018-09-03 21:58:42 +0300
committerGravatar Dirk Hohndel <dirk@hohndel.org>2018-09-03 13:29:03 -0700
commitc47b6b672f20638448badd6d681644dcff69c0eb (patch)
treebcbdb62de43918195f8c82f437c7cb22da9d561d /core/windows.c
parent0ef145337a879e5ff88227117388c9bcac51ad43 (diff)
downloadsubsurface-c47b6b672f20638448badd6d681644dcff69c0eb.tar.gz
code/windows.c: add method for converting from utf16 to utf8
Modify the funcion system_default_path_append() to both receive and return wchar_t types. Remove fallback in system_default_path_append() as this is now redundant. Add a function utf16_to_utf8() and use that in places where system_default_path_append() needs to be converted to utf8. Move both utf16_to_utf8*() and utf8_to_utf16*() near the top of the file. Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Diffstat (limited to 'core/windows.c')
-rw-r--r--core/windows.c111
1 files changed, 62 insertions, 49 deletions
diff --git a/core/windows.c b/core/windows.c
index 6feb3f740..f1c95fff1 100644
--- a/core/windows.c
+++ b/core/windows.c
@@ -41,11 +41,60 @@ bool subsurface_ignore_font(const char *font)
return false;
}
+/* this function converts a win32's utf-16 2 byte string to utf-8.
+ * the caller function should manage the allocated memory.
+ */
+static char *utf16_to_utf8_fl(const wchar_t *utf16, char *file, int line)
+{
+ assert(utf16 != NULL);
+ assert(file != NULL);
+ assert(line);
+ /* estimate buffer size */
+ const int sz = wcslen(utf16) + 1;
+ char *utf8 = (char *)malloc(sz);
+ if (!utf8) {
+ fprintf(stderr, "%s:%d: %s %d.", file, line, "cannot allocate buffer of size", sz);
+ return NULL;
+ }
+ if (WideCharToMultiByte(CP_UTF8, 0, utf16, -1, utf8, sz, NULL, NULL)) {
+ return utf8;
+ }
+ fprintf(stderr, "%s:%d: %s", file, line, "cannot convert string.");
+ free((void *)utf8);
+ return NULL;
+}
+
+#define utf16_to_utf8(s) utf16_to_utf8_fl(s, __FILE__, __LINE__)
+
+/* this function converts a utf-8 string to win32's utf-16 2 byte string.
+ * the caller function should manage the allocated memory.
+ */
+static wchar_t *utf8_to_utf16_fl(const char *utf8, char *file, int line)
+{
+ assert(utf8 != NULL);
+ assert(file != NULL);
+ assert(line);
+ /* estimate buffer size */
+ const int sz = strlen(utf8) + 1;
+ wchar_t *utf16 = (wchar_t *)malloc(sizeof(wchar_t) * sz);
+ if (!utf16) {
+ fprintf(stderr, "%s:%d: %s %d.", file, line, "cannot allocate buffer of size", sz);
+ return NULL;
+ }
+ if (MultiByteToWideChar(CP_UTF8, 0, utf8, -1, utf16, sz))
+ return utf16;
+ fprintf(stderr, "%s:%d: %s", file, line, "cannot convert string.");
+ free((void *)utf16);
+ return NULL;
+}
+
+#define utf8_to_utf16(s) utf8_to_utf16_fl(s, __FILE__, __LINE__)
+
/* this function returns the Win32 Roaming path for the current user as UTF-8.
* it never returns NULL but fallsback to .\ instead!
* the append argument will append a wchar_t string to the end of the path.
*/
-static const char *system_default_path_append(const wchar_t *append)
+static wchar_t *system_default_path_append(const wchar_t *append)
{
wchar_t wpath[MAX_PATH] = { 0 };
const char *fname = "system_default_path_append()";
@@ -66,27 +115,10 @@ static const char *system_default_path_append(const wchar_t *append)
wcscat(wpath, append);
}
- /* attempt to convert the UTF-16 string to UTF-8.
- * resize the buffer and fallback to .\Subsurface if it fails.
- */
- const int wsz = wcslen(wpath);
- const int sz = WideCharToMultiByte(CP_UTF8, 0, wpath, wsz, NULL, 0, NULL, NULL);
- char *path = (char *)malloc(sz + 1);
- if (!sz)
- goto fallback;
- if (WideCharToMultiByte(CP_UTF8, 0, wpath, wsz, path, sz, NULL, NULL)) {
- path[sz] = '\0';
- return path;
- }
-
-fallback:
- fprintf(stderr, "%s: cannot obtain path as UTF-8!\n", fname);
- const char *local = ".\\Subsurface";
- const int len = strlen(local) + 1;
- path = (char *)realloc(path, len);
- memset(path, 0, len);
- strcat(path, local);
- return path;
+ wchar_t *result = wcsdup(wpath);
+ if (!result)
+ fprintf(stderr, "%s: cannot allocate memory for path!\n", fname);
+ return result;
}
/* by passing NULL to system_default_path_append() we obtain the pure path.
@@ -95,8 +127,11 @@ fallback:
const char *system_default_directory(void)
{
static const char *path = NULL;
- if (!path)
- path = system_default_path_append(NULL);
+ if (!path) {
+ wchar_t *wpath = system_default_path_append(NULL);
+ path = utf16_to_utf8(wpath);
+ free((void *)wpath);
+ }
return path;
}
@@ -112,7 +147,9 @@ const char *system_default_filename(void)
wchar_t filename[UNLEN + 5] = { 0 };
wcscat(filename, username);
wcscat(filename, L".xml");
- path = system_default_path_append(filename);
+ wchar_t *wpath = system_default_path_append(filename);
+ path = utf16_to_utf8(wpath);
+ free((void *)wpath);
}
return path;
}
@@ -205,30 +242,6 @@ int enumerate_devices(device_callback_t callback, void *userdata, unsigned int t
return index;
}
-/* this function converts a utf-8 string to win32's utf-16 2 byte string.
- * the caller function should manage the allocated memory.
- */
-static wchar_t *utf8_to_utf16_fl(const char *utf8, char *file, int line)
-{
- assert(utf8 != NULL);
- assert(file != NULL);
- assert(line);
- /* estimate buffer size */
- const int sz = strlen(utf8) + 1;
- wchar_t *utf16 = (wchar_t *)malloc(sizeof(wchar_t) * sz);
- if (!utf16) {
- fprintf(stderr, "%s:%d: %s %d.", file, line, "cannot allocate buffer of size", sz);
- return NULL;
- }
- if (MultiByteToWideChar(CP_UTF8, 0, utf8, -1, utf16, sz))
- return utf16;
- fprintf(stderr, "%s:%d: %s", file, line, "cannot convert string.");
- free((void *)utf16);
- return NULL;
-}
-
-#define utf8_to_utf16(s) utf8_to_utf16_fl(s, __FILE__, __LINE__)
-
/* bellow we provide a set of wrappers for some I/O functions to use wchar_t.
* on win32 this solves the issue that we need paths to be utf-16 encoded.
*/