core/file: Move f_mode out of data files

This might also be useful for cache files to track their current state.
To help with accurate tracking, I take this opportunity to add a CLOSED
state that files default to.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2018-02-20 09:31:40 -05:00
parent 3736b6cf3b
commit 659aaff6a1
3 changed files with 33 additions and 19 deletions

View File

@ -18,6 +18,7 @@ static void __file_init_common(struct file *file, const gchar *subdir,
file->f_file = NULL;
file->f_name = name;
file->f_subdir = subdir;
file->f_mode = CLOSED;
file->f_user_dir = user_dir;
}
@ -78,7 +79,6 @@ void file_init_data(struct file *file, const gchar *subdir,
{
__file_init_common(file, subdir, name, g_get_user_data_dir);
file->f_data.f_mode = OPEN_READ;
file->f_data.f_version = OCARINA_MINOR_VERSION;
file->f_data.f_prev = 0;
file->f_data.f_min = min;
@ -115,7 +115,7 @@ 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 && (file->f_mode == OPEN_READ))
if (data->f_file && (data->f_mode == OPEN_READ))
return file->f_prev;
return file->f_version;
}
@ -138,7 +138,7 @@ static bool __file_open_read(struct file *data)
if (!data->f_file)
return false;
file->f_mode = OPEN_READ;
data->f_mode = OPEN_READ;
if (data_file_readf(data, "%u\n", &file->f_prev) != 1)
return false;
if (file->f_prev < file->f_min) {
@ -166,7 +166,7 @@ static bool __file_open_write(struct file *data)
if (!data->f_file)
return false;
file->f_mode = OPEN_WRITE;
data->f_mode = OPEN_WRITE;
return data_file_writef(data, "%d\n", file->f_version) > 0;
}
@ -175,31 +175,34 @@ 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 == OPEN_READ)
if (mode == CLOSED)
return false;
else if (mode == OPEN_READ)
return __file_open_read(data);
return __file_open_write(data);
}
bool cache_file_open(struct file *cache, enum open_mode mode)
{
if (mode == OPEN_READ)
return false;
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;
cache->f_file = __file_open(file_write_path(cache), "wb");
cache->f_mode = mode;
return cache->f_file != NULL;
}
void data_file_close(struct file *data)
{
struct data_file *file = &data->f_data;
__file_close(data->f_file,
file->f_mode == OPEN_WRITE ? file_path(data) : NULL,
file->f_mode == OPEN_WRITE ? file_write_path(data) : NULL);
data->f_mode == OPEN_WRITE ? file_path(data) : NULL,
data->f_mode == OPEN_WRITE ? file_write_path(data) : NULL);
data->f_file = NULL;
data->f_mode = CLOSED;
}
void cache_file_close(struct file *cache)
@ -208,6 +211,7 @@ void cache_file_close(struct file *cache)
file_path(cache),
file_write_path(cache));
cache->f_file = NULL;
cache->f_mode = CLOSED;
}
int data_file_readf(struct file *data, const char *fmt, ...)

View File

@ -30,12 +30,12 @@
enum open_mode {
OPEN_READ,
OPEN_WRITE,
CLOSED, /* File is not open. */
OPEN_READ, /* File is open for reading text. */
OPEN_WRITE, /* File is open for writing text. */
};
struct data_file {
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. */
@ -46,6 +46,8 @@ struct file {
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. */
struct data_file f_data;
const gchar *(*f_user_dir)(void); /* The file's user directory. */
};
@ -55,9 +57,9 @@ struct file {
.f_file = NULL, \
.f_name = fname, \
.f_subdir = fdir, \
.f_mode = CLOSED, \
.f_user_dir = g_get_user_data_dir, \
.f_data = { \
.f_mode = OPEN_READ, \
.f_version = OCARINA_MINOR_VERSION, \
.f_prev = 0, \
.f_min = min, \

View File

@ -11,7 +11,7 @@ static void test_verify_constructor(struct file *file, gchar *fpath, gchar *ftmp
{
g_assert_null(file->f_file);
g_assert_cmpuint(data_file_version(file), ==, OCARINA_MINOR_VERSION);
g_assert_cmpuint(file->f_data.f_mode, ==, OPEN_READ);
g_assert_cmpuint(file->f_mode, ==, CLOSED);
g_assert_cmpstr_free(file_path(file), ==, fpath);
g_assert_cmpstr_free(file_write_path(file), ==, ftmp);
}
@ -27,7 +27,7 @@ static void test_invalid_file(gconstpointer path)
g_assert_null(file.f_file);
g_assert_false(data_file_open(&file, OPEN_WRITE));
g_assert_null(file.f_file);
g_assert_cmpuint(file.f_data.f_mode, ==, OPEN_READ);
g_assert_cmpuint(file.f_mode, ==, CLOSED);
g_assert_false(file_exists(&file));
}
@ -45,15 +45,16 @@ static void __test_file_subprocess()
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_true(data_file_open(&file, OPEN_WRITE));
g_assert_nonnull(file.f_file);
g_assert_cmpuint(file.f_data.f_mode, ==, OPEN_WRITE);
g_assert_cmpuint(file.f_mode, ==, OPEN_WRITE);
g_assert_false(data_file_open(&file, OPEN_WRITE));
g_assert_false(file_exists(&file));
data_file_close(&file);
g_assert_null(file.f_file);
g_assert_cmpuint(file.f_data.f_mode, ==, OPEN_WRITE);
g_assert_cmpuint(file.f_mode, ==, CLOSED);
g_assert_true(file_exists(&file));
g_chmod(filepath, 0444);
@ -61,15 +62,17 @@ static void __test_file_subprocess()
g_chmod(filepath, 0200);
g_assert_false(data_file_open(&file, OPEN_READ));
g_chmod(filepath, 0644);
g_assert_false(data_file_open(&file, CLOSED));
g_assert_true(data_file_open(&file, OPEN_READ));
g_assert_nonnull(file.f_file);
g_assert_cmpuint(file.f_data.f_mode, ==, OPEN_READ);
g_assert_cmpuint(file.f_mode, ==, OPEN_READ);
g_assert_false(data_file_open(&file, OPEN_READ));
g_assert_false(data_file_remove(&file));
g_assert_true(file_exists(&file));
data_file_close(&file);
g_assert_cmpuint(file.f_mode, ==, CLOSED);
g_assert_true(data_file_remove(&file));
g_assert_false(file_exists(&file));
@ -184,6 +187,7 @@ static void test_cache()
g_assert_null(file.f_file);
g_assert_cmpstr(file.f_name, ==, "file.txt");
g_assert_cmpstr(file.f_subdir, ==, "dir");
g_assert_cmpuint(file.f_mode, ==, CLOSED);
g_assert_cmpstr_free(file_path(&file), ==, filepath);
g_assert_cmpstr_free(file_write_path(&file), ==, writepath);
@ -191,15 +195,19 @@ static void test_cache()
/* Test writing data to a cache file. */
g_assert_false(file_exists(&file));
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_nonnull(file.f_file);
g_assert_cmpuint(file.f_mode, ==, OPEN_WRITE);
g_assert_false(cache_file_open(&file, OPEN_WRITE));
g_assert_false(file_exists(&file));
g_assert_cmpuint(cache_file_write(&file, "abcde", 5), ==, 5);
cache_file_close(&file);
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));
/* Test importing a file into the cache. */
g_assert_false(file_exists(&copy));