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:
parent
f24da08d85
commit
dbd27d1297
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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); }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue