From bb06d6cf28e46c623e701fd65e88feaaa3fd2fa1 Mon Sep 17 00:00:00 2001 From: Luca Bacci Date: Thu, 29 Dec 2022 15:14:38 +0100 Subject: [PATCH] Add a few babl libc wrappers Add the following wrappers: * babl_fopen * babl_rename * babl_remove * babl_mkdir * babl_stat And the following util: * babl_dir_list On Windows, the wrappers internally convert from UTF8 to UTF16 and call the wide char routines, that way the string need not be limited to the ANSI character set. Outside of Windows the wrappers are no-op. babl_dir_list is implemented using opendir / readdir on non-Windows and _wfindfirst64 / _wfindnext64 on Windows. --- babl/babl-util.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++ babl/babl-util.h | 43 ++++++++++++ 2 files changed, 220 insertions(+) diff --git a/babl/babl-util.c b/babl/babl-util.c index cf1d8c6..cc77654 100644 --- a/babl/babl-util.c +++ b/babl/babl-util.c @@ -17,14 +17,19 @@ */ #include "config.h" +#include #include +#include +#include #include "babl-internal.h" #ifdef __WIN32__ #include +#include #else #include #include +#include #endif #ifdef __WIN32__ @@ -101,6 +106,178 @@ babl_rel_avg_error (const double *imgA, return error; } +FILE * +_babl_fopen (const char *path, + const char *mode) +{ +#ifndef _WIN32 + return fopen (path, mode); +#else + wchar_t *path_utf16 = babl_convert_utf8_to_utf16 (path); + wchar_t *mode_utf16 = babl_convert_utf8_to_utf16 (mode); + FILE *result = NULL; + + result = _wfopen (path_utf16, mode_utf16); + + if (path_utf16) + babl_free (path_utf16); + + if (mode_utf16) + babl_free (mode_utf16); + + return result; +#endif +} + +int +_babl_remove (const char *path) +{ +#ifndef _WIN32 + return remove (path); +#else + wchar_t *path_utf16 = babl_convert_utf8_to_utf16 (path); + int result = 0; + + result = _wremove (path_utf16); + + if (path_utf16) + babl_free (path_utf16); + + return result; +#endif +} + +int +_babl_rename (const char *oldname, + const char *newname) +{ +#ifndef _WIN32 + return rename (oldname, newname); +#else + wchar_t *oldname_utf16 = babl_convert_utf8_to_utf16 (oldname); + wchar_t *newname_utf16 = babl_convert_utf8_to_utf16 (newname); + int result = 0; + + result = _wrename (oldname_utf16, newname_utf16); + + if (oldname_utf16) + babl_free (oldname_utf16); + + if (newname_utf16) + babl_free (newname_utf16); + + return result; +#endif +} + +int +_babl_stat (const char *path, + BablStat *buffer) +{ +#ifndef _WIN32 + return stat (path, buffer); +#else + wchar_t *path_utf16 = babl_convert_utf8_to_utf16 (path); + int result = 0; + + result = _wstat64 (path_utf16, buffer); + + if (path_utf16) + babl_free (path_utf16); + + return result; +#endif +} + +void +_babl_dir_foreach (const char *path, + _babl_dir_foreach_cb_t callback, + void *user_data) +{ +#ifndef _WIN32 + DIR *dir = opendir (path); + + if (!path) + return; + + if (dir != NULL) + { + struct dirent *dentry; + + while ((dentry = readdir (dir))) + callback (path, dentry->d_name, user_data); + + closedir (dir); + } +#else + char *search = NULL; + wchar_t *search_utf16 = NULL; + struct _wfinddata64_t info; + intptr_t search_id = 0; + + if (!path) + return; + + search = babl_strcat (search, path); + search = babl_strcat (search, "\\*"); + search_utf16 = babl_convert_utf8_to_utf16 (search); + if (!search_utf16) + goto cleanup; + + memset (&info, 0, sizeof (info)); + if ((search_id = _wfindfirst64 (search_utf16, &info)) != (intptr_t)-1) + { + do + { + char *entry = babl_convert_utf16_to_utf8 (info.name); + + if (entry) + { + callback (path, entry, user_data); + babl_free (entry); + } + } + while (_wfindnext64 (search_id, &info) == 0); + + _findclose (search_id); + } + +cleanup: + if (search_utf16) + babl_free (search_utf16); + + if (search) + babl_free (search); +#endif +} + +#ifndef _WIN32 + +int +_babl_mkdir (const char *path, + mode_t mode) +{ + return mkdir (path, mode); +} + +#else + +int +_babl_mkdir (const char *path) +{ + wchar_t *path_utf16 = babl_convert_utf8_to_utf16 (path); + int result = 0; + + result = _wmkdir (path_utf16); + + if (path_utf16) + babl_free (path_utf16); + + return result; +} + +#endif + int _babl_file_get_contents (const char *path, char **contents, diff --git a/babl/babl-util.h b/babl/babl-util.h index 82c421a..ad094e1 100644 --- a/babl/babl-util.h +++ b/babl/babl-util.h @@ -20,6 +20,15 @@ #define _BABL_UTIL_H #include +#include +#include +#include + +#ifndef _WIN32 +typedef struct stat BablStat; +#else +typedef struct _stat64 BablStat; +#endif long babl_ticks (void); @@ -29,6 +38,40 @@ babl_rel_avg_error (const double *imgA, const double *imgB, long samples); +FILE * +_babl_fopen (const char *path, + const char *mode); + +int +_babl_remove (const char *path); + +int +_babl_rename (const char *oldname, + const char *newname); + +int +_babl_stat (const char *path, + BablStat *buffer); + +#ifndef _WIN32 +int +_babl_mkdir (const char *path, + mode_t mode); +#else +int +_babl_mkdir (const char *path); +#endif + +typedef void +(*_babl_dir_foreach_cb_t) (const char *base_path, + const char *entry, + void *data); + +void +_babl_dir_foreach (const char *path, + _babl_dir_foreach_cb_t callback, + void *user_data); + #ifdef _WIN32 wchar_t * -- 2.30.2