summaryrefslogtreecommitdiffstats
path: root/utils/storage
diff options
context:
space:
mode:
Diffstat (limited to 'utils/storage')
-rw-r--r--utils/storage/tag_utility.cpp127
-rw-r--r--utils/storage/tag_utility.h8
2 files changed, 119 insertions, 16 deletions
diff --git a/utils/storage/tag_utility.cpp b/utils/storage/tag_utility.cpp
index 03b8bbc..af4dda8 100644
--- a/utils/storage/tag_utility.cpp
+++ b/utils/storage/tag_utility.cpp
@@ -1,3 +1,4 @@
+#include <assert.h>
#include <glib.h>
#include "tag_utility.h"
@@ -5,23 +6,123 @@
/* internal taglib structure */
struct tag_entry{
int m_line_type;
- const char * m_line_tag;
+ char * m_line_tag;
int m_num_of_values;
- const char ** m_required_tags;
- /* const char ** m_optional_tags; */
+ char ** m_required_tags;
+ /* char ** m_optional_tags; */
/* int m_optional_count = 0; */
- const char ** m_ignored_tags;
-
-public:
- tag_entry(int line_type, const char * line_tag, int num_of_values,
- const char * required_tags[], const char * ignored_tags[]){
- m_line_type = line_type; m_line_tag = line_tag;
- m_num_of_values = num_of_values;
- m_required_tags = required_tags;
- m_ignored_tags = ignored_tags;
- }
+ char ** m_ignored_tags;
};
+tag_entry tag_entry_copy(int line_type, const char * line_tag,
+ int num_of_values,
+ char * required_tags[],
+ char * ignored_tags[]){
+ tag_entry entry;
+ entry.m_line_type = line_type;
+ entry.m_line_tag = g_strdup( line_tag );
+ entry.m_num_of_values = num_of_values;
+ entry.m_required_tags = g_strdupv( required_tags );
+ entry.m_ignored_tags = g_strdupv( ignored_tags );
+ return entry;
+}
+
+tag_entry tag_entry_clone(tag_entry * entry){
+ return tag_entry_copy(entry->m_line_type, entry->m_line_tag,
+ entry->m_num_of_values,
+ entry->m_required_tags, entry->m_ignored_tags);
+}
+
+void tag_entry_reclaim(tag_entry * entry){
+ g_free( entry->m_line_tag );
+ g_strfreev( entry->m_required_tags );
+ g_strfreev(entry->m_ignored_tags);
+}
+
+static bool taglib_free_tag_array(GArray * tag_array){
+ for ( size_t i = 0; i < tag_array->len; ++i) {
+ tag_entry * entry = &g_array_index(tag_array, tag_entry, i);
+ tag_entry_reclaim(entry);
+ }
+ g_array_free(tag_array, TRUE);
+ return true;
+}
+
+/* Pointer Array of Array of tag_entry */
+static GPtrArray * g_tagutils_stack = NULL;
+
+bool taglib_init(){
+ assert( g_tagutils_stack == NULL);
+ g_tagutils_stack = g_ptr_array_new();
+ GArray * tag_array = g_array_new(TRUE, TRUE, sizeof(tag_entry));
+ g_ptr_array_add(g_tagutils_stack, tag_array);
+ return true;
+}
+
+bool taglib_add_tag(int line_type, const char * line_tag, int num_of_values,
+ const char * required_tags[], const char * ignored_tags[]){
+ GArray * tag_array = (GArray *) g_ptr_array_index(g_tagutils_stack,
+ g_tagutils_stack->len - 1);
+ tag_entry entry = tag_entry_copy(line_type, line_tag, num_of_values,
+ (char **)required_tags,
+ (char **)ignored_tags);
+ /* TODO: maybe also do some duplicate tagname or line_type check here. */
+ g_array_append_val(tag_array, entry);
+ return true;
+}
+
+bool taglib_read(const char * input_line, int & line_type, GPtrArray * values,
+ GHashTable * required){
+ /* TODO: implement this. */
+ assert(false);
+ /* use own version of string split
+ instead of g_strsplit for special token.*/
+}
+
+bool taglib_remove_tag(int line_type){
+ /* Note: duplicate entry check is in taglib_add_tag. */
+ GArray * tag_array = (GArray *) g_ptr_array_index(g_tagutils_stack, g_tagutils_stack->len - 1);
+ for ( size_t i = 0; i < tag_array->len; ++i) {
+ tag_entry * entry = &g_array_index(tag_array, tag_entry, i);
+ if (entry->m_line_type != line_type)
+ continue;
+ tag_entry_reclaim(entry);
+ g_array_remove_index(tag_array, i);
+ return true;
+ }
+ return false;
+}
+
+bool taglib_push_state(){
+ assert(g_tagutils_stack->len >= 1);
+ GArray * next_tag_array = g_array_new(TRUE, TRUE, sizeof(tag_entry));
+ GArray * prev_tag_array = (GArray *) g_ptr_array_index(g_tagutils_stack, g_tagutils_stack->len - 1);
+ for ( size_t i = 0; i < prev_tag_array->len; ++i) {
+ tag_entry * entry = &g_array_index(prev_tag_array, tag_entry, i);
+ tag_entry new_entry = tag_entry_clone(entry);
+ g_array_append_val(next_tag_array, new_entry);
+ }
+ g_ptr_array_add(g_tagutils_stack, next_tag_array);
+ return true;
+}
+
+bool taglib_pop_state(){
+ assert(g_tagutils_stack->len > 1);
+ GArray * tag_array = (GArray *) g_ptr_array_index(g_tagutils_stack, g_tagutils_stack->len - 1);
+ g_ptr_array_remove_index(g_tagutils_stack, g_tagutils_stack->len - 1);
+ taglib_free_tag_array(tag_array);
+ return true;
+}
+
+bool taglib_fini(){
+ for ( size_t i = 0; i < g_tagutils_stack->len; ++i){
+ GArray * tag_array = (GArray *) g_ptr_array_index(g_tagutils_stack, i);
+ taglib_free_tag_array(tag_array);
+ }
+ g_ptr_array_free(g_tagutils_stack, TRUE);
+ return true;
+}
+
void test(){
TAGLIB_BEGIN_ADD_TAG(1, "\\data", 0);
TAGLIB_REQUIRED_TAGS = {"model", NULL};
diff --git a/utils/storage/tag_utility.h b/utils/storage/tag_utility.h
index 38a5bf8..fd5e89e 100644
--- a/utils/storage/tag_utility.h
+++ b/utils/storage/tag_utility.h
@@ -31,7 +31,9 @@ bool taglib_init();
/* Note: most string array (const char *) are null pointer terminated. */
bool taglib_add_tag(int line_type, const char * line_tag, int num_of_values, const char * required_tags[], const char * ignored_tags[]);
-/* most parameters are hash table of string (const char *). */
+/* most parameters are hash table of string (const char *).
+ * "..." special token handling is also omitted from the first implementation.
+ */
bool taglib_read(const char * input_line, int & line_type, GPtrArray * values, GHashTable * required);
/* Note: taglib_write is omited, as printf is more suitable for this. */
@@ -57,9 +59,9 @@ bool taglib_fini();
#define TAGLIB_BEGIN_ADD_TAG(line_type, line_tag, num_of_values) \
{ \
- const int line_type_saved = line_type; \
+ int line_type_saved = line_type; \
const char * line_tag_saved = line_tag; \
- const int num_of_values_saved = num_of_values; \
+ int num_of_values_saved = num_of_values; \
;
#define TAGLIB_REQUIRED_TAGS const char * required_tags_saved[]