diff options
Diffstat (limited to 'src/st/croco/cr-prop-list.c')
-rw-r--r-- | src/st/croco/cr-prop-list.c | 404 |
1 files changed, 404 insertions, 0 deletions
diff --git a/src/st/croco/cr-prop-list.c b/src/st/croco/cr-prop-list.c new file mode 100644 index 0000000..03c4478 --- /dev/null +++ b/src/st/croco/cr-prop-list.c @@ -0,0 +1,404 @@ +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + +#include <string.h> +#include "cr-prop-list.h" + +#define PRIVATE(a_obj) (a_obj)->priv + +struct _CRPropListPriv { + CRString *prop; + CRDeclaration *decl; + CRPropList *next; + CRPropList *prev; +}; + +static CRPropList *cr_prop_list_allocate (void); + +/** + *Default allocator of CRPropList + *@return the newly allocated CRPropList or NULL + *if an error arises. + */ +static CRPropList * +cr_prop_list_allocate (void) +{ + CRPropList *result = NULL; + + result = g_try_malloc (sizeof (CRPropList)); + if (!result) { + cr_utils_trace_info ("could not allocate CRPropList"); + return NULL; + } + memset (result, 0, sizeof (CRPropList)); + PRIVATE (result) = g_try_malloc (sizeof (CRPropListPriv)); + if (!result) { + cr_utils_trace_info ("could not allocate CRPropListPriv"); + g_free (result); + return NULL; + } + memset (PRIVATE (result), 0, sizeof (CRPropListPriv)); + return result; +} + +/**************** + *public methods + ***************/ + +/** + * cr_prop_list_append: + *@a_this: the current instance of #CRPropList + *@a_to_append: the property list to append + * + *Appends a property list to the current one. + * + *Returns the resulting prop list, or NULL if an error + *occurred + */ +CRPropList * +cr_prop_list_append (CRPropList * a_this, CRPropList * a_to_append) +{ + CRPropList *cur = NULL; + + g_return_val_if_fail (a_to_append, NULL); + + if (!a_this) + return a_to_append; + + /*go fetch the last element of the list */ + for (cur = a_this; + cur && PRIVATE (cur) && PRIVATE (cur)->next; + cur = PRIVATE (cur)->next) ; + g_return_val_if_fail (cur, NULL); + PRIVATE (cur)->next = a_to_append; + PRIVATE (a_to_append)->prev = cur; + return a_this; +} + +/** + * cr_prop_list_append2: + *Appends a pair of prop/declaration to + *the current prop list. + *@a_this: the current instance of #CRPropList + *@a_prop: the property to consider + *@a_decl: the declaration to consider + * + *Returns the resulting property list, or NULL in case + *of an error. + */ +CRPropList * +cr_prop_list_append2 (CRPropList * a_this, + CRString * a_prop, + CRDeclaration * a_decl) +{ + CRPropList *list = NULL, + *result = NULL; + + g_return_val_if_fail (a_prop && a_decl, NULL); + + list = cr_prop_list_allocate (); + g_return_val_if_fail (list && PRIVATE (list), NULL); + + PRIVATE (list)->prop = a_prop; + PRIVATE (list)->decl = a_decl; + + result = cr_prop_list_append (a_this, list); + return result; +} + +/** + * cr_prop_list_prepend: + *@a_this: the current instance of #CRPropList + *@a_to_prepend: the new list to prepend. + * + *Prepends a list to the current list + *Returns the new properties list. + */ +CRPropList * +cr_prop_list_prepend (CRPropList * a_this, CRPropList * a_to_prepend) +{ + CRPropList *cur = NULL; + + g_return_val_if_fail (a_to_prepend, NULL); + + if (!a_this) + return a_to_prepend; + + for (cur = a_to_prepend; cur && PRIVATE (cur)->next; + cur = PRIVATE (cur)->next) ; + g_return_val_if_fail (cur, NULL); + PRIVATE (cur)->next = a_this; + PRIVATE (a_this)->prev = cur; + return a_to_prepend; +} + +/** + * cr_prop_list_prepend2: + *@a_this: the current instance of #CRPropList + *@a_prop_name: property name to append + *@a_decl: the property value to append. + * + *Prepends a property to a list of properties + * + *Returns the new property list. + */ +CRPropList * +cr_prop_list_prepend2 (CRPropList * a_this, + CRString * a_prop_name, CRDeclaration * a_decl) +{ + CRPropList *list = NULL, + *result = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_prop_name && a_decl, NULL); + + list = cr_prop_list_allocate (); + g_return_val_if_fail (list, NULL); + PRIVATE (list)->prop = a_prop_name; + PRIVATE (list)->decl = a_decl; + result = cr_prop_list_prepend (a_this, list); + return result; +} + +/** + * cr_prop_list_set_prop: + *@a_this: the current instance of #CRPropList + *@a_prop: the property to set + * + *Sets the property of a CRPropList + */ +enum CRStatus +cr_prop_list_set_prop (CRPropList * a_this, CRString * a_prop) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_prop, CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->prop = a_prop; + return CR_OK; +} + +/** + * cr_prop_list_get_prop: + *@a_this: the current instance of #CRPropList + *@a_prop: out parameter. The returned property + * + *Getter of the property associated to the current instance + *of #CRPropList + * + *Returns CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_prop_list_get_prop (CRPropList const * a_this, CRString ** a_prop) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_prop, CR_BAD_PARAM_ERROR); + + *a_prop = PRIVATE (a_this)->prop; + return CR_OK; +} + +/** + * cr_prop_list_set_decl: + * @a_this: the current instance of #CRPropList + * @a_decl: the new property value. + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_prop_list_set_decl (CRPropList * a_this, CRDeclaration * a_decl) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_decl, CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->decl = a_decl; + return CR_OK; +} + +/** + * cr_prop_list_get_decl: + * @a_this: the current instance of #CRPropList + * @a_decl: out parameter. The property value + * + * Returns CR_OK upon successful completion. + */ +enum CRStatus +cr_prop_list_get_decl (CRPropList const * a_this, CRDeclaration ** a_decl) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_decl, CR_BAD_PARAM_ERROR); + + *a_decl = PRIVATE (a_this)->decl; + return CR_OK; +} + +/** + * cr_prop_list_lookup_prop: + *@a_this: the current instance of #CRPropList + *@a_prop: the property to lookup + *@a_prop_list: out parameter. The property/declaration + *pair found (if and only if the function returned code if CR_OK) + * + *Lookup a given property/declaration pair + * + *Returns CR_OK if a prop/decl pair has been found, + *CR_VALUE_NOT_FOUND_ERROR if not, or an error code if something + *bad happens. + */ +enum CRStatus +cr_prop_list_lookup_prop (CRPropList * a_this, + CRString * a_prop, CRPropList ** a_pair) +{ + CRPropList *cur = NULL; + + g_return_val_if_fail (a_prop && a_pair, CR_BAD_PARAM_ERROR); + + if (!a_this) + return CR_VALUE_NOT_FOUND_ERROR; + + g_return_val_if_fail (PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + for (cur = a_this; cur; cur = PRIVATE (cur)->next) { + if (PRIVATE (cur)->prop + && PRIVATE (cur)->prop->stryng + && PRIVATE (cur)->prop->stryng->str + && a_prop->stryng + && a_prop->stryng->str + && !strcmp (PRIVATE (cur)->prop->stryng->str, + a_prop->stryng->str)) + break; + } + + if (cur) { + *a_pair = cur; + return CR_OK; + } + + return CR_VALUE_NOT_FOUND_ERROR; +} + +/** + * cr_prop_list_get_next: + *@a_this: the current instance of CRPropList + * + *Gets the next prop/decl pair in the list + * + *Returns the next prop/declaration pair of the list, + *or NULL if we reached end of list (or if an error occurs) + */ +CRPropList * +cr_prop_list_get_next (CRPropList * a_this) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), NULL); + + return PRIVATE (a_this)->next; +} + +/** + * cr_prop_list_get_prev: + *@a_this: the current instance of CRPropList + * + *Gets the previous prop/decl pair in the list + * + *Returns the previous prop/declaration pair of the list, + *or NULL if we reached end of list (or if an error occurs) + */ +CRPropList * +cr_prop_list_get_prev (CRPropList * a_this) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), NULL); + + return PRIVATE (a_this)->prev; +} + +/** + * cr_prop_list_unlink: + *@a_this: the current list of prop/decl pairs + *@a_pair: the prop/decl pair to unlink. + * + *Unlinks a prop/decl pair from the list + * + *Returns the new list or NULL in case of an error. + */ +CRPropList * +cr_prop_list_unlink (CRPropList * a_this, CRPropList * a_pair) +{ + CRPropList *prev = NULL, + *next = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_pair, NULL); + + /*some sanity checks */ + if (PRIVATE (a_pair)->next) { + next = PRIVATE (a_pair)->next; + g_return_val_if_fail (PRIVATE (next), NULL); + g_return_val_if_fail (PRIVATE (next)->prev == a_pair, NULL); + } + if (PRIVATE (a_pair)->prev) { + prev = PRIVATE (a_pair)->prev; + g_return_val_if_fail (PRIVATE (prev), NULL); + g_return_val_if_fail (PRIVATE (prev)->next == a_pair, NULL); + } + if (prev) { + PRIVATE (prev)->next = next; + } + if (next) { + PRIVATE (next)->prev = prev; + } + PRIVATE (a_pair)->prev = PRIVATE (a_pair)->next = NULL; + if (a_this == a_pair) { + if (next) + return next; + return NULL; + } + return a_this; +} + +/** + * cr_prop_list_destroy: + * @a_this: the current instance of #CRPropList + */ +void +cr_prop_list_destroy (CRPropList * a_this) +{ + CRPropList *tail = NULL, + *cur = NULL; + + g_return_if_fail (a_this && PRIVATE (a_this)); + + for (tail = a_this; + tail && PRIVATE (tail) && PRIVATE (tail)->next; + tail = cr_prop_list_get_next (tail)) ; + g_return_if_fail (tail); + + cur = tail; + + while (cur) { + tail = PRIVATE (cur)->prev; + if (tail && PRIVATE (tail)) + PRIVATE (tail)->next = NULL; + PRIVATE (cur)->prev = NULL; + g_free (PRIVATE (cur)); + PRIVATE (cur) = NULL; + g_free (cur); + cur = tail; + } +} |