Libcroco
cr-selector.c
Go to the documentation of this file.
1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2 
3 /*
4  * This file is part of The Croco Library
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of version 2.1 of the GNU Lesser General Public
8  * License as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18  * USA
19  *
20  * See COPYRIGHTS file for copyright information.
21  */
22 
23 #include <string.h>
24 #include "cr-selector.h"
25 #include "cr-parser.h"
26 
27 /**
28  * cr_selector_new:
29  *
30  *@a_simple_sel: the initial simple selector list
31  *of the current instance of #CRSelector.
32  *
33  *Creates a new instance of #CRSelector.
34  *
35  *Returns the newly built instance of #CRSelector, or
36  *NULL in case of failure.
37  */
38 CRSelector *
39 cr_selector_new (CRSimpleSel * a_simple_sel)
40 {
41  CRSelector *result = NULL;
42 
43  result = g_try_malloc (sizeof (CRSelector));
44  if (!result) {
45  cr_utils_trace_info ("Out of memory");
46  return NULL;
47  }
48  memset (result, 0, sizeof (CRSelector));
49  result->simple_sel = a_simple_sel;
50  return result;
51 }
52 
53 CRSelector *
54 cr_selector_parse_from_buf (const guchar * a_char_buf, enum CREncoding a_enc)
55 {
56  CRParser *parser = NULL;
57 
58  g_return_val_if_fail (a_char_buf, NULL);
59 
60  parser = cr_parser_new_from_buf ((guchar*)a_char_buf, strlen ((const char *) a_char_buf),
61  a_enc, FALSE);
62  g_return_val_if_fail (parser, NULL);
63 
64  return NULL;
65 }
66 
67 /**
68  * cr_selector_append:
69  *
70  *@a_this: the current instance of #CRSelector.
71  *@a_new: the instance of #CRSelector to be appended.
72  *
73  *Appends a new instance of #CRSelector to the current selector list.
74  *
75  *Returns the new list.
76  */
77 CRSelector *
79 {
80  CRSelector *cur = NULL;
81 
82  if (!a_this) {
83  return a_new;
84  }
85 
86  /*walk forward the list headed by a_this to get the list tail */
87  for (cur = a_this; cur && cur->next; cur = cur->next) ;
88 
89  cur->next = a_new;
90  a_new->prev = cur;
91 
92  return a_this;
93 }
94 
95 /**
96  * cr_selector_prepend:
97  *
98  *@a_this: the current instance of #CRSelector list.
99  *@a_new: the instance of #CRSelector.
100  *
101  *Prepends an element to the #CRSelector list.
102  *
103  *Returns the new list.
104  */
105 CRSelector *
107 {
108  CRSelector *cur = NULL;
109 
110  a_new->next = a_this;
111  a_this->prev = a_new;
112 
113  for (cur = a_new; cur && cur->prev; cur = cur->prev) ;
114 
115  return cur;
116 }
117 
118 /**
119  * cr_selector_append_simple_sel:
120  *
121  *@a_this: the current instance of #CRSelector.
122  *@a_simple_sel: the simple selector to append.
123  *
124  *append a simple selector to the current #CRSelector list.
125  *
126  *Returns the new list or NULL in case of failure.
127  */
128 CRSelector *
130  CRSimpleSel * a_simple_sel)
131 {
132  CRSelector *selector = NULL;
133 
134  selector = cr_selector_new (a_simple_sel);
135  g_return_val_if_fail (selector, NULL);
136 
137  return cr_selector_append (a_this, selector);
138 }
139 
140 guchar *
142 {
143  guchar *result = NULL;
144  GString *str_buf = NULL;
145 
146  str_buf = g_string_new (NULL);
147  g_return_val_if_fail (str_buf, NULL);
148 
149  if (a_this) {
150  CRSelector const *cur = NULL;
151 
152  for (cur = a_this; cur; cur = cur->next) {
153  if (cur->simple_sel) {
154  guchar *tmp_str = NULL;
155 
156  tmp_str = cr_simple_sel_to_string
157  (cur->simple_sel);
158 
159  if (tmp_str) {
160  if (cur->prev)
161  g_string_append (str_buf,
162  ", ");
163 
164  g_string_append (str_buf, (const gchar *) tmp_str);
165 
166  g_free (tmp_str);
167  tmp_str = NULL;
168  }
169  }
170  }
171  }
172 
173  if (str_buf) {
174  result = (guchar *) str_buf->str;
175  g_string_free (str_buf, FALSE);
176  str_buf = NULL;
177  }
178 
179  return result;
180 }
181 
182 /**
183  * cr_selector_dump:
184  *
185  *@a_this: the current instance of #CRSelector.
186  *@a_fp: the destination file.
187  *
188  *Serializes the current instance of #CRSelector to a file.
189  */
190 void
191 cr_selector_dump (CRSelector const * a_this, FILE * a_fp)
192 {
193  guchar *tmp_buf = NULL;
194 
195  if (a_this) {
196  tmp_buf = cr_selector_to_string (a_this);
197  if (tmp_buf) {
198  fprintf (a_fp, "%s", tmp_buf);
199  g_free (tmp_buf);
200  tmp_buf = NULL;
201  }
202  }
203 }
204 
205 /**
206  * cr_selector_ref:
207  *
208  *@a_this: the current instance of #CRSelector.
209  *
210  *Increments the ref count of the current instance
211  *of #CRSelector.
212  */
213 void
215 {
216  g_return_if_fail (a_this);
217 
218  a_this->ref_count++;
219 }
220 
221 /**
222  * cr_selector_unref:
223  *
224  *@a_this: the current instance of #CRSelector.
225  *
226  *Decrements the ref count of the current instance of
227  *#CRSelector.
228  *If the ref count reaches zero, the current instance of
229  *#CRSelector is destroyed.
230  *
231  *Returns TRUE if this function destroyed the current instance
232  *of #CRSelector, FALSE otherwise.
233  */
234 gboolean
236 {
237  g_return_val_if_fail (a_this, FALSE);
238 
239  if (a_this->ref_count) {
240  a_this->ref_count--;
241  }
242 
243  if (a_this->ref_count == 0) {
244  cr_selector_destroy (a_this);
245  return TRUE;
246  }
247 
248  return FALSE;
249 }
250 
251 /**
252  * cr_selector_destroy:
253  *
254  *@a_this: the current instance of #CRSelector.
255  *
256  *Destroys the selector list.
257  */
258 void
260 {
261  CRSelector *cur = NULL;
262 
263  g_return_if_fail (a_this);
264 
265  /*
266  *go and get the list tail. In the same time, free
267  *all the simple selectors contained in the list.
268  */
269  for (cur = a_this; cur && cur->next; cur = cur->next) {
270  if (cur->simple_sel) {
271  cr_simple_sel_destroy (cur->simple_sel);
272  cur->simple_sel = NULL;
273  }
274  }
275 
276  if (cur) {
277  if (cur->simple_sel) {
278  cr_simple_sel_destroy (cur->simple_sel);
279  cur->simple_sel = NULL;
280  }
281  }
282 
283  /*in case the list has only one element */
284  if (cur && !cur->prev) {
285  g_free (cur);
286  return;
287  }
288 
289  /*walk backward the list and free each "next element" */
290  for (cur = cur->prev; cur && cur->prev; cur = cur->prev) {
291  if (cur->next) {
292  g_free (cur->next);
293  cur->next = NULL;
294  }
295  }
296 
297  if (!cur)
298  return;
299 
300  if (cur->next) {
301  g_free (cur->next);
302  cur->next = NULL;
303  }
304 
305  g_free (cur);
306 }
cr_selector_to_string
guchar * cr_selector_to_string(CRSelector const *a_this)
Definition: cr-selector.c:141
cr-selector.h
cr_selector_dump
void cr_selector_dump(CRSelector const *a_this, FILE *a_fp)
cr_selector_dump:
Definition: cr-selector.c:191
cr_parser_new_from_buf
CRParser * cr_parser_new_from_buf(guchar *a_buf, gulong a_len, enum CREncoding a_enc, gboolean a_free_buf)
cr_parser_new_from_buf: @a_buf: the buffer to parse.
Definition: cr-parser.c:2784
_CRParser
The implementation of the SAC parser.
Definition: cr-parser.h:51
cr_simple_sel_destroy
void cr_simple_sel_destroy(CRSimpleSel *a_this)
cr_simple_sel_destroy:
Definition: cr-simple-sel.c:304
cr_selector_parse_from_buf
CRSelector * cr_selector_parse_from_buf(const guchar *a_char_buf, enum CREncoding a_enc)
Definition: cr-selector.c:54
cr_selector_new
CRSelector * cr_selector_new(CRSimpleSel *a_simple_sel)
cr_selector_new:
Definition: cr-selector.c:39
cr_selector_prepend
CRSelector * cr_selector_prepend(CRSelector *a_this, CRSelector *a_new)
cr_selector_prepend:
Definition: cr-selector.c:106
cr_selector_destroy
void cr_selector_destroy(CRSelector *a_this)
cr_selector_destroy:
Definition: cr-selector.c:259
cr-parser.h
cr_selector_unref
gboolean cr_selector_unref(CRSelector *a_this)
cr_selector_unref:
Definition: cr-selector.c:235
cr_selector_ref
void cr_selector_ref(CRSelector *a_this)
cr_selector_ref:
Definition: cr-selector.c:214
cr_simple_sel_to_string
guchar * cr_simple_sel_to_string(CRSimpleSel const *a_this)
Definition: cr-simple-sel.c:103
_CRSimpleSel
The abstraction of a css2 simple selection list as defined by the right part of the "selector" produc...
Definition: cr-simple-sel.h:74
CREncoding
CREncoding
Encoding values.
Definition: cr-utils.h:84
CRSelector
typedefG_BEGIN_DECLS struct _CRSelector CRSelector
Definition: cr-selector.h:40
cr_selector_append
CRSelector * cr_selector_append(CRSelector *a_this, CRSelector *a_new)
cr_selector_append:
Definition: cr-selector.c:78
cr_utils_trace_info
#define cr_utils_trace_info(a_msg)
Traces an info message.
Definition: cr-utils.h:127
cr_selector_append_simple_sel
CRSelector * cr_selector_append_simple_sel(CRSelector *a_this, CRSimpleSel *a_simple_sel)
cr_selector_append_simple_sel:
Definition: cr-selector.c:129