Add a few babl libc wrappers
authorLuca Bacci <luca.bacci982@gmail.com>
Thu, 29 Dec 2022 14:14:38 +0000 (15:14 +0100)
committerØyvind "pippin" Kolås <pippin@gimp.org>
Tue, 3 Jan 2023 10:33:37 +0000 (10:33 +0000)
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
babl/babl-util.h

index cf1d8c64fcd9ef72920aa2e62de688884041745d..cc7765430afc945b3d544e03f977738f17b39194 100644 (file)
  */
 
 #include "config.h"
+#include <stdio.h>
 #include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include "babl-internal.h"
 
 #ifdef __WIN32__
 #include <windows.h>
+#include <wchar.h>
 #else
 #include <sys/time.h>
 #include <time.h>
+#include <dirent.h>
 #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,
index 82c421aa8c703eb4124435ff40cac58c9191dea7..ad094e1a110e1e5784bcae77735f24447ebd3739 100644 (file)
 #define _BABL_UTIL_H
 
 #include <stddef.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#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 *