diff options
Diffstat (limited to 'src/cr-prop-list.c')
-rw-r--r-- | src/cr-prop-list.c | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/src/cr-prop-list.c b/src/cr-prop-list.c new file mode 100644 index 0000000..d910a7b --- /dev/null +++ b/src/cr-prop-list.c @@ -0,0 +1,350 @@ +/* + * 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 + * + * See COPYRIGHTS file for copyrights information. + */ + +#include <string.h> +#include "cr-prop-list.h" + +#define PRIVATE(a_obj) (a_obj)->priv + +struct _CRPropListPriv +{ + GString *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 + ***************/ + +/** + *Appends a property list to the current one. + *@param a_this the current instance of #CRPropList + *@param a_to_append the property list to append + *@return the resulting prop list, or NULL if an error + *occured + */ +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 ; +} + + +/** + *appends a pair of prop/declaration to + *the current prop list. + *@param a_this the current instance of #CRPropList + *@param a_prop the property to consider + *@param a_decl the declaration to consider + *@return the resulting property list, or NULL in case + *of an error. + */ +CRPropList * +cr_prop_list_append2 (CRPropList *a_this, + GString *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 ; +} + +/** + *Prepends a list to the current list + *@param a_this the current instance of #CRPropList + *@param the new list to prepend. + */ +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 ; +} + +/** + *Prepends a list to the current list + *@param a_this the current instance of #CRPropList + *@param the new list to prepend. + */ +CRPropList * +cr_prop_list_prepend2 (CRPropList *a_this, + GString *a_prop, + CRDeclaration *a_decl) +{ + CRPropList *list = NULL, *result = NULL ; + + g_return_val_if_fail (a_this + && PRIVATE (a_this) + && a_prop && a_decl, NULL) ; + + list = cr_prop_list_allocate () ; + g_return_val_if_fail (list, NULL) ; + PRIVATE (list)->prop = a_prop ; + PRIVATE (list)->decl = a_decl ; + result = cr_prop_list_prepend (a_this, list) ; + return result ; +} + +/** + *sets the property of a CRPropList + *@param a_this the current instance of #CRPropList + *@param a_prop the property to set + */ +enum CRStatus +cr_prop_list_set_prop (CRPropList *a_this, + GString *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 ; +} + + +/** + *Getter of the property associated to the current instance + *of #CRpropList + *@param a_this the current instance of #CRPropList + *@param a_prop out parameter. The returned property + *@return CR_OK upon sucessful completion, an error code + *otherwise. + */ +enum CRStatus +cr_prop_list_get_prop (CRPropList *a_this, + GString **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 ; +} + +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 ; +} + + +enum CRStatus +cr_prop_list_get_decl (CRPropList *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 ; +} + +/** + *Lookup a given property/declaration pair + *@param a_this the current instance of #CRPropList + *@param a_prop the property to lookup + *@param a_prop_list out parameter. The property/declaration + *pair found (if and only if the function returned code if CR_OK) + *@return CR_OK upon 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, + GString *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->str + && a_prop->str + && ! strcmp (PRIVATE (cur)->prop->str, + a_prop->str)) + break ; + } + + if (cur) + { + *a_pair = cur ; + return CR_OK ; + } + + return CR_VALUE_NOT_FOUND_ERROR ; +} + + +/** + *Gets the next prop/decl pair in the list + *@param a_this the current instance of CRPropList + *@param the next prop/decl pair, or NULL if we + *reached the end of the list. + *@return 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 ; +} + +/** + *Gets the previous prop/decl pair in the list + *@param a_this the current instance of CRPropList + *@param the previous prop/decl pair, or NULL if we + *reached the end of the list. + *@return 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 ; +} + +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 ; + } +} |