cr-prop-list.c

Go to the documentation of this file.
00001 /*
00002  * This file is part of The Croco Library
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of version 2.1 of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation.
00007  *
00008  * This program is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  * GNU General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this program; if not, write to the Free Software
00015  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00016  * USA
00017  *
00018  * Author: Dodji Seketeli
00019  * See COPYRIGHTS file for copyrights information.
00020  */
00021 
00022 #include <string.h>
00023 #include "cr-prop-list.h"
00024 
00025 #define PRIVATE(a_obj) (a_obj)->priv
00026 
00027 struct _CRPropListPriv {
00028         CRString *prop;
00029         CRDeclaration *decl;
00030         CRPropList *next;
00031         CRPropList *prev;
00032 };
00033 
00034 static CRPropList *cr_prop_list_allocate (void);
00035 
00036 /**
00037  *Default allocator of CRPropList
00038  *@return the newly allocated CRPropList or NULL
00039  *if an error arises.
00040  */
00041 static CRPropList *
00042 cr_prop_list_allocate (void)
00043 {
00044         CRPropList *result = NULL;
00045 
00046         result = g_try_malloc (sizeof (CRPropList));
00047         if (!result) {
00048                 cr_utils_trace_info ("could not allocate CRPropList");
00049                 return NULL;
00050         }
00051         memset (result, 0, sizeof (CRPropList));
00052         PRIVATE (result) = g_try_malloc (sizeof (CRPropListPriv));
00053         if (!result) {
00054                 cr_utils_trace_info ("could not allocate CRPropListPriv");
00055                 g_free (result);
00056                 return NULL;
00057         }
00058         memset (PRIVATE (result), 0, sizeof (CRPropListPriv));
00059         return result;
00060 }
00061 
00062 /****************
00063  *public methods
00064  ***************/
00065 
00066 /**
00067  * cr_prop_list_append:
00068  *@a_this: the current instance of #CRPropList
00069  *@a_to_append: the property list to append
00070  *
00071  *Appends a property list to the current one.
00072  *
00073  *Returns the resulting prop list, or NULL if an error
00074  *occured
00075  */
00076 CRPropList *
00077 cr_prop_list_append (CRPropList * a_this, CRPropList * a_to_append)
00078 {
00079         CRPropList *cur = NULL;
00080 
00081         g_return_val_if_fail (a_to_append, NULL);
00082 
00083         if (!a_this)
00084                 return a_to_append;
00085 
00086         /*go fetch the last element of the list */
00087         for (cur = a_this;
00088              cur && PRIVATE (cur) && PRIVATE (cur)->next;
00089              cur = PRIVATE (cur)->next) ;
00090         g_return_val_if_fail (cur, NULL);
00091         PRIVATE (cur)->next = a_to_append;
00092         PRIVATE (a_to_append)->prev = cur;
00093         return a_this;
00094 }
00095 
00096 /**
00097  * cr_prop_list_append2:
00098  *Appends a pair of prop/declaration to
00099  *the current prop list.
00100  *@a_this: the current instance of #CRPropList
00101  *@a_prop: the property to consider
00102  *@a_decl: the declaration to consider
00103  *Returns the resulting property list, or NULL in case
00104  *of an error.
00105  */
00106 CRPropList *
00107 cr_prop_list_append2 (CRPropList * a_this,
00108                       CRString * a_prop, 
00109                       CRDeclaration * a_decl)
00110 {
00111         CRPropList *list = NULL,
00112                 *result = NULL;
00113 
00114         g_return_val_if_fail (a_prop && a_decl, NULL);
00115 
00116         list = cr_prop_list_allocate ();
00117         g_return_val_if_fail (list && PRIVATE (list), NULL);
00118 
00119         PRIVATE (list)->prop = a_prop;
00120         PRIVATE (list)->decl = a_decl;
00121 
00122         result = cr_prop_list_append (a_this, list);
00123         return result;
00124 }
00125 
00126 /**
00127  * cr_prop_list_prepend:
00128  *@a_this: the current instance of #CRPropList
00129  *@a_to_prepend: the new list to prepend.
00130  *
00131  *Prepends a list to the current list
00132  *Returns the new properties list.
00133  */
00134 CRPropList *
00135 cr_prop_list_prepend (CRPropList * a_this, CRPropList * a_to_prepend)
00136 {
00137         CRPropList *cur = NULL;
00138 
00139         g_return_val_if_fail (a_to_prepend, NULL);
00140 
00141         if (!a_this)
00142                 return a_to_prepend;
00143 
00144         for (cur = a_to_prepend; cur && PRIVATE (cur)->next;
00145              cur = PRIVATE (cur)->next) ;
00146         g_return_val_if_fail (cur, NULL);
00147         PRIVATE (cur)->next = a_this;
00148         PRIVATE (a_this)->prev = cur;
00149         return a_to_prepend;
00150 }
00151 
00152 /**
00153  * cr_prop_list_prepend2:
00154  *@a_this: the current instance of #CRPropList
00155  *@a_prop_name: property name to append
00156  *@a_decl: the property value to append.
00157  *
00158  *Prepends a propertie to a list of properties 
00159  *
00160  * Returns the new property list.
00161  */
00162 CRPropList *
00163 cr_prop_list_prepend2 (CRPropList * a_this,
00164                        CRString * a_prop_name, CRDeclaration * a_decl)
00165 {
00166         CRPropList *list = NULL,
00167                 *result = NULL;
00168 
00169         g_return_val_if_fail (a_this && PRIVATE (a_this)
00170                               && a_prop_name && a_decl, NULL);
00171 
00172         list = cr_prop_list_allocate ();
00173         g_return_val_if_fail (list, NULL);
00174         PRIVATE (list)->prop = a_prop_name;
00175         PRIVATE (list)->decl = a_decl;
00176         result = cr_prop_list_prepend (a_this, list);
00177         return result;
00178 }
00179 
00180 /**
00181  * cr_prop_list_set_prop:
00182  *@a_this: the current instance of #CRPropList
00183  *@a_prop: the property to set
00184  *
00185  *Sets the property of a CRPropList
00186  */
00187 enum CRStatus
00188 cr_prop_list_set_prop (CRPropList * a_this, CRString * a_prop)
00189 {
00190         g_return_val_if_fail (a_this && PRIVATE (a_this)
00191                               && a_prop, CR_BAD_PARAM_ERROR);
00192 
00193         PRIVATE (a_this)->prop = a_prop;
00194         return CR_OK;
00195 }
00196 
00197 /**
00198  * cr_prop_list_get_prop:
00199  *@a_this: the current instance of #CRPropList
00200  *@a_prop: out parameter. The returned property
00201  *
00202  *Getter of the property associated to the current instance
00203  *of #CRPropList
00204  *
00205  *Returns CR_OK upon successful completion, an error code
00206  *otherwise.
00207  */
00208 enum CRStatus
00209 cr_prop_list_get_prop (CRPropList * a_this, CRString ** a_prop)
00210 {
00211         g_return_val_if_fail (a_this && PRIVATE (a_this)
00212                               && a_prop, CR_BAD_PARAM_ERROR);
00213 
00214         *a_prop = PRIVATE (a_this)->prop;
00215         return CR_OK;
00216 }
00217 
00218 /**
00219  * cr_prop_list_set_decl:
00220  * @a_this: the current instance of #CRPropList
00221  * @a_decl: the new property value.
00222  * Returns CR_OK upon successful completion, an error code otherwise.
00223  */
00224 enum CRStatus
00225 cr_prop_list_set_decl (CRPropList * a_this, CRDeclaration * a_decl)
00226 {
00227         g_return_val_if_fail (a_this && PRIVATE (a_this)
00228                               && a_decl, CR_BAD_PARAM_ERROR);
00229 
00230         PRIVATE (a_this)->decl = a_decl;
00231         return CR_OK;
00232 }
00233 
00234 /**
00235  * cr_prop_list_get_decl:
00236  * @a_this: the current instance of #CRPropList
00237  * @a_decl: out parameter. The property value
00238  * Returns CR_OK upon successful completion.
00239  */
00240 enum CRStatus
00241 cr_prop_list_get_decl (CRPropList * a_this, CRDeclaration ** a_decl)
00242 {
00243         g_return_val_if_fail (a_this && PRIVATE (a_this)
00244                               && a_decl, CR_BAD_PARAM_ERROR);
00245 
00246         *a_decl = PRIVATE (a_this)->decl;
00247         return CR_OK;
00248 }
00249 
00250 /**
00251  * cr_prop_list_lookup_prop:
00252  *@a_this: the current instance of #CRPropList
00253  *@a_prop: the property to lookup
00254  *@a_prop_list: out parameter. The property/declaration
00255  *pair found (if and only if the function returned code if CR_OK)
00256  *
00257  *Lookup a given property/declaration pair
00258  *
00259  *Returns CR_OK if a prop/decl pair has been found,
00260  *CR_VALUE_NOT_FOUND_ERROR if not, or an error code if something
00261  *bad happens.
00262  */
00263 enum CRStatus
00264 cr_prop_list_lookup_prop (CRPropList * a_this,
00265                           CRString * a_prop, CRPropList ** a_pair)
00266 {
00267         CRPropList *cur = NULL;
00268 
00269         g_return_val_if_fail (a_prop && a_pair, CR_BAD_PARAM_ERROR);
00270 
00271         if (!a_this)
00272                 return CR_VALUE_NOT_FOUND_ERROR;
00273 
00274         g_return_val_if_fail (PRIVATE (a_this), CR_BAD_PARAM_ERROR);
00275 
00276         for (cur = a_this; cur; cur = PRIVATE (cur)->next) {
00277                 if (PRIVATE (cur)->prop
00278                     && PRIVATE (cur)->prop->stryng
00279                     && PRIVATE (cur)->prop->stryng->str
00280                     && a_prop->stryng
00281                     && a_prop->stryng->str
00282                     && !strcmp (PRIVATE (cur)->prop->stryng->str, 
00283                                 a_prop->stryng->str))
00284                         break;
00285         }
00286 
00287         if (cur) {
00288                 *a_pair = cur;
00289                 return CR_OK;
00290         }
00291 
00292         return CR_VALUE_NOT_FOUND_ERROR;
00293 }
00294 
00295 /**
00296  * cr_prop_list_get_next:
00297  *@a_this: the current instance of CRPropList
00298  *
00299  *Gets the next prop/decl pair in the list
00300  *
00301  *Returns the next prop/declaration pair of the list, 
00302  *or NULL if we reached end of list (or if an error occurs)
00303  */
00304 CRPropList *
00305 cr_prop_list_get_next (CRPropList * a_this)
00306 {
00307         g_return_val_if_fail (a_this && PRIVATE (a_this), NULL);
00308 
00309         return PRIVATE (a_this)->next;
00310 }
00311 
00312 /**
00313  * cr_prop_list_get_prev:
00314  *@a_this: the current instance of CRPropList
00315  *
00316  *Gets the previous prop/decl pair in the list
00317  *
00318  *Returns the previous prop/declaration pair of the list, 
00319  *or NULL if we reached end of list (or if an error occurs)
00320  */
00321 CRPropList *
00322 cr_prop_list_get_prev (CRPropList * a_this)
00323 {
00324         g_return_val_if_fail (a_this && PRIVATE (a_this), NULL);
00325 
00326         return PRIVATE (a_this)->prev;
00327 }
00328 
00329 /**
00330  * cr_prop_list_unlink:
00331  *@a_this: the current list of prop/decl pairs
00332  *@a_pair: the prop/decl pair to unlink.
00333  *
00334  *Unlinks a prop/decl pair from the list
00335  *
00336  *Returns the new list or NULL in case of an error.
00337  */
00338 CRPropList *
00339 cr_prop_list_unlink (CRPropList * a_this, CRPropList * a_pair)
00340 {
00341         CRPropList *prev = NULL,
00342                 *next = NULL;
00343 
00344         g_return_val_if_fail (a_this && PRIVATE (a_this) && a_pair, NULL);
00345 
00346         /*some sanity checks */
00347         if (PRIVATE (a_pair)->next) {
00348                 next = PRIVATE (a_pair)->next;
00349                 g_return_val_if_fail (PRIVATE (next), NULL);
00350                 g_return_val_if_fail (PRIVATE (next)->prev == a_pair, NULL);
00351         }
00352         if (PRIVATE (a_pair)->prev) {
00353                 prev = PRIVATE (a_pair)->prev;
00354                 g_return_val_if_fail (PRIVATE (prev), NULL);
00355                 g_return_val_if_fail (PRIVATE (prev)->next == a_pair, NULL);
00356         }
00357         if (prev) {
00358                 PRIVATE (prev)->next = next;
00359         }
00360         if (next) {
00361                 PRIVATE (next)->prev = prev;
00362         }
00363         PRIVATE (a_pair)->prev = PRIVATE (a_pair)->next = NULL;
00364         if (a_this == a_pair) {
00365                 if (next)
00366                         return next;
00367                 return NULL;
00368         }
00369         return a_this;
00370 }
00371 
00372 /**
00373  * cr_prop_list_detroy:
00374  * @a_this: the current instance of #CRPropList
00375  */
00376 void
00377 cr_prop_list_destroy (CRPropList * a_this)
00378 {
00379         CRPropList *tail = NULL,
00380                 *cur = NULL;
00381 
00382         g_return_if_fail (a_this && PRIVATE (a_this));
00383 
00384         for (tail = a_this;
00385              tail && PRIVATE (tail) && PRIVATE (tail)->next;
00386              tail = cr_prop_list_get_next (tail)) ;
00387         g_return_if_fail (tail);
00388 
00389         cur = tail;
00390 
00391         while (cur) {
00392                 tail = PRIVATE (cur)->prev;
00393                 if (tail && PRIVATE (tail))
00394                         PRIVATE (tail)->next = NULL;
00395                 PRIVATE (cur)->prev = NULL;
00396                 g_free (PRIVATE (cur));
00397                 PRIVATE (cur) = NULL;
00398                 g_free (cur);
00399                 cur = tail;
00400         }
00401 }

Generated on Thu Mar 9 19:18:50 2006 for Libcroco by  doxygen 1.4.6