ocarina/core/tags/library.c
Anna Schumaker e1f13a7ef4 core/file: Create new functions for reading data from files
The readd(), readu(), and readhu() functions are all used to read
various forms of integers.  The readl() and readw() are for reading
either lines or individual whitespace-delimited words

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2018-02-21 16:01:15 -05:00

123 lines
2.4 KiB
C

/*
* Copyright 2014 (c) Anna Schumaker.
*/
#include <core/string.h>
#include <core/tags/library.h>
#define LIBRARY_DB_MIN 0 /* Ocarina 6.0 */
static struct database library_db;
static struct library *__library_alloc(gchar *path)
{
struct library *library = g_malloc(sizeof(struct library));
dbe_init(&library->li_dbe, library);
library->li_path = path;
library->li_playlist = NULL;
return library;
}
static struct db_entry *library_alloc(const gchar *path, unsigned int index)
{
return &__library_alloc(g_strdup(path))->li_dbe;
}
static void library_free(struct db_entry *dbe)
{
g_free(LIBRARY(dbe));
}
static gchar *library_key(struct db_entry *dbe)
{
return LIBRARY(dbe)->li_path;
}
static struct db_entry *library_read(struct file *file, unsigned int index)
{
gchar *path;
/* Old "enabled" flag */
if (file_version(file) == 0)
file_readd(file);
path = file_readl(file);
return &__library_alloc(path)->li_dbe;
}
static void library_write(struct file *file, struct db_entry *dbe)
{
file_writef(file, "%s", LIBRARY(dbe)->li_path);
}
static const struct db_ops library_ops = {
.dbe_alloc = library_alloc,
.dbe_free = library_free,
.dbe_key = library_key,
.dbe_read = library_read,
.dbe_write = library_write,
};
void library_db_init()
{
db_init(&library_db, "library.db", true, &library_ops, LIBRARY_DB_MIN);
db_load(&library_db);
}
void library_db_deinit()
{
db_deinit(&library_db);
}
bool library_db_defrag()
{
return db_defrag(&library_db);
}
const struct database *library_db_get()
{
return &library_db;
}
struct library *library_find(const gchar *path)
{
struct library *library = library_lookup(path);
if (library)
return library;
return LIBRARY(db_insert(&library_db, path));
}
struct library *library_lookup(const gchar *path)
{
struct db_entry *dbe, *next;
db_for_each(dbe, next, &library_db) {
if (string_is_subdir(path, LIBRARY(dbe)->li_path))
return LIBRARY(dbe);
}
return NULL;
}
struct library *library_get(const unsigned int index)
{
return LIBRARY(db_at(&library_db, index));
}
void library_remove(struct library *library)
{
if (library)
db_remove(&library_db, &library->li_dbe);
}
gchar *library_file(struct library *library, const gchar *path)
{
return g_strdup_printf("%s/%s", library->li_path, path);
}
#ifdef CONFIG_TESTING
const struct db_ops *test_library_ops() { return &library_ops; }
#endif /* CONFIG_TESTING */