]> git.sur5r.net Git - glabels/blob - libglabels/lgl-xml.c
Imported Upstream version 3.0.0
[glabels] / libglabels / lgl-xml.c
1 /*
2  *  lgl-xml.c
3  *  Copyright (C) 2003-2010  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of libglabels.
6  *
7  *  libglabels is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU Lesser General Public License as published by
9  *  the Free Software Foundation, either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  libglabels is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public License
18  *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22
23 #include "lgl-xml.h"
24
25 #include <glib/gi18n.h>
26 #include <glib.h>
27 #include <string.h>
28
29 #include "libglabels-private.h"
30
31
32 /*========================================================*/
33 /* Private macros and constants.                          */
34 /*========================================================*/
35
36 /*========================================================*/
37 /* Private types.                                         */
38 /*========================================================*/
39
40 /*========================================================*/
41 /* Private globals.                                       */
42 /*========================================================*/
43
44 static lglUnits  default_units        = LGL_UNITS_POINT;
45
46
47 /****************************************************************************/
48
49 /**
50  * lgl_xml_get_prop_string:
51  * @node:        the libxml2 #xmlNodePtr of the node
52  * @property:    the property name
53  * @default_val: a default value to return if property not found
54  *
55  * Return value of property as a string.
56  *
57  * Returns: the property as a pointer to a gchar string.  This string should
58  *          be freed with g_free().
59  *
60  */
61 gchar *
62 lgl_xml_get_prop_string (xmlNodePtr   node,
63                          const gchar *property,
64                          const gchar *default_val)
65 {
66         gchar   *val;
67         xmlChar *string;
68
69         string = xmlGetProp (node, (xmlChar *)property);
70         if ( string != NULL )
71         {
72                 val = g_strdup ((gchar *)string);
73                 xmlFree (string);
74                 return val;
75         }
76
77         if (default_val)
78         {
79                 return g_strdup (default_val);
80         }
81
82         return NULL;
83 }
84
85
86 /**
87  * lgl_xml_get_prop_i18n_string:
88  * @node:        the libxml2 #xmlNodePtr of the node
89  * @property:    the property name
90  * @default_val: a default value to return if property not found
91  *
92  * Return value of a translatable property as a string.
93  *
94  * Returns: the property as a pointer to a gchar string.  This string should
95  *          be freed with g_free().
96  *
97  */
98 gchar *
99 lgl_xml_get_prop_i18n_string (xmlNodePtr   node,
100                               const gchar *property,
101                               const gchar *default_val)
102 {
103         gchar   *_property;
104         gchar   *val;
105         xmlChar *string;
106
107         _property = g_strdup_printf ("_%s", property);
108         string = xmlGetProp (node, (xmlChar *)_property);
109         g_free (_property);
110
111         if ( string != NULL )
112         {
113                 val = g_strdup (gettext ((char *)string));
114                 xmlFree (string);
115                 return val;
116         }
117
118         string = xmlGetProp (node, (xmlChar *)property);
119         if ( string != NULL )
120         {
121                 val = g_strdup ((gchar *)string);
122                 xmlFree (string);
123                 return val;
124         }
125
126         if (default_val)
127         {
128                 return g_strdup (default_val);
129         }
130
131         return NULL;
132 }
133
134
135 /**
136  * lgl_xml_get_prop_double:
137  * @node:        the libxml2 #xmlNodePtr of the node
138  * @property:    the property name
139  * @default_val: a default value to return if property not found
140  *
141  * Return value of property as a double.
142  *
143  * Returns: the property as a double.
144  *
145  */
146 gdouble
147 lgl_xml_get_prop_double (xmlNodePtr   node,
148                          const gchar *property,
149                          gdouble      default_val)
150 {
151         gdouble  val;
152         xmlChar *string;
153
154         string = xmlGetProp (node, (xmlChar *)property);
155         if ( string != NULL )
156         {
157                 val = g_strtod ((gchar *)string, NULL);
158                 xmlFree (string);
159                 return val;
160         }
161
162         return default_val;
163 }
164
165
166 /**
167  * lgl_xml_get_prop_boolean:
168  * @node:        the libxml2 #xmlNodePtr of the node
169  * @property:    the property name
170  * @default_val: a default value to return if property not found
171  *
172  * Return value of property as a boolean.
173  *
174  * Returns: the property as a boolean.
175  *
176  */
177 gboolean
178 lgl_xml_get_prop_boolean (xmlNodePtr   node,
179                          const gchar *property,
180                          gboolean     default_val)
181 {
182         gboolean  val;
183         xmlChar  *string;
184
185         string = xmlGetProp (node, (xmlChar *)property);
186         if ( string != NULL )
187         {
188                 val = !((xmlStrcasecmp (string, (xmlChar *)"false") == 0) ||
189                         xmlStrEqual (string, (xmlChar *)"0"));;
190                 xmlFree (string);
191                 return val;
192         }
193
194         return default_val;
195 }
196
197
198 /**
199  * lgl_xml_get_prop_int:
200  * @node:        the libxml2 #xmlNodePtr of the node
201  * @property:    the property name
202  * @default_val: a default value to return if property not found
203  *
204  * Return value of property as an integer.
205  *
206  * Returns: the property as an integer.
207  *
208  */
209 gint
210 lgl_xml_get_prop_int (xmlNodePtr   node,
211                       const gchar *property,
212                       gint         default_val)
213 {
214         gint     val;
215         xmlChar *string;
216
217         string = xmlGetProp (node, (xmlChar *)property);
218         if ( string != NULL )
219         {
220                 val = strtol ((char *)string, NULL, 0);
221                 xmlFree (string);
222                 return val;
223         }
224
225         return default_val;
226 }
227
228
229 /**
230  * lgl_xml_get_prop_uint:
231  * @node:        the libxml2 #xmlNodePtr of the node
232  * @property:    the property name
233  * @default_val: a default value to return if property not found
234  *
235  * Return value of property (usually formatted in hex) as an unsigned integer.
236  *
237  * Returns: the property as an unsigned integer.
238  *
239  */
240 guint
241 lgl_xml_get_prop_uint (xmlNodePtr   node,
242                        const gchar *property,
243                        guint        default_val)
244 {
245         guint    val;
246         xmlChar *string;
247
248         string = xmlGetProp (node, (xmlChar *)property);
249         if ( string != NULL )
250         {
251                 val = strtoul ((char *)string, NULL, 0);
252                 xmlFree (string);
253                 return val;
254         }
255
256         return default_val;
257 }
258
259
260 /**
261  * lgl_xml_get_prop_length:
262  * @node:        the libxml2 #xmlNodePtr of the node
263  * @property:    the property name
264  * @default_val: a default value to return if property not found
265  *
266  * Return value of a length property as a double, converting to internal
267  * units (points).  The property is expected to be formatted as a number
268  * followed by a units string.  If there is no units string, the length
269  * is assumed to be in points.  Valid units strings are "pt" for points,
270  * "in" for inches, "mm" for millimeters, "cm" for centimeters, and
271  * "pc" for picas.
272  *
273  * Returns: the length in points.
274  *
275  */
276 gdouble
277 lgl_xml_get_prop_length (xmlNodePtr   node,
278                          const gchar *property,
279                          gdouble      default_val)
280 {
281         gdouble  val;
282         xmlChar *string;
283         xmlChar *unit_id;
284         lglUnits units;
285
286         string = xmlGetProp (node, (xmlChar *)property);
287         if ( string != NULL )
288         {
289
290                 val = g_strtod ((gchar *)string, (gchar **)&unit_id);
291
292                 if (unit_id != string)
293                 {
294                         unit_id = (xmlChar *)g_strchug ((gchar *)unit_id);
295                         units = lgl_units_from_id ((gchar *)unit_id);
296                         if (units != LGL_UNITS_INVALID)
297                         {
298                                 val *= lgl_units_get_points_per_unit (units);
299                         }
300                         else
301                         {
302                                 g_message ("Line %ld, Node \"%s\", Property \"%s\": Unknown unit \"%s\", assuming points",
303                                            xmlGetLineNo (node), node->name, property, unit_id);
304                         }
305                 }
306                 else
307                 {
308                         val = 0.0;
309                 }
310
311                 xmlFree (string);
312                 return val;
313         }
314
315         return default_val;
316 }
317
318
319 /**
320  * lgl_xml_set_prop_string:
321  * @node:        the libxml2 #xmlNodePtr of the node
322  * @property:    the property name
323  * @val:         the value to set
324  *
325  * Set a property from a string.
326  *
327  */
328 void
329 lgl_xml_set_prop_string (xmlNodePtr    node,
330                          const gchar  *property,
331                          const gchar  *val)
332 {
333         if (val != NULL)
334         {
335                 xmlSetProp (node, (xmlChar *)property, (xmlChar *)val);
336         }
337 }
338
339
340 /**
341  * lgl_xml_set_prop_double:
342  * @node:        the libxml2 #xmlNodePtr of the node
343  * @property:    the property name
344  * @val:         the value to set
345  *
346  * Set a property from a double.
347  *
348  */
349 void
350 lgl_xml_set_prop_double (xmlNodePtr    node,
351                          const gchar  *property,
352                          gdouble       val)
353 {
354         gchar  *string, buffer[G_ASCII_DTOSTR_BUF_SIZE];
355
356         /* Guarantee "C" locale by use of g_ascii_formatd */
357         string = g_ascii_formatd (buffer, G_ASCII_DTOSTR_BUF_SIZE, "%g", val);
358
359         xmlSetProp (node, (xmlChar *)property, (xmlChar *)string);
360 }
361
362
363 /**
364  * lgl_xml_set_prop_boolean:
365  * @node:        the libxml2 #xmlNodePtr of the node
366  * @property:    the property name
367  * @val:         the value to set
368  *
369  * Set a property from a boolean.
370  *
371  */
372 void
373 lgl_xml_set_prop_boolean (xmlNodePtr    node,
374                           const gchar  *property,
375                           gboolean      val)
376 {
377         xmlSetProp (node, (xmlChar *)property, (xmlChar *)(val ? "True" : "False"));
378 }
379
380 /**
381  * lgl_xml_set_prop_int:
382  * @node:        the libxml2 #xmlNodePtr of the node
383  * @property:    the property name
384  * @val:         the value to set
385  *
386  * Set a property from an integer.
387  *
388  */
389 void
390 lgl_xml_set_prop_int (xmlNodePtr    node,
391                       const gchar  *property,
392                       gint          val)
393 {
394         gchar  *string;
395
396         string = g_strdup_printf ("%d", val);
397         xmlSetProp (node, (xmlChar *)property, (xmlChar *)string);
398         g_free (string);
399 }
400
401 /**
402  * lgl_xml_set_prop_uint_hex:
403  * @node:        the libxml2 #xmlNodePtr of the node
404  * @property:    the property name
405  * @val:         the value to set
406  *
407  * Set a property from an unsigned integer and format in hex.
408  *
409  */
410 void
411 lgl_xml_set_prop_uint_hex (xmlNodePtr    node,
412                            const gchar  *property,
413                            guint         val)
414 {
415         gchar  *string;
416
417         string = g_strdup_printf ("0x%08x", val);
418         xmlSetProp (node, (xmlChar *)property, (xmlChar *)string);
419         g_free (string);
420 }
421
422 /**
423  * lgl_xml_set_prop_length:
424  * @node:        the libxml2 #xmlNodePtr of the node
425  * @property:    the property name
426  * @val:         the length to set in internal units (points)
427  *
428  * Set a property from a length, performing any necessary conversion.
429  * Length properties are formatted as a number followed by a units string.
430  * The units of the formatted property is determined by the most recent call to
431  * lgl_xml_set_default_units().
432  *
433  */
434 void
435 lgl_xml_set_prop_length (xmlNodePtr    node,
436                          const gchar  *property,
437                          gdouble       val)
438 {
439         gchar  *string, buffer[G_ASCII_DTOSTR_BUF_SIZE];
440         gchar  *string_unit;
441
442         /* Convert to default units */
443         val *= lgl_units_get_units_per_point (default_units);
444
445         /* Guarantee "C" locale by use of g_ascii_formatd */
446         string = g_ascii_formatd (buffer, G_ASCII_DTOSTR_BUF_SIZE, "%g", val);
447
448         string_unit = g_strdup_printf ("%s%s", string, lgl_units_get_id (default_units));
449         xmlSetProp (node, (xmlChar *)property, (xmlChar *)string_unit);
450         g_free (string_unit);
451 }
452
453 /**
454  * lgl_xml_is_node
455  * @node:        the libxml2 #xmlNodePtr of the node
456  * @name    :    the node name
457  *
458  * Test if a node name matches given name.
459  *
460  * Returns: TRUE if the name of the node matches.  Otherwise FALSE.
461  *
462  */
463 gboolean
464 lgl_xml_is_node (xmlNodePtr   node,
465                  const gchar *name)
466 {
467         return xmlStrEqual (node->name, (xmlChar *)name);
468 }
469
470
471 /**
472  * lgl_xml_get_node_content
473  * @node:        the libxml2 #xmlNodePtr of the node
474  *
475  * Get the content of a node.
476  *
477  * Returns: the property as a pointer to a gchar string.  This string should
478  *          be freed with g_free().
479  */
480 gchar *
481 lgl_xml_get_node_content (xmlNodePtr   node)
482 {
483         xmlChar *xml_content;
484         gchar   *g_content;
485
486         xml_content = xmlNodeGetContent (node);
487
488         if (xml_content != NULL)
489         {
490                 g_content = g_strdup ((gchar *)xml_content);
491                 xmlFree (xml_content);
492                 return g_content;
493         }
494
495         return NULL;
496 }
497
498
499 /**
500  * lgl_xml_set_default_units:
501  * @units:       default units selection (#lglUnits)
502  *
503  * Set the default units when formatting lengths.  See
504  * lgl_xml_set_prop_length().
505  *
506  */
507 void
508 lgl_xml_set_default_units (lglUnits   units)
509 {
510         g_return_if_fail ((units >= LGL_UNITS_FIRST) && (units <= LGL_UNITS_LAST));
511
512         default_units = units;
513 }
514
515
516
517 /*
518  * Local Variables:       -- emacs
519  * mode: C                -- emacs
520  * c-basic-offset: 8      -- emacs
521  * tab-width: 8           -- emacs
522  * indent-tabs-mode: nil  -- emacs
523  * End:                   -- emacs
524  */