1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
2 /* gdome-xml-str.c
3 *
4 * Copyright (C) 1999 Raph Levien <raph@acm.org>
5 * Copyright (C) 2000 Mathieu Lacage <mathieu@gnu.org>
6 * Copyright (C) 2001 Paolo Casarini <paolo@casarini.org>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26 #include <stdlib.h>
27 #include <string.h>
28 #include <libxml/tree.h>
29 #include <libxml/parser.h>
30 #include <libxml/xmlmemory.h>
31 #include "gdome.h"
32 #include "gdome-refdebug.h"
33 #include "gdome-xml-str.h"
34
35 void
gdome_xml_str_const_unref(GdomeDOMString * self)36 gdome_xml_str_const_unref (GdomeDOMString *self) {
37 #ifdef DEBUG_REFCNT
38 gdome_refdbg_delRef ((void *)self, GDOME_REFDBG_STR);
39 #endif
40 g_free(self);
41 }
42
43 void
gdome_xml_str_unref_own(GdomeDOMString * self)44 gdome_xml_str_unref_own (GdomeDOMString *self) {
45 g_free (self->str);
46 #ifdef DEBUG_REFCNT
47 gdome_refdbg_delRef ((void *)self, GDOME_REFDBG_STR);
48 #endif
49 g_free (self);
50 }
51
52 void
gdome_xml_str_unref_xml(GdomeDOMString * self)53 gdome_xml_str_unref_xml (GdomeDOMString *self) {
54 xmlFree (self->str);
55 #ifdef DEBUG_REFCNT
56 gdome_refdbg_delRef ((void *)self, GDOME_REFDBG_STR);
57 #endif
58 g_free (self);
59 }
60
61 /**
62 * gdome_xml_str_mkref:
63 * @str: a %NULL terminated string
64 *
65 * Creates a #GdomeDOMString from a statically allocated string.
66 * Returns: the new DOMString object.
67 */
68 GdomeDOMString *
gdome_xml_str_mkref(const gchar * str)69 gdome_xml_str_mkref (const gchar *str) {
70 GdomeDOMString *ds;
71
72 if (str == NULL)
73 return NULL;
74
75 ds = g_new (GdomeDOMString, 1);
76 #ifdef DEBUG_REFCNT
77 gdome_refdbg_addRef ((void *)ds, GDOME_REFDBG_STR);
78 #endif
79 ds->refcnt = 1;
80 ds->unref = gdome_xml_str_const_unref;
81 ds->str = (gchar *)str;
82 return ds;
83 }
84
85 /**
86 * gdome_xml_str_mkref_own:
87 * @str: a %NULL terminated string
88 *
89 * Creates a #GdomeDOMString from a dynamically allocated gchar buffer.
90 * Returns: the new DOMString object.
91 */
92 GdomeDOMString *
gdome_xml_str_mkref_own(gchar * str)93 gdome_xml_str_mkref_own (gchar *str) {
94 GdomeDOMString *ds;
95
96 if (str == NULL)
97 return NULL;
98
99 ds = g_new (GdomeDOMString, 1);
100 #ifdef DEBUG_REFCNT
101 gdome_refdbg_addRef ((void *)ds, GDOME_REFDBG_STR);
102 #endif
103 ds->refcnt = 1;
104 ds->unref = gdome_xml_str_unref_own;
105 ds->str = str;
106 return ds;
107 }
108
109 /**
110 * gdome_xml_str_mkref_xml:
111 * @str: a %NULL terminated string
112 *
113 * Creates a #GdomeDOMString from a xmlChar buffer already allocated by libxml.
114 * DEPRECATED
115 * Returns: the new DOMString object.
116 */
117 GdomeDOMString *
gdome_xml_str_mkref_xml(xmlChar * str)118 gdome_xml_str_mkref_xml (xmlChar *str) {
119 GdomeDOMString *ds;
120
121 if (str == NULL)
122 return NULL;
123
124 ds = g_new (GdomeDOMString, 1);
125 #ifdef DEBUG_REFCNT
126 gdome_refdbg_addRef ((void *)ds, GDOME_REFDBG_STR);
127 #endif
128 ds->refcnt = 1;
129 ds->unref = gdome_xml_str_unref_xml;
130 ds->str = str;
131 return ds;
132 }
133
134 /**
135 * gdome_xml_str_mkref_dup:
136 * @str: a %NULL terminated string
137 *
138 * Creates a #GdomeDOMString from a static or dynamically allocated gchar
139 * buffer, but a copy of the initializing string is done before construction.
140 * Returns: the new DOMString object.
141 */
142 GdomeDOMString *
gdome_xml_str_mkref_dup(const gchar * str)143 gdome_xml_str_mkref_dup (const gchar *str) {
144 GdomeDOMString *ds;
145
146 if (str == NULL)
147 return NULL;
148
149 ds = g_new (GdomeDOMString, 1);
150 #ifdef DEBUG_REFCNT
151 gdome_refdbg_addRef ((void *)ds, GDOME_REFDBG_STR);
152 #endif
153 ds->refcnt = 1;
154 ds->unref = gdome_xml_str_unref_own;
155 ds->str = g_strdup(str);
156 return ds;
157 }
158
159 /**
160 * gdome_xml_str_ref:
161 * @self: DOMString Object ref
162 *
163 * Increase the reference count of the specified #GdomeDOMString.
164 */
165 void
gdome_xml_str_ref(GdomeDOMString * self)166 gdome_xml_str_ref (GdomeDOMString *self) {
167 g_return_if_fail (self != NULL);
168
169 self->refcnt++;
170 }
171
172 /**
173 * gdome_xml_str_unref:
174 * @self: DOMString Object ref
175 *
176 * Decrease the reference count of the specified #GdomeDOMString. Free the
177 * structure if the object will have zero reference.
178 */
179 void
gdome_xml_str_unref(GdomeDOMString * self)180 gdome_xml_str_unref (GdomeDOMString *self) {
181 g_return_if_fail (self != NULL);
182
183 self->refcnt--;
184
185 if(self->refcnt == 0)
186 self->unref (self);
187 }
188
189 /**
190 * gdome_xml_str_equal:
191 * @self: DOMString Object ref
192 * @str: DOMString to be compared
193 *
194 * Returns: %TRUE if the strings are equal, %FALSE otherwise.
195 */
196 GdomeBoolean
gdome_xml_str_equal(GdomeDOMString * self,GdomeDOMString * str)197 gdome_xml_str_equal(GdomeDOMString *self, GdomeDOMString *str) {
198 g_return_val_if_fail (self != NULL, FALSE);
199 if (str == NULL)
200 return FALSE;
201 if(xmlStrEqual((xmlChar *)self->str, (xmlChar *)str->str))
202 return TRUE;
203 else
204 return FALSE;
205 }
206
207 /**
208 * gdome_xml_str_equalIgnoreCase:
209 * @self: DOMString Object ref
210 * @str: DOMString to be compared
211 *
212 * Returns: %TRUE if the strings are equal ignoring case, %FALSE otherwise.
213 */
214 GdomeBoolean
gdome_xml_str_equalIgnoreCase(GdomeDOMString * self,GdomeDOMString * str)215 gdome_xml_str_equalIgnoreCase(GdomeDOMString *self, GdomeDOMString *str) {
216 g_return_val_if_fail (self != NULL, FALSE);
217 if (str == NULL)
218 return FALSE;
219 if(!xmlStrcasecmp((xmlChar *)self->str, (xmlChar *)str->str))
220 return TRUE;
221 else
222 return FALSE;
223 }
224
225 /**
226 * gdome_xml_str_charAt:
227 * @self: DOMString Object ref
228 * @index: the index of the character wanted
229 *
230 * Returns: the @index -th character in the specified string
231 */
232 gchar
gdome_xml_str_charAt(GdomeDOMString * self,int index)233 gdome_xml_str_charAt (GdomeDOMString *self, int index)
234 {
235 g_return_val_if_fail (self != NULL, '\0');
236 if (index < 0 || index >= strlen (self->str)) {
237 g_warning ("gdome_str_charAt: out bound error\n");
238 return '\0';
239 }
240
241 return self->str[index];
242 }
243
244 /**
245 * gdome_xml_str_concat:
246 * @self: DOMString Object ref
247 * @str: DOMString to be appended
248 *
249 * Returns: a new #GdomeDOMString that is the concatenation of this string
250 * with @str. If @str is %NULL a new reference to this string is returned.
251 */
252 GdomeDOMString *
gdome_xml_str_concat(GdomeDOMString * self,GdomeDOMString * str)253 gdome_xml_str_concat (GdomeDOMString *self, GdomeDOMString *str)
254 {
255 gchar *ret;
256
257 g_return_val_if_fail (self != NULL, NULL);
258 if (str == NULL) {
259 self->refcnt++;
260 return self;
261 }
262
263 ret = g_strconcat (self->str, str->str, NULL);
264
265 return gdome_xml_str_mkref_own (ret);
266 }
267
268 /**
269 * gdome_xml_str_endsWith:
270 * @self: DOMString Object ref
271 * @suffix: DOMString to check
272 *
273 * Returns: %TRUE if this string ends with @str.
274 */
275 GdomeBoolean
gdome_xml_str_endsWith(GdomeDOMString * self,GdomeDOMString * suffix)276 gdome_xml_str_endsWith (GdomeDOMString *self, GdomeDOMString *suffix)
277 {
278 int len_self, len_str;
279
280 g_return_val_if_fail (self != NULL, FALSE);
281 if (suffix == NULL) {
282 return TRUE;
283 }
284 len_self = strlen (self->str);
285 len_str = strlen (suffix->str);
286
287 if (len_str > len_self)
288 return FALSE;
289
290 if(xmlStrEqual((xmlChar *)&(self->str[len_self-len_str]), (xmlChar *)suffix->str))
291 return TRUE;
292 else
293 return FALSE;
294 }
295
296 /**
297 * gdome_xml_str_isEmpty:
298 * @self: DOMString Object ref
299 *
300 * Returns: %TRUE if this string is empty, %FALSE otherwise.
301 */
302 GdomeBoolean
gdome_xml_str_isEmpty(GdomeDOMString * self)303 gdome_xml_str_isEmpty (GdomeDOMString *self)
304 {
305 if (self != NULL && strlen (self->str) > 0)
306 return TRUE;
307 return FALSE;
308 }
309
310 /**
311 * gdome_xml_str_length:
312 * @self: DOMString Object ref
313 *
314 * Returns: the length of this string.
315 */
316 int
gdome_xml_str_length(GdomeDOMString * self)317 gdome_xml_str_length (GdomeDOMString *self)
318 {
319 g_return_val_if_fail (self != NULL, 0);
320
321 return strlen (self->str);
322 }
323
324 /**
325 * gdome_xml_str_startsWith:
326 * @self: DOMString Object ref
327 * @prefix: DOMString to check
328 *
329 * Returns: %TRUE if this string starts with @str.
330 */
331 GdomeBoolean
gdome_xml_str_startsWith(GdomeDOMString * self,GdomeDOMString * prefix)332 gdome_xml_str_startsWith (GdomeDOMString *self, GdomeDOMString *prefix)
333 {
334 int len_self, len_str;
335
336 g_return_val_if_fail (self != NULL, FALSE);
337 if (prefix == NULL) {
338 return TRUE;
339 }
340 len_self = strlen (self->str);
341 len_str = strlen (prefix->str);
342
343 if (len_str > len_self)
344 return FALSE;
345
346 if(!xmlStrncmp((xmlChar *)self->str, (xmlChar *)prefix->str, len_str))
347 return TRUE;
348 else
349 return FALSE;
350 }
351