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

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.  * $Log: ParserTest_Parser.cpp,v $
  58.  * Revision 1.9  2001/11/28 21:15:08  tng
  59.  * Fix broken ParserTest.
  60.  *
  61.  * Revision 1.8  2000/03/02 19:55:46  roddey
  62.  * This checkin includes many changes done while waiting for the
  63.  * 1.1.0 code to be finished. I can't list them all here, but a list is
  64.  * available elsewhere.
  65.  *
  66.  * Revision 1.7  2000/02/06 07:48:37  rahulj
  67.  * Year 2K copyright swat.
  68.  *
  69.  * Revision 1.6  2000/01/27 20:31:31  roddey
  70.  * More recovery from the move away from the util/xx streams.
  71.  *
  72.  * Revision 1.5  2000/01/26 19:35:57  roddey
  73.  * When the /Debug output format is used, it will spit out source offset
  74.  * data as well now.
  75.  *
  76.  * Revision 1.4  2000/01/25 01:02:12  roddey
  77.  * More small fixes in the output from the recent change to get away from
  78.  * the util/xx streams.
  79.  *
  80.  * Revision 1.3  2000/01/21 23:58:06  roddey
  81.  * Initial move away from util streams was bad. Wide char APIs didn't allow enough
  82.  * control to do canonical output, so changed to use std short char APIs.
  83.  *
  84.  * Revision 1.1  1999/11/09 01:02:22  twl
  85.  * Initial revision
  86.  *
  87.  * Revision 1.3  1999/11/08 20:42:25  rahul
  88.  * Swat for adding in Product name and CVS comment log variable.
  89.  *
  90.  */
  91. // ---------------------------------------------------------------------------
  92. //  Includes
  93. // ---------------------------------------------------------------------------
  94. #include <util/RefVectorOf.hpp>
  95. #include <util/XMLString.hpp>
  96. #include <util/XMLUni.hpp>
  97. #include <internal/XMLReader.hpp>
  98. #include <internal/XMLScanner.hpp>
  99. #include <framework/XMLAttr.hpp>
  100. #include <framework/XMLNotationDecl.hpp>
  101. #include <framework/XMLValidator.hpp>
  102. #include <validators/DTD/DTDAttDef.hpp>
  103. #include <validators/DTD/DTDElementDecl.hpp>
  104. #include <validators/DTD/DTDEntityDecl.hpp>
  105. #include "ParserTest.hpp"
  106. #include <stdlib.h>
  107. #include <ctype.h>
  108. // ---------------------------------------------------------------------------
  109. //  Local functions
  110. // ---------------------------------------------------------------------------
  111. static int attrComp(const void* elemOne, const void* elemTwo)
  112. {
  113.     return XMLString::compareString
  114.     (
  115.         (*(XMLAttr**)elemOne)->getName()
  116.         , (*(XMLAttr**)elemTwo)->getName()
  117.     );
  118. }
  119. // ---------------------------------------------------------------------------
  120. //  TestParser: Constructors and Destructor
  121. // ---------------------------------------------------------------------------
  122. TestParser::TestParser() :
  123.     fDoNamespaces(false)
  124.     , fInExtSubset(false)
  125.     , fInsideRoot(false)
  126.     , fIntDTDOutput(false)
  127.     , fNestingLevel(0)
  128.     , fOutputType(OutputType_None)
  129.     , fShowErrLoc(false)
  130.     , fShowWarnings(false)
  131.     , fSurrogate(0)
  132. {
  133. }
  134. TestParser::~TestParser()
  135. {
  136. }
  137. // ---------------------------------------------------------------------------
  138. //  TestParser: The document handler interfaces
  139. // ---------------------------------------------------------------------------
  140. void TestParser::docCharacters( const   XMLCh* const    chars
  141.                                 , const unsigned int    length
  142.                                 , const bool            cdataSection)
  143. {
  144.     if (fOutputType == OutputType_Debug)
  145.     {
  146.         cout << "Got CHARS:n    Bytes: "
  147.              << length << ", CDATA?: "
  148.              << (cdataSection ? "Yes" : "No")
  149.              << "n"
  150.              << "    SrcOfs: " << fScanner->getSrcOffset()
  151.              << "n" << endl;
  152.     }
  153.      else if ((fOutputType == OutputType_JCCanon)
  154.           ||  (fOutputType == OutputType_SunCanon))
  155.     {
  156.         showChars(chars, length);
  157.     }
  158.      else if (fOutputType == OutputType_XML)
  159.     {
  160.         if (cdataSection)
  161.             cout << "<![CDATA[";
  162.         showChars(chars, length);
  163.         if (cdataSection)
  164.             cout << "]]>";
  165.     }
  166. }
  167. void TestParser::docComment(const XMLCh* const comment)
  168. {
  169.     if (fOutputType == OutputType_Debug)
  170.     {
  171.         cout << "Got document COMMENT:n    "
  172.              << "Text: "" << StrX(comment) << ""n"
  173.              << "    SrcOfs: " << fScanner->getSrcOffset()
  174.              << "n" << endl;
  175.     }
  176.      else if (fOutputType == OutputType_XML)
  177.     {
  178.         cout << "<!--";
  179.         showString(comment);
  180.         cout << "-->";
  181.     }
  182. }
  183. void TestParser::docPI( const   XMLCh* const    target
  184.                         , const XMLCh* const    data)
  185. {
  186.     if (fOutputType == OutputType_Debug)
  187.     {
  188.         cout << "Got document PI:n     "
  189.              << "Target: "" << target << '"';
  190.         if (XMLString::stringLen(data))
  191.             cout << ", Data: "" << StrX(data) << ""n";
  192.         cout << "    SrcOfs: " << fScanner->getSrcOffset()
  193.              << "n" << endl;
  194.     }
  195.      else if ((fOutputType == OutputType_XML)
  196.           ||  (fOutputType == OutputType_JCCanon)
  197.           ||  (fOutputType == OutputType_SunCanon))
  198.     {
  199.         cout << "<?";
  200.         showString(target);
  201.         cout << " ";
  202.         if (XMLString::stringLen(data))
  203.             cout << StrX(data);
  204.         cout << "?>";
  205.     }
  206. }
  207. void TestParser::endDocument()
  208. {
  209.     if (fOutputType == OutputType_Debug)
  210.     {
  211.         cout << "Got ENDDOCUMENT:n"
  212.              << "    SrcOfs: " << fScanner->getSrcOffset()
  213.              << "n" << endl;
  214.     }
  215.      else if (fOutputType == OutputType_SunCanon)
  216.     {
  217.         cout << "rn";
  218.     }
  219. }
  220. void TestParser::endElement(const   XMLElementDecl& elemDecl
  221.                             , const unsigned int    uriId
  222.                             , const bool            isRoot)
  223. {
  224.     if (fOutputType == OutputType_Debug)
  225.     {
  226.         if (fDoNamespaces)
  227.         {
  228.             XMLBuffer bufURI;
  229.             fScanner->getURIText(uriId, bufURI);
  230.             cout << "Got ENDELEMENT:n    Name: "
  231.                  << "{" << StrX(bufURI.getRawBuffer()) << "}"
  232.                  << StrX(elemDecl.getBaseName())
  233.                  << endl;
  234.         }
  235.          else
  236.         {
  237.             cout << "Got ENDELEMENT:n    Name: "
  238.                  << StrX(elemDecl.getFullName()) << endl;
  239.         }
  240.         cout << "    SrcOfs: " << fScanner->getSrcOffset()
  241.              << "n" << endl;
  242.     }
  243.      else if ((fOutputType == OutputType_XML)
  244.           ||  (fOutputType == OutputType_JCCanon)
  245.           ||  (fOutputType == OutputType_SunCanon))
  246.     {
  247.         cout << "</";
  248.         showString(elemDecl.getFullName());
  249.         cout << ">";
  250.     }
  251.     // Clear the flag that says we're now inside the root
  252.     if (isRoot)
  253.         fInsideRoot = false;
  254. }
  255. void TestParser::endEntityReference(const XMLEntityDecl& entDecl)
  256. {
  257.     if (fOutputType == OutputType_Debug)
  258.     {
  259.         cout << "Got ENDENTITYREF:n    "
  260.              << "Name: " << StrX(entDecl.getName()) << "n" << endl;
  261.     }
  262. }
  263. void TestParser::ignorableWhitespace(const  XMLCh* const    chars
  264.                                     , const unsigned int    length
  265.                                     , const bool            cdataSection)
  266. {
  267.     if (fOutputType == OutputType_Debug)
  268.     {
  269.         cout << "Got WHITESPACE:n    Bytes: "
  270.              << length << ", CDATA?: "
  271.              << (cdataSection ? "Yes" : "No")
  272.              << "n"
  273.              << "    SrcOfs: " << fScanner->getSrcOffset()
  274.              << "n" << endl;
  275.     }
  276.      else if (fOutputType == OutputType_XML)
  277.     {
  278.         if (cdataSection)
  279.             cout << "<![CDATA[";
  280.         showChars(chars, length);
  281.         if (cdataSection)
  282.             cout << "]]>";
  283.     }
  284.      else if ((fOutputType == OutputType_JCCanon)
  285.           ||  (fOutputType == OutputType_SunCanon))
  286.     {
  287.         if (!fInsideRoot)
  288.             return;
  289.         showChars(chars, length);
  290.     }
  291. }
  292. void TestParser::resetDocument()
  293. {
  294.     if (fOutputType == OutputType_Debug)
  295.         cout << "Got RESETDOCUMENT:n" << endl;
  296. }
  297. void TestParser::startDocument()
  298. {
  299.     if (fOutputType == OutputType_Debug)
  300.         cout << "Got STARTDOCUMENT:n" << endl;
  301. }
  302. void
  303. TestParser::startElement(const  XMLElementDecl&         elemDecl
  304.                         , const unsigned int            uriId
  305.                         , const XMLCh* const            prefixName
  306.                         , const RefVectorOf<XMLAttr>&   attrList
  307.                         , const unsigned int            attCount
  308.                         , const bool                    isEmpty
  309.                         , const bool                    isRoot)
  310. {
  311.     // Set the flag that says we're now inside the root, if its not empty
  312.     if (isRoot && !isEmpty)
  313.         fInsideRoot = true;
  314.     if (fOutputType == OutputType_Debug)
  315.     {
  316.         XMLBuffer bufURI;
  317.         if (fDoNamespaces)
  318.         {
  319.             fScanner->getURIText(uriId, bufURI);
  320.             cout << "Got STARTELEMENT:n    "
  321.                  << " Name: {" << StrX(bufURI.getRawBuffer()) << "}"
  322.                  << StrX(elemDecl.getBaseName())
  323.                  << ", AttCount: " << attCount
  324.                  << ", Empty?: "
  325.                  << (isEmpty ? "yes" : "no")
  326.                  << "n";
  327.         }
  328.          else
  329.         {
  330.             cout << "Got STARTELEMENT:n    Name: "
  331.                  << StrX(elemDecl.getFullName())
  332.                  << ", AttCount: " << attCount
  333.                  << ", Empty?: "
  334.                  << (isEmpty ? "yes" : "no")
  335.                  << "n";
  336.         }
  337.         cout << "    SrcOfs: " << fScanner->getSrcOffset() << "n";
  338.         // If any attributes, then show them
  339.         if (attCount)
  340.         {
  341.             cout << "    Attrs: ";
  342.             for (unsigned int attInd = 0; attInd < attCount; attInd++)
  343.             {
  344.                 const XMLAttr* curAttr = attrList.elementAt(attInd);
  345.                 if (fDoNamespaces)
  346.                 {
  347.                     fScanner->getURIText(curAttr->getURIId(), bufURI);
  348.                     cout << "Name=" << "{" << StrX(bufURI.getRawBuffer())
  349.                          << "}" << StrX(curAttr->getName());
  350.                 }
  351.                  else
  352.                 {
  353.                     cout << "Name=" << StrX(curAttr->getQName());
  354.                 }
  355.                 if (curAttr->getSpecified())
  356.                     cout << " (Explicit)  ";
  357.                 else
  358.                     cout << " (Defaulted) ";
  359.                 cout << "Value=" << StrX(curAttr->getValue()) << "n"
  360.                      << "           ";
  361.             }
  362.         }
  363.         cout << endl;
  364.     }
  365.      else if (fOutputType == OutputType_XML)
  366.     {
  367.         cout << "<";
  368.         showString(elemDecl.getFullName());
  369.         if (attCount)
  370.         {
  371.             cout << " ";
  372.             for (unsigned int index = 0; index < attCount; index++)
  373.             {
  374.                 const XMLAttr* curAttr = attrList.elementAt(index);
  375.                 showString(curAttr->getQName());
  376.                 cout << "="";
  377.                 showString(curAttr->getValue());
  378.                 cout << """;
  379.                 if (index < attCount-1)
  380.                     cout << " ";
  381.             }
  382.         }
  383.         if (isEmpty)
  384.             cout << "/>";
  385.         else
  386.             cout << ">";
  387.     }
  388.      else if ((fOutputType == OutputType_JCCanon)
  389.           ||  (fOutputType == OutputType_SunCanon))
  390.     {
  391.         cout << "<";
  392.         showString(elemDecl.getFullName());
  393.         if (attCount)
  394.         {
  395.             cout << " ";
  396.             //
  397.             //  Get a list of attribute pointers. The canonical output
  398.             //  format requires sorted attributes. If we aren't doing
  399.             //  canonical output, then we don't sort it, but we still use
  400.             //  the array.
  401.             //
  402.             const XMLAttr** attrTmp = new const XMLAttr*[attCount];
  403.             unsigned int index;
  404.             for (index = 0; index < attCount; index++)
  405.                 attrTmp[index] = attrList.elementAt(index);
  406.             if (attCount > 1)
  407.                 qsort(attrTmp, attCount, sizeof(XMLAttr*), attrComp);
  408.             for (index = 0; index < attCount; index++)
  409.             {
  410.                 const XMLAttr* curAttr = attrTmp[index];
  411.                 showString(curAttr->getQName());
  412.                 cout << "="";
  413.                 showString(curAttr->getValue());
  414.                 cout << """;
  415.                 if (index < attCount-1)
  416.                     cout << " ";
  417.             }
  418.             delete [] attrTmp;
  419.         }
  420.         if (isEmpty)
  421.         {
  422.             cout << "></";
  423.             showString(elemDecl.getFullName());
  424.             cout << ">";
  425.         }
  426.          else
  427.         {
  428.             cout << ">";
  429.         }
  430.     }
  431. }
  432. void TestParser::startEntityReference(const XMLEntityDecl& entDecl)
  433. {
  434.     if (fOutputType == OutputType_Debug)
  435.     {
  436.         cout << "Got STARTENTITY:n    "
  437.              << "Name: " << StrX(entDecl.getName()) << "n" << endl;
  438.     }
  439. }
  440. void TestParser::XMLDecl(const  XMLCh* const    versionStr
  441.                         , const XMLCh* const    encodingStr
  442.                         , const XMLCh* const    standaloneStr
  443.                         , const XMLCh* const    autoEncStr)
  444. {
  445.     if (fOutputType == OutputType_Debug)
  446.     {
  447.         cout << "Got XMLDECL:n    "
  448.              << "Version:"" << StrX(versionStr) << """
  449.              << " Encoding:"" << StrX(encodingStr) << """
  450.              << " Standalone:"" << StrX(standaloneStr) << """
  451.              << " Auto Encoding:"" << StrX(autoEncStr) << """
  452.              << "n"
  453.              << "    SrcOfs: " << fScanner->getSrcOffset()
  454.              << "n" << endl;
  455.     }
  456.      else if (fOutputType == OutputType_XML)
  457.     {
  458.         cout << "<?xml";
  459.         if (XMLString::stringLen(versionStr))
  460.             cout << " version="" << StrX(versionStr) << '"';
  461.         if (XMLString::stringLen(encodingStr))
  462.             cout << " encoding="" << StrX(encodingStr) << '"';
  463.         if (XMLString::stringLen(standaloneStr))
  464.             cout  << " standlone="" << StrX(standaloneStr) << '"';
  465.         cout << " ?>";
  466.     }
  467. }
  468. // -----------------------------------------------------------------------
  469. //  TestParser: The DocTypeHandler interface
  470. // -----------------------------------------------------------------------
  471. void TestParser::attDef(const   DTDElementDecl& elemDecl
  472.                         , const DTDAttDef&      attDef
  473.                         , const bool            ignoring)
  474. {
  475.     if (fOutputType == OutputType_Debug)
  476.     {
  477.         cout << "Got ATTDEF:n    "
  478.              << "Name: " << StrX(attDef.getFullName())
  479.              << ", Type: "
  480.              << StrX(XMLAttDef::getAttTypeString(attDef.getType()))
  481.              << ", DefType: "
  482.              << StrX(XMLAttDef::getDefAttTypeString(attDef.getDefaultType()));
  483.         if (XMLString::stringLen(attDef.getValue()))
  484.             cout << ", Value: "" << StrX(attDef.getValue()) << '"';
  485.         cout << "n    SrcOfs: " << fScanner->getSrcOffset()
  486.              << "n" << endl;
  487.     }
  488.      else if (fOutputType != OutputType_None)
  489.     {
  490.         if (fInExtSubset)
  491.             return;
  492.         if (fIntDTDOutput)
  493.         {
  494.             cout << StrX(attDef.getFullName()) << " ";
  495.             if (attDef.getType() == XMLAttDef::Enumeration)
  496.             {
  497.                 cout << '(';
  498.                 StrX tmpStr(attDef.getEnumeration());
  499.                 const char* curCh = tmpStr.localForm();
  500.                 while (*curCh)
  501.                 {
  502.                     while (!isspace(*curCh) && *curCh)
  503.                         cout << *curCh++;
  504.                     if (*curCh)
  505.                     {
  506.                         cout << '|';
  507.                         curCh++;
  508.                     }
  509.                 }
  510.                 cout << ')';
  511.             }
  512.              else
  513.             {
  514.                 cout << StrX(XMLAttDef::getAttTypeString(attDef.getType()));
  515.             }
  516.             if (XMLString::stringLen(attDef.getValue()))
  517.                 cout << " "" << StrX(attDef.getValue()) << '"';
  518.             if (attDef.getDefaultType() != XMLAttDef::Default)
  519.             {
  520.                 cout << " "
  521.                      << StrX(XMLAttDef::getDefAttTypeString(attDef.getDefaultType()));
  522.             }
  523.         }
  524.     }
  525. }
  526. void TestParser::doctypeComment(const XMLCh* const comment)
  527. {
  528.     if (fOutputType == OutputType_Debug)
  529.     {
  530.         cout << "Got DTD COMMENT:n    "
  531.              << "Text: "" << StrX(comment) << ""n"
  532.              << "    SrcOfs: " << fScanner->getSrcOffset()
  533.              << "n" << endl;
  534.     }
  535.      else if (fOutputType != OutputType_None)
  536.     {
  537.         if (fInExtSubset)
  538.             return;
  539.         if (fIntDTDOutput)
  540.             cout << "<!--" << StrX(comment) << "-->";
  541.     }
  542. }
  543. void TestParser::doctypeDecl(const  DTDElementDecl& elemDecl
  544.                             , const XMLCh* const    publicId
  545.                             , const XMLCh* const    systemId
  546.                             , const bool            hasIntSubset)
  547. {
  548.     if (fOutputType == OutputType_Debug)
  549.     {
  550.         cout << "Got DOCTYPE:n    "
  551.                 << "Root: " << StrX(elemDecl.getFullName());
  552.         if (XMLString::stringLen(publicId))
  553.             cout << ", PUBLIC: " << StrX(publicId);
  554.         if (XMLString::stringLen(systemId))
  555.             cout << ", SYSTEM: " << StrX(systemId);
  556.         cout << "n    SrcOfs: " << fScanner->getSrcOffset()
  557.              << "n" << endl;
  558.     }
  559.      else if (fOutputType != OutputType_None)
  560.     {
  561.         if (fIntDTDOutput)
  562.         {
  563.             cout << "<!DOCTYPE " << StrX(elemDecl.getFullName());
  564.             showIds(publicId, systemId);
  565.             if (!hasIntSubset)
  566.                 cout << ">";
  567.         }
  568.     }
  569. }
  570. void TestParser::doctypePI( const   XMLCh* const    target
  571.                             , const XMLCh* const    data)
  572. {
  573.     if (fOutputType == OutputType_Debug)
  574.     {
  575.         cout << "Got DTD PI:n     "
  576.                 << "Target: "" << StrX(target) << '"';
  577.         if (XMLString::stringLen(data))
  578.             cout << ", Data: "" << StrX(data) << '"';
  579.         cout << "    SrcOfs: " << fScanner->getSrcOffset()
  580.              << "n" << endl;
  581.     }
  582.      else if (fOutputType != OutputType_None)
  583.     {
  584.         if (fInExtSubset)
  585.             return;
  586.         if (fIntDTDOutput)
  587.         {
  588.             cout << "<?" << target;
  589.             if (XMLString::stringLen(data))
  590.                 cout << " " << StrX(data);
  591.             cout << "?>";
  592.         }
  593.     }
  594. }
  595. void TestParser::doctypeWhitespace( const   XMLCh* const    chars
  596.                                     , const unsigned int    length)
  597. {
  598.     if (fOutputType == OutputType_Debug)
  599.     {
  600.         cout << "Got DTD Spaces:n    Bytes: "
  601.              << length << "n"
  602.              << "    SrcOfs: " << fScanner->getSrcOffset()
  603.              << "n" << endl;
  604.     }
  605.      else if (fOutputType != OutputType_None)
  606.     {
  607.         if (fInExtSubset)
  608.             return;
  609.         if (fIntDTDOutput)
  610.             showChars(chars, length);
  611.     }
  612. }
  613. void TestParser::elementDecl(const  DTDElementDecl&     decl
  614.                             , const bool                isIgnored)
  615. {
  616.     if (fOutputType == OutputType_Debug)
  617.     {
  618.         cout << "Got ELEMENT DECL:n    "
  619.              << "Name: " << StrX(decl.getFullName());
  620.         if (isIgnored)
  621.             cout << " (Ignored)";
  622.         cout << ", Content: "
  623.              << StrX(decl.getFormattedContentModel())
  624.              << "n    SrcOfs: " << fScanner->getSrcOffset()
  625.              << "n" << endl;
  626.     }
  627.      else if (fOutputType != OutputType_None)
  628.     {
  629.         if (fInExtSubset)
  630.             return;
  631.         if (fIntDTDOutput)
  632.         {
  633.             cout << "<!ELEMENT " << StrX(decl.getFullName()) << " "
  634.                  << StrX(decl.getFormattedContentModel())
  635.                  << ">";
  636.         }
  637.     }
  638. }
  639. void TestParser::endAttList(const DTDElementDecl& elemDecl)
  640. {
  641.     if (fOutputType == OutputType_Debug)
  642.     {
  643.         cout << "Got ENDATTLIST:n    "
  644.              << "Name: " << StrX(elemDecl.getFullName()) << "n"
  645.              << "    SrcOfs: " << fScanner->getSrcOffset()
  646.              << "n" << endl;
  647.     }
  648.      else if (fOutputType != OutputType_None)
  649.     {
  650.         if (fInExtSubset)
  651.             return;
  652.         if (fIntDTDOutput)
  653.             cout << ">";
  654.     }
  655. }
  656. void TestParser::endIntSubset()
  657. {
  658.     if (fOutputType == OutputType_Debug)
  659.     {
  660.         cout << "Got ENDINTSUBSETn"
  661.              << "    SrcOfs: " << fScanner->getSrcOffset()
  662.              << "n" << endl;
  663.     }
  664.      else if (fOutputType != OutputType_None)
  665.     {
  666.         if (fIntDTDOutput)
  667.             cout << "]>";
  668.     }
  669. }
  670. void TestParser::endExtSubset()
  671. {
  672.     fInExtSubset = false;
  673.     if (fOutputType == OutputType_Debug)
  674.         cout << "Got ENDEXTSUBSETn" << endl;
  675. }
  676. void TestParser::entityDecl(const   DTDEntityDecl&  entityDecl
  677.                             , const bool            isPEDecl
  678.                             , const bool            isIgnored)
  679. {
  680.     if (fOutputType == OutputType_Debug)
  681.     {
  682.         cout << "Got ENTITYDECL:n    "
  683.              << "Name: " << StrX(entityDecl.getName())
  684.              << (isPEDecl ? " [Parameter Entity]" : " [General Entity]")
  685.              << "n" << endl;
  686.     }
  687.      else if (fOutputType != OutputType_None)
  688.     {
  689.         if (fInExtSubset)
  690.             return;
  691.         if (fIntDTDOutput)
  692.         {
  693.             cout << "<!ENTITY ";
  694.             if (isPEDecl)
  695.                 cout << "% ";
  696.             cout << StrX(entityDecl.getName());
  697.             if (entityDecl.isExternal())
  698.                 showIds(entityDecl.getPublicId(), entityDecl.getSystemId());
  699.              else
  700.                 cout << " "" << StrX(entityDecl.getValue()) << """;
  701.             cout << ">";
  702.         }
  703.     }
  704. }
  705. void TestParser::resetDocType()
  706. {
  707.     if (fOutputType == OutputType_Debug)
  708.         cout << "Got RESETDOCTYPE:n" << endl;
  709. }
  710. void TestParser::notationDecl(  const   XMLNotationDecl&    notDecl
  711.                                 , const bool                isIgnored)
  712. {
  713.     if (fOutputType == OutputType_Debug)
  714.     {
  715.         cout << "Got NOTATIONDECL:n    "
  716.              << "Name: " << StrX(notDecl.getName())
  717.              << endl;
  718.     }
  719.      else if (fOutputType != OutputType_None)
  720.     {
  721.         if (fInExtSubset)
  722.             return;
  723.         if (fIntDTDOutput)
  724.         {
  725.             cout << "<!NOTATION " << StrX(notDecl.getName()) << " ";
  726.             if (!XMLString::stringLen(notDecl.getSystemId()))
  727.                 cout << "PUBLIC ";
  728.             else
  729.                 cout << "SYSTEM ";
  730.             if (XMLString::stringLen(notDecl.getPublicId()))
  731.                 cout << """ << StrX(notDecl.getPublicId()) << '"';
  732.             if (XMLString::stringLen(notDecl.getSystemId()))
  733.                 cout << " "" << StrX(notDecl.getSystemId()) << '"';
  734.             cout << ">";
  735.         }
  736.     }
  737. }
  738. void TestParser::startAttList(const DTDElementDecl& elemDecl)
  739. {
  740.     if (fOutputType == OutputType_Debug)
  741.     {
  742.         cout << "Got STARTATTLIST:n    "
  743.                 << "Name: " << StrX(elemDecl.getFullName())
  744.                 << "n" << endl;
  745.     }
  746.      else if (fOutputType != OutputType_None)
  747.     {
  748.         if (fInExtSubset)
  749.             return;
  750.         if (fIntDTDOutput)
  751.             cout << "<!ATTLIST " << StrX(elemDecl.getFullName());
  752.     }
  753. }
  754. void TestParser::startIntSubset()
  755. {
  756.     if (fOutputType == OutputType_Debug)
  757.     {
  758.         cout << "Got STARTINTSUBSETn" << endl;
  759.     }
  760.      else if (fOutputType != OutputType_None)
  761.     {
  762.         if (fIntDTDOutput)
  763.             cout << " [";
  764.     }
  765. }
  766. void TestParser::startExtSubset()
  767. {
  768.     fInExtSubset = true;
  769.     if (fOutputType == OutputType_Debug)
  770.         cout << "Got STARTEXTSUBSETn" << endl;
  771. }
  772. void TestParser::TextDecl(  const   XMLCh* const    versionStr
  773.                             , const XMLCh* const    encodingStr)
  774. {
  775.     if (fOutputType == OutputType_Debug)
  776.     {
  777.         cout << "Got TEXTDECL:n    ";
  778.         if (XMLString::stringLen(versionStr))
  779.             cout << "Version: " << StrX(versionStr);
  780.         if (XMLString::stringLen(encodingStr))
  781.             cout << "Encoding: " << StrX(encodingStr);
  782.         cout << "n" << endl;
  783.     }
  784. }
  785. // ---------------------------------------------------------------------------
  786. //  TestParser: Implementation of the XMLErrorReporter interface
  787. // ---------------------------------------------------------------------------
  788. void TestParser::error( const   unsigned int                errCode
  789.                         , const XMLCh* const                msgDomain
  790.                         , const XMLErrorReporter::ErrTypes  type
  791.                         , const XMLCh* const                text
  792.                         , const XMLCh* const                systemId
  793.                         , const XMLCh* const                publicId
  794.                         , const unsigned int                lineNum
  795.                         , const unsigned int                colNum)
  796. {
  797.     //
  798.     //  If we are in 'show error loc' mode, then we do a special, condensed
  799.     //  display of error location info. Else we fall through and do the
  800.     //  normal one for human consumption.
  801.     //
  802.     if (fShowErrLoc)
  803.     {
  804.         // We only do fatal and validity errors in this case
  805.         if (type == XMLErrorReporter::ErrType_Warning)
  806.             return;
  807.         //
  808.         //  We want to display the entity name, but not the whole path, since
  809.         //  this output is for regression testing and has to be compared
  810.         //  against previous runs potentitally on other machines.
  811.         //
  812.         const XMLCh* entName = systemId;
  813.         int ofs = XMLString::lastIndexOf(systemId, chForwardSlash);
  814.         if (ofs == -1)
  815.             ofs = XMLString::lastIndexOf(systemId, chBackSlash);
  816.         if (ofs != -1)
  817.             entName = &systemId[ofs + 1];
  818.         cout << lineNum << "/" << colNum
  819.                 << ":" << StrX(entName)
  820.                 << " - " << StrX(text)
  821.                 << endl;
  822.         return;
  823.     }
  824.     // If its a warning and we are not showing warnings, then get out
  825.     if ((type == XMLErrorReporter::ErrType_Warning) && !fShowWarnings)
  826.         return;
  827.     const char* typeStr = "?";
  828.     if (type == XMLErrorReporter::ErrType_Fatal)
  829.         typeStr = "ERROR";
  830.     else if (type == XMLErrorReporter::ErrType_Warning)
  831.         typeStr = "WARNING";
  832.     else if (type == XMLErrorReporter::ErrType_Error)
  833.         typeStr = "VALIDITY";
  834.     // Output the error heading and the error type string
  835.     cout << "nError: (" << typeStr;
  836.     // If we have either id, display them
  837.     if (XMLString::stringLen(systemId))
  838.          cout << ", System Id: " << StrX(systemId);
  839.     if (XMLString::stringLen(publicId))
  840.         cout << ", Public Id: " << StrX(publicId);
  841.     // Display the position information
  842.     cout << ", Line/Col: " << lineNum << "/" << colNum
  843.          << ")n";
  844.     // And finally the error text
  845.     cout << StrX(text) << endl;
  846. }
  847. void TestParser::resetErrors()
  848. {
  849.     if (fOutputType == OutputType_Debug)
  850.         cout << "Got RESETERRORS:n" << endl;
  851. }
  852. // ---------------------------------------------------------------------------
  853. //  TestParser: Private helpers
  854. // ---------------------------------------------------------------------------
  855. void TestParser::showChars( const   XMLCh* const    chars
  856.                             , const unsigned int    length)
  857. {
  858.     static const XMLByte FirstByteMark[7] =
  859.     {
  860.         0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
  861.     };
  862.     const bool doCan = ((fOutputType == OutputType_SunCanon)
  863.                         || (fOutputType == OutputType_JCCanon));
  864.     unsigned int index = 0;
  865.     while (index < length)
  866.     {
  867.         //
  868.         //  Convert the char to UTF-8 format. This will generate multiple
  869.         //  short chars to display. For each one, call the showChar()
  870.         //  method to display it.
  871.         //
  872.         XMLUInt32 tmpVal = chars[index++];
  873.         if ((tmpVal >= 0xD800) && (tmpVal <= 0xDBFF))
  874.         {
  875.             if (index == length)
  876.             {
  877.                 cout << "Missing trailing surrogaten" << endl;
  878.                 break;
  879.             }
  880.             tmpVal = ((tmpVal - 0xD800) << 10)
  881.                      + ((chars[index] - 0xDC00) + 0x10000);
  882.             index++;
  883.         }
  884.         // Figure out how many bytes we'll kick out
  885.         unsigned int outBytes;
  886.         if (tmpVal < 0x80)
  887.             outBytes = 1;
  888.         else if (tmpVal < 0x800)
  889.             outBytes = 2;
  890.         else if (tmpVal < 0x10000)
  891.             outBytes = 3;
  892.         else if (tmpVal < 0x200000)
  893.             outBytes = 4;
  894.         else if (tmpVal < 0x4000000)
  895.             outBytes = 5;
  896.         else
  897.         {
  898.             outBytes = 6;
  899.             if (tmpVal & 0x80000000)
  900.             {
  901.                 outBytes = 2;
  902.                 tmpVal = 0xFFFD;
  903.             }
  904.         }
  905.         // Get the chars into a temp buffer in the right order
  906.         char tmpOutChars[6];
  907.         unsigned int outIndex = outBytes;
  908.         switch(outBytes)
  909.         {
  910.             case 6 : tmpOutChars[--outIndex] = char((tmpVal | 0x80) & 0xBF);
  911.                      tmpVal >>= 6;
  912.             case 5 : tmpOutChars[--outIndex] = char((tmpVal | 0x80) & 0xBF);
  913.                      tmpVal >>= 6;
  914.             case 4 : tmpOutChars[--outIndex] = char((tmpVal | 0x80) & 0xBF);
  915.                      tmpVal >>= 6;
  916.             case 3 : tmpOutChars[--outIndex] = char((tmpVal | 0x80) & 0xBF);
  917.                      tmpVal >>= 6;
  918.             case 2 : tmpOutChars[--outIndex] = char((tmpVal | 0x80) & 0xBF);
  919.                      tmpVal >>= 6;
  920.             case 1 : tmpOutChars[--outIndex] = char(tmpVal | FirstByteMark[outBytes]);
  921.         }
  922.         // And spit them out
  923.         for (outIndex = 0; outIndex < outBytes; outIndex++)
  924.             showChar(tmpOutChars[outIndex], doCan);
  925.     }
  926. }
  927. void TestParser::showChar(const char toShow, const bool doCan)
  928. {
  929.     if (doCan)
  930.     {
  931.         if (toShow == chLF)
  932.             cout << "&#10;";
  933.         else if (toShow == chHTab)
  934.             cout << "&#9;";
  935.         else if (toShow == chCR)
  936.             cout << "&#13;";
  937.         else if (toShow == chSingleQuote)
  938.             cout << "&apos;";
  939.         else if (toShow == chAmpersand)
  940.             cout << "&amp;";
  941.         else if (toShow == chDoubleQuote)
  942.             cout << "&quot;";
  943.         else if (toShow == chOpenAngle)
  944.             cout << "&lt;";
  945.         else if (toShow == chCloseAngle)
  946.             cout << "&gt;";
  947.         else
  948.             cout << toShow;
  949.     }
  950.      else
  951.     {
  952.         cout << toShow;
  953.     }
  954. }
  955. void
  956. TestParser::showIds(const XMLCh* const publicId, const XMLCh* const systemId)
  957. {
  958.     if (XMLString::stringLen(publicId) || XMLString::stringLen(systemId))
  959.     {
  960.         if (!XMLString::stringLen(publicId))
  961.         {
  962.             cout << " SYSTEM '" << StrX(systemId) << "'";
  963.         }
  964.          else
  965.         {
  966.             cout << " PUBLIC '" << StrX(publicId) << "'";
  967.             if (systemId)
  968.                 cout << " '" << StrX(systemId) << "'";
  969.         }
  970.     }
  971. }
  972. void TestParser::showString(const XMLCh* const toShow)
  973. {
  974.     showChars(toShow, XMLString::stringLen(toShow));
  975. }