core/file: Use a C-style file stream for reading from files

I also introduced a file_readf() function to make it easier to read a
formatted string from the file.

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2015-10-08 11:16:38 -04:00
parent f24da08d85
commit dbd27d1297
14 changed files with 101 additions and 66 deletions

View File

@ -82,7 +82,7 @@ void audio :: init()
file_init(&f_cur_track, "cur_track", 0);
if (file_exists(&f_cur_track)) {
file_open(&f_cur_track, OPEN_READ);
f_cur_track >> id;
file_readf(&f_cur_track, "%u", &id);
file_close(&f_cur_track);
audio :: load_track(tags :: get_track(id));
}

View File

@ -73,12 +73,12 @@ static void upgrade_v0()
unsigned int num, field;
Queue *library = library :: get_queue();
deck_file >> random >> num;
file_readf(&deck_file, "%d %u", &random, &num);
if (random)
library->set_flag(Q_RANDOM);
for (unsigned int i = 0; i < num; i++) {
deck_file >> field >> ascending;
file_readf(&deck_file, "%u %d", &field, &ascending);
library->sort((sort_t)field, (i == 0) ? true : false);
if (!ascending)
library->sort((sort_t)field, false);
@ -100,7 +100,7 @@ void deck :: init()
upgraded = true;
}
deck_file >> num;
file_readf(&deck_file, "%u", &num);
queue_deck.resize(num);
for (it = queue_deck.begin(); it != queue_deck.end(); it++)

View File

