Create retro_dirent.c/retro_dirent.h

This commit is contained in:
twinaphex 2015-09-04 18:38:29 +02:00
parent 6006fa98b2
commit 56c8a57e0c
5 changed files with 232 additions and 129 deletions

View File

@ -130,6 +130,7 @@ OBJ += frontend/frontend.o \
content.o \
libretro-common/file/file_list.o \
libretro-common/file/dir_list.o \
libretro-common/file/retro_dirent.o \
libretro-common/string/string_list.o \
libretro-common/string/stdstring.o \
libretro-common/memmap/memalign.o \

View File

@ -584,6 +584,7 @@ FILE
#ifndef IOS
#include "../libretro-common/file/dir_list.c"
#endif
#include "../libretro-common/file/retro_dirent.c"
#include "../dir_list_special.c"
#include "../libretro-common/string/string_list.c"
#include "../libretro-common/string/stdstring.c"

View File

@ -20,36 +20,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <file/dir_list.h>
#include <file/file_path.h>
#include <compat/strl.h>
#include <compat/posix_string.h>
#if defined(_WIN32)
#ifdef _MSC_VER
#define setmode _setmode
#endif
#ifdef _XBOX
#include <xtl.h>
#define INVALID_FILE_ATTRIBUTES -1
#else
#include <io.h>
#include <fcntl.h>
#include <direct.h>
#include <windows.h>
#endif
#elif defined(VITA)
#include <psp2/io/fcntl.h>
#include <psp2/io/dirent.h>
#else
#if defined(PSP)
#include <pspiofilemgr.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#endif
#include <retro_dirent.h>
#include <retro_miscellaneous.h>
@ -102,46 +79,6 @@ void dir_list_free(struct string_list *list)
string_list_free(list);
}
/**
*
* dirent_is_directory:
* @path : path to the directory entry.
* @entry : pointer to the directory entry.
*
* Is the directory listing entry a directory?
*
* Returns: true if directory listing entry is
* a directory, false if not.
*/
static bool dirent_is_directory(const char *path, const void *data)
{
#if defined(_WIN32)
const WIN32_FIND_DATA *entry = (const WIN32_FIND_DATA*)data;
return entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
#elif defined(PSP) || defined(VITA)
const SceIoDirent *entry = (const SceIoDirent*)data;
#if defined(PSP)
return (entry->d_stat.st_attr & FIO_SO_IFDIR) == FIO_SO_IFDIR;
#elif defined(VITA)
return PSP2_S_ISDIR(entry->d_stat.st_mode);
#endif
#elif defined(DT_DIR)
const struct dirent *entry = (const struct dirent*)data;
if (entry->d_type == DT_DIR)
return true;
else if (entry->d_type == DT_UNKNOWN /* This can happen on certain file systems. */
|| entry->d_type == DT_LNK)
return path_is_directory(path);
return false;
#else /* dirent struct doesn't have d_type, do it the slow way ... */
const struct dirent *entry = (const struct dirent*)data;
return path_is_directory(path);
#endif
}
/**
* parse_dir_entry:
* @name : name of the directory listing entry.
@ -208,44 +145,6 @@ static int parse_dir_entry(const char *name, char *file_path,
return 0;
}
#if defined(_WIN32)
#define dirent_opendir(directory, dir) \
{ \
char path_buf[PATH_MAX_LENGTH]; \
snprintf(path_buf, sizeof(path_buf), "%s\\*", dir); \
directory = FindFirstFile(path_buf, &entry); \
}
#elif defined(VITA) || defined(PSP)
#define dirent_opendir(directory, dir) directory = sceIoDopen(dir)
#else
#define dirent_opendir(directory, dir) directory = opendir(dir)
#endif
#if defined(_WIN32)
#define dirent_error(directory) ((directory) == INVALID_HANDLE_VALUE)
#elif defined(VITA) || defined(PSP)
#define dirent_error(directory) ((directory) < 0)
#else
#define dirent_error(directory) (!(directory))
#endif
#if defined(_WIN32)
#define dirent_readdir(directory, entry) (FindNextFile((directory), &(entry)) != 0)
#elif defined(VITA) || defined(PSP)
#define dirent_readdir(directory, entry) (sceIoDread((directory), &(entry)) > 0)
#else
#define dirent_readdir(directory, entry) (entry = readdir(directory))
#endif
#if defined(_WIN32)
#define dirent_closedir(directory) if (directory != INVALID_HANDLE_VALUE) FindClose(directory)
#elif defined(VITA) || defined(PSP)
#define dirent_closedir(directory) sceIoDclose(directory)
#else
#define dirent_closedir(directory) if (directory) closedir(directory)
#endif
/**
* dir_list_new:
* @dir : directory path.
@ -261,16 +160,7 @@ static int parse_dir_entry(const char *name, char *file_path,
struct string_list *dir_list_new(const char *dir,
const char *ext, bool include_dirs, bool include_compressed)
{
#if defined(_WIN32)
WIN32_FIND_DATA entry;
HANDLE directory = INVALID_HANDLE_VALUE;
#elif defined(VITA) || defined(PSP)
SceUID directory;
SceIoDirent entry;
#else
DIR *directory = NULL;
const struct dirent *entry = NULL;
#endif
struct RDIR *entry = NULL;
struct string_list *ext_list = NULL;
struct string_list *list = NULL;
@ -280,25 +170,20 @@ struct string_list *dir_list_new(const char *dir,
if (ext)
ext_list = string_split(ext, "|");
dirent_opendir(directory, dir);
entry = retro_opendir(dir);
if (dirent_error(directory))
if (!entry)
goto error;
while (dirent_readdir(directory, entry))
if (retro_dirent_error(entry))
goto error;
while (retro_readdir(entry))
{
char file_path[PATH_MAX_LENGTH];
int ret = 0;
#ifdef _WIN32
const char *name = entry.cFileName;
bool is_dir = dirent_is_directory(file_path, &entry);
#elif defined(VITA) || defined(PSP)
const char *name = entry.d_name;
bool is_dir = dirent_is_directory(file_path, &entry);
#else
const char *name = entry->d_name;
bool is_dir = dirent_is_directory(file_path, entry);
#endif
const char *name = retro_dirent_get_name(entry);
bool is_dir = retro_dirent_is_dir(entry, file_path);
const char *file_ext = path_get_extension(name);
fill_pathname_join(file_path, dir, name, sizeof(file_path));
@ -313,13 +198,13 @@ struct string_list *dir_list_new(const char *dir,
continue;
}
dirent_closedir(directory);
retro_closedir(entry);
string_list_free(ext_list);
return list;
error:
dirent_closedir(directory);
retro_closedir(entry);
string_list_free(list);
string_list_free(ext_list);

View File

@ -0,0 +1,155 @@
#include <stdlib.h>
#if defined(_WIN32)
#ifdef _MSC_VER
#define setmode _setmode
#endif
#ifdef _XBOX
#include <xtl.h>
#define INVALID_FILE_ATTRIBUTES -1
#else
#include <io.h>
#include <fcntl.h>
#include <direct.h>
#include <windows.h>
#endif
#elif defined(VITA)
#include <psp2/io/fcntl.h>
#include <psp2/io/dirent.h>
#else
#if defined(PSP)
#include <pspiofilemgr.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#endif
#include <boolean.h>
#include <file/file_path.h>
struct RDIR
{
#if defined(_WIN32)
WIN32_FIND_DATA entry;
HANDLE directory;
#elif defined(VITA) || defined(PSP)
SceUID directory;
SceIoDirent entry;
#else
DIR *directory;
const struct dirent *entry;
#endif
};
struct RDIR *retro_opendir(const char *name)
{
char path_buf[1024];
struct RDIR *rdir = (struct RDIR*)calloc(1, sizeof(*rdir));
if (!rdir)
return NULL;
#if defined(_WIN32)
snprintf(path_buf, sizeof(path_buf), "%s\\*", name);
rdir->directory = FindFirstFile(path_buf, &rdir->entry);
#elif defined(VITA) || defined(PSP)
rdir->directory = sceIoDopen(name);
rdir->entry = NULL;
#else
rdir->directory = opendir(name);
rdir->entry = NULL;
#endif
return rdir;
}
bool retro_dirent_error(struct RDIR *rdir)
{
#if defined(_WIN32)
return (rdir->directory == INVALID_HANDLE_VALUE);
#elif defined(VITA) || defined(PSP)
return (rdir->directory < 0);
#else
return !(rdir->directory);
#endif
}
int retro_readdir(struct RDIR *rdir)
{
#if defined(_WIN32)
return (FindNextFile(rdir->directory, &rdir->entry) != 0);
#elif defined(VITA) || defined(PSP)
return (sceIoDread(rdir->directory, &rdir->entry) > 0);
#else
return ((rdir->entry = readdir(rdir->directory)) != NULL);
#endif
}
const char *retro_dirent_get_name(struct RDIR *rdir)
{
#if defined(_WIN32)
return rdir->entry.cFileName;
#elif defined(VITA) || defined(PSP)
return rdir->entry.d_name;
#else
return rdir->entry->d_name;
#endif
}
/**
*
* retro_dirent_is_dir:
* @rdir : pointer to the directory entry.
* @path : path to the directory entry.
*
* Is the directory listing entry a directory?
*
* Returns: true if directory listing entry is
* a directory, false if not.
*/
bool retro_dirent_is_dir(struct RDIR *rdir, const char *path)
{
#if defined(_WIN32)
const WIN32_FIND_DATA *entry = (const WIN32_FIND_DATA*)rdir->entry;
return entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
#elif defined(PSP) || defined(VITA)
const SceIoDirent *entry = (const SceIoDirent*)rdir->entry;
#if defined(PSP)
return (entry->d_stat.st_attr & FIO_SO_IFDIR) == FIO_SO_IFDIR;
#elif defined(VITA)
return PSP2_S_ISDIR(entry->d_stat.st_mode);
#endif
#elif defined(DT_DIR)
const struct dirent *entry = (const struct dirent*)rdir->entry;
if (entry->d_type == DT_DIR)
return true;
else if (entry->d_type == DT_UNKNOWN /* This can happen on certain file systems. */
|| entry->d_type == DT_LNK)
return path_is_directory(path);
return false;
#else /* dirent struct doesn't have d_type, do it the slow way ... */
const struct dirent *entry = (const struct dirent*)data;
return path_is_directory(path);
#endif
}
void retro_closedir(struct RDIR *rdir)
{
if (!rdir)
return;
#if defined(_WIN32)
if (rdir->directory != INVALID_HANDLE_VALUE)
FindClose(rdir->directory);
#elif defined(VITA) || defined(PSP)
sceIoDclose(rdir->directory);
#else
if (rdir->directory)
closedir(rdir->directory);
#endif
free(rdir);
}

View File

@ -0,0 +1,61 @@
/* Copyright (C) 2010-2015 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (retro_dirent.h).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __RETRO_DIRENT_H
#define __RETRO_DIRENT_H
#include <boolean.h>
#ifdef __cplusplus
extern "C" {
#endif
struct RDIR;
struct RDIR *retro_opendir(const char *name);
int retro_readdir(struct RDIR *rdir);
bool retro_dirent_error(struct RDIR *rdir);
const char *retro_dirent_get_name(struct RDIR *rdir);
/**
*
* retro_dirent_is_dir:
* @rdir : pointer to the directory entry.
* @path : path to the directory entry.
*
* Is the directory listing entry a directory?
*
* Returns: true if directory listing entry is
* a directory, false if not.
*/
bool retro_dirent_is_dir(struct RDIR *rdir, const char *path);
void retro_closedir(struct RDIR *rdir);
#ifdef __cplusplus
}
#endif
#endif