EncodingTest.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:14k
源码类别:

xml/soap/webservice

开发平台:

C/C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 1999, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. //---------------------------------------------------------------------
  57. //
  58. //  This test program is used, in conjunction with a set of test data files,
  59. //  to verify support for different character encodings in XML.
  60. //
  61. //---------------------------------------------------------------------
  62. // ---------------------------------------------------------------------------
  63. //  Includes
  64. // ---------------------------------------------------------------------------
  65. #include <util/PlatformUtils.hpp>
  66. #include <util/XMLString.hpp>
  67. #include <util/XMLException.hpp>
  68. #include <sax/SAXException.hpp>
  69. #include <sax/ErrorHandler.hpp>
  70. #include <sax/SAXParseException.hpp>
  71. #include <parsers/DOMParser.hpp>
  72. #include <dom/DOM.hpp>
  73. #include <stdio.h>
  74. static int gTestsFailed = 0;
  75. static int gTestsRun    = 0;
  76. //-----------------------------------------------------------------------
  77. //
  78. //  ErrorHandler.   The DOM Parser will report any parsing errors by means
  79. //                  of call-backs to the methods of this class.
  80. //                  This is just necessary boilerplate, as far as this
  81. //                  program is concerned.
  82. //
  83. //-----------------------------------------------------------------------
  84. class  ParseErrorHandler: public ErrorHandler
  85. {
  86. public:
  87.     void warning(const SAXParseException& e);
  88.     void error(const SAXParseException& e);
  89.     void fatalError(const SAXParseException& e);
  90.     void resetErrors() {};
  91. };
  92. void ParseErrorHandler::error(const SAXParseException& e)
  93. {
  94.     fprintf(stderr, "nError at file "%s", line %d, char %d:  %sn",
  95.         XMLString::transcode(e.getSystemId()), e.getLineNumber(),
  96.         e.getColumnNumber(), XMLString::transcode(e.getMessage()));
  97.     throw e;
  98. };
  99. void ParseErrorHandler::fatalError(const SAXParseException& e)
  100. {
  101.     fprintf(stderr, "nFatal Error at file "%s", line %d, char %d:  %sn",
  102.         XMLString::transcode(e.getSystemId()), e.getLineNumber(),
  103.         e.getColumnNumber(), XMLString::transcode(e.getMessage()));
  104.     throw e;
  105. };
  106. void ParseErrorHandler::warning(const SAXParseException& e)
  107. {
  108.     fprintf(stderr, "nWarning at file "%s", line %d, char %d:  %sn",
  109.         XMLString::transcode(e.getSystemId()), e.getLineNumber(),
  110.         e.getColumnNumber(), XMLString::transcode(e.getMessage()));
  111.     throw e;
  112. };
  113. //------------------------------------------------------------------------
  114. //
  115. //   parseFile  - a simpler to use function for just parsing an XML file
  116. //                and getting the DOM Document back.
  117. //
  118. //------------------------------------------------------------------------
  119. static DOM_Document parseFile(char *fileName)
  120. {
  121.     ParseErrorHandler eh;
  122.     DOMParser parser;
  123.     parser.setDoValidation(false);
  124.     parser.setErrorHandler(&eh);
  125.     try
  126.     {
  127.         parser.parse(fileName);
  128.     }
  129.     catch (const XMLException& e )
  130.     {
  131. fprintf(stderr, "Exception Occured "%s".  n",
  132. XMLString::transcode(e.getMessage()));
  133. fprintf(stderr, "File being parsed is "%s".n", fileName);
  134.         return DOM_Document();  // A null document.
  135.     }
  136. catch (...)
  137. {
  138. fprintf(stderr, "Unexpected Exception thrown during parse of file "%s".n",
  139.                  fileName);
  140. return DOM_Document();
  141. }
  142.     return parser.getDocument();
  143. }
  144. //------------------------------------------------------------------------
  145. //
  146. //  writeUData - Write out a udata xml element for a DOMString contents.
  147. //
  148. //------------------------------------------------------------------------
  149. static void writeUData(const DOMString s)
  150. {
  151.     unsigned int i;
  152.     printf("<udata>n");
  153.     for (i=0; i<s.length(); i++)
  154.     {
  155.         if (i % 16 == 0)
  156.             printf("n");
  157.         XMLCh c = s.charAt(i);
  158.         printf("%4x ", c);
  159.     }
  160.     printf("n</udata>n");
  161. };
  162. //------------------------------------------------------------------------
  163. //
  164. //  eatWhiteSpace -  DOMStrings are kind of short on utility functions :-(
  165. //
  166. //------------------------------------------------------------------------
  167. static void eatWhiteSpace(DOMString s, unsigned int &i)
  168. {
  169.     while (i < s.length())
  170.     {
  171.     XMLCh c = s.charAt(i);
  172.     if (!(c == 0x20 ||           // These are the official XML space characters,
  173.         c == 0x09 ||             //   expressed as Unicode constants.
  174.         c == 0x0A))
  175.         break;
  176.     i++;
  177.     }
  178. }
  179. //------------------------------------------------------------------------
  180. //
  181. //   convertHexValue     if the DOMString contains a hex number at position i,
  182. //                       convert it and return it, and update i to index the
  183. //                       first char not in the string.
  184. //                       return 0 if string[i] didn't have a hex digit.
  185. //                       0 return is ambiguous, but it doesn't matter for XML,
  186. //                       where 0 is not a valid character.
  187. //
  188. //------------------------------------------------------------------------
  189. static int convertHexValue(DOMString s, unsigned int &i)
  190. {
  191.     int value = 0;
  192.                                    // For reference, the digits  0-9 are Unicode 0x30-39
  193.                                    //                the letters A-F are Unicode 0x41-0x46
  194.                                    //                the letters a-f are Unicode 0x61-66
  195.                                    // We can't use character literals - we might be
  196.                                    //  building on an EBCDIC machine.
  197.     while (i < s.length())
  198.     {
  199.         XMLCh c = s.charAt(i);
  200.         if (c >= 0x61 && c <= 0x66)     // Uppercase a-f to A-F.
  201.             c -= 0x20;
  202.         if (c < 0x30 || c >0x46)        // Stop if not a hex digit
  203.             break;
  204.         if (c > 0x39 && c <0x41)
  205.             break;
  206.         value = value << 4;             // Append this digit to accumulating value
  207.         if (c <= 0x39)
  208.             value += c-0x30;
  209.         else
  210.             value += 0xA + c - 0x41;
  211.         i++;
  212.     }
  213.     return value;
  214. }
  215. //------------------------------------------------------------------------
  216. //
  217. //  processTestFile   Given the file name of an encoding test xml file,
  218. //                    run it.
  219. //
  220. //------------------------------------------------------------------------
  221. static bool  processTestFile(DOMString fileName)
  222. {
  223.     //
  224.     //  Send the input file through the parse, create a DOM document for it.
  225.     //
  226.     char *cFileName = fileName.transcode();
  227.     DOM_Document testDoc = parseFile(fileName.transcode());
  228.     if (testDoc == 0)
  229.         return false;    // parse errors in the source xml.
  230.     //
  231.     //  Pull the "data" element out of the document.
  232.     //
  233.     DOM_NodeList nl = testDoc.getElementsByTagName("data");
  234.     if (nl.getLength() != 1) {
  235.         fprintf(stderr, "Test file "%s" must have exactly one "data" element.n", cFileName);
  236.         return false;
  237.     };
  238.     DOM_Node tmpNode = nl.item(0);
  239.     DOM_Element data = (DOM_Element &) tmpNode;
  240.     //
  241.     //  Build up a string containing the character data contents of the data element.
  242.     //
  243.     DOM_Node child;
  244.     DOMString elData;
  245.     for (child=data.getFirstChild(); child != 0; child= child.getNextSibling())
  246.     {
  247. if (child.getNodeType() == DOM_Node::COMMENT_NODE)
  248. continue;
  249.         if (! (child.getNodeType() == DOM_Node::TEXT_NODE ||
  250.                child.getNodeType() == DOM_Node::CDATA_SECTION_NODE ||
  251.                child.getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE))
  252.         {
  253.                fprintf(stderr, "Test file "%s": data element contains unexpected children.",
  254.                     cFileName);
  255.                return false;
  256.         }
  257.         elData += ((DOM_CharacterData &)child).getData();
  258.     };
  259.     //
  260.     //  Pull the "udata" element out of the document
  261.     //
  262.     nl = testDoc.getElementsByTagName("udata");
  263.     if (nl.getLength() != 1) {
  264.         fprintf(stderr, "Test file "%s" must have exactly one "udata" element.n", cFileName);
  265.         return false;
  266.     };
  267.     DOM_Node tmpNode1 = nl.item(0);
  268.     DOM_Element udata = (DOM_Element &) tmpNode1;
  269.     //
  270.     //  Build up a string containing the character data contents of the udata element.
  271.     //  This will consist of a whole bunch hex numbers, still in string from
  272.     //
  273.     DOMString rawUData;
  274.     for (child=udata.getFirstChild(); child != 0; child= child.getNextSibling())
  275.     {
  276.         if (child.getNodeType() == DOM_Node::COMMENT_NODE)
  277.             continue;
  278.         if (! (child.getNodeType() == DOM_Node::TEXT_NODE ||
  279.             child.getNodeType() == DOM_Node::CDATA_SECTION_NODE ||
  280.             child.getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE))
  281.         {
  282.             fprintf(stderr, "Test file "%s": udata element contains unexpected children.",
  283.                 cFileName);
  284.             return false;
  285.         }
  286.         rawUData += ((DOM_CharacterData &)child).getData();
  287.     };
  288.     //
  289.     // Convert the raw (hex numbers)  form of the udata to the corresponding string.
  290.     //
  291.     DOMString uData;
  292.     unsigned int rawIndex = 0;
  293.     while (rawIndex < rawUData.length())
  294.     {
  295.         eatWhiteSpace(rawUData, rawIndex);
  296.         XMLCh c = convertHexValue(rawUData, rawIndex);
  297.         if (c > 0)
  298.             uData += c;
  299.         else
  300.             if (rawIndex < rawUData.length())
  301.             {
  302.                 fprintf(stderr, "Test file "%s": Bad hex number in udata element.  "
  303.                     "Data character number %dn", cFileName, uData.length());
  304.                 return false;
  305.             }
  306.     }
  307.     //
  308.     // Compare the two strings.
  309.     //
  310.     unsigned int i;
  311.     for (i=0; i<elData.length(); i++)
  312.     {
  313.         if (i >= uData.length())
  314.         {
  315.             fprintf(stderr, "Test file "%s": udata element shorter than data at char number %dn",
  316.                 cFileName, i);
  317.             writeUData(elData);
  318.             return false;
  319.         }
  320.         if (uData.charAt(i) != elData.charAt(i))
  321.         {
  322.             fprintf(stderr, "Test file "%s": comparison failure at character number %dn",
  323.                 cFileName, i);
  324.             writeUData(elData);
  325.             return false;
  326.         };
  327.     }
  328.     if (elData.length() != uData.length())
  329.     {
  330.         fprintf(stderr, "Test file "%s": udata element longer than data at char number %dn",
  331.             cFileName, i);
  332.         writeUData(elData);
  333.         return false;
  334.     }
  335.     return true;
  336. }
  337. int main(int argc, char ** argv) {
  338.    //
  339.     // Initialize the Xerces-c environment
  340.     //
  341. try
  342.     {
  343.         XMLPlatformUtils::Initialize();
  344.     }
  345.     catch (const XMLException& toCatch)
  346.     {
  347.         fprintf(stderr, "Error during initialization of xerces-c: %sn",
  348.             XMLString::transcode(toCatch.getMessage()));
  349.          return 1;
  350.     }
  351.     //
  352.     // Parse the command line, which should specify exactly one file, which is an
  353.     //   xml file containing the list of test files to be processed.
  354.     //
  355.     if (argc != 2) {
  356.         printf("usage: %s file_name n"
  357.                "   where file name is the xml file specifying the list of test files.", argv[0]);
  358.         return 1;
  359.     }
  360.     DOM_Document fileListDoc = parseFile(argv[1]);
  361.     if (fileListDoc == 0) return 1;
  362.     //
  363.     // Iterate over the list of files, running each as a test.
  364.     //
  365.     DOM_NodeList list = fileListDoc.getElementsByTagName("testFile");
  366.     int i;
  367.     int numFiles = list.getLength();
  368.     for (i=0; i<numFiles; i++)
  369.     {
  370.         ++gTestsRun;
  371.         DOM_Node tmpNode3 = list.item(i);
  372.         DOMString fileName = ((DOM_Element &) tmpNode3).getAttribute("name");
  373.         if (processTestFile(fileName) == false)
  374.             ++gTestsFailed;
  375.     };
  376.     //
  377.     // We are done.  Print out a summary of the results
  378.     //
  379.     printf("Encoding Tests Results Summary: n"
  380.            "   %d encoding tests run.n"
  381.            "   %d tests passed,n"
  382.            "   %d tests failedn", gTestsRun, gTestsRun-gTestsFailed, gTestsFailed);
  383.    return 0;
  384. };