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