[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