Commit f8471e1d authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Add ToCharset() helper to convert from UTF-8

parent 67a62cc7
...@@ -109,6 +109,7 @@ static inline char *FromLatin1 (const char *latin) ...@@ -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( 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( double, us_strtod, ( const char *, char ** ) LIBVLC_USED );
VLC_EXPORT( float, us_strtof, ( const char *, char ** ) LIBVLC_USED ); VLC_EXPORT( float, us_strtof, ( const char *, char ** ) LIBVLC_USED );
......
...@@ -438,6 +438,7 @@ subpicture_region_Delete ...@@ -438,6 +438,7 @@ subpicture_region_Delete
subpicture_region_New subpicture_region_New
tls_ClientCreate tls_ClientCreate
tls_ClientDelete tls_ClientDelete
ToCharset
ToLocale ToLocale
ToLocaleDup ToLocaleDup
update_Check update_Check
......
...@@ -466,3 +466,57 @@ char *FromCharset(const char *charset, const void *data, size_t data_size) ...@@ -466,3 +466,57 @@ char *FromCharset(const char *charset, const void *data, size_t data_size)
return out; 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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment