Commit adf38793 authored by Christophe Massiot's avatar Christophe Massiot

* src/misc/charset.c: New function vlc_fix_readdir_charset. It is used

   under Mac OS X to transform UTF-8-MAC returned by readdir() into
   UTF-8. Darwin always uses UTF-8 internally, so we vlc_current_charset
   should always return UTF-8. Also made vlc_current_charset()
   thread-safe and added a few missing const's.
parent 6ef8ef2a
/*****************************************************************************
* charset.h: Determine a canonical name for the current locale's character encoding.
*****************************************************************************
* Copyright (C) 2003 the VideoLAN team
* Copyright (C) 2003-2005 the VideoLAN team
* $Id$
*
* Author: Derk-Jan Hartman <thedj at users.sourceforge.net>
......@@ -30,6 +30,7 @@ VLC_EXPORT( void, LocaleFree, ( const char * ) );
VLC_EXPORT( char *, FromLocale, ( const char * ) );
VLC_EXPORT( char *, ToLocale, ( const char * ) );
VLC_EXPORT( char *, EnsureUTF8, ( char * ) );
VLC_EXPORT( char *, vlc_fix_readdir_charset, ( vlc_object_t *, const char * ) );
# ifdef __cplusplus
}
......
......@@ -69,6 +69,8 @@ struct libvlc_t
char * psz_vlcpath;
#elif defined( SYS_DARWIN )
char * psz_vlcpath;
vlc_iconv_t iconv_macosx; /* for HFS+ file names */
vlc_mutex_t iconv_lock;
#elif defined( WIN32 ) && !defined( UNDER_CE )
SIGNALOBJECTANDWAIT SignalObjectAndWait;
vlc_bool_t b_fast_mutex;
......
......@@ -387,6 +387,7 @@ struct module_symbols_t
void (*LocaleFree_inner) (const char *);
char * (*ToLocale_inner) (const char *);
char * (*EnsureUTF8_inner) (char *);
char * (*vlc_fix_readdir_charset_inner) (vlc_object_t *, const char *);
};
# if defined (__PLUGIN__)
# define aout_FiltersCreatePipeline (p_symbols)->aout_FiltersCreatePipeline_inner
......@@ -759,6 +760,7 @@ struct module_symbols_t
# define LocaleFree (p_symbols)->LocaleFree_inner
# define ToLocale (p_symbols)->ToLocale_inner
# define EnsureUTF8 (p_symbols)->EnsureUTF8_inner
# define vlc_fix_readdir_charset (p_symbols)->vlc_fix_readdir_charset_inner
# elif defined (HAVE_DYNAMIC_PLUGINS) && !defined (__BUILTIN__)
/******************************************************************
* STORE_SYMBOLS: store VLC APIs into p_symbols for plugin access.
......@@ -1134,6 +1136,7 @@ struct module_symbols_t
((p_symbols)->LocaleFree_inner) = LocaleFree; \
((p_symbols)->ToLocale_inner) = ToLocale; \
((p_symbols)->EnsureUTF8_inner) = EnsureUTF8; \
((p_symbols)->vlc_fix_readdir_charset_inner) = vlc_fix_readdir_charset; \
(p_symbols)->net_ConvertIPv4_deprecated = NULL; \
# endif /* __PLUGIN__ */
......
......@@ -43,6 +43,11 @@
# include <windows.h>
#endif
#ifdef SYS_DARWIN
# include <errno.h>
# include <string.h>
#endif
#include "charset.h"
typedef struct VLCCharsetAlias
......@@ -198,14 +203,14 @@ static const char* vlc_charset_aliases( const char *psz_name )
/* Returns charset from "language_COUNTRY.charset@modifier" string */
#if defined WIN32 || defined OS2 || !HAVE_LANGINFO_CODESET
static char *vlc_encoding_from_locale( char *psz_locale )
static const char *vlc_encoding_from_locale( char *psz_locale )
{
char *psz_dot = strchr( psz_locale, '.' );
if( psz_dot != NULL )
{
const char *psz_modifier;
static char buf[2 + 10 + 1];
char buf[2 + 10 + 1];
psz_dot++;
......@@ -223,7 +228,7 @@ static char *vlc_encoding_from_locale( char *psz_locale )
}
}
/* try language mapping */
return (char *)vlc_encoding_from_language( psz_locale );
return vlc_encoding_from_language( psz_locale );
}
#endif
......@@ -231,7 +236,7 @@ vlc_bool_t vlc_current_charset( char **psz_charset )
{
const char *psz_codeset;
#if !(defined WIN32 || defined OS2)
#if !(defined WIN32 || defined OS2 || defined SYS_DARWIN)
# if HAVE_LANGINFO_CODESET
/* Most systems support nl_langinfo( CODESET ) nowadays. */
......@@ -263,9 +268,14 @@ vlc_bool_t vlc_current_charset( char **psz_charset )
psz_codeset = vlc_encoding_from_locale( (char *)psz_locale );
# endif /* HAVE_LANGINFO_CODESET */
#elif defined SYS_DARWIN
/* Darwin is always using UTF-8 internally. */
psz_codeset = "UTF-8";
#elif defined WIN32
static char buf[2 + 10 + 1];
char buf[2 + 10 + 1];
/* Woe32 has a function returning the locale's codepage as a number. */
sprintf( buf, "CP%u", GetACP() );
......@@ -274,7 +284,7 @@ vlc_bool_t vlc_current_charset( char **psz_charset )
#elif defined OS2
const char *psz_locale;
static char buf[2 + 10 + 1];
char buf[2 + 10 + 1];
ULONG cp[3];
ULONG cplen;
......@@ -318,7 +328,7 @@ vlc_bool_t vlc_current_charset( char **psz_charset )
}
if( psz_charset )
*psz_charset = strdup((char *)psz_codeset);
*psz_charset = strdup(psz_codeset);
if( !strcasecmp(psz_codeset, "UTF8") || !strcasecmp(psz_codeset, "UTF-8") )
return VLC_TRUE;
......@@ -326,3 +336,34 @@ vlc_bool_t vlc_current_charset( char **psz_charset )
return VLC_FALSE;
}
char *vlc_fix_readdir_charset( vlc_object_t *p_this, const char *psz_string )
{
#ifdef SYS_DARWIN
if ( p_this->p_libvlc->iconv_macosx != (vlc_iconv_t)-1 )
{
const char *psz_in = psz_string;
size_t i_in = strlen(psz_in);
size_t i_out = i_in * 2;
char *psz_utf8 = malloc(i_out + 1);
char *psz_out = psz_utf8;
vlc_mutex_lock( &p_this->p_libvlc->iconv_lock );
size_t i_ret = vlc_iconv( p_this->p_libvlc->iconv_macosx,
&psz_in, &i_in, &psz_out, &i_out );
vlc_mutex_unlock( &p_this->p_libvlc->iconv_lock );
if( i_ret == (size_t)-1 || i_in )
{
msg_Warn( p_this,
"failed to convert \"%s\" from HFS+ charset (%s)",
psz_string, strerror(errno) );
free( psz_utf8 );
return strdup( psz_string );
}
*psz_out = '\0';
return psz_utf8;
}
#endif
return strdup( psz_string );
}
......@@ -27,6 +27,7 @@
#include <vlc/vlc.h>
#include <Cocoa/Cocoa.h>
#include <CoreFoundation/CFString.h>
#ifdef HAVE_LOCALE_H
# include <locale.h>
......@@ -114,6 +115,9 @@ void system_Init( vlc_t *p_this, int *pi_argc, char *ppsz_argv[] )
[o_pool release];
}
vlc_mutex_init( p_this, &p_this->p_libvlc->iconv_lock );
p_this->p_libvlc->iconv_macosx = vlc_iconv_open( "UTF-8", "UTF-8-MAC" );
}
/*****************************************************************************
......@@ -130,5 +134,9 @@ void system_Configure( vlc_t *p_this, int *pi_argc, char *ppsz_argv[] )
void system_End( vlc_t *p_this )
{
free( p_this->p_libvlc->psz_vlcpath );
if ( p_this->p_libvlc->iconv_macosx != (vlc_iconv_t)-1 )
vlc_iconv_close( p_this->p_libvlc->iconv_macosx );
vlc_mutex_destroy( &p_this->p_libvlc->iconv_lock );
}
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