+
+/*****************************************************************************
+ * FromLocale: converts a locale string to UTF-8
+ *****************************************************************************/
+char *FromLocale( const char *locale )
+{
+ if( locale == NULL )
+ return NULL;
+
+ if( libvlc.from_locale != (vlc_iconv_t)(-1) )
+ {
+ char *iptr = (char *)locale, *output, *optr;
+ size_t inb, outb;
+
+ /*
+ * We are not allowed to modify the locale pointer, even if we cast it
+ * to non-const.
+ */
+ inb = strlen( locale );
+ /* FIXME: I'm not sure about the value for the multiplication
+ * (for western people, multiplication by 3 (Latin9) is sufficient) */
+ outb = inb * 6 + 1;
+
+ optr = output = calloc( outb , 1);
+
+ vlc_mutex_lock( &libvlc.from_locale_lock );
+ vlc_iconv( libvlc.from_locale, NULL, NULL, NULL, NULL );
+
+ while( vlc_iconv( libvlc.from_locale, &iptr, &inb, &optr, &outb )
+ == (size_t)-1 )
+ {
+ *optr++ = '?';
+ outb--;
+ iptr++;
+ inb--;
+ vlc_iconv( libvlc.from_locale, NULL, NULL, NULL, NULL );
+ }
+ vlc_mutex_unlock( &libvlc.from_locale_lock );
+
+ assert (inb == 0);
+ assert (*iptr == '\0');
+ assert (*optr == '\0');
+ assert (strlen( output ) == (size_t)(optr - output));
+ return realloc( output, optr - output + 1 );
+ }
+ return (char *)locale;
+}
+
+/*****************************************************************************
+ * ToLocale: converts an UTF-8 string to locale
+ *****************************************************************************/
+char *ToLocale( const char *utf8 )
+{
+ if( utf8 == NULL )
+ return NULL;
+
+ if( libvlc.to_locale != (vlc_iconv_t)(-1) )
+ {
+ char *iptr = (char *)utf8, *output, *optr;
+ size_t inb, outb;
+
+ /*
+ * We are not allowed to modify the locale pointer, even if we cast it
+ * to non-const.
+ */
+ inb = strlen( utf8 );
+ /* FIXME: I'm not sure about the value for the multiplication
+ * (for western people, multiplication is not needed) */
+ outb = inb * 2 + 1;
+
+ optr = output = calloc( outb, 1 );
+ vlc_mutex_lock( &libvlc.to_locale_lock );
+ vlc_iconv( libvlc.to_locale, NULL, NULL, NULL, NULL );
+
+ while( vlc_iconv( libvlc.to_locale, &iptr, &inb, &optr, &outb )
+ == (size_t)-1 )
+ {
+ *optr++ = '?'; /* should not happen, and yes, it sucks */
+ outb--;
+ iptr++;
+ inb--;
+ vlc_iconv( libvlc.to_locale, NULL, NULL, NULL, NULL );
+ }
+ vlc_mutex_unlock( &libvlc.to_locale_lock );
+
+ assert (inb == 0);
+ assert (*iptr == '\0');
+ assert (*optr == '\0');
+ assert (strlen( output ) == (size_t)(optr - output));
+ return realloc( output, optr - output + 1 );
+ }
+ return (char *)utf8;
+}
+
+void LocaleFree( const char *str )
+{
+ if( ( str != NULL ) && ( libvlc.to_locale != (vlc_iconv_t)(-1) ) )
+ free( (char *)str );
+}