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.
23 #include <libxml/tree.h>
24 #include <libxml/xmlwriter.h>
25 #include <libxml/xmlreader.h>
26 #include "mm-string-utils.h"
30 MMComparisionOperator op
;
34 static OperatorGrid operator_grid
[] =
36 { MM_COMP_EQUAL
, "EQ" },
37 { MM_COMP_GREATER
, "GR" },
38 { MM_COMP_GREATER_EQUAL
, "GRQ" },
39 { MM_COMP_LESS
, "LS" },
40 { MM_COMP_LESS_EQUAL
, "LSQ" },
45 value_to_string (GValue
*v
)
49 GType type
= G_VALUE_TYPE (v
);
51 /* guess the most used cases and handle those first */
52 if (type
== G_TYPE_STRING
) {
53 ret
= g_strdup (g_value_get_string (v
));
54 } else if (type
== G_TYPE_BOOLEAN
) {
55 ret
= g_strdup_printf ("%d", g_value_get_boolean (v
));
56 } else if (type
== G_TYPE_INT
) {
57 ret
= g_strdup_printf ("%d", g_value_get_int (v
));
58 } else if (type
== G_TYPE_FLOAT
) {
59 ret
= g_strdup_printf ("%f", g_value_get_float (v
));
60 } else if (type
== G_TYPE_DOUBLE
) {
61 char double_buff
[G_ASCII_DTOSTR_BUF_SIZE
];
62 ret
= g_ascii_dtostr (double_buff
, sizeof (double_buff
),
63 g_value_get_double (v
));
64 } else if (type
== G_TYPE_LONG
) {
65 ret
= g_strdup_printf ("%ld", g_value_get_long (v
));
66 } else if (type
== G_TYPE_INT64
) {
67 ret
= g_strdup_printf ("%lld", g_value_get_int64 (v
));
68 } else if (type
== G_TYPE_UINT
) {
69 ret
= g_strdup_printf ("%u", g_value_get_uint (v
));
70 } else if (type
== G_TYPE_ULONG
) {
71 ret
= g_strdup_printf ("%lu", g_value_get_ulong (v
));
72 } else if (type
== G_TYPE_UINT64
) {
73 ret
= g_strdup_printf ("%llu", g_value_get_uint64 (v
));
74 } else if (G_VALUE_HOLDS_CHAR (v
)) {
75 ret
= g_strdup_printf ("%c", g_value_get_char (v
));
76 } else if (G_VALUE_HOLDS_UCHAR (v
)) {
77 ret
= g_strdup_printf ("%c", g_value_get_uchar (v
));
79 g_warning ("Can't convert the value to string: unhandled type");
83 safe
= xmlCharStrdup (ret
);
89 op_to_string (MMComparisionOperator op
)
93 for (idx
= 0; idx
< G_N_ELEMENTS (operator_grid
); idx
++) {
94 if (op
== operator_grid
[idx
].op
) {
95 return xmlCharStrdup (operator_grid
[idx
].string
);
103 add_filter_param_to_xml (MMFilterParam
*fp
,
104 xmlTextWriterPtr writer
)
106 MMAttribute
*attribute
;
109 attribute
= mm_filter_param_get_attribute (fp
);
111 xmlTextWriterStartElement (writer
, BAD_CAST ("filter-param"));
113 xmlTextWriterStartElement (writer
, BAD_CAST ("attribute"));
114 safe_str
= xmlCharStrdup (mm_attribute_get_id (attribute
));
115 xmlTextWriterWriteAttribute (writer
, BAD_CAST ("id"), safe_str
);
117 safe_str
= xmlCharStrdup (mm_attribute_get_name (attribute
));
118 xmlTextWriterWriteAttribute (writer
, BAD_CAST ("name"), safe_str
);
120 safe_str
= xmlCharStrdup (mm_attribute_get_description (attribute
));
121 xmlTextWriterWriteAttribute (writer
, BAD_CAST ("description"), safe_str
);
123 xmlTextWriterWriteAttribute (writer
, BAD_CAST ("type"), BAD_CAST (g_type_name (mm_attribute_get_value_type (attribute
))));
124 /* close "attribute" */
125 xmlTextWriterEndElement (writer
);
127 safe_str
= value_to_string (mm_filter_param_get_value (fp
));
128 xmlTextWriterWriteElement (writer
, BAD_CAST ("value"), safe_str
);
131 safe_str
= op_to_string (mm_filter_param_get_operator (fp
));
132 xmlTextWriterWriteElement (writer
, BAD_CAST ("op"), safe_str
);
135 /* close "filter-param" */
136 xmlTextWriterEndElement (writer
);
140 unserialize_operator (xmlTextReaderPtr reader
, MMComparisionOperator
*op
)
142 const xmlChar
* op_string
;
143 gboolean found
= FALSE
;
146 /* we should be on <op> */
147 if (xmlStrcmp (xmlTextReaderConstName (reader
), BAD_CAST ("op")) != 0) {
148 g_warning ("Error while parsing the serialized xml opeator");
152 /* move on to the content */
153 res
= xmlTextReaderRead (reader
);
155 g_warning ("Error while parsing the serialized xml operator");
159 op_string
= xmlTextReaderConstValue (reader
);
160 for (idx
= 0; idx
< G_N_ELEMENTS (operator_grid
); idx
++) {
161 if (xmlStrcmp (op_string
, BAD_CAST (operator_grid
[idx
].string
)) == 0) {
168 *op
= operator_grid
[idx
].op
;
169 res
= xmlTextReaderRead (reader
);
171 g_warning ("Error while parsing the serialized xml operator");
174 return xmlTextReaderRead (reader
);
176 g_warning ("Error while parsing the serialized xml operator");
182 unserialize_value (xmlTextReaderPtr reader
, GValue
*v
)
186 const char *val_string
;
188 /* we should be on <value> */
189 if (xmlStrcmp (xmlTextReaderConstName (reader
), BAD_CAST ("value")) != 0) {
190 g_warning ("Error while parsing the serialized xml value");
194 /* move on to the content node */
195 res
= xmlTextReaderRead (reader
);
197 g_warning ("Error while parsing the serialized xml value");
201 type
= G_VALUE_TYPE (v
);
202 val_string
= (const char *) xmlTextReaderConstValue (reader
);
204 if (type
== G_TYPE_STRING
) {
205 g_value_set_string (v
, val_string
);
206 } else if (type
== G_TYPE_BOOLEAN
) {
208 sscanf (val_string
, "%d", &bval
);
209 g_value_set_boolean (v
, bval
);
210 } else if (type
== G_TYPE_INT
) {
212 sscanf (val_string
, "%d", &ival
);
213 g_value_set_int (v
, ival
);
214 } else if (type
== G_TYPE_FLOAT
) {
216 sscanf (val_string
, "%f", &fval
);
217 g_value_set_float (v
, fval
);
218 } else if (type
== G_TYPE_DOUBLE
) {
220 dval
= g_ascii_strtod (val_string
, NULL
);
221 g_value_set_double (v
, dval
);
222 } else if (type
== G_TYPE_LONG
) {
224 sscanf (val_string
, "%ld", &lval
);
225 g_value_set_long (v
, lval
);
226 } else if (type
== G_TYPE_INT64
) {
227 g_value_set_int64 (v
, g_ascii_strtoll (val_string
, NULL
, 0));
228 } else if (type
== G_TYPE_UINT
) {
230 sscanf (val_string
, "%u", &uval
);
231 g_value_set_uint (v
, uval
);
232 } else if (type
== G_TYPE_ULONG
) {
234 sscanf (val_string
, "%lu", &ulval
);
235 g_value_set_ulong (v
, ulval
);
236 } else if (type
== G_TYPE_UINT64
) {
237 g_value_set_uint64 (v
, g_ascii_strtoull (val_string
, NULL
, 0));
238 } else if (G_VALUE_HOLDS_CHAR (v
)) {
240 sscanf (val_string
, "%c", &cval
);
241 g_value_set_char (v
, cval
);
242 } else if (G_VALUE_HOLDS_UCHAR (v
)) {
244 sscanf (val_string
, "%c", &ucval
);
245 g_value_set_uchar (v
, ucval
);
247 g_warning ("Can't convert the string to a value: unhandled type");
250 /* move over </value> */
251 res
= xmlTextReaderRead (reader
);
253 g_warning ("Error while parsing the serialized xml value");
257 return xmlTextReaderRead (reader
);
261 unserialize_attribute (xmlTextReaderPtr reader
, MMAttribute
**attribute
)
263 xmlChar
*id
, *name
, *desc
, *type_name
;
266 /* we should be on <attribute> */
267 if (xmlStrcmp (xmlTextReaderConstName (reader
), BAD_CAST ("attribute")) != 0) {
268 g_warning ("Error while parsing the serialized xml attribute");
272 id
= xmlTextReaderGetAttribute (reader
, BAD_CAST ("id"));
273 name
= xmlTextReaderGetAttribute (reader
, BAD_CAST ("name"));
274 desc
= xmlTextReaderGetAttribute (reader
, BAD_CAST ("desc"));
275 type_name
= xmlTextReaderGetAttribute (reader
, BAD_CAST ("type"));
277 type
= g_type_from_name ((const char *) type_name
);
279 g_warning ("Error while parsing the serialized xml attribute");
283 *attribute
= mm_attribute_new (type
,
286 (const char *) desc
);
293 return xmlTextReaderRead (reader
);
296 static MMFilterParam
*
297 unserialize_filter_param (xmlTextReaderPtr reader
)
300 MMAttribute
*attribute
= NULL
;
301 MMComparisionOperator op
= MM_COMP_NONE
;
305 res
= xmlTextReaderRead (reader
);
306 /* we're either on <attribute> or </filter-param> if the object is empty */
307 while (!((xmlTextReaderNodeType (reader
) == XML_READER_TYPE_END_ELEMENT
) &&
308 xmlStrcmp (xmlTextReaderConstName (reader
), BAD_CAST ("filter-param")) == 0) && res
> 0) {
309 res
= unserialize_attribute (reader
, &attribute
);
313 val
= mm_create_gvalue_for_attribute (attribute
);
314 res
= unserialize_value (reader
, val
);
318 res
= unserialize_operator (reader
, &op
);
325 g_warning ("Error while parsing the serialized xml filter param");
329 if (attribute
== NULL
|| op
== MM_COMP_NONE
|| val
== NULL
) {
330 g_warning ("Error while parsing the serialized xml filter param");
334 fp
= mm_filter_param_new (attribute
, val
, op
);
338 /* public functions */
340 mm_filter_serialize (MMFilter
*filter
)
344 xmlTextWriterPtr writer
;
345 GList
*filter_params
;
347 buffer
= xmlBufferCreate ();
348 writer
= xmlNewTextWriterMemory (buffer
, 0);
350 xmlTextWriterStartDocument (writer
, NULL
, NULL
, NULL
);
352 xmlTextWriterStartElement (writer
, BAD_CAST ("filter"));
353 filter_params
= mm_filter_get_filtering_params (filter
);
354 g_list_foreach (filter_params
, (GFunc
) add_filter_param_to_xml
, writer
);
356 xmlTextWriterEndElement (writer
);
358 xmlTextWriterEndDocument (writer
);
360 xmlFreeTextWriter (writer
);
361 serialized
= g_strdup ((char *) xmlBufferContent (buffer
));
362 xmlBufferFree (buffer
);
368 mm_filter_unserialize (const char *s
)
372 xmlTextReaderPtr reader
;
374 const xmlChar
*node_name
;
376 f
= mm_filter_new ();
377 reader
= xmlReaderForMemory (s
, strlen (s
), NULL
, NULL
, 0);
379 /* cut all the elements before <filter> */
381 res
= xmlTextReaderRead (reader
);
382 node_name
= xmlTextReaderConstName (reader
);
383 } while (xmlStrcmp (node_name
, BAD_CAST ("filter")) != 0);
385 res
= xmlTextReaderRead (reader
);
386 /* we're either on the first <filter-param> or on </filter> if the
387 * object is empty. cycle until we're on </filter>.
389 while (!((xmlTextReaderNodeType (reader
) == XML_READER_TYPE_END_ELEMENT
) &&
390 xmlStrcmp (xmlTextReaderConstName (reader
), BAD_CAST ("filter")) == 0) && res
> 0) {
391 fp
= unserialize_filter_param (reader
);
395 mm_filter_add_filtering_param (f
, fp
);
396 res
= xmlTextReaderRead (reader
);
400 g_warning ("Error while parsing the serialized filter.");
403 xmlFreeTextReader (reader
);
409 mm_hit_collection_serialize (MMHitCollection
*hc
)
411 /* TODO: implement */
416 mm_hit_collection_unserialize (const char *s
)
418 /* TODO: implement */