Libcroco
cr-prop-list.c
Go to the documentation of this file.
1 /*
2  * This file is part of The Croco Library
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of version 2.1 of the GNU Lesser General Public
6  * License as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
16  * USA
17  *
18  * Author: Dodji Seketeli
19  * See COPYRIGHTS file for copyrights information.
20  */
21 
22 #include <string.h>
23 #include "cr-prop-list.h"
24 
25 #define PRIVATE(a_obj) (a_obj)->priv
26 
32 };
33 
34 static CRPropList *cr_prop_list_allocate (void);
35 
36 /**
37  *Default allocator of CRPropList
38  *@return the newly allocated CRPropList or NULL
39  *if an error arises.
40  */
41 static CRPropList *
42 cr_prop_list_allocate (void)
43 {
44  CRPropList *result = NULL;
45 
46  result = g_try_malloc (sizeof (CRPropList));
47  if (!result) {
48  cr_utils_trace_info ("could not allocate CRPropList");
49  return NULL;
50  }
51  memset (result, 0, sizeof (CRPropList));
52  PRIVATE (result) = g_try_malloc (sizeof (CRPropListPriv));
53  if (!result) {
54  cr_utils_trace_info ("could not allocate CRPropListPriv");
55  g_free (result);
56  return NULL;
57  }
58  memset (PRIVATE (result), 0, sizeof (CRPropListPriv));
59  return result;
60 }
61 
62 /****************
63  *public methods
64  ***************/
65 
66 /**
67  * cr_prop_list_append:
68  *@a_this: the current instance of #CRPropList
69  *@a_to_append: the property list to append
70  *
71  *Appends a property list to the current one.
72  *
73  *Returns the resulting prop list, or NULL if an error
74  *occurred
75  */
76 CRPropList *
77 cr_prop_list_append (CRPropList * a_this, CRPropList * a_to_append)
78 {
79  CRPropList *cur = NULL;
80 
81  g_return_val_if_fail (a_to_append, NULL);
82 
83  if (!a_this)
84  return a_to_append;
85 
86  /*go fetch the last element of the list */
87  for (cur = a_this;
88  cur && PRIVATE (cur) && PRIVATE (cur)->next;
89  cur = PRIVATE (cur)->next) ;
90  g_return_val_if_fail (cur, NULL);
91  PRIVATE (cur)->next = a_to_append;
92  PRIVATE (a_to_append)->prev = cur;
93  return a_this;
94 }
95 
96 /**
97  * cr_prop_list_append2:
98  *Appends a pair of prop/declaration to
99  *the current prop list.
100  *@a_this: the current instance of #CRPropList
101  *@a_prop: the property to consider
102  *@a_decl: the declaration to consider
103  *
104  *Returns the resulting property list, or NULL in case
105  *of an error.
106  */
107 CRPropList *
109  CRString * a_prop,
110  CRDeclaration * a_decl)
111 {
112  CRPropList *list = NULL,
113  *result = NULL;
114 
115  g_return_val_if_fail (a_prop && a_decl, NULL);
116 
117  list = cr_prop_list_allocate ();
118  g_return_val_if_fail (list && PRIVATE (list), NULL);
119 
120  PRIVATE (list)->prop = a_prop;
121  PRIVATE (list)->decl = a_decl;
122 
123  result = cr_prop_list_append (a_this, list);
124  return result;
125 }
126 
127 /**
128  * cr_prop_list_prepend:
129  *@a_this: the current instance of #CRPropList
130  *@a_to_prepend: the new list to prepend.
131  *
132  *Prepends a list to the current list
133  *Returns the new properties list.
134  */
135 CRPropList *
136 cr_prop_list_prepend (CRPropList * a_this, CRPropList * a_to_prepend)
137 {
138  CRPropList *cur = NULL;
139 
140  g_return_val_if_fail (a_to_prepend, NULL);
141 
142  if (!a_this)
143  return a_to_prepend;
144 
145  for (cur = a_to_prepend; cur && PRIVATE (cur)->next;
146  cur = PRIVATE (cur)->next) ;
147  g_return_val_if_fail (cur, NULL);
148  PRIVATE (cur)->next = a_this;
149  PRIVATE (a_this)->prev = cur;
150  return a_to_prepend;
151 }
152 
153 /**
154  * cr_prop_list_prepend2:
155  *@a_this: the current instance of #CRPropList
156  *@a_prop_name: property name to append
157  *@a_decl: the property value to append.
158  *
159  *Prepends a propertie to a list of properties
160  *
161  *Returns the new property list.
162  */
163 CRPropList *
165  CRString * a_prop_name, CRDeclaration * a_decl)
166 {
167  CRPropList *list = NULL,
168  *result = NULL;
169 
170  g_return_val_if_fail (a_this && PRIVATE (a_this)
171  && a_prop_name && a_decl, NULL);
172 
173  list = cr_prop_list_allocate ();
174  g_return_val_if_fail (list, NULL);
175  PRIVATE (list)->prop = a_prop_name;
176  PRIVATE (list)->decl = a_decl;
177  result = cr_prop_list_prepend (a_this, list);
178  return result;
179 }
180 
181 /**
182  * cr_prop_list_set_prop:
183  *@a_this: the current instance of #CRPropList
184  *@a_prop: the property to set
185  *
186  *Sets the property of a CRPropList
187  */
188 enum CRStatus
190 {
191  g_return_val_if_fail (a_this && PRIVATE (a_this)
192  && a_prop, CR_BAD_PARAM_ERROR);
193 
194  PRIVATE (a_this)->prop = a_prop;
195  return CR_OK;
196 }
197 
198 /**
199  * cr_prop_list_get_prop:
200  *@a_this: the current instance of #CRPropList
201  *@a_prop: out parameter. The returned property
202  *
203  *Getter of the property associated to the current instance
204  *of #CRPropList
205  *
206  *Returns CR_OK upon successful completion, an error code
207  *otherwise.
208  */
209 enum CRStatus
210 cr_prop_list_get_prop (CRPropList const * a_this, CRString ** a_prop)
211 {
212  g_return_val_if_fail (a_this && PRIVATE (a_this)
213  && a_prop, CR_BAD_PARAM_ERROR);
214 
215  *a_prop = PRIVATE (a_this)->prop;
216  return CR_OK;
217 }
218 
219 /**
220  * cr_prop_list_set_decl:
221  * @a_this: the current instance of #CRPropList
222  * @a_decl: the new property value.
223  *
224  * Returns CR_OK upon successful completion, an error code otherwise.
225  */
226 enum CRStatus
228 {
229  g_return_val_if_fail (a_this && PRIVATE (a_this)
230  && a_decl, CR_BAD_PARAM_ERROR);
231 
232  PRIVATE (a_this)->decl = a_decl;
233  return CR_OK;
234 }
235 
236 /**
237  * cr_prop_list_get_decl:
238  * @a_this: the current instance of #CRPropList
239  * @a_decl: out parameter. The property value
240  *
241  * Returns CR_OK upon successful completion.
242  */
243 enum CRStatus
244 cr_prop_list_get_decl (CRPropList const * a_this, CRDeclaration ** a_decl)
245 {
246  g_return_val_if_fail (a_this && PRIVATE (a_this)
247  && a_decl, CR_BAD_PARAM_ERROR);
248 
249  *a_decl = PRIVATE (a_this)->decl;
250  return CR_OK;
251 }
252 
253 /**
254  * cr_prop_list_lookup_prop:
255  *@a_this: the current instance of #CRPropList
256  *@a_prop: the property to lookup
257  *@a_prop_list: out parameter. The property/declaration
258  *pair found (if and only if the function returned code if CR_OK)
259  *
260  *Lookup a given property/declaration pair
261  *
262  *Returns CR_OK if a prop/decl pair has been found,
263  *CR_VALUE_NOT_FOUND_ERROR if not, or an error code if something
264  *bad happens.
265  */
266 enum CRStatus
268  CRString * a_prop, CRPropList ** a_pair)
269 {
270  CRPropList *cur = NULL;
271 
272  g_return_val_if_fail (a_prop && a_pair, CR_BAD_PARAM_ERROR);
273 
274  if (!a_this)
276 
277  g_return_val_if_fail (PRIVATE (a_this), CR_BAD_PARAM_ERROR);
278 
279  for (cur = a_this; cur; cur = PRIVATE (cur)->next) {
280  if (PRIVATE (cur)->prop
281  && PRIVATE (cur)->prop->stryng
282  && PRIVATE (cur)->prop->stryng->str
283  && a_prop->stryng
284  && a_prop->stryng->str
285  && !strcmp (PRIVATE (cur)->prop->stryng->str,
286  a_prop->stryng->str))
287  break;
288  }
289 
290  if (cur) {
291  *a_pair = cur;
292  return CR_OK;
293  }
294 
296 }
297 
298 /**
299  * cr_prop_list_get_next:
300  *@a_this: the current instance of CRPropList
301  *
302  *Gets the next prop/decl pair in the list
303  *
304  *Returns the next prop/declaration pair of the list,
305  *or NULL if we reached end of list (or if an error occurs)
306  */
307 CRPropList *
309 {
310  g_return_val_if_fail (a_this && PRIVATE (a_this), NULL);
311 
312  return PRIVATE (a_this)->next;
313 }
314 
315 /**
316  * cr_prop_list_get_prev:
317  *@a_this: the current instance of CRPropList
318  *
319  *Gets the previous prop/decl pair in the list
320  *
321  *Returns the previous prop/declaration pair of the list,
322  *or NULL if we reached end of list (or if an error occurs)
323  */
324 CRPropList *
326 {
327  g_return_val_if_fail (a_this && PRIVATE (a_this), NULL);
328 
329  return PRIVATE (a_this)->prev;
330 }
331 
332 /**
333  * cr_prop_list_unlink:
334  *@a_this: the current list of prop/decl pairs
335  *@a_pair: the prop/decl pair to unlink.
336  *
337  *Unlinks a prop/decl pair from the list
338  *
339  *Returns the new list or NULL in case of an error.
340  */
341 CRPropList *
343 {
344  CRPropList *prev = NULL,
345  *next = NULL;
346 
347  g_return_val_if_fail (a_this && PRIVATE (a_this) && a_pair, NULL);
348 
349  /*some sanity checks */
350  if (PRIVATE (a_pair)->next) {
351  next = PRIVATE (a_pair)->next;
352  g_return_val_if_fail (PRIVATE (next), NULL);
353  g_return_val_if_fail (PRIVATE (next)->prev == a_pair, NULL);
354  }
355  if (PRIVATE (a_pair)->prev) {
356  prev = PRIVATE (a_pair)->prev;
357  g_return_val_if_fail (PRIVATE (prev), NULL);
358  g_return_val_if_fail (PRIVATE (prev)->next == a_pair, NULL);
359  }
360  if (prev) {
361  PRIVATE (prev)->next = next;
362  }
363  if (next) {
364  PRIVATE (next)->prev = prev;
365  }
366  PRIVATE (a_pair)->prev = PRIVATE (a_pair)->next = NULL;
367  if (a_this == a_pair) {
368  if (next)
369  return next;
370  return NULL;
371  }
372  return a_this;
373 }
374 
375 /**
376  * cr_prop_list_destroy:
377  * @a_this: the current instance of #CRPropList
378  */
379 void
381 {
382  CRPropList *tail = NULL,
383  *cur = NULL;
384 
385  g_return_if_fail (a_this && PRIVATE (a_this));
386 
387  for (tail = a_this;
388  tail && PRIVATE (tail) && PRIVATE (tail)->next;
389  tail = cr_prop_list_get_next (tail)) ;
390  g_return_if_fail (tail);
391 
392  cur = tail;
393 
394  while (cur) {
395  tail = PRIVATE (cur)->prev;
396  if (tail && PRIVATE (tail))
397  PRIVATE (tail)->next = NULL;
398  PRIVATE (cur)->prev = NULL;
399  g_free (PRIVATE (cur));
400  PRIVATE (cur) = NULL;
401  g_free (cur);
402  cur = tail;
403  }
404 }
CRPropList * cr_prop_list_append2(CRPropList *a_this, CRString *a_prop, CRDeclaration *a_decl)
cr_prop_list_append2: Appends a pair of prop/declaration to the current prop list.
Definition: cr-prop-list.c:108
CRString * prop
Definition: cr-prop-list.c:28
#define PRIVATE(a_obj)
Definition: cr-prop-list.c:25
CRPropList * cr_prop_list_prepend2(CRPropList *a_this, CRString *a_prop_name, CRDeclaration *a_decl)
cr_prop_list_prepend2: @a_this: the current instance of CRPropList @a_prop_name: property name to app...
Definition: cr-prop-list.c:164
enum CRStatus cr_prop_list_set_prop(CRPropList *a_this, CRString *a_prop)
cr_prop_list_set_prop: @a_this: the current instance of CRPropList @a_prop: the property to set
Definition: cr-prop-list.c:189
CRDeclaration * decl
Definition: cr-prop-list.c:29
enum CRStatus cr_prop_list_lookup_prop(CRPropList *a_this, CRString *a_prop, CRPropList **a_pair)
cr_prop_list_lookup_prop: @a_this: the current instance of CRPropList @a_prop: the property to lookup...
Definition: cr-prop-list.c:267
CRStatus
The status type returned by the methods of the croco library.
Definition: cr-utils.h:43
typedefG_BEGIN_DECLS struct _CRPropList CRPropList
Definition: cr-prop-list.h:31
void cr_prop_list_destroy(CRPropList *a_this)
cr_prop_list_destroy: @a_this: the current instance of CRPropList
Definition: cr-prop-list.c:380
Definition: cr-utils.h:44
CRPropList * cr_prop_list_get_next(CRPropList *a_this)
cr_prop_list_get_next: @a_this: the current instance of CRPropList
Definition: cr-prop-list.c:308
CRPropList * cr_prop_list_unlink(CRPropList *a_this, CRPropList *a_pair)
cr_prop_list_unlink: @a_this: the current list of prop/decl pairs @a_pair: the prop/decl pair to unli...
Definition: cr-prop-list.c:342
typedefG_BEGIN_DECLS struct _CRString CRString
Definition: cr-string.h:37
CRPropList * cr_prop_list_append(CRPropList *a_this, CRPropList *a_to_append)
cr_prop_list_append: @a_this: the current instance of CRPropList @a_to_append: the property list to a...
Definition: cr-prop-list.c:77
CRPropList * cr_prop_list_get_prev(CRPropList *a_this)
cr_prop_list_get_prev: @a_this: the current instance of CRPropList
Definition: cr-prop-list.c:325
enum CRStatus cr_prop_list_get_decl(CRPropList const *a_this, CRDeclaration **a_decl)
cr_prop_list_get_decl: @a_this: the current instance of CRPropList @a_decl: out parameter.
Definition: cr-prop-list.c:244
CRPropList * next
Definition: cr-prop-list.c:30
enum CRStatus cr_prop_list_get_prop(CRPropList const *a_this, CRString **a_prop)
cr_prop_list_get_prop: @a_this: the current instance of CRPropList @a_prop: out parameter.
Definition: cr-prop-list.c:210
CRPropList * cr_prop_list_prepend(CRPropList *a_this, CRPropList *a_to_prepend)
cr_prop_list_prepend: @a_this: the current instance of CRPropList @a_to_prepend: the new list to prep...
Definition: cr-prop-list.c:136
CRPropList * prev
Definition: cr-prop-list.c:31
enum CRStatus cr_prop_list_set_decl(CRPropList *a_this, CRDeclaration *a_decl)
cr_prop_list_set_decl: @a_this: the current instance of CRPropList @a_decl: the new property value.
Definition: cr-prop-list.c:227
#define cr_utils_trace_info(a_msg)
Traces an info message.
Definition: cr-utils.h:127