/////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2000-2003 Intel Corporation // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither name of Intel Corporation nor the names of its contributors // may be used to endorse or promote products derived from this software // without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // /////////////////////////////////////////////////////////////////////////// #include "ixmlmembuf.h" #include "ixmlparser.h" /*================================================================ * copy_with_escape * * *=================================================================*/ static void copy_with_escape( INOUT ixml_membuf * buf, IN const char *p ) { int i; int plen; if( p == NULL ) return; plen = strlen( p ); for( i = 0; i < plen; i++ ) { switch ( p[i] ) { case '<': ixml_membuf_append_str( buf, "<" ); break; case '>': ixml_membuf_append_str( buf, ">" ); break; case '&': ixml_membuf_append_str( buf, "&" ); break; case '\'': ixml_membuf_append_str( buf, "'" ); break; case '\"': ixml_membuf_append_str( buf, """ ); break; default: ixml_membuf_append( buf, &p[i] ); } } } /*================================================================ * ixmlPrintDomTreeRecursive * It is a recursive function to print all the node in a tree. * Internal to parser only. * *=================================================================*/ void ixmlPrintDomTreeRecursive( IN IXML_Node * nodeptr, IN ixml_membuf * buf ) { const char *nodeName = NULL; const char *nodeValue = NULL; IXML_Node *child = NULL, *sibling = NULL; if( nodeptr != NULL ) { nodeName = ( const char * )ixmlNode_getNodeName( nodeptr ); nodeValue = ixmlNode_getNodeValue( nodeptr ); switch ( ixmlNode_getNodeType( nodeptr ) ) { case eTEXT_NODE: copy_with_escape( buf, nodeValue ); break; case eCDATA_SECTION_NODE: ixml_membuf_append_str( buf, "" ); break; case ePROCESSING_INSTRUCTION_NODE: ixml_membuf_append_str( buf, "\n" ); break; case eDOCUMENT_NODE: ixmlPrintDomTreeRecursive( ixmlNode_getFirstChild ( nodeptr ), buf ); break; case eATTRIBUTE_NODE: ixml_membuf_append_str( buf, nodeName ); ixml_membuf_append_str( buf, "=\"" ); copy_with_escape( buf, nodeValue ); ixml_membuf_append_str( buf, "\"" ); if( nodeptr->nextSibling != NULL ) { ixml_membuf_append_str( buf, " " ); ixmlPrintDomTreeRecursive( nodeptr->nextSibling, buf ); } break; case eELEMENT_NODE: ixml_membuf_append_str( buf, "<" ); ixml_membuf_append_str( buf, nodeName ); if( nodeptr->firstAttr != NULL ) { ixml_membuf_append_str( buf, " " ); ixmlPrintDomTreeRecursive( nodeptr->firstAttr, buf ); } child = ixmlNode_getFirstChild( nodeptr ); if( ( child != NULL ) && ( ixmlNode_getNodeType( child ) == eELEMENT_NODE ) ) { ixml_membuf_append_str( buf, ">\r\n" ); } else { ixml_membuf_append_str( buf, ">" ); } // output the children ixmlPrintDomTreeRecursive( ixmlNode_getFirstChild ( nodeptr ), buf ); // Done with children. Output the end tag. ixml_membuf_append_str( buf, "" ); } else { ixml_membuf_append_str( buf, ">\r\n" ); } ixmlPrintDomTreeRecursive( ixmlNode_getNextSibling ( nodeptr ), buf ); break; default: break; } } } /*================================================================ * ixmlPrintDomTree * Print a DOM tree. * Element, and Attribute nodes are handled differently. * We don't want to print the Element and Attribute nodes' sibling. * External function. * *=================================================================*/ void ixmlPrintDomTree( IN IXML_Node * nodeptr, IN ixml_membuf * buf ) { const char *nodeName = NULL; const char *nodeValue = NULL; IXML_Node *child = NULL; if( ( nodeptr == NULL ) || ( buf == NULL ) ) { return; } nodeName = ( const char * )ixmlNode_getNodeName( nodeptr ); nodeValue = ixmlNode_getNodeValue( nodeptr ); switch ( ixmlNode_getNodeType( nodeptr ) ) { case eTEXT_NODE: case eCDATA_SECTION_NODE: case ePROCESSING_INSTRUCTION_NODE: case eDOCUMENT_NODE: ixmlPrintDomTreeRecursive( nodeptr, buf ); break; case eATTRIBUTE_NODE: ixml_membuf_append_str( buf, nodeName ); ixml_membuf_append_str( buf, "=\"" ); copy_with_escape( buf, nodeValue ); ixml_membuf_append_str( buf, "\"" ); break; case eELEMENT_NODE: ixml_membuf_append_str( buf, "<" ); ixml_membuf_append_str( buf, nodeName ); if( nodeptr->firstAttr != NULL ) { ixml_membuf_append_str( buf, " " ); ixmlPrintDomTreeRecursive( nodeptr->firstAttr, buf ); } child = ixmlNode_getFirstChild( nodeptr ); if( ( child != NULL ) && ( ixmlNode_getNodeType( child ) == eELEMENT_NODE ) ) { ixml_membuf_append_str( buf, ">\r\n" ); } else { ixml_membuf_append_str( buf, ">" ); } // output the children ixmlPrintDomTreeRecursive( ixmlNode_getFirstChild( nodeptr ), buf ); // Done with children. Output the end tag. ixml_membuf_append_str( buf, "\r\n" ); break; default: break; } } /*================================================================ * ixmlDomTreetoString * Converts a DOM tree into a text string * Element, and Attribute nodes are handled differently. * We don't want to print the Element and Attribute nodes' sibling. * External function. * *=================================================================*/ void ixmlDomTreetoString( IN IXML_Node * nodeptr, IN ixml_membuf * buf ) { const char *nodeName = NULL; const char *nodeValue = NULL; IXML_Node *child = NULL; if( ( nodeptr == NULL ) || ( buf == NULL ) ) { return; } nodeName = ( const char * )ixmlNode_getNodeName( nodeptr ); nodeValue = ixmlNode_getNodeValue( nodeptr ); switch ( ixmlNode_getNodeType( nodeptr ) ) { case eTEXT_NODE: case eCDATA_SECTION_NODE: case ePROCESSING_INSTRUCTION_NODE: case eDOCUMENT_NODE: ixmlPrintDomTreeRecursive( nodeptr, buf ); break; case eATTRIBUTE_NODE: ixml_membuf_append_str( buf, nodeName ); ixml_membuf_append_str( buf, "=\"" ); copy_with_escape( buf, nodeValue ); ixml_membuf_append_str( buf, "\"" ); break; case eELEMENT_NODE: ixml_membuf_append_str( buf, "<" ); ixml_membuf_append_str( buf, nodeName ); if( nodeptr->firstAttr != NULL ) { ixml_membuf_append_str( buf, " " ); ixmlPrintDomTreeRecursive( nodeptr->firstAttr, buf ); } child = ixmlNode_getFirstChild( nodeptr ); if( ( child != NULL ) && ( ixmlNode_getNodeType( child ) == eELEMENT_NODE ) ) { ixml_membuf_append_str( buf, ">" ); } else { ixml_membuf_append_str( buf, ">" ); } // output the children ixmlPrintDomTreeRecursive( ixmlNode_getFirstChild( nodeptr ), buf ); // Done with children. Output the end tag. ixml_membuf_append_str( buf, "" ); break; default: break; } } /*================================================================ * ixmlLoadDocumentEx * Parses the given file, and returns the DOM tree from it. * External function. * *=================================================================*/ int ixmlLoadDocumentEx( IN const char *xmlFile, IXML_Document ** doc ) { if( ( xmlFile == NULL ) || ( doc == NULL ) ) { return IXML_INVALID_PARAMETER; } return Parser_LoadDocument( doc, xmlFile, TRUE ); } /*================================================================ * ixmlLoadDocument * Parses the given file, and returns the DOM tree from it. * External function. * *=================================================================*/ IXML_Document * ixmlLoadDocument( IN const char *xmlFile ) { IXML_Document *doc = NULL; ixmlLoadDocumentEx( xmlFile, &doc ); return doc; } /*================================================================ * ixmlPrintDocument * Prints entire document, prepending XML prolog first. * Puts lots of white spaces. * External function. * *=================================================================*/ DOMString ixmlPrintDocument(IXML_Document *doc) { IXML_Node* rootNode = ( IXML_Node * )doc; ixml_membuf memBuf; ixml_membuf *buf = &memBuf; if( rootNode == NULL ) { return NULL; } ixml_membuf_init( buf ); ixml_membuf_append_str( buf, "\r\n" ); ixmlPrintDomTree( rootNode, buf ); return buf->buf; } /*================================================================ * ixmlPrintNode * Print DOM tree under node. Puts lots of white spaces * External function. * *=================================================================*/ DOMString ixmlPrintNode( IN IXML_Node * node ) { ixml_membuf memBuf; ixml_membuf *buf = &memBuf; if( node == NULL ) { return NULL; } ixml_membuf_init( buf ); ixmlPrintDomTree( node, buf ); return buf->buf; } /*================================================================ * ixmlDocumenttoString * converts DOM tree under node to text string, * prepending XML prolog first. * External function. * *=================================================================*/ DOMString ixmlDocumenttoString(IXML_Document *doc) { IXML_Node* rootNode = ( IXML_Node * )doc; ixml_membuf memBuf; ixml_membuf *buf = &memBuf; if( rootNode == NULL ) { return NULL; } ixml_membuf_init( buf ); ixml_membuf_append_str( buf, "\r\n" ); ixmlDomTreetoString( rootNode, buf ); return buf->buf; } /*================================================================ * ixmlNodetoString * converts DOM tree under node to text string * External function. * *=================================================================*/ DOMString ixmlNodetoString( IN IXML_Node * node ) { ixml_membuf memBuf; ixml_membuf *buf = &memBuf; if( node == NULL ) { return NULL; } ixml_membuf_init( buf ); ixmlDomTreetoString( node, buf ); return buf->buf; } /*================================================================ * ixmlRelaxParser * Makes the XML parser more tolerant to malformed text. * External function. * *=================================================================*/ void ixmlRelaxParser(char errorChar) { Parser_setErrorChar( errorChar ); } /*================================================================ * ixmlParseBufferEx * Parse xml file stored in buffer. * External function. * *=================================================================*/ int ixmlParseBufferEx( IN const char *buffer, IXML_Document ** retDoc ) { if( ( buffer == NULL ) || ( retDoc == NULL ) ) { return IXML_INVALID_PARAMETER; } if( buffer[0] == '\0' ) { return IXML_INVALID_PARAMETER; } return Parser_LoadDocument( retDoc, buffer, FALSE ); } /*================================================================ * ixmlParseBuffer * Parse xml file stored in buffer. * External function. * *=================================================================*/ IXML_Document * ixmlParseBuffer( IN const char *buffer ) { IXML_Document *doc = NULL; ixmlParseBufferEx( buffer, &doc ); return doc; } /*================================================================ * ixmlCloneDOMString * Clones a DOM String. * External function. * *=================================================================*/ DOMString ixmlCloneDOMString( IN const DOMString src ) { if( src == NULL ) { return NULL; } return ( strdup( src ) ); } /*================================================================ * ixmlFreeDOMString * Frees a DOM String. * External function. * *=================================================================*/ void ixmlFreeDOMString( IN DOMString buf ) { if( buf != NULL ) { free( buf ); } }