]> git.sesse.net Git - vlc/commitdiff
Add ToCharset() helper to convert from UTF-8
authorRémi Denis-Courmont <remi@remlab.net>
Tue, 26 Oct 2010 17:48:46 +0000 (20:48 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Tue, 26 Oct 2010 17:58:55 +0000 (20:58 +0300)
include/vlc_charset.h
src/libvlccore.sym
src/text/unicode.c

index 55974a96da7f2782ceffa57b33bf6f35dc17004c..07f9dee3e9b3adcb88782b074534c74aa23b021b 100644 (file)
@@ -109,6 +109,7 @@ static inline char *FromLatin1 (const char *latin)
 }
 
 VLC_EXPORT( char *, FromCharset, ( const char *charset, const void *data, size_t data_size ) LIBVLC_USED );
+VLC_EXPORT( void *, ToCharset, ( const char *charset, const char *in, size_t *outsize ) LIBVLC_USED );
 
 VLC_EXPORT( double, us_strtod, ( const char *, char ** ) LIBVLC_USED );
 VLC_EXPORT( float, us_strtof, ( const char *, char ** ) LIBVLC_USED );
index 03938fb0310e8f1f0ce753b6efb57114af70dee0..8d05c37e3eb00bbf0fc03e63d24cb13efcc715ca 100644 (file)
@@ -438,6 +438,7 @@ subpicture_region_Delete
 subpicture_region_New
 tls_ClientCreate
 tls_ClientDelete
+ToCharset
 ToLocale
 ToLocaleDup
 update_Check
index c39edaf2090fdf66fc41e4f9440e2e2c47675c21..83e82e889b5595bb3731ddacddbc3d81793da9a9 100644 (file)
@@ -466,3 +466,57 @@ char *FromCharset(const char *charset, const void *data, size_t data_size)
     return out;
 }
 
+/**
+ * Converts a nul-terminated UTF-8 string to a given character encoding.
+ * @param charset iconv name of the character set
+ * @param in nul-terminated UTF-8 string
+ * @param outsize pointer to hold the byte size of result
+ *
+ * @return A pointer to the result, which must be released using free().
+ * The UTF-8 nul terminator is included in the conversion if the target
+ * character encoding supports it. However it is not included in the returned
+ * byte size.
+ * In case of error, NULL is returned and the byte size is undefined.
+ */
+void *ToCharset(const char *charset, const char *in, size_t *outsize)
+{
+    vlc_iconv_t hd = vlc_iconv_open (charset, "UTF-8");
+    if (hd == (vlc_iconv_t)(-1))
+        return NULL;
+
+    const size_t inlen = strlen (in);
+    void *res;
+
+    for (unsigned mul = 4; mul < 16; mul++)
+    {
+        size_t outlen = mul * (inlen + 1);
+        res = malloc (outlen);
+        if (unlikely(res == NULL))
+            break;
+
+        const char *inp = in;
+        char *outp = res;
+        size_t inb = inlen + 1;
+        size_t outb = outlen;
+
+        if (vlc_iconv (hd, &inp, &inb, &outp, &outb) != (size_t)(-1))
+        {
+            *outsize = outlen - outb;
+            inb = 1; /* append nul terminator if possible */
+            if (vlc_iconv (hd, &inp, &inb, &outp, &outb) != (size_t)(-1))
+                break;
+            if (errno == EILSEQ) /* cannot translate nul terminator!? */
+                break;
+        }
+
+        free (res);
+        if (errno != E2BIG) /* conversion failure */
+        {
+            res = NULL;
+            break;
+        }
+    }
+    vlc_iconv_close (hd);
+    return res;
+}
+