Libcroco
|
00001 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ 00002 00003 /* 00004 * This file is part of The Croco Library 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of version 2.1 of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00018 * USA 00019 * 00020 * See COPYRIGHTS file for copyright information. 00021 */ 00022 00023 #include <string.h> 00024 #include "cr-selector.h" 00025 #include "cr-parser.h" 00026 00027 /** 00028 * cr_selector_new: 00029 * 00030 *@a_simple_sel: the initial simple selector list 00031 *of the current instance of #CRSelector. 00032 * 00033 *Creates a new instance of #CRSelector. 00034 * 00035 *Returns the newly built instance of #CRSelector, or 00036 *NULL in case of failure. 00037 */ 00038 CRSelector * 00039 cr_selector_new (CRSimpleSel * a_simple_sel) 00040 { 00041 CRSelector *result = NULL; 00042 00043 result = g_try_malloc (sizeof (CRSelector)); 00044 if (!result) { 00045 cr_utils_trace_info ("Out of memory"); 00046 return NULL; 00047 } 00048 memset (result, 0, sizeof (CRSelector)); 00049 result->simple_sel = a_simple_sel; 00050 return result; 00051 } 00052 00053 CRSelector * 00054 cr_selector_parse_from_buf (const guchar * a_char_buf, enum CREncoding a_enc) 00055 { 00056 CRParser *parser = NULL; 00057 00058 g_return_val_if_fail (a_char_buf, NULL); 00059 00060 parser = cr_parser_new_from_buf ((guchar*)a_char_buf, strlen (a_char_buf), 00061 a_enc, FALSE); 00062 g_return_val_if_fail (parser, NULL); 00063 00064 return NULL; 00065 } 00066 00067 /** 00068 * cr_selector_append: 00069 * 00070 *@a_this: the current instance of #CRSelector. 00071 *@a_new: the instance of #CRSelector to be appended. 00072 * 00073 *Appends a new instance of #CRSelector to the current selector list. 00074 * 00075 *Returns the new list. 00076 */ 00077 CRSelector * 00078 cr_selector_append (CRSelector * a_this, CRSelector * a_new) 00079 { 00080 CRSelector *cur = NULL; 00081 00082 if (!a_this) { 00083 return a_new; 00084 } 00085 00086 /*walk forward the list headed by a_this to get the list tail */ 00087 for (cur = a_this; cur && cur->next; cur = cur->next) ; 00088 00089 cur->next = a_new; 00090 a_new->prev = cur; 00091 00092 return a_this; 00093 } 00094 00095 /** 00096 * cr_selector_prepend: 00097 * 00098 *@a_this: the current instance of #CRSelector list. 00099 *@a_new: the instance of #CRSelector. 00100 * 00101 *Prepends an element to the #CRSelector list. 00102 * 00103 *Returns the new list. 00104 */ 00105 CRSelector * 00106 cr_selector_prepend (CRSelector * a_this, CRSelector * a_new) 00107 { 00108 CRSelector *cur = NULL; 00109 00110 a_new->next = a_this; 00111 a_this->prev = a_new; 00112 00113 for (cur = a_new; cur && cur->prev; cur = cur->prev) ; 00114 00115 return cur; 00116 } 00117 00118 /** 00119 * cr_selector_append_simple_sel: 00120 * 00121 *@a_this: the current instance of #CRSelector. 00122 *@a_simple_sel: the simple selector to append. 00123 * 00124 *append a simple selector to the current #CRSelector list. 00125 * 00126 *Returns the new list or NULL in case of failure. 00127 */ 00128 CRSelector * 00129 cr_selector_append_simple_sel (CRSelector * a_this, 00130 CRSimpleSel * a_simple_sel) 00131 { 00132 CRSelector *selector = NULL; 00133 00134 selector = cr_selector_new (a_simple_sel); 00135 g_return_val_if_fail (selector, NULL); 00136 00137 return cr_selector_append (a_this, selector); 00138 } 00139 00140 guchar * 00141 cr_selector_to_string (CRSelector const * a_this) 00142 { 00143 guchar *result = NULL; 00144 GString *str_buf = NULL; 00145 00146 str_buf = g_string_new (NULL); 00147 g_return_val_if_fail (str_buf, NULL); 00148 00149 if (a_this) { 00150 CRSelector const *cur = NULL; 00151 00152 for (cur = a_this; cur; cur = cur->next) { 00153 if (cur->simple_sel) { 00154 guchar *tmp_str = NULL; 00155 00156 tmp_str = cr_simple_sel_to_string 00157 (cur->simple_sel); 00158 00159 if (tmp_str) { 00160 if (cur->prev) 00161 g_string_append (str_buf, 00162 ", "); 00163 00164 g_string_append (str_buf, tmp_str); 00165 00166 g_free (tmp_str); 00167 tmp_str = NULL; 00168 } 00169 } 00170 } 00171 } 00172 00173 if (str_buf) { 00174 result = str_buf->str; 00175 g_string_free (str_buf, FALSE); 00176 str_buf = NULL; 00177 } 00178 00179 return result; 00180 } 00181 00182 /** 00183 * cr_selector_dump: 00184 * 00185 *@a_this: the current instance of #CRSelector. 00186 *@a_fp: the destination file. 00187 * 00188 *Serializes the current instance of #CRSelector to a file. 00189 */ 00190 void 00191 cr_selector_dump (CRSelector const * a_this, FILE * a_fp) 00192 { 00193 guchar *tmp_buf = NULL; 00194 00195 if (a_this) { 00196 tmp_buf = cr_selector_to_string (a_this); 00197 if (tmp_buf) { 00198 fprintf (a_fp, "%s", tmp_buf); 00199 g_free (tmp_buf); 00200 tmp_buf = NULL; 00201 } 00202 } 00203 } 00204 00205 /** 00206 * cr_selector_ref: 00207 * 00208 *@a_this: the current instance of #CRSelector. 00209 * 00210 *Increments the ref count of the current instance 00211 *of #CRSelector. 00212 */ 00213 void 00214 cr_selector_ref (CRSelector * a_this) 00215 { 00216 g_return_if_fail (a_this); 00217 00218 a_this->ref_count++; 00219 } 00220 00221 /** 00222 * cr_selector_unref: 00223 * 00224 *@a_this: the current instance of #CRSelector. 00225 * 00226 *Decrements the ref count of the current instance of 00227 *#CRSelector. 00228 *If the ref count reaches zero, the current instance of 00229 *#CRSelector is destroyed. 00230 * 00231 *Returns TRUE if this function destroyed the current instance 00232 *of #CRSelector, FALSE otherwise. 00233 */ 00234 gboolean 00235 cr_selector_unref (CRSelector * a_this) 00236 { 00237 g_return_val_if_fail (a_this, FALSE); 00238 00239 if (a_this->ref_count) { 00240 a_this->ref_count--; 00241 } 00242 00243 if (a_this->ref_count == 0) { 00244 cr_selector_destroy (a_this); 00245 return TRUE; 00246 } 00247 00248 return FALSE; 00249 } 00250 00251 /** 00252 * cr_selector_destroy: 00253 * 00254 *@a_this: the current instance of #CRSelector. 00255 * 00256 *Destroys the selector list. 00257 */ 00258 void 00259 cr_selector_destroy (CRSelector * a_this) 00260 { 00261 CRSelector *cur = NULL; 00262 00263 g_return_if_fail (a_this); 00264 00265 /* 00266 *go and get the list tail. In the same time, free 00267 *all the simple selectors contained in the list. 00268 */ 00269 for (cur = a_this; cur && cur->next; cur = cur->next) { 00270 if (cur->simple_sel) { 00271 cr_simple_sel_destroy (cur->simple_sel); 00272 cur->simple_sel = NULL; 00273 } 00274 } 00275 00276 if (cur) { 00277 if (cur->simple_sel) { 00278 cr_simple_sel_destroy (cur->simple_sel); 00279 cur->simple_sel = NULL; 00280 } 00281 } 00282 00283 /*in case the list has only one element */ 00284 if (cur && !cur->prev) { 00285 g_free (cur); 00286 return; 00287 } 00288 00289 /*walk backward the list and free each "next element" */ 00290 for (cur = cur->prev; cur && cur->prev; cur = cur->prev) { 00291 if (cur->next) { 00292 g_free (cur->next); 00293 cur->next = NULL; 00294 } 00295 } 00296 00297 if (!cur) 00298 return; 00299 00300 if (cur->next) { 00301 g_free (cur->next); 00302 cur->next = NULL; 00303 } 00304 00305 g_free (cur); 00306 }