1/* -*- Mode: C; indent-tabs-mode: ni; 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 <config.h> 24#include <string.h> 25#include "cr-selector.h" 26#include "cr-parser.h" 27 28/** 29 * cr_selector_new: 30 * 31 *@a_simple_sel: the initial simple selector list 32 *of the current instance of #CRSelector. 33 * 34 *Creates a new instance of #CRSelector. 35 * 36 *Returns the newly built instance of #CRSelector, or 37 *NULL in case of failure. 38 */ 39CRSelector * 40cr_selector_new (CRSimpleSel * a_simple_sel) 41{ 42 CRSelector *result = NULL; 43 44 result = g_try_malloc (sizeof (CRSelector)); 45 if (!result) { 46 cr_utils_trace_info ("Out of memory"); 47 return NULL; 48 } 49 memset (result, 0, sizeof (CRSelector)); 50 result->simple_sel = a_simple_sel; 51 return result; 52} 53 54CRSelector * 55cr_selector_parse_from_buf (const guchar * a_char_buf, enum CREncoding a_enc) 56{ 57 CRParser *parser = NULL; 58 59 g_return_val_if_fail (a_char_buf, NULL); 60 61 parser = cr_parser_new_from_buf ((guchar*)a_char_buf, strlen (a_char_buf), 62 a_enc, FALSE); 63 g_return_val_if_fail (parser, NULL); 64 65 return NULL; 66} 67 68/** 69 * cr_selector_append: 70 * 71 *@a_this: the current instance of #CRSelector. 72 *@a_new: the instance of #CRSelector to be appended. 73 * 74 *Appends a new instance of #CRSelector to the current selector list. 75 * 76 *Returns the new list. 77 */ 78CRSelector * 79cr_selector_append (CRSelector * a_this, CRSelector * a_new) 80{ 81 CRSelector *cur = NULL; 82 83 if (!a_this) { 84 return a_new; 85 } 86 87 /*walk forward the list headed by a_this to get the list tail */ 88 for (cur = a_this; cur && cur->next; cur = cur->next) ; 89 90 cur->next = a_new; 91 a_new->prev = cur; 92 93 return a_this; 94} 95 96/** 97 * cr_selector_prepend: 98 * 99 *@a_this: the current instance of #CRSelector list. 100 *@a_new: the instance of #CRSelector. 101 * 102 *Prepends an element to the #CRSelector list. 103 * 104 *Returns the new list. 105 */ 106CRSelector * 107cr_selector_prepend (CRSelector * a_this, CRSelector * a_new) 108{ 109 CRSelector *cur = NULL; 110 111 a_new->next = a_this; 112 a_this->prev = a_new; 113 114 for (cur = a_new; cur && cur->prev; cur = cur->prev) ; 115 116 return cur; 117} 118 119/** 120 * cr_selector_append_simple_sel: 121 * 122 *@a_this: the current instance of #CRSelector. 123 *@a_simple_sel: the simple selector to append. 124 * 125 *append a simple selector to the current #CRSelector list. 126 * 127 *Returns the new list or NULL in case of failure. 128 */ 129CRSelector * 130cr_selector_append_simple_sel (CRSelector * a_this, 131 CRSimpleSel * a_simple_sel) 132{ 133 CRSelector *selector = NULL; 134 135 selector = cr_selector_new (a_simple_sel); 136 g_return_val_if_fail (selector, NULL); 137 138 return cr_selector_append (a_this, selector); 139} 140 141guchar * 142cr_selector_to_string (CRSelector * a_this) 143{ 144 guchar *result = NULL; 145 GString *str_buf = NULL; 146 147 str_buf = g_string_new (NULL); 148 g_return_val_if_fail (str_buf, NULL); 149 150 if (a_this) { 151 CRSelector *cur = NULL; 152 153 for (cur = a_this; cur; cur = cur->next) { 154 if (cur->simple_sel) { 155 guchar *tmp_str = NULL; 156 157 tmp_str = cr_simple_sel_to_string 158 (cur->simple_sel); 159 160 if (tmp_str) { 161 if (cur->prev) 162 g_string_append (str_buf, 163 ", "); 164 165 g_string_append (str_buf, tmp_str); 166 167 g_free (tmp_str); 168 tmp_str = NULL; 169 } 170 } 171 } 172 } 173 174 if (str_buf) { 175 result = str_buf->str; 176 g_string_free (str_buf, FALSE); 177 str_buf = NULL; 178 } 179 180 return result; 181} 182 183/** 184 * cr_selector_dump: 185 * 186 *@a_this: the current instance of #CRSelector. 187 *@a_fp: the destination file. 188 * 189 *Serializes the current instance of #CRSelector to a file. 190 */ 191void 192cr_selector_dump (CRSelector * a_this, FILE * a_fp) 193{ 194 guchar *tmp_buf = NULL; 195 196 if (a_this) { 197 tmp_buf = cr_selector_to_string (a_this); 198 if (tmp_buf) { 199 fprintf (a_fp, "%s", tmp_buf); 200 g_free (tmp_buf); 201 tmp_buf = NULL; 202 } 203 } 204} 205 206/** 207 * cr_selector_ref: 208 * 209 *@a_this: the current instance of #CRSelector. 210 * 211 *Increments the ref count of the current instance 212 *of #CRSelector. 213 */ 214void 215cr_selector_ref (CRSelector * a_this) 216{ 217 g_return_if_fail (a_this); 218 219 a_this->ref_count++; 220} 221 222/** 223 * cr_selector_unref: 224 * 225 *@a_this: the current instance of #CRSelector. 226 * 227 *Decrements the ref count of the current instance of 228 *#CRSelector. 229 *If the ref count reaches zero, the current instance of 230 *#CRSelector is destroyed. 231 * 232 *Returns TRUE if this function destroyed the current instance 233 *of #CRSelector, FALSE otherwise. 234 */ 235gboolean 236cr_selector_unref (CRSelector * a_this) 237{ 238 g_return_val_if_fail (a_this, FALSE); 239 240 if (a_this->ref_count) { 241 a_this->ref_count--; 242 } 243 244 if (a_this->ref_count == 0) { 245 cr_selector_destroy (a_this); 246 return TRUE; 247 } 248 249 return FALSE; 250} 251 252/** 253 * cr_selector_destroy: 254 * 255 *@a_this: the current instance of #CRSelector. 256 * 257 *Destroys the selector list. 258 */ 259void 260cr_selector_destroy (CRSelector * a_this) 261{ 262 CRSelector *cur = NULL; 263 264 g_return_if_fail (a_this); 265 266 /* 267 *go and get the list tail. In the same time, free 268 *all the simple selectors contained in the list. 269 */ 270 for (cur = a_this; cur && cur->next; cur = cur->next) { 271 if (cur->simple_sel) { 272 cr_simple_sel_destroy (cur->simple_sel); 273 cur->simple_sel = NULL; 274 } 275 } 276 277 if (cur) { 278 if (cur->simple_sel) { 279 cr_simple_sel_destroy (cur->simple_sel); 280 cur->simple_sel = NULL; 281 } 282 } 283 284 /*in case the list has only one element */ 285 if (cur && !cur->prev) { 286 g_free (cur); 287 return; 288 } 289 290 /*walk backward the list and free each "next element" */ 291 for (cur = cur->prev; cur && cur->prev; cur = cur->prev) { 292 if (cur->next) { 293 g_free (cur->next); 294 cur->next = NULL; 295 } 296 } 297 298 if (!cur) 299 return; 300 301 if (cur->next) { 302 g_free (cur->next); 303 cur->next = NULL; 304 } 305 306 g_free (cur); 307} 308