Преглед изворни кода

OS/2: Deal with UTF-8 -> codepage conversion on older OS/2 installs.

(untested attempt.)
Ryan C. Gordon пре 8 година
родитељ
комит
69d3df3286
1 измењених фајлова са 39 додато и 21 уклоњено
  1. 39 21
      src/physfs_platform_os2.c

+ 39 - 21
src/physfs_platform_os2.c

@@ -95,25 +95,42 @@ static PHYSFS_ErrorCode errcodeFromAPIRET(const APIRET rc)
 
 static char *cvtUtf8ToCodepage(const char *utf8str)
 {
-    if (uconvdll)
-    {
-        int rc;
-        size_t len = strlen(utf8str) + 1;
-        const size_t uc2buflen = len * sizeof (UniChar);
-        UniChar *uc2ptr = (UniChar *) __PHYSFS_smallAlloc(uc2buflen);
-        UniChar *uc2str = uc2ptr;
-        char *cpptr = NULL;
-        char *cpstr = NULL;
-        size_t subs = 0;
-        size_t unilen;
-        size_t cplen;
+    const size_t len = strlen(utf8str) + 1;
+    const size_t uc2buflen = len * sizeof (UniChar);
+    UniChar *uc2ptr = (UniChar *) __PHYSFS_smallAlloc(uc2buflen);
+    UniChar *uc2str = uc2ptr;
+    char *cpptr = NULL;
+    char *cpstr = NULL;
+    size_t subs = 0;
+    size_t unilen;
+
+    BAIL_IF(!uc2str, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+    PHYSFS_utf8ToUcs2(utf8str, (PHYSFS_uint16 *) uc2str, uc2buflen);
+    for (unilen = 0; uc2str[unilen]; unilen++) { /* spin */ }
+    unilen++;  /* null terminator. */
 
-        GOTO_IF(!uc2str, PHYSFS_ERR_OUT_OF_MEMORY, failed);
-        PHYSFS_utf8ToUcs2(utf8str, (PHYSFS_uint16 *) uc2str, uc2buflen);
-        for (unilen = 0; uc2str[unilen]; unilen++) { /* spin */ }
-        unilen++;  /* null terminator. */
+    if (!uconvdll)
+    {
+        /* There's really not much we can do on older OS/2s except pray this
+           is latin1-compatible. */
+        size_t i;
+        cpptr = (char *) allocator.Malloc(unilen);
+        cpstr = cpptr;
+        GOTO_IF(!cpptr, PHYSFS_ERR_OUT_OF_MEMORY, failed);
+        for (i = 0; i < unilen; i++)
+        {
+            const UniChar ch = uc2str[i];
+            GOTO_IF(ch > 0xFF, PHYSFS_ERR_BAD_FILENAME, failed);
+            cpptr[i] = (char) ((unsigned char) ch);
+        } /* for */
 
-        cplen = unilen * 4; /* overallocate, just in case. */
+        __PHYSFS_smallFree(uc2ptr);
+        return cpstr;
+    } /* if */
+    else
+    {
+        int rc;
+        const size_t cplen = unilen * 4; /* overallocate, just in case. */
         cpptr = (char *) allocator.Malloc(cplen);
         GOTO_IF(!cpptr, PHYSFS_ERR_OUT_OF_MEMORY, failed);
         cpstr = cpptr;
@@ -123,12 +140,13 @@ static char *cvtUtf8ToCodepage(const char *utf8str)
         GOTO_IF(subs > 0, PHYSFS_ERR_BAD_FILENAME, failed);
         assert(unilen == 0);
 
+        __PHYSFS_smallFree(uc2ptr);
         return cpptr;
+    } /* else */
 
-        failed:
-        __PHYSFS_smallFree(uc2ptr);
-        allocator.Free(cpptr);
-    } /* if */
+failed:
+    __PHYSFS_smallFree(uc2ptr);
+    allocator.Free(cpptr);
 
     return NULL;
 } /* cvtUtf8ToCodepage */