Add wbxml_tree_from_xml_with_lang function 06/4006/1
authorBaptiste DURAND <baptiste.durand@eurogiciel.fr>
Fri, 14 Jun 2013 12:30:05 +0000 (14:30 +0200)
committerBaptiste DURAND <baptiste.durand@eurogiciel.fr>
Fri, 14 Jun 2013 12:30:05 +0000 (14:30 +0200)
It permits to parse an XML document with given language and construct a WBXML Tree

needed sync-agent component

src/wbxml_tree.c
src/wbxml_tree.h

index e30da74d4d6accbaf4bc3f8aab3d90c469db59dc..d074e4254fd4a4a7a59c0d63410419811e0d27d2 100644 (file)
@@ -295,6 +295,119 @@ WBXML_DECLARE(WBXMLError) wbxml_tree_from_xml(WB_UTINY *xml, WB_ULONG xml_len, W
 }
 
 
+WBXML_DECLARE(WBXMLError) wbxml_tree_from_xml_with_lang(WB_UTINY *xml,
+                                              WB_ULONG xml_len,
+                                              WBXMLLanguage lang,
+                                              WBXMLTree **tree)
+{
+#if defined( HAVE_EXPAT )
+
+    const XML_Feature *feature_list = NULL;
+    XML_Parser         xml_parser   = NULL;
+    WBXMLError         ret          = WBXML_OK;
+    WB_BOOL            expat_utf16  = FALSE;
+    WBXMLTreeClbCtx    wbxml_tree_clb_ctx;
+
+    /* First Check if Expat is outputing UTF-16 strings */
+    feature_list = (const XML_Feature *)XML_GetFeatureList();
+
+    if ((feature_list != NULL) && (feature_list[0].value != sizeof(WB_TINY))) {
+#if !defined( HAVE_ICONV )
+        /* Ouch, can't convert from UTF-16 to UTF-8 */
+        return WBXML_ERROR_XMLPARSER_OUTPUT_UTF16;
+#else
+        /* Expat returns UTF-16 encoded strings in its callbacks */
+        expat_utf16 = TRUE;
+#endif /* !HAVE_ICONV */
+    }
+
+    if (tree != NULL)
+        *tree = NULL;
+
+    /* Create Expat XML Parser */
+    if ((xml_parser = XML_ParserCreateNS(NULL, WBXML_NAMESPACE_SEPARATOR)) == NULL)
+        return WBXML_ERROR_NOT_ENOUGH_MEMORY;
+
+    /* Init context */
+    wbxml_tree_clb_ctx.current = NULL;
+    wbxml_tree_clb_ctx.error = WBXML_OK;
+    wbxml_tree_clb_ctx.skip_lvl = 0;
+    wbxml_tree_clb_ctx.skip_start = 0;
+    wbxml_tree_clb_ctx.xml_parser = xml_parser;
+    wbxml_tree_clb_ctx.input_buff = xml;
+    wbxml_tree_clb_ctx.expat_utf16 = expat_utf16;
+
+    /* Create WBXML Tree */
+    if ((wbxml_tree_clb_ctx.tree = wbxml_tree_create(lang, WBXML_CHARSET_UNKNOWN)) == NULL) {
+        XML_ParserFree(xml_parser);
+        WBXML_ERROR((WBXML_PARSER, "Can't create WBXML Tree"));
+        return WBXML_ERROR_NOT_ENOUGH_MEMORY;
+    }
+
+    /* Set Handlers Callbacks */
+    XML_SetXmlDeclHandler(xml_parser, wbxml_tree_clb_xml_decl);
+
+    if (lang == WBXML_LANG_UNKNOWN) {
+       XML_SetStartDoctypeDeclHandler(xml_parser, wbxml_tree_clb_xml_doctype_decl);
+    }
+
+    XML_SetElementHandler(xml_parser, wbxml_tree_clb_xml_start_element, wbxml_tree_clb_xml_end_element);
+    XML_SetCdataSectionHandler(xml_parser, wbxml_tree_clb_xml_start_cdata, wbxml_tree_clb_xml_end_cdata);
+    XML_SetProcessingInstructionHandler(xml_parser , wbxml_tree_clb_xml_pi);
+    XML_SetCharacterDataHandler(xml_parser, wbxml_tree_clb_xml_characters);
+    XML_SetUserData(xml_parser, (void*)&wbxml_tree_clb_ctx);
+
+    /* Parse the XML Document to WBXML Tree */
+    if (XML_Parse(xml_parser, (WB_TINY*) xml, xml_len, TRUE) == 0)
+    {
+        WBXML_ERROR((WBXML_CONV, "xml2wbxml conversion failed - expat error %i\n"
+            "\tdescription: %s\n"
+            "\tline: %i\n"
+            "\tcolumn: %i\n"
+            "\tbyte index: %i\n"
+            "\ttotal bytes: %i\n%s",
+            XML_GetErrorCode(xml_parser),
+            XML_ErrorString(XML_GetErrorCode(xml_parser)),
+            XML_GetCurrentLineNumber(xml_parser),
+            XML_GetCurrentColumnNumber(xml_parser),
+            XML_GetCurrentByteIndex(xml_parser),
+            XML_GetCurrentByteCount(xml_parser), xml));
+
+        wbxml_tree_destroy(wbxml_tree_clb_ctx.tree);
+
+        ret = WBXML_ERROR_XML_PARSING_FAILED;
+    }
+    else {
+        if ((ret = wbxml_tree_clb_ctx.error) != WBXML_OK)
+        {
+            WBXML_ERROR((WBXML_CONV, "xml2wbxml conversion failed - context error %i", ret));
+            wbxml_tree_destroy(wbxml_tree_clb_ctx.tree);
+        }
+        else
+            *tree = wbxml_tree_clb_ctx.tree;
+    }
+
+    /* Clean-up */
+    XML_ParserFree(xml_parser);
+
+    return ret;
+
+#else /* HAVE_EXPAT */
+
+#if defined( HAVE_LIBXML )
+
+    /** @todo Use LibXML2 SAX interface ! */
+    return WBXML_ERROR_NO_XMLPARSER;
+
+#else /* HAVE_LIBXML */
+
+    /** @note You can add here another XML Parser support */
+    return WBXML_ERROR_NO_XMLPARSER;
+
+#endif /* HAVE_LIBXML */
+
+#endif /* HAVE_EXPAT */
+}
 WBXML_DECLARE(WBXMLError) wbxml_tree_to_xml(WBXMLTree *tree,
                                             WB_UTINY **xml,
                                             WB_ULONG  *xml_len,
index 3c5a6adb8953e0b6aa7f2634a8d46086561d83a6..f02b43a46c104eda9574154d964044fb7d8bd8e6 100644 (file)
@@ -186,6 +186,19 @@ WBXML_DECLARE(WBXMLError) wbxml_tree_from_xml(WB_UTINY *xml,
                                               WB_ULONG xml_len,
                                               WBXMLTree **tree);
 
+/**
+ * @brief Parse an XML document with given language, using internal callbacks (in wbxml_tree_clb_xml.c), and construct a WBXML Tree
+ * @param xml     [in]  The XML document to parse
+ * @param xml_len [in]  Length of the XML document
+ * @param tree    [out] The resulting WBXML Tree
+ * @result Return WBXML_OK if no error, an error code otherwise
+ * @note Needs 'HAVE_EXPAT' compile flag. If lang == WBXML_VERSION_UNKNOWN, then this function is same as wbxml_tree_from_xml
+ */
+WBXML_DECLARE(WBXMLError) wbxml_tree_from_xml_with_lang(WB_UTINY *xml,
+                                              WB_ULONG xml_len,
+                                              WBXMLLanguage lang,
+                                              WBXMLTree **tree);
+
 /**
  * @brief Convert a WBXML Tree to an XML document
  * @param tree    [in]  The WBXML Tree to convert