Logo Search packages:      
Sourcecode: libupnp4 version File versions  Download package

ixml.c

Go to the documentation of this file.
/**************************************************************************
 *
 * 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.
 *
 **************************************************************************/


/*!
 * \file
 */


#include "ixmldebug.h"
#include "ixmlmembuf.h"
#include "ixmlparser.h"


#include <stdlib.h> /* for free() */
#include <string.h>


/*!
 * \brief Appends a string to a buffer, substituting some characters by escape
 * sequences.
 */
00051 static void copy_with_escape(
      /*! [in,out] The input/output buffer. */
      ixml_membuf *buf,
      /*! [in] The string to copy from. */
      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, "&lt;");
                  break;

            case '>':
                  ixml_membuf_append_str(buf, "&gt;");
                  break;

            case '&':
                  ixml_membuf_append_str(buf, "&amp;");
                  break;

            case '\'':
                  ixml_membuf_append_str(buf, "&apos;");
                  break;

            case '\"':
                  ixml_membuf_append_str(buf, "&quot;");
                  break;

            default:
                  ixml_membuf_append(buf, &p[i]);
                  break;
            }
      }
}


/*!
 * \brief Recursive function to print all the node in a tree.
 * Internal to parser only.
 */
00100 static void ixmlPrintDomTreeRecursive(
      /*! [in] \todo documentation. */
      IXML_Node *nodeptr,
      /*! [in] \todo documentation. */
      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, "<![CDATA[");
                  ixml_membuf_append_str(buf, nodeValue);
                  ixml_membuf_append_str(buf, "]]>");
                  break;

            case ePROCESSING_INSTRUCTION_NODE:
                  ixml_membuf_append_str(buf, "<?");
                  ixml_membuf_append_str(buf, nodeName);
                  ixml_membuf_append_str(buf, " ");
                  copy_with_escape(buf, nodeValue);
                  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, "</");
                  ixml_membuf_append_str(buf, nodeName);

                  sibling = ixmlNode_getNextSibling(nodeptr);
                  if (sibling != NULL &&
                      ixmlNode_getNodeType(sibling) == eTEXT_NODE) {
                        ixml_membuf_append_str( buf, ">" );
                  } else {
                        ixml_membuf_append_str( buf, ">\r\n" );
                  }
                  ixmlPrintDomTreeRecursive(
                        ixmlNode_getNextSibling(nodeptr), buf);
                  break;

            default:
                  IxmlPrintf("(%s::ixmlPrintDomTreeRecursive) line %d: "
                        "Warning, unknown node type %d\n",
                        __FILE__, __LINE__, ixmlNode_getNodeType(nodeptr));
                  break;
            }
      }
}


/*!
 * \brief Print a DOM tree.
 *
 * Element, and Attribute nodes are handled differently. We don't want to print
 * the Element and Attribute nodes' sibling.
 */
00199 static void ixmlPrintDomTree(
      /*! [in] \todo documentation. */
      IXML_Node *nodeptr,
      /*! [in] \todo documentation. */
      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, "</");
            ixml_membuf_append_str(buf, nodeName);
            ixml_membuf_append_str(buf, ">\r\n");
            break;

      default:
            IxmlPrintf("(%s::ixmlPrintDomTree) line %d: "
                  "Warning, unknown node type %d\n",
                  __FILE__, __LINE__, ixmlNode_getNodeType(nodeptr));
            break;
      }
}


/*!
 * \brief 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.
 */
00270 static void ixmlDomTreetoString(
      /*! [in] \todo documentation. */
      IXML_Node *nodeptr,
      /*! [in] \todo documentation. */
      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, "</");
            ixml_membuf_append_str(buf, nodeName);
            ixml_membuf_append_str(buf, ">");
            break;

      default:
            IxmlPrintf("(%s::ixmlDomTreetoString) line %d: "
                  "Warning, unknown node type %d\n",
                  __FILE__, __LINE__, ixmlNode_getNodeType(nodeptr));
            break;
      }
}


00335 int ixmlLoadDocumentEx(const char *xmlFile, IXML_Document **doc)
{
      if (xmlFile == NULL || doc == NULL) {
            return IXML_INVALID_PARAMETER;
      }

      return Parser_LoadDocument(doc, xmlFile, TRUE);
}


00345 IXML_Document *ixmlLoadDocument(const char *xmlFile)
{
      IXML_Document *doc = NULL;

      ixmlLoadDocumentEx(xmlFile, &doc);

      return doc;
}


00355 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, "<?xml version=\"1.0\"?>\r\n");
      ixmlPrintDomTree(rootNode, buf);

      return buf->buf;
}


00373 DOMString ixmlPrintNode(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;
}


00389 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, "<?xml version=\"1.0\"?>\r\n");
      ixmlDomTreetoString(rootNode, buf);

      return buf->buf;
}


00407 DOMString ixmlNodetoString(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;
}


00423 void ixmlRelaxParser(char errorChar)
{
      Parser_setErrorChar(errorChar);
}


00429 int ixmlParseBufferEx(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);
}


00443 IXML_Document *ixmlParseBuffer(const char *buffer)
{
      IXML_Document *doc = NULL;

      ixmlParseBufferEx(buffer, &doc);

      return doc;
}


00453 DOMString ixmlCloneDOMString(const DOMString src)
{
      if (src == NULL) {
            return NULL;
      }

      return strdup(src);
}


00463 void ixmlFreeDOMString(DOMString buf)
{
      if (buf != NULL) {
            free(buf);
      }
}


Generated by  Doxygen 1.6.0   Back to index