convert more file IO functions to use filestream, fixes encoding issues on Windows

This commit is contained in:
Brad Parker 2017-10-29 12:08:20 -04:00
parent 89265f5cf2
commit 68a8198e4a
10 changed files with 124 additions and 39 deletions

View File

@ -25,6 +25,7 @@
#include <compat/posix_string.h> #include <compat/posix_string.h>
#include <retro_assert.h> #include <retro_assert.h>
#include <string/stdstring.h> #include <string/stdstring.h>
#include <streams/file_stream.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
@ -3699,15 +3700,15 @@ bool config_save_file(const char *path)
#ifdef HAVE_LAKKA #ifdef HAVE_LAKKA
if (settings->bools.ssh_enable) if (settings->bools.ssh_enable)
fclose(fopen(LAKKA_SSH_PATH, "w")); filestream_close(filestream_open(LAKKA_SSH_PATH, RFILE_MODE_WRITE, -1));
else else
path_file_remove(LAKKA_SSH_PATH); path_file_remove(LAKKA_SSH_PATH);
if (settings->bools.samba_enable) if (settings->bools.samba_enable)
fclose(fopen(LAKKA_SAMBA_PATH, "w")); filestream_close(filestream_open(LAKKA_SAMBA_PATH, RFILE_MODE_WRITE, -1));
else else
path_file_remove(LAKKA_SAMBA_PATH); path_file_remove(LAKKA_SAMBA_PATH);
if (settings->bools.bluetooth_enable) if (settings->bools.bluetooth_enable)
fclose(fopen(LAKKA_BLUETOOTH_PATH, "w")); filestream_close(filestream_open(LAKKA_BLUETOOTH_PATH, RFILE_MODE_WRITE, -1));
else else
path_file_remove(LAKKA_BLUETOOTH_PATH); path_file_remove(LAKKA_BLUETOOTH_PATH);
#endif #endif

View File

@ -44,6 +44,7 @@
#include <lists/string_list.h> #include <lists/string_list.h>
#include <string/stdstring.h> #include <string/stdstring.h>
#include <rhash.h> #include <rhash.h>
#include <streams/file_stream.h>
#define MAX_INCLUDE_DEPTH 16 #define MAX_INCLUDE_DEPTH 16
@ -78,13 +79,13 @@ struct config_file
static config_file_t *config_file_new_internal( static config_file_t *config_file_new_internal(
const char *path, unsigned depth); const char *path, unsigned depth);
static char *getaline(FILE *file) static char *getaline(RFILE *file)
{ {
char* newline = (char*)malloc(9); char* newline = (char*)malloc(9);
char* newline_tmp = NULL; char* newline_tmp = NULL;
size_t cur_size = 8; size_t cur_size = 8;
size_t idx = 0; size_t idx = 0;
int in = getc(file); int in = filestream_getc(file);
if (!newline) if (!newline)
return NULL; return NULL;
@ -106,7 +107,7 @@ static char *getaline(FILE *file)
} }
newline[idx++] = in; newline[idx++] = in;
in = getc(file); in = filestream_getc(file);
} }
newline[idx] = '\0'; newline[idx] = '\0';
return newline; return newline;
@ -366,7 +367,7 @@ error:
static config_file_t *config_file_new_internal( static config_file_t *config_file_new_internal(
const char *path, unsigned depth) const char *path, unsigned depth)
{ {
FILE *file = NULL; RFILE *file = NULL;
struct config_file *conf = (struct config_file*)malloc(sizeof(*conf)); struct config_file *conf = (struct config_file*)malloc(sizeof(*conf));
if (!conf) if (!conf)
return NULL; return NULL;
@ -388,16 +389,16 @@ static config_file_t *config_file_new_internal(
goto error; goto error;
conf->include_depth = depth; conf->include_depth = depth;
file = fopen(path, "r"); file = filestream_open(path, RFILE_MODE_READ_TEXT, -1);
if (!file) if (!file)
{ {
free(conf->path); free(conf->path);
goto error; goto error;
} }
setvbuf(file, NULL, _IOFBF, 0x4000); setvbuf(filestream_get_fp(file), NULL, _IOFBF, 0x4000);
while (!feof(file)) while (!filestream_eof(file))
{ {
char *line = NULL; char *line = NULL;
struct config_entry_list *list = (struct config_entry_list*)malloc(sizeof(*list)); struct config_entry_list *list = (struct config_entry_list*)malloc(sizeof(*list));
@ -405,7 +406,7 @@ static config_file_t *config_file_new_internal(
if (!list) if (!list)
{ {
config_file_free(conf); config_file_free(conf);
fclose(file); filestream_close(file);
return NULL; return NULL;
} }
@ -439,7 +440,7 @@ static config_file_t *config_file_new_internal(
free(list); free(list);
} }
fclose(file); filestream_close(file);
return conf; return conf;
@ -894,27 +895,28 @@ void config_set_bool(config_file_t *conf, const char *key, bool val)
bool config_file_write(config_file_t *conf, const char *path) bool config_file_write(config_file_t *conf, const char *path)
{ {
FILE *file; RFILE *file = NULL;
if (!string_is_empty(path)) if (!string_is_empty(path))
{ {
file = fopen(path, "w"); file = filestream_open(path, RFILE_MODE_WRITE, -1);
if (!file) if (!file)
return false; return false;
#ifdef WIIU #ifdef WIIU
/* TODO: use FBF everywhere once https://i.imgur.com/muVhNeF.jpg is fixed */ /* TODO: use FBF everywhere once https://i.imgur.com/muVhNeF.jpg is fixed */
setvbuf(file, NULL, _IONBF, 0x4000); setvbuf(filestream_get_fp(file), NULL, _IONBF, 0x4000);
#else #else
setvbuf(file, NULL, _IOFBF, 0x4000); setvbuf(filestream_get_fp(file), NULL, _IOFBF, 0x4000);
#endif #endif
config_file_dump(conf, filestream_get_fp(file));
} }
else else
file = stdout; {
config_file_dump(conf, stdout);
}
config_file_dump(conf, file); if (file)
filestream_close(file);
if (path)
fclose(file);
return true; return true;
} }

View File

@ -960,3 +960,69 @@ int path_file_remove(const char *path)
return -1; return -1;
} }
int path_file_rename(const char *old_path, const char *new_path)
{
char *old_path_local = NULL;
char *new_path_local = NULL;
wchar_t *old_path_wide = NULL;
wchar_t *new_path_wide = NULL;
if (!old_path || !*old_path || !new_path || !*new_path)
return false;
(void)old_path_local;
(void)new_path_local;
(void)old_path_wide;
(void)new_path_wide;
#if defined(_WIN32) && !defined(_XBOX)
#if defined(_MSC_VER) && _MSC_VER < 1400
old_path_local = utf8_to_local_string_alloc(old_path);
new_path_local = utf8_to_local_string_alloc(new_path);
if (old_path_local)
{
bool ret;
if (new_path_local)
{
ret = rename(old_path_local, new_path_local);
free(old_path_local);
free(new_path_local);
return ret;
}
free(old_path_local);
}
if (new_path_local)
free(new_path_local);
#else
old_path_wide = utf8_to_utf16_string_alloc(old_path);
new_path_wide = utf8_to_utf16_string_alloc(new_path);
if (old_path_wide)
{
bool ret;
if (new_path_wide)
{
ret = _wrename(old_path_wide, new_path_wide);
free(old_path_wide);
free(new_path_wide);
return ret;
}
free(old_path_wide);
}
if (new_path_wide)
free(new_path_wide);
#endif
#else
return rename(old_path, new_path);
#endif
return -1;
}

View File

@ -468,6 +468,8 @@ int32_t path_get_size(const char *path);
int path_file_remove(const char *path); int path_file_remove(const char *path);
int path_file_rename(const char *old_path, const char *new_path);
RETRO_END_DECLS RETRO_END_DECLS
#endif #endif

View File

@ -23,6 +23,7 @@
#ifndef __LIBRETRO_SDK_FILE_STREAM_H #ifndef __LIBRETRO_SDK_FILE_STREAM_H
#define __LIBRETRO_SDK_FILE_STREAM_H #define __LIBRETRO_SDK_FILE_STREAM_H
#include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
@ -44,7 +45,7 @@ enum
RFILE_MODE_WRITE, RFILE_MODE_WRITE,
RFILE_MODE_READ_WRITE, RFILE_MODE_READ_WRITE,
/* There is no garantee these requests will be attended. */ /* There is no guarantee these requests will be attended. */
RFILE_HINT_UNBUFFERED = 1<<8, RFILE_HINT_UNBUFFERED = 1<<8,
RFILE_HINT_MMAP = 1<<9 /* requires RFILE_MODE_READ */ RFILE_HINT_MMAP = 1<<9 /* requires RFILE_MODE_READ */
}; };
@ -91,6 +92,8 @@ int filestream_error(RFILE *stream);
int filestream_get_fd(RFILE *stream); int filestream_get_fd(RFILE *stream);
FILE* filestream_get_fp(RFILE *stream);
int filestream_flush(RFILE *stream); int filestream_flush(RFILE *stream);
RETRO_END_DECLS RETRO_END_DECLS

View File

@ -111,6 +111,13 @@ struct RFILE
#endif #endif
}; };
FILE* filestream_get_fp(RFILE *stream)
{
if (!stream)
return NULL;
return stream->fp;
}
int filestream_get_fd(RFILE *stream) int filestream_get_fd(RFILE *stream)
{ {
if (!stream) if (!stream)

View File

@ -1858,7 +1858,7 @@ static void systemd_service_toggle(const char *path, char *unit, bool enable)
args[2] = unit; args[2] = unit;
if (enable) if (enable)
fclose(fopen(path, "w")); filestream_close(filestream_open(path, RFILE_MODE_WRITE, -1));
else else
path_file_remove(path); path_file_remove(path);

View File

@ -380,12 +380,12 @@ success:
void playlist_write_file(playlist_t *playlist) void playlist_write_file(playlist_t *playlist)
{ {
size_t i; size_t i;
FILE *file = NULL; RFILE *file = NULL;
if (!playlist || !playlist->modified) if (!playlist || !playlist->modified)
return; return;
file = fopen(playlist->conf_path, "w"); file = filestream_open(playlist->conf_path, RFILE_MODE_WRITE, -1);
RARCH_LOG("Trying to write to playlist file: %s\n", playlist->conf_path); RARCH_LOG("Trying to write to playlist file: %s\n", playlist->conf_path);
@ -396,7 +396,7 @@ void playlist_write_file(playlist_t *playlist)
} }
for (i = 0; i < playlist->size; i++) for (i = 0; i < playlist->size; i++)
fprintf(file, "%s\n%s\n%s\n%s\n%s\n%s\n", fprintf(filestream_get_fp(file), "%s\n%s\n%s\n%s\n%s\n%s\n",
playlist->entries[i].path ? playlist->entries[i].path : "", playlist->entries[i].path ? playlist->entries[i].path : "",
playlist->entries[i].label ? playlist->entries[i].label : "", playlist->entries[i].label ? playlist->entries[i].label : "",
playlist->entries[i].core_path, playlist->entries[i].core_path,
@ -406,7 +406,7 @@ void playlist_write_file(playlist_t *playlist)
); );
playlist->modified = false; playlist->modified = false;
fclose(file); filestream_close(file);
} }
/** /**

View File

@ -1263,9 +1263,9 @@ bool content_rename_state(const char *origin, const char *dest)
{ {
int ret = 0; int ret = 0;
if (path_file_exists(dest)) if (path_file_exists(dest))
unlink(dest); path_file_remove(dest);
ret = rename (origin, dest); ret = path_file_rename(origin, dest);
if (!ret) if (!ret)
return true; return true;

View File

@ -34,6 +34,7 @@
#endif #endif
#include <string/stdstring.h> #include <string/stdstring.h>
#include <streams/file_stream.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
@ -48,7 +49,8 @@
/* If this is non-NULL. RARCH_LOG and friends /* If this is non-NULL. RARCH_LOG and friends
* will write to this file. */ * will write to this file. */
static FILE *log_file = NULL; static RFILE *log_file = NULL;
static FILE *log_file_fp = NULL;
static bool main_verbosity = false; static bool main_verbosity = false;
static bool log_file_initialized = false; static bool log_file_initialized = false;
@ -82,7 +84,7 @@ bool *verbosity_get_ptr(void)
void *retro_main_log_file(void) void *retro_main_log_file(void)
{ {
return log_file; return log_file_fp;
} }
void retro_main_log_file_init(const char *path) void retro_main_log_file_init(const char *path)
@ -90,19 +92,21 @@ void retro_main_log_file_init(const char *path)
if (log_file_initialized) if (log_file_initialized)
return; return;
log_file = stderr; log_file_fp = stderr;
if (path == NULL) if (path == NULL)
return; return;
log_file = fopen(path, "wb"); log_file = filestream_open(path, RFILE_MODE_WRITE, -1);
log_file_fp = filestream_get_fp(log_file);
log_file_initialized = true; log_file_initialized = true;
} }
void retro_main_log_file_deinit(void) void retro_main_log_file_deinit(void)
{ {
if (log_file && log_file != stderr) if (log_file && log_file_fp != stderr)
fclose(log_file); filestream_close(log_file);
log_file = NULL; log_file = NULL;
log_file_fp = NULL;
} }
#if !defined(HAVE_LOGGER) #if !defined(HAVE_LOGGER)