diff options
Diffstat (limited to 'utils/storage')
-rw-r--r-- | utils/storage/tag_utility.cpp | 127 | ||||
-rw-r--r-- | utils/storage/tag_utility.h | 8 |
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[] |