[libbdplus-devel] [Git][videolan/libbdplus][master] Add directory access wrappers (from libbluray)

Petri Hintukainen (@hpi) gitlab at videolan.org
Thu Oct 7 10:07:14 UTC 2021



Petri Hintukainen pushed to branch master at VideoLAN / libbdplus


Commits:
6889d280 by anonymous at 2021-10-07T13:06:07+03:00
Add directory access wrappers (from libbluray)

- - - - -


4 changed files:

- Makefile.am
- + src/file/dir_posix.c
- + src/file/dir_win32.c
- src/file/file.h


Changes:

=====================================
Makefile.am
=====================================
@@ -69,9 +69,11 @@ endif
 
 if HAVE_WIN32
 libbdplus_la_SOURCES+= \
+	src/file/dir_win32.c \
 	src/file/file_win32.c
 else
 libbdplus_la_SOURCES+= \
+	src/file/dir_posix.c \
 	src/file/file_posix.c
 endif
 


=====================================
src/file/dir_posix.c
=====================================
@@ -0,0 +1,119 @@
+/*
+ * This file is part of libbluray
+ * Copyright (C) 2009-2010  John Stebbins
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "file.h"
+#include "util/macro.h"
+#include "util/logging.h"
+#include "util/strutl.h"
+
+#include <stdlib.h>
+#include <string.h>
+#if defined(HAVE_DIRENT_H)
+#   include <dirent.h>
+#endif
+
+#if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
+#  if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 24)
+#    define USE_READDIR
+#    include <errno.h>
+#  endif
+#endif
+
+static void _dir_close_posix(BD_DIR_H *dir)
+{
+    if (dir) {
+        closedir((DIR *)dir->internal);
+
+        BD_DEBUG(DBG_DIR, "Closed POSIX dir (%p)\n", (void*)dir);
+
+        X_FREE(dir);
+    }
+}
+
+static void _error(const char *msg, int errnum, void *dir)
+{
+    char buf[128];
+    if (strerror_r(errnum, buf, sizeof(buf))) {
+        strcpy(buf, "?");
+    }
+    BD_DEBUG(DBG_DIR | DBG_CRIT, "%s: %d %s (%p)\n", msg, errnum, buf, dir);
+}
+
+static int _dir_read_posix(BD_DIR_H *dir, BD_DIRENT *entry)
+{
+    struct dirent *p_e;
+
+#ifdef USE_READDIR
+    errno = 0;
+    p_e = readdir((DIR*)dir->internal);
+    if (!p_e && errno) {
+        _error("Error reading directory", errno, dir);
+        return -1;
+    }
+#else /* USE_READDIR */
+    int result;
+    struct dirent e;
+
+    result = readdir_r((DIR*)dir->internal, &e, &p_e);
+    if (result) {
+        _error("Error reading directory", result, dir);
+        return -result;
+    }
+#endif /* USE_READDIR */
+
+    if (p_e == NULL) {
+        return 1;
+    }
+    strncpy(entry->d_name, p_e->d_name, sizeof(entry->d_name));
+    entry->d_name[sizeof(entry->d_name) - 1] = 0;
+
+    return 0;
+}
+
+static BD_DIR_H *_dir_open_posix(const char* dirname)
+{
+    BD_DIR_H *dir = calloc(1, sizeof(BD_DIR_H));
+
+    if (!dir) {
+        return NULL;
+    }
+
+    dir->close = _dir_close_posix;
+    dir->read = _dir_read_posix;
+
+    if ((dir->internal = opendir(dirname))) {
+        BD_DEBUG(DBG_DIR, "Opened POSIX dir %s (%p)\n", dirname, (void*)dir);
+        return dir;
+    }
+
+    BD_DEBUG(DBG_DIR, "Error opening dir %s\n", dirname);
+
+    X_FREE(dir);
+
+    return NULL;
+}
+
+BD_DIR_OPEN dir_open_default(void)
+{
+    return _dir_open_posix;
+}


