From 877d9ac1d7b481ff7782671f04decf5e530d58b8 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Thu, 5 Nov 2015 15:56:24 -0500 Subject: [PATCH] core/database: Convert file to C Signed-off-by: Anna Schumaker --- core/{database.cpp => database.c} | 2 +- include/core/database.h | 47 ++++++++-------- include/core/index.h | 2 +- include/core/tags/album.h | 2 + include/core/tags/artist.h | 2 + include/core/tags/genre.h | 2 + include/core/tags/library.h | 2 + include/core/tags/track.h | 2 +- tests/core/Sconscript | 2 +- tests/core/{database.cpp => database.c} | 71 +++++++++++++------------ 10 files changed, 70 insertions(+), 64 deletions(-) rename core/{database.cpp => database.c} (99%) rename tests/core/{database.cpp => database.c} (81%) diff --git a/core/database.cpp b/core/database.c similarity index 99% rename from core/database.cpp rename to core/database.c index 0007ba2e..5e331b2b 100644 --- a/core/database.cpp +++ b/core/database.c @@ -1,4 +1,4 @@ -/** +/* * Copyright 2013 (c) Anna Schumaker. */ #include diff --git a/include/core/database.h b/include/core/database.h index 577bc252..63c84916 100644 --- a/include/core/database.h +++ b/include/core/database.h @@ -1,23 +1,36 @@ -/** +/* * Copyright 2013 (c) Anna Schumaker. + * + * Databases are a generic store for information used by Ocarina. Users must + * provide a struct db_ops when initializing a database. + * + * When writing a database to disk, databases will store their size in additon + * to valid bits and values at each index. For example, let's say we have a + * database with the following values: { 1, 2, NULL, 4 }. The resulting file + * would look like: + * + * 4 + * 1 1 + * 1 2 + * 0 + * 1 4 + * + * + * The database class will add a newline after each struct db_entry. */ #ifndef OCARINA_CORE_DATABASE_H #define OCARINA_CORE_DATABASE_H -extern "C" { #include -} -/** - * The DatabaseEntry class is the base class for storing - * generic data inside a Database. - */ + struct db_entry { unsigned int dbe_index; /* The db_entry's position in the database. */ gchar *dbe_key; /* The db_entry's hash key. */ void *dbe_data; /* The db_entry's private data. */ }; + static inline void dbe_init(struct db_entry *dbe, void *data) { dbe->dbe_index = 0; @@ -54,27 +67,9 @@ struct db_ops { }; -/** - * Databases are a generic store for information used by Ocarina. Users - * need to inherit from a DatabaseEntry class to properly use a Database. - * - * When writing a Database to disk, Databases need to store their size in - * addition to values and valid bits at each index. For example, let's say - * we have a Database with the following values: { 1, 2, NULL, 4 }. On - * disk this would look like: - * - * 4 - * 0 true 1 - * 1 true 2 - * 2 false - * 3 true 4 - * - * - * The Database class will add a newline after each DatabaseEntry. - */ struct database { unsigned int db_size; /* The database's count of valid entries. */ - bool db_autosave; /* True if the database saves when changed. */ + bool db_autosave; /* The database's automatic save setting. */ struct file db_file; /* The database's associated file object. */ GPtrArray *db_entries; /* The database's backing array. */ GHashTable *db_keys; /* The database's mapping of key -> value. */ diff --git a/include/core/index.h b/include/core/index.h index caff760f..5d1a697b 100644 --- a/include/core/index.h +++ b/include/core/index.h @@ -4,8 +4,8 @@ #ifndef OCARINA_CORE_INDEX_H #define OCARINA_CORE_INDEX_H -#include extern "C" { +#include #include } diff --git a/include/core/tags/album.h b/include/core/tags/album.h index d350a024..7c14ec72 100644 --- a/include/core/tags/album.h +++ b/include/core/tags/album.h @@ -4,7 +4,9 @@ #ifndef OCARINA_CORE_TAGS_ALBUM_H #define OCARINA_CORE_TAGS_ALBUM_H +extern "C" { #include +} #include /** diff --git a/include/core/tags/artist.h b/include/core/tags/artist.h index 793455a1..8053e9f8 100644 --- a/include/core/tags/artist.h +++ b/include/core/tags/artist.h @@ -4,7 +4,9 @@ #ifndef OCARINA_CORE_TAGS_ARTIST_H #define OCARINA_CORE_TAGS_ARTIST_H +extern "C" { #include +} #include /** diff --git a/include/core/tags/genre.h b/include/core/tags/genre.h index 582cce34..73390171 100644 --- a/include/core/tags/genre.h +++ b/include/core/tags/genre.h @@ -4,7 +4,9 @@ #ifndef OCARINA_CORE_TAGS_GENRE_H #define OCARINA_CORE_TAGS_GENRE_H +extern "C" { #include +} #include /** diff --git a/include/core/tags/library.h b/include/core/tags/library.h index 7a37802b..53c91c26 100644 --- a/include/core/tags/library.h +++ b/include/core/tags/library.h @@ -4,7 +4,9 @@ #ifndef OCARINA_CORE_TAGS_LIBRARY_H #define OCARINA_CORE_TAGS_LIBRARY_H +extern "C" { #include +} #include /** diff --git a/include/core/tags/track.h b/include/core/tags/track.h index 6dd51d9a..9621c0c7 100644 --- a/include/core/tags/track.h +++ b/include/core/tags/track.h @@ -5,9 +5,9 @@ #define OCARINA_CORE_TAGS_TRACK_H extern "C" { +#include #include } -#include #include #include #include diff --git a/tests/core/Sconscript b/tests/core/Sconscript index 30b51202..46b70ada 100644 --- a/tests/core/Sconscript +++ b/tests/core/Sconscript @@ -19,7 +19,7 @@ res += [ CoreTest("random", "random.c") ] res += [ CoreTest("file", "file.c") ] res += [ CoreTest("date", "date.c") ] res += [ CoreTest("set", "set.c") ] -res += [ CoreTest("database", "database.cpp") ] +res += [ CoreTest("database", "database.c") ] res += [ CoreTest("index", "index.cpp") ] res += [ CoreTest("filter", "filter.cpp") ] res += [ CoreTest("idle", "idle.cpp") ] diff --git a/tests/core/database.cpp b/tests/core/database.c similarity index 81% rename from tests/core/database.cpp rename to tests/core/database.c index 87c0da67..2edc748b 100644 --- a/tests/core/database.cpp +++ b/tests/core/database.c @@ -4,9 +4,7 @@ */ #include #include -#include "test.h" - -#include +#include /* * Derive a db_entry for storing integerss @@ -22,7 +20,7 @@ static unsigned int test_setup_count = 0; static struct int_entry *__int_alloc(unsigned int val) { - struct int_entry *ent = new int_entry; + struct int_entry *ent = g_malloc(sizeof(struct int_entry)); ent->ie_val = val; dbe_init(&ent->ie_dbe, ent); return ent; @@ -38,7 +36,7 @@ static struct db_entry *int_alloc(const gchar *key) static void int_free(struct db_entry *dbe) { test_free_count++; - delete INT_ENTRY(dbe); + g_free(INT_ENTRY(dbe)); } static gchar *int_key(struct db_entry *dbe) @@ -64,12 +62,12 @@ static void int_write(struct file *file, struct db_entry *dbe) } static const struct db_ops int_ops = { - int_alloc, - int_free, - int_key, - int_read, - int_setup, - int_write, + .dbe_alloc = int_alloc, + .dbe_free = int_free, + .dbe_key = int_key, + .dbe_read = int_read, + .dbe_setup = int_setup, + .dbe_write = int_write, }; @@ -80,7 +78,7 @@ static void test_db_entry() ent = INT_ENTRY(int_ops.dbe_alloc("1")); test_equal(ent->ie_dbe.dbe_index, 0); - test_equal(ent->ie_dbe.dbe_data, ent); + test_equal((void *)ent->ie_dbe.dbe_data, (void *)ent); test_equal(ent->ie_val, 1); test_str_equal(int_ops.dbe_key(&ent->ie_dbe), "1"); @@ -97,7 +95,7 @@ static void test_db_entry() file_close(&f); int_ops.dbe_setup(&ent->ie_dbe); - test_equal(ent->ie_dbe.dbe_data, ent); + test_equal((void *)ent->ie_dbe.dbe_data, (void *)ent); test_equal(ent->ie_val, 1); test_str_equal(int_ops.dbe_key(&ent->ie_dbe), "1"); test_equal(test_setup_count, 1); @@ -116,19 +114,22 @@ static void test_init() test_equal(db.db_entries->len, 0); test_equal(g_hash_table_size(db.db_keys), 0); test_equal(db.db_size, 0); - test_equal(db.db_autosave, false); + test_equal(db.db_autosave, (bool)false); test_equal(db.db_file.f_version, 0); test_equal(db.db_file.f_name, "init.db"); db_deinit(&db); } +#define PTRS_AT(db, index) \ + g_ptr_array_index(db, index) + static void test_stress(unsigned int N) { - std::vector ptrs; struct db_entry *dbe, *next; struct int_entry rmv; struct database db; + GPtrArray *ptrs; unsigned int i; gchar *key; @@ -137,21 +138,22 @@ static void test_stress(unsigned int N) test_free_count = 0; test_setup_count = 0; db_init(&db, "stress.db", false, &int_ops); + ptrs = g_ptr_array_new(); /* db_insert() */ for (i = 0; i < N; i++) { key = g_strdup_printf("%u", i); dbe = db_insert(&db, &__int_alloc(i)->ie_dbe); - test_loop_not_equal(dbe, NULL, i); + test_loop_not_equal((void *)dbe, NULL, i); test_loop_equal(dbe->dbe_index, i, i); test_loop_equal(dbe->dbe_key, key, i); test_loop_equal(INT_ENTRY(dbe)->ie_val, i, i); - ptrs.push_back(INT_ENTRY(dbe)); + g_ptr_array_add(ptrs, INT_ENTRY(dbe)); g_free(key); } test_loop_passed(); dbe = db_insert(&db, NULL); - test_equal(dbe, NULL); + test_equal((void *)dbe, NULL); test_equal(db.db_size, N); test_equal(db_actual_size(&db), N); test_equal(test_setup_count, N); @@ -159,35 +161,35 @@ static void test_stress(unsigned int N) /* db_at() */ for (i = 0; i < N; i++) { dbe = db_at(&db, i); - test_loop_not_equal(dbe, NULL, i); - test_loop_equal(INT_ENTRY(dbe), ptrs.at(i), i); + test_loop_not_equal((void *)dbe, NULL, i); + test_loop_equal((void *)INT_ENTRY(dbe), PTRS_AT(ptrs, i), i); test_loop_equal(INT_ENTRY(dbe)->ie_val, i, i); } test_loop_passed(); - test_equal(db_at(&db, N), NULL); + test_equal((void *)db_at(&db, N), NULL); /* db_get() */ for (i = 0; i < N; i++) { key = g_strdup_printf("%u", i); dbe = db_get(&db, key); - test_loop_not_equal(dbe, NULL, i); + test_loop_not_equal((void *)dbe, NULL, i); test_loop_str_equal(int_ops.dbe_key(dbe), key, i); - test_loop_equal(INT_ENTRY(dbe), ptrs.at(i), i); + test_loop_equal((void *)INT_ENTRY(dbe), PTRS_AT(ptrs, i), i); test_loop_equal(INT_ENTRY(dbe)->ie_val, i, i); g_free(key); } test_loop_passed(); key = g_strdup_printf("%u", N); - test_equal(db_get(&db, key), NULL); + test_equal((void *)db_get(&db, key), NULL); g_free(key); /* db_find() */ for (i = 0; i <= N; i++) { key = g_strdup_printf("%u", i); dbe = db_find(&db, key); - test_loop_not_equal(dbe, NULL, i); + test_loop_not_equal((void *)dbe, NULL, i); test_loop_str_equal(int_ops.dbe_key(dbe), key, i); test_loop_equal(INT_ENTRY(dbe)->ie_val, i, i); if (i < N) - test_loop_equal(INT_ENTRY(dbe), ptrs.at(i), i); + test_loop_equal((void *)INT_ENTRY(dbe), PTRS_AT(ptrs, i), i); g_free(key); } test_loop_passed(); test_equal(db.db_size, N + 1); @@ -198,8 +200,8 @@ static void test_stress(unsigned int N) key = g_strdup_printf("%u", i); dbe = db_get(&db, key); db_remove(&db, dbe); - test_loop_equal(INT_ENTRY(db_at(&db, i)), NULL, i); - test_loop_equal(INT_ENTRY(db_get(&db, key)), NULL, i); + test_loop_equal((void *)INT_ENTRY(db_at(&db, i)), NULL, i); + test_loop_equal((void *)INT_ENTRY(db_get(&db, key)), NULL, i); g_free(key); } test_loop_passed(); db_remove(&db, &rmv.ie_dbe); @@ -210,24 +212,25 @@ static void test_stress(unsigned int N) /* db_for_each() (db_first() / db_next()) */ i = 1; db_for_each(dbe, next, &db) { - test_loop_not_equal(dbe, NULL, i); + test_loop_not_equal((void *)dbe, NULL, i); if (i == (N - 1)) { - test_loop_equal(next, NULL, i); + test_loop_equal((void *)next, NULL, i); } else { - test_loop_not_equal(next, NULL, i); + test_loop_not_equal((void *)next, NULL, i); test_loop_equal(INT_ENTRY(next)->ie_val, i + 2, i); } - test_loop_equal(INT_ENTRY(dbe), ptrs.at(i), i); + test_loop_equal((void *)INT_ENTRY(dbe), PTRS_AT(ptrs, i), i); test_loop_equal(INT_ENTRY(dbe)->ie_val, i, i); - test_loop_equal(db_next(&db, dbe), next, i); + test_loop_equal((void *)db_next(&db, dbe), (void *)next, i); i += 2; } test_loop_passed(); test_equal(i, N + 1); db_deinit(&db); + g_ptr_array_free(ptrs, true); test_equal(db.db_size, 0); test_equal(db_actual_size(&db), 0); - test_equal(db_first(&db), NULL); + test_equal((void *)db_first(&db), NULL); test_equal(test_free_count, N + 1); }