Example #1
0
WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_create_tree(WBXMLTreeNode *root,
                                                           WBXMLLanguage lang,
                                                           WBXMLCharsetMIBEnum orig_charset)
{
    WBXMLTreeNode* result = NULL;
    WBXMLTree*     tree   = NULL;
    
    if ((root == NULL) || (lang == WBXML_LANG_UNKNOWN))
        return NULL;
    
    /* Create Tree */
    if ((tree = wbxml_tree_create(lang, orig_charset)) == NULL)
        return NULL;
    
    /* Fill Tree */
    tree->root = root;
    
    /* Create Tree Node */
    if ((result = wbxml_tree_node_create(WBXML_TREE_TREE_NODE)) == NULL) {
        wbxml_tree_destroy(tree);
        return NULL;
    }
    
    /* Fill Tree Node */
    result->tree = tree;
    
    return result;
}
Example #2
0
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);
}
Example #3
0
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;
}
Example #4
0
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_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(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 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 */
}
void wbxml_tree_clb_xml_end_element(void           *ctx,
                                    const XML_Char *localName)
{
    WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx;
    WBXMLBuffer *content = NULL;
    WBXMLTreeNode *node = NULL;
    WBXMLError ret = WBXML_OK;

    WBXML_DEBUG((WBXML_PARSER, "Expat element end callback ('%s')", localName));

    /* If the node is flagged as binary node
     * then the data is base64 encoded in the XML document
     * and the data must be decoded in one step.
     * Examples: Microsoft ActiveSync tags ConversationId or MIME
     */

    node = tree_ctx->current;
    if (node && node->type == WBXML_TREE_ELEMENT_NODE &&
            node->name->type == WBXML_VALUE_TOKEN &&
            node->name->u.token->options & WBXML_TAG_OPTION_BINARY)
    {
        if (node->content == NULL)
        {
            WBXML_DEBUG((WBXML_PARSER, "    Binary tag: No content => no conversion!"));
        } else {
            WBXML_DEBUG((WBXML_PARSER, "    Binary tag: Convert base64 data"));
            ret = wbxml_buffer_decode_base64(node->content);
            if (ret != WBXML_OK)
            {
                WBXML_DEBUG((WBXML_PARSER, "    Binary tag: Base64 decoder failed!"));
                tree_ctx->error = ret;
            } else {
                /* Add the buffer as a regular string node (since libwbxml doesn't
                 * offer a way to specify an opaque data node). The WBXML
                 * encoder is responsible for generating correct opaque data for
                 * nodes like this.
                 */
                if (wbxml_tree_add_text(tree_ctx->tree,
                                        tree_ctx->current,
                                        (const WB_UTINY*)wbxml_buffer_get_cstr(node->content),
                                        wbxml_buffer_len(node->content)) == NULL)
                {
                    WBXML_DEBUG((WBXML_PARSER, "    Binary tag: Cannot add base64 decoded node!"));
                    tree_ctx->error = WBXML_ERROR_INTERNAL;
                }
            }
            /* safe cleanup */
            content = node->content;
            node->content = NULL;
            wbxml_buffer_destroy(content);
        }
    }

    if (tree_ctx->expat_utf16) {
        /** @todo Convert from UTF-16 to UTF-8 */
    }

    /* Check for Error */
    if (tree_ctx->error != WBXML_OK)
        return;

    /* Are we skipping a whole node ? */
    if (tree_ctx->skip_lvl > 0) {
        if (tree_ctx->skip_lvl == 1)
        {
            /* End of skipped node */

#if defined( WBXML_SUPPORT_SYNCML )
            if (WBXML_STRCMP(localName, "syncml:devinf:DevInf") == 0 ||
                    WBXML_STRCMP(localName, "syncml:dmddf1.2:MgmtTree") == 0) {
                /* definitions first ... or some compilers don't like it */
                WBXMLBuffer *embed_doc = NULL;
                WBXMLTree *tree = NULL;
                const WBXMLLangEntry *lang;

                /* Get embedded DevInf or DM DDF Document */
                embed_doc = wbxml_buffer_create(tree_ctx->input_buff + tree_ctx->skip_start,
                                                XML_GetCurrentByteIndex(tree_ctx->xml_parser) - tree_ctx->skip_start,
                                                XML_GetCurrentByteIndex(tree_ctx->xml_parser) - tree_ctx->skip_start + 10);
                if (embed_doc == NULL) {
                    tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY;
                    wbxml_buffer_destroy(embed_doc);
                    return;
                }

                if (tree_ctx->expat_utf16) {
                    /** @todo Convert from UTF-16 to UTF-8 */
                }

                /* Check Buffer Creation and add the closing tag */
                if ((WBXML_STRCMP(localName, "syncml:devinf:DevInf") == 0 &&
                        (!wbxml_buffer_append_cstr(embed_doc, "</DevInf>")))
                        ||
                        (WBXML_STRCMP(localName, "syncml:dmddf1.2:MgmtTree") == 0 &&
                         (!wbxml_buffer_append_cstr(embed_doc, "</MgmtTree>"))))
                {
                    tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY;
                    wbxml_buffer_destroy(embed_doc);
                    return;
                }

                /* Add doctype to give the XML parser a chance */
                if (WBXML_STRCMP(localName, "syncml:dmddf1.2:MgmtTree") == 0 &&
                        tree_ctx->tree->lang->langID != WBXML_LANG_SYNCML_SYNCML12)
                {
                    tree_ctx->error = WBXML_ERROR_UNKNOWN_XML_LANGUAGE;
                    wbxml_buffer_destroy(embed_doc);
                    return;
                }
                switch(tree_ctx->tree->lang->langID)
                {
                case WBXML_LANG_SYNCML_SYNCML10:
                    lang = wbxml_tables_get_table(WBXML_LANG_SYNCML_DEVINF10);
                    break;
                case WBXML_LANG_SYNCML_SYNCML11:
                    lang = wbxml_tables_get_table(WBXML_LANG_SYNCML_DEVINF11);
                    break;
                case WBXML_LANG_SYNCML_SYNCML12:
                    if (WBXML_STRCMP(localName, "syncml:dmddf1.2:MgmtTree") == 0) {
                        lang = wbxml_tables_get_table(WBXML_LANG_SYNCML_DMDDF12);
                    } else {
                        lang = wbxml_tables_get_table(WBXML_LANG_SYNCML_DEVINF12);
                    }
                    break;
                default:
                    tree_ctx->error = WBXML_ERROR_UNKNOWN_XML_LANGUAGE;
                    wbxml_buffer_destroy(embed_doc);
                    return;
                }

                assert (lang!= NULL);
                if (lang == NULL) {
                    tree_ctx->error = WBXML_ERROR_UNKNOWN_XML_LANGUAGE;
                    wbxml_buffer_destroy(embed_doc);
                    return;
                }

                /* DOCTYPE in reverse order */
                if (!wbxml_buffer_insert_cstr(embed_doc,(WB_UTINY *) "\">\n", 0) ||                     /* > */
                        !wbxml_buffer_insert_cstr(embed_doc, (WB_UTINY *) lang->publicID->xmlDTD, 0) ||      /* DTD */
                        !wbxml_buffer_insert_cstr(embed_doc, (WB_UTINY *) "\" \"", 0) ||                     /* DTD */
                        !wbxml_buffer_insert_cstr(embed_doc, (WB_UTINY *) lang->publicID->xmlPublicID, 0) || /* Public ID */
                        !wbxml_buffer_insert_cstr(embed_doc, (WB_UTINY *) " PUBLIC \"", 0) ||                /*  PUBLIC " */
                        !wbxml_buffer_insert_cstr(embed_doc, (WB_UTINY *) lang->publicID->xmlRootElt, 0) ||  /* Root Element */
                        !wbxml_buffer_insert_cstr(embed_doc, (WB_UTINY *) "<!DOCTYPE ", 0))                  /* <!DOCTYPE */
                {
                    tree_ctx->error = WBXML_ERROR_ENCODER_APPEND_DATA;
                    wbxml_buffer_destroy(embed_doc);
                    return;
                }

                WBXML_DEBUG((WBXML_PARSER, "\t Embedded Doc : '%s'", wbxml_buffer_get_cstr(embed_doc)));

                /* Parse 'DevInf' Document */
                if ((ret = wbxml_tree_from_xml(wbxml_buffer_get_cstr(embed_doc),
                                               wbxml_buffer_len(embed_doc),
                                               &tree)) != WBXML_OK)
                {
                    tree_ctx->error = ret;
                    wbxml_buffer_destroy(embed_doc);
                    return;
                }

                /* Add Tree Node */
                tree_ctx->current = wbxml_tree_add_tree(tree_ctx->tree,
                                                        tree_ctx->current,
                                                        tree);
                if (tree_ctx->current == NULL)
                {
                    tree_ctx->error = WBXML_ERROR_INTERNAL;
                    wbxml_tree_destroy(tree);
                    wbxml_buffer_destroy(embed_doc);
                    return;
                }

                /* Clean-up */
                wbxml_buffer_destroy(embed_doc);
                tree_ctx->skip_lvl = 0;
            }
#endif /* WBXML_SUPPORT_SYNCML */
        }
        else {
            tree_ctx->skip_lvl--;
            return;
        }
    }

    if (tree_ctx->current == NULL) {
        tree_ctx->error = WBXML_ERROR_INTERNAL;
        return;
    }

    if (tree_ctx->current->parent == NULL) {
        /* This must be the Root Element */
        if (tree_ctx->current != tree_ctx->tree->root) {
            tree_ctx->error = WBXML_ERROR_INTERNAL;
        }
    }
    else {
#if defined ( WBXML_SUPPORT_SYNCML )
        /* Have we added a missing CDATA section ?
         * If so, we assume that now that we have reached an end of Element,
         * the CDATA section ended, and so we go back to parent.
         */
        if ((tree_ctx->current != NULL) && (tree_ctx->current->type == WBXML_TREE_CDATA_NODE))
            tree_ctx->current = tree_ctx->current->parent;
#endif /* WBXML_SUPPORT_SYNCML */

        /* Go back one step upper in the tree */
        tree_ctx->current = tree_ctx->current->parent;
    }
}
Example #6
0
void wbxml_tree_clb_wbxml_characters(void *ctx, WB_UTINY *ch, WB_ULONG start, WB_ULONG length)
{
    WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx;

#if defined ( WBXML_SUPPORT_SYNCML )
    WBXMLTree *tmp_tree = NULL;
#endif /* WBXML_SUPPORT_SYNCML */

    if (tree_ctx->error != WBXML_OK)
        return;

    if(WbxmlUserCBs)	// CSH added for WBXML parser
    {
        WbxmlUserCBs->value_Userclb(WbxmlUserData, (const WB_UTINY*)ch + start,  length);
        return;
    }

#if defined ( WBXML_SUPPORT_SYNCML )
    /* Specific treatment for SyncML */
    switch (wbxml_tree_node_get_syncml_data_type(tree_ctx->current)) {
    case WBXML_SYNCML_DATA_TYPE_WBXML:
        /* Deal with Embedded SyncML Documents - Parse WBXML */
        if (wbxml_tree_from_wbxml(ch + start, length, WBXML_LANG_UNKNOWN, &tmp_tree) != WBXML_OK) {
            /* Not parsable ? Just add it as a Text Node... */
            goto text_node;
        }

        /* Add Tree Node */
        if (wbxml_tree_add_tree(tree_ctx->tree,
                                tree_ctx->current,
                                tmp_tree) == NULL)
        {
            tree_ctx->error = WBXML_ERROR_INTERNAL;
            wbxml_tree_destroy(tmp_tree);
        }

        /* Return !! */
        return;
        break;

    case WBXML_SYNCML_DATA_TYPE_CLEAR:
    case WBXML_SYNCML_DATA_TYPE_DIRECTORY_VCARD:
    case WBXML_SYNCML_DATA_TYPE_VCALENDAR:
    case WBXML_SYNCML_DATA_TYPE_VCARD:
    case WBXML_SYNCML_DATA_TYPE_VOBJECT:
        /*
         * Add a CDATA section node
         *
         * Example:
         * <Add>
         *   <CmdID>6</CmdID>
         *   <Meta><Type xmlns='syncml:metinf'>text/x-vcard</Type></Meta>
         *   <Item>
         *     <Source>
         *         <LocURI>pas-id-3F4B790300000000</LocURI>
         *     </Source>
         *     <Data><![CDATA[BEGIN:VCARD
         *  VERSION:2.1
         *  X-EVOLUTION-FILE-AS:Ximian, Inc.
         *  N:
         *  LABEL;WORK;ENCODING=QUOTED-PRINTABLE:401 Park Drive  3 West=0ABoston, MA
         *  02215=0AUSA
         *  TEL;WORK;VOICE:(617) 236-0442
         *  TEL;WORK;FAX:(617) 236-8630
         *  EMAIL;INTERNET:[EMAIL PROTECTED]
         *  URL:www.ximian.com/
         *  ORG:Ximian, Inc.
         *  NOTE:Welcome to the Ximian Addressbook.
         *  UID:pas-id-3F4B790300000000
         *  END:VCARD
         *  ]]>
         *     </Data>
         *   </Item>
         * </Add>
         *
         * The end of CDATA section is assumed to be reached when parsing the end
         * of </Data> element.
         */

        /* Add new CDATA Node */
        tree_ctx->current = wbxml_tree_add_cdata(tree_ctx->tree, tree_ctx->current);
        if (tree_ctx->current == NULL) {
            tree_ctx->error = WBXML_ERROR_INTERNAL;
            return;
        }

        /* Now we can add the Text Node */
        break;

    default:
        /* NOP */
        break;
    } /* switch */

text_node:

#endif /* WBXML_SUPPORT_SYNCML */
#ifdef ENABLE_WBXML2XML  //CSH1213. 2008 	
    /* Add Text Node */
    if (wbxml_tree_add_text(tree_ctx->tree,
                            tree_ctx->current,
                            (const WB_UTINY*) ch + start,
                            length) == NULL)
    {
        tree_ctx->error = WBXML_ERROR_INTERNAL;
    }
#endif
}