mirror of
https://github.com/libretro/libretro-common.git
synced 2024-11-23 16:19:50 +00:00
Resync
This commit is contained in:
parent
596ab8a25a
commit
44c8c11348
@ -87,7 +87,7 @@ dylib_t dylib_load(const char *path)
|
||||
fill_pathname_abbreviate_special(relative_path_abbrev, path, PATH_MAX_LENGTH * sizeof(char));
|
||||
|
||||
char *relative_path = relative_path_abbrev;
|
||||
if (relative_path[0] != ':' || !path_char_is_slash(relative_path[1]))
|
||||
if (relative_path[0] != ':' || !PATH_CHAR_IS_SLASH(relative_path[1]))
|
||||
{
|
||||
/* Path to dylib_load is not inside app install directory.
|
||||
* Loading will probably fail. */
|
||||
|
@ -571,7 +571,7 @@ void path_parent_dir(char *path)
|
||||
|
||||
len = strlen(path);
|
||||
|
||||
if (len && path_char_is_slash(path[len - 1]))
|
||||
if (len && PATH_CHAR_IS_SLASH(path[len - 1]))
|
||||
{
|
||||
bool path_was_absolute = path_is_absolute(path);
|
||||
|
||||
@ -1004,7 +1004,7 @@ void fill_pathname_expand_special(char *out_path,
|
||||
out_path += src_size;
|
||||
size -= src_size;
|
||||
|
||||
if (!path_char_is_slash(out_path[-1]))
|
||||
if (!PATH_CHAR_IS_SLASH(out_path[-1]))
|
||||
{
|
||||
src_size = strlcpy(out_path, PATH_DEFAULT_SLASH(), size);
|
||||
retro_assert(src_size < size);
|
||||
@ -1035,7 +1035,7 @@ void fill_pathname_expand_special(char *out_path,
|
||||
out_path += src_size;
|
||||
size -= src_size;
|
||||
|
||||
if (!path_char_is_slash(out_path[-1]))
|
||||
if (!PATH_CHAR_IS_SLASH(out_path[-1]))
|
||||
{
|
||||
src_size = strlcpy(out_path, PATH_DEFAULT_SLASH(), size);
|
||||
retro_assert(src_size < size);
|
||||
@ -1098,7 +1098,7 @@ void fill_pathname_abbreviate_special(char *out_path,
|
||||
size -= src_size;
|
||||
in_path += strlen(candidates[i]);
|
||||
|
||||
if (!path_char_is_slash(*in_path))
|
||||
if (!PATH_CHAR_IS_SLASH(*in_path))
|
||||
{
|
||||
retro_assert(strlcpy(out_path,
|
||||
PATH_DEFAULT_SLASH(), size) < size);
|
||||
@ -1286,7 +1286,9 @@ bool is_path_accessible_using_standard_io(const char *path)
|
||||
char *relative_path_abbrev = (char*)malloc(path_sizeof);
|
||||
fill_pathname_abbreviate_special(relative_path_abbrev, path, path_sizeof);
|
||||
|
||||
result = strlen(relative_path_abbrev) >= 2 && (relative_path_abbrev[0] == ':' || relative_path_abbrev[0] == '~') && path_char_is_slash(relative_path_abbrev[1]);
|
||||
result = (strlen(relative_path_abbrev) >= 2 )
|
||||
&& (relative_path_abbrev[0] == ':' || relative_path_abbrev[0] == '~')
|
||||
&& PATH_CHAR_IS_SLASH(relative_path_abbrev[1]);
|
||||
|
||||
free(relative_path_abbrev);
|
||||
#endif
|
||||
|
@ -460,9 +460,9 @@ void path_basedir_wrapper(char *path);
|
||||
* Returns: true (1) if character is a slash, otherwise false (0).
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#define path_char_is_slash(c) (((c) == '/') || ((c) == '\\'))
|
||||
#define PATH_CHAR_IS_SLASH(c) (((c) == '/') || ((c) == '\\'))
|
||||
#else
|
||||
#define path_char_is_slash(c) ((c) == '/')
|
||||
#define PATH_CHAR_IS_SLASH(c) ((c) == '/')
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -59,10 +59,13 @@ namespace
|
||||
{
|
||||
void windowsize_path(wchar_t* path)
|
||||
{
|
||||
/* UWP deals with paths containing / instead of \ way worse than normal Windows */
|
||||
/* and RetroArch may sometimes mix them (e.g. on archive extraction) */
|
||||
/* UWP deals with paths containing / instead of
|
||||
* \ way worse than normal Windows */
|
||||
/* and RetroArch may sometimes mix them
|
||||
* (e.g. on archive extraction) */
|
||||
if (!path)
|
||||
return;
|
||||
|
||||
while (*path)
|
||||
{
|
||||
if (*path == '/')
|
||||
@ -139,15 +142,21 @@ namespace
|
||||
/* Look for a matching directory we can use */
|
||||
for each (StorageFolder^ folder in accessible_directories)
|
||||
{
|
||||
std::wstring file_path;
|
||||
std::wstring folder_path = folder->Path->Data();
|
||||
size_t folder_path_size = folder_path.size();
|
||||
/* Could be C:\ or C:\Users\somebody - remove the trailing slash to unify them */
|
||||
if (folder_path[folder_path.size() - 1] == '\\')
|
||||
folder_path.erase(folder_path.size() - 1);
|
||||
std::wstring file_path = path->Data();
|
||||
if (folder_path[folder_path_size - 1] == '\\')
|
||||
folder_path.erase(folder_path_size - 1);
|
||||
|
||||
file_path = path->Data();
|
||||
|
||||
if (file_path.find(folder_path) == 0)
|
||||
{
|
||||
/* Found a match */
|
||||
file_path = file_path.length() > folder_path.length() ? file_path.substr(folder_path.length() + 1) : L"";
|
||||
file_path = file_path.length() > folder_path.length()
|
||||
? file_path.substr(folder_path.length() + 1)
|
||||
: L"";
|
||||
return concurrency::create_task(GetItemInFolderFromPathAsync<T>(folder, ref new Platform::String(file_path.data())));
|
||||
}
|
||||
}
|
||||
@ -226,7 +235,8 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT __stdcall RuntimeClassInitialize(byte *buffer, uint32_t capacity, uint32_t length)
|
||||
HRESULT __stdcall RuntimeClassInitialize(
|
||||
byte *buffer, uint32_t capacity, uint32_t length)
|
||||
{
|
||||
m_buffer = buffer;
|
||||
m_capacity = capacity;
|
||||
@ -292,33 +302,38 @@ struct libretro_vfs_implementation_file
|
||||
size_t buffer_fill;
|
||||
};
|
||||
|
||||
libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, unsigned mode, unsigned hints)
|
||||
libretro_vfs_implementation_file *retro_vfs_file_open_impl(
|
||||
const char *path, unsigned mode, unsigned hints)
|
||||
{
|
||||
char *dirpath, *filename;
|
||||
wchar_t *dirpath_wide;
|
||||
wchar_t *filename_wide;
|
||||
Platform::String^ filename_str;
|
||||
Platform::String^ dirpath_str;
|
||||
if (!path || !*path)
|
||||
return NULL;
|
||||
|
||||
/* Something tried to access files from current directory.
|
||||
* This is not allowed on UWP. */
|
||||
if (!path_is_absolute(path))
|
||||
{
|
||||
/* Something tried to access files from current directory. This is not allowed on UWP. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Trying to open a directory as file?! */
|
||||
if (path_char_is_slash(path[strlen(path) - 1]))
|
||||
if (PATH_CHAR_IS_SLASH(path[strlen(path) - 1]))
|
||||
return NULL;
|
||||
|
||||
char* dirpath = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
dirpath = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
fill_pathname_basedir(dirpath, path, PATH_MAX_LENGTH);
|
||||
wchar_t *dirpath_wide = utf8_to_utf16_string_alloc(dirpath);
|
||||
dirpath_wide = utf8_to_utf16_string_alloc(dirpath);
|
||||
windowsize_path(dirpath_wide);
|
||||
Platform::String^ dirpath_str = ref new Platform::String(dirpath_wide);
|
||||
dirpath_str = ref new Platform::String(dirpath_wide);
|
||||
free(dirpath_wide);
|
||||
free(dirpath);
|
||||
|
||||
char* filename = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
filename = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
fill_pathname_base(filename, path, PATH_MAX_LENGTH);
|
||||
wchar_t *filename_wide = utf8_to_utf16_string_alloc(filename);
|
||||
Platform::String^ filename_str = ref new Platform::String(filename_wide);
|
||||
filename_wide = utf8_to_utf16_string_alloc(filename);
|
||||
filename_str = ref new Platform::String(filename_wide);
|
||||
free(filename_wide);
|
||||
free(filename);
|
||||
|
||||
@ -332,7 +347,7 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, uns
|
||||
return dir->CreateFileAsync(filename_str, (mode & RETRO_VFS_FILE_ACCESS_UPDATE_EXISTING) != 0 ?
|
||||
CreationCollisionOption::OpenIfExists : CreationCollisionOption::ReplaceExisting);
|
||||
}).then([&](StorageFile^ file) {
|
||||
FileAccessMode accessMode = mode == RETRO_VFS_FILE_ACCESS_READ ?
|
||||
FileAccessMode accessMode = (mode == RETRO_VFS_FILE_ACCESS_READ) ?
|
||||
FileAccessMode::Read : FileAccessMode::ReadWrite;
|
||||
return file->OpenAsync(accessMode);
|
||||
}).then([&](IRandomAccessStream^ fpstream) {
|
||||
@ -340,13 +355,14 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, uns
|
||||
if (!stream)
|
||||
return (libretro_vfs_implementation_file*)NULL;
|
||||
|
||||
stream->orig_path = strdup(path);
|
||||
stream->fp = fpstream;
|
||||
stream->orig_path = strdup(path);
|
||||
stream->fp = fpstream;
|
||||
stream->fp->Seek(0);
|
||||
// Preallocate a small buffer for manually buffered IO, makes short read faster
|
||||
int buf_size = 8 * 1024;
|
||||
stream->buffer = (char*)malloc(buf_size);
|
||||
stream->bufferp = CreateNativeBuffer(stream->buffer, buf_size, 0);
|
||||
/* Preallocate a small buffer for manually buffered I/O,
|
||||
* makes short read faster */
|
||||
int buf_size = 8 * 1024;
|
||||
stream->buffer = (char*)malloc(buf_size);
|
||||
stream->bufferp = CreateNativeBuffer(stream->buffer, buf_size, 0);
|
||||
stream->buffer_left = 0;
|
||||
stream->buffer_fill = 0;
|
||||
stream->buffer_size = buf_size;
|
||||
@ -395,116 +411,131 @@ int64_t retro_vfs_file_tell_impl(libretro_vfs_implementation_file *stream)
|
||||
return stream->fp->Position - stream->buffer_left;
|
||||
}
|
||||
|
||||
int64_t retro_vfs_file_seek_impl(libretro_vfs_implementation_file *stream, int64_t offset, int seek_position)
|
||||
int64_t retro_vfs_file_seek_impl(
|
||||
libretro_vfs_implementation_file *stream,
|
||||
int64_t offset, int seek_position)
|
||||
{
|
||||
if (!stream || !stream->fp)
|
||||
return -1;
|
||||
if (!stream || !stream->fp)
|
||||
return -1;
|
||||
|
||||
switch (seek_position)
|
||||
{
|
||||
case RETRO_VFS_SEEK_POSITION_START:
|
||||
stream->fp->Seek(offset);
|
||||
break;
|
||||
switch (seek_position)
|
||||
{
|
||||
case RETRO_VFS_SEEK_POSITION_START:
|
||||
stream->fp->Seek(offset);
|
||||
break;
|
||||
|
||||
case RETRO_VFS_SEEK_POSITION_CURRENT:
|
||||
stream->fp->Seek(retro_vfs_file_tell_impl(stream) + offset);
|
||||
break;
|
||||
case RETRO_VFS_SEEK_POSITION_CURRENT:
|
||||
stream->fp->Seek(retro_vfs_file_tell_impl(stream) + offset);
|
||||
break;
|
||||
|
||||
case RETRO_VFS_SEEK_POSITION_END:
|
||||
stream->fp->Seek(stream->fp->Size - offset);
|
||||
break;
|
||||
}
|
||||
case RETRO_VFS_SEEK_POSITION_END:
|
||||
stream->fp->Seek(stream->fp->Size - offset);
|
||||
break;
|
||||
}
|
||||
|
||||
// For simplicity always flush the buffer on seek
|
||||
stream->buffer_left = 0;
|
||||
// For simplicity always flush the buffer on seek
|
||||
stream->buffer_left = 0;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t retro_vfs_file_read_impl(libretro_vfs_implementation_file *stream, void *s, uint64_t len)
|
||||
int64_t retro_vfs_file_read_impl(
|
||||
libretro_vfs_implementation_file *stream, void *s, uint64_t len)
|
||||
{
|
||||
int64_t ret;
|
||||
int64_t bytes_read = 0;
|
||||
IBuffer^ buffer;
|
||||
|
||||
if (!stream || !stream->fp || !s)
|
||||
return -1;
|
||||
|
||||
int64_t bytes_read = 0;
|
||||
if (len <= stream->buffer_size)
|
||||
{
|
||||
/* Small read, use manually buffered I/O */
|
||||
if (stream->buffer_left < len)
|
||||
{
|
||||
/* Exhaust the buffer */
|
||||
memcpy(s,
|
||||
&stream->buffer[stream->buffer_fill - stream->buffer_left],
|
||||
stream->buffer_left);
|
||||
len -= stream->buffer_left;
|
||||
bytes_read += stream->buffer_left;
|
||||
stream->buffer_left = 0;
|
||||
|
||||
if (len <= stream->buffer_size) {
|
||||
// Small read, use manually buffered IO
|
||||
if (stream->buffer_left < len) {
|
||||
// Exhaust the buffer
|
||||
memcpy(s, &stream->buffer[stream->buffer_fill - stream->buffer_left], stream->buffer_left);
|
||||
len -= stream->buffer_left;
|
||||
bytes_read += stream->buffer_left;
|
||||
stream->buffer_left = 0;
|
||||
/* Fill buffer */
|
||||
stream->buffer_left = RunAsyncAndCatchErrors<int64_t>([&]() {
|
||||
return concurrency::create_task(stream->fp->ReadAsync(stream->bufferp, stream->bufferp->Capacity, InputStreamOptions::None)).then([&](IBuffer^ buf) {
|
||||
retro_assert(stream->bufferp == buf);
|
||||
return (int64_t)stream->bufferp->Length;
|
||||
});
|
||||
}, -1);
|
||||
stream->buffer_fill = stream->buffer_left;
|
||||
|
||||
// Fill buffer
|
||||
stream->buffer_left = RunAsyncAndCatchErrors<int64_t>([&]() {
|
||||
return concurrency::create_task(stream->fp->ReadAsync(stream->bufferp, stream->bufferp->Capacity, InputStreamOptions::None)).then([&](IBuffer^ buf) {
|
||||
retro_assert(stream->bufferp == buf);
|
||||
return (int64_t)stream->bufferp->Length;
|
||||
});
|
||||
}, -1);
|
||||
stream->buffer_fill = stream->buffer_left;
|
||||
if (stream->buffer_left == -1)
|
||||
{
|
||||
stream->buffer_left = 0;
|
||||
stream->buffer_fill = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stream->buffer_left == -1) {
|
||||
stream->buffer_left = 0;
|
||||
stream->buffer_fill = 0;
|
||||
return -1;
|
||||
}
|
||||
if (stream->buffer_left < len)
|
||||
{
|
||||
/* EOF */
|
||||
memcpy(&((char*)s)[bytes_read],
|
||||
stream->buffer, stream->buffer_left);
|
||||
bytes_read += stream->buffer_left;
|
||||
stream->buffer_left = 0;
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
if (stream->buffer_left < len) {
|
||||
// EOF
|
||||
memcpy(&((char*)s)[bytes_read], stream->buffer, stream->buffer_left);
|
||||
bytes_read += stream->buffer_left;
|
||||
stream->buffer_left = 0;
|
||||
return bytes_read;
|
||||
}
|
||||
memcpy(&((char*)s)[bytes_read], stream->buffer, len);
|
||||
bytes_read += len;
|
||||
stream->buffer_left -= len;
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
memcpy(&((char*)s)[bytes_read], stream->buffer, len);
|
||||
bytes_read += len;
|
||||
stream->buffer_left -= len;
|
||||
return bytes_read;
|
||||
}
|
||||
/* Internal buffer already contains requested amount */
|
||||
memcpy(s,
|
||||
&stream->buffer[stream->buffer_fill - stream->buffer_left],
|
||||
len);
|
||||
stream->buffer_left -= len;
|
||||
return len;
|
||||
}
|
||||
|
||||
// Internal buffer already contains requested amount
|
||||
memcpy(s, &stream->buffer[stream->buffer_fill - stream->buffer_left], len);
|
||||
stream->buffer_left -= len;
|
||||
return len;
|
||||
}
|
||||
|
||||
// Big read exceeding buffer size, exhaust small buffer and read rest in one go
|
||||
/* Big read exceeding buffer size,
|
||||
* exhaust small buffer and read rest in one go */
|
||||
memcpy(s, &stream->buffer[stream->buffer_fill - stream->buffer_left], stream->buffer_left);
|
||||
len -= stream->buffer_left;
|
||||
bytes_read += stream->buffer_left;
|
||||
stream->buffer_left = 0;
|
||||
len -= stream->buffer_left;
|
||||
bytes_read += stream->buffer_left;
|
||||
stream->buffer_left = 0;
|
||||
|
||||
IBuffer^ buffer = CreateNativeBuffer(&((char*)s)[bytes_read], len, 0);
|
||||
|
||||
int64_t ret = RunAsyncAndCatchErrors<int64_t>([&]() {
|
||||
buffer = CreateNativeBuffer(&((char*)s)[bytes_read], len, 0);
|
||||
ret = RunAsyncAndCatchErrors<int64_t>([&]() {
|
||||
return concurrency::create_task(stream->fp->ReadAsync(buffer, buffer->Capacity - bytes_read, InputStreamOptions::None)).then([&](IBuffer^ buf) {
|
||||
retro_assert(buf == buffer);
|
||||
return (int64_t)buffer->Length;
|
||||
});
|
||||
}, -1);
|
||||
|
||||
if (ret == -1) {
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
}
|
||||
return bytes_read + ret;
|
||||
}
|
||||
|
||||
int64_t retro_vfs_file_write_impl(libretro_vfs_implementation_file *stream, const void *s, uint64_t len)
|
||||
int64_t retro_vfs_file_write_impl(
|
||||
libretro_vfs_implementation_file *stream, const void *s, uint64_t len)
|
||||
{
|
||||
if (!stream || !stream->fp || !s)
|
||||
return -1;
|
||||
IBuffer^ buffer;
|
||||
if (!stream || !stream->fp || !s)
|
||||
return -1;
|
||||
|
||||
// const_cast to remove const modifier is undefined behaviour, but the buffer is only read, should be safe
|
||||
IBuffer^ buffer = CreateNativeBuffer(const_cast<void*>(s), len, len);
|
||||
return RunAsyncAndCatchErrors<int64_t>([&]() {
|
||||
return concurrency::create_task(stream->fp->WriteAsync(buffer)).then([&](unsigned int written) {
|
||||
return (int64_t)written;
|
||||
});
|
||||
}, -1);
|
||||
/* const_cast to remove const modifier is undefined behaviour, but the buffer is only read, should be safe */
|
||||
buffer = CreateNativeBuffer(const_cast<void*>(s), len, len);
|
||||
return RunAsyncAndCatchErrors<int64_t>([&]() {
|
||||
return concurrency::create_task(stream->fp->WriteAsync(buffer)).then([&](unsigned int written) {
|
||||
return (int64_t)written;
|
||||
});
|
||||
}, -1);
|
||||
}
|
||||
|
||||
int retro_vfs_file_flush_impl(libretro_vfs_implementation_file *stream)
|
||||
@ -523,12 +554,15 @@ int retro_vfs_file_flush_impl(libretro_vfs_implementation_file *stream)
|
||||
|
||||
int retro_vfs_file_remove_impl(const char *path)
|
||||
{
|
||||
wchar_t *path_wide;
|
||||
Platform::String^ path_str;
|
||||
|
||||
if (!path || !*path)
|
||||
return -1;
|
||||
|
||||
wchar_t *path_wide = utf8_to_utf16_string_alloc(path);
|
||||
path_wide = utf8_to_utf16_string_alloc(path);
|
||||
windowsize_path(path_wide);
|
||||
Platform::String^ path_str = ref new Platform::String(path_wide);
|
||||
path_str = ref new Platform::String(path_wide);
|
||||
free(path_wide);
|
||||
|
||||
return RunAsyncAndCatchErrors<int>([&]() {
|
||||
@ -543,25 +577,33 @@ int retro_vfs_file_remove_impl(const char *path)
|
||||
/* TODO: this may not work if trying to move a directory */
|
||||
int retro_vfs_file_rename_impl(const char *old_path, const char *new_path)
|
||||
{
|
||||
if (!old_path || !*old_path || !new_path || !*new_path)
|
||||
char *new_file_name;
|
||||
char *new_dir_path;
|
||||
wchar_t *new_file_name_wide;
|
||||
wchar_t *old_path_wide, *new_dir_path_wide;
|
||||
Platform::String^ old_path_str;
|
||||
Platform::String^ new_dir_path_str;
|
||||
Platform::String^ new_file_name_str;
|
||||
|
||||
if (!old_path || !*old_path || !new_path || !*new_path)
|
||||
return -1;
|
||||
|
||||
wchar_t* old_path_wide = utf8_to_utf16_string_alloc(old_path);
|
||||
Platform::String^ old_path_str = ref new Platform::String(old_path_wide);
|
||||
old_path_wide = utf8_to_utf16_string_alloc(old_path);
|
||||
old_path_str = ref new Platform::String(old_path_wide);
|
||||
free(old_path_wide);
|
||||
|
||||
char* new_dir_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
new_dir_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
fill_pathname_basedir(new_dir_path, new_path, PATH_MAX_LENGTH);
|
||||
wchar_t *new_dir_path_wide = utf8_to_utf16_string_alloc(new_dir_path);
|
||||
new_dir_path_wide = utf8_to_utf16_string_alloc(new_dir_path);
|
||||
windowsize_path(new_dir_path_wide);
|
||||
Platform::String^ new_dir_path_str = ref new Platform::String(new_dir_path_wide);
|
||||
new_dir_path_str = ref new Platform::String(new_dir_path_wide);
|
||||
free(new_dir_path_wide);
|
||||
free(new_dir_path);
|
||||
|
||||
char* new_file_name = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
new_file_name = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
fill_pathname_base(new_file_name, new_path, PATH_MAX_LENGTH);
|
||||
wchar_t *new_file_name_wide = utf8_to_utf16_string_alloc(new_file_name);
|
||||
Platform::String^ new_file_name_str = ref new Platform::String(new_file_name_wide);
|
||||
new_file_name_wide = utf8_to_utf16_string_alloc(new_file_name);
|
||||
new_file_name_str = ref new Platform::String(new_file_name_wide);
|
||||
free(new_file_name_wide);
|
||||
free(new_file_name);
|
||||
|
||||
@ -595,15 +637,19 @@ const char *retro_vfs_file_get_path_impl(libretro_vfs_implementation_file *strea
|
||||
|
||||
int retro_vfs_stat_impl(const char *path, int32_t *size)
|
||||
{
|
||||
wchar_t *path_wide;
|
||||
Platform::String^ path_str;
|
||||
IStorageItem^ item;
|
||||
|
||||
if (!path || !*path)
|
||||
return 0;
|
||||
|
||||
wchar_t *path_wide = utf8_to_utf16_string_alloc(path);
|
||||
path_wide = utf8_to_utf16_string_alloc(path);
|
||||
windowsize_path(path_wide);
|
||||
Platform::String^ path_str = ref new Platform::String(path_wide);
|
||||
path_str = ref new Platform::String(path_wide);
|
||||
free(path_wide);
|
||||
|
||||
IStorageItem^ item = LocateStorageFileOrFolder(path_str);
|
||||
item = LocateStorageFileOrFolder(path_str);
|
||||
if (!item)
|
||||
return 0;
|
||||
|
||||
@ -618,36 +664,44 @@ int retro_vfs_stat_impl(const char *path, int32_t *size)
|
||||
|
||||
int retro_vfs_mkdir_impl(const char *dir)
|
||||
{
|
||||
Platform::String^ parent_path_str;
|
||||
Platform::String^ dir_name_str;
|
||||
wchar_t *dir_name_wide, *parent_path_wide;
|
||||
char *dir_local, *tmp, *dir_name, *parent_path;
|
||||
if (!dir || !*dir)
|
||||
return -1;
|
||||
|
||||
char* dir_local = strdup(dir);
|
||||
/* If the path ends with a slash, we have to remove it for basename to work */
|
||||
char* tmp = dir_local + strlen(dir_local) - 1;
|
||||
if (path_char_is_slash(*tmp))
|
||||
*tmp = 0;
|
||||
/* If the path ends with a slash, we have to remove
|
||||
* it for basename to work */
|
||||
dir_local = strdup(dir);
|
||||
tmp = dir_local + strlen(dir_local) - 1;
|
||||
|
||||
char* dir_name = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
if (PATH_CHAR_IS_SLASH(*tmp))
|
||||
*tmp = 0;
|
||||
|
||||
dir_name = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
fill_pathname_base(dir_name, dir_local, PATH_MAX_LENGTH);
|
||||
wchar_t *dir_name_wide = utf8_to_utf16_string_alloc(dir_name);
|
||||
Platform::String^ dir_name_str = ref new Platform::String(dir_name_wide);
|
||||
dir_name_wide = utf8_to_utf16_string_alloc(dir_name);
|
||||
dir_name_str = ref new Platform::String(dir_name_wide);
|
||||
free(dir_name_wide);
|
||||
free(dir_name);
|
||||
|
||||
char* parent_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
parent_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
fill_pathname_parent_dir(parent_path, dir_local, PATH_MAX_LENGTH);
|
||||
wchar_t *parent_path_wide = utf8_to_utf16_string_alloc(parent_path);
|
||||
parent_path_wide = utf8_to_utf16_string_alloc(parent_path);
|
||||
windowsize_path(parent_path_wide);
|
||||
Platform::String^ parent_path_str = ref new Platform::String(parent_path_wide);
|
||||
parent_path_str = ref new Platform::String(parent_path_wide);
|
||||
free(parent_path_wide);
|
||||
free(parent_path);
|
||||
|
||||
retro_assert(!dir_name_str->IsEmpty() && !parent_path_str->IsEmpty());
|
||||
retro_assert(!dir_name_str->IsEmpty()
|
||||
&& !parent_path_str->IsEmpty());
|
||||
|
||||
free(dir_local);
|
||||
|
||||
return RunAsyncAndCatchErrors<int>([&]() {
|
||||
return concurrency::create_task(LocateStorageItem<StorageFolder>(parent_path_str)).then([&](StorageFolder^ parent) {
|
||||
return concurrency::create_task(LocateStorageItem<StorageFolder>(
|
||||
parent_path_str)).then([&](StorageFolder^ parent) {
|
||||
return parent->CreateFolderAsync(dir_name_str);
|
||||
}).then([&](concurrency::task<StorageFolder^> new_dir) {
|
||||
try
|
||||
@ -678,6 +732,8 @@ struct libretro_vfs_implementation_dir
|
||||
|
||||
libretro_vfs_implementation_dir *retro_vfs_opendir_impl(const char *name, bool include_hidden)
|
||||
{
|
||||
wchar_t *name_wide;
|
||||
Platform::String^ name_str;
|
||||
libretro_vfs_implementation_dir *rdir;
|
||||
|
||||
if (!name || !*name)
|
||||
@ -687,9 +743,9 @@ libretro_vfs_implementation_dir *retro_vfs_opendir_impl(const char *name, bool i
|
||||
if (!rdir)
|
||||
return NULL;
|
||||
|
||||
wchar_t *name_wide = utf8_to_utf16_string_alloc(name);
|
||||
name_wide = utf8_to_utf16_string_alloc(name);
|
||||
windowsize_path(name_wide);
|
||||
Platform::String^ name_str = ref new Platform::String(name_wide);
|
||||
name_str = ref new Platform::String(name_wide);
|
||||
free(name_wide);
|
||||
|
||||
rdir->directory = RunAsyncAndCatchErrors<IVectorView<IStorageItem^>^>([&]() {
|
||||
@ -712,17 +768,16 @@ bool retro_vfs_readdir_impl(libretro_vfs_implementation_dir *rdir)
|
||||
rdir->entry = rdir->directory->First();
|
||||
return rdir->entry->HasCurrent;
|
||||
}
|
||||
else
|
||||
{
|
||||
return rdir->entry->MoveNext();
|
||||
}
|
||||
return rdir->entry->MoveNext();
|
||||
}
|
||||
|
||||
const char *retro_vfs_dirent_get_name_impl(libretro_vfs_implementation_dir *rdir)
|
||||
const char *retro_vfs_dirent_get_name_impl(
|
||||
libretro_vfs_implementation_dir *rdir)
|
||||
{
|
||||
if (rdir->entry_name)
|
||||
free(rdir->entry_name);
|
||||
rdir->entry_name = utf16_to_utf8_string_alloc(rdir->entry->Current->Name->Data());
|
||||
rdir->entry_name = utf16_to_utf8_string_alloc(
|
||||
rdir->entry->Current->Name->Data());
|
||||
return rdir->entry_name;
|
||||
}
|
||||
|
||||
@ -738,7 +793,7 @@ int retro_vfs_closedir_impl(libretro_vfs_implementation_dir *rdir)
|
||||
|
||||
if (rdir->entry_name)
|
||||
free(rdir->entry_name);
|
||||
rdir->entry = nullptr;
|
||||
rdir->entry = nullptr;
|
||||
rdir->directory = nullptr;
|
||||
|
||||
free(rdir);
|
||||
@ -747,18 +802,20 @@ int retro_vfs_closedir_impl(libretro_vfs_implementation_dir *rdir)
|
||||
|
||||
bool uwp_drive_exists(const char *path)
|
||||
{
|
||||
if (!path || !*path)
|
||||
return 0;
|
||||
wchar_t *path_wide;
|
||||
Platform::String^ path_str;
|
||||
if (!path || !*path)
|
||||
return 0;
|
||||
|
||||
wchar_t *path_wide = utf8_to_utf16_string_alloc(path);
|
||||
Platform::String^ path_str = ref new Platform::String(path_wide);
|
||||
free(path_wide);
|
||||
path_wide = utf8_to_utf16_string_alloc(path);
|
||||
path_str = ref new Platform::String(path_wide);
|
||||
free(path_wide);
|
||||
|
||||
return RunAsyncAndCatchErrors<bool>([&]() {
|
||||
return concurrency::create_task(StorageFolder::GetFolderFromPathAsync(path_str)).then([](StorageFolder^ properties) {
|
||||
return true;
|
||||
});
|
||||
}, false);
|
||||
return RunAsyncAndCatchErrors<bool>([&]() {
|
||||
return concurrency::create_task(StorageFolder::GetFolderFromPathAsync(path_str)).then([](StorageFolder^ properties) {
|
||||
return true;
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
||||
char* uwp_trigger_picker(void)
|
||||
|
Loading…
Reference in New Issue
Block a user