diff options
author | jstebbins <[email protected]> | 2013-09-22 17:19:38 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2013-09-22 17:19:38 +0000 |
commit | 5e712218d8eb3f71a06356ed6f952b86ca947fca (patch) | |
tree | cd20ec0c7f22a94c11594deb195c7ec939dee4d1 /libhb/ports.c | |
parent | 10fda25f44d362349694a42127e8ba4974a4a6ad (diff) |
libhb: make libhb internal character code utf8
This makes libhb expect all strings passed to it to be in utf8 format.
The cli converts the converts from the current code page to utf8. libhb
converts back to the current code page when necessary for libraries that
expect it.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@5798 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb/ports.c')
-rw-r--r-- | libhb/ports.c | 139 |
1 files changed, 136 insertions, 3 deletions
diff --git a/libhb/ports.c b/libhb/ports.c index 94bb95227..0f5ed363d 100644 --- a/libhb/ports.c +++ b/libhb/ports.c @@ -47,6 +47,9 @@ #ifdef SYS_MINGW #include <pthread.h> #include <windows.h> +#include <wchar.h> +#include <mbctype.h> +#include <locale.h> #endif #ifdef SYS_SunOS @@ -100,6 +103,34 @@ int gettimeofday( struct timeval * tv, struct timezone * tz ) #endif */ +// Convert utf8 string to current code page. +// The internal string representation in hb is utf8. But some +// libraries (libmkv, and mp4v2) expect filenames in the current +// code page. So we must convert. +char * hb_utf8_to_cp(const char *src) +{ + char *dst = NULL; + +#if defined( SYS_MINGW ) + int num_chars = MultiByteToWideChar(CP_UTF8, 0, src, -1, NULL, 0); + if (num_chars <= 0) + return NULL; + wchar_t * tmp = calloc(num_chars, sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, src, -1, tmp, num_chars); + int len = WideCharToMultiByte(GetACP(), 0, tmp, num_chars, NULL, 0, NULL, NULL); + if (len <= 0) + return NULL; + dst = calloc(len, sizeof(char)); + WideCharToMultiByte(GetACP(), 0, tmp, num_chars, dst, len, NULL, NULL); + free(tmp); +#else + // Other platforms don't have code pages + dst = strdup(src); +#endif + + return dst; +} + int hb_dvd_region(char *device, int *region_mask) { #if defined( DVD_LU_SEND_RPC_STATE ) && defined( DVD_AUTH ) @@ -456,17 +487,119 @@ void hb_get_tempory_filename( hb_handle_t * h, char name[1024], } /************************************************************************ + * hb_stat + ************************************************************************ + * Wrapper to the real stat, needed to handle utf8 filenames on + * windows. + ***********************************************************************/ +int hb_stat(const char *path, hb_stat_t *sb) +{ +#ifdef SYS_MINGW + wchar_t path_utf16[MAX_PATH]; + if (!MultiByteToWideChar(CP_UTF8, 0, path, -1, path_utf16, MAX_PATH)) + return -1; + return _wstat64( path_utf16, sb ); +#else + return stat(path, sb); +#endif +} + +/************************************************************************ + * hb_fopen + ************************************************************************ + * Wrapper to the real fopen, needed to handle utf8 filenames on + * windows. + ***********************************************************************/ +FILE * hb_fopen(const char *path, const char *mode) +{ +#ifdef SYS_MINGW + FILE *f; + wchar_t path_utf16[MAX_PATH]; + wchar_t mode_utf16[16]; + if (!MultiByteToWideChar(CP_UTF8, 0, path, -1, path_utf16, MAX_PATH)) + return NULL; + if (!MultiByteToWideChar(CP_UTF8, 0, mode, -1, mode_utf16, 16)) + return NULL; + errno_t ret = _wfopen_s(&f, path_utf16, mode_utf16); + if (ret) + return NULL; + return f; +#else + return fopen(path, mode); +#endif +} + +HB_DIR* hb_opendir(char *path) +{ +#ifdef SYS_MINGW + HB_DIR *dir; + wchar_t path_utf16[MAX_PATH]; + + if (!MultiByteToWideChar(CP_UTF8, 0, path, -1, path_utf16, MAX_PATH)) + return NULL; + dir = malloc(sizeof(HB_DIR)); + if (dir == NULL) + return NULL; + dir->wdir = _wopendir(path_utf16); + if (dir->wdir == NULL) + { + free(dir); + return NULL; + } + return dir; +#else + return opendir(path); +#endif +} + +int hb_closedir(HB_DIR *dir) +{ +#ifdef SYS_MINGW + int ret; + + ret = _wclosedir(dir->wdir); + free(dir); + return ret; +#else + return closedir(dir); +#endif +} + +struct dirent * hb_readdir(HB_DIR *dir) +{ +#ifdef SYS_MINGW + struct _wdirent *entry; + entry = _wreaddir(dir->wdir); + if (entry == NULL) + return NULL; + + int len = WideCharToMultiByte(CP_UTF8, 0, entry->d_name, -1, + dir->entry.d_name, sizeof(dir->entry.d_name), + NULL, NULL ); + dir->entry.d_ino = entry->d_ino; + dir->entry.d_reclen = entry->d_reclen; + dir->entry.d_namlen = len - 1; + return &dir->entry; +#else + return readdir(dir); +#endif +} + +/************************************************************************ * hb_mkdir ************************************************************************ * Wrapper to the real mkdir, needed only because it doesn't take a * second argument on Win32. Grrr. ***********************************************************************/ -void hb_mkdir( char * name ) +int hb_mkdir(char * path) { #ifdef SYS_MINGW - mkdir( name ); + wchar_t path_utf16[MAX_PATH]; + if (!MultiByteToWideChar(CP_UTF8, 0, path, -1, path_utf16, MAX_PATH)) + return -1; + return _wmkdir(path_utf16); #else - mkdir( name, 0755 ); + return mkdir(path, 0755); #endif } |