core/file: Create a new, unified file structure
We'll spend the next several patches slowly switching over to the new way of accessing files. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
82280edfa2
commit
198fbf7f9b
|
@ -13,7 +13,7 @@
|
|||
static const char *SETTINGS_TRACK = "core.audio.cur";
|
||||
static const char *SETTINGS_VOLUME = "core.audio.volume";
|
||||
|
||||
static struct data_file audio_file = DATA_FILE_INIT("cur_track", 0);
|
||||
static struct file audio_file = DATA_FILE_INIT("cur_track", 0);
|
||||
static struct track *audio_track = NULL;
|
||||
static int audio_pause_count = -1;
|
||||
|
||||
|
|
|
@ -24,24 +24,24 @@ void date_today(struct date *date)
|
|||
date_set(date, now->tm_year + 1900, now->tm_mon + 1, now->tm_mday);
|
||||
}
|
||||
|
||||
void date_read(struct data_file *f, struct date *date)
|
||||
void date_read(struct file *f, struct date *date)
|
||||
{
|
||||
data_file_readf(f, "%u %u %u", &date->d_year, &date->d_month, &date->d_day);
|
||||
}
|
||||
|
||||
void date_read_stamp(struct data_file *f, struct date *date)
|
||||
void date_read_stamp(struct file *f, struct date *date)
|
||||
{
|
||||
uint32_t stamp;
|
||||
data_file_readf(f, "%u", &stamp);
|
||||
date->d_stamp = be32toh(stamp);
|
||||
}
|
||||
|
||||
void date_write(struct data_file *f, struct date *date)
|
||||
void date_write(struct file *f, struct date *date)
|
||||
{
|
||||
data_file_writef(f, "%u %u %u", date->d_year, date->d_month, date->d_day);
|
||||
}
|
||||
|
||||
void date_write_stamp(struct data_file *f, struct date *date)
|
||||
void date_write_stamp(struct file *f, struct date *date)
|
||||
{
|
||||
data_file_writef(f, "%u", htobe32(date->d_stamp));
|
||||
}
|
||||
|
|
100
core/file.c
100
core/file.c
|
@ -81,9 +81,9 @@ static bool __file_mkdir(const gchar *basedir, const gchar *subdir)
|
|||
return ret == 0;
|
||||
}
|
||||
|
||||
static bool __file_can_write(struct data_file *file)
|
||||
static bool __file_can_write(struct file *data)
|
||||
{
|
||||
gchar *path = data_file_path(file);
|
||||
gchar *path = data_file_path(data);
|
||||
bool ret = true;
|
||||
|
||||
if (g_access(path, F_OK) == 0 && g_access(path, W_OK) < 0)
|
||||
|
@ -94,8 +94,9 @@ static bool __file_can_write(struct data_file *file)
|
|||
}
|
||||
|
||||
|
||||
void data_file_init(struct data_file *file, const gchar *name, unsigned int min)
|
||||
void data_file_init(struct file *data, const gchar *name, unsigned int min)
|
||||
{
|
||||
struct data_file *file = &data->f_data;
|
||||
file->f_mode = OPEN_READ;
|
||||
file->f_version = OCARINA_MINOR_VERSION;
|
||||
file->f_prev = 0;
|
||||
|
@ -104,104 +105,114 @@ void data_file_init(struct data_file *file, const gchar *name, unsigned int min)
|
|||
file->f_name = name;
|
||||
}
|
||||
|
||||
void cache_file_init(struct cache_file *file, const gchar *subdir, const gchar *name)
|
||||
void cache_file_init(struct file *cache, const gchar *subdir, const gchar *name)
|
||||
{
|
||||
struct cache_file *file = &cache->f_cache;
|
||||
file->cf_file = NULL;
|
||||
file->cf_name = name;
|
||||
file->cf_subdir = subdir;
|
||||
}
|
||||
|
||||
gchar *data_file_path(struct data_file *file)
|
||||
gchar *data_file_path(struct file *data)
|
||||
{
|
||||
struct data_file *file = &data->f_data;
|
||||
return __file_build_path(g_get_user_data_dir(), NULL, file->f_name);
|
||||
}
|
||||
|
||||
gchar *cache_file_path(struct cache_file *file)
|
||||
gchar *cache_file_path(struct file *cache)
|
||||
{
|
||||
struct cache_file *file = &cache->f_cache;
|
||||
return __file_build_path(g_get_user_cache_dir(), file->cf_subdir,
|
||||
file->cf_name);
|
||||
}
|
||||
|
||||
gchar *data_file_write_path(struct data_file *file)
|
||||
gchar *data_file_write_path(struct file *data)
|
||||
{
|
||||
struct data_file *file = &data->f_data;
|
||||
return __file_build_tmp(g_get_user_data_dir(), NULL, file->f_name);
|
||||
}
|
||||
|
||||
gchar *cache_file_write_path(struct cache_file *file)
|
||||
gchar *cache_file_write_path(struct file *cache)
|
||||
{
|
||||
struct cache_file *file = &cache->f_cache;
|
||||
return __file_build_tmp(g_get_user_cache_dir(), file->cf_subdir,
|
||||
file->cf_name);
|
||||
}
|
||||
|
||||
const unsigned int data_file_version(struct data_file *file)
|
||||
const unsigned int data_file_version(struct file *data)
|
||||
{
|
||||
struct data_file *file = &data->f_data;
|
||||
if (file->f_file && (file->f_mode == OPEN_READ))
|
||||
return file->f_prev;
|
||||
return file->f_version;
|
||||
}
|
||||
|
||||
bool data_file_exists(struct data_file *file)
|
||||
bool data_file_exists(struct file *file)
|
||||
{
|
||||
return __file_exists(data_file_path(file));
|
||||
}
|
||||
|
||||
bool cache_file_exists(struct cache_file *file)
|
||||
bool cache_file_exists(struct file *file)
|
||||
{
|
||||
return __file_exists(cache_file_path(file));
|
||||
}
|
||||
|
||||
static bool __file_open_read(struct data_file *file)
|
||||
static bool __file_open_read(struct file *data)
|
||||
{
|
||||
if (!data_file_exists(file))
|
||||
struct data_file *file = &data->f_data;
|
||||
if (!data_file_exists(data))
|
||||
return false;
|
||||
|
||||
file->f_file = __file_open(data_file_path(file), "r");
|
||||
file->f_file = __file_open(data_file_path(data), "r");
|
||||
if (!file->f_file)
|
||||
return false;
|
||||
|
||||
file->f_mode = OPEN_READ;
|
||||
if (data_file_readf(file, "%u\n", &file->f_prev) != 1)
|
||||
if (data_file_readf(data, "%u\n", &file->f_prev) != 1)
|
||||
return false;
|
||||
if (file->f_prev < file->f_min) {
|
||||
REPORT_ERROR(file->f_name, "File too old to be upgraded.");
|
||||
data_file_close(file);
|
||||
data_file_close(data);
|
||||
exit(1);
|
||||
}
|
||||
if (file->f_prev > file->f_version) {
|
||||
REPORT_ERROR(file->f_name, "File too new to be opened.");
|
||||
data_file_close(file);
|
||||
data_file_close(data);
|
||||
exit(1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __file_open_write(struct data_file *file)
|
||||
static bool __file_open_write(struct file *data)
|
||||
{
|
||||
struct data_file *file = &data->f_data;
|
||||
if (!__file_mkdir(g_get_user_data_dir(), NULL))
|
||||
return false;
|
||||
if (!__file_can_write(file))
|
||||
if (!__file_can_write(data))
|
||||
return false;
|
||||
|
||||
file->f_file = __file_open(data_file_write_path(file), "w");
|
||||
file->f_file = __file_open(data_file_write_path(data), "w");
|
||||
if (!file->f_file)
|
||||
return false;
|
||||
|
||||
file->f_mode = OPEN_WRITE;
|
||||
return data_file_writef(file, "%d\n", file->f_version) > 0;
|
||||
return data_file_writef(data, "%d\n", file->f_version) > 0;
|
||||
}
|
||||
|
||||
bool data_file_open(struct data_file *file, enum open_mode mode)
|
||||
bool data_file_open(struct file *data, enum open_mode mode)
|
||||
{
|
||||
struct data_file *file = &data->f_data;
|
||||
if ((string_length(file->f_name) == 0) || (file->f_file != NULL))
|
||||
return false;
|
||||
|
||||
if (mode == OPEN_READ)
|
||||
return __file_open_read(file);
|
||||
return __file_open_write(file);
|
||||
return __file_open_read(data);
|
||||
return __file_open_write(data);
|
||||
}
|
||||
|
||||
bool cache_file_open(struct cache_file *file, enum open_mode mode)
|
||||
bool cache_file_open(struct file *cache, enum open_mode mode)
|
||||
{
|
||||
struct cache_file *file = &cache->f_cache;
|
||||
if (mode == OPEN_READ)
|
||||
return false;
|
||||
if ((string_length(file->cf_name) == 0) || (file->cf_file != NULL))
|
||||
|
@ -209,28 +220,31 @@ bool cache_file_open(struct cache_file *file, enum open_mode mode)
|
|||
if (!__file_mkdir(g_get_user_cache_dir(), file->cf_subdir))
|
||||
return false;
|
||||
|
||||
file->cf_file = __file_open(cache_file_write_path(file), "wb");
|
||||
file->cf_file = __file_open(cache_file_write_path(cache), "wb");
|
||||
return file->cf_file != NULL;
|
||||
}
|
||||
|
||||
void data_file_close(struct data_file *file)
|
||||
void data_file_close(struct file *data)
|
||||
{
|
||||
struct data_file *file = &data->f_data;
|
||||
__file_close(file->f_file,
|
||||
file->f_mode == OPEN_WRITE ? data_file_path(file) : NULL,
|
||||
file->f_mode == OPEN_WRITE ? data_file_write_path(file) : NULL);
|
||||
file->f_mode == OPEN_WRITE ? data_file_path(data) : NULL,
|
||||
file->f_mode == OPEN_WRITE ? data_file_write_path(data) : NULL);
|
||||
file->f_file = NULL;
|
||||
}
|
||||
|
||||
void cache_file_close(struct cache_file *file)
|
||||
void cache_file_close(struct file *cache)
|
||||
{
|
||||
struct cache_file *file = &cache->f_cache;
|
||||
__file_close(file->cf_file,
|
||||
cache_file_path(file),
|
||||
cache_file_write_path(file));
|
||||
cache_file_path(cache),
|
||||
cache_file_write_path(cache));
|
||||
file->cf_file = NULL;
|
||||
}
|
||||
|
||||
int data_file_readf(struct data_file *file, const char *fmt, ...)
|
||||
int data_file_readf(struct file *data, const char *fmt, ...)
|
||||
{
|
||||
struct data_file *file = &data->f_data;
|
||||
va_list argp;
|
||||
int ret;
|
||||
|
||||
|
@ -241,19 +255,20 @@ int data_file_readf(struct data_file *file, const char *fmt, ...)
|
|||
return ret;
|
||||
}
|
||||
|
||||
gchar *data_file_readl(struct data_file *file)
|
||||
gchar *data_file_readl(struct file *data)
|
||||
{
|
||||
gchar *res;
|
||||
|
||||
if (data_file_readf(file, "%m[^\n]\n", &res) == 0)
|
||||
if (data_file_readf(data, "%m[^\n]\n", &res) == 0)
|
||||
return g_strdup("");
|
||||
|
||||
g_strstrip(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
int data_file_writef(struct data_file *file, const char *fmt, ...)
|
||||
int data_file_writef(struct file *data, const char *fmt, ...)
|
||||
{
|
||||
struct data_file *file = &data->f_data;
|
||||
va_list argp;
|
||||
int ret;
|
||||
|
||||
|
@ -266,15 +281,17 @@ int data_file_writef(struct data_file *file, const char *fmt, ...)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int cache_file_write(struct cache_file *file, const void *data, size_t len)
|
||||
int cache_file_write(struct file *cache, const void *data, size_t len)
|
||||
{
|
||||
struct cache_file *file = &cache->f_cache;
|
||||
if (fwrite(data, len, 1, file->cf_file) == 1)
|
||||
return len;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool cache_file_import(struct cache_file *file, const gchar *srcpath)
|
||||
bool cache_file_import(struct file *cache, const gchar *srcpath)
|
||||
{
|
||||
struct cache_file *file = &cache->f_cache;
|
||||
gchar *contents = NULL;
|
||||
gsize length = 0;
|
||||
|
||||
|
@ -283,17 +300,18 @@ bool cache_file_import(struct cache_file *file, const gchar *srcpath)
|
|||
if (!g_file_get_contents(srcpath, &contents, &length, NULL))
|
||||
return false;
|
||||
|
||||
cache_file_write(file, contents, length);
|
||||
cache_file_write(cache, contents, length);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool data_file_remove(struct data_file *file)
|
||||
bool data_file_remove(struct file *data)
|
||||
{
|
||||
struct data_file *file = &data->f_data;
|
||||
int ret = -1;
|
||||
gchar *path;
|
||||
|
||||
if (!file->f_file) {
|
||||
path = data_file_path(file);
|
||||
path = data_file_path(data);
|
||||
ret = g_unlink(path);
|
||||
g_free(path);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <core/playlists/artist.h>
|
||||
#include <core/string.h>
|
||||
|
||||
static struct data_file artist_file = DATA_FILE_INIT("playlist.artist", 0);
|
||||
static struct file artist_file = DATA_FILE_INIT("playlist.artist", 0);
|
||||
|
||||
static struct playlist_ops pl_artist_ops = {
|
||||
.pl_can_select = playlist_generic_can_select,
|
||||
|
|
|
@ -95,7 +95,7 @@ void playlist_generic_free(struct playlist *playlist)
|
|||
}
|
||||
}
|
||||
|
||||
void playlist_generic_save(struct playlist *playlist, struct data_file *file,
|
||||
void playlist_generic_save(struct playlist *playlist, struct file *file,
|
||||
unsigned int flags)
|
||||
{
|
||||
playlist_iter it;
|
||||
|
@ -129,7 +129,7 @@ void playlist_generic_save(struct playlist *playlist, struct data_file *file,
|
|||
}
|
||||
}
|
||||
|
||||
void playlist_generic_load(struct playlist *playlist, struct data_file *file,
|
||||
void playlist_generic_load(struct playlist *playlist, struct file *file,
|
||||
unsigned int flags)
|
||||
{
|
||||
unsigned int f, n, i, t, it = 0;
|
||||
|
|
|
@ -14,7 +14,7 @@ struct scan_data {
|
|||
};
|
||||
|
||||
static bool __lib_pl_scan_dir(void *);
|
||||
static struct data_file lib_file = DATA_FILE_INIT("playlist.library", 0);
|
||||
static struct file lib_file = DATA_FILE_INIT("playlist.library", 0);
|
||||
|
||||
static struct playlist_ops pl_library_ops;
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ static struct playlist *pl_system_lookup(const gchar *);
|
|||
static struct playlist *pl_system_get(unsigned int);
|
||||
static void pl_system_save();
|
||||
|
||||
static struct data_file sys_file = DATA_FILE_INIT("playlist.db", 0);
|
||||
static struct data_file sys_deck_f = DATA_FILE_INIT("deck", 1);
|
||||
static struct data_file sys_collection_f = DATA_FILE_INIT("library.q", 0);
|
||||
static struct data_file sys_pl_file = DATA_FILE_INIT("playlist.system", 0);
|
||||
static struct file sys_file = DATA_FILE_INIT("playlist.db", 0);
|
||||
static struct file sys_deck_f = DATA_FILE_INIT("deck", 1);
|
||||
static struct file sys_collection_f = DATA_FILE_INIT("library.q", 0);
|
||||
static struct file sys_pl_file = DATA_FILE_INIT("playlist.system", 0);
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -37,7 +37,7 @@ static gchar *user_db_key(struct db_entry *dbe)
|
|||
return g_strdup(USER_PLAYLIST(dbe)->pl_playlist.pl_name);
|
||||
}
|
||||
|
||||
static struct db_entry *user_db_read(struct data_file *file, unsigned int index)
|
||||
static struct db_entry *user_db_read(struct file *file, unsigned int index)
|
||||
{
|
||||
gchar *name = data_file_readl(file);
|
||||
struct user_playlist *playlist = __user_db_alloc(name, index);
|
||||
|
@ -46,7 +46,7 @@ static struct db_entry *user_db_read(struct data_file *file, unsigned int index)
|
|||
return &playlist->pl_dbe;
|
||||
}
|
||||
|
||||
static void user_db_write(struct data_file *file, struct db_entry *dbe)
|
||||
static void user_db_write(struct file *file, struct db_entry *dbe)
|
||||
{
|
||||
struct playlist *playlist = &USER_PLAYLIST(dbe)->pl_playlist;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <core/settings.h>
|
||||
|
||||
static GHashTable *gui_settings = NULL;
|
||||
static struct data_file gui_settings_file = DATA_FILE_INIT("settings", 0);
|
||||
static struct file gui_settings_file = DATA_FILE_INIT("settings", 0);
|
||||
|
||||
|
||||
static void __settings_save_item(gpointer key, gpointer value, gpointer data)
|
||||
|
|
|
@ -20,7 +20,7 @@ static struct database album_db;
|
|||
static bool album_db_upgraded = false;
|
||||
|
||||
struct album_cache_file {
|
||||
struct cache_file ac_file;
|
||||
struct file ac_file;
|
||||
gchar *ac_subdir;
|
||||
gchar *ac_name;
|
||||
};
|
||||
|
@ -252,7 +252,7 @@ static struct album *__album_parse_v0(gchar *line)
|
|||
return __album_alloc(NULL, NULL, name, year);
|
||||
}
|
||||
|
||||
static struct db_entry *album_read(struct data_file *file, unsigned int index)
|
||||
static struct db_entry *album_read(struct file *file, unsigned int index)
|
||||
{
|
||||
unsigned int year, artist_id, genre_id, n;
|
||||
struct album *album;
|
||||
|
@ -276,7 +276,7 @@ out:
|
|||
return &album->al_dbe;
|
||||
}
|
||||
|
||||
static void album_write(struct data_file *file, struct db_entry *dbe)
|
||||
static void album_write(struct file *file, struct db_entry *dbe)
|
||||
{
|
||||
struct album *album = ALBUM(dbe);
|
||||
struct artist *artist = album->al_artist;
|
||||
|
|
|
@ -37,12 +37,12 @@ static gchar *artist_key(struct db_entry *dbe)
|
|||
return ARTIST(dbe)->ar_name;
|
||||
}
|
||||
|
||||
struct db_entry *artist_read(struct data_file *file, unsigned int index)
|
||||
struct db_entry *artist_read(struct file *file, unsigned int index)
|
||||
{
|
||||
return &__artist_alloc(data_file_readl(file))->ar_dbe;
|
||||
}
|
||||
|
||||
static void artist_write(struct data_file *file, struct db_entry *dbe)
|
||||
static void artist_write(struct file *file, struct db_entry *dbe)
|
||||
{
|
||||
data_file_writef(file, "%s", ARTIST(dbe)->ar_name);
|
||||
}
|
||||
|
|
|
@ -35,12 +35,12 @@ static gchar *genre_key(struct db_entry *dbe)
|
|||
return GENRE(dbe)->ge_name;
|
||||
}
|
||||
|
||||
static struct db_entry *genre_read(struct data_file *file, unsigned int index)
|
||||
static struct db_entry *genre_read(struct file *file, unsigned int index)
|
||||
{
|
||||
return &__genre_alloc(data_file_readl(file))->ge_dbe;
|
||||
}
|
||||
|
||||
static void genre_write(struct data_file *file, struct db_entry *dbe)
|
||||
static void genre_write(struct file *file, struct db_entry *dbe)
|
||||
{
|
||||
data_file_writef(file, "%s", GENRE(dbe)->ge_name);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ static gchar *library_key(struct db_entry *dbe)
|
|||
return LIBRARY(dbe)->li_path;
|
||||
}
|
||||
|
||||
static struct db_entry *library_read(struct data_file *file, unsigned int index)
|
||||
static struct db_entry *library_read(struct file *file, unsigned int index)
|
||||
{
|
||||
int enabled;
|
||||
gchar *path;
|
||||
|
@ -45,7 +45,7 @@ static struct db_entry *library_read(struct data_file *file, unsigned int index)
|
|||
return &__library_alloc(path)->li_dbe;
|
||||
}
|
||||
|
||||
static void library_write(struct data_file *file, struct db_entry *dbe)
|
||||
static void library_write(struct file *file, struct db_entry *dbe)
|
||||
{
|
||||
data_file_writef(file, "%s", LIBRARY(dbe)->li_path);
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ static gchar *track_key(struct db_entry *dbe)
|
|||
return TRACK(dbe)->tr_path;
|
||||
}
|
||||
|
||||
static void track_read_v0(struct data_file *file, struct track *track)
|
||||
static void track_read_v0(struct file *file, struct track *track)
|
||||
{
|
||||
unsigned int artist_id, album_id, genre_id;
|
||||
struct artist *artist;
|
||||
|
@ -147,7 +147,7 @@ static void track_read_v0(struct data_file *file, struct track *track)
|
|||
track->tr_album = album;
|
||||
}
|
||||
|
||||
static struct db_entry *track_read(struct data_file *file, unsigned int index)
|
||||
static struct db_entry *track_read(struct file *file, unsigned int index)
|
||||
{
|
||||
struct track *track = __track_alloc();
|
||||
unsigned int library_id, album_id;
|
||||
|
@ -177,7 +177,7 @@ static struct db_entry *track_read(struct data_file *file, unsigned int index)
|
|||
|
||||
}
|
||||
|
||||
static void track_write(struct data_file *file, struct db_entry *dbe)
|
||||
static void track_write(struct file *file, struct db_entry *dbe)
|
||||
{
|
||||
struct track *track = TRACK(dbe);
|
||||
gchar *path = __track_path(track);
|
||||
|
|
|
@ -57,17 +57,17 @@ struct db_ops {
|
|||
gchar *(*dbe_key)(struct db_entry *);
|
||||
|
||||
/* Read a single struct db_entry from disk. */
|
||||
struct db_entry *(*dbe_read)(struct data_file *, unsigned int);
|
||||
struct db_entry *(*dbe_read)(struct file *, unsigned int);
|
||||
|
||||
/* Write a single struct db_entry to disk. */
|
||||
void (*dbe_write)(struct data_file *, struct db_entry *);
|
||||
void (*dbe_write)(struct file *, struct db_entry *);
|
||||
};
|
||||
|
||||
|
||||
struct database {
|
||||
unsigned int db_size; /* The database's count of valid entries. */
|
||||
bool db_autosave; /* The database's automatic save setting. */
|
||||
struct data_file db_file; /* The database's associated file object. */
|
||||
struct file db_file; /* The database's associated file object. */
|
||||
GPtrArray *db_entries; /* The database's backing array. */
|
||||
GHashTable *db_keys; /* The database's mapping of key -> value. */
|
||||
|
||||
|
|
|
@ -27,12 +27,12 @@ void date_set(struct date *, unsigned int, unsigned int, unsigned int);
|
|||
void date_today(struct date *);
|
||||
|
||||
/* Read the date from file. */
|
||||
void date_read(struct data_file *, struct date *);
|
||||
void date_read_stamp(struct data_file *, struct date *);
|
||||
void date_read(struct file *, struct date *);
|
||||
void date_read_stamp(struct file *, struct date *);
|
||||
|
||||
/* Write the date to file. */
|
||||
void date_write(struct data_file *, struct date *);
|
||||
void date_write_stamp(struct data_file *, struct date *);
|
||||
void date_write(struct file *, struct date *);
|
||||
void date_write_stamp(struct file *, struct date *);
|
||||
|
||||
/*
|
||||
* Convert the date into a string.
|
||||
|
|
|
@ -43,47 +43,55 @@ struct data_file {
|
|||
const gchar *f_name; /* The file's basename. */
|
||||
};
|
||||
|
||||
#define DATA_FILE_INIT(fname, min) \
|
||||
{ \
|
||||
.f_mode = OPEN_READ, \
|
||||
.f_version = OCARINA_MINOR_VERSION, \
|
||||
.f_prev = 0, \
|
||||
.f_min = min, \
|
||||
.f_file = NULL, \
|
||||
.f_name = fname, \
|
||||
}
|
||||
|
||||
|
||||
struct cache_file {
|
||||
FILE *cf_file; /* The cache file's IO stream. */
|
||||
const gchar *cf_name; /* The cache file's basename. */
|
||||
const gchar *cf_subdir; /* The cache file's subdirectory. */
|
||||
};
|
||||
|
||||
/* Initialize a new file object. */
|
||||
void data_file_init(struct data_file *, const gchar *, unsigned int);
|
||||
void cache_file_init(struct cache_file *, const gchar *, const gchar *);
|
||||
struct file {
|
||||
union {
|
||||
struct data_file f_data;
|
||||
struct cache_file f_cache;
|
||||
};
|
||||
};
|
||||
|
||||
#define DATA_FILE_INIT(fname, min) \
|
||||
{ \
|
||||
.f_data = { \
|
||||
.f_mode = OPEN_READ, \
|
||||
.f_version = OCARINA_MINOR_VERSION, \
|
||||
.f_prev = 0, \
|
||||
.f_min = min, \
|
||||
.f_file = NULL, \
|
||||
.f_name = fname, \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Initialize a file object. */
|
||||
void data_file_init(struct file *, const gchar *, unsigned int);
|
||||
void cache_file_init(struct file *, const gchar *, const gchar *);
|
||||
|
||||
/*
|
||||
* Returns the full path of the file or an empty string if filename is not set.
|
||||
* These functions allocates a new string that MUST be freed with g_free().
|
||||
*/
|
||||
gchar *data_file_path(struct data_file *);
|
||||
gchar *cache_file_path(struct cache_file *);
|
||||
gchar *data_file_path(struct file *);
|
||||
gchar *cache_file_path(struct file *);
|
||||
|
||||
/*
|
||||
* Returns the path to the temporary file used for writes.
|
||||
* This function allocates a new string that MUST be freed with g_free().
|
||||
*/
|
||||
gchar *data_file_write_path(struct data_file *);
|
||||
gchar *cache_file_write_path(struct cache_file *);
|
||||
gchar *data_file_write_path(struct file *);
|
||||
gchar *cache_file_write_path(struct file *);
|
||||
|
||||
/* Returns the version number of the file. */
|
||||
const unsigned int data_file_version(struct data_file *);
|
||||
const unsigned int data_file_version(struct file *);
|
||||
|
||||
/* Returns true if the file exists on disk and false otherwise. */
|
||||
bool data_file_exists(struct data_file *);
|
||||
bool cache_file_exists(struct cache_file *);
|
||||
bool data_file_exists(struct file *);
|
||||
bool cache_file_exists(struct file *);
|
||||
|
||||
/*
|
||||
* Call to open a file for either reading or writing. Callers
|
||||
|
@ -101,44 +109,44 @@ bool cache_file_exists(struct cache_file *);
|
|||
* 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 data_file *, enum open_mode);
|
||||
bool cache_file_open(struct cache_file *, enum open_mode);
|
||||
bool data_file_open(struct file *, enum open_mode);
|
||||
bool cache_file_open(struct file *, enum open_mode);
|
||||
|
||||
/*
|
||||
* Closes an open file, setting file->{f|cf}_file to NULL. If the file was opened
|
||||
* with OPEN_WRITE, then rename the temporary file to file_path().
|
||||
*/
|
||||
void data_file_close(struct data_file *);
|
||||
void cache_file_close(struct cache_file *);
|
||||
void data_file_close(struct file *);
|
||||
void cache_file_close(struct file *);
|
||||
|
||||
/*
|
||||
* Read an entire line from the file and return it to the caller.
|
||||
* This function allocates a new string that MUST be freed with g_free().
|
||||
*/
|
||||
gchar *data_file_readl(struct data_file *);
|
||||
gchar *data_file_readl(struct file *);
|
||||
|
||||
/*
|
||||
* Read from a file with an fscanf(3) style format string.
|
||||
* Returns the number of items matched.
|
||||
*/
|
||||
int data_file_readf(struct data_file *, const char *, ...);
|
||||
int data_file_readf(struct file *, const char *, ...);
|
||||
|
||||
/*
|
||||
* Write to a file with an fprintf(3) style format string.
|
||||
* Returns the number of bytes successfully written.
|
||||
*/
|
||||
int data_file_writef(struct data_file *, const char *, ...);
|
||||
int data_file_writef(struct file *, const char *, ...);
|
||||
|
||||
/*
|
||||
* Write binary data to a cache file similar to fwrite(3).
|
||||
* Returns the number of bytes successfully written.
|
||||
*/
|
||||
int cache_file_write(struct cache_file *, const void *, size_t);
|
||||
int cache_file_write(struct file *, const void *, size_t);
|
||||
|
||||
/* Import a file into the cache. */
|
||||
bool cache_file_import(struct cache_file *, const gchar *);
|
||||
bool cache_file_import(struct file *, const gchar *);
|
||||
|
||||
/* Removes a closed file from disk. */
|
||||
bool data_file_remove(struct data_file *);
|
||||
bool data_file_remove(struct file *);
|
||||
|
||||
#endif /* OCARINA_CORE_FILE_H */
|
||||
|
|
|
@ -54,10 +54,10 @@ struct playlist *playlist_generic_alloc(gchar *, enum playlist_type_t,
|
|||
void playlist_generic_free(struct playlist *);
|
||||
|
||||
/* Generic playlist save function. */
|
||||
void playlist_generic_save(struct playlist *, struct data_file *, unsigned int);
|
||||
void playlist_generic_save(struct playlist *, struct file *, unsigned int);
|
||||
|
||||
/* Generic playlist load function. */
|
||||
void playlist_generic_load(struct playlist *, struct data_file *, unsigned int);
|
||||
void playlist_generic_load(struct playlist *, struct file *, unsigned int);
|
||||
|
||||
/* Generic playlist can-select function. */
|
||||
bool playlist_generic_can_select(struct playlist *);
|
||||
|
|
|
@ -44,14 +44,14 @@ static gchar *int_key(struct db_entry *dbe)
|
|||
return g_strdup_printf("%u", INT_ENTRY(dbe)->ie_val);
|
||||
}
|
||||
|
||||
static struct db_entry *int_read(struct data_file *f, unsigned int index)
|
||||
static struct db_entry *int_read(struct file *f, unsigned int index)
|
||||
{
|
||||
unsigned int val;
|
||||
data_file_readf(f, "%u", &val);
|
||||
return &__int_alloc(val)->ie_dbe;
|
||||
}
|
||||
|
||||
static void int_write(struct data_file *file, struct db_entry *dbe)
|
||||
static void int_write(struct file *file, struct db_entry *dbe)
|
||||
{
|
||||
data_file_writef(file, "%u", INT_ENTRY(dbe)->ie_val);
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ static const struct db_ops int_ops = {
|
|||
static void test_db_entry()
|
||||
{
|
||||
struct int_entry *ent;
|
||||
struct data_file f;
|
||||
struct file f;
|
||||
|
||||
ent = INT_ENTRY(int_ops.dbe_alloc("1", 0));
|
||||
g_assert_cmpuint(ent->ie_dbe.dbe_index, ==, 0);
|
||||
|
@ -105,8 +105,8 @@ static void test_init()
|
|||
g_assert_cmpuint(g_hash_table_size(db.db_keys), ==, 0);
|
||||
g_assert_cmpuint(db.db_size, ==, 0);
|
||||
g_assert_false(db.db_autosave);
|
||||
g_assert_cmpuint(db.db_file.f_version, ==, OCARINA_MINOR_VERSION);
|
||||
g_assert_cmpstr(db.db_file.f_name, ==, "init.db");
|
||||
g_assert_cmpuint(db.db_file.f_data.f_version, ==, OCARINA_MINOR_VERSION);
|
||||
g_assert_cmpstr(db.db_file.f_data.f_name, ==, "init.db");
|
||||
|
||||
db_deinit(&db);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ void test_date()
|
|||
.d_month = 0,
|
||||
.d_day = 0,
|
||||
};
|
||||
struct data_file f = DATA_FILE_INIT("date", 0);
|
||||
struct file f = DATA_FILE_INIT("date", 0);
|
||||
|
||||
date_today(NULL);
|
||||
date_set(NULL, 0, 0, 0);
|
||||
|
|
|
@ -7,34 +7,34 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
|
||||
static void test_verify_constructor(struct data_file *file, gchar *fpath, gchar *ftmp)
|
||||
static void test_verify_constructor(struct file *file, gchar *fpath, gchar *ftmp)
|
||||
{
|
||||
g_assert_null(file->f_file);
|
||||
g_assert_null(file->f_data.f_file);
|
||||
g_assert_cmpuint(data_file_version(file), ==, OCARINA_MINOR_VERSION);
|
||||
g_assert_cmpuint(file->f_mode, ==, OPEN_READ);
|
||||
g_assert_cmpuint(file->f_data.f_mode, ==, OPEN_READ);
|
||||
g_assert_cmpstr_free(data_file_path(file), ==, fpath);
|
||||
g_assert_cmpstr_free(data_file_write_path(file), ==, ftmp);
|
||||
}
|
||||
|
||||
static void test_invalid_file(gconstpointer path)
|
||||
{
|
||||
struct data_file file;
|
||||
struct file file;
|
||||
|
||||
data_file_init(&file, (gchar *)path, 0);
|
||||
test_verify_constructor(&file, "", "");
|
||||
|
||||
g_assert_false(data_file_open(&file, OPEN_READ));
|
||||
g_assert_null(file.f_file);
|
||||
g_assert_null(file.f_data.f_file);
|
||||
g_assert_false(data_file_open(&file, OPEN_WRITE));
|
||||
g_assert_null(file.f_file);
|
||||
g_assert_cmpuint(file.f_mode, ==, OPEN_READ);
|
||||
g_assert_null(file.f_data.f_file);
|
||||
g_assert_cmpuint(file.f_data.f_mode, ==, OPEN_READ);
|
||||
|
||||
g_assert_false(data_file_exists(&file));
|
||||
}
|
||||
|
||||
static void __test_file_subprocess()
|
||||
{
|
||||
struct data_file file = DATA_FILE_INIT("file.txt", 0);
|
||||
struct file file = DATA_FILE_INIT("file.txt", 0);
|
||||
gchar *basepath, *filepath, *realpath;
|
||||
|
||||
basepath = g_strjoin("/", g_get_user_data_dir(), OCARINA_NAME, NULL);
|
||||
|
@ -46,14 +46,14 @@ static void __test_file_subprocess()
|
|||
|
||||
g_assert_false(data_file_open(&file, OPEN_READ));
|
||||
g_assert_true(data_file_open(&file, OPEN_WRITE));
|
||||
g_assert_nonnull(file.f_file);
|
||||
g_assert_cmpuint(file.f_mode, ==, OPEN_WRITE);
|
||||
g_assert_nonnull(file.f_data.f_file);
|
||||
g_assert_cmpuint(file.f_data.f_mode, ==, OPEN_WRITE);
|
||||
g_assert_false(data_file_open(&file, OPEN_WRITE));
|
||||
|
||||
g_assert_false(data_file_exists(&file));
|
||||
data_file_close(&file);
|
||||
g_assert_null(file.f_file);
|
||||
g_assert_cmpuint(file.f_mode, ==, OPEN_WRITE);
|
||||
g_assert_null(file.f_data.f_file);
|
||||
g_assert_cmpuint(file.f_data.f_mode, ==, OPEN_WRITE);
|
||||
g_assert_true(data_file_exists(&file));
|
||||
|
||||
g_chmod(filepath, 0444);
|
||||
|
@ -63,8 +63,8 @@ static void __test_file_subprocess()
|
|||
g_chmod(filepath, 0644);
|
||||
|
||||
g_assert_true(data_file_open(&file, OPEN_READ));
|
||||
g_assert_nonnull(file.f_file);
|
||||
g_assert_cmpuint(file.f_mode, ==, OPEN_READ);
|
||||
g_assert_nonnull(file.f_data.f_file);
|
||||
g_assert_cmpuint(file.f_data.f_mode, ==, OPEN_READ);
|
||||
g_assert_false(data_file_open(&file, OPEN_READ));
|
||||
|
||||
g_assert_false(data_file_remove(&file));
|
||||
|
@ -90,12 +90,12 @@ static void test_file()
|
|||
|
||||
static void test_io()
|
||||
{
|
||||
struct data_file fout = DATA_FILE_INIT("file.txt", 0);
|
||||
struct data_file fin = DATA_FILE_INIT("file.txt", 1);
|
||||
struct file fout = DATA_FILE_INIT("file.txt", 0);
|
||||
struct file fin = DATA_FILE_INIT("file.txt", 1);
|
||||
char *res = NULL;
|
||||
unsigned int i;
|
||||
|
||||
fout.f_version = 1;
|
||||
fout.f_data.f_version = 1;
|
||||
g_assert_true(data_file_open(&fout, OPEN_WRITE));
|
||||
data_file_writef(&fout, "1 ABCDE\n");
|
||||
data_file_writef(&fout, "2 FGHIJ KLMNO\n");
|
||||
|
@ -130,11 +130,11 @@ static void test_io()
|
|||
|
||||
static void __test_versioning_subprocess(unsigned int out, unsigned int in)
|
||||
{
|
||||
struct data_file fout = DATA_FILE_INIT("file.txt", out);
|
||||
struct data_file fin = DATA_FILE_INIT("file.txt", in);
|
||||
struct file fout = DATA_FILE_INIT("file.txt", out);
|
||||
struct file fin = DATA_FILE_INIT("file.txt", in);
|
||||
|
||||
fout.f_version = out;
|
||||
fin.f_version = in;
|
||||
fout.f_data.f_version = out;
|
||||
fin.f_data.f_version = in;
|
||||
|
||||
g_assert_true(data_file_open(&fout, OPEN_WRITE));
|
||||
data_file_writef(&fout, "abcdefghijklmnopqrstuvwxyz");
|
||||
|
@ -142,7 +142,7 @@ static void __test_versioning_subprocess(unsigned int out, unsigned int in)
|
|||
g_assert_true(data_file_exists(&fout));
|
||||
|
||||
g_assert_false(data_file_open(&fin, OPEN_READ));
|
||||
g_assert_null(fin.f_file);
|
||||
g_assert_null(fin.f_data.f_file);
|
||||
}
|
||||
|
||||
static void test_versioning_old()
|
||||
|
@ -172,7 +172,7 @@ static void test_versioning_new()
|
|||
static void test_cache()
|
||||
{
|
||||
gchar *basepath, *filepath, *writepath;
|
||||
struct cache_file file, copy;
|
||||
struct file file, copy;
|
||||
|
||||
cache_file_init(&file, "dir", "file.txt");
|
||||
cache_file_init(©, "dir", "copy.txt");
|
||||
|
@ -181,9 +181,9 @@ static void test_cache()
|
|||
filepath = g_strjoin("/", basepath, "dir", "file.txt", NULL);
|
||||
writepath = g_strjoin("/", basepath, "dir", ".file.txt.tmp", NULL);
|
||||
|
||||
g_assert_null(file.cf_file);
|
||||
g_assert_cmpstr(file.cf_name, ==, "file.txt");
|
||||
g_assert_cmpstr(file.cf_subdir, ==, "dir");
|
||||
g_assert_null(file.f_cache.cf_file);
|
||||
g_assert_cmpstr(file.f_cache.cf_name, ==, "file.txt");
|
||||
g_assert_cmpstr(file.f_cache.cf_subdir, ==, "dir");
|
||||
|
||||
g_assert_cmpstr_free(cache_file_path(&file), ==, filepath);
|
||||
g_assert_cmpstr_free(cache_file_write_path(&file), ==, writepath);
|
||||
|
@ -192,13 +192,13 @@ static void test_cache()
|
|||
g_assert_false(cache_file_exists(&file));
|
||||
g_assert_false(cache_file_open(&file, OPEN_READ));
|
||||
g_assert_true(cache_file_open(&file, OPEN_WRITE));
|
||||
g_assert_nonnull(file.cf_file);
|
||||
g_assert_nonnull(file.f_cache.cf_file);
|
||||
g_assert_false(cache_file_open(&file, OPEN_WRITE));
|
||||
|
||||
g_assert_false(cache_file_exists(&file));
|
||||
g_assert_cmpuint(cache_file_write(&file, "abcde", 5), ==, 5);
|
||||
cache_file_close(&file);
|
||||
g_assert_null(file.cf_file);
|
||||
g_assert_null(file.f_cache.cf_file);
|
||||
g_assert_true(cache_file_exists(&file));
|
||||
|
||||
/* Test importing a file into the cache. */
|
||||
|
|
|
@ -329,7 +329,7 @@ static void test_save_load()
|
|||
struct playlist q = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test 2", 0, NULL);
|
||||
struct playlist r = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, &test_ops);
|
||||
struct playlist s = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test 2", 0, NULL);
|
||||
struct data_file f = DATA_FILE_INIT("test.playlist", 0);
|
||||
struct file f = DATA_FILE_INIT("test.playlist", 0);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 13; i++) {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
static void test_settings()
|
||||
{
|
||||
struct data_file f = DATA_FILE_INIT("settings", 0);
|
||||
struct file f = DATA_FILE_INIT("settings", 0);
|
||||
|
||||
settings_set(NULL, 0);
|
||||
g_assert_cmpuint(settings_get(NULL), ==, 0);
|
||||
|
|
|
@ -46,7 +46,7 @@ static void test_album()
|
|||
struct album *album;
|
||||
struct artist *koji;
|
||||
struct genre *genre;
|
||||
struct data_file f;
|
||||
struct file f;
|
||||
|
||||
idle_init(IDLE_SYNC);
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ static void test_artist()
|
|||
const struct db_ops *artist_ops = test_artist_ops();
|
||||
struct artist *artist;
|
||||
unsigned int i;
|
||||
struct data_file f;
|
||||
struct file f;
|
||||
|
||||
artist = ARTIST(artist_ops->dbe_alloc("Koji Kondo", 0));
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ static void test_genre()
|
|||
const struct db_ops *genre_ops = test_genre_ops();
|
||||
struct genre *genre;
|
||||
unsigned int i;
|
||||
struct data_file f;
|
||||
struct file f;
|
||||
|
||||
genre = GENRE(genre_ops->dbe_alloc("Video Game Music", 0));
|
||||
test_verify_vg(genre);
|
||||
|
|
|
@ -22,7 +22,7 @@ static void test_library()
|
|||
{
|
||||
const struct db_ops *library_ops = test_library_ops();
|
||||
struct library *link, *zelda, *library;
|
||||
struct data_file f;
|
||||
struct file f;
|
||||
|
||||
link = LIBRARY(library_ops->dbe_alloc("/home/Link/Music", 0));
|
||||
zelda = LIBRARY(library_ops->dbe_alloc("/home/Zelda/Music", 0));
|
||||
|
|
|
@ -83,7 +83,7 @@ static void test_track()
|
|||
time_t rawtime = time(NULL);
|
||||
struct tm *now = localtime(&rawtime);
|
||||
struct track *track;
|
||||
struct data_file f;
|
||||
struct file f;
|
||||
gchar *date;
|
||||
|
||||
data_file_init(&f, "track_tag", 1);
|
||||
|
|
Loading…
Reference in New Issue