core/file: Create a single file_open() function
This function currently only supports opening files for reading, but it will soon be expanded to supporting writes as well. To support binary reads, I add a new OPEN_READ_BINARY open mode. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
0aaafcb5f7
commit
a848d5d03c
|
@ -131,7 +131,7 @@ static bool __audio_init_idle(void *data)
|
|||
if (settings_has(SETTINGS_TRACK)) {
|
||||
track = settings_get(SETTINGS_TRACK);
|
||||
__audio_load(track_get(track), LOAD_HISTORY);
|
||||
} else if (data_file_open(&audio_file, OPEN_READ)) {
|
||||
} else if (file_open(&audio_file, OPEN_READ)) {
|
||||
data_file_readf(&audio_file, "%u", &track);
|
||||
file_close(&audio_file);
|
||||
file_remove(&audio_file);
|
||||
|
|
|
@ -115,7 +115,7 @@ void db_load(struct database *db)
|
|||
unsigned int size;
|
||||
bool save;
|
||||
|
||||
if (data_file_open(&db->db_file, OPEN_READ) == false)
|
||||
if (file_open(&db->db_file, OPEN_READ) == false)
|
||||
return;
|
||||
|
||||
data_file_readf(&db->db_file, "%u", &size);
|
||||
|
|
68
core/file.c
68
core/file.c
|
@ -32,14 +32,23 @@ static gchar *__file_path(const gchar *base, const gchar *dir,
|
|||
return g_build_filename(base, OCARINA_NAME, dir ? dir : "", name, NULL);
|
||||
}
|
||||
|
||||
static FILE *__file_open(gchar *path, const gchar *mode)
|
||||
static bool __file_open(struct file *file, enum open_mode mode)
|
||||
{
|
||||
FILE *ret = g_fopen(path, mode);
|
||||
gchar *cmode, *path;
|
||||
|
||||
if (!ret)
|
||||
if (mode == OPEN_READ || mode == OPEN_READ_BINARY) {
|
||||
cmode = "r";
|
||||
path = file_path(file);
|
||||
} else {
|
||||
cmode = "w";
|
||||
path = file_write_path(file);
|
||||
}
|
||||
|
||||
file->f_file = g_fopen(path, cmode);
|
||||
if (!file->f_file)
|
||||
REPORT_ERRNO(path);
|
||||
g_free(path);
|
||||
return ret;
|
||||
return file->f_file != NULL;
|
||||
}
|
||||
|
||||
static bool __file_mkdir(const gchar *basedir, const gchar *subdir)
|
||||
|
@ -115,26 +124,27 @@ bool file_exists(struct file *file)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool __file_open_read(struct file *data)
|
||||
static bool __file_open_read(struct file *file, enum open_mode mode)
|
||||
{
|
||||
if (!file_exists(data))
|
||||
if (!file_exists(file))
|
||||
return false;
|
||||
if (!__file_open(file, mode))
|
||||
return false;
|
||||
|
||||
data->f_file = __file_open(file_path(data), "r");
|
||||
if (!data->f_file)
|
||||
return false;
|
||||
file->f_mode = mode;
|
||||
if (mode == OPEN_READ_BINARY)
|
||||
return true;
|
||||
|
||||
data->f_mode = OPEN_READ;
|
||||
if (data_file_readf(data, "%u\n", &data->f_prev) != 1)
|
||||
if (data_file_readf(file, "%u\n", &file->f_prev) != 1)
|
||||
return false;
|
||||
if (data->f_prev < data->f_min) {
|
||||
REPORT_ERROR(data->f_name, "File too old to be upgraded.");
|
||||
file_close(data);
|
||||
if (file->f_prev < file->f_min) {
|
||||
REPORT_ERROR(file->f_name, "File too old to be upgraded.");
|
||||
file_close(file);
|
||||
exit(1);
|
||||
}
|
||||
if (data->f_prev > data->f_version) {
|
||||
REPORT_ERROR(data->f_name, "File too new to be opened.");
|
||||
file_close(data);
|
||||
if (file->f_prev > file->f_version) {
|
||||
REPORT_ERROR(file->f_name, "File too new to be opened.");
|
||||
file_close(file);
|
||||
exit(1);
|
||||
}
|
||||
return true;
|
||||
|
@ -146,9 +156,7 @@ static bool __file_open_write(struct file *data)
|
|||
return false;
|
||||
if (!__file_can_write(data))
|
||||
return false;
|
||||
|
||||
data->f_file = __file_open(file_write_path(data), "w");
|
||||
if (!data->f_file)
|
||||
if (!__file_open(data, OPEN_WRITE))
|
||||
return false;
|
||||
|
||||
data->f_mode = OPEN_WRITE;
|
||||
|
@ -159,11 +167,8 @@ bool data_file_open(struct file *data, enum open_mode mode)
|
|||
{
|
||||
if ((string_length(data->f_name) == 0) || (data->f_file != NULL))
|
||||
return false;
|
||||
|
||||
if (mode == CLOSED)
|
||||
if (mode == CLOSED || mode == OPEN_READ)
|
||||
return false;
|
||||
else if (mode == OPEN_READ)
|
||||
return __file_open_read(data);
|
||||
return __file_open_write(data);
|
||||
}
|
||||
|
||||
|
@ -175,12 +180,25 @@ bool cache_file_open(struct file *cache, enum open_mode mode)
|
|||
return false;
|
||||
if (!__file_mkdir(g_get_user_cache_dir(), cache->f_subdir))
|
||||
return false;
|
||||
if (!__file_open(cache, OPEN_WRITE))
|
||||
return false;
|
||||
|
||||
cache->f_file = __file_open(file_write_path(cache), "wb");
|
||||
cache->f_mode = mode;
|
||||
return cache->f_file != NULL;
|
||||
}
|
||||
|
||||
bool file_open(struct file *file, enum open_mode mode)
|
||||
{
|
||||
if ((string_length(file->f_name) == 0) || (file->f_file != NULL))
|
||||
return false;
|
||||
if (mode == CLOSED)
|
||||
return false;
|
||||
|
||||
if (mode == OPEN_READ || mode == OPEN_READ_BINARY)
|
||||
return __file_open_read(file, mode);
|
||||
return false;
|
||||
}
|
||||
|
||||
void file_close(struct file *file)
|
||||
{
|
||||
gchar *path = file_path(file);
|
||||
|
|
|
@ -47,7 +47,7 @@ static bool __artist_pl_load(void *data)
|
|||
unsigned int i, n;
|
||||
gchar *name;
|
||||
|
||||
if (!data_file_open(&artist_file, OPEN_READ))
|
||||
if (!file_open(&artist_file, OPEN_READ))
|
||||
return true;
|
||||
|
||||
data_file_readf(&artist_file, "%u\n", &n);
|
||||
|
|
|
@ -52,7 +52,7 @@ static bool __lib_pl_load(void *data)
|
|||
unsigned int i, n;
|
||||
gchar *name;
|
||||
|
||||
if (!data_file_open(&lib_file, OPEN_READ))
|
||||
if (!file_open(&lib_file, OPEN_READ))
|
||||
return true;
|
||||
|
||||
data_file_readf(&lib_file, "%u\n", &n);
|
||||
|
|
|
@ -143,7 +143,7 @@ static bool sys_pl_queued_load()
|
|||
struct playlist *playlist = pl_system_get(SYS_PL_QUEUED);
|
||||
unsigned int num, i, flags = 0;
|
||||
|
||||
if (!data_file_open(&sys_deck_f, OPEN_READ))
|
||||
if (!file_open(&sys_deck_f, OPEN_READ))
|
||||
return true;
|
||||
|
||||
data_file_readf(&sys_deck_f, "%u", &num);
|
||||
|
@ -193,7 +193,7 @@ static bool sys_pl_collection_load()
|
|||
{
|
||||
struct playlist *playlist = pl_system_get(SYS_PL_COLLECTION);
|
||||
|
||||
if (data_file_open(&sys_collection_f, OPEN_READ)) {
|
||||
if (file_open(&sys_collection_f, OPEN_READ)) {
|
||||
playlist_generic_load(playlist, &sys_collection_f, PL_SAVE_FLAGS);
|
||||
file_close(&sys_collection_f);
|
||||
file_remove(&sys_collection_f);
|
||||
|
@ -261,7 +261,7 @@ static bool __sys_pl_load()
|
|||
unsigned int i, n;
|
||||
gchar *name;
|
||||
|
||||
if (!data_file_open(&sys_file, OPEN_READ))
|
||||
if (!file_open(&sys_file, OPEN_READ))
|
||||
return true;
|
||||
|
||||
data_file_readf(&sys_file, "%u\n", &n);
|
||||
|
@ -289,7 +289,7 @@ static bool __sys_pl_load_new()
|
|||
unsigned int i, n, load;
|
||||
gchar *name;
|
||||
|
||||
if (!data_file_open(&sys_pl_file, OPEN_READ)) {
|
||||
if (!file_open(&sys_pl_file, OPEN_READ)) {
|
||||
__sys_pl_load();
|
||||
sys_pl_collection_load();
|
||||
sys_pl_queued_load();
|
||||
|
|
|
@ -42,7 +42,7 @@ void settings_init()
|
|||
gui_settings = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||
g_free, NULL);
|
||||
|
||||
if (data_file_open(&gui_settings_file, OPEN_READ))
|
||||
if (file_open(&gui_settings_file, OPEN_READ))
|
||||
__settings_read();
|
||||
file_close(&gui_settings_file);
|
||||
}
|
||||
|
|
|
@ -30,9 +30,10 @@
|
|||
|
||||
|
||||
enum open_mode {
|
||||
CLOSED, /* File is not open. */
|
||||
OPEN_READ, /* File is open for reading text. */
|
||||
OPEN_WRITE, /* File is open for writing text. */
|
||||
CLOSED, /* File is not open. */
|
||||
OPEN_READ, /* File is open for reading text. */
|
||||
OPEN_READ_BINARY, /* File is open for reading binary data. */
|
||||
OPEN_WRITE, /* File is open for writing text. */
|
||||
};
|
||||
|
||||
struct file {
|
||||
|
@ -86,9 +87,10 @@ bool file_exists(struct file *);
|
|||
* Call to open a file for either reading or writing. Callers
|
||||
* are expected to call file_close() when IO is completed.
|
||||
*
|
||||
* When opening a file for reading (OPEN_READ):
|
||||
* - Check if the file exists.
|
||||
* - Read in file->_prev_version from the start of the file.
|
||||
* When opening a file for reading (OPEN_READ / OPEN_READ_BINARY):
|
||||
* - Check if the file exists
|
||||
* - If open for reading text (OPEN_READ):
|
||||
* - Read in file->_prev_version from the start of the file.
|
||||
*
|
||||
* When opening a file for writing (OPEN_WRITE):
|
||||
* - Create missing directories as needed.
|
||||
|
@ -96,10 +98,10 @@ bool file_exists(struct file *);
|
|||
* - Write file->_version to the start of the file (data files only).
|
||||
*
|
||||
* Returns true if the open was successful and false otherwise.
|
||||
* Oening a cache file with OPEN_READ is currently unsupported.
|
||||
*/
|
||||
bool data_file_open(struct file *, enum open_mode);
|
||||
bool cache_file_open(struct file *, enum open_mode);
|
||||
bool file_open(struct file *, enum open_mode);
|
||||
|
||||
/*
|
||||
* Closes an open file, setting file->f_file to NULL and file->f_mode
|
||||
|
|
|
@ -83,7 +83,7 @@ static void test_db_entry()
|
|||
int_ops.dbe_free(&ent->ie_dbe);
|
||||
g_assert_cmpuint(test_free_count, ==, 1);
|
||||
|
||||
data_file_open(&f, OPEN_READ);
|
||||
file_open(&f, OPEN_READ);
|
||||
ent = INT_ENTRY(int_ops.dbe_read(&f, 0));
|
||||
file_close(&f);
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ void test_date()
|
|||
date_write_stamp(&f, &date);
|
||||
|
||||
file_close(&f);
|
||||
data_file_open(&f, OPEN_READ);
|
||||
file_open(&f, OPEN_READ);
|
||||
|
||||
date_read(&f, &date);
|
||||
g_assert_cmpuint(date.d_year, ==, 1988);
|
||||
|
|
|
@ -23,7 +23,7 @@ static void test_invalid_file(gconstpointer path)
|
|||
file_init_data(&file, "", (gchar *)path, 0);
|
||||
test_verify_constructor(&file, "", "");
|
||||
|
||||
g_assert_false(data_file_open(&file, OPEN_READ));
|
||||
g_assert_false(file_open(&file, OPEN_READ));
|
||||
g_assert_null(file.f_file);
|
||||
g_assert_false(data_file_open(&file, OPEN_WRITE));
|
||||
g_assert_null(file.f_file);
|
||||
|
@ -44,8 +44,8 @@ static void __test_file_subprocess()
|
|||
test_verify_constructor(&file, filepath, realpath);
|
||||
g_assert_false(file_exists(&file));
|
||||
|
||||
g_assert_false(data_file_open(&file, OPEN_READ));
|
||||
g_assert_false(data_file_open(&file, CLOSED));
|
||||
g_assert_false(file_open(&file, OPEN_READ));
|
||||
g_assert_false(file_open(&file, CLOSED));
|
||||
g_assert_true(data_file_open(&file, OPEN_WRITE));
|
||||
g_assert_nonnull(file.f_file);
|
||||
g_assert_cmpuint(file.f_mode, ==, OPEN_WRITE);
|
||||
|
@ -60,14 +60,14 @@ static void __test_file_subprocess()
|
|||
g_chmod(filepath, 0444);
|
||||
g_assert_false(data_file_open(&file, OPEN_WRITE));
|
||||
g_chmod(filepath, 0200);
|
||||
g_assert_false(data_file_open(&file, OPEN_READ));
|
||||
g_assert_false(file_open(&file, OPEN_READ));
|
||||
g_chmod(filepath, 0644);
|
||||
g_assert_false(data_file_open(&file, CLOSED));
|
||||
g_assert_false(file_open(&file, CLOSED));
|
||||
|
||||
g_assert_true(data_file_open(&file, OPEN_READ));
|
||||
g_assert_true(file_open(&file, OPEN_READ));
|
||||
g_assert_nonnull(file.f_file);
|
||||
g_assert_cmpuint(file.f_mode, ==, OPEN_READ);
|
||||
g_assert_false(data_file_open(&file, OPEN_READ));
|
||||
g_assert_false(file_open(&file, OPEN_READ));
|
||||
|
||||
g_assert_false(file_remove(&file));
|
||||
g_assert_true(file_exists(&file));
|
||||
|
@ -107,7 +107,7 @@ static void test_io()
|
|||
file_close(&fout);
|
||||
g_assert_true(file_exists(&fout));
|
||||
|
||||
g_assert_true(data_file_open(&fin, OPEN_READ));
|
||||
g_assert_true(file_open(&fin, OPEN_READ));
|
||||
g_assert_cmpuint(data_file_version(&fin), ==, 1);
|
||||
|
||||
g_assert_cmpuint(data_file_readf(&fin, "%u %ms\n", &i, &res), ==, 2);
|
||||
|
@ -144,7 +144,7 @@ static void __test_versioning_subprocess(unsigned int out, unsigned int in)
|
|||
file_close(&fout);
|
||||
g_assert_true(file_exists(&fout));
|
||||
|
||||
g_assert_false(data_file_open(&fin, OPEN_READ));
|
||||
g_assert_false(file_open(&fin, OPEN_READ));
|
||||
g_assert_null(fin.f_file);
|
||||
}
|
||||
|
||||
|
@ -194,6 +194,7 @@ static void test_cache()
|
|||
|
||||
/* Test writing data to a cache file. */
|
||||
g_assert_false(file_exists(&file));
|
||||
g_assert_false(file_open(&file, OPEN_READ_BINARY));
|
||||
g_assert_false(cache_file_open(&file, OPEN_READ));
|
||||
g_assert_false(cache_file_open(&file, CLOSED));
|
||||
g_assert_true(cache_file_open(&file, OPEN_WRITE));
|
||||
|
@ -209,6 +210,12 @@ static void test_cache()
|
|||
g_assert_true(file_exists(&file));
|
||||
g_assert_false(cache_file_open(&file, OPEN_READ));
|
||||
|
||||
g_assert_true(file_open(&file, OPEN_READ_BINARY));
|
||||
g_assert_cmpuint(file.f_mode, ==, OPEN_READ_BINARY);
|
||||
g_assert_cmpuint(file.f_version, ==, OCARINA_MINOR_VERSION);
|
||||
g_assert_cmpuint(file.f_prev, ==, 0);
|
||||
file_close(&file);
|
||||
|
||||
/* Test importing a file into the cache. */
|
||||
g_assert_false(file_exists(©));
|
||||
g_assert_false(cache_file_import(©, filepath));
|
||||
|
|
|
@ -349,7 +349,7 @@ static void test_save_load()
|
|||
playlist_generic_save(&q, &f, PL_SAVE_ALL);
|
||||
file_close(&f);
|
||||
|
||||
g_assert_true(data_file_open(&f, OPEN_READ));
|
||||
g_assert_true(file_open(&f, OPEN_READ));
|
||||
playlist_generic_load(&r, &f, PL_SAVE_METADATA);
|
||||
playlist_generic_load(&s, &f, PL_SAVE_ALL);
|
||||
file_close(&f);
|
||||
|
|
|
@ -64,7 +64,7 @@ static void test_album()
|
|||
file_close(&f);
|
||||
album_ops->dbe_free(&album->al_dbe);
|
||||
|
||||
data_file_open(&f, OPEN_READ);
|
||||
file_open(&f, OPEN_READ);
|
||||
album = ALBUM(album_ops->dbe_read(&f, 0));
|
||||
test_verify_empty(album);
|
||||
album_ops->dbe_free(&album->al_dbe);
|
||||
|
|
|
@ -47,7 +47,7 @@ static void test_artist()
|
|||
g_free(artist->ar_name);
|
||||
artist_ops->dbe_free(&artist->ar_dbe);
|
||||
|
||||
data_file_open(&f, OPEN_READ);
|
||||
file_open(&f, OPEN_READ);
|
||||
data_file_readf(&f, "%u", &i);
|
||||
artist = ARTIST(artist_ops->dbe_read(&f, 0));
|
||||
test_verify_empty(artist);
|
||||
|
|
|
@ -45,7 +45,7 @@ static void test_genre()
|
|||
g_free(genre->ge_name);
|
||||
genre_ops->dbe_free(&genre->ge_dbe);
|
||||
|
||||
data_file_open(&f, OPEN_READ);
|
||||
file_open(&f, OPEN_READ);
|
||||
data_file_readf(&f, "%u", &i);
|
||||
genre = GENRE(genre_ops->dbe_read(&f, 0));
|
||||
test_verify_empty(genre);
|
||||
|
|
|
@ -36,7 +36,7 @@ static void test_library()
|
|||
library_ops->dbe_write(&f, &zelda->li_dbe);
|
||||
file_close(&f);
|
||||
|
||||
data_file_open(&f, OPEN_READ);
|
||||
file_open(&f, OPEN_READ);
|
||||
library = LIBRARY(library_ops->dbe_read(&f, 0));
|
||||
test_verify_link(library);
|
||||
g_assert_cmpstr_free(library_file(library, "navi.mp3"), ==,
|
||||
|
|
|
@ -107,7 +107,7 @@ static void test_track()
|
|||
g_free(track->tr_path);
|
||||
track_ops->dbe_free(&track->tr_dbe);
|
||||
|
||||
data_file_open(&f, OPEN_READ);
|
||||
file_open(&f, OPEN_READ);
|
||||
track = TRACK(track_ops->dbe_read(&f, 0));
|
||||
track->tr_dbe.dbe_index = 0;
|
||||
test_verify_notrack(track);
|
||||
|
|
Loading…
Reference in New Issue
Block a user