diff --git a/core/audio.c b/core/audio.c index 55d1a30d..8cdd87f0 100644 --- a/core/audio.c +++ b/core/audio.c @@ -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); diff --git a/core/database.c b/core/database.c index 71a02972..d98064d4 100644 --- a/core/database.c +++ b/core/database.c @@ -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); diff --git a/core/file.c b/core/file.c index a9ab6dae..ea14d5ab 100644 --- a/core/file.c +++ b/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); diff --git a/core/playlists/artist.c b/core/playlists/artist.c index efe257e0..2ed49859 100644 --- a/core/playlists/artist.c +++ b/core/playlists/artist.c @@ -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); diff --git a/core/playlists/library.c b/core/playlists/library.c index 2e73696e..2354a32e 100644 --- a/core/playlists/library.c +++ b/core/playlists/library.c @@ -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); diff --git a/core/playlists/system.c b/core/playlists/system.c index 8029efe1..64bb16c4 100644 --- a/core/playlists/system.c +++ b/core/playlists/system.c @@ -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(); diff --git a/core/settings.c b/core/settings.c index ca77db59..515f61de 100644 --- a/core/settings.c +++ b/core/settings.c @@ -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); } diff --git a/include/core/file.h b/include/core/file.h index f7f05246..93306d42 100644 --- a/include/core/file.h +++ b/include/core/file.h @@ -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 diff --git a/tests/core/database.c b/tests/core/database.c index bdd4454c..cb97699a 100644 --- a/tests/core/database.c +++ b/tests/core/database.c @@ -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); diff --git a/tests/core/date.c b/tests/core/date.c index df6a118e..8e0953f5 100644 --- a/tests/core/date.c +++ b/tests/core/date.c @@ -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); diff --git a/tests/core/file.c b/tests/core/file.c index f1a2a1c1..72ac0fa8 100644 --- a/tests/core/file.c +++ b/tests/core/file.c @@ -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)); diff --git a/tests/core/playlist.c b/tests/core/playlist.c index 41b511a2..c5a2332c 100644 --- a/tests/core/playlist.c +++ b/tests/core/playlist.c @@ -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); diff --git a/tests/core/tags/album.c b/tests/core/tags/album.c index 7d70994e..e258a1ec 100644 --- a/tests/core/tags/album.c +++ b/tests/core/tags/album.c @@ -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); diff --git a/tests/core/tags/artist.c b/tests/core/tags/artist.c index bd58bca4..52893769 100644 --- a/tests/core/tags/artist.c +++ b/tests/core/tags/artist.c @@ -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); diff --git a/tests/core/tags/genre.c b/tests/core/tags/genre.c index d8a53f85..631b0e1e 100644 --- a/tests/core/tags/genre.c +++ b/tests/core/tags/genre.c @@ -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); diff --git a/tests/core/tags/library.c b/tests/core/tags/library.c index ea7cf89c..7a28a825 100644 --- a/tests/core/tags/library.c +++ b/tests/core/tags/library.c @@ -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"), ==, diff --git a/tests/core/tags/track.c b/tests/core/tags/track.c index 529f03cc..44bfbd68 100644 --- a/tests/core/tags/track.c +++ b/tests/core/tags/track.c @@ -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);