]> git.sesse.net Git - vlc/blobdiff - src/text/unicode.c
Added FromCharset helper.
[vlc] / src / text / unicode.c
index bcc1029a93d51f17b56b58b8eb730a32be06b577..8a8641724cccf70194b0d93d5068813c8305bf27 100644 (file)
@@ -40,8 +40,9 @@
 #ifdef UNDER_CE
 #  include <tchar.h>
 #endif
+#include <errno.h>
 
-#ifdef __APPLE__
+#if defined (__APPLE__) || defined (HAVE_MAEMO)
 /* Define this if the OS always use UTF-8 internally */
 # define ASSUME_UTF8 1
 #endif
@@ -118,17 +119,18 @@ static char *locale_fast (const char *string, bool from)
 
     len = 1 + MultiByteToWideChar (from ? CP_ACP : CP_UTF8,
                                    0, string, -1, NULL, 0);
-    wchar_t wide[len];
+    wchar_t *wide = malloc (len * sizeof (wchar_t));
+    if (wide == NULL)
+        return NULL;
 
     MultiByteToWideChar (from ? CP_ACP : CP_UTF8, 0, string, -1, wide, len);
     len = 1 + WideCharToMultiByte (from ? CP_UTF8 : CP_ACP, 0, wide, -1,
                                    NULL, 0, NULL, NULL);
     out = malloc (len);
-    if (out == NULL)
-        return NULL;
-
-    WideCharToMultiByte (from ? CP_UTF8 : CP_ACP, 0, wide, -1, out, len,
-                         NULL, NULL);
+    if (out != NULL)
+        WideCharToMultiByte (from ? CP_UTF8 : CP_ACP, 0, wide, -1, out, len,
+                             NULL, NULL);
+    free (wide);
     return out;
 #else
     (void)from;
@@ -364,3 +366,40 @@ const char *IsUTF8( const char *str )
 {
     return CheckUTF8( (char *)str, 0 );
 }
+
+/**
+ * Converts a string from the given character encoding to utf-8.
+ *
+ * @return a nul-terminated utf-8 string, or null in case of error.
+ * The result must be freed using free().
+ */
+static char *FromCharset(const char *charset, const void *data, size_t data_size)
+{
+    vlc_iconv_t handle = vlc_iconv_open ("UTF-8", charset);
+    if (handle == (vlc_iconv_t)(-1))
+        return NULL;
+
+    char *out = NULL;
+    for(unsigned mul = 4; mul < 8; mul++ )
+    {
+        size_t in_size = data_size;
+        const char *in = data;
+        size_t out_max = mul * data_size;
+        char *tmp = out = malloc (1 + out_max);
+        if (!out)
+            break;
+
+        if (vlc_iconv (handle, &in, &in_size, &tmp, &out_max) != (size_t)(-1)) {
+            *tmp = '\0';
+            break;
+        }
+        free(out);
+        out = NULL;
+
+        if (errno != E2BIG)
+            break;
+    }
+    vlc_iconv_close(handle);
+    return out;
+}
+