summaryrefslogtreecommitdiff
path: root/src/cr-prop-list.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cr-prop-list.c')
-rw-r--r--src/cr-prop-list.c350
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 ;
+ }
+}