From 35d53855f5fd81ccbf1b35d8fd42d32256f9156a Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Tue, 20 Feb 2018 15:38:28 -0500 Subject: [PATCH] core/file: Add write support to file_open() I also take this opportunity to add a OPEN_WRITE_BINARY mode to support writing binary data to files. Signed-off-by: Anna Schumaker --- core/database.c | 2 +- core/file.c | 57 +++++++++++---------------------------- core/playlists/artist.c | 2 +- core/playlists/library.c | 2 +- core/playlists/system.c | 2 +- core/settings.c | 2 +- core/tags/album.c | 4 +-- include/core/file.h | 8 +++--- tests/core/database.c | 2 +- tests/core/date.c | 2 +- tests/core/file.c | 24 ++++++++--------- tests/core/playlist.c | 2 +- tests/core/tags/album.c | 2 +- tests/core/tags/artist.c | 2 +- tests/core/tags/genre.c | 2 +- tests/core/tags/library.c | 2 +- tests/core/tags/track.c | 2 +- 17 files changed, 45 insertions(+), 74 deletions(-) diff --git a/core/database.c b/core/database.c index d98064d4..0fdb383b 100644 --- a/core/database.c +++ b/core/database.c @@ -94,7 +94,7 @@ void db_deinit(struct database *db) void db_save(struct database *db) { - if (data_file_open(&db->db_file, OPEN_WRITE) == false) + if (file_open(&db->db_file, OPEN_WRITE) == false) return; data_file_writef(&db->db_file, "%u\n", db_actual_size(db)); diff --git a/core/file.c b/core/file.c index ea14d5ab..6d67d2a8 100644 --- a/core/file.c +++ b/core/file.c @@ -26,12 +26,6 @@ static void __file_init_common(struct file *file, const gchar *subdir, file->f_user_dir = user_dir; } -static gchar *__file_path(const gchar *base, const gchar *dir, - const gchar *name) -{ - return g_build_filename(base, OCARINA_NAME, dir ? dir : "", name, NULL); -} - static bool __file_open(struct file *file, enum open_mode mode) { gchar *cmode, *path; @@ -51,9 +45,10 @@ static bool __file_open(struct file *file, enum open_mode mode) return file->f_file != NULL; } -static bool __file_mkdir(const gchar *basedir, const gchar *subdir) +static bool __file_mkdir(struct file *file) { - gchar *dir = __file_path(basedir, subdir, NULL); + gchar *dir = g_build_filename(file->f_user_dir(), OCARINA_NAME, + file->f_subdir, NULL); int ret = g_mkdir_with_parents(dir, 0755); if (ret != 0) @@ -62,9 +57,9 @@ static bool __file_mkdir(const gchar *basedir, const gchar *subdir) return ret == 0; } -static bool __file_can_write(struct file *data) +static bool __file_can_write(struct file *file) { - gchar *path = file_path(data); + gchar *path = file_path(file); bool ret = true; if (g_access(path, F_OK) == 0 && g_access(path, W_OK) < 0) @@ -150,41 +145,19 @@ static bool __file_open_read(struct file *file, enum open_mode mode) return true; } -static bool __file_open_write(struct file *data) +static bool __file_open_write(struct file *file, enum open_mode mode) { - if (!__file_mkdir(g_get_user_data_dir(), NULL)) + if (!__file_mkdir(file)) return false; - if (!__file_can_write(data)) + if (!__file_can_write(file)) return false; - if (!__file_open(data, OPEN_WRITE)) + if (!__file_open(file, OPEN_WRITE)) return false; - data->f_mode = OPEN_WRITE; - return data_file_writef(data, "%d\n", data->f_version) > 0; -} - -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 || mode == OPEN_READ) - return false; - return __file_open_write(data); -} - -bool cache_file_open(struct file *cache, enum open_mode mode) -{ - if ((string_length(cache->f_name) == 0) || (cache->f_file != NULL)) - return false; - if (mode == OPEN_READ || mode == CLOSED) - 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_mode = mode; - return cache->f_file != NULL; + file->f_mode = mode; + if (mode == OPEN_WRITE_BINARY) + return true; + return data_file_writef(file, "%d\n", file->f_version) > 0; } bool file_open(struct file *file, enum open_mode mode) @@ -196,7 +169,7 @@ bool file_open(struct file *file, enum open_mode mode) if (mode == OPEN_READ || mode == OPEN_READ_BINARY) return __file_open_read(file, mode); - return false; + return __file_open_write(file, mode); } void file_close(struct file *file) @@ -206,7 +179,7 @@ void file_close(struct file *file) if (file->f_file) { fclose(file->f_file); - if (file->f_mode == OPEN_WRITE) + if (file->f_mode == OPEN_WRITE || file->f_mode == OPEN_WRITE_BINARY) g_rename(tmp, path); } diff --git a/core/playlists/artist.c b/core/playlists/artist.c index 2ed49859..88247a0a 100644 --- a/core/playlists/artist.c +++ b/core/playlists/artist.c @@ -70,7 +70,7 @@ static void pl_artist_save(void) struct db_entry *dbe, *next; struct playlist *playlist; - if (!data_file_open(&artist_file, OPEN_WRITE)) + if (!file_open(&artist_file, OPEN_WRITE)) return; data_file_writef(&artist_file, "%u\n", artist_db_get()->db_size); diff --git a/core/playlists/library.c b/core/playlists/library.c index 2354a32e..d7e56448 100644 --- a/core/playlists/library.c +++ b/core/playlists/library.c @@ -187,7 +187,7 @@ static void pl_library_save(void) struct db_entry *dbe, *next; struct playlist *playlist; - if (!data_file_open(&lib_file, OPEN_WRITE)) + if (!file_open(&lib_file, OPEN_WRITE)) return; data_file_writef(&lib_file, "%u\n", library_db_get()->db_size); diff --git a/core/playlists/system.c b/core/playlists/system.c index 64bb16c4..9bd2d1e6 100644 --- a/core/playlists/system.c +++ b/core/playlists/system.c @@ -330,7 +330,7 @@ static void pl_system_save(void) struct playlist *playlist; unsigned int i, save; - if (!data_file_open(&sys_pl_file, OPEN_WRITE)) + if (!file_open(&sys_pl_file, OPEN_WRITE)) return; data_file_writef(&sys_pl_file, "%u\n", SYS_PL_NUM_PLAYLISTS); diff --git a/core/settings.c b/core/settings.c index 515f61de..559b6163 100644 --- a/core/settings.c +++ b/core/settings.c @@ -16,7 +16,7 @@ static void __settings_save_item(gpointer key, gpointer value, gpointer data) static void __settings_save() { - data_file_open(&gui_settings_file, OPEN_WRITE); + file_open(&gui_settings_file, OPEN_WRITE); data_file_writef(&gui_settings_file, "%u\n", g_hash_table_size(gui_settings)); g_hash_table_foreach(gui_settings, __settings_save_item, NULL); diff --git a/core/tags/album.c b/core/tags/album.c index 125924f2..2c8ce518 100644 --- a/core/tags/album.c +++ b/core/tags/album.c @@ -64,7 +64,7 @@ static bool __album_fetch_cover(struct album *album, gchar *releaseid) } file = __album_alloc_file(album); - if (cache_file_open(&file->ac_file, OPEN_WRITE)) { + if (file_open(&file->ac_file, OPEN_WRITE_BINARY)) { cache_file_write(&file->ac_file, caa_imagedata_data(image), caa_imagedata_size(image)); file_close(&file->ac_file); @@ -391,7 +391,7 @@ bool album_artwork_import(struct album *album, gchar *path) bool ret = false; file = __album_alloc_file(album); - if (path && cache_file_open(&file->ac_file, OPEN_WRITE)) { + if (path && file_open(&file->ac_file, OPEN_WRITE_BINARY)) { ret = cache_file_import(&file->ac_file, path); file_close(&file->ac_file); } diff --git a/include/core/file.h b/include/core/file.h index 93306d42..84b01983 100644 --- a/include/core/file.h +++ b/include/core/file.h @@ -34,6 +34,7 @@ enum open_mode { 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. */ + OPEN_WRITE_BINARY, /* File is open for writing binary data. */ }; struct file { @@ -92,15 +93,14 @@ bool file_exists(struct file *); * - 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): + * When opening a file for writing (OPEN_WRITE / OPEN_WRITE_BINARY): * - Create missing directories as needed. * - Open a temporary file to protect data if Ocarina crashes. - * - Write file->_version to the start of the file (data files only). + * - If open for writing text (OPEN_WRITE): + * - Write file->_version to the start of the file (data files only). * * Returns true if the open was successful and false otherwise. */ -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); /* diff --git a/tests/core/database.c b/tests/core/database.c index cb97699a..5304860f 100644 --- a/tests/core/database.c +++ b/tests/core/database.c @@ -76,7 +76,7 @@ static void test_db_entry() g_assert_cmpuint(ent->ie_val, ==, 1); g_assert_cmpstr_free(int_ops.dbe_key(&ent->ie_dbe), ==, "1"); - data_file_open(&f, OPEN_WRITE); + file_open(&f, OPEN_WRITE); int_ops.dbe_write(&f, &ent->ie_dbe); file_close(&f); diff --git a/tests/core/date.c b/tests/core/date.c index 8e0953f5..2d71cf01 100644 --- a/tests/core/date.c +++ b/tests/core/date.c @@ -20,7 +20,7 @@ void test_date() date_today(NULL); date_set(NULL, 0, 0, 0); - data_file_open(&f, OPEN_WRITE); + file_open(&f, OPEN_WRITE); date_set(&date, 1988, 6, 17); g_assert_cmpuint(date.d_year, ==, 1988); diff --git a/tests/core/file.c b/tests/core/file.c index 72ac0fa8..85a379bd 100644 --- a/tests/core/file.c +++ b/tests/core/file.c @@ -25,7 +25,7 @@ static void test_invalid_file(gconstpointer path) 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_false(file_open(&file, OPEN_WRITE)); g_assert_null(file.f_file); g_assert_cmpuint(file.f_mode, ==, CLOSED); @@ -46,10 +46,10 @@ static void __test_file_subprocess() 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_true( file_open(&file, OPEN_WRITE)); g_assert_nonnull(file.f_file); g_assert_cmpuint(file.f_mode, ==, OPEN_WRITE); - g_assert_false(data_file_open(&file, OPEN_WRITE)); + g_assert_false(file_open(&file, OPEN_WRITE)); g_assert_false(file_exists(&file)); file_close(&file); @@ -58,7 +58,7 @@ static void __test_file_subprocess() g_assert_true(file_exists(&file)); g_chmod(filepath, 0444); - g_assert_false(data_file_open(&file, OPEN_WRITE)); + g_assert_false(file_open(&file, OPEN_WRITE)); g_chmod(filepath, 0200); g_assert_false(file_open(&file, OPEN_READ)); g_chmod(filepath, 0644); @@ -99,7 +99,7 @@ static void test_io() unsigned int i; fout.f_version = 1; - g_assert_true(data_file_open(&fout, OPEN_WRITE)); + g_assert_true(file_open(&fout, OPEN_WRITE)); data_file_writef(&fout, "1 ABCDE\n"); data_file_writef(&fout, "2 FGHIJ KLMNO\n"); data_file_writef(&fout, "3 \n"); @@ -139,7 +139,7 @@ static void __test_versioning_subprocess(unsigned int out, unsigned int in) fout.f_version = out; fin.f_version = in; - g_assert_true(data_file_open(&fout, OPEN_WRITE)); + g_assert_true(file_open(&fout, OPEN_WRITE)); data_file_writef(&fout, "abcdefghijklmnopqrstuvwxyz"); file_close(&fout); g_assert_true(file_exists(&fout)); @@ -195,12 +195,11 @@ 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)); + g_assert_false(file_open(&file, CLOSED)); + g_assert_true( file_open(&file, OPEN_WRITE_BINARY)); g_assert_nonnull(file.f_file); - g_assert_cmpuint(file.f_mode, ==, OPEN_WRITE); - g_assert_false(cache_file_open(&file, OPEN_WRITE)); + g_assert_cmpuint(file.f_mode, ==, OPEN_WRITE_BINARY); + g_assert_false(file_open(&file, OPEN_WRITE_BINARY)); g_assert_false(file_exists(&file)); g_assert_cmpuint(cache_file_write(&file, "abcde", 5), ==, 5); @@ -208,7 +207,6 @@ static void test_cache() g_assert_null(file.f_file); g_assert_cmpuint(file.f_mode, ==, CLOSED); 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); @@ -220,7 +218,7 @@ static void test_cache() g_assert_false(file_exists(©)); g_assert_false(cache_file_import(©, filepath)); g_assert_false(file_exists(©)); - g_assert_true(cache_file_open(©, OPEN_WRITE)); + g_assert_true(file_open(©, OPEN_WRITE_BINARY)); g_assert_false(cache_file_import(©, NULL)); g_assert_true(cache_file_import(©, filepath)); g_assert_false(file_exists(©)); diff --git a/tests/core/playlist.c b/tests/core/playlist.c index c5a2332c..de39da39 100644 --- a/tests/core/playlist.c +++ b/tests/core/playlist.c @@ -344,7 +344,7 @@ static void test_save_load() playlist_current_set(&q, 4); g_assert_false(file_exists(&f)); - g_assert_true( data_file_open(&f, OPEN_WRITE)); + g_assert_true( file_open(&f, OPEN_WRITE)); playlist_generic_save(&p, &f, PL_SAVE_METADATA); playlist_generic_save(&q, &f, PL_SAVE_ALL); file_close(&f); diff --git a/tests/core/tags/album.c b/tests/core/tags/album.c index e258a1ec..dbfaaf8b 100644 --- a/tests/core/tags/album.c +++ b/tests/core/tags/album.c @@ -58,7 +58,7 @@ static void test_album() g_assert_true( album_match_token(album, "symphony")); g_assert_false(album_match_token(album, "skyward")); - data_file_open(&f, OPEN_WRITE); + file_open(&f, OPEN_WRITE); data_file_writef(&f, "0 0 0 \n"); album_ops->dbe_write(&f, &album->al_dbe); file_close(&f); diff --git a/tests/core/tags/artist.c b/tests/core/tags/artist.c index 52893769..c948d18e 100644 --- a/tests/core/tags/artist.c +++ b/tests/core/tags/artist.c @@ -40,7 +40,7 @@ static void test_artist() g_assert_true( artist_match_token(artist, "kondo")); g_assert_false(artist_match_token(artist, "hajime")); - data_file_open(&f, OPEN_WRITE); + file_open(&f, OPEN_WRITE); data_file_writef(&f, "1 \n2 "); artist_ops->dbe_write(&f, &artist->ar_dbe); file_close(&f); diff --git a/tests/core/tags/genre.c b/tests/core/tags/genre.c index 631b0e1e..44735491 100644 --- a/tests/core/tags/genre.c +++ b/tests/core/tags/genre.c @@ -38,7 +38,7 @@ static void test_genre() g_assert_true( genre_match_token(genre, "music")); g_assert_false(genre_match_token(genre, "rock")); - data_file_open(&f, OPEN_WRITE); + file_open(&f, OPEN_WRITE); data_file_writef(&f, "1 \n1 "); genre_ops->dbe_write(&f, &genre->ge_dbe); file_close(&f); diff --git a/tests/core/tags/library.c b/tests/core/tags/library.c index 7a28a825..6fc54023 100644 --- a/tests/core/tags/library.c +++ b/tests/core/tags/library.c @@ -30,7 +30,7 @@ static void test_library() test_verify_link(link); test_verify_zelda(zelda); - data_file_open(&f, OPEN_WRITE); + file_open(&f, OPEN_WRITE); library_ops->dbe_write(&f, &link->li_dbe); data_file_writef(&f, "\n"); library_ops->dbe_write(&f, &zelda->li_dbe); diff --git a/tests/core/tags/track.c b/tests/core/tags/track.c index 44bfbd68..57e21e9d 100644 --- a/tests/core/tags/track.c +++ b/tests/core/tags/track.c @@ -98,7 +98,7 @@ static void test_track() g_assert_true( track_match_token(track, "theme")); g_assert_false(track_match_token(track, "hyrule")); - data_file_open(&f, OPEN_WRITE); + file_open(&f, OPEN_WRITE); data_file_writef(&f, "0 0 0 0 0 0 \n"); data_file_writef(&f, "Hyrule Symphony/00 - No Track.ogg\n"); track_ops->dbe_write(&f, &track->tr_dbe);