=====================================
src/file/dir_win32.c
=====================================
@@ -0,0 +1,134 @@
+/*
+ * This file is part of libbluray
+ * Copyright (C) 2009-2010  John Stebbins
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "file.h"
+#include "util/macro.h"
+#include "util/logging.h"
+#include "util/strutl.h"
+
+#include <stdlib.h>
+#include <string.h>
+#if defined(HAVE_DIRENT_H)
+#   include <dirent.h>
+#endif
+
+#include <io.h>
+#include <windows.h>
+
+
+typedef struct {
+    intptr_t            handle;
+    struct _wfinddata_t info;
+} dir_data_t;
+
+static void _dir_close_win32(BD_DIR_H *dir)
+{
+    if (dir) {
+        dir_data_t *priv = (dir_data_t*)dir->internal;
+
+        _findclose(priv->handle);
+
+        BD_DEBUG(DBG_DIR, "Closed WIN32 dir (%p)\n", (void*)dir);
+
+        X_FREE(dir->internal);
+        X_FREE(dir);
+    }
+}
+
+static int _dir_read_win32(BD_DIR_H *dir, BD_DIRENT *entry)
+{
+    dir_data_t *priv = (dir_data_t*)dir->internal;
+
+    if (!priv->info.name[0]) {
+        return 1;
+    }
+    if (!WideCharToMultiByte(CP_UTF8, 0, priv->info.name, -1, entry->d_name, sizeof(entry->d_name), NULL, NULL)) {
+        return -1;
+    }
+
+    priv->info.name[0] = 0;
+    _wfindnext(priv->handle, &priv->info);
+
+    return 0;
+}
+
+static dir_data_t *_open_impl(const char *dirname)
+{
+    dir_data_t *priv;
+    char *filespec;
+    wchar_t wfilespec[MAX_PATH];
+    int result;
+
+    filespec = str_printf("%s" DIR_SEP "*", dirname);
+    if (!filespec) {
+        return NULL;
+    }
+
+    result = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filespec, -1, wfilespec, MAX_PATH);
+    X_FREE(filespec);
+    if (!result) {
+        return NULL;
+    }
+
+    priv = calloc(1, sizeof(dir_data_t));
+    if (!priv) {
+        return NULL;
+    }
+
+    priv->handle = _wfindfirst(wfilespec, &priv->info);
+    if (priv->handle == -1) {
+        X_FREE(priv);
+    }
+
+    return priv;
+}
+
+static BD_DIR_H *_dir_open_win32(const char* dirname)
+{
+    BD_DIR_H *dir = calloc(1, sizeof(BD_DIR_H));
+    dir_data_t *priv = NULL;
+
+    if (!dir) {
+        return NULL;
+    }
+
+    priv = _open_impl(dirname);
+    if (priv) {
+        BD_DEBUG(DBG_DIR, "Opened WIN32 dir %s (%p)\n", dirname, (void*)dir);
+        dir->close = _dir_close_win32;
+        dir->read = _dir_read_win32;
+        dir->internal = priv;
+
+        return dir;
+    }
+
+    BD_DEBUG(DBG_DIR, "Error opening dir %s\n", dirname);
+    X_FREE(dir);
+
+    return NULL;
+}
+
+BD_DIR_OPEN dir_open_default(void)
+{
+    return _dir_open_win32;
+}


=====================================
src/file/file.h
=====================================
@@ -68,6 +68,30 @@ BD_PRIVATE int64_t file_size(BD_FILE_H *fp);
 
 BD_PRIVATE BDPLUS_FILE_OPEN file_open_default(void);
 
+/*
+ * directory access
+ */
+
+typedef struct
+{
+    char    d_name[256];
+} BD_DIRENT;
+
+typedef struct bdplus_dir_s BD_DIR_H;
+struct bdplus_dir_s
+{
+    void* internal;
+    void (*close)(BD_DIR_H *dir);
+    int (*read)(BD_DIR_H *dir, BD_DIRENT *entry);
+};
+
+typedef BD_DIR_H* (*BD_DIR_OPEN) (const char* dirname);
+
+#define dir_close(X) X->close(X)
+#define dir_read(X,Y) X->read(X,Y)
+
+BD_PRIVATE BD_DIR_OPEN dir_open_default(void);
+
 /*
  * local filesystem
  */



View it on GitLab: https://code.videolan.org/videolan/libbdplus/-/commit/6889d280befd3b091538bb876b1eafe0134a83ea

-- 
View it on GitLab: https://code.videolan.org/videolan/libbdplus/-/commit/6889d280befd3b091538bb876b1eafe0134a83ea
You're receiving this email because of your account on code.videolan.org.




More information about the libbdplus-devel mailing list