mirror of
https://github.com/CTCaer/RetroArch.git
synced 2025-01-20 18:02:12 +00:00
win32: use unicode functions for file IO if supported
This commit is contained in:
parent
f3c57ee343
commit
1b1d5c468d
@ -20,7 +20,6 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
@ -350,3 +349,68 @@ char* local_to_utf8_string_alloc(const char *str)
|
||||
return mb_to_mb_string_alloc(str, CODEPAGE_LOCAL, CODEPAGE_UTF8);
|
||||
}
|
||||
|
||||
/* Returned pointer MUST be freed by the caller if non-NULL. */
|
||||
wchar_t* utf8_to_utf16_string_alloc(const char *str)
|
||||
{
|
||||
size_t len, out_len;
|
||||
wchar_t *buf;
|
||||
|
||||
if (!str || !*str)
|
||||
return NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
|
||||
|
||||
buf = (wchar_t*)calloc(len, sizeof(wchar_t));
|
||||
|
||||
out_len = MultiByteToWideChar(CP_UTF8, 0, str, -1, buf, len);
|
||||
#else
|
||||
/* NOTE: For now, assume non-Windows platforms' locale is already UTF-8. */
|
||||
len = mbstowcs(NULL, str, 0) + 1;
|
||||
|
||||
buf = (wchar_t*)calloc(len, sizeof(wchar_t));
|
||||
|
||||
out_len = mbstowcs(buf, str, len);
|
||||
#endif
|
||||
|
||||
if (out_len < 0)
|
||||
{
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Returned pointer MUST be freed by the caller if non-NULL. */
|
||||
char* utf16_to_utf8_string_alloc(const wchar_t *str)
|
||||
{
|
||||
size_t len, out_len;
|
||||
char *buf;
|
||||
|
||||
if (!str || !*str)
|
||||
return NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
len = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
|
||||
|
||||
buf = (char*)calloc(len, sizeof(char));
|
||||
|
||||
out_len = WideCharToMultiByte(CP_UTF8, 0, str, -1, buf, len, NULL, NULL);
|
||||
#else
|
||||
/* NOTE: For now, assume non-Windows platforms' locale is already UTF-8. */
|
||||
len = wcstombs(NULL, str, 0) + 1;
|
||||
|
||||
buf = (char*)calloc(len, sizeof(char));
|
||||
|
||||
out_len = wcstombs(buf, str, len);
|
||||
#endif
|
||||
|
||||
if (out_len < 0)
|
||||
{
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
@ -116,11 +116,17 @@ static bool path_stat(const char *path, enum stat_mode mode, int32_t *size)
|
||||
return false;
|
||||
#elif defined(_WIN32)
|
||||
struct _stat buf;
|
||||
char *path_local;
|
||||
wchar_t *path_wide;
|
||||
|
||||
if (!path || !*path)
|
||||
return false;
|
||||
|
||||
char *path_local = utf8_to_local_string_alloc(path);
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1400
|
||||
(void)path_wide;
|
||||
|
||||
/* assume W-functions do not work below VC2005 */
|
||||
path_local = utf8_to_local_string_alloc(path);
|
||||
|
||||
DWORD file_info = GetFileAttributes(path_local);
|
||||
|
||||
@ -128,6 +134,18 @@ static bool path_stat(const char *path, enum stat_mode mode, int32_t *size)
|
||||
|
||||
if (path_local)
|
||||
free(path_local);
|
||||
#else
|
||||
(void)path_local;
|
||||
|
||||
path_wide = utf8_to_utf16_string_alloc(path);
|
||||
|
||||
DWORD file_info = GetFileAttributesW(path_wide);
|
||||
|
||||
_wstat(path_wide, &buf);
|
||||
|
||||
if (path_wide)
|
||||
free(path_wide);
|
||||
#endif
|
||||
|
||||
if (file_info == INVALID_FILE_ATTRIBUTES)
|
||||
return false;
|
||||
@ -897,10 +915,16 @@ void fill_short_pathname_representation_noext(char* out_rep,
|
||||
|
||||
int path_file_remove(const char *path)
|
||||
{
|
||||
char *path_local;
|
||||
wchar_t *path_wide;
|
||||
|
||||
if (!path || !*path)
|
||||
return false;
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
char *path_local = utf8_to_local_string_alloc(path);
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1400
|
||||
(void)path_wide;
|
||||
|
||||
path_local = utf8_to_local_string_alloc(path);
|
||||
|
||||
if (path_local)
|
||||
{
|
||||
@ -909,6 +933,19 @@ int path_file_remove(const char *path)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
(void)path_local;
|
||||
|
||||
path_wide = utf8_to_utf16_string_alloc(path);
|
||||
|
||||
if (path_wide)
|
||||
{
|
||||
bool ret = _wremove(path_wide);
|
||||
free(path_wide);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
return remove(path);
|
||||
#endif
|
||||
|
@ -70,7 +70,11 @@
|
||||
struct RDIR
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1400
|
||||
WIN32_FIND_DATA entry;
|
||||
#else
|
||||
WIN32_FIND_DATAW entry;
|
||||
#endif
|
||||
HANDLE directory;
|
||||
bool next;
|
||||
char path[PATH_MAX_LENGTH];
|
||||
@ -92,6 +96,7 @@ struct RDIR *retro_opendir(const char *name)
|
||||
#if defined(_WIN32)
|
||||
char path_buf[1024];
|
||||
char *path_local = NULL;
|
||||
wchar_t *path_wide = NULL;
|
||||
#endif
|
||||
struct RDIR *rdir = (struct RDIR*)calloc(1, sizeof(*rdir));
|
||||
|
||||
@ -101,11 +106,23 @@ struct RDIR *retro_opendir(const char *name)
|
||||
#if defined(_WIN32)
|
||||
path_buf[0] = '\0';
|
||||
snprintf(path_buf, sizeof(path_buf), "%s\\*", name);
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1400
|
||||
(void)path_wide;
|
||||
|
||||
path_local = utf8_to_local_string_alloc(path_buf);
|
||||
rdir->directory = FindFirstFile(path_local, &rdir->entry);
|
||||
|
||||
if (path_local)
|
||||
free(path_local);
|
||||
#else
|
||||
(void)path_local;
|
||||
|
||||
path_wide = utf8_to_utf16_string_alloc(path_buf);
|
||||
rdir->directory = FindFirstFileW(path_wide, &rdir->entry);
|
||||
|
||||
if (path_wide)
|
||||
free(path_wide);
|
||||
#endif
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
rdir->directory = sceIoDopen(name);
|
||||
#elif defined(_3DS)
|
||||
@ -138,7 +155,11 @@ int retro_readdir(struct RDIR *rdir)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
if(rdir->next)
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1400
|
||||
return (FindNextFile(rdir->directory, &rdir->entry) != 0);
|
||||
#else
|
||||
return (FindNextFileW(rdir->directory, &rdir->entry) != 0);
|
||||
#endif
|
||||
|
||||
rdir->next = true;
|
||||
return (rdir->directory != INVALID_HANDLE_VALUE);
|
||||
@ -156,13 +177,22 @@ int retro_readdir(struct RDIR *rdir)
|
||||
const char *retro_dirent_get_name(struct RDIR *rdir)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1400
|
||||
char *name_local = local_to_utf8_string_alloc(rdir->entry.cFileName);
|
||||
memset(rdir->entry.cFileName, 0, sizeof(rdir->entry.cFileName));
|
||||
strlcpy(rdir->entry.cFileName, name_local, sizeof(rdir->entry.cFileName));
|
||||
|
||||
if (name_local)
|
||||
free(name_local);
|
||||
return rdir->entry.cFileName;
|
||||
#else
|
||||
char *name = utf16_to_utf8_string_alloc(rdir->entry.cFileName);
|
||||
memset(rdir->entry.cFileName, 0, sizeof(rdir->entry.cFileName));
|
||||
strlcpy((char*)rdir->entry.cFileName, name, sizeof(rdir->entry.cFileName));
|
||||
|
||||
if (name)
|
||||
free(name);
|
||||
#endif
|
||||
return (char*)rdir->entry.cFileName;
|
||||
#elif defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__)
|
||||
return rdir->entry.d_name;
|
||||
#else
|
||||
|
@ -58,6 +58,10 @@ char* utf8_to_local_string_alloc(const char *str);
|
||||
|
||||
char* local_to_utf8_string_alloc(const char *str);
|
||||
|
||||
wchar_t* utf8_to_utf16_string_alloc(const char *str);
|
||||
|
||||
char* utf16_to_utf8_string_alloc(const wchar_t *str);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user