@ -64,16 +64,10 @@ bool file_exists(struct file *file)
static bool __file_open_common(struct file *file, OpenMode mode)
{
if (mode == OPEN_READ) {
((std::fstream *)file)->open(file_path(file).c_str(), std::fstream::in);
if (file->fail())
return false;
} else {
file->f_file = g_fopen(file_path(file).c_str(), "w");
if (!file->f_file) {
REPORT_ERROR();
return false;
}
file->f_file = g_fopen(file_path(file).c_str(), (mode == OPEN_READ) ? "r" : "w");
if (!file->f_file) {
REPORT_ERROR();
return false;
}
file->f_mode = mode;
@ -86,10 +80,7 @@ static bool __file_open_read(struct file *file)
return false;
if (!__file_open_common(file, OPEN_READ))
return false;
*file >> file->f_prev;
file_readl(file);
return true;
return file_readf(file, "%u\n", &file->f_prev) == 1;
}
static bool __file_open_write(struct file *file)
@ -115,7 +106,6 @@ bool file_open(struct file *file, OpenMode mode)
void file_close(struct file *file)
{
if (file->f_mode != NOT_OPEN) {
file->close();
if (file->f_file)
fclose(file->f_file);
file->f_file = NULL;
@ -123,16 +113,29 @@ void file_close(struct file *file)
file->f_mode = NOT_OPEN;
}
int file_readf(struct file *file, const char *fmt, ...)
{
va_list argp;
int ret;
va_start(argp, fmt);
ret = vfscanf(file->f_file, fmt, argp);
va_end(argp);
return ret;
}
std::string file_readl(struct file *file)
{
char c;
std::string res;
gchar *g_res;
/* Ignore leading whitespace */
while (file->peek() == ' ')
file->read(&c, 1);
if (file_readf(file, "%m[^\n]\n", &g_res) == 0)
g_res = g_strdup("");
std::getline(*static_cast<std::fstream *>(file), res);
g_strstrip(g_res);
res = g_res;
g_free(g_res);
return res;
}

View File

@ -56,9 +56,11 @@ void IndexEntry :: read(file &file)
{
unsigned int num, val;
file >> _key >> num;
_key = file_readl(&file);
file_readf(&file, "%u", &num);
for (unsigned int i = 0; i < num; i++) {
file >> val;
file_readf(&file, "%u", &val);
insert(val);
}
}

View File

@ -39,15 +39,15 @@ public:
void load()
{
unsigned int field;
bool ascending;
int ascending;
unsigned int n;
if (!file_open(&f, OPEN_READ))
return;
f >> _flags >> n;
file_readf(&f, "%u %u", &_flags, &n);
for (unsigned int i = 0; i < n; i++) {
f >> field >> ascending;
file_readf(&f, "%u %d", &field, &ascending);
Queue :: sort((sort_t)field, (i == 0) ? true : false);
if (ascending == false)
Queue :: sort((sort_t)field, false);

View File

@ -41,10 +41,10 @@ void Queue :: write(file &file)
void Queue :: read(file &file)
{
unsigned int n, id;
file >> _flags >> n;
file_readf(&file, "%u %u", &_flags, &n);
_tracks.resize(n);
for (unsigned int i = 0; i < n; i++) {
file >> id;
file_readf(&file, "%u", &id);
_tracks[i] = tags :: get_track(id);
_length += _tracks[i]->length();
}

View File

@ -32,7 +32,7 @@ const std::string Album :: primary_key() const
void Album :: read(file &file)
{
file >> _year;
file_readf(&file, "%u", &_year);
GenericTag :: read(file);
}

View File

@ -24,7 +24,10 @@ const std::string Library :: primary_key() const
void Library :: read(file &file)
{
file >> _enabled;
int enabled;
file_readf(&file, "%d\n", &enabled);
_enabled = enabled;
_path = file_readl(&file);
}

View File

@ -120,9 +120,9 @@ void Track :: read(file &file)
{
unsigned int library_id, artist_id, album_id, genre_id;
file >> library_id >> artist_id >> album_id >> genre_id;
file >> _track >> _date.year >> _date.month >> _date.day;
file >> _count >> _length;
file_readf(&file, "%u %u %u %u %u %u %u %u %u %u", &library_id,
&artist_id, &album_id, &genre_id, &_track, &_date.year,
&_date.month, &_date.day, &_count, &_length);
GenericTag :: read(file);
_path = file_readl(&file);

View File

@ -53,20 +53,20 @@ template <class T>
void Database<T> :: load()
{
unsigned int db_size;
bool valid;
int valid;
if (file_exists(&_file) == false)
return;
else if (file_open(&_file, OPEN_READ) == false)
return;
_file >> db_size;
file_readf(&_file, "%u", &db_size);
_db.resize(db_size);
for (unsigned int i = 0; i < db_size; i++) {
_file >> valid;
if (valid == false)
file_readf(&_file, "%d", &valid);
if (valid == false) {
_db[i] = NULL;
else {
} else {
_db[i] = new T;
_db[i]->_index = i;
_db[i]->read(_file);

View File

@ -7,7 +7,6 @@
#include <glib.h>
#include <glib/gstdio.h>
#include <fstream>
#include <string>
@ -45,7 +44,7 @@ enum OpenMode {
* Data should be written to files using either a space or newline as
* a delimiter.
*/
struct file : public std::fstream {
struct file {
OpenMode 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. */
@ -88,6 +87,12 @@ void file_close(struct file *);
/* Read an entire line from the file and return it to the caller. */
std::string file_readl(struct file *);
/*
* Read from a file with an fscanf(3) style format string.
* Returns the number of items matched.
*/
int file_readf(struct file *, const char *, ...);
/*
* Write to a file with an fprintf(3) style format string.
* Returns the number of bytes successfully written.

View File

@ -27,8 +27,8 @@ public:
return res;
}
void write(file &f) { file_writef(&f, "%d", val); }
void read(file &f) { f >> val; }
void write(file &f) { file_writef(&f, "%u", val); }
void read(file &f) { file_readf(&f, "%u", &val); }
};

View File

@ -41,18 +41,18 @@ static void test_init()
file_init(&f, "deck", 0);
file_open(&f, OPEN_READ);
test_equal(file_version(&f), (unsigned)1);
f >> val; /* number of queues */
file_readf(&f, "%u", &val);
test_equal(val, (unsigned)2);
for (unsigned int i = 0; i < 2; i++) {
f >> val; /* queues[i].flags */
file_readf(&f, "%u", &val); /* queues[i].flags */
test_equal(val, (unsigned)1);
f >> val; /* queues[i].size */
file_readf(&f, "%u", &val); /* queues[i].size */
test_equal(val, 4 + i);
for (unsigned int j = 0; j < 4 + i; j++) {
f >> val;
file_readf(&f, "%u", &val);
test_equal(val, (4 * i) + j);
}
}

View File

@ -2,6 +2,7 @@
* Copyright 2014 (c) Anna Schumaker.
*/
#include <core/file.h>
#include <stdlib.h>
#include "test.h"
@ -63,6 +64,7 @@ static void test_file()
g_chmod(file_path(&file).c_str(), 0644);
test_equal(file_open(&file, OPEN_READ), (bool)true);
test_not_equal((void *)file.f_file, NULL);
test_equal(file.f_mode, OPEN_READ);
test_equal(file_open(&file, OPEN_READ), (bool)false);
file_close(&file);
@ -72,25 +74,45 @@ static void test_file()
static void test_io()
{
struct file a, b;
std::string res;
struct file fout, fin;
char *res = NULL;
unsigned int i;
file_init(&a, "file.txt", 1);
test_equal(file_open(&a, OPEN_WRITE), (bool)true);
file_writef(&a, "ABCDE FGHIJ KLMNO PQRST UVWXYZ\n");
file_close(&a);
test_equal(file_exists(&a), (bool)true);
file_init(&fout, "file.txt", 1);
file_init(&fin, "file.txt", 0);
file_init(&b, "file.txt", 0);
test_equal(file_open(&b, OPEN_READ), (bool)true);
test_equal(file_version(&b), (unsigned)1);
b >> res;
test_equal(res, (std::string)"ABCDE");
b >> res;
test_equal(res, (std::string)"FGHIJ");
res = file_readl(&b);
test_equal(res, (std::string)"KLMNO PQRST UVWXYZ");
file_close(&b);
test_equal(file_open(&fout, OPEN_WRITE), (bool)true);
file_writef(&fout, "1 ABCDE\n");
file_writef(&fout, "2 FGHIJ KLMNO\n");
file_writef(&fout, "3 \n");
file_writef(&fout, "4 5 PQRST\n");
file_close(&fout);
test_equal(file_exists(&fout), (bool)true);
test_equal(file_open(&fin, OPEN_READ), (bool)true);
test_equal(file_version(&fin), 1);
test_equal(file_readf(&fin, "%u %ms\n", &i, &res), 2);
test_equal(i, 1);
test_equal(res, "ABCDE");
free(res);
test_equal(file_readf(&fin, "%u %m[^\n]\n", &i, &res), 2);
test_equal(i, 2);
test_equal(res, "FGHIJ KLMNO");
free(res);
test_equal(file_readf(&fin, "%u", &i), 1);
test_equal(i, 3);
test_equal(file_readl(&fin), "");
test_equal(file_readf(&fin, "%u %m[^\n]", &i, &res), 2);
test_equal(i, 4);
test_equal(res, "5 PQRST");
free(res);
file_close(&fin);
test_equal(file_version(&fin), 0);
}
DECLARE_UNIT_TESTS(