⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wbxml_tree.c

📁 WAP Binary XML 简单地说
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * libwbxml, the WBXML Library. * Copyright (C) 2002-2005 Aymerick Jehanne <aymerick@jehanne.org> *  * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA *  * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt *  * Contact: libwbxml@aymerick.com * Home: http://libwbxml.aymerick.com */ /** * @file wbxml_tree.c * @ingroup wbxml_tree * * @author Aymerick Jehanne <libwbxml@aymerick.com> * @date 03/02/18 * * @brief WBXML Tree */#include "wbxml.h"/*************************************************** *    Public Functions */WBXML_DECLARE(WBXMLError) wbxml_tree_from_wbxml(WB_UTINY *wbxml, WB_ULONG wbxml_len, WBXMLLanguage lang, WBXMLTree **tree){    WBXMLParser *wbxml_parser = NULL;    WB_LONG error_index = 0;    WBXMLTreeClbCtx wbxml_tree_clb_ctx;    WBXMLError ret = WBXML_OK;    WBXMLContentHandler wbxml_tree_content_handler =         {            wbxml_tree_clb_wbxml_start_document,            wbxml_tree_clb_wbxml_end_document,            wbxml_tree_clb_wbxml_start_element,            wbxml_tree_clb_wbxml_end_element,            wbxml_tree_clb_wbxml_characters,            wbxml_tree_clb_wbxml_pi        };    if (tree != NULL)        *tree = NULL;    /* Create WBXML Parser */    if((wbxml_parser = wbxml_parser_create()) == NULL) {        WBXML_ERROR((WBXML_PARSER, "Can't create WBXML Parser"));        return WBXML_ERROR_NOT_ENOUGH_MEMORY;    }    /* Init context */    wbxml_tree_clb_ctx.error = WBXML_OK;    wbxml_tree_clb_ctx.current = NULL;    if ((wbxml_tree_clb_ctx.tree = wbxml_tree_create(WBXML_LANG_UNKNOWN, WBXML_CHARSET_UNKNOWN)) == NULL) {        wbxml_parser_destroy(wbxml_parser);        WBXML_ERROR((WBXML_PARSER, "Can't create WBXML Tree"));        return WBXML_ERROR_NOT_ENOUGH_MEMORY;    }        /* Set Handlers Callbacks */    wbxml_parser_set_user_data(wbxml_parser, &wbxml_tree_clb_ctx);    wbxml_parser_set_content_handler(wbxml_parser, &wbxml_tree_content_handler);    /* Give the user the possibility to force Document Language */    if (lang != WBXML_LANG_UNKNOWN)        wbxml_parser_set_language(wbxml_parser, lang);    /** @todo Use wbxml_parser_set_meta_charset() */    /* Parse the WBXML document to WBXML Tree */    ret = wbxml_parser_parse(wbxml_parser, wbxml, wbxml_len);    if ((ret != WBXML_OK) || (wbxml_tree_clb_ctx.error != WBXML_OK))     {        error_index = wbxml_parser_get_current_byte_index(wbxml_parser);        WBXML_ERROR((WBXML_PARSER, "WBXML Parser failed at %ld - token: %x (%s)",                                    error_index,                                   wbxml[error_index],                                   ret != WBXML_OK ? wbxml_errors_string(ret) : wbxml_errors_string(wbxml_tree_clb_ctx.error)));                wbxml_tree_destroy(wbxml_tree_clb_ctx.tree);    }    else {        *tree = wbxml_tree_clb_ctx.tree;    }    /* Clean-up */    wbxml_parser_destroy(wbxml_parser);    if (ret != WBXML_OK)        return ret;    else        return wbxml_tree_clb_ctx.error;}WBXML_DECLARE(WBXMLError) wbxml_tree_to_wbxml(WBXMLTree *tree,                                              WB_UTINY **wbxml,                                              WB_ULONG  *wbxml_len,                                              WBXMLGenWBXMLParams *params){    WBXMLEncoder *wbxml_encoder = NULL;    WBXMLError ret = WBXML_OK;    /* Encode WBXML Tree to WBXML Document */    if ((wbxml_encoder = wbxml_encoder_create()) == NULL) {        return WBXML_ERROR_NOT_ENOUGH_MEMORY;    }    /* Set the WBXML Tree to encode */    wbxml_encoder_set_tree(wbxml_encoder, tree);    /* Set encoder parameters */    if (params == NULL) {        /* Default Parameters */        /* Ignores "Empty Text" Nodes */        wbxml_encoder_set_ignore_empty_text(wbxml_encoder, TRUE);        /* Remove leading and trailing whitespaces in "Text Nodes" */        wbxml_encoder_set_remove_text_blanks(wbxml_encoder, TRUE);        /* Use String Table */        wbxml_encoder_set_use_strtbl(wbxml_encoder, TRUE);    }    else {        /* WBXML Version */        wbxml_encoder_set_wbxml_version(wbxml_encoder, params->wbxml_version);        /* Keep Ignorable Whitespaces ? */        if (!params->keep_ignorable_ws) {            /* Ignores "Empty Text" Nodes */            wbxml_encoder_set_ignore_empty_text(wbxml_encoder, TRUE);            /* Remove leading and trailing whitespaces in "Text Nodes" */            wbxml_encoder_set_remove_text_blanks(wbxml_encoder, TRUE);        }        /* String Table */        wbxml_encoder_set_use_strtbl(wbxml_encoder, params->use_strtbl);        /** @todo Add parameter to call : wbxml_encoder_set_output_charset() */    }    /* Encode WBXML */    ret = wbxml_encoder_encode_to_wbxml(wbxml_encoder, wbxml, wbxml_len);    /* Clean-up */    wbxml_encoder_destroy(wbxml_encoder);    return ret;}WBXML_DECLARE(WBXMLError) wbxml_tree_from_xml(WB_UTINY *xml, WB_ULONG xml_len, 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_ParserCreate(NULL)) == 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(WBXML_LANG_UNKNOWN, 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);    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 convertion 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_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,                                            WBXMLGenXMLParams *params){    WBXMLEncoder *wbxml_encoder = NULL;    WBXMLError ret = WBXML_OK;    /* Create WBXML Encoder */    if ((wbxml_encoder = wbxml_encoder_create()) == NULL) {        return WBXML_ERROR_NOT_ENOUGH_MEMORY;    }    /* Set the WBXML Tree to encode */    wbxml_encoder_set_tree(wbxml_encoder, tree);    /* Set encoder parameters */    if (params == NULL) {        /* Default Values */        /* Set XML Generation Type */        wbxml_encoder_set_xml_gen_type(wbxml_encoder, WBXML_GEN_XML_INDENT);        /* Set Indent */        wbxml_encoder_set_indent(wbxml_encoder, 0);        /* Skip Ignorable Whitespaces */        wbxml_encoder_set_ignore_empty_text(wbxml_encoder, TRUE);        wbxml_encoder_set_remove_text_blanks(wbxml_encoder, TRUE);    }    else {        /* Set XML Generation Type */        wbxml_encoder_set_xml_gen_type(wbxml_encoder, params->gen_type);        /* Set Indent */        if (params->gen_type == WBXML_GEN_XML_INDENT)            wbxml_encoder_set_indent(wbxml_encoder, params->indent);        /* Ignorable Whitespaces */        if (params->keep_ignorable_ws) {            wbxml_encoder_set_ignore_empty_text(wbxml_encoder, FALSE);            wbxml_encoder_set_remove_text_blanks(wbxml_encoder, FALSE);        }        else {            wbxml_encoder_set_ignore_empty_text(wbxml_encoder, TRUE);            wbxml_encoder_set_remove_text_blanks(wbxml_encoder, TRUE);        }        /** @todo Add parameter to call : wbxml_encoder_set_output_charset() */    }    /* Encode WBXML Tree to XML */    ret = wbxml_encoder_encode_tree_to_xml(wbxml_encoder, xml, xml_len);    /* Clean-up */    wbxml_encoder_destroy(wbxml_encoder);    return ret;}#if defined( HAVE_LIBXML )WBXML_DECLARE(WBXMLError) wbxml_tree_from_libxml_doc(xmlDocPtr libxml_doc,                                                     WBXMLTree **tree){    /** @todo wbxml_tree_from_libxml_doc() */    return WBXML_ERROR_NOT_IMPLEMENTED;}WBXML_DECLARE(WBXMLError) wbxml_tree_to_libxml_doc(WBXMLTree *tree,                                                   xmlDocPtr *libxml_doc){    /** @todo wbxml_tree_to_libxml_doc() */    return WBXML_ERROR_NOT_IMPLEMENTED;}#endif /* HAVE_LIBXML */WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_create(WBXMLTreeNodeType type){    WBXMLTreeNode *result = NULL;        if ((result = (WBXMLTreeNode *) wbxml_malloc(sizeof(WBXMLTreeNode))) == NULL)        return NULL;    result->type = type;    result->name = NULL;    result->attrs = NULL;    result->content = NULL;    result->tree = NULL;    result->parent = NULL;    result->children = NULL;    result->next = NULL;    result->prev = NULL;    return result;}WBXML_DECLARE(void) wbxml_tree_node_destroy(WBXMLTreeNode *node){    if (node == NULL)        return;    wbxml_tag_destroy(node->name);    wbxml_list_destroy(node->attrs, wbxml_attribute_destroy_item);    wbxml_buffer_destroy(node->content);    wbxml_tree_destroy(node->tree);    wbxml_free(node);}WBXML_DECLARE(void) wbxml_tree_node_destroy_item(void *node){    wbxml_tree_node_destroy((WBXMLTreeNode *)node);}WBXML_DECLARE(void) wbxml_tree_node_destroy_all(WBXMLTreeNode *node){    WBXMLTreeNode *parent_node   = NULL;    WBXMLTreeNode *current_node  = NULL;    WBXMLTreeNode *previous_node = NULL;    WBXMLTreeNode *tmp_node      = NULL;    WB_BOOL        end_of_walk   = FALSE;    if (node == NULL)        return;    /* Let's go through the sub-tree (iteratively) to free all the nodes */    current_node = node;    parent_node  = node->parent;    while (!end_of_walk)    {        if (current_node == NULL) {            /* Leaf reached */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -