Fix a crash
[framework/location/libdecarta.git] / decarta / xml_wrapper.c
1 /*
2  * libdecarta
3  *
4  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
7  *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21
22 #include <glib.h>
23 #include <string.h>
24 #include <libxml/encoding.h>
25 #include <libxml/xmlwriter.h>
26 #include <libxml/xpath.h>
27 #include <libxml/xpathInternals.h>
28 #include <libxml/globals.h>
29 #include <libxml/xmlerror.h>
30 #include <libxml/parser.h>
31 #include <libxml/parserInternals.h>
32 #include <libxml/tree.h>
33 #include <libxml/debugXML.h>
34 #include <libxml/xmlmemory.h>
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include "decarta_log.h"
41 #include "xml_wrapper.h"
42 #include "decarta_xml_internal.h"
43
44 #define DECARTA_XML_LOG "DECARTA_XML_LOG"   // if this environment value is "1", print out xml log
45
46 typedef struct {
47         xmlTextWriterPtr writer;
48         xmlBufferPtr buf;
49 } XmlWriterWrapper;
50
51 typedef struct {
52         xmlDocPtr doc;
53         xmlXPathContextPtr xpath_ctx;
54 } XmlReaderWrapper;
55
56 XmlWriterHandler
57 xml_writer_open (char* encoding)
58 {
59         if(!encoding){
60                 DECARTA_LOGW("encoding is NULL");
61                 return NULL;
62         }
63         XmlWriterWrapper* xml = g_new0(XmlWriterWrapper, 1);
64
65         xml->buf = xmlBufferCreate();
66     if(!xml->buf) {
67         DECARTA_LOGW("failed to xmlBufferCreate() failed");
68         return NULL;
69     }
70     xml->writer = xmlNewTextWriterMemory(xml->buf, 0);
71     if (!xml->writer) {
72         DECARTA_LOGW("failed to xmlNewTextWriterMemory(0x%x) failed", xml->buf);
73         xmlBufferFree(xml->buf);
74         g_free(xml);
75         return NULL;
76     }
77     if( xmlTextWriterStartDocument(xml->writer, NULL, encoding, NULL) < 0 ){
78         DECARTA_LOGW("failed to xmlTextWriterStartDocument(0x%x, NULL, %s, NULL)", xml->writer, encoding);
79         xmlFreeTextWriter(xml->writer);
80         xmlBufferFree(xml->buf);
81         g_free(xml);
82         return NULL;
83     }
84     return xml;
85 }
86
87 gboolean
88 xml_writer_close (XmlWriterHandler handle, char **content, unsigned int *size)
89 {
90         XmlWriterWrapper* xml = (XmlWriterWrapper*)handle;
91         if(!xml || !xml->buf ||!xml->writer){
92                 DECARTA_LOGW("XmlWriterHandler or buffer or writer is NULL");
93                 return FALSE;
94         }
95         if( xmlTextWriterEndDocument(xml->writer) < 0){
96                 DECARTA_LOGW("failed to xmlTextWriterEndDocument(0x%x)", xml->writer);
97                 return FALSE;
98         }
99         xmlFreeTextWriter(xml->writer);
100         if (0 == g_strcmp0(g_getenv (DECARTA_XML_LOG), "1")) g_printf ("\nrequest: %s", (const char*)xml->buf->content);
101         if (content && size){
102                 if(xml->buf->content) {
103                         *content = g_strdup((const char*)xml->buf->content);
104                         *size = g_utf8_strlen(*content, 4096);
105                 } else {
106                         *content = NULL;
107                         *size = 0;
108                 }
109         }
110         xmlBufferFree(xml->buf);
111         g_free(xml);
112         return TRUE;
113 }
114
115 gboolean
116 xml_writer_element_start (XmlWriterHandler handle, const char* element)
117 {
118         XmlWriterWrapper* xml = (XmlWriterWrapper*)handle;
119         if(!xml || !xml->buf ||!xml->writer){
120                 DECARTA_LOGW("XmlWriterHandler or buffer or writer is NULL");
121                 return FALSE;
122         }
123         if(!element){
124                 DECARTA_LOGW("element is NULL");
125                 return FALSE;
126         }
127         xmlTextWriterPtr writer = xml->writer;
128
129         if( xmlTextWriterStartElement(writer, BAD_CAST element) < 0 ){
130         DECARTA_LOGW("failed to xmlTextWriterStartElement(0x%x, %s)", writer, element);
131         return FALSE;
132         }
133         return TRUE;
134 }
135
136 gboolean
137 xml_writer_attribute_write (XmlWriterHandler handle, const gchar *name, const gchar *value)
138 {
139         XmlWriterWrapper* xml = (XmlWriterWrapper*)handle;
140         if(!xml || !xml->buf ||!xml->writer){
141                 DECARTA_LOGW("XmlWriterHandler or buffer or writer is NULL");
142                 return FALSE;
143         }
144         xmlTextWriterPtr writer = xml->writer;
145
146         if(xmlTextWriterWriteAttribute(writer, BAD_CAST name, BAD_CAST value) < 0 ){
147                 DECARTA_LOGW("failed to xmlTextWriterWriteAttribute(0x%x, %s, %s)", writer, name, value);
148                 return FALSE;
149         }
150         return TRUE;
151 }
152
153 gboolean
154 xml_writer_all_start (XmlWriterHandler handle, const char* element, const char* content, ...)
155 {
156         XmlWriterWrapper* xml = (XmlWriterWrapper*)handle;
157         if(!xml || !xml->buf ||!xml->writer){
158                 DECARTA_LOGW("XmlWriterHandler or buffer or writer is NULL");
159                 return FALSE;
160         }
161         if(!element){
162                 DECARTA_LOGW("element is NULL");
163                 return FALSE;
164         }
165         xmlTextWriterPtr writer = xml->writer;
166
167         if( xmlTextWriterStartElement(writer, BAD_CAST element) < 0 ){
168         DECARTA_LOGW("failed to xmlTextWriterStartElement(0x%x, %s)", writer, element);
169         return FALSE;
170         }
171
172         va_list ap;
173         char *attr = NULL;
174         char *val = NULL;
175         va_start(ap, content);
176         while( (attr = va_arg(ap, char*))!= NULL ){
177                 val = va_arg(ap, char*);
178                 if(attr && val){
179                     if(xmlTextWriterWriteAttribute(writer, BAD_CAST attr, BAD_CAST val) < 0 ){
180                                 DECARTA_LOGW("failed to xmlTextWriterWriteAttribute(0x%x, %s, %s)", writer, attr, val);
181                                 return FALSE;
182                         }
183                 }
184         }
185         va_end(ap);
186
187     if(content){
188                 if(xmlTextWriterWriteFormatRaw(writer, content) < 0 ){
189                 DECARTA_LOGW("failed to xmlTextWriterWriteFormatRaw(%s, %s)", element, content);
190                         return FALSE;
191                 }
192         }
193         return TRUE;
194 }
195
196
197 gboolean
198 xml_writer_end (XmlWriterHandler handle)
199 {
200         XmlWriterWrapper* xml = (XmlWriterWrapper*)handle;
201         if(!xml || !xml->buf ||!xml->writer){
202                 DECARTA_LOGW("XmlWriterHandler or buffer or writer is NULL");
203                 return FALSE;
204         }
205         xmlTextWriterPtr writer = xml->writer;
206
207         if(xmlTextWriterFullEndElement(writer) < 0) {
208                 DECARTA_LOGW("failed to xmlTextWriterFullEndElement(0x%x)", writer);
209                 return FALSE;
210         }
211         return TRUE;
212 }
213
214 static char *
215 remove_noise (const char *data)
216 {
217         if (!data) return NULL;
218         char **split = g_strsplit (data, ":XLS>", 2);
219         char *dup = g_strconcat (split[0], ":XLS>", NULL);
220         g_strfreev (split);
221         return dup;
222 }
223
224 XmlReaderHandler
225 xml_reader_open (const char* data,
226         ...)
227 {
228         DECARTA_LOGD ("xml_reader_open");
229         if (!data){
230                 DECARTA_LOGW("data is NULL");
231                 return NULL;
232         }       XmlReaderWrapper* reader = g_new0 (XmlReaderWrapper, 1);
233         char *xml_data = remove_noise (data);
234         if (0 == g_strcmp0(g_getenv (DECARTA_XML_LOG), "1")) printf ("\nresponse: %s", xml_data);
235         reader->doc = xmlParseDoc (BAD_CAST xml_data);
236         if (!reader->doc) {
237                 DECARTA_LOGW("failed to xmlParseDoc(%s)", xml_data);
238                 g_free (xml_data);
239                 g_free (reader);
240                 return NULL;
241         }
242         g_free (xml_data);
243
244         reader->xpath_ctx = xmlXPathNewContext (reader->doc);
245         if (!reader->xpath_ctx) {
246                 DECARTA_LOGW("failed to xmlXPathNewContext(0x%x)", reader->doc);
247                 xmlFreeDoc (reader->doc);
248                 g_free(reader);
249                 return NULL;
250         }
251
252         va_list ap;
253         char* ns= NULL;
254         char* ns_uri = NULL;
255         va_start(ap, data);
256         while( (ns = va_arg(ap, char*))!= NULL ){
257                 ns_uri= va_arg(ap, char*);
258                 if (ns && ns_uri)
259                         if (xmlXPathRegisterNs (reader->xpath_ctx, BAD_CAST ns, BAD_CAST ns_uri) < 0) {
260                                 DECARTA_LOGW ("failed to xmlXPathRegisterNs(0x%x, %s, %s)", reader->xpath_ctx, ns, ns_uri);
261                                 xmlFreeDoc (reader->doc);
262                                 xmlXPathFreeContext (reader->xpath_ctx);
263                                 g_free(reader);
264                                 reader = NULL;
265                                 break;
266                         }
267         }
268         va_end(ap);
269
270         return reader;
271 }
272
273 void
274 xml_reader_close (XmlReaderHandler handle)
275 {
276         XmlReaderWrapper* reader = (XmlReaderWrapper*)handle;
277         if (!reader) {
278                 DECARTA_LOGW("handle is NULL");
279                 return;
280         }
281         if(reader->doc)       xmlFreeDoc (reader->doc);
282         if(reader->xpath_ctx) xmlXPathFreeContext (reader->xpath_ctx);
283         g_free(reader);
284 }
285
286 gboolean
287 xml_reader_is_valid (XmlReaderHandler handle,
288         const char *xpath_format,
289         ...)
290 {
291         XmlReaderWrapper* reader = (XmlReaderWrapper*)handle;
292         if (!handle || !reader->xpath_ctx || !xpath_format) {
293                 DECARTA_LOGW("handle or xmlXPathContextPtr or xpath_format is NULL");
294                 return FALSE;
295         }
296         gboolean ret = TRUE;
297         va_list ap;
298         va_start(ap, xpath_format);
299         char *xpath = g_strdup_vprintf (xpath_format, ap);
300         va_end(ap);
301         xmlXPathObjectPtr obj = xmlXPathEvalExpression (BAD_CAST xpath, reader->xpath_ctx);
302         g_free (xpath);
303         if (!obj) ret = FALSE;
304         else if (!obj->nodesetval || xmlXPathNodeSetIsEmpty (obj->nodesetval)) ret = FALSE;
305         xmlXPathFreeObject (obj);
306         return ret;
307 }
308
309 gboolean
310 xml_reader_get_string (XmlReaderHandler handle,
311         char **string,
312         const char *xpath_format,
313         ...)
314 {
315         XmlReaderWrapper* reader = (XmlReaderWrapper*)handle;
316         if (!reader || !reader->xpath_ctx || !xpath_format || !string) {
317                 DECARTA_LOGW("handle or xmlXPathContextPtr or xpath_format or string is NULL");
318                 return FALSE;
319         }
320
321
322         va_list ap;
323         va_start(ap, xpath_format);
324         char *xpath = g_strdup_vprintf (xpath_format, ap);
325         va_end(ap);
326         gboolean ret = FALSE;
327         xmlXPathObjectPtr obj = xmlXPathEvalExpression (BAD_CAST xpath, reader->xpath_ctx);
328         g_free(xpath);
329         if (obj) {
330                 if (obj->nodesetval && !xmlXPathNodeSetIsEmpty (obj->nodesetval)) {
331                         *string = (char*)xmlXPathCastNodeSetToString (obj->nodesetval);
332                         ret = TRUE;
333                 } else ret = FALSE;
334                 xmlXPathFreeObject (obj);
335         }
336         return ret;
337 }
338
339 /**
340  * __sax_internal_subset_cb:
341  * @ctxt:  An XML parser context
342  *
343  * Does this document has an internal subset
344  */
345 static void
346 __sax_internal_subset_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
347                const xmlChar *ExternalID, const xmlChar *SystemID)
348 {
349
350         if (!name) {
351                 DECARTA_LOGD("[ERROR] name is NULL\n");
352                 return;
353         }
354
355         DECARTA_LOGD( "SAX.internalSubset(%s,", name);
356         if (ExternalID == NULL) {
357                 DECARTA_LOGD( " ,");
358         } else {
359                 DECARTA_LOGD( " %s,", ExternalID);
360         }
361         if (SystemID == NULL) {
362                 DECARTA_LOGD( " )\n");
363         } else {
364                 DECARTA_LOGD( " %s)\n", SystemID);
365         }
366 }
367
368 /**
369  * __sax_is_standalone_cb:
370  * @ctxt:  An XML parser context
371  *
372  * Is this document tagged standalone ?
373  *
374  * Returns 1 if true
375  */
376 static int
377 __sax_is_standalone_cb(void *ctx ATTRIBUTE_UNUSED)
378 {
379
380         DECARTA_LOGD( "SAX.isStandalone()\n");
381         return(0);
382 }
383
384 /**
385  * __sax_has_internal_subset_cb:
386  * @ctxt:  An XML parser context
387  *
388  * Does this document has an internal subset
389  *
390  * Returns 1 if true
391  */
392 static int
393 __sax_has_internal_subset_cb(void *ctx ATTRIBUTE_UNUSED)
394 {
395
396         DECARTA_LOGD( "SAX.hasInternalSubset()\n");
397         return(0);
398 }
399
400 /**
401  * __sax_has_external_subset_cb:
402  * @ctxt:  An XML parser context
403  *
404  * Does this document has an external subset
405  *
406  * Returns 1 if true
407  */
408 static int
409 __sax_has_external_subset_cb(void *ctx ATTRIBUTE_UNUSED)
410 {
411
412         DECARTA_LOGD( "SAX.hasExternalSubset()\n");
413         return(0);
414 }
415
416 /**
417  * __sax_resolve_entity_cb:
418  * @ctxt:  An XML parser context
419  * @publicId: The public ID of the entity
420  * @systemId: The system ID of the entity
421  *
422  * Special entity resolver, better left to the parser, it has
423  * more context than the application layer.
424  * The default behaviour is to NOT resolve the entities, in that case
425  * the ENTITY_REF nodes are built in the structure (and the parameter
426  * values).
427  *
428  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
429  */
430 static xmlParserInputPtr
431 __sax_resolve_entity_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
432 {
433
434         DECARTA_LOGD( "SAX.resolveEntity(");
435         if (publicId != NULL) {
436                 DECARTA_LOGD( "%s", (char *)publicId);
437         } else {
438                 DECARTA_LOGD( " ");
439         }
440         if (systemId != NULL) {
441                 DECARTA_LOGD( ", %s)\n", (char *)systemId);
442         } else {
443                 DECARTA_LOGD( ", )\n");
444         }
445
446         return(NULL);
447 }
448
449 /**
450  * __sax_get_entity_cb:
451  * @ctxt:  An XML parser context
452  * @name: The entity name
453  *
454  * Get an entity by name
455  *
456  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
457  */
458 static xmlEntityPtr
459 __sax_get_entity_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
460 {
461         if (!name) {
462                 DECARTA_LOGD("[ERROR] name is NULL\n");
463                 return;
464         }
465         DECARTA_LOGD( "SAX.getEntity(%s)\n", name);
466         return(NULL);
467 }
468
469 /**
470  * __sax_entity_decl_cb:
471  * @ctxt:  An XML parser context
472  * @name:  the entity name
473  * @type:  the entity type
474  * @publicId: The public ID of the entity
475  * @systemId: The system ID of the entity
476  * @content: the entity value (without processing).
477  *
478  * An entity definition has been parsed
479  */
480 static void
481 __sax_entity_decl_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
482           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
483 {
484         if (!name || !type) {
485                 DECARTA_LOGD("[ERROR] name or type is NULL\n");
486                 return;
487         }
488         const xmlChar *nullstr = BAD_CAST "(null)";
489         /* not all libraries handle printing null pointers nicely */
490         if (publicId == NULL) {
491                 publicId = nullstr;
492         }
493         if (systemId == NULL) {
494                 systemId = nullstr;
495         }
496         if (content == NULL) {
497                 content = (xmlChar *)nullstr;
498         }
499
500         DECARTA_LOGD( "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
501                 name, type, publicId, systemId, content);
502 }
503
504 /**
505  * __sax_notation_decl_cb:
506  * @ctxt:  An XML parser context
507  * @name: The name of the notation
508  * @publicId: The public ID of the entity
509  * @systemId: The system ID of the entity
510  *
511  * What to do when a notation declaration has been parsed.
512  */
513 static void
514 __sax_notation_decl_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
515              const xmlChar *publicId, const xmlChar *systemId)
516 {
517
518         if (!name || !publicId || !systemId) {
519                 DECARTA_LOGD("[ERROR] name or publicId or systemId is NULL\n");
520                 return;
521         }
522         DECARTA_LOGD( "SAX.notationDecl(%s, %s, %s)\n",
523                 (char *) name, (char *) publicId, (char *) systemId);
524 }
525
526 /**
527  * __sax_attribute_decl_cb:
528  * @ctxt:  An XML parser context
529  * @name:  the attribute name
530  * @type:  the attribute type
531  *
532  * An attribute definition has been parsed
533  */
534 static void
535 __sax_attribute_decl_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
536                    const xmlChar * name, int type, int def,
537                    const xmlChar * defaultValue, xmlEnumerationPtr tree)
538 {
539         if (!elem || !name || !type || !def) {
540                 DECARTA_LOGD("[ERROR] elem or name or type or def is NULL\n");
541                 return;
542         }
543         if (defaultValue == NULL) {
544                 DECARTA_LOGD( "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
545                         elem, name, type, def);
546         } else {
547                 DECARTA_LOGD( "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
548                         elem, name, type, def, defaultValue);
549         }
550         xmlFreeEnumeration(tree);
551 }
552
553 /**
554  * __sax_element_decl_cb:
555  * @ctxt:  An XML parser context
556  * @name:  the element name
557  * @type:  the element type
558  * @content: the element value (without processing).
559  *
560  * An element definition has been parsed
561  */
562 static void
563 __sax_element_decl_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
564             xmlElementContentPtr content ATTRIBUTE_UNUSED)
565 {
566         if (!name || !type) {
567                 DECARTA_LOGD("[ERROR] name or type is NULL\n");
568                 return;
569         }
570
571         DECARTA_LOGD( "SAX.elementDecl(%s, %d, ...)\n", name, type);
572 }
573
574 /**
575  * __sax_unparsed_entity_decl_cb:
576  * @ctxt:  An XML parser context
577  * @name: The name of the entity
578  * @publicId: The public ID of the entity
579  * @systemId: The system ID of the entity
580  * @notationName: the name of the notation
581  *
582  * What to do when an unparsed entity declaration is parsed
583  */
584 static void
585 __sax_unparsed_entity_decl_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
586                    const xmlChar *publicId, const xmlChar *systemId,
587                    const xmlChar *notationName)
588 {
589         if (!name) {
590                 DECARTA_LOGD("[ERROR] name is NULL\n");
591                 return;
592         }
593         const xmlChar *nullstr = BAD_CAST "(null)";
594
595         if (publicId == NULL) {
596                 publicId = nullstr;
597         }
598         if (systemId == NULL) {
599                 systemId = nullstr;
600         }
601         if (notationName == NULL) {
602                 notationName = nullstr;
603         }
604
605         DECARTA_LOGD( "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
606                 (char *) name, (char *) publicId, (char *) systemId,
607                 (char *) notationName);
608 }
609
610
611 /**
612  * __sax_set_document_locator_cb:
613  * @ctxt:  An XML parser context
614  * @loc: A SAX Locator
615  *
616  * Receive the document locator at startup, actually xmlDefaultSAXLocator
617  * Everything is available on the context, so this is useless in our case.
618  */
619 static void
620 __sax_set_document_locator_cb(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
621 {
622         DECARTA_LOGD( "SAX.setDocumentLocator()\n");
623 }
624
625 /**
626  * __sax_start_document_cb:
627  * @ctxt:  An XML parser context
628  *
629  * called when the document start being processed.
630  */
631 static void
632 __sax_start_document_cb(void *ctx)
633 {
634         DECARTA_LOGD( "SAX.startDocument()\n");
635         if (!ctx) {
636                 DECARTA_LOGD("[ERROR] ctx is NULL\n");
637                 return;
638         }
639
640         sax_route_data_s *route_data = (sax_route_data_s *)ctx;
641
642         /** error check */
643         route_data->has_error = 0;
644         route_data->error_code_str = NULL;
645         route_data->error_message_str = NULL;
646         route_data->error_severity_str = NULL;
647
648         /** check wether has route responce */
649         route_data->has_route_resp = 0;
650
651         route_data->route_geometry_state = 0;
652         route_data->route_totaltime_state = 0;
653         route_data->route_totaldist_state = 0;
654         route_data->route_bbox_state = 0;
655
656         route_data->route_start_state = 0;
657         route_data->route_end_state = 0;
658
659         route_data->route_map_overview_state = 0;
660
661         route_data->route_instruction_state = 0;
662         route_data->route_map_state = 0;
663
664 }
665
666 /**
667  * __sax_end_document_cb:
668  * @ctxt:  An XML parser context
669  *
670  * called when the document end has been detected.
671  */
672 static void
673 __sax_end_document_cb(void *ctx ATTRIBUTE_UNUSED)
674 {
675         DECARTA_LOGD( "SAX.endDocument()\n");
676
677 }
678
679
680 /**
681  * __sax_reference_cb:
682  * @ctxt:  An XML parser context
683  * @name:  The entity name
684  *
685  * called when an entity reference is detected.
686  */
687 static void
688 __sax_reference_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
689 {
690         if (!name) {
691                 DECARTA_LOGD("[ERROR] name is NULL\n");
692                 return;
693         }
694         DECARTA_LOGD( "SAX.reference(%s)\n", name);
695 }
696
697 /**
698  * __sax_characters_cb:
699  * @ctxt:  An XML parser context
700  * @ch:  a xmlChar string
701  * @len: the number of xmlChar
702  *
703  * receiving some chars from the parser.
704  * Question: how much at a time ???
705  */
706 static void
707 __sax_characters_cb(void *ctx, const xmlChar *ch, int len)
708 {
709         if (!ctx || !ch) {
710                 DECARTA_LOGD("[ERROR] ctx or ch is NULL\n");
711                 return;
712         }
713
714         sax_route_data_s *route_data = (sax_route_data_s *)ctx;
715
716         if (route_data->route_geometry_state) {
717                 DECARTA_LOGD("save the VectorString string\n");
718                 route_data->route_geometry_str = g_strndup((gchar *) ch, len);
719         } else if (route_data->route_totaltime_state) {
720                 DECARTA_LOGD("save the totaltime string\n");
721                 route_data->route_totaltime_str = g_strndup((gchar *) ch, len);
722         } else if (route_data->route_totaldist_state) {
723                 /** get string from attribute */
724                 DECARTA_LOGD("save the totaldistance string\n");
725         } else if (route_data->route_bbox_state == 2) {
726                 DECARTA_LOGD("save the route bbox pos1 string\n");
727                 /** get bbox pos1 */
728                 route_data->route_bbox_pos1_str = g_strndup((gchar *) ch, len);
729         } else if (route_data->route_bbox_state == 4) {
730                 DECARTA_LOGD("save the route bbox pos2 string\n");
731                 /** get bbox pos2 */
732                 route_data->route_bbox_pos2_str = g_strndup((gchar *) ch, len);
733         } else if (route_data->route_start_state == 3) {
734                 /** start address pos */
735                 DECARTA_LOGD("save the route start address pos string\n");
736                 GList *last_item = g_list_last(route_data->route_start_addr_list);
737                 if (last_item) {
738                         decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data;
739                         if (route_start_addr_item) {
740                                 route_start_addr_item->pos = g_strndup((gchar *) ch, len);
741                                 DECARTA_LOGD("characters cb start pos [%s]\n", route_start_addr_item->pos);
742                         } else {
743                                 DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n");
744                         }
745                 } else {
746                         DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n");
747                 }
748         } else if (route_data->route_start_state == 5) {
749                 /** start address freeform address */
750                 DECARTA_LOGD("save the route start address freeform address string\n");
751                 GList *last_item = g_list_last(route_data->route_start_addr_list);
752                 if (last_item) {
753                         decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data;
754                         if (route_start_addr_item) {
755                                 route_start_addr_item->freeform_addr = g_strndup((gchar *) ch, len);
756                                 DECARTA_LOGD("characters cb start freeform address [%s]\n", route_start_addr_item->freeform_addr);
757                         } else {
758                                 DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n");
759                         }
760                 } else {
761                         DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n");
762                 }
763         } else if (route_data->route_start_state == 8) {
764                 /** start address form address's street */
765                 DECARTA_LOGD("save the route start address form address's street\n");
766                 GList *last_item = g_list_last(route_data->route_start_addr_list);
767                 if (last_item) {
768                         decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data;
769                         if (route_start_addr_item) {
770                                 route_start_addr_item->street = g_strndup((gchar *) ch, len);
771                                 DECARTA_LOGD("characters cb start street [%s]\n", route_start_addr_item->street);
772                         } else {
773                                 DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n");
774                         }
775                 } else {
776                         DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n");
777                 }
778         } else if (route_data->route_start_state == 9) {
779                 /** start address form address's CountrySubdivision */
780                 DECARTA_LOGD("save the route start address form address's CountrySubdivision\n");
781                 GList *last_item = g_list_last(route_data->route_start_addr_list);
782                 if (last_item) {
783                         decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data;
784                         if (route_start_addr_item) {
785                                 route_start_addr_item->country_subdivision = g_strndup((gchar *) ch, len);
786                                 DECARTA_LOGD("characters cb start country_subdivision [%s]\n", route_start_addr_item->country_subdivision);
787                         } else {
788                                 DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n");
789                         }
790                 } else {
791                         DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n");
792                 }
793         } else if (route_data->route_start_state == 10) {
794                 /** start address form address's CountrySecondarySubdivision */
795                 DECARTA_LOGD("save the route CountrySecondarySubdivision\n");
796                 GList *last_item = g_list_last(route_data->route_start_addr_list);
797                 if (last_item) {
798                         decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data;
799                         if (route_start_addr_item) {
800                                 route_start_addr_item->country_2_subdivision = g_strndup((gchar *) ch, len);
801                                 DECARTA_LOGD("characters cb start country_2_subdivision [%s]\n", route_start_addr_item->country_2_subdivision);
802                         } else {
803                                 DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n");
804                         }
805                 } else {
806                         DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n");
807                 }
808         } else if (route_data->route_start_state == 11) {
809                 /** start address form address's Municipality */
810                 DECARTA_LOGD("save the route form address's Municipality\n");
811                 GList *last_item = g_list_last(route_data->route_start_addr_list);
812                 if (last_item) {
813                         decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data;
814                         if (route_start_addr_item) {
815                                 route_start_addr_item->municipality = g_strndup((gchar *) ch, len);
816                                 DECARTA_LOGD("characters cb start municipality [%s]\n", route_start_addr_item->municipality);
817                         } else {
818                                 DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n");
819                         }
820                 } else {
821                         DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n");
822                 }
823         } else if (route_data->route_start_state == 12) {
824                 /** start address form address's MunicipalitySubdivision */
825                 DECARTA_LOGD("save the route form address's MunicipalitySubdivision string\n");
826                 GList *last_item = g_list_last(route_data->route_start_addr_list);
827                 if (last_item) {
828                         decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data;
829                         if (route_start_addr_item) {
830                                 route_start_addr_item->municipality_subdivision = g_strndup((gchar *) ch, len);
831                                 DECARTA_LOGD("characters cb start municipality_subdivision [%s]\n", route_start_addr_item->municipality_subdivision);
832                         } else {
833                                 DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n");
834                         }
835                 } else {
836                         DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n");
837                 }
838         } else if (route_data->route_start_state == 13) {
839                 /** start address form address's PostalCode */
840                 DECARTA_LOGD("save the route PostalCode string\n");
841                 GList *last_item = g_list_last(route_data->route_start_addr_list);
842                 if (last_item) {
843                         decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data;
844                         if (route_start_addr_item) {
845                                 route_start_addr_item->postcode = g_strndup((gchar *) ch, len);
846                                 DECARTA_LOGD("characters cb start postcode [%s]\n", route_start_addr_item->postcode);
847                         } else {
848                                 DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n");
849                         }
850                 } else {
851                         DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n");
852                 }
853         } else if (route_data->route_start_state == 14) {
854                 /** start address form address's landmark name */
855                 DECARTA_LOGD("save the route landmark string\n");
856                 GList *last_item = g_list_last(route_data->route_start_addr_list);
857                 if (last_item) {
858                         decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data;
859                         if (route_start_addr_item) {
860                                 route_start_addr_item->landmark_name = g_strndup((gchar *) ch, len);
861                                 DECARTA_LOGD("characters cb start landmark_name [%s]\n", route_start_addr_item->landmark_name);
862                         } else {
863                                 DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n");
864                         }
865                 } else {
866                         DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n");
867                 }
868         } else if (route_data->route_end_state == 3) {
869                 /** end address pos */
870                 DECARTA_LOGD("save the route end address pos string\n");
871                 GList *last_item = g_list_last(route_data->route_end_addr_list);
872                 if (last_item) {
873                         decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data;
874                         if (route_end_addr_item) {
875                                 route_end_addr_item->pos = g_strndup((gchar *) ch, len);
876                                 DECARTA_LOGD("characters cb end pos [%s]\n", route_end_addr_item->pos);
877                         } else {
878                                 DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n");
879                         }
880                 } else {
881                         DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n");
882                 }
883         } else if (route_data->route_end_state == 5) {
884                 /** end address freeform address */
885                 DECARTA_LOGD("save the route end address freeform address string\n");
886                 GList *last_item = g_list_last(route_data->route_end_addr_list);
887                 if (last_item) {
888                         decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data;
889                         if (route_end_addr_item) {
890                                 route_end_addr_item->freeform_addr = g_strndup((gchar *) ch, len);
891                                 DECARTA_LOGD("characters cb end freeform address [%s]\n", route_end_addr_item->freeform_addr);
892                         } else {
893                                 DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n");
894                         }
895                 } else {
896                         DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n");
897                 }
898         } else if (route_data->route_end_state == 8) {
899                 /** end address form address's street */
900                 DECARTA_LOGD("save the route end address form address's street\n");
901                 GList *last_item = g_list_last(route_data->route_end_addr_list);
902                 if (last_item) {
903                         decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data;
904                         if (route_end_addr_item) {
905                                 route_end_addr_item->street = g_strndup((gchar *) ch, len);
906                                 DECARTA_LOGD("characters cb end street [%s]\n", route_end_addr_item->street);
907                         } else {
908                                 DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n");
909                         }
910                 } else {
911                         DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n");
912                 }
913         } else if (route_data->route_end_state == 9) {
914                 /** end address form address's CountrySubdivision */
915                 DECARTA_LOGD("save the route end address form address's CountrySubdivision\n");
916                 GList *last_item = g_list_last(route_data->route_end_addr_list);
917                 if (last_item) {
918                         decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data;
919                         if (route_end_addr_item) {
920                                 route_end_addr_item->country_subdivision = g_strndup((gchar *) ch, len);
921                                 DECARTA_LOGD("characters cb end country_subdivision [%s]\n", route_end_addr_item->country_subdivision);
922                         } else {
923                                 DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n");
924                         }
925                 } else {
926                         DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n");
927                 }
928         } else if (route_data->route_end_state == 10) {
929                 /** end address form address's CountrySecondarySubdivision */
930                 DECARTA_LOGD("save the route end CountrySecondarySubdivision\n");
931                 GList *last_item = g_list_last(route_data->route_end_addr_list);
932                 if (last_item) {
933                         decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data;
934                         if (route_end_addr_item) {
935                                 route_end_addr_item->country_2_subdivision = g_strndup((gchar *) ch, len);
936                                 DECARTA_LOGD("characters cb end country_2_subdivision [%s]\n", route_end_addr_item->country_2_subdivision);
937                         } else {
938                                 DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n");
939                         }
940                 } else {
941                         DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n");
942                 }
943         } else if (route_data->route_end_state == 11) {
944                 /** end address form address's Municipality */
945                 DECARTA_LOGD("save the route end form address's Municipality\n");
946                 GList *last_item = g_list_last(route_data->route_end_addr_list);
947                 if (last_item) {
948                         decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data;
949                         if (route_end_addr_item) {
950                                 route_end_addr_item->municipality = g_strndup((gchar *) ch, len);
951                                 DECARTA_LOGD("characters cb end municipality [%s]\n", route_end_addr_item->municipality);
952                         } else {
953                                 DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n");
954                         }
955                 } else {
956                         DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n");
957                 }
958         } else if (route_data->route_end_state == 12) {
959                 /** end address form address's MunicipalitySubdivision */
960                 DECARTA_LOGD("save the route form end address's MunicipalitySubdivision string\n");
961                 GList *last_item = g_list_last(route_data->route_end_addr_list);
962                 if (last_item) {
963                         decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data;
964                         if (route_end_addr_item) {
965                                 route_end_addr_item->municipality_subdivision = g_strndup((gchar *) ch, len);
966                                 DECARTA_LOGD("characters cb end municipality_subdivision [%s]\n", route_end_addr_item->municipality_subdivision);
967                         } else {
968                                 DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n");
969                         }
970                 } else {
971                         DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n");
972                 }
973         } else if (route_data->route_end_state == 13) {
974                 /** end address form address's PostalCode */
975                 DECARTA_LOGD("save the route end PostalCode string\n");
976                 GList *last_item = g_list_last(route_data->route_end_addr_list);
977                 if (last_item) {
978                         decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data;
979                         if (route_end_addr_item) {
980                                 route_end_addr_item->postcode = g_strndup((gchar *) ch, len);
981                                 DECARTA_LOGD("characters cb end postcode [%s]\n", route_end_addr_item->postcode);
982                         } else {
983                                 DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n");
984                         }
985                 } else {
986                         DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n");
987                 }
988         } else if (route_data->route_end_state == 14) {
989                 /** end address form address's landmark name */
990                 DECARTA_LOGD("save the route end landmark string\n");
991                 GList *last_item = g_list_last(route_data->route_end_addr_list);
992                 if (last_item) {
993                         decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data;
994                         if (route_end_addr_item) {
995                                 route_end_addr_item->landmark_name = g_strndup((gchar *) ch, len);
996                                 DECARTA_LOGD("characters cb end landmark_name [%s]\n", route_end_addr_item->landmark_name);
997                         } else {
998                                 DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n");
999                         }
1000                 } else {
1001                         DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n");
1002                 }
1003         } else if (route_data->route_map_overview_state == 3) {
1004                 /** overview URL */
1005                 DECARTA_LOGD("save the route overview URL string\n");
1006                 route_data->route_ov_tile_url_str = g_strndup((gchar *) ch, len);
1007         } else if (route_data->route_map_overview_state == 5) {
1008                 /** overview pos1 */
1009                 DECARTA_LOGD("save the route overview pos1 string\n");
1010                 route_data->route_ov_pos1_str = g_strndup((const gchar *) ch, len);
1011         } else if (route_data->route_map_overview_state == 7) {
1012                 /** overview pos2 */
1013                 DECARTA_LOGD("save the route overview pos2 string\n");
1014                 route_data->route_ov_pos2_str = g_strndup((gchar *) ch, len);
1015         } else if (route_data->route_instruction_state == 3) {
1016                 /** instruction string */
1017                 DECARTA_LOGD("save the route instruction string\n");
1018                 GList *last_item = g_list_last(route_data->route_inst_str_list);
1019                 if (last_item) {
1020                         decarta_route_inst_str_s *route_inst_item = (decarta_route_inst_str_s *)last_item->data;
1021                         if (route_inst_item) {
1022                                 route_inst_item->instruction = g_strndup((gchar *) ch, len);
1023                                 DECARTA_LOGD("characters cb instruction [%s]\n", route_inst_item->instruction);
1024                         } else {
1025                                 DECARTA_LOGD("[ERROR] characters cb route_inst_item NULL\n");
1026                         }
1027                 } else {
1028                         DECARTA_LOGD("[ERROR] characters cb route_inst_str_list g_list_last NULL\n");
1029                 }
1030         } else if (route_data->route_map_state == 3) {
1031                 /** map URL */
1032                 DECARTA_LOGD("save the route map URL string\n");
1033                 /** Notice: the map URL seprated to pieces */
1034                 GList *last_item = g_list_last(route_data->route_map_str_list);
1035                 if (last_item) {
1036                         decarta_route_map_str_s *route_map_item = (decarta_route_map_str_s *)last_item->data;
1037                         if (route_map_item) {
1038                                 if (route_map_item->url == NULL) {
1039                                         route_map_item->url = g_strndup((gchar *) ch, len);
1040                                 } else {
1041                                         char *former_url = g_strdup(route_map_item->url);
1042                                         g_free(route_map_item->url);
1043                                         char *cur_url = g_strndup((gchar *) ch, len);
1044                                         route_map_item->url = g_strdup_printf("%s%s", former_url, cur_url);
1045                                         g_free(former_url);
1046                                         g_free(cur_url);
1047                                 }
1048                                 DECARTA_LOGD("characters cb URL [%s]\n", route_map_item->url);
1049                         } else {
1050                                 DECARTA_LOGD("[ERROR] characters cb route_map_item NULL\n");
1051                         }
1052                 } else {
1053                         DECARTA_LOGD("[ERROR] characters cb route_map_str_list g_list_last NULL\n");
1054                 }
1055         } else if (route_data->route_map_state == 5) {
1056                 /** map pos1 */
1057                 DECARTA_LOGD("save the route map pos1 string\n");
1058                 GList *last_item = g_list_last(route_data->route_map_str_list);
1059                 if (last_item) {
1060                         decarta_route_map_str_s *route_map_item = (decarta_route_map_str_s *)last_item->data;
1061                         if (route_map_item) {
1062                                 route_map_item->pos1 = g_strndup((gchar *) ch, len);
1063                                 DECARTA_LOGD("characters cb pos1 [%s]\n", route_map_item->pos1);
1064                         } else {
1065                                 DECARTA_LOGD("[ERROR] characters cb route_map_item NULL\n");
1066                         }
1067                 } else {
1068                         DECARTA_LOGD("[ERROR] characters cb route_map_str_list g_list_last NULL\n");
1069                 }
1070         } else if (route_data->route_map_state == 7) {
1071                 /** map pos2 */
1072                 DECARTA_LOGD("save the route map pos2 string\n");
1073                 GList *last_item = g_list_last(route_data->route_map_str_list);
1074                 if (last_item) {
1075                         decarta_route_map_str_s *route_map_item = (decarta_route_map_str_s *)last_item->data;
1076                         if (route_map_item) {
1077                                 route_map_item->pos2 = g_strndup((gchar *) ch, len);
1078                                 DECARTA_LOGD("characters cb pos2 [%s]\n", route_map_item->pos2);
1079                         } else {
1080                                 DECARTA_LOGD("[ERROR] characters cb route_map_item NULL\n");
1081                         }
1082                 } else {
1083                         DECARTA_LOGD("[ERROR] characters cb route_map_str_list g_list_last NULL\n");
1084                 }
1085         } else {
1086                 DECARTA_LOGD("Not save string in character callback\n");
1087         }
1088 }
1089
1090 /**
1091  * __sax_ignorable_whitespace_cb:
1092  * @ctxt:  An XML parser context
1093  * @ch:  a xmlChar string
1094  * @start: the first char in the string
1095  * @len: the number of xmlChar
1096  *
1097  * receiving some ignorable whitespaces from the parser.
1098  * Question: how much at a time ???
1099  */
1100 static void
1101 __sax_ignorable_whitespace_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1102 {
1103         if (!ch) {
1104                 DECARTA_LOGD("[ERROR] ch is NULL\n");
1105                 return;
1106         }
1107
1108         char output[40];
1109         int i;
1110
1111         for (i = 0;(i<len) && (i < 30);i++) {
1112                 output[i] = ch[i];
1113         }
1114         output[i] = 0;
1115         DECARTA_LOGD( "SAX.ignorableWhitespace(%s, %d)\n", output, len);
1116 }
1117
1118 /**
1119  * __sax_processing_instruction_cb:
1120  * @ctxt:  An XML parser context
1121  * @target:  the target name
1122  * @data: the PI data's
1123  * @len: the number of xmlChar
1124  *
1125  * A processing instruction has been parsed.
1126  */
1127 static void
1128 __sax_processing_instruction_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
1129                       const xmlChar *data)
1130 {
1131
1132         if (!target) {
1133                 DECARTA_LOGD("[ERROR] target is NULL\n");
1134                 return;
1135         }
1136         if (data != NULL) {
1137                 DECARTA_LOGD( "SAX.processingInstruction(%s, %s)\n",
1138                         (char *) target, (char *) data);
1139         } else {
1140                 DECARTA_LOGD( "SAX.processingInstruction(%s, NULL)\n",
1141                         (char *) target);
1142         }
1143 }
1144
1145 /**
1146  * __sax_comment_cb:
1147  * @ctxt:  An XML parser context
1148  * @value:  the comment content
1149  *
1150  * A comment has been parsed.
1151  */
1152 static void
1153 __sax_comment_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
1154 {
1155         if (!value) {
1156                 DECARTA_LOGD("[ERROR] value is NULL\n");
1157                 return;
1158         }
1159
1160         DECARTA_LOGD( "SAX.comment(%s)\n", value);
1161 }
1162
1163 /**
1164  * __sax_warning_cb:
1165  * @ctxt:  An XML parser context
1166  * @msg:  the message to display/transmit
1167  * @...:  extra parameters for the message display
1168  *
1169  * Display and format a warning messages, gives file, line, position and
1170  * extra parameters.
1171  */
1172 static void XMLCDECL
1173 __sax_warning_cb(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1174 {
1175         va_list args;
1176
1177         va_start(args, msg);
1178         DECARTA_LOGD( "SAX.warning: ");
1179         vfprintf(stdout, msg, args);
1180         va_end(args);
1181 }
1182
1183 /**
1184  * __sax_error_cb:
1185  * @ctxt:  An XML parser context
1186  * @msg:  the message to display/transmit
1187  * @...:  extra parameters for the message display
1188  *
1189  * Display and format a error messages, gives file, line, position and
1190  * extra parameters.
1191  */
1192 static void XMLCDECL
1193 __sax_error_cb(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1194 {
1195         va_list args;
1196
1197         va_start(args, msg);
1198         DECARTA_LOGD( "SAX.error: ");
1199         vfprintf(stdout, msg, args);
1200         va_end(args);
1201 }
1202
1203 /**
1204  * __sax_fatal_error_cb:
1205  * @ctxt:  An XML parser context
1206  * @msg:  the message to display/transmit
1207  * @...:  extra parameters for the message display
1208  *
1209  * Display and format a fatalError messages, gives file, line, position and
1210  * extra parameters.
1211  */
1212 static void XMLCDECL
1213 __sax_fatal_error_cb(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1214 {
1215         va_list args;
1216
1217         va_start(args, msg);
1218         DECARTA_LOGD( "SAX.fatalError: ");
1219         vfprintf(stdout, msg, args);
1220         va_end(args);
1221 }
1222
1223 /**
1224  * __sax_get_parameter_entity_cb:
1225  * @ctxt:  An XML parser context
1226  * @name: The entity name
1227  *
1228  * Get a parameter entity by name
1229  *
1230  * Returns the xmlParserInputPtr
1231  */
1232 static xmlEntityPtr
1233 __sax_get_parameter_entity_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1234 {
1235         if (!name) {
1236                 DECARTA_LOGD("[ERROR] name is NULL\n");
1237                 return(NULL);
1238         }
1239
1240         DECARTA_LOGD( "SAX.getParameterEntity(%s)\n", name);
1241         return(NULL);
1242 }
1243
1244 /**
1245  * __sax_cdata_block_cb:
1246  * @ctx: the user data (XML parser context)
1247  * @value:  The pcdata content
1248  * @len:  the block length
1249  *
1250  * called when a pcdata block has been parsed
1251  */
1252 static void
1253 __sax_cdata_block_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
1254 {
1255
1256         if (!value) {
1257                 DECARTA_LOGD("[ERROR] value is NULL\n");
1258                 return;
1259         }
1260         DECARTA_LOGD( "SAX.pcdata(%.20s, %d)\n",
1261                 (char *) value, len);
1262 }
1263
1264 /**
1265  * __sax_external_subset_cb:
1266  * @ctxt:  An XML parser context
1267  *
1268  * Does this document has an external subset
1269  */
1270 static void
1271 __sax_external_subset_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1272                const xmlChar *ExternalID, const xmlChar *SystemID)
1273 {
1274
1275         if (!name) {
1276                 DECARTA_LOGD("[ERROR] name is NULL\n");
1277                 return;
1278         }
1279         DECARTA_LOGD( "SAX.externalSubset(%s,", name);
1280         if (ExternalID == NULL) {
1281                 DECARTA_LOGD( " ,");
1282         } else {
1283                 DECARTA_LOGD( " %s,", ExternalID);
1284         }
1285         if (SystemID == NULL) {
1286                 DECARTA_LOGD( " )\n");
1287         } else {
1288                 DECARTA_LOGD( " %s)\n", SystemID);
1289         }
1290 }
1291
1292 /*
1293  * SAX2 specific callbacks
1294  */
1295 /**
1296  * __sax_start_element_ns_cb:
1297  * @ctxt:  An XML parser context
1298  * @name:  The element name
1299  *
1300  * called when an opening tag has been processed.
1301  */
1302 static void
1303 __sax_start_element_ns_cb(void *ctx,
1304                     const xmlChar *localname,
1305                     const xmlChar *prefix,
1306                     const xmlChar *URI,
1307                     int nb_namespaces,
1308                     const xmlChar **namespaces,
1309                     int nb_attributes,
1310                     int nb_defaulted,
1311                     const xmlChar **attributes)
1312 {
1313         if (!ctx || !localname) {
1314                 DECARTA_LOGD("[ERROR] ctx or localname is NULL\n");
1315                 return;
1316         }
1317
1318         DECARTA_LOGD( "SAX.startElementNs(%s)", (char *) localname);
1319         int i = 0;
1320         int j = 0;
1321         sax_route_data_s *route_data = (sax_route_data_s *)ctx;
1322
1323         if (!g_strcmp0("Error", (char *) localname)) {
1324                 DECARTA_LOGD("Response Error!");
1325                 route_data->has_error = 1;
1326                 /** <ns1:Error severity="Error" message="not implemented" errorCode="NotSupported"/> */
1327                 if (attributes != NULL) {
1328                         for (i = 0;i < nb_attributes * 5;i += 5) {
1329                                 if (attributes[i] && !g_strcmp0("severity", (char *) attributes[i])) {
1330                                         route_data->error_severity_str = g_strndup((gchar *) attributes[i + 3],
1331                                                 (int)(attributes[i + 4] - attributes[i + 3]));
1332                                         DECARTA_LOGD("severity: [%s]", route_data->error_severity_str);
1333                                 } else if (attributes[i] && !g_strcmp0("message", (char *) attributes[i])) {
1334                                         route_data->error_message_str = g_strndup((gchar *) attributes[i + 3],
1335                                                 (int)(attributes[i + 4] - attributes[i + 3]));
1336                                         DECARTA_LOGD("message: [%s]\n", route_data->error_message_str);
1337                                 } else if (attributes[i] && !g_strcmp0("errorCode", (char *) attributes[i])) {
1338                                         route_data->error_code_str = g_strndup((gchar *) attributes[i + 3],
1339                                                 (int)(attributes[i + 4] - attributes[i + 3]));
1340                                         DECARTA_LOGD("errorCode: [%s]\n", route_data->error_code_str);
1341                                 }
1342                         }
1343                 }
1344         } else if (!g_strcmp0("DetermineRouteResponse", (char *) localname)) {
1345                 route_data->has_route_resp = 1;
1346         } else if (!g_strcmp0("VectorString", (char *) localname)) {
1347                 DECARTA_LOGD("enter the VectorString state");
1348                 route_data->route_geometry_state = 1;
1349         } else if (!g_strcmp0("TotalTime", (char *) localname)) {
1350                 route_data->route_totaltime_state = 1;
1351         } else if (!g_strcmp0("TotalDistance", (char *) localname)) {
1352                 route_data->route_totaldist_state = 1;
1353                 /** total distance is attribute: value='1796...' */
1354                 if (attributes != NULL) {
1355                         for (i = 0;i < nb_attributes * 5;i += 5) {
1356                                 if (attributes[i] && !g_strcmp0("value", (char *) attributes[i])) {
1357                                         route_data->route_totaldist_str = g_strndup((gchar *) attributes[i + 3],
1358                                                 (int)(attributes[i + 4] - attributes[i + 3]));
1359                                         DECARTA_LOGD("TotalDistance: %s\n", route_data->route_totaldist_str);
1360                                 }
1361                         }
1362                 }
1363         } else if (!g_strcmp0("BoundingBox", (char *) localname)) {
1364                 route_data->route_bbox_state = 1;
1365         } else if (!g_strcmp0("StartAddressCandidates", (char *) localname)) {
1366                 route_data->route_start_state = 1;
1367         } else if (!g_strcmp0("EndAddressCandidates", (char *) localname)) {
1368                 route_data->route_end_state = 1;
1369         } else if (!g_strcmp0("GeocodedAddress", (char *) localname)) {
1370                 if (route_data->route_start_state == 1) {
1371                         route_data->route_start_state = 2;
1372                         /** create one geocoded address item, and append to list */
1373                         decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)g_new0(decarta_geo_addr_s, 1);
1374                         route_start_addr_item->is_freeform = 0;
1375                         route_data->route_start_addr_list = g_list_append (route_data->route_start_addr_list, (gpointer)route_start_addr_item);
1376                 } else if (route_data->route_end_state == 1) {
1377                         route_data->route_end_state = 2;
1378                         /** create one geocoded address item, and append to list */
1379                         decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)g_new0(decarta_geo_addr_s, 1);
1380                         route_end_addr_item->is_freeform = 0;
1381                         route_data->route_end_addr_list = g_list_append (route_data->route_end_addr_list, (gpointer)route_end_addr_item);
1382                 }
1383         } else if (!g_strcmp0("Point", (char *) localname)) {
1384                 /** plz ignore <Point> element, maybe not exist */
1385         } else if (!g_strcmp0("pos", (char *) localname)) {
1386                 if (route_data->route_bbox_state == 1) {
1387                         route_data->route_bbox_state = 2;
1388                 } else if (route_data->route_bbox_state == 3) {
1389                         route_data->route_bbox_state = 4;
1390                 } else if (route_data->route_map_overview_state == 4) {
1391                         /** overview pos1 */
1392                         route_data->route_map_overview_state = 5;
1393                 } else if (route_data->route_map_overview_state == 6) {
1394                         /** overview pos2 */
1395                         route_data->route_map_overview_state = 7;
1396                 } else if (route_data->route_map_state == 4) {
1397                         /** map pos1 */
1398                         route_data->route_map_state = 5;
1399                 } else if (route_data->route_map_state == 6) {
1400                         /** map pos2 */
1401                         route_data->route_map_state = 7;
1402                 } else if (route_data->route_start_state == 2) {
1403                         route_data->route_start_state = 3;
1404                 } else if (route_data->route_end_state == 2) {
1405                         route_data->route_end_state = 3;
1406                 }
1407         } else if (!g_strcmp0("Address", (char *) localname)) {
1408                 if (route_data->route_start_state == 2) {
1409                         route_data->route_start_state = 4;
1410                         if (attributes != NULL) {
1411                                 for (i = 0;i < nb_attributes * 5;i += 5) {
1412                                         if (attributes[i] && !g_strcmp0("countryCode", (char *) attributes[i])) {
1413                                                 GList *last_item = g_list_last(route_data->route_start_addr_list);
1414                                                 if (last_item) {
1415                                                         decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data;
1416                                                         if (route_start_addr_item) {
1417                                                                 route_start_addr_item->country_code = g_strndup((gchar *) attributes[i + 3],
1418                                                                         (int)(attributes[i + 4] - attributes[i + 3]));
1419                                                                 DECARTA_LOGD("countryCode [%s]\n", route_start_addr_item->country_code);
1420                                                         } else {
1421                                                                 DECARTA_LOGD("[ERROR] route_start_addr_item NULL\n");
1422                                                         }
1423                                                 } else {
1424                                                         DECARTA_LOGD("[ERROR] g_list_last NULL\n");
1425                                                 }
1426
1427                                         } else if (attributes[i] && !g_strcmp0("language", (char *) attributes[i])) {
1428                                                 GList *last_item = g_list_last(route_data->route_start_addr_list);
1429                                                 if (last_item) {
1430                                                         decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data;
1431                                                         if (route_start_addr_item) {
1432                                                                 route_start_addr_item->lang_code = g_strndup((gchar *) attributes[i + 3],
1433                                                                         (int)(attributes[i + 4] - attributes[i + 3]));
1434                                                                 DECARTA_LOGD("lang_code [%s]\n", route_start_addr_item->lang_code);
1435                                                         } else {
1436                                                                 DECARTA_LOGD("[ERROR] route_start_addr_item NULL\n");
1437                                                         }
1438                                                 } else {
1439                                                         DECARTA_LOGD("[ERROR] g_list_last NULL\n");
1440                                                 }
1441                                         }
1442                                 }
1443                         }
1444                 } else if (route_data->route_end_state == 2) {
1445                         route_data->route_end_state = 4;
1446                         if (attributes != NULL) {
1447                                 for (i = 0;i < nb_attributes * 5;i += 5) {
1448                                         if (attributes[i] && !g_strcmp0("countryCode", (char *) attributes[i])) {
1449                                                 GList *last_item = g_list_last(route_data->route_end_addr_list);
1450                                                 if (last_item) {
1451                                                         decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data;
1452                                                         if (route_end_addr_item) {
1453                                                                 route_end_addr_item->country_code = g_strndup((gchar *) attributes[i + 3],
1454                                                                         (int)(attributes[i + 4] - attributes[i + 3]));
1455                                                                 DECARTA_LOGD("countryCode [%s]\n", route_end_addr_item->country_code);
1456                                                         } else {
1457                                                                 DECARTA_LOGD("[ERROR] route_end_addr_item NULL\n");
1458                                                         }
1459                                                 } else {
1460                                                         DECARTA_LOGD("[ERROR] g_list_last NULL\n");
1461                                                 }
1462
1463                                         } else if (attributes[i] && !g_strcmp0("language", (char *) attributes[i])) {
1464                                                 GList *last_item = g_list_last(route_data->route_end_addr_list);
1465                                                 if (last_item) {
1466                                                         decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data;
1467                                                         if (route_end_addr_item) {
1468                                                                 route_end_addr_item->lang_code = g_strndup((gchar *) attributes[i + 3],
1469                                                                         (int)(attributes[i + 4] - attributes[i + 3]));
1470                                                                 DECARTA_LOGD("lang_code [%s]\n", route_end_addr_item->lang_code);
1471                                                         } else {
1472                                                                 DECARTA_LOGD("[ERROR] route_end_addr_item NULL\n");
1473                                                         }
1474                                                 } else {
1475                                                         DECARTA_LOGD("[ERROR] g_list_last NULL\n");
1476                                                 }
1477
1478                                         }
1479                                 }
1480                         }
1481                 }
1482         } else if (!g_strcmp0("freeFormAddress", (char *) localname)) {
1483                 if (route_data->route_start_state == 4) {
1484                         /** get free address, set free form address flag */
1485                         route_data->route_start_state = 5;
1486                         GList *last_item = g_list_last(route_data->route_start_addr_list);
1487                         if (last_item) {
1488                                 decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data;
1489                                 route_start_addr_item->is_freeform = 1;
1490                         } else {
1491                                 DECARTA_LOGD("[ERROR] g_list_last NULL\n");
1492                         }
1493                 } else if (route_data->route_end_state == 4) {
1494                         route_data->route_end_state = 5;
1495                         GList *last_item = g_list_last(route_data->route_end_addr_list);
1496                         if (last_item) {
1497                                 decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data;
1498                                 route_end_addr_item->is_freeform = 1;
1499                         } else {
1500                                 DECARTA_LOGD("[ERROR] g_list_last NULL\n");
1501                         }
1502                 }
1503         } else if (!g_strcmp0("StreetAddress", (char *) localname)) {
1504                 if (route_data->route_start_state == 4) {
1505                         route_data->route_start_state = 6;
1506                 } else if (route_data->route_end_state == 4) {
1507                         route_data->route_end_state = 6;
1508                 }
1509         } else if (!g_strcmp0("Building", (char *) localname)) {
1510                 if (route_data->route_start_state == 6) {
1511                         route_data->route_start_state = 7;
1512                         if (attributes != NULL) {
1513                                 for (i = 0;i < nb_attributes * 5;i += 5) {
1514                                         if (attributes[i] && !g_strcmp0("number", (char *) attributes[i])) {
1515                                                 GList *last_item = g_list_last(route_data->route_start_addr_list);
1516                                                 if (last_item) {
1517                                                         decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data;
1518                                                         if (route_start_addr_item) {
1519                                                                 route_start_addr_item->building_num = g_strndup((gchar *) attributes[i + 3],
1520                                                                         (int)(attributes[i + 4] - attributes[i + 3]));
1521                                                                 DECARTA_LOGD("building_num [%s]\n", route_start_addr_item->building_num);
1522                                                         } else {
1523                                                                 DECARTA_LOGD("[ERROR] route_start_addr_item NULL\n");
1524                                                         }
1525                                                 } else {
1526                                                         DECARTA_LOGD("[ERROR] g_list_last NULL\n");
1527                                                 }
1528                                         }
1529                                 }
1530                         }
1531                 }else if (route_data->route_end_state == 6) {
1532                         route_data->route_end_state = 7;
1533                         if (attributes != NULL) {
1534                                 for (i = 0;i < nb_attributes * 5;i += 5) {
1535                                         if (attributes[i] && !g_strcmp0("number", (char *) attributes[i])) {
1536                                                 GList *last_item = g_list_last(route_data->route_end_addr_list);
1537                                                 if (last_item) {
1538                                                         decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data;
1539                                                         if (route_end_addr_item) {
1540                                                                 route_end_addr_item->building_num = g_strndup((gchar *) attributes[i + 3],
1541                                                                         (int)(attributes[i + 4] - attributes[i + 3]));
1542                                                                 DECARTA_LOGD("building_num [%s]\n", route_end_addr_item->building_num);
1543                                                         } else {
1544                                                                 DECARTA_LOGD("[ERROR] route_end_addr_item NULL\n");
1545                                                         }
1546                                                 } else {
1547                                                         DECARTA_LOGD("[ERROR] g_list_last NULL\n");
1548                                                 }
1549                                         }
1550                                 }
1551                         }
1552                 }
1553         } else if (!g_strcmp0("Street", (char *) localname)) {
1554                 if (route_data->route_start_state == 6) {
1555                         route_data->route_start_state = 8;
1556                 } else if (route_data->route_end_state == 6) {
1557                         route_data->route_end_state = 8;
1558
1559                 }
1560         } else if (!g_strcmp0("Place", (char *) localname)) {
1561                 if (attributes != NULL) {
1562                         for (i = 0;i < nb_attributes * 5;i += 5) {
1563                                 if (attributes[i] && !g_strcmp0("type", (char *) attributes[i])) {
1564                                         char *type = g_strndup((gchar *) attributes[i + 3],
1565                                                 (int)(attributes[i + 4] - attributes[i + 3]));
1566                                         if (!g_strcmp0("CountrySubDivision", type)) {
1567                                                 if (route_data->route_start_state == 4) {
1568                                                         route_data->route_start_state = 9;
1569                                                 } else if (route_data->route_end_state == 4) {
1570                                                         route_data->route_end_state = 9;
1571                                                 }
1572                                         } else if (!g_strcmp0("CountrySecondarySubDivision", type)) {
1573                                                 if (route_data->route_start_state == 4) {
1574                                                         route_data->route_start_state = 10;
1575                                                 } else if (route_data->route_end_state == 4) {
1576                                                         route_data->route_end_state = 10;
1577                                                 }
1578                                         } else if (!g_strcmp0("Municipality", type)) {
1579                                                 if (route_data->route_start_state == 4) {
1580                                                         route_data->route_start_state = 11;
1581                                                 } else if (route_data->route_end_state == 4) {
1582                                                         route_data->route_end_state = 11;
1583                                                 }
1584                                         } else if (!g_strcmp0("MunicipalitySubdivision", type)) {
1585                                                 if (route_data->route_start_state == 4) {
1586                                                         route_data->route_start_state = 12;
1587                                                 } else if (route_data->route_end_state == 4) {
1588                                                         route_data->route_end_state = 12;
1589                                                 }
1590                                         } else if (!g_strcmp0("Landmark", type)) {
1591                                                 if (route_data->route_start_state == 4) {
1592                                                         route_data->route_start_state = 14;
1593                                                         for (j = 0; j < nb_attributes * 5; j += 5) {
1594                                                                 if (attributes[j] && !g_strcmp0("subType", (char *) attributes[j])) {
1595                                                                         GList *last_item = g_list_last(route_data->route_start_addr_list);
1596                                                                         if (last_item) {
1597                                                                                 decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data;
1598                                                                                 route_start_addr_item->landmark_type = g_strndup((gchar *) attributes[j + 3],
1599                                                                                         (int)(attributes[j + 4] - attributes[j + 3]));
1600                                                                         }
1601                                                                 }
1602                                                         }
1603                                                 } else if (route_data->route_end_state == 4) {
1604                                                         route_data->route_end_state = 14;
1605                                                         for (j = 0; j < nb_attributes * 5; j += 5) {
1606                                                                 if (attributes[j] && !g_strcmp0("subType", (char *) attributes[j])) {
1607                                                                         GList *last_item = g_list_last(route_data->route_end_addr_list);
1608                                                                         if (last_item) {
1609                                                                                 decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data;
1610                                                                                 route_end_addr_item->landmark_type = g_strndup((gchar *) attributes[j + 3],
1611                                                                                         (int)(attributes[j + 4] - attributes[j + 3]));
1612                                                                         }
1613                                                                 }
1614                                                         }
1615                                                 }
1616                                         }
1617                                         g_free(type);
1618                                 }
1619                         }
1620                 }
1621         } else if (!g_strcmp0("PostalCode", (char *) localname)) {
1622                 if (route_data->route_start_state == 4) {
1623                         route_data->route_start_state = 13;
1624                 } else if (route_data->route_end_state == 4) {
1625                         route_data->route_end_state = 13;
1626                 }
1627         } else if (!g_strcmp0("RouteMap", (char *) localname)) {
1628
1629                 decarta_route_map_str_s *route_map_item = (decarta_route_map_str_s *)g_new0(decarta_route_map_str_s, 1);
1630                 route_map_item->url = NULL;
1631                 route_data->route_map_str_list = g_list_append (route_data->route_map_str_list, (gpointer)route_map_item);
1632                 if (attributes != NULL) {
1633                         for (i = 0;i < nb_attributes * 5;i += 5) {
1634                                 if (attributes[i] && !g_strcmp0("description", (char *) attributes[i])) {
1635                                         route_map_item->description = g_strndup((gchar *) attributes[i + 3],
1636                                                 (int)(attributes[i + 4] - attributes[i + 3]));
1637                                         if (!g_strcmp0("Route Overview", route_map_item->description)) {
1638                                                 DECARTA_LOGD("RouteMap: description=Route Overview\n");
1639                                                 /** <xls:RouteMap description="Route Overview"> */
1640                                                 route_data->route_map_overview_state = 1;
1641                                         } else {
1642                                                 /** RouteMap */
1643                                                 route_data->route_map_state = 1;
1644                                         }
1645                                 }
1646                         }
1647                 }
1648         } else if (!g_strcmp0("Content", (char *) localname)) {
1649                 if (route_data->route_map_overview_state == 1) {
1650                         route_data->route_map_overview_state = 2;
1651                 } else if (route_data->route_map_state == 1) {
1652                         route_data->route_map_state = 2;
1653                 }
1654         } else if (!g_strcmp0("URL", (char *) localname)) {
1655                 if (route_data->route_map_overview_state == 2) {
1656                         /** URL string */
1657                         route_data->route_map_overview_state = 3;
1658                 } else if (route_data->route_map_state == 2) {
1659                         /** get URL string*/
1660                         route_data->route_map_state = 3;
1661                 }
1662         } else if (!g_strcmp0("BBoxContext", (char *) localname)) {
1663                 if (route_data->route_map_overview_state == 1) {
1664                         /** BBoxContext */
1665                         route_data->route_map_overview_state = 4;
1666                 } else if (route_data->route_map_state == 1) {
1667                         /** BBoxContext */
1668                         route_data->route_map_state = 4;
1669                 }
1670         } else if (!g_strcmp0("RouteInstructionsList", (char *) localname)) {
1671                 route_data->route_instruction_state = 1;
1672         } else if (!g_strcmp0("RouteInstruction", (char *) localname)) {
1673                 if (route_data->route_instruction_state == 1) {
1674                         /** RouteInstruction */
1675                         route_data->route_instruction_state = 2;
1676                         decarta_route_inst_str_s *route_inst_item = (decarta_route_inst_str_s *)g_new0(decarta_route_inst_str_s, 1);
1677                         route_data->route_inst_str_list = g_list_append (route_data->route_inst_str_list, (gpointer)route_inst_item);
1678                         /** <xls:RouteInstruction description="route maneuver 1" duration="PT0H0M0S" tour="0"> */
1679                         if (attributes != NULL) {
1680                                 for (i = 0;i < nb_attributes * 5;i += 5) {
1681                                         if (attributes[i] && !g_strcmp0("description", (char *) attributes[i])) {
1682                                                 route_inst_item->description = g_strndup((gchar *) attributes[i + 3],
1683                                                         (int)(attributes[i + 4] - attributes[i + 3]));
1684                                                 DECARTA_LOGD("description: %s\n", route_inst_item->description);
1685                                         } else if (attributes[i] && !g_strcmp0("duration", (char *) attributes[i])) {
1686                                                 route_inst_item->duration = g_strndup((gchar *) attributes[i + 3],
1687                                                         (int)(attributes[i + 4] - attributes[i + 3]));
1688                                                 DECARTA_LOGD("duration: %s\n", route_inst_item->duration);
1689                                         } else if (attributes[i] && !g_strcmp0("tour", (char *) attributes[i])) {
1690                                                 route_inst_item->tour = g_strndup((gchar *) attributes[i + 3],
1691                                                         (int)(attributes[i + 4] - attributes[i + 3]));
1692                                                 DECARTA_LOGD("tour: %s\n", route_inst_item->tour);
1693                                         }
1694                                 }
1695                         }
1696                 }
1697         } else if (!g_strcmp0("Instruction", (char *) localname)) {
1698                 if (route_data->route_instruction_state == 2) {
1699                          /** get instruction string */
1700                         route_data->route_instruction_state = 3;
1701                 }
1702         } else if (!g_strcmp0("distance", (char *) localname)) {
1703                 if (route_data->route_instruction_state == 2) {
1704                         /** <xls:distance value="0.00"/> */
1705                         route_data->route_instruction_state = 4;
1706                         GList *last_item = g_list_last(route_data->route_inst_str_list);
1707                         if (last_item) {
1708                                 decarta_route_inst_str_s *route_inst_item = (decarta_route_inst_str_s *)last_item->data;
1709                                 if (attributes != NULL) {
1710                                         for (i = 0;i < nb_attributes * 5;i += 5) {
1711                                                 if (attributes[i] && !g_strcmp0("value", (char *) attributes[i])) {
1712                                                         if (route_inst_item) {
1713                                                                 route_inst_item->distance = g_strndup((gchar *) attributes[i + 3],
1714                                                                         (int)(attributes[i + 4] - attributes[i + 3]));
1715                                                                 DECARTA_LOGD("distance value: %s\n", route_inst_item->distance);
1716                                                         } else {
1717                                                                 DECARTA_LOGD("[ERROR] startElement <distance>: route_inst_item NULL\n ");
1718                                                                 char *distance = g_strndup((gchar *) attributes[i + 3],
1719                                                                         (int)(attributes[i + 4] - attributes[i + 3]));
1720                                                                 DECARTA_LOGD("distance value: %s\n", distance);
1721                                                                 g_free(distance);
1722                                                         }
1723                                                 }
1724                                         }
1725                                 }
1726                         } else {
1727                                 DECARTA_LOGD("[ERROR] startElement <distance>: g_list_last NULL\n ");
1728                         }
1729                 }
1730         } else {
1731         }
1732 }
1733
1734 /**
1735  * __sax_end_element_ns_cb:
1736  * @ctxt:  An XML parser context
1737  * @name:  The element name
1738  *
1739  * called when the end of an element has been detected.
1740  */
1741 static void
1742 __sax_end_element_ns_cb(void *ctx,
1743                   const xmlChar *localname,
1744                   const xmlChar *prefix,
1745                   const xmlChar *URI)
1746 {
1747         if (!ctx || !localname) {
1748                 DECARTA_LOGD("[ERROR] ctx or localname is NULL\n");
1749                 return;
1750         }
1751
1752         DECARTA_LOGD( "SAX.endElementNs(%s)", (char *) localname);
1753
1754         sax_route_data_s *route_data = (sax_route_data_s *)ctx;
1755         if (!g_strcmp0("VectorString", (char *) localname)) {
1756                 DECARTA_LOGD("leave the VectorString state");
1757                 route_data->route_geometry_state = 0;
1758         } else if (!g_strcmp0("TotalTime", (char *) localname)) {
1759                 route_data->route_totaltime_state = 0;
1760         } else if (!g_strcmp0("TotalDistance", (char *) localname)) {
1761                 route_data->route_totaldist_state = 0;
1762         } else if (!g_strcmp0("BoundingBox", (char *) localname)) {
1763                 route_data->route_bbox_state = 0;
1764         } else if (!g_strcmp0("pos", (char *) localname)) {
1765                 if (route_data->route_bbox_state == 2) {
1766                         route_data->route_bbox_state = 3;
1767                 } else if (route_data->route_bbox_state == 4) {
1768                         route_data->route_bbox_state = 1;
1769                 } else if (route_data->route_map_state == 5) {
1770                         /** map pos1 -> pos2 */
1771                         route_data->route_map_state = 6;
1772                 } else if (route_data->route_map_state == 7) {
1773                         /** map pos2 -> BBoxContext */
1774                         route_data->route_map_state = 4;
1775                 } else if (route_data->route_map_overview_state == 5) {
1776                         /** overview pos1 -> pos2 */
1777                         route_data->route_map_overview_state = 6;
1778                 } else if (route_data->route_map_overview_state == 7) {
1779                         /** overview pos2 -> BBoxContext */
1780                         route_data->route_map_overview_state = 4;
1781                 } else if (route_data->route_start_state == 3) {
1782                         route_data->route_start_state = 2;
1783                 } else if (route_data->route_end_state == 3) {
1784                         route_data->route_end_state = 2;
1785                 }
1786         } else if (!g_strcmp0("StartAddressCandidates", (char *) localname)) {
1787                 route_data->route_start_state = 0;
1788         } else if (!g_strcmp0("EndAddressCandidates", (char *) localname)) {
1789                 route_data->route_end_state = 0;
1790         } else if (!g_strcmp0("GeocodedAddress", (char *) localname)) {
1791                 if (route_data->route_start_state == 2) {
1792                         route_data->route_start_state = 1;
1793                 } else if (route_data->route_end_state == 2) {
1794                         route_data->route_end_state = 1;
1795                 }
1796         } else if (!g_strcmp0("Point", (char *) localname)) {
1797                 /** plz ignore this. */
1798         } else if (!g_strcmp0("Address", (char *) localname)) {
1799                 if (route_data->route_start_state == 4) {
1800                         route_data->route_start_state = 2;
1801                 } else if (route_data->route_end_state == 4) {
1802                         route_data->route_end_state = 2;
1803                 }
1804         } else if (!g_strcmp0("freeFormAddress", (char *) localname)) {
1805                 if (route_data->route_start_state == 5) {
1806                         route_data->route_start_state = 4;
1807                 } else if (route_data->route_end_state == 5) {
1808                         route_data->route_end_state = 4;
1809                 }
1810         } else if (!g_strcmp0("StreetAddress", (char *) localname)) {
1811                 if (route_data->route_start_state == 6) {
1812                         route_data->route_start_state = 4;
1813                 } else if (route_data->route_end_state == 6) {
1814                         route_data->route_end_state = 4;
1815                 }
1816         } else if (!g_strcmp0("Building", (char *) localname)) {
1817                 if (route_data->route_start_state == 7) {
1818                         route_data->route_start_state = 6;
1819                 } else if (route_data->route_end_state == 7) {
1820                         route_data->route_end_state = 6;
1821                 }
1822         } else if (!g_strcmp0("Street", (char *) localname)) {
1823                 if (route_data->route_start_state == 8) {
1824                         route_data->route_start_state = 6;
1825                 } else if (route_data->route_end_state == 8) {
1826                         route_data->route_end_state = 6;
1827                 }
1828         } else if (!g_strcmp0("Place", (char *) localname)) {
1829                 if (route_data->route_start_state != 0) {
1830                         route_data->route_start_state = 4;
1831                 } else if (route_data->route_end_state != 0) {
1832                         route_data->route_end_state = 4;
1833                 }
1834         } else if (!g_strcmp0("PostalCode", (char *) localname)) {
1835                 if (route_data->route_start_state == 13) {
1836                         route_data->route_start_state = 4;
1837                 } else if (route_data->route_end_state == 13) {
1838                         route_data->route_end_state = 4;
1839                 }
1840         } else if (!g_strcmp0("RouteMap", (char *) localname)) {
1841                 if (route_data->route_map_overview_state == 1) {
1842                         route_data->route_map_overview_state = 0;
1843                 } else if (route_data->route_map_state == 1) {
1844                         route_data->route_map_state = 0;
1845                 }
1846         } else if (!g_strcmp0("Content", (char *) localname)) {
1847                 if (route_data->route_map_overview_state == 2) {
1848                         route_data->route_map_overview_state = 1;
1849                 } else if (route_data->route_map_state == 2) {
1850                         /** Content -> RouteMap */
1851                         route_data->route_map_state = 1;
1852                 }
1853         } else if (!g_strcmp0("URL", (char *) localname)) {
1854                 if (route_data->route_map_overview_state == 3) {
1855                         route_data->route_map_overview_state = 2;
1856                 } else if (route_data->route_map_state == 3) {
1857                         /** URL -> Content */
1858                         route_data->route_map_state = 2;
1859                 }
1860
1861         } else if (!g_strcmp0("BBoxContext", (char *) localname)) {
1862                 if (route_data->route_map_overview_state == 4) {
1863                         route_data->route_map_overview_state = 1;
1864                 } else if (route_data->route_map_state == 4) {
1865                         /** BBoxContext -> RouteMap */
1866                         route_data->route_map_state = 1;
1867                 }
1868
1869         } else if (!g_strcmp0("RouteInstructionsList", (char *) localname)) {
1870                 route_data->route_instruction_state = 0;
1871         } else if (!g_strcmp0("RouteInstruction", (char *) localname)) {
1872                 if (route_data->route_instruction_state == 2) {
1873                         /** "distance" -> next "RouteInstruction" */
1874                         route_data->route_instruction_state = 1;
1875                 }
1876         } else if (!g_strcmp0("Instruction", (char *) localname)) {
1877                 if (route_data->route_instruction_state == 3) {
1878                         route_data->route_instruction_state = 2;
1879                 }
1880         } else if (!g_strcmp0("distance", (char *) localname)) {
1881                 if (route_data->route_instruction_state == 4) {
1882                         route_data->route_instruction_state = 2;
1883                 }
1884         } else {
1885         }
1886 }
1887
1888
1889 static xmlSAXHandler __sax2_handler_struct = {
1890     __sax_internal_subset_cb,
1891     __sax_is_standalone_cb,
1892     __sax_has_internal_subset_cb,
1893     __sax_has_external_subset_cb,
1894     __sax_resolve_entity_cb,
1895     __sax_get_entity_cb,
1896     __sax_entity_decl_cb,
1897     __sax_notation_decl_cb,
1898     __sax_attribute_decl_cb,
1899     __sax_element_decl_cb,
1900     __sax_unparsed_entity_decl_cb,
1901     __sax_set_document_locator_cb,
1902     __sax_start_document_cb,
1903     __sax_end_document_cb,
1904     NULL,
1905     NULL,
1906     __sax_reference_cb,
1907     __sax_characters_cb,
1908     __sax_ignorable_whitespace_cb,
1909     __sax_processing_instruction_cb,
1910     __sax_comment_cb,
1911     __sax_warning_cb,
1912     __sax_error_cb,
1913     __sax_fatal_error_cb,
1914     __sax_get_parameter_entity_cb,
1915     __sax_cdata_block_cb,
1916     __sax_external_subset_cb,
1917     XML_SAX2_MAGIC,
1918     NULL,
1919     __sax_start_element_ns_cb,
1920     __sax_end_element_ns_cb,
1921     NULL
1922 };
1923
1924 static xmlSAXHandlerPtr __sax2_handler = &__sax2_handler_struct;
1925
1926 int _xml_sax_read(const char* data, void *user_data)
1927 {
1928         if (!data || !user_data) {
1929                 DECARTA_LOGD("[ERROR] data or user_data is NULL");
1930                 return -1;
1931         }
1932
1933         int ret_val = -1;
1934         char *xml_data = remove_noise(data);
1935         if (xml_data) {
1936                 ret_val = xmlSAXUserParseMemory(__sax2_handler, user_data, (const char *)xml_data, strlen(xml_data));
1937                 if (ret_val != 0) {
1938                         DECARTA_LOGD( "[ERROR] xmlSAXUserParseFile error [%d]", ret_val);
1939                 }
1940                 free(xml_data);
1941         }
1942         return ret_val;
1943 }
1944