core/file: Move versioning info into the main file structure

I'll eventually want to support text and binary files in both locations,
so cache files might need access to this too.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2018-02-20 10:35:34 -05:00
parent 8f13765b08
commit 0aaafcb5f7
4 changed files with 23 additions and 32 deletions

View File

@ -13,12 +13,16 @@
#define REPORT_ERRNO(fname) REPORT_ERROR(fname, strerror(errno))
static void __file_init_common(struct file *file, const gchar *subdir,
const gchar *name, const gchar *(*user_dir)(void))
const gchar *name, unsigned int min,
const gchar *(*user_dir)(void))
{
file->f_file = NULL;
file->f_name = name;
file->f_subdir = subdir;
file->f_mode = CLOSED;
file->f_version = OCARINA_MINOR_VERSION;
file->f_prev = 0;
file->f_min = min;
file->f_user_dir = user_dir;
}
@ -65,16 +69,12 @@ static bool __file_can_write(struct file *data)
void file_init_data(struct file *file, const gchar *subdir,
const gchar *name, unsigned int min)
{
__file_init_common(file, subdir, name, g_get_user_data_dir);
file->f_data.f_version = OCARINA_MINOR_VERSION;
file->f_data.f_prev = 0;
file->f_data.f_min = min;
__file_init_common(file, subdir, name, min, g_get_user_data_dir);
}
void file_init_cache(struct file *file, const gchar *subdir, const gchar *name)
{
__file_init_common(file, subdir, name, g_get_user_cache_dir);
__file_init_common(file, subdir, name, 0, g_get_user_cache_dir);
}
gchar *file_path(struct file *file)
@ -102,10 +102,9 @@ gchar *file_write_path(struct file *file)
const unsigned int data_file_version(struct file *data)
{
struct data_file *file = &data->f_data;
if (data->f_file && (data->f_mode == OPEN_READ))
return file->f_prev;
return file->f_version;
return data->f_prev;
return data->f_version;
}
bool file_exists(struct file *file)
@ -118,7 +117,6 @@ bool file_exists(struct file *file)
static bool __file_open_read(struct file *data)
{
struct data_file *file = &data->f_data;
if (!file_exists(data))
return false;
@ -127,14 +125,14 @@ static bool __file_open_read(struct file *data)
return false;
data->f_mode = OPEN_READ;
if (data_file_readf(data, "%u\n", &file->f_prev) != 1)
if (data_file_readf(data, "%u\n", &data->f_prev) != 1)
return false;
if (file->f_prev < file->f_min) {
if (data->f_prev < data->f_min) {
REPORT_ERROR(data->f_name, "File too old to be upgraded.");
file_close(data);
exit(1);
}
if (file->f_prev > file->f_version) {
if (data->f_prev > data->f_version) {
REPORT_ERROR(data->f_name, "File too new to be opened.");
file_close(data);
exit(1);
@ -144,7 +142,6 @@ static bool __file_open_read(struct file *data)
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(data))
@ -155,7 +152,7 @@ static bool __file_open_write(struct file *data)
return false;
data->f_mode = OPEN_WRITE;
return data_file_writef(data, "%d\n", file->f_version) > 0;
return data_file_writef(data, "%d\n", data->f_version) > 0;
}
bool data_file_open(struct file *data, enum open_mode mode)

View File

@ -35,20 +35,16 @@ enum open_mode {
OPEN_WRITE, /* File is open for writing text. */
};
struct data_file {
unsigned int f_version; /* The file's current data version. */
unsigned int f_prev; /* The file's on-disk data version. */
unsigned int f_min; /* The file's minimum data version. */
};
struct file {
FILE *f_file; /* The file's IO stream. */
const gchar *f_name; /* The file's basename. */
const gchar *f_subdir; /* The file's subdirectory. */
enum open_mode f_mode; /* The file's current open mode. */
unsigned int f_version; /* The file's current data version. */
unsigned int f_prev; /* The file's on-disk data version. */
unsigned int f_min; /* The file's minimum data version. */
struct data_file f_data;
const gchar *(*f_user_dir)(void); /* The file's user directory. */
};
@ -58,12 +54,10 @@ struct file {
.f_name = fname, \
.f_subdir = fdir, \
.f_mode = CLOSED, \
.f_version = OCARINA_MINOR_VERSION, \
.f_prev = 0, \
.f_min = min, \
.f_user_dir = g_get_user_data_dir, \
.f_data = { \
.f_version = OCARINA_MINOR_VERSION, \
.f_prev = 0, \
.f_min = min, \
} \
}
/* Initialize a file object. */

View File

@ -104,7 +104,7 @@ 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_data.f_version, ==, OCARINA_MINOR_VERSION);
g_assert_cmpuint(db.db_file.f_version, ==, OCARINA_MINOR_VERSION);
g_assert_cmpstr(db.db_file.f_name, ==, "init.db");
db_deinit(&db);

View File

@ -98,7 +98,7 @@ static void test_io()
char *res = NULL;
unsigned int i;
fout.f_data.f_version = 1;
fout.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");
@ -136,8 +136,8 @@ static void __test_versioning_subprocess(unsigned int out, unsigned int in)
struct file fout = FILE_INIT_DATA("", "file.txt", out);
struct file fin = FILE_INIT_DATA("", "file.txt", in);
fout.f_data.f_version = out;
fin.f_data.f_version = in;
fout.f_version = out;
fin.f_version = in;
g_assert_true(data_file_open(&fout, OPEN_WRITE));
data_file_writef(&fout, "abcdefghijklmnopqrstuvwxyz");