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 <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
a848d5d03c
commit
35d53855f5
|
@ -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));
|
||||
|
|
57
core/file.c
57
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(©));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue