Start documenting objects.
[mmediamanager.git] / libmmanager / mm-string-utils.c
blob4d18fad846c30569d7a5daa781dec42d87dddfac
1 /* MManager - a Desktop wide manager for multimedia applications.
3 * Copyright (C) 2008 Cosimo Cecchi <cosimoc@gnome.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library 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 GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
21 #include <glib.h>
22 #include <string.h>
23 #include <libxml/tree.h>
24 #include <libxml/xmlwriter.h>
25 #include <libxml/xmlreader.h>
26 #include <libxml/xmlerror.h>
27 #include "mm-string-utils.h"
28 #include "mm-utils.h"
29 #include "mm-hit.h"
30 #include "mm-error.h"
32 typedef struct {
33 MMComparisionOperator op;
34 const char *string;
35 } OperatorGrid;
37 typedef struct {
38 xmlTextWriterPtr writer;
39 GError **error;
40 } SerializeData;
42 static OperatorGrid operator_grid[] =
44 { MM_COMP_EQUAL, "EQ" },
45 { MM_COMP_GREATER, "GR" },
46 { MM_COMP_GREATER_EQUAL, "GRQ" },
47 { MM_COMP_LESS, "LS" },
48 { MM_COMP_LESS_EQUAL, "LSQ" },
49 { MM_COMP_NONE, "" }
52 static void
53 set_error (int res, GError **error, const char *obj_name)
55 xmlErrorPtr xml_error;
57 if (res == -1) {
58 xml_error = xmlGetLastError ();
59 g_set_error (error, MM_XML_ERROR_QUARK, MM_XML_ERROR_UNSERIALIZE_FAILED,
60 "Error while parsing the serialized xml %s: %s",
61 obj_name, (xml_error != NULL) ? (xml_error->message) : "");
62 } else if (res == 0) {
63 g_set_error (error, MM_XML_ERROR_QUARK, MM_XML_ERROR_UNEXPECTED_EOF,
64 "Error while parsing the serialized xml %s: unexpected "
65 "end of the xml buffer.", obj_name);
69 static void
70 set_hit_error (int res, GError **error)
72 set_error (res, error, "Hit");
75 static void
76 set_hit_collection_error (int res, GError **error)
78 set_error (res, error, "HitCollection");
81 static void
82 set_value_error (int res, GError **error)
84 set_error (res, error, "Value");
87 static void
88 set_filter_param_error (int res, GError **error)
90 set_error (res, error, "FilterParam");
93 static void
94 set_operator_error (int res, GError **error)
96 set_error (res, error, "ComparisionOperator");
99 static void
100 set_filter_error (int res, GError **error)
102 set_error (res, error, "Filter");
105 static void
106 set_pair_error (int res, GError **error)
108 set_error (res, error, "Pair");
111 static void
112 set_attribute_error (int res, GError **error)
114 set_error (res, error, "Attribute");
117 static void
118 serialize_value (xmlTextWriterPtr writer, GValue *v, GError **error)
120 xmlChar *safe;
121 int res;
122 char *ret = NULL;
124 ret = mm_gvalue_to_string (v);
125 if (!ret) {
126 return;
129 safe = xmlCharStrdup (ret);
130 g_free (ret);
132 res = xmlTextWriterWriteElement (writer, BAD_CAST ("value"), safe);
133 g_free (safe);
134 if (res == -1) {
135 set_value_error (res, error);
136 return;
140 static void
141 serialize_op (xmlTextWriterPtr writer, MMComparisionOperator op, GError **error)
143 int idx, res;
144 xmlChar *str = NULL;
146 for (idx = 0; idx < G_N_ELEMENTS (operator_grid); idx++) {
147 if (op == operator_grid[idx].op) {
148 str = xmlCharStrdup (operator_grid[idx].string);
152 if (str) {
153 res = xmlTextWriterWriteElement (writer, BAD_CAST ("op"), str);
154 g_free (str);
155 if (res == -1) {
156 set_operator_error (res, error);
157 return;
162 static void
163 serialize_attribute (xmlTextWriterPtr writer,
164 MMAttribute *attribute,
165 GError **error)
167 xmlChar *safe_str;
168 int res;
170 res = xmlTextWriterStartElement (writer, BAD_CAST ("attribute"));
171 if (res == -1) {
172 set_attribute_error (res, error);
173 return;
176 safe_str = xmlCharStrdup (mm_attribute_get_id (attribute));
177 res = xmlTextWriterWriteAttribute (writer, BAD_CAST ("id"), safe_str);
178 g_free (safe_str);
179 if (res == -1) {
180 set_attribute_error (res, error);
181 return;
184 safe_str = xmlCharStrdup (mm_attribute_get_name (attribute));
185 xmlTextWriterWriteAttribute (writer, BAD_CAST ("name"), safe_str);
186 g_free (safe_str);
187 if (res == -1) {
188 set_attribute_error (res, error);
189 return;
192 safe_str = xmlCharStrdup (mm_attribute_get_description (attribute));
193 xmlTextWriterWriteAttribute (writer, BAD_CAST ("description"), safe_str);
194 g_free (safe_str);
195 if (res == -1) {
196 set_attribute_error (res, error);
197 return;
200 res = xmlTextWriterWriteAttribute (writer, BAD_CAST ("type"),
201 BAD_CAST (g_type_name (mm_attribute_get_value_type (attribute))));
202 if (res == -1) {
203 set_attribute_error (res, error);
204 return;
207 /* close "attribute" */
208 res = xmlTextWriterEndElement (writer);
209 if (res == -1) {
210 set_attribute_error (res, error);
211 return;
215 static void
216 serialize_filter_param (MMFilterParam *fp,
217 SerializeData *data)
219 MMAttribute *attribute;
220 GValue *val;
221 MMComparisionOperator op;
222 int res;
223 xmlTextWriterPtr writer = data->writer;
224 GError **error = data->error;
226 attribute = mm_filter_param_get_attribute (fp);
227 val = mm_filter_param_get_value (fp);
228 op = mm_filter_param_get_operator (fp);
230 res = xmlTextWriterStartElement (writer, BAD_CAST ("filter-param"));
231 if (res == -1) {
232 set_filter_param_error (res, error);
233 return;
236 serialize_attribute (writer, attribute, error);
237 if (*error) {
238 return;
240 serialize_value (writer, val, error);
241 if (*error) {
242 return;
244 serialize_op (writer, op, error);
245 if (*error) {
246 return;
249 /* close "filter-param" */
250 res = xmlTextWriterEndElement (writer);
251 if (res == -1) {
252 set_filter_param_error (res, error);
253 return;
257 static void
258 unserialize_operator (xmlTextReaderPtr reader, MMComparisionOperator *op,
259 GError **error)
261 const xmlChar * op_string;
262 gboolean found = FALSE;
263 int idx, res;
265 /* we should be on <op> */
266 if (xmlStrcmp (xmlTextReaderConstName (reader), BAD_CAST ("op")) != 0) {
267 g_set_error (error, MM_XML_ERROR_QUARK, MM_XML_ERROR_UNEXPECTED_NODE,
268 "Error while parsing the serialized xml opeator: the xml reader "
269 "does not point to a ComparisionOperator");
270 return;
273 /* move on to the content */
274 res = xmlTextReaderRead (reader);
275 if (res <= 0) {
276 set_operator_error (res, error);
277 return;
280 op_string = xmlTextReaderConstValue (reader);
281 for (idx = 0; idx < G_N_ELEMENTS (operator_grid); idx++) {
282 if (xmlStrcmp (op_string, BAD_CAST (operator_grid[idx].string)) == 0) {
283 found = TRUE;
284 break;
288 /* move to </op> */
289 res = xmlTextReaderRead (reader);
290 if (res <= 0) {
291 set_operator_error (res, error);
292 return;
295 if (found) {
296 *op = operator_grid[idx].op;
300 static void
301 unserialize_value (xmlTextReaderPtr reader, GValue *v, GError **error)
303 int res;
304 GType type;
305 const char *val_string;
306 gboolean result;
308 /* we should be on <value> */
309 if (xmlStrcmp (xmlTextReaderConstName (reader), BAD_CAST ("value")) != 0) {
310 g_set_error (error, MM_XML_ERROR_QUARK, MM_XML_ERROR_UNEXPECTED_NODE,
311 "Error while parsing the serialized xml value: the xml reader "
312 " does not point to a value");
313 return;
316 /* move on to the content node */
317 res = xmlTextReaderRead (reader);
318 if (res <= 0) {
319 set_value_error (res, error);
320 return;
323 type = G_VALUE_TYPE (v);
324 val_string = (const char *) xmlTextReaderConstValue (reader);
326 result = mm_gvalue_from_string (val_string, type, v);
327 if (!result) {
328 g_set_error (error, MM_XML_ERROR_QUARK, MM_XML_ERROR_UNKNOWN_GTYPE,
329 "Can't convert the string to a value: unhandled type");
330 return;
333 /* move over </value> */
334 res = xmlTextReaderRead (reader);
335 if (res <= 0) {
336 set_value_error (res, error);
337 g_value_unset (v);
338 g_free (v);
339 v = NULL;
343 static void
344 unserialize_attribute (xmlTextReaderPtr reader, MMAttribute **attribute, GError **error)
346 xmlChar *id, *name, *desc, *type_name;
347 GType type;
349 /* we should be on <attribute> */
350 if (xmlStrcmp (xmlTextReaderConstName (reader), BAD_CAST ("attribute")) != 0) {
351 g_set_error (error, MM_XML_ERROR_QUARK, MM_XML_ERROR_UNEXPECTED_NODE,
352 "Error while parsing the serialized xml attribute: the xml reader"
353 " does not point to an attribute.");
354 return;
357 id = xmlTextReaderGetAttribute (reader, BAD_CAST ("id"));
358 name = xmlTextReaderGetAttribute (reader, BAD_CAST ("name"));
359 desc = xmlTextReaderGetAttribute (reader, BAD_CAST ("desc"));
360 type_name = xmlTextReaderGetAttribute (reader, BAD_CAST ("type"));
362 type = g_type_from_name ((const char *) type_name);
363 if (type == 0) {
364 g_set_error (error, MM_XML_ERROR_QUARK, MM_XML_ERROR_UNKNOWN_GTYPE,
365 "Error while parsing the serialized xml attribute: cannot get a GType"
366 " for the name %s.", (const char *) type_name);
367 goto out;
370 *attribute = mm_attribute_new (type,
371 (const char *) id,
372 (const char *) name,
373 (const char *) desc);
374 out:
375 g_free (id);
376 g_free (name);
377 g_free (desc);
378 g_free (type_name);
381 static MMFilterParam *
382 unserialize_filter_param (xmlTextReaderPtr reader, GError **error)
384 int res;
385 MMAttribute *attribute = NULL;
386 MMComparisionOperator op = MM_COMP_NONE;
387 GValue *val = NULL;
388 MMFilterParam *fp = NULL;
390 res = xmlTextReaderRead (reader);
391 if (res <= 0) {
392 set_filter_param_error (res, error);
393 goto out;
396 /* we're either on <attribute> or </filter-param> if the object is empty */
397 while (!((xmlTextReaderNodeType (reader) == XML_READER_TYPE_END_ELEMENT) &&
398 xmlStrcmp (xmlTextReaderConstName (reader), BAD_CAST ("filter-param")) == 0) && res > 0) {
399 unserialize_attribute (reader, &attribute, error);
400 if (*error) {
401 goto out;
404 res = xmlTextReaderRead (reader);
405 if (res <= 0) {
406 set_filter_param_error (res, error);
407 goto out;
409 /* we're now on <value> */
410 val = mm_create_gvalue_for_attribute (attribute);
411 unserialize_value (reader, val, error);
412 if (*error) {
413 goto out;
416 res = xmlTextReaderRead (reader);
417 if (res <= 0) {
418 set_filter_param_error (res, error);
419 goto out;
421 /* we're now on <op> */
422 unserialize_operator (reader, &op, error);
423 if (*error) {
424 goto out;
427 /* move after </op> */
428 res = xmlTextReaderRead (reader);
429 if (res <= 0) {
430 set_filter_param_error (res, error);
431 goto out;
435 /* if we're here, everything in the unserialize sub-operations went well */
436 fp = mm_filter_param_new (attribute, val, op);
438 out:
439 if (val) {
440 g_value_unset (val);
441 g_free (val);
444 return fp;
447 static void
448 serialize_pair (MMAttribute *attr,
449 GValue *val,
450 SerializeData *pair_data)
452 xmlTextWriterPtr writer = pair_data->writer;
453 GError **error = pair_data->error;
454 int res;
456 if (*error) {
457 /* an error occurred in a previous iteration of this function, don't do
458 * anything.
460 return;
463 xmlTextWriterStartElement (writer, BAD_CAST ("pair"));
464 serialize_attribute (writer, attr, error);
465 if (*error) {
466 return;
469 serialize_value (writer, val, error);
470 if (*error) {
471 return;
474 /* end "pair" */
475 res = xmlTextWriterEndElement (writer);
476 if (res == -1) {
477 set_pair_error (res, error);
481 static MMHit *
482 unserialize_hit (xmlTextReaderPtr reader, GError **error)
484 int res;
485 MMAttribute *attribute = NULL;
486 GValue *v;
487 MMHit *hit = NULL;
489 hit = g_object_new (MM_TYPE_HIT, NULL);
491 do {
492 /* skip <pair> */
493 res = xmlTextReaderRead (reader);
494 if (res <= 0) {
495 set_hit_error (res, error);
496 g_object_unref (hit);
497 hit = NULL;
498 break;
500 res = xmlTextReaderRead (reader);
501 /* now we should be on "attribute" */
502 if (res <= 0) {
503 set_hit_error (res, error);
504 g_object_unref (hit);
505 hit = NULL;
506 break;
508 unserialize_attribute (reader, &attribute, error);
509 if (*error) {
510 g_object_unref (hit);
511 hit = NULL;
512 break;
514 res = xmlTextReaderRead (reader);
515 /* we're now on "value" */
516 if (res <= 0) {
517 set_hit_error (res, error);
518 g_object_unref (hit);
519 hit = NULL;
520 break;
523 v = mm_create_gvalue_for_attribute (attribute);
524 unserialize_value (reader, v, error);
525 if (*error) {
526 g_object_unref (hit);
527 hit = NULL;
528 break;
531 mm_hit_set_value (hit, attribute, v);
533 res = xmlTextReaderRead (reader);
534 /* now we're on </pair> */
535 if (res <= 0) {
536 set_hit_error (res, error);
537 g_object_unref (hit);
538 hit = NULL;
539 break;
542 res = xmlTextReaderRead (reader);
543 if (res <= 0) {
544 set_hit_error (res, error);
545 g_object_unref (hit);
546 hit = NULL;
547 break;
549 /* now we're either on <pair> again or </hit>. we must end they cycle
550 * on </hit>.
552 } while (!((xmlTextReaderNodeType (reader) == XML_READER_TYPE_END_ELEMENT) &&
553 xmlStrcmp (xmlTextReaderConstName (reader), BAD_CAST ("hit"))));
555 return hit;
558 /* public functions */
561 * mm_filter_serialize:
562 * @filter: a #MMFilter object.
563 * @error: a #GError.
565 * Builds a serialized XML version of @filter.
567 * Return value: a newly allocated string buffer containing the serialized
568 * #MMFilter.
571 char *
572 mm_filter_serialize (MMFilter *filter, GError **error)
574 char *serialized = NULL;
575 xmlBufferPtr buffer;
576 xmlTextWriterPtr writer;
577 GList *filter_params;
578 SerializeData *fp_data;
579 int res;
581 buffer = xmlBufferCreate ();
582 writer = xmlNewTextWriterMemory (buffer, 0);
584 res = xmlTextWriterStartDocument (writer, NULL, NULL, NULL);
585 if (res == -1) {
586 set_filter_error (res, error);
587 goto out;
590 res = xmlTextWriterStartElement (writer, BAD_CAST ("filter"));
591 if (res == -1) {
592 set_filter_error (res, error);
593 goto out;
596 filter_params = mm_filter_get_filtering_params (filter);
597 fp_data = g_new0 (SerializeData, 1);
598 fp_data->writer = writer;
599 fp_data->error = error;
600 g_list_foreach (filter_params, (GFunc) serialize_filter_param, fp_data);
601 g_free (fp_data);
602 if (*error) {
603 goto out;
606 /* close "filter" */
607 res = xmlTextWriterEndElement (writer);
608 if (res == -1) {
609 set_filter_error (res, error);
610 goto out;
613 res = xmlTextWriterEndDocument (writer);
614 if (res == -1) {
615 set_filter_error (res, error);
616 goto out;
619 /* everything went well */
620 serialized = g_strdup ((char *) xmlBufferContent (buffer));
622 out:
623 xmlFreeTextWriter (writer);
624 xmlBufferFree (buffer);
626 return serialized;
630 * mm_hit_collection_serialize:
631 * @hc: a #MMHitCollection object.
632 * @error: a #GError.
634 * Builds a serialized XML version of the #MMHitCollection.
636 * Return value: a newly allocated string buffer containing the serialized
637 * #MMHitCollection.
640 char *
641 mm_hit_collection_serialize (MMHitCollection *hc, GError **error)
643 char *serialized = NULL;
644 int res;
645 xmlBufferPtr buffer;
646 xmlTextWriterPtr writer;
647 MMHit *hit;
648 GHashTable *attrs_and_values;
649 SerializeData *pair_data;
651 buffer = xmlBufferCreate ();
652 writer = xmlNewTextWriterMemory (buffer, 0);
654 res = xmlTextWriterStartDocument (writer, NULL, NULL, NULL);
655 if (res == -1) {
656 set_hit_collection_error (res, error);
657 goto out;
660 res = xmlTextWriterStartElement (writer, BAD_CAST ("hit-collection"));
661 if (res == -1) {
662 set_hit_collection_error (res, error);
663 goto out;
666 while ((hit = mm_hit_collection_get_next_hit (hc)) != NULL) {
667 res = xmlTextWriterStartElement (writer, BAD_CAST ("hit"));
668 if (res == -1) {
669 g_object_unref (hit);
670 set_hit_collection_error (res, error);
671 goto out;
674 attrs_and_values = mm_hit_get_all_values (hit);
675 g_object_unref (hit);
677 pair_data = g_slice_new0 (SerializeData);
678 pair_data->writer = writer;
679 pair_data->error = error;
681 g_hash_table_foreach (attrs_and_values,
682 (GHFunc) serialize_pair,
683 pair_data);
684 g_slice_free (SerializeData, pair_data);
685 g_hash_table_destroy (attrs_and_values);
687 if (*error) {
688 /* an error occurred somewhere in one of the sub-functions */
689 goto out;
692 /* close "hit" */
693 res = xmlTextWriterEndElement (writer);
694 if (res == -1) {
695 set_hit_collection_error (res, error);
696 goto out;
700 /* close "hit-collection" */
701 res = xmlTextWriterEndElement (writer);
702 if (res == -1) {
703 set_hit_collection_error (res, error);
704 goto out;
706 res = xmlTextWriterEndDocument (writer);
707 if (res == -1) {
708 set_hit_collection_error (res, error);
709 goto out;
712 /* it seems everything has gone well */
713 serialized = g_strdup ((char *) xmlBufferContent (buffer));
715 out:
716 xmlFreeTextWriter (writer);
717 xmlBufferFree (buffer);
719 return serialized;
723 * mm_filter_unserialize:
724 * @s: a serialized #MMFilter, obtained with
725 * #mm_filter_serialize.
726 * @error: a #GError.
728 * Builds a #MMFilter object from a serialized XML string.
730 * Return value: a #MMFilter object. Unref it when done.
733 MMFilter *
734 mm_filter_unserialize (const char *s, GError **error)
736 MMFilter *f = NULL;
737 MMFilterParam *fp;
738 xmlTextReaderPtr reader;
739 int res;
740 const xmlChar *node_name;
742 reader = xmlReaderForMemory (s, strlen (s), NULL, NULL, 0);
744 /* cut all the elements before <filter> */
745 do {
746 res = xmlTextReaderRead (reader);
747 node_name = xmlTextReaderConstName (reader);
748 } while (xmlStrcmp (node_name, BAD_CAST ("filter")) != 0);
750 /* do the error checking here and not in each iteration of the cycle */
751 if (res <= 0) {
752 set_filter_error (res, error);
753 goto out;
756 res = xmlTextReaderRead (reader);
757 node_name = xmlTextReaderConstName (reader);
758 f = mm_filter_new ();
760 /* we're either on the first <filter-param> or on </filter> if the
761 * object is empty. cycle until we're on </filter>.
763 while (!((xmlTextReaderNodeType (reader) == XML_READER_TYPE_END_ELEMENT) &&
764 xmlStrcmp (node_name, BAD_CAST ("filter")) == 0) && res > 0) {
765 fp = unserialize_filter_param (reader, error);
766 if (*error) {
767 g_object_unref (f);
768 f = NULL;
769 goto out;
771 mm_filter_add_filtering_param (f, fp);
772 g_object_unref (fp);
773 res = xmlTextReaderRead (reader);
774 node_name = xmlTextReaderConstName (reader);
777 if (res <= 0) {
778 /* do not return an incomplete filter */
779 set_filter_error (res, error);
780 g_object_unref (f);
781 f = NULL;
784 out:
785 xmlFreeTextReader (reader);
787 return f;
791 * mm_hit_collection_unserialize:
792 * @s: a serialized #MMHitCollection, obtained with
793 * #mm_hit_collection_serialize.
794 * @error: a #GError.
796 * Builds a #MMHitCollection object from a serialized XML string.
798 * Return value: a #MMHitCollection object. Unref it when done.
801 MMHitCollection *
802 mm_hit_collection_unserialize (const char *s, GError **error)
804 MMHitCollection *hc = NULL;
805 MMHit *hit;
806 xmlTextReaderPtr reader;
807 int res;
808 const xmlChar *node_name;
810 reader = xmlReaderForMemory (s, strlen (s), NULL, NULL, 0);
812 /* cut all the elements before <hit-collection> */
813 do {
814 res = xmlTextReaderRead (reader);
815 node_name = xmlTextReaderConstName (reader);
816 } while (xmlStrcmp (node_name, BAD_CAST ("hit-collection")) != 0);
818 /* check for errors before <hit-collection> all at once, and not
819 * in every iteration of the cycle.
821 if (res <= 0) {
822 set_hit_collection_error (res, error);
823 goto out;
826 hc = mm_hit_collection_new ();
827 res = xmlTextReaderRead (reader);
828 node_name = xmlTextReaderConstName (reader);
830 /* we're either on the first <hit> or on </hit-collection> if the
831 * object is empty. cycle until we're at the end of file.
833 while (!((xmlTextReaderNodeType (reader) == XML_READER_TYPE_END_ELEMENT) &&
834 xmlStrcmp (node_name, BAD_CAST ("hit-collection")) == 0) && res > 0) {
835 hit = unserialize_hit (reader, error);
836 if (*error) {
837 /* do not return an incomplete HitCollection */
838 g_object_unref (hc);
839 hc = NULL;
840 goto out;
842 mm_hit_collection_add_hit (hc, hit);
843 g_object_unref (hit);
844 res = xmlTextReaderRead (reader);
845 node_name = xmlTextReaderConstName (reader);
848 if (res <= 0) {
849 /* do not return an incomplete HitCollection */
850 set_hit_collection_error (res, error);
851 g_object_unref (hc);
852 hc = NULL;
853 goto out;
856 out:
857 xmlFreeTextReader (reader);
859 return hc;
863 * mm_gvalue_to_string:
864 * @v: a #GValue
866 * Builds a serialized XML version of a #GValue.
868 * Return value: a newly allocated string buffer containing the serialized
869 * #GValue.
872 char *
873 mm_gvalue_to_string (GValue *v)
875 char *ret = NULL;
876 GType type = G_VALUE_TYPE (v);
878 /* guess the most used cases and handle those first */
879 if (type == G_TYPE_STRING) {
880 ret = g_strdup (g_value_get_string (v));
881 } else if (type == G_TYPE_BOOLEAN) {
882 ret = g_strdup_printf ("%d", g_value_get_boolean (v));
883 } else if (type == G_TYPE_INT) {
884 ret = g_strdup_printf ("%d", g_value_get_int (v));
885 } else if (type == G_TYPE_FLOAT) {
886 ret = g_strdup_printf ("%f", g_value_get_float (v));
887 } else if (type == G_TYPE_DOUBLE) {
888 char double_buff[G_ASCII_DTOSTR_BUF_SIZE];
889 ret = g_ascii_dtostr (double_buff, sizeof (double_buff),
890 g_value_get_double (v));
891 } else if (type == G_TYPE_LONG) {
892 ret = g_strdup_printf ("%ld", g_value_get_long (v));
893 } else if (type == G_TYPE_INT64) {
894 ret = g_strdup_printf ("%lld", g_value_get_int64 (v));
895 } else if (type == G_TYPE_UINT) {
896 ret = g_strdup_printf ("%u", g_value_get_uint (v));
897 } else if (type == G_TYPE_ULONG) {
898 ret = g_strdup_printf ("%lu", g_value_get_ulong (v));
899 } else if (type == G_TYPE_UINT64) {
900 ret = g_strdup_printf ("%llu", g_value_get_uint64 (v));
901 } else if (G_VALUE_HOLDS_CHAR (v)) {
902 ret = g_strdup_printf ("%c", g_value_get_char (v));
903 } else if (G_VALUE_HOLDS_UCHAR (v)) {
904 ret = g_strdup_printf ("%c", g_value_get_uchar (v));
905 } else {
906 g_warning ("Can't convert the value to string: unhandled type");
909 return ret;
913 * mm_gvalue_from_string:
914 * @val_string: a string description of a #GValue. You can use
915 * #mm_gvalue_to_string to have one.
916 * @type: the type of the #GValue.
917 * @v: a zero-filled uninitialized #GValue.
919 * Fills @v with the #GValue contained in the XML description @val_string.
921 * Return value: %TRUE in case of success, %FALSE in case of failure.
924 gboolean
925 mm_gvalue_from_string (const char *val_string, GType type, GValue *v)
927 gboolean retval = TRUE;
929 g_value_init (v, type);
931 if (type == G_TYPE_STRING) {
932 g_value_set_string (v, val_string);
933 } else if (type == G_TYPE_BOOLEAN) {
934 gboolean bval;
935 sscanf (val_string, "%d", &bval);
936 g_value_set_boolean (v, bval);
937 } else if (type == G_TYPE_INT) {
938 gint ival;
939 sscanf (val_string, "%d", &ival);
940 g_value_set_int (v, ival);
941 } else if (type == G_TYPE_FLOAT) {
942 gfloat fval;
943 sscanf (val_string, "%f", &fval);
944 g_value_set_float (v, fval);
945 } else if (type == G_TYPE_DOUBLE) {
946 gdouble dval;
947 dval = g_ascii_strtod (val_string, NULL);
948 g_value_set_double (v, dval);
949 } else if (type == G_TYPE_LONG) {
950 glong lval;
951 sscanf (val_string, "%ld", &lval);
952 g_value_set_long (v, lval);
953 } else if (type == G_TYPE_INT64) {
954 g_value_set_int64 (v, g_ascii_strtoll (val_string, NULL, 0));
955 } else if (type == G_TYPE_UINT) {
956 guint uval;
957 sscanf (val_string, "%u", &uval);
958 g_value_set_uint (v, uval);
959 } else if (type == G_TYPE_ULONG) {
960 gulong ulval;
961 sscanf (val_string, "%lu", &ulval);
962 g_value_set_ulong (v, ulval);
963 } else if (type == G_TYPE_UINT64) {
964 g_value_set_uint64 (v, g_ascii_strtoull (val_string, NULL, 0));
965 } else if (G_VALUE_HOLDS_CHAR (v)) {
966 gchar cval;
967 sscanf (val_string, "%c", &cval);
968 g_value_set_char (v, cval);
969 } else if (G_VALUE_HOLDS_UCHAR (v)) {
970 guchar ucval;
971 sscanf (val_string, "%c", &ucval);
972 g_value_set_uchar (v, ucval);
973 } else {
974 retval = FALSE;
977 return retval;