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

xml/soap/webservice

开发平台:

C/C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-2001 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.  * $Id: XMLScanner.cpp,v 1.78 2001/11/30 22:19:15 peiyongz Exp $
  58.  */
  59. // ---------------------------------------------------------------------------
  60. //  Includes
  61. // ---------------------------------------------------------------------------
  62. #include <util/Janitor.hpp>
  63. #include <util/Mutexes.hpp>
  64. #include <util/PlatformUtils.hpp>
  65. #include <util/RefVectorOf.hpp>
  66. #include <util/RuntimeException.hpp>
  67. #include <util/UnexpectedEOFException.hpp>
  68. #include <util/XMLMsgLoader.hpp>
  69. #include <util/XMLRegisterCleanup.hpp>
  70. #include <util/XMLUniDefs.hpp>
  71. #include <util/XMLUni.hpp>
  72. #include <util/XMLURL.hpp>
  73. #include <sax/InputSource.hpp>
  74. #include <sax/SAXException.hpp>
  75. #include <framework/LocalFileInputSource.hpp>
  76. #include <framework/URLInputSource.hpp>
  77. #include <framework/XMLDocumentHandler.hpp>
  78. #include <framework/XMLErrorReporter.hpp>
  79. #include <framework/XMLEntityHandler.hpp>
  80. #include <framework/XMLPScanToken.hpp>
  81. #include <framework/XMLValidator.hpp>
  82. #include <framework/XMLValidityCodes.hpp>
  83. #include <internal/XMLScanner.hpp>
  84. #include <internal/EndOfEntityException.hpp>
  85. #include <validators/DTD/DocTypeHandler.hpp>
  86. #include <validators/DTD/DTDScanner.hpp>
  87. #include <validators/schema/SchemaSymbols.hpp>
  88. #include <validators/schema/identity/FieldActivator.hpp>
  89. #include <validators/schema/identity/XPathMatcherStack.hpp>
  90. #include <validators/schema/identity/ValueStoreCache.hpp>
  91. #include <validators/schema/identity/IC_Selector.hpp>
  92. #include <validators/schema/identity/ValueStore.hpp>
  93. // ---------------------------------------------------------------------------
  94. //  Local static data
  95. // ---------------------------------------------------------------------------
  96. static XMLUInt32       gScannerId;
  97. static bool            sRegistered = false;
  98. static XMLMutex*       sScannerMutex = 0;
  99. static XMLRegisterCleanup scannerMutexCleanup;
  100. static XMLMsgLoader*   gMsgLoader = 0;
  101. static XMLRegisterCleanup cleanupMsgLoader;
  102. // ---------------------------------------------------------------------------
  103. //  Local const data
  104. //
  105. //  These are the text for the require char refs that must always be present.
  106. //  We init these into the entity pool upon construction.
  107. // ---------------------------------------------------------------------------
  108. static const XMLCh gAmp[] = { chLatin_a, chLatin_m, chLatin_p, chNull };
  109. static const XMLCh gLT[] = { chLatin_l, chLatin_t, chNull };
  110. static const XMLCh gGT[] = { chLatin_g, chLatin_t, chNull };
  111. static const XMLCh gQuot[] = { chLatin_q, chLatin_u, chLatin_o, chLatin_t, chNull };
  112. static const XMLCh gApos[] = { chLatin_a, chLatin_p, chLatin_o, chLatin_s, chNull };
  113. // ---------------------------------------------------------------------------
  114. //  Local, static functions
  115. // ---------------------------------------------------------------------------
  116. // -----------------------------------------------------------------------
  117. //  Cleanup for the message loader
  118. // -----------------------------------------------------------------------
  119. void XMLScanner::reinitMsgLoader()
  120. {
  121. delete gMsgLoader;
  122. gMsgLoader = 0;
  123. }
  124. // -----------------------------------------------------------------------
  125. //  Cleanup for the scanner mutex
  126. // -----------------------------------------------------------------------
  127. void XMLScanner::reinitScannerMutex()
  128. {
  129.     delete sScannerMutex;
  130.     sScannerMutex = 0;
  131.     sRegistered = false;
  132. }
  133. //
  134. //  We need to fault in this mutex. But, since its used for synchronization
  135. //  itself, we have to do this the low level way using a compare and swap.
  136. //
  137. static XMLMutex& gScannerMutex()
  138. {
  139.     if (!sScannerMutex)
  140.     {
  141.         XMLMutex* tmpMutex = new XMLMutex;
  142.         if (XMLPlatformUtils::compareAndSwap((void**)&sScannerMutex, tmpMutex, 0))
  143.         {
  144.             // Someone beat us to it, so let's clean up ours
  145.             delete tmpMutex;
  146.         }
  147.         // Now lock it and try to register it
  148.         XMLMutexLock lock(sScannerMutex);
  149.         // If we got here first, then register it and set the registered flag
  150.         if (!sRegistered)
  151.         {
  152. scannerMutexCleanup.registerCleanup(XMLScanner::reinitScannerMutex);
  153.             sRegistered = true;
  154.         }
  155.     }
  156.     return *sScannerMutex;
  157. }
  158. // ---------------------------------------------------------------------------
  159. //  XMLScanner: Constructors and Destructor
  160. // ---------------------------------------------------------------------------
  161. XMLScanner::XMLScanner(XMLValidator* const valToAdopt) :
  162.     fDoNamespaces(false)
  163.     , fExitOnFirstFatal(true)
  164.     , fValidationConstraintFatal(false)
  165.     , fInException(false)
  166.     , fReuseGrammar(false)
  167.     , fStandalone(false)
  168.     , fHasNoDTD(true)
  169.     , fValidate(false)
  170.     , fValidatorFromUser(false)
  171.     , fDoSchema(false)
  172.     , fSchemaFullChecking(false)
  173.     , fSeeXsi(false)
  174.     , fErrorCount(0)
  175.     , fEmptyNamespaceId(0)
  176.     , fUnknownNamespaceId(0)
  177.     , fXMLNamespaceId(0)
  178.     , fXMLNSNamespaceId(0)
  179.     , fSchemaNamespaceId(0)
  180.     , fElemStateSize(16)
  181.     , fScannerId(0)
  182.     , fSequenceId(0)
  183.     , fElemState(0)
  184.     , fAttrList(0)
  185.     , fDocHandler(0)
  186.     , fDocTypeHandler(0)
  187.     , fEntityHandler(0)
  188.     , fEntityResolver(0)
  189.     , fErrorReporter(0)
  190.     , fErrorHandler(0)
  191.     , fIDRefList(0)
  192.     , fRawAttrList(0)
  193.     , fValidator(valToAdopt)
  194.     , fDTDValidator(0)
  195.     , fSchemaValidator(0)
  196.     , fValScheme(Val_Never)
  197.     , fGrammarResolver(0)
  198.     , fGrammar(0)
  199.     , fEntityDeclPool(0)
  200.     , fURIStringPool(0)
  201.     , fMatcherStack(0)
  202.     , fValueStoreCache(0)
  203.     , fFieldActivator(0)
  204.     , fRootElemName(0)
  205.     , fExternalSchemaLocation(0)
  206.     , fExternalNoNamespaceSchemaLocation(0)
  207. {
  208.    commonInit();
  209.    if (fValidator) {
  210.        fValidatorFromUser = true;
  211.        initValidator(fValidator);
  212.    }
  213.    else {
  214.        //use fDTDValidator as the default validator
  215.        fValidator = fDTDValidator;
  216.    }
  217. }
  218. XMLScanner::XMLScanner( XMLDocumentHandler* const  docHandler
  219.                         , DocTypeHandler* const    docTypeHandler
  220.                         , XMLEntityHandler* const  entityHandler
  221.                         , XMLErrorReporter* const  errHandler
  222.                         , XMLValidator* const      valToAdopt) :
  223.     fDoNamespaces(false)
  224.     , fExitOnFirstFatal(true)
  225.     , fValidationConstraintFatal(false)
  226.     , fInException(false)
  227.     , fReuseGrammar(false)
  228.     , fStandalone(false)
  229.     , fHasNoDTD(true)
  230.     , fValidate(false)
  231.     , fValidatorFromUser(false)
  232.     , fDoSchema(false)
  233.     , fSchemaFullChecking(false)
  234.     , fSeeXsi(false)
  235.     , fErrorCount(0)
  236.     , fEmptyNamespaceId(0)
  237.     , fUnknownNamespaceId(0)
  238.     , fXMLNamespaceId(0)
  239.     , fXMLNSNamespaceId(0)
  240.     , fSchemaNamespaceId(0)
  241.     , fElemStateSize(16)
  242.     , fScannerId(0)
  243.     , fSequenceId(0)
  244.     , fElemState(0)
  245.     , fAttrList(0)
  246.     , fDocHandler(docHandler)
  247.     , fDocTypeHandler(docTypeHandler)
  248.     , fEntityHandler(entityHandler)
  249.     , fEntityResolver(0)
  250.     , fErrorReporter(errHandler)
  251.     , fErrorHandler(0)
  252.     , fIDRefList(0)
  253.     , fRawAttrList(0)
  254.     , fValidator(valToAdopt)
  255.     , fDTDValidator(0)
  256.     , fSchemaValidator(0)
  257.     , fValScheme(Val_Never)
  258.     , fGrammarResolver(0)
  259.     , fGrammar(0)
  260.     , fEntityDeclPool(0)
  261.     , fURIStringPool(0)
  262.     , fMatcherStack(0)
  263.     , fValueStoreCache(0)
  264.     , fFieldActivator(0)
  265.     , fRootElemName(0)
  266.     , fExternalSchemaLocation(0)
  267.     , fExternalNoNamespaceSchemaLocation(0)
  268. {
  269.    commonInit();
  270.    if (valToAdopt){
  271.        fValidatorFromUser = true;
  272.        initValidator(fValidator);
  273.    }
  274.    else {
  275.        //use fDTDValidator as the default validator
  276.        fValidator = fDTDValidator;
  277.    }
  278. }
  279. XMLScanner::~XMLScanner()
  280. {
  281.     delete [] fElemState;
  282.     delete fAttrList;
  283.     delete fIDRefList;
  284.     delete fRawAttrList;
  285.     if (fValidatorFromUser)
  286.         delete fValidator;
  287.     delete fDTDValidator;
  288.     delete fSchemaValidator;
  289.     delete fEntityDeclPool;
  290.     //fGrammarResolver will delete the fGrammar as well
  291.     delete fGrammarResolver;
  292.     delete fURIStringPool;
  293.     delete fFieldActivator;
  294.     delete fMatcherStack;
  295.     delete fValueStoreCache;
  296.     delete [] fRootElemName;
  297.     delete [] fExternalSchemaLocation;
  298.     delete [] fExternalNoNamespaceSchemaLocation;
  299. }
  300. // ---------------------------------------------------------------------------
  301. //  XMLScanner: Main entry point to scan a document
  302. // ---------------------------------------------------------------------------
  303. void XMLScanner::scanDocument(  const   XMLCh* const    systemId
  304.                                 , const bool            reuseGrammar)
  305. {
  306.     //
  307.     //  First we try to parse it as a URL. If that fails, we assume its
  308.     //  a file and try it that way.
  309.     //
  310.     InputSource* srcToUse = 0;
  311.     try
  312.     {
  313.         //
  314.         //  Create a temporary URL. Since this is the primary document,
  315.         //  it has to be fully qualified. If not, then assume we are just
  316.         //  mistaking a file for a URL.
  317.         //
  318.         XMLURL tmpURL(systemId);
  319.         if (tmpURL.isRelative()) {
  320.             srcToUse = new LocalFileInputSource(systemId);
  321.         }
  322.         else
  323.         {
  324.             srcToUse = new URLInputSource(tmpURL);
  325.         }
  326.     }
  327.     catch(const MalformedURLException&)
  328.     {
  329.         srcToUse = new LocalFileInputSource(systemId);
  330.     }
  331.     catch(...)
  332.     {
  333.         // Just rethrow this, since its not our problem
  334.         throw;
  335.     }
  336.     Janitor<InputSource> janSrc(srcToUse);
  337.     scanDocument(*srcToUse, reuseGrammar);
  338. }
  339. void XMLScanner::scanDocument(  const   char* const systemId
  340.                                 , const bool        reuseGrammar)
  341. {
  342.     // We just delegate this to the XMLCh version after transcoding
  343.     XMLCh* tmpBuf = XMLString::transcode(systemId);
  344.     ArrayJanitor<XMLCh> janBuf(tmpBuf);
  345.     scanDocument(tmpBuf, reuseGrammar);
  346. }
  347. void XMLScanner::scanDocument(const InputSource& src, const bool reuseGrammar)
  348. {
  349.     //
  350.     //  Bump up the sequence id for this parser instance. This will invalidate
  351.     //  any previous progressive scan tokens.
  352.     //
  353.     fSequenceId++;
  354.     // Store the reuse validator flag
  355.     fReuseGrammar = reuseGrammar;
  356.     try
  357.     {
  358.         //
  359.         //  Reset the scanner and its plugged in stuff for a new run. This
  360.         //  resets all the data structures, creates the initial reader and
  361.         //  pushes it on the stack, and sets up the base document path.
  362.         //
  363.         scanReset(src);
  364.         // If we have a document handler, then call the start document
  365.         if (fDocHandler)
  366.             fDocHandler->startDocument();
  367.         fValueStoreCache->startDocument();
  368.         //
  369.         //  Scan the prolog part, which is everything before the root element
  370.         //  including the DTD subsets.
  371.         //
  372.         scanProlog();
  373.         //
  374.         //  If we got to the end of input, then its not a valid XML file.
  375.         //  Else, go on to scan the content.
  376.         //
  377.         if (fReaderMgr.atEOF())
  378.         {
  379.             emitError(XMLErrs::EmptyMainEntity);
  380.         }
  381.          else
  382.         {
  383.             // Scan content, and tell it its not an external entity
  384.             if (scanContent(false))
  385.             {
  386.                 // Do post-parse validation if required
  387.                 if (fValidate)
  388.                 {
  389.                     //
  390.                     //  We handle ID reference semantics at this level since
  391.                     //  its required by XML 1.0.
  392.                     //
  393.                     checkIDRefs();
  394.                     // Then allow the validator to do any extra stuff it wants
  395.                     fValidator->postParseValidation();
  396.                 }
  397.                 // That went ok, so scan for any miscellaneous stuff
  398.                 if (!fReaderMgr.atEOF())
  399.                     scanMiscellaneous();
  400.             }
  401.         }
  402.         if (fValidate)
  403.             fValueStoreCache->endDocument();
  404.         // If we have a document handler, then call the end document
  405.         if (fDocHandler)
  406.             fDocHandler->endDocument();
  407.         // Reset the reader manager to close all files, sockets, etc...
  408.         fReaderMgr.reset();
  409.     }
  410.     //
  411.     //  NOTE:
  412.     //
  413.     //  In all of the error processing below, the emitError() call MUST come
  414.     //  before the flush of the reader mgr, or it will fail because it tries
  415.     //  to find out the position in the XML source of the error.
  416.     //
  417.     catch(const XMLErrs::Codes)
  418.     {
  419.         // This is a 'first fatal error' type exit, so reset and fall through
  420.         fReaderMgr.reset();
  421.     }
  422.     catch(const XMLValid::Codes)
  423.     {
  424.         // This is a 'first fatal error' type exit, so reset and fall through
  425.         fReaderMgr.reset();
  426.     }
  427.     catch(const SAXException&)
  428.     {
  429.         //
  430.         //  We have to propogate SAX exceptions.
  431.         //
  432.         //  Make sure that the reader manager gets reset, then rethrow this
  433.         //  exception since it means nothing much to us.
  434.         //
  435.         fReaderMgr.reset();
  436.         throw;
  437.     }
  438.     catch(const XMLException& excToCatch)
  439.     {
  440.         //
  441.         //  Emit the error and catch any user exception thrown from here. Make
  442.         //  sure in all cases we flush the reader manager.
  443.         //
  444.         fInException = true;
  445.         try
  446.         {
  447.             if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning)
  448.                 emitError
  449.                 (
  450.                     XMLErrs::XMLException_Warning
  451.                     , excToCatch.getType()
  452.                     , excToCatch.getMessage()
  453.                 );
  454.             else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal)
  455.                 emitError
  456.                 (
  457.                     XMLErrs::XMLException_Fatal
  458.                     , excToCatch.getType()
  459.                     , excToCatch.getMessage()
  460.                 );
  461.             else
  462.                 emitError
  463.                 (
  464.                     XMLErrs::XMLException_Error
  465.                     , excToCatch.getType()
  466.                     , excToCatch.getMessage()
  467.                 );
  468.         }
  469.         catch(...)
  470.         {
  471.             // Flush the reader manager and rethrow user's error
  472.             fReaderMgr.reset();
  473.             throw;
  474.         }
  475.         // If it returned, then reset the reader manager and fall through
  476.         fReaderMgr.reset();
  477.     }
  478.     catch(...)
  479.     {
  480.         // Reset and rethrow
  481.         fReaderMgr.reset();
  482.         throw;
  483.     }
  484. }
  485. //
  486. //  This method begins a progressive parse. It scans through the prolog and
  487. //  returns a token to be used on subsequent scanNext() calls. If the return
  488. //  value is true, then the token is legal and ready for further use. If it
  489. //  returns false, then the scan of the prolog failed and the token is not
  490. //  going to work on subsequent scanNext() calls.
  491. //
  492. bool XMLScanner::scanFirst( const   XMLCh* const    systemId
  493.                             ,       XMLPScanToken&  toFill
  494.                             , const bool            reuseGrammar)
  495. {
  496.     //
  497.     //  First we try to parse it as a URL. If that fails, we assume its
  498.     //  a file and try it that way.
  499.     //
  500.     InputSource* srcToUse = 0;
  501.     try
  502.     {
  503.         //
  504.         //  Create a temporary URL. Since this is the primary document,
  505.         //  it has to be fully qualified. If not, then assume we are just
  506.         //  mistaking a file for a URL.
  507.         //
  508.         XMLURL tmpURL(systemId);
  509.         if (tmpURL.isRelative())
  510.             ThrowXML(MalformedURLException, XMLExcepts::URL_NoProtocolPresent);
  511.         srcToUse = new URLInputSource(tmpURL);
  512.     }
  513.     catch(const MalformedURLException&)
  514.     {
  515.         srcToUse = new LocalFileInputSource(systemId);
  516.     }
  517.     catch(...)
  518.     {
  519.         // Just rethrow this, since its not our problem
  520.         throw;
  521.     }
  522.     Janitor<InputSource> janSrc(srcToUse);
  523.     return scanFirst(*srcToUse, toFill, reuseGrammar);
  524. }
  525. bool XMLScanner::scanFirst( const   char* const     systemId
  526.                             ,       XMLPScanToken&  toFill
  527.                             , const bool            reuseGrammar)
  528. {
  529.     // We just delegate this to the XMLCh version after transcoding
  530.     XMLCh* tmpBuf = XMLString::transcode(systemId);
  531.     ArrayJanitor<XMLCh> janBuf(tmpBuf);
  532.     return scanFirst(tmpBuf, toFill, reuseGrammar);
  533. }
  534. bool XMLScanner::scanFirst( const   InputSource&    src
  535.                             ,       XMLPScanToken&  toFill
  536.                             , const bool            reuseGrammar)
  537. {
  538.     // Store the reuse validator flag
  539.     fReuseGrammar = reuseGrammar;
  540.     //
  541.     //  Bump up the sequence id for this new scan cycle. This will invalidate
  542.     //  any previous tokens we've returned.
  543.     //
  544.     fSequenceId++;
  545.     //
  546.     // Reset the scanner and its plugged in stuff for a new run.  This
  547.     // resets all the data structures, creates the initial reader and
  548.     // pushes it on the stack, and sets up the base document path
  549.     //
  550.     scanReset(src);
  551.     // If we have a document handler, then call the start document
  552.     if (fDocHandler)
  553.         fDocHandler->startDocument();
  554.     fValueStoreCache->startDocument();
  555.     try
  556.     {
  557.         //
  558.         //  Scan the prolog part, which is everything before the root element
  559.         //  including the DTD subsets. This is all that is done on the scan
  560.         //  first.
  561.         //
  562.         scanProlog();
  563.     }
  564.     //
  565.     //  NOTE:
  566.     //
  567.     //  In all of the error processing below, the emitError() call MUST come
  568.     //  before the flush of the reader mgr, or it will fail because it tries
  569.     //  to find out the position in the XML source of the error.
  570.     //
  571.     catch(const XMLErrs::Codes)
  572.     {
  573.         // This is a 'first failure' exception so reset and return a failure
  574.         fReaderMgr.reset();
  575.         return false;
  576.     }
  577.     catch(const XMLValid::Codes)
  578.     {
  579.         // This is a 'first fatal error' type exit, so reset and reuturn failure
  580.         fReaderMgr.reset();
  581.         return false;
  582.     }
  583.     // We have to propogate SAX exceptions
  584.     catch(const SAXException&)
  585.     {
  586.         fReaderMgr.reset();
  587.         throw;
  588.     }
  589.     catch(const XMLException& excToCatch)
  590.     {
  591.         //
  592.         //  Emit the error and catch any user exception thrown from here. Make
  593.         //  sure in all cases we flush the reader manager.
  594.         //
  595.         fInException = true;
  596.         try
  597.         {
  598.             if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning)
  599.                 emitError
  600.                 (
  601.                     XMLErrs::XMLException_Warning
  602.                     , excToCatch.getType()
  603.                     , excToCatch.getMessage()
  604.                 );
  605.             else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal)
  606.                 emitError
  607.                 (
  608.                     XMLErrs::XMLException_Fatal
  609.                     , excToCatch.getType()
  610.                     , excToCatch.getMessage()
  611.                 );
  612.             else
  613.                 emitError
  614.                 (
  615.                     XMLErrs::XMLException_Error
  616.                     , excToCatch.getType()
  617.                     , excToCatch.getMessage()
  618.                 );
  619.         }
  620.         catch(...)
  621.         {
  622.             // Reset and rethrow the user error
  623.             fReaderMgr.reset();
  624.             throw;
  625.         }
  626.         // Reset and return a failure
  627.         fReaderMgr.reset();
  628.         return false;
  629.     }
  630.     catch(...)
  631.     {
  632.         // Reset and rethrow original error
  633.         fReaderMgr.reset();
  634.         throw;
  635.     }
  636.     // Fill in the caller's token to make it legal and return success
  637.     toFill.set(fScannerId, fSequenceId);
  638.     return true;
  639. }
  640. bool XMLScanner::scanNext(XMLPScanToken& token)
  641. {
  642.     // Make sure this token is still legal
  643.     if (!isLegalToken(token))
  644.         ThrowXML(RuntimeException, XMLExcepts::Scan_BadPScanToken);
  645.     // Find the next token and remember the reader id
  646.     unsigned int orgReader;
  647.     XMLTokens curToken;
  648.     //
  649.     //  We have to handle any end of entity exceptions that happen here.
  650.     //  We could be at the end of X nested entities, each of which will
  651.     //  generate an end of entity exception as we try to move forward.
  652.     //
  653.     while (true)
  654.     {
  655.         try
  656.         {
  657.             curToken = senseNextToken(orgReader);
  658.             break;
  659.         }
  660.         catch(const EndOfEntityException& toCatch)
  661.         {
  662.             // Send an end of entity reference event
  663.             if (fDocHandler)
  664.                 fDocHandler->endEntityReference(toCatch.getEntity());
  665.         }
  666.     }
  667.     bool retVal = true;
  668.     try
  669.     {
  670.         if (curToken == Token_CharData)
  671.         {
  672.             scanCharData(fCDataBuf);
  673.         }
  674.          else if (curToken == Token_EOF)
  675.         {
  676.             if (!fElemStack.isEmpty())
  677.             {
  678.                 const ElemStack::StackElem* topElem = fElemStack.popTop();
  679.                 emitError
  680.                 (
  681.                     XMLErrs::EndedWithTagsOnStack
  682.                     , topElem->fThisElement->getFullName()
  683.                 );
  684.             }
  685.             retVal = false;
  686.         }
  687.          else
  688.         {
  689.             // Its some sort of markup
  690.             bool gotData = true;
  691.             switch(curToken)
  692.             {
  693.                 case Token_CData :
  694.                     // Make sure we are within content
  695.                     if (fElemStack.isEmpty())
  696.                         emitError(XMLErrs::CDATAOutsideOfContent);
  697.                     scanCDSection();
  698.                     break;
  699.                 case Token_Comment :
  700.                     scanComment();
  701.                     break;
  702.                 case Token_EndTag :
  703.                     scanEndTag(gotData);
  704.                     break;
  705.                 case Token_PI :
  706.                     scanPI();
  707.                     break;
  708.                 case Token_StartTag :
  709.                     if (fDoNamespaces)
  710.                         scanStartTagNS(gotData);
  711.                     else
  712.                         scanStartTag(gotData);
  713.                     break;
  714.                 default :
  715.                     fReaderMgr.skipToChar(chOpenAngle);
  716.                     break;
  717.             }
  718.             if (orgReader != fReaderMgr.getCurrentReaderNum())
  719.                 emitError(XMLErrs::PartialMarkupInEntity);
  720.             // If we hit the end, then do the miscellaneous part
  721.             if (!gotData)
  722.             {
  723.                 scanMiscellaneous();
  724.                 if (fValidate)
  725.                     fValueStoreCache->endDocument();
  726.                 if (fDocHandler)
  727.                     fDocHandler->endDocument();
  728.             }
  729.         }
  730.     }
  731.     //
  732.     //  NOTE:
  733.     //
  734.     //  In all of the error processing below, the emitError() call MUST come
  735.     //  before the flush of the reader mgr, or it will fail because it tries
  736.     //  to find out the position in the XML source of the error.
  737.     //
  738.     catch(const XMLErrs::Codes)
  739.     {
  740.         // This is a 'first failure' exception, so reset and return failure
  741.         fReaderMgr.reset();
  742.         return false;
  743.     }
  744.     catch(const XMLValid::Codes)
  745.     {
  746.         // This is a 'first fatal error' type exit, so reset and reuturn failure
  747.         fReaderMgr.reset();
  748.         return false;
  749.     }
  750.     // We have to propogate SAX exceptions
  751.     catch(const SAXException&)
  752.     {
  753.         // Just reset our reader manager and rethrow SAX exception
  754.         fReaderMgr.reset();
  755.         throw;
  756.     }
  757.     catch(const XMLException& excToCatch)
  758.     {
  759.         //
  760.         //  Emit the error and catch any user exception thrown from here. Make
  761.         //  sure in all cases we flush the reader manager.
  762.         //
  763.         fInException = true;
  764.         try
  765.         {
  766.             if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning)
  767.                 emitError
  768.                 (
  769.                     XMLErrs::XMLException_Warning
  770.                     , excToCatch.getType()
  771.                     , excToCatch.getMessage()
  772.                 );
  773.             else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal)
  774.                 emitError
  775.                 (
  776.                     XMLErrs::XMLException_Fatal
  777.                     , excToCatch.getType()
  778.                     , excToCatch.getMessage()
  779.                 );
  780.             else
  781.                 emitError
  782.                 (
  783.                     XMLErrs::XMLException_Error
  784.                     , excToCatch.getType()
  785.                     , excToCatch.getMessage()
  786.                 );
  787.         }
  788.         catch(...)
  789.         {
  790.             // Reset and rethrow user error
  791.             fReaderMgr.reset();
  792.             throw;
  793.         }
  794.         // Reset and return failure
  795.         fReaderMgr.reset();
  796.         return false;
  797.     }
  798.     catch(...)
  799.     {
  800.         // Reset and rethrow original error
  801.         fReaderMgr.reset();
  802.         throw;
  803.     }
  804.     // If we hit the end, then flush the reader manager
  805.     if (!retVal)
  806.         fReaderMgr.reset();
  807.     return retVal;
  808. }
  809. void XMLScanner::scanReset(XMLPScanToken& token)
  810. {
  811.     // Make sure this token is still legal
  812.     if (!isLegalToken(token))
  813.         ThrowXML(RuntimeException, XMLExcepts::Scan_BadPScanToken);
  814.     // Reset the reader manager
  815.     fReaderMgr.reset();
  816.     // And invalidate any tokens by bumping our sequence number
  817.     fSequenceId++;
  818.     // Reset our error count
  819.     fErrorCount = 0;
  820. }
  821. // ---------------------------------------------------------------------------
  822. //  XMLScanner: Private helper methods. Most of these are implemented in
  823. //  XMLScanner2.Cpp.
  824. // ---------------------------------------------------------------------------
  825. //
  826. //  This method handles the common initialization, to avoid having to do
  827. //  it redundantly in multiple constructors.
  828. //
  829. void XMLScanner::commonInit()
  830. {
  831.     //
  832.     //  We have to do a little init that involves statics, so we have to
  833.     //  use the mutex to protect it.
  834.     //
  835.     {
  836.         XMLMutexLock lockInit(&gScannerMutex());
  837.         // If we haven't loaded our message yet, then do that
  838.         if (!gMsgLoader)
  839.         {
  840.             gMsgLoader = XMLPlatformUtils::loadMsgSet(XMLUni::fgXMLErrDomain);
  841.             if (!gMsgLoader)
  842.                 XMLPlatformUtils::panic(XMLPlatformUtils::Panic_CantLoadMsgDomain);
  843.             // Register this object to be cleaned up at termination
  844. cleanupMsgLoader.registerCleanup(reinitMsgLoader);
  845.         }
  846.         // And assign ourselves the next available scanner id
  847.         fScannerId = ++gScannerId;
  848.     }
  849.     //
  850.     //  Create the element state array
  851.     //
  852.     fElemState = new unsigned int[fElemStateSize];
  853.     //
  854.     //  Create the attribute list, which is used to store attribute values
  855.     //  during start tag processing. Give it a reasonable initial size that
  856.     //  will serve for most folks, though it will grow as required.
  857.     //
  858.     fAttrList = new RefVectorOf<XMLAttr>(32);
  859.     //
  860.     //  And we need one for the raw attribute scan. This just stores key/
  861.     //  value string pairs (prior to any processing.)
  862.     //
  863.     fRawAttrList = new RefVectorOf<KVStringPair>(32);
  864.     //
  865.     //  Create the id ref list. This is used to enforce XML 1.0 ID ref
  866.     //  semantics, i.e. all id refs must refer to elements that exist
  867.     //
  868.     fIDRefList = new RefHashTableOf<XMLRefInfo>(109);
  869.     //  Create the EntityDeclPool
  870.     fEntityDeclPool = new NameIdPool<DTDEntityDecl>(109);
  871.     //  Create the GrammarResolver
  872.     fGrammarResolver = new GrammarResolver();
  873.     resetEntityDeclPool();
  874.     //  Create the Validator and init them
  875.     fDTDValidator = new DTDValidator();
  876.     initValidator(fDTDValidator);
  877.     fSchemaValidator = new SchemaValidator();
  878.     initValidator(fSchemaValidator);
  879.     // Create IdentityConstraint info
  880.     fMatcherStack = new XPathMatcherStack();
  881.     fValueStoreCache = new ValueStoreCache();
  882.     fFieldActivator = new FieldActivator(fValueStoreCache, fMatcherStack);
  883.     fValueStoreCache->setScanner(this);
  884. }
  885. void XMLScanner::initValidator(XMLValidator* theValidator) {
  886.     //
  887.     //  Tell the validator about the stuff it needs to know in order to
  888.     //  do its work.
  889.     //
  890.     theValidator->setScannerInfo(this, &fReaderMgr, &fBufMgr);
  891.     theValidator->setErrorReporter(fErrorReporter);
  892.     if (theValidator->handlesSchema())
  893.         ((SchemaValidator*) theValidator)->setGrammarResolver(fGrammarResolver);
  894. }
  895. void XMLScanner::resetEntityDeclPool() {
  896.     fEntityDeclPool->removeAll();
  897.     //
  898.     //  Add the default entity entries for the character refs that must always
  899.     //  be present. We indicate that they are from the internal subset. They
  900.     //  aren't really, but they have to look that way so that they are still
  901.     //  valid for use within a standalone document.
  902.     //
  903.     //  We also mark them as special char entities, which allows them to be
  904.     //  used in places whether other non-numeric general entities cannot.
  905.     //
  906.     fEntityDeclPool->put(new DTDEntityDecl(gAmp, chAmpersand, true, true));
  907.     fEntityDeclPool->put(new DTDEntityDecl(gLT, chOpenAngle, true, true));
  908.     fEntityDeclPool->put(new DTDEntityDecl(gGT, chCloseAngle, true, true));
  909.     fEntityDeclPool->put(new DTDEntityDecl(gQuot, chDoubleQuote, true, true));
  910.     fEntityDeclPool->put(new DTDEntityDecl(gApos, chSingleQuote, true, true));
  911. }
  912. void XMLScanner::resetURIStringPool() {
  913.     fURIStringPool->flushAll();
  914.     fEmptyNamespaceId   = fURIStringPool->addOrFind(XMLUni::fgZeroLenString);
  915.     fUnknownNamespaceId = fURIStringPool->addOrFind(XMLUni::fgUnknownURIName);
  916.     fXMLNamespaceId     = fURIStringPool->addOrFind(XMLUni::fgXMLURIName);
  917.     fXMLNSNamespaceId   = fURIStringPool->addOrFind(XMLUni::fgXMLNSURIName);
  918.     fSchemaNamespaceId  = fURIStringPool->addOrFind(SchemaSymbols::fgURI_XSI);
  919. }
  920. // ---------------------------------------------------------------------------
  921. //  XMLScanner: Error emitting methods
  922. // ---------------------------------------------------------------------------
  923. //
  924. //  These methods are called whenever the scanner wants to emit an error.
  925. //  It handles getting the message loaded, doing token replacement, etc...
  926. //  and then calling the error handler, if its installed.
  927. //
  928. void XMLScanner::emitError(const XMLErrs::Codes toEmit)
  929. {
  930.     // Bump the error count if it is not a warning
  931.     if (XMLErrs::errorType(toEmit) != XMLErrorReporter::ErrType_Warning)
  932.         incrementErrorCount();
  933.     if (fErrorReporter)
  934.     {
  935.         // Load the message into a local for display
  936.         const unsigned int msgSize = 1023;
  937.         XMLCh errText[msgSize + 1];
  938.         // Lock the mutex and load the text
  939.         {
  940.             XMLMutexLock lockInit(&gScannerMutex());
  941.             if (!gMsgLoader->loadMsg(toEmit, errText, msgSize))
  942.             {
  943.                 // <TBD> Probably should load a default msg here
  944.             }
  945.         }
  946.         //
  947.         //  Create a LastExtEntityInfo structure and get the reader manager
  948.         //  to fill it in for us. This will give us the information about
  949.         //  the last reader on the stack that was an external entity of some
  950.         //  sort (i.e. it will ignore internal entities.
  951.         //
  952.         ReaderMgr::LastExtEntityInfo lastInfo;
  953.         fReaderMgr.getLastExtEntityInfo(lastInfo);
  954.         fErrorReporter->error
  955.         (
  956.             toEmit
  957.             , XMLUni::fgXMLErrDomain
  958.             , XMLErrs::errorType(toEmit)
  959.             , errText
  960.             , lastInfo.systemId
  961.             , lastInfo.publicId
  962.             , lastInfo.lineNumber
  963.             , lastInfo.colNumber
  964.         );
  965.     }
  966.     // Bail out if its fatal an we are to give up on the first fatal error
  967.     if (XMLErrs::isFatal(toEmit) && fExitOnFirstFatal && !fInException)
  968.         throw toEmit;
  969. }
  970. void XMLScanner::emitError( const   XMLErrs::Codes    toEmit
  971.                             , const XMLCh* const        text1
  972.                             , const XMLCh* const        text2
  973.                             , const XMLCh* const        text3
  974.                             , const XMLCh* const        text4)
  975. {
  976.     // Bump the error count if it is not a warning
  977.     if (XMLErrs::errorType(toEmit) != XMLErrorReporter::ErrType_Warning)
  978.         incrementErrorCount();
  979.     if (fErrorReporter)
  980.     {
  981.         //
  982.         //  Load the message into alocal and replace any tokens found in
  983.         //  the text.
  984.         //
  985.         const unsigned int maxChars = 2047;
  986.         XMLCh errText[maxChars + 1];
  987.         // Lock the mutex and load the text
  988.         {
  989.             XMLMutexLock lockInit(&gScannerMutex());
  990.             if (!gMsgLoader->loadMsg(toEmit, errText, maxChars, text1, text2, text3, text4))
  991.             {
  992.                 // <TBD> Should probably load a default message here
  993.             }
  994.         }
  995.         //
  996.         //  Create a LastExtEntityInfo structure and get the reader manager
  997.         //  to fill it in for us. This will give us the information about
  998.         //  the last reader on the stack that was an external entity of some
  999.         //  sort (i.e. it will ignore internal entities.
  1000.         //
  1001.         ReaderMgr::LastExtEntityInfo lastInfo;
  1002.         fReaderMgr.getLastExtEntityInfo(lastInfo);
  1003.         fErrorReporter->error
  1004.         (
  1005.             toEmit
  1006.             , XMLUni::fgXMLErrDomain
  1007.             , XMLErrs::errorType(toEmit)
  1008.             , errText
  1009.             , lastInfo.systemId
  1010.             , lastInfo.publicId
  1011.             , lastInfo.lineNumber
  1012.             , lastInfo.colNumber
  1013.         );
  1014.     }
  1015.     // Bail out if its fatal an we are to give up on the first fatal error
  1016.     if (XMLErrs::isFatal(toEmit) && fExitOnFirstFatal && !fInException)
  1017.         throw toEmit;
  1018. }
  1019. void XMLScanner::emitError( const   XMLErrs::Codes    toEmit
  1020.                             , const char* const         text1
  1021.                             , const char* const         text2
  1022.                             , const char* const         text3
  1023.                             , const char* const         text4)
  1024. {
  1025.     // Bump the error count if it is not a warning
  1026.     if (XMLErrs::errorType(toEmit) != XMLErrorReporter::ErrType_Warning)
  1027.         incrementErrorCount();
  1028.     if (fErrorReporter)
  1029.     {
  1030.         //
  1031.         //  Load the message into alocal and replace any tokens found in
  1032.         //  the text.
  1033.         //
  1034.         const unsigned int maxChars = 2047;
  1035.         XMLCh errText[maxChars + 1];
  1036.         // Lock the mutex and load the text
  1037.         {
  1038.             XMLMutexLock lockInit(&gScannerMutex());
  1039.             if (!gMsgLoader->loadMsg(toEmit, errText, maxChars, text1, text2, text3, text4))
  1040.             {
  1041.                 // <TBD> Should probably load a default message here
  1042.             }
  1043.         }
  1044.         //
  1045.         //  Create a LastExtEntityInfo structure and get the reader manager
  1046.         //  to fill it in for us. This will give us the information about
  1047.         //  the last reader on the stack that was an external entity of some
  1048.         //  sort (i.e. it will ignore internal entities.
  1049.         //
  1050.         ReaderMgr::LastExtEntityInfo lastInfo;
  1051.         fReaderMgr.getLastExtEntityInfo(lastInfo);
  1052.         fErrorReporter->error
  1053.         (
  1054.             toEmit
  1055.             , XMLUni::fgXMLErrDomain
  1056.             , XMLErrs::errorType(toEmit)
  1057.             , errText
  1058.             , lastInfo.systemId
  1059.             , lastInfo.publicId
  1060.             , lastInfo.lineNumber
  1061.             , lastInfo.colNumber
  1062.         );
  1063.     }
  1064.     // Bail out if its fatal an we are to give up on the first fatal error
  1065.     if (XMLErrs::isFatal(toEmit) && fExitOnFirstFatal && !fInException)
  1066.         throw toEmit;
  1067. }
  1068. // ---------------------------------------------------------------------------
  1069. //  XMLScanner: Getter methods
  1070. // ---------------------------------------------------------------------------
  1071. //
  1072. //  This method allows the caller to query the current location of the scanner.
  1073. //  It will return the sys/public ids of the current entity, and the line/col
  1074. //  position within it.
  1075. //
  1076. //  NOTE: This API returns the location with the last external file. So if its
  1077. //  currently scanning an entity, the position returned will be the end of
  1078. //  the entity reference in the file that had the reference.
  1079. //
  1080. bool
  1081. XMLScanner::getLastExtLocation(         XMLCh* const    sysIdToFill
  1082.                                 , const unsigned int    maxSysIdChars
  1083.                                 ,       XMLCh* const    pubIdToFill
  1084.                                 , const unsigned int    maxPubIdChars
  1085.                                 ,       unsigned int&   lineToFill
  1086.                                 ,       unsigned int&   colToFill)
  1087. {
  1088.     // Create a local info object and get it filled in by the reader manager
  1089.     ReaderMgr::LastExtEntityInfo lastInfo;
  1090.     fReaderMgr.getLastExtEntityInfo(lastInfo);
  1091.     // Fill in the line and column number
  1092.     lineToFill = lastInfo.lineNumber;
  1093.     colToFill = lastInfo.colNumber;
  1094.     // And copy over as much of the ids as will fit
  1095.     sysIdToFill[0] = 0;
  1096.     if (lastInfo.systemId)
  1097.     {
  1098.         if (XMLString::stringLen(lastInfo.systemId) > maxSysIdChars)
  1099.             return false;
  1100.         XMLString::copyString(sysIdToFill, lastInfo.systemId);
  1101.     }
  1102.     pubIdToFill[0] = 0;
  1103.     if (lastInfo.publicId)
  1104.     {
  1105.         if (XMLString::stringLen(lastInfo.publicId) > maxPubIdChars)
  1106.             return false;
  1107.         XMLString::copyString(pubIdToFill, lastInfo.publicId);
  1108.     }
  1109.     return true;
  1110. }
  1111. // ---------------------------------------------------------------------------
  1112. //  XMLScanner: Private scanning methods
  1113. // ---------------------------------------------------------------------------
  1114. //
  1115. //  This method is called from scanStartTag() to handle the very raw initial
  1116. //  scan of the attributes. It just fills in the passed collection with
  1117. //  key/value pairs for each attribute. No processing is done on them at all.
  1118. //
  1119. unsigned int
  1120. XMLScanner::rawAttrScan(const   XMLCh* const                elemName
  1121.                         ,       RefVectorOf<KVStringPair>&  toFill
  1122.                         ,       bool&                       isEmpty)
  1123. {
  1124.     //
  1125.     //  Keep up with how many attributes we've seen so far, and how many
  1126.     //  elements are available in the vector. This way we can reuse old
  1127.     //  elements until we run out and then expand it.
  1128.     //
  1129.     unsigned int attCount = 0;
  1130.     unsigned int curVecSize = toFill.size();
  1131.     // Assume it is not empty
  1132.     isEmpty = false;
  1133.     //
  1134.     //  We loop until we either see a /> or >, handling key/value pairs util
  1135.     //  we get there. We place them in the passed vector, which we will expand
  1136.     //  as required to hold them.
  1137.     //
  1138.     while (true)
  1139.     {
  1140.         // Get the next character, which should be non-space
  1141.         XMLCh nextCh = fReaderMgr.peekNextChar();
  1142.         //
  1143.         //  If the next character is not a slash or closed angle bracket,
  1144.         //  then it must be whitespace, since whitespace is required
  1145.         //  between the end of the last attribute and the name of the next
  1146.         //  one.
  1147.         //
  1148.         if (attCount)
  1149.         {
  1150.             if ((nextCh != chForwardSlash) && (nextCh != chCloseAngle))
  1151.             {
  1152.                 if (XMLReader::isWhitespace(nextCh))
  1153.                 {
  1154.                     // Ok, skip by them and get another char
  1155.                     fReaderMgr.getNextChar();
  1156.                     fReaderMgr.skipPastSpaces();
  1157.                     nextCh = fReaderMgr.peekNextChar();
  1158.                 }
  1159.                  else
  1160.                 {
  1161.                     // Emit the error but keep on going
  1162.                     emitError(XMLErrs::ExpectedWhitespace);
  1163.                 }
  1164.             }
  1165.         }
  1166.         //
  1167.         //  Ok, here we first check for any of the special case characters.
  1168.         //  If its not one, then we do the normal case processing, which
  1169.         //  assumes that we've hit an attribute value, Otherwise, we do all
  1170.         //  the special case checks.
  1171.         //
  1172.         if (!XMLReader::isSpecialStartTagChar(nextCh))
  1173.         {
  1174.             //
  1175.             //  Assume its going to be an attribute, so get a name from
  1176.             //  the input.
  1177.             //
  1178.             if (!fReaderMgr.getName(fAttNameBuf))
  1179.             {
  1180.                 emitError(XMLErrs::ExpectedAttrName);
  1181.                 fReaderMgr.skipPastChar(chCloseAngle);
  1182.                 return attCount;
  1183.             }
  1184.             // And next must be an equal sign
  1185.             if (!scanEq())
  1186.             {
  1187.                 static const XMLCh tmpList[] =
  1188.                 {
  1189.                     chSingleQuote, chDoubleQuote, chCloseAngle
  1190.                     , chOpenAngle, chForwardSlash, chNull
  1191.                 };
  1192.                 emitError(XMLErrs::ExpectedEqSign);
  1193.                 //
  1194.                 //  Try to sync back up by skipping forward until we either
  1195.                 //  hit something meaningful.
  1196.                 //
  1197.                 const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);
  1198.                 if ((chFound == chCloseAngle) || (chFound == chForwardSlash))
  1199.                 {
  1200.                     // Jump back to top for normal processing of these
  1201.                     continue;
  1202.                 }
  1203.                  else if ((chFound == chSingleQuote)
  1204.                       ||  (chFound == chDoubleQuote)
  1205.                       ||  XMLReader::isWhitespace(chFound))
  1206.                 {
  1207.                     // Just fall through assuming that the value is to follow
  1208.                 }
  1209.                  else if (chFound == chOpenAngle)
  1210.                 {
  1211.                     // Assume a malformed tag and that new one is starting
  1212.                     emitError(XMLErrs::UnterminatedStartTag, elemName);
  1213.                     return attCount;
  1214.                 }
  1215.                  else
  1216.                 {
  1217.                     // Something went really wrong
  1218.                     return attCount;
  1219.                 }
  1220.             }
  1221.             //
  1222.             //  Next should be the quoted attribute value. We just do a simple
  1223.             //  and stupid scan of this value. The only thing we do here
  1224.             //  is to expand entity references.
  1225.             //
  1226.             if (!basicAttrValueScan(fAttNameBuf.getRawBuffer(), fAttValueBuf))
  1227.             {
  1228.                 static const XMLCh tmpList[] =
  1229.                 {
  1230.                     chCloseAngle, chOpenAngle, chForwardSlash, chNull
  1231.                 };
  1232.                 emitError(XMLErrs::ExpectedAttrValue);
  1233.                 //
  1234.                 //  It failed, so lets try to get synced back up. We skip
  1235.                 //  forward until we find some whitespace or one of the
  1236.                 //  chars in our list.
  1237.                 //
  1238.                 const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);
  1239.                 if ((chFound == chCloseAngle)
  1240.                 ||  (chFound == chForwardSlash)
  1241.                 ||  XMLReader::isWhitespace(chFound))
  1242.                 {
  1243.                     //
  1244.                     //  Just fall through and process this attribute, though
  1245.                     //  the value will be "".
  1246.                     //
  1247.                 }
  1248.                  else if (chFound == chOpenAngle)
  1249.                 {
  1250.                     // Assume a malformed tag and that new one is starting
  1251.                     emitError(XMLErrs::UnterminatedStartTag, elemName);
  1252.                     return attCount;
  1253.                 }
  1254.                  else
  1255.                 {
  1256.                     // Something went really wrong
  1257.                     return attCount;
  1258.                 }
  1259.             }
  1260.             //
  1261.             //  Make sure that the name is basically well formed for namespace
  1262.             //  enabled rules. It either has no colons, or it has one which
  1263.             //  is neither the first or last char.
  1264.             //
  1265.             const int colonFirst = XMLString::indexOf(fAttNameBuf.getRawBuffer(), chColon);
  1266.             if (colonFirst != -1)
  1267.             {
  1268.                 const int colonLast = XMLString::lastIndexOf(fAttNameBuf.getRawBuffer(), chColon);
  1269.                 if (colonFirst != colonLast)
  1270.                 {
  1271.                     emitError(XMLErrs::TooManyColonsInName);
  1272.                     continue;
  1273.                 }
  1274.                  else if ((colonFirst == 0)
  1275.                       ||  (colonLast == (int)fAttNameBuf.getLen() - 1))
  1276.                 {
  1277.                     emitError(XMLErrs::InvalidColonPos);
  1278.                     continue;
  1279.                 }
  1280.             }
  1281.             //
  1282.             //  And now lets add it to the passed collection. If we have not
  1283.             //  filled it up yet, then we use the next element. Else we add
  1284.             //  a new one.
  1285.             //
  1286.             KVStringPair* curPair = 0;
  1287.             if (attCount >= curVecSize)
  1288.             {
  1289.                 curPair = new KVStringPair
  1290.                 (
  1291.                     fAttNameBuf.getRawBuffer()
  1292.                     , fAttValueBuf.getRawBuffer()
  1293.                 );
  1294.                 toFill.addElement(curPair);
  1295.             }
  1296.              else
  1297.             {
  1298.                 curPair = toFill.elementAt(attCount);
  1299.                 curPair->set(fAttNameBuf.getRawBuffer(), fAttValueBuf.getRawBuffer());
  1300.             }
  1301.             // And bump the count of attributes we've gotten
  1302.             attCount++;
  1303.             // And go to the top again for another attribute
  1304.             continue;
  1305.         }
  1306.         //
  1307.         //  It was some special case character so do all of the checks and
  1308.         //  deal with it.
  1309.         //
  1310.         if (!nextCh)
  1311.             ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
  1312.         if (nextCh == chForwardSlash)
  1313.         {
  1314.             fReaderMgr.getNextChar();
  1315.             isEmpty = true;
  1316.             if (!fReaderMgr.skippedChar(chCloseAngle))
  1317.                 emitError(XMLErrs::UnterminatedStartTag, elemName);
  1318.             break;
  1319.         }
  1320.          else if (nextCh == chCloseAngle)
  1321.         {
  1322.             fReaderMgr.getNextChar();
  1323.             break;
  1324.         }
  1325.          else if (nextCh == chOpenAngle)
  1326.         {
  1327.             //
  1328.             //  Check for this one specially, since its going to be common
  1329.             //  and it is kind of auto-recovering since we've already hit the
  1330.             //  next open bracket, which is what we would have seeked to (and
  1331.             //  skipped this whole tag.)
  1332.             //
  1333.             emitError(XMLErrs::UnterminatedStartTag, elemName);
  1334.             break;
  1335.         }
  1336.          else if ((nextCh == chSingleQuote) || (nextCh == chDoubleQuote))
  1337.         {
  1338.             //
  1339.             //  Check for this one specially, which is probably a missing
  1340.             //  attribute name, e.g. ="value". Just issue expected name
  1341.             //  error and eat the quoted string, then jump back to the
  1342.             //  top again.
  1343.             //
  1344.             emitError(XMLErrs::ExpectedAttrName);
  1345.             fReaderMgr.getNextChar();
  1346.             fReaderMgr.skipQuotedString(nextCh);
  1347.             fReaderMgr.skipPastSpaces();
  1348.             continue;
  1349.         }
  1350.     }
  1351.     return attCount;
  1352. }
  1353. //
  1354. //  This method will kick off the scanning of the primary content of the
  1355. //  document, i.e. the elements.
  1356. //
  1357. bool XMLScanner::scanContent(const bool extEntity)
  1358. {
  1359.     //
  1360.     //  Go into a loop until we hit the end of the root element, or we fall
  1361.     //  out because there is no root element.
  1362.     //
  1363.     //  We have to do kind of a deeply nested double loop here in order to
  1364.     //  avoid doing the setup/teardown of the exception handler on each
  1365.     //  round. Doing it this way we only do it when an exception actually
  1366.     //  occurs.
  1367.     //
  1368.     bool gotData = true;
  1369.     bool inMarkup = false;
  1370.     while (gotData)
  1371.     {
  1372.         try
  1373.         {
  1374.             while (gotData)
  1375.             {
  1376.                 //  Sense what the next top level token is. According to what
  1377.                 //  this tells us, we will call something to handle that kind
  1378.                 //  of thing.
  1379.                 //
  1380.                 unsigned int orgReader;
  1381.                 const XMLTokens curToken = senseNextToken(orgReader);
  1382.                 //
  1383.                 //  Handle character data and end of file specially. Char data
  1384.                 //  is not markup so we don't want to handle it in the loop
  1385.                 //  below.
  1386.                 //
  1387.                 if (curToken == Token_CharData)
  1388.                 {
  1389.                     //
  1390.                     //  Scan the character data and call appropriate events. Let
  1391.                     //  him use our local character data buffer for efficiency.
  1392.                     //
  1393.                     scanCharData(fCDataBuf);
  1394.                     continue;
  1395.                 }
  1396.                  else if (curToken == Token_EOF)
  1397.                 {
  1398.                     //
  1399.                     //  The element stack better be empty at this point or we
  1400.                     //  ended prematurely before all elements were closed.
  1401.                     //
  1402.                     if (!fElemStack.isEmpty())
  1403.                     {
  1404.                         const ElemStack::StackElem* topElem = fElemStack.popTop();
  1405.                         emitError
  1406.                         (
  1407.                             XMLErrs::EndedWithTagsOnStack
  1408.                             , topElem->fThisElement->getFullName()
  1409.                         );
  1410.                     }
  1411.                     // Its the end of file, so clear the got data flag
  1412.                     gotData = false;
  1413.                     continue;
  1414.                 }
  1415.                 // We are in some sort of markup now
  1416.                 inMarkup = true;
  1417.                 //
  1418.                 //  According to the token we got, call the appropriate
  1419.                 //  scanning method.
  1420.                 //
  1421.                 switch(curToken)
  1422.                 {
  1423.                     case Token_CData :
  1424.                         // Make sure we are within content
  1425.                         if (fElemStack.isEmpty())
  1426.                             emitError(XMLErrs::CDATAOutsideOfContent);
  1427.                         scanCDSection();
  1428.                         break;
  1429.                     case Token_Comment :
  1430.                         scanComment();
  1431.                         break;
  1432.                     case Token_EndTag :
  1433.                         scanEndTag(gotData);
  1434.                         break;
  1435.                     case Token_PI :
  1436.                         scanPI();
  1437.                         break;
  1438.                     case Token_StartTag :
  1439.                         if (fDoNamespaces)
  1440.                             scanStartTagNS(gotData);
  1441.                         else
  1442.                             scanStartTag(gotData);
  1443.                         break;
  1444.                     default :
  1445.                         fReaderMgr.skipToChar(chOpenAngle);
  1446.                         break;
  1447.                 }
  1448.                 if (orgReader != fReaderMgr.getCurrentReaderNum())
  1449.                     emitError(XMLErrs::PartialMarkupInEntity);
  1450.                 // And we are back out of markup again
  1451.                 inMarkup = false;
  1452.             }
  1453.         }
  1454.         catch(const EndOfEntityException& toCatch)
  1455.         {
  1456.             //
  1457.             //  If we were in some markup when this happened, then its a
  1458.             //  partial markup error.
  1459.             //
  1460.             if (inMarkup)
  1461.                 emitError(XMLErrs::PartialMarkupInEntity);
  1462.             // Send an end of entity reference event
  1463.             if (fDocHandler)
  1464.                 fDocHandler->endEntityReference(toCatch.getEntity());
  1465.             inMarkup = false;
  1466.         }
  1467.     }
  1468.     // It went ok, so return success
  1469.     return true;
  1470. }
  1471. void XMLScanner::scanEndTag(bool& gotData)
  1472. {
  1473.     //
  1474.     //  Assume we will still have data until proven otherwise. It will only
  1475.     //  ever be false if this is the end of the root element.
  1476.     //
  1477.     gotData = true;
  1478.     //
  1479.     //  Check if the element stack is empty. If so, then this is an unbalanced
  1480.     //  element (i.e. more ends than starts, perhaps because of bad text
  1481.     //  causing one to be skipped.)
  1482.     //
  1483.     if (fElemStack.isEmpty())
  1484.     {
  1485.         emitError(XMLErrs::MoreEndThanStartTags);
  1486.         fReaderMgr.skipPastChar(chCloseAngle);
  1487.         ThrowXML(RuntimeException, XMLExcepts::Scan_UnbalancedStartEnd);
  1488.     }
  1489.     // After the </ is the element QName, so get a name from the input
  1490.     XMLBufBid bbQName(&fBufMgr);
  1491.     XMLBuffer& qnameBuf = bbQName.getBuffer();
  1492.     if (!fReaderMgr.getName(qnameBuf))
  1493.     {
  1494.         // It failed so we can't really do anything with it
  1495.         emitError(XMLErrs::ExpectedElementName);
  1496.         fReaderMgr.skipPastChar(chCloseAngle);
  1497.         return;
  1498.     }
  1499.     unsigned int uriId = fEmptyNamespaceId;
  1500.     XMLBufBid bbName(&fBufMgr);
  1501.     if (fDoNamespaces)
  1502.     {
  1503.         XMLBufBid bbPrefix(&fBufMgr);
  1504.         uriId = resolveQName
  1505.         (
  1506.             qnameBuf.getRawBuffer()
  1507.             , bbName.getBuffer()
  1508.             , bbPrefix.getBuffer()
  1509.             , ElemStack::Mode_Element
  1510.         );
  1511.     }
  1512.     //
  1513.     //  Pop the stack of the element we are supposed to be ending. Remember
  1514.     //  that we don't own this. The stack just keeps them and reuses them.
  1515.     //
  1516.     //  NOTE: We CANNOT do this until we've resolved the element name because
  1517.     //  the element stack top contains the prefix to URI mappings for this
  1518.     //  element.
  1519.     //
  1520.     unsigned int topUri = fElemStack.getCurrentURI();
  1521.     const ElemStack::StackElem* topElem = fElemStack.popTop();
  1522.     // See if it was the root element, to avoid multiple calls below
  1523.     const bool isRoot = fElemStack.isEmpty();
  1524.     // Make sure that its the end of the element that we expect
  1525.     XMLElementDecl* tempElement = topElem->fThisElement;
  1526.     if (fDoNamespaces && fGrammarType == Grammar::SchemaGrammarType) {
  1527.         if ((topUri != uriId) || (XMLString::compareString(tempElement->getBaseName(), bbName.getRawBuffer())))
  1528.         {
  1529.             emitError
  1530.             (
  1531.                 XMLErrs::ExpectedEndOfTagX
  1532.                 , topElem->fThisElement->getFullName()
  1533.             );
  1534.         }
  1535.     }
  1536.     else {
  1537.         if (XMLString::compareString(tempElement->getFullName(), qnameBuf.getRawBuffer()))
  1538.         {
  1539.             emitError
  1540.             (
  1541.                 XMLErrs::ExpectedEndOfTagX
  1542.                 , topElem->fThisElement->getFullName()
  1543.             );
  1544.         }
  1545.     }
  1546.     // Make sure we are back on the same reader as where we started
  1547.     if (topElem->fReaderNum != fReaderMgr.getCurrentReaderNum())
  1548.         emitError(XMLErrs::PartialTagMarkupError);
  1549.     // Skip optional whitespace
  1550.     fReaderMgr.skipPastSpaces();
  1551.     // Make sure we find the closing bracket
  1552.     if (!fReaderMgr.skippedChar(chCloseAngle))
  1553.     {
  1554.         emitError
  1555.         (
  1556.             XMLErrs::UnterminatedEndTag
  1557.             , topElem->fThisElement->getFullName()
  1558.         );
  1559.     }
  1560.     // If we have a doc handler, tell it about the end tag
  1561.     if (fDocHandler)
  1562.     {
  1563.         fDocHandler->endElement
  1564.         (
  1565.             *topElem->fThisElement
  1566.             , uriId
  1567.             , isRoot
  1568.         );
  1569.     }
  1570.     //
  1571.     //  If validation is enabled, then lets pass him the list of children and
  1572.     //  this element and let him validate it.
  1573.     //
  1574.     if (fValidate)
  1575.     {
  1576.         int res = fValidator->checkContent
  1577.         (
  1578.             topElem->fThisElement
  1579.             , topElem->fChildren
  1580.             , topElem->fChildCount
  1581.         );
  1582.         if (res >= 0)
  1583.         {
  1584.             //
  1585.             //  One of the elements is not valid for the content. NOTE that
  1586.             //  if no children were provided but the content model requires
  1587.             //  them, it comes back with a zero value. But we cannot use that
  1588.             //  to index the child array in this case, and have to put out a
  1589.             //  special message.
  1590.             //
  1591.             if (!topElem->fChildCount)
  1592.             {
  1593.                 fValidator->emitError
  1594.                 (
  1595.                     XMLValid::EmptyNotValidForContent
  1596.                     , topElem->fThisElement->getFormattedContentModel()
  1597.                 );
  1598.             }
  1599.              else if ((unsigned int)res >= topElem->fChildCount)
  1600.             {
  1601.                 fValidator->emitError
  1602.                 (
  1603.                     XMLValid::NotEnoughElemsForCM
  1604.                     , topElem->fThisElement->getFormattedContentModel()
  1605.                 );
  1606.             }
  1607.              else
  1608.             {
  1609.                 fValidator->emitError
  1610.                 (
  1611.                     XMLValid::ElementNotValidForContent
  1612.                     , topElem->fChildren[res]->getRawName()
  1613.                     , topElem->fThisElement->getFormattedContentModel()
  1614.                 );
  1615.             }
  1616.         }
  1617.         // reset xsi:type ComplexTypeInfo
  1618.         if (fGrammarType == Grammar::SchemaGrammarType) {
  1619.             ((SchemaElementDecl*)topElem->fThisElement)->setXsiComplexTypeInfo(0);
  1620.             // call matchers and de-activate context
  1621.             int oldCount = fMatcherStack->getMatcherCount();
  1622.             if (oldCount ||
  1623.                 ((SchemaElementDecl*)topElem->fThisElement)->getIdentityConstraintCount()) {
  1624.                 for (int i = oldCount - 1; i >= 0; i--) {
  1625.                     XPathMatcher* matcher = fMatcherStack->getMatcherAt(i);
  1626.                     matcher->endElement(*(topElem->fThisElement));
  1627.                 }
  1628.                 if (fMatcherStack->size() > 0) {
  1629.                     fMatcherStack->popContext();
  1630.                 }
  1631.                 // handle everything *but* keyref's.
  1632.                 int newCount = fMatcherStack->getMatcherCount();
  1633.                 for (int j = oldCount - 1; j >= newCount; j--) {
  1634.                     XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
  1635.                     IdentityConstraint* ic = matcher->getIdentityConstraint();
  1636.                     if (ic  && (ic->getType() != IdentityConstraint::KEYREF)) {
  1637.                         matcher->endDocumentFragment();
  1638.                         fValueStoreCache->transplant(ic);
  1639.                     }
  1640.                     else if (!ic) {
  1641.                         matcher->endDocumentFragment();
  1642.                     }
  1643.                 }
  1644.                 // now handle keyref's...
  1645.                 for (int k = oldCount - 1; k >= newCount; k--) {
  1646.                     XPathMatcher* matcher = fMatcherStack->getMatcherAt(k);
  1647.                     IdentityConstraint* ic = matcher->getIdentityConstraint();
  1648.                     if (ic && (ic->getType() == IdentityConstraint::KEYREF)) {
  1649.                         ValueStore* values = fValueStoreCache->getValueStoreFor(ic);
  1650.                         if (values) { // nothing to do if nothing matched!
  1651.                             values->endDcocumentFragment(fValueStoreCache);
  1652.                         }
  1653.                         matcher->endDocumentFragment();
  1654.                     }
  1655.                 }
  1656.                 fValueStoreCache->endElement();
  1657.             }
  1658.         }
  1659.     }
  1660.     // If this was the root, then done with content
  1661.     gotData = !isRoot;
  1662.     if (gotData) {
  1663.         if (fDoNamespaces) {
  1664.             // Restore the grammar
  1665.             fGrammar = fElemStack.getCurrentGrammar();
  1666.             fGrammarType = fGrammar->getGrammarType();
  1667.             if (fGrammarType == Grammar::SchemaGrammarType && !fValidator->handlesSchema()) {
  1668.                 if (fValidatorFromUser)
  1669.                     ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
  1670.                 else {
  1671.                     fValidator = fSchemaValidator;
  1672.                 }
  1673.             }
  1674.             else if (fGrammarType == Grammar::DTDGrammarType && !fValidator->handlesDTD()) {
  1675.                 if (fValidatorFromUser)
  1676.                     ThrowXML(RuntimeException, XMLExcepts::Gen_NoDTDValidator);
  1677.                 else {
  1678.                     fValidator = fDTDValidator;
  1679.                 }
  1680.             }
  1681.             fValidator->setGrammar(fGrammar);
  1682.         }
  1683.         // Restore the validation flag
  1684.         fValidate = fElemStack.getValidationFlag();
  1685.     }
  1686. }
  1687. //
  1688. //  This method is called after the end of the root element, to handle
  1689. //  any miscellaneous stuff hanging around.
  1690. //
  1691. void XMLScanner::scanMiscellaneous()
  1692. {
  1693.     // Get a buffer for this work
  1694.     XMLBufBid bbCData(&fBufMgr);
  1695.     while (true)
  1696.     {
  1697.         try
  1698.         {
  1699.             const XMLCh nextCh = fReaderMgr.peekNextChar();
  1700.             // Watch for end of file and break out
  1701.             if (!nextCh)
  1702.                 break;
  1703.             if (nextCh == chOpenAngle)
  1704.             {
  1705.                 if (checkXMLDecl(true))
  1706.                 {
  1707.                     // Can't have an XML decl here
  1708.                     emitError(XMLErrs::NotValidAfterContent);
  1709.                     fReaderMgr.skipPastChar(chCloseAngle);
  1710.                 }
  1711.                  else if (fReaderMgr.skippedString(XMLUni::fgPIString))
  1712.                 {
  1713.                     scanPI();
  1714.                 }
  1715.                  else if (fReaderMgr.skippedString(XMLUni::fgCommentString))
  1716.                 {
  1717.                     scanComment();
  1718.                 }
  1719.                  else
  1720.                 {
  1721.                     // This can't be possible, so just give up
  1722.                     emitError(XMLErrs::ExpectedCommentOrPI);
  1723.                     fReaderMgr.skipPastChar(chCloseAngle);
  1724.                 }
  1725.             }
  1726.              else if (XMLReader::isWhitespace(nextCh))
  1727.             {
  1728.                 //
  1729.                 //  If we have a doc handler, then gather up the spaces and
  1730.                 //  call back. Otherwise, just skip over whitespace.
  1731.                 //
  1732.                 if (fDocHandler)
  1733.                 {
  1734.                     fReaderMgr.getSpaces(bbCData.getBuffer());
  1735.                     fDocHandler->ignorableWhitespace
  1736.                     (
  1737.                         bbCData.getRawBuffer()
  1738.                         , bbCData.getLen()
  1739.                         , false
  1740.                     );
  1741.                 }
  1742.                  else
  1743.                 {
  1744.                     fReaderMgr.skipPastSpaces();
  1745.                 }
  1746.             }
  1747.              else
  1748.             {
  1749.                 emitError(XMLErrs::ExpectedCommentOrPI);
  1750.                 fReaderMgr.skipPastChar(chCloseAngle);
  1751.             }
  1752.         }
  1753.         catch(const EndOfEntityException&)
  1754.         {
  1755.             //
  1756.             //  Some entity leaked out of the content part of the document. Issue
  1757.             //  a warning and keep going.
  1758.             //
  1759.             emitError(XMLErrs::EntityPropogated);
  1760.         }
  1761.     }
  1762. }
  1763. //
  1764. //  Scans a PI and calls the appropriate callbacks. At entry we have just
  1765. //  scanned the <? part, and need to now start on the PI target name.
  1766. //
  1767. void XMLScanner::scanPI()
  1768. {
  1769.     const XMLCh* namePtr = 0;
  1770.     const XMLCh* targetPtr = 0;
  1771.     //
  1772.     //  If there are any spaces here, then warn about it. If we aren't in
  1773.     //  'first error' mode, then we'll come back and can easily pick up
  1774.     //  again by just skipping them.
  1775.     //
  1776.     if (fReaderMgr.lookingAtSpace())
  1777.     {
  1778.         emitError(XMLErrs::PINameExpected);
  1779.         fReaderMgr.skipPastSpaces();
  1780.     }
  1781.     // Get a buffer for the PI name and scan it in
  1782.     XMLBufBid bbName(&fBufMgr);
  1783.     if (!fReaderMgr.getName(bbName.getBuffer()))
  1784.     {
  1785.         emitError(XMLErrs::PINameExpected);
  1786.         fReaderMgr.skipPastChar(chCloseAngle);
  1787.         return;
  1788.     }
  1789.     // Point the name pointer at the raw data
  1790.     namePtr = bbName.getRawBuffer();
  1791.     // See if it is some form of 'xml' and emit a warning
  1792.     if (!XMLString::compareIString(namePtr, XMLUni::fgXMLString))
  1793.         emitError(XMLErrs::NoPIStartsWithXML);
  1794.     // If namespaces are enabled, then no colons allowed
  1795.     if (fDoNamespaces)
  1796.     {
  1797.         if (XMLString::indexOf(namePtr, chColon) != -1)
  1798.             emitError(XMLErrs::ColonNotLegalWithNS);
  1799.     }
  1800.     //
  1801.     //  If we don't hit a space next, then the PI has no target. If we do
  1802.     //  then get out the target. Get a buffer for it as well
  1803.     //
  1804.     XMLBufBid bbTarget(&fBufMgr);
  1805.     if (fReaderMgr.skippedSpace())
  1806.     {
  1807.         // Skip any leading spaces
  1808.         fReaderMgr.skipPastSpaces();
  1809.         // It does have a target, so lets move on to deal with that.
  1810.         while (1)
  1811.         {
  1812.             const XMLCh nextCh = fReaderMgr.getNextChar();
  1813.             // Watch for an end of file, which is always bad here
  1814.             if (!nextCh)
  1815.             {
  1816.                 emitError(XMLErrs::UnterminatedPI);
  1817.                 ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
  1818.             }
  1819.             // Watch for potential terminating character
  1820.             if (nextCh == chQuestion)
  1821.             {
  1822.                 // It must be followed by '>' to be a termination of the target
  1823.                 if (fReaderMgr.skippedChar(chCloseAngle))
  1824.                     break;
  1825.             }
  1826.             // Watch for invalid chars but try to keep going
  1827.             if (!XMLReader::isXMLChar(nextCh))
  1828.             {
  1829.                 XMLCh tmpBuf[9];
  1830.                 XMLString::binToText
  1831.                 (
  1832.                     nextCh
  1833.                     , tmpBuf
  1834.                     , 8
  1835.                     , 16
  1836.                 );
  1837.                 emitError(XMLErrs::InvalidCharacter, tmpBuf);
  1838.             }
  1839.             bbTarget.append(nextCh);
  1840.         }
  1841.     }
  1842.      else
  1843.     {
  1844.         // No target, but make sure its terminated ok
  1845.         if (!fReaderMgr.skippedChar(chQuestion))
  1846.         {
  1847.             emitError(XMLErrs::UnterminatedPI);
  1848.             fReaderMgr.skipPastChar(chCloseAngle);
  1849.             return;
  1850.         }
  1851.         if (!fReaderMgr.skippedChar(chCloseAngle))
  1852.         {
  1853.             emitError(XMLErrs::UnterminatedPI);
  1854.             fReaderMgr.skipPastChar(chCloseAngle);
  1855.             return;
  1856.         }
  1857.     }
  1858.     // Point the target pointer at the raw data
  1859.     targetPtr = bbTarget.getRawBuffer();
  1860.     // If we have a handler, then call it
  1861.     if (fDocHandler)
  1862.     {
  1863.         fDocHandler->docPI
  1864.         (
  1865.             namePtr
  1866.             , targetPtr
  1867.        );
  1868.     }
  1869. }
  1870. //
  1871. //  Scans all the input from the start of the file to the root element.
  1872. //  There does not have to be anything in the prolog necessarily, but usually
  1873. //  there is at least an XMLDecl.
  1874. //
  1875. //  On exit from here we are either at the end of the file or about to read
  1876. //  the opening < of the root element.
  1877. //
  1878. void XMLScanner::scanProlog()
  1879. {
  1880.     // Get a buffer for whitespace processing
  1881.     XMLBufBid bbCData(&fBufMgr);
  1882.     //
  1883.     //  Loop through the prolog. If there is no content, this could go all
  1884.     //  the way to the end of the file.
  1885.     //
  1886.     //  Note that we use a double loop here to avoid the overhead of the
  1887.     //  setup/teardown of the exception handler on each loop.
  1888.     //
  1889.     while (true)
  1890.     {
  1891.     try
  1892.     {
  1893.         while (true)
  1894.         {
  1895.             const XMLCh nextCh = fReaderMgr.peekNextChar();
  1896.             // An end of file is legal here between markup
  1897.             if (!nextCh)
  1898.                 return;
  1899.             if (nextCh == chOpenAngle)
  1900.             {
  1901.                 //
  1902.                 //  Ok, it could be the xml decl, a comment, the doc type line,
  1903.                 //  or the start of the root element.
  1904.                 //
  1905.                 if (checkXMLDecl(true))
  1906.                 {
  1907.                     // There shall be at lease --ONE-- space in between
  1908.                     // the tag '<?xml' and the VersionInfo.
  1909.                     //
  1910.                     //
  1911.                     //  If we are not at line 1, col 6, then the decl was not
  1912.                     //  the first text, so its invalid.
  1913.                     //
  1914.                     const XMLReader* curReader = fReaderMgr.getCurrentReader();
  1915.                     if ((curReader->getLineNumber() != 1)
  1916.                     ||  (curReader->getColumnNumber() != 7))
  1917.                     {
  1918.                         emitError(XMLErrs::XMLDeclMustBeFirst);
  1919.                     }
  1920.                     scanXMLDecl(Decl_XML);
  1921.                 }
  1922.                  else if (fReaderMgr.skippedString(XMLUni::fgPIString))
  1923.                 {
  1924.                     scanPI();
  1925.                 }
  1926.                  else if (fReaderMgr.skippedString(XMLUni::fgCommentString))
  1927.                 {
  1928.                     scanComment();
  1929.                 }
  1930.                  else if (fReaderMgr.skippedString(XMLUni::fgDocTypeString))
  1931.                 {
  1932.                     if (!fReuseGrammar && fValidatorFromUser && !fValidator->handlesDTD())
  1933.                     {
  1934.                         ThrowXML(RuntimeException, XMLExcepts::Gen_NoDTDValidator);
  1935.                     }
  1936.                     //
  1937.                     //  We have a doc type. So, create a DTDScanner and
  1938.                     //  switch the Grammar to the emptyNamespace one.
  1939.                     //
  1940.                     if (!switchGrammar(XMLUni::fgZeroLenString) && fValidate)
  1941.                     {
  1942.                         fValidator->emitError
  1943.                         (
  1944.                             XMLValid::GrammarNotFound
  1945.                           , XMLUni::fgZeroLenString
  1946.                         );
  1947.                     }
  1948.                     DTDScanner fDTDScanner((DTDGrammar*)fGrammar, fEntityDeclPool, fDocTypeHandler);
  1949.                     fDTDScanner.setScannerInfo(this, &fReaderMgr, &fBufMgr);
  1950.                     fDTDScanner.scanDocTypeDecl(fReuseGrammar);
  1951.                     // if reusing grammar, this has been validated already in first scan
  1952.                     // skip for performance
  1953.                     if (!fReuseGrammar && fValidate) {
  1954.                         //  validate the DTD scan so far
  1955.                         fValidator->preContentValidation(fReuseGrammar);
  1956.                     }
  1957.                 }
  1958.                  else
  1959.                 {
  1960.                     // Assume its the start of the root element
  1961.                     return;
  1962.                 }
  1963.             }
  1964.              else if (XMLReader::isWhitespace(nextCh))
  1965.             {
  1966.                 //
  1967.                 //  If we have a document handler then gather up the
  1968.                 //  whitespace and call back. Otherwise just skip over spaces.
  1969.                 //
  1970.                 if (fDocHandler)
  1971.                 {
  1972.                     fReaderMgr.getSpaces(bbCData.getBuffer());
  1973.                     fDocHandler->ignorableWhitespace
  1974.                     (
  1975.                         bbCData.getRawBuffer()
  1976.                         , bbCData.getLen()
  1977.                         , false
  1978.                     );
  1979.                 }
  1980.                  else
  1981.                 {
  1982.                     fReaderMgr.skipPastSpaces();
  1983.                 }
  1984.             }
  1985.              else
  1986.             {
  1987.                 emitError(XMLErrs::InvalidDocumentStructure);
  1988.                 fReaderMgr.skipPastChar(chCloseAngle);
  1989.             }
  1990.         }
  1991.     }
  1992.     catch(const EndOfEntityException&)
  1993.     {
  1994.         //
  1995.         //  We should never get an end of entity here. They should only
  1996.         //  occur within the doc type scanning method, and not leak out to
  1997.         //  here.
  1998.         //
  1999.         emitError
  2000.         (
  2001.             XMLErrs::UnexpectedEOE
  2002.             , "in prolog"
  2003.         );
  2004.     }
  2005.     }
  2006. }
  2007. bool XMLScanner::scanStartTag(bool& gotData)
  2008. {
  2009.     //
  2010.     //  Assume we will still have data until proven otherwise. It will only
  2011.     //  ever be false if this is the root and its empty.
  2012.     //
  2013.     gotData = true;
  2014.     //
  2015.     //  Get the QName. In this case, we are not doing namespaces, so we just
  2016.     //  use it as is and don't have to break it into parts.
  2017.     //
  2018.     if (!fReaderMgr.getName(fQNameBuf))
  2019.     {
  2020.         emitError(XMLErrs::ExpectedElementName);
  2021.         fReaderMgr.skipToChar(chOpenAngle);
  2022.         return false;
  2023.     }
  2024.     // Assume it won't be an empty tag
  2025.     bool isEmpty = false;
  2026.     //
  2027.     //  Lets try to look up the element in the validator's element decl pool
  2028.     //  We can pass bogus values for the URI id and the base name. We know that
  2029.     //  this can only be called if we are doing a DTD style validator and that
  2030.     //  he will only look at the QName.
  2031.     //
  2032.     //  We tell him to fault in a decl if he does not find one.
  2033.     //
  2034.     bool wasAdded = false;
  2035.     XMLElementDecl* elemDecl = fGrammar->findOrAddElemDecl
  2036.     (
  2037.         fEmptyNamespaceId
  2038.         , 0
  2039.         , 0
  2040.         , fQNameBuf.getRawBuffer()
  2041.         , Grammar::TOP_LEVEL_SCOPE
  2042.         , wasAdded
  2043.     );
  2044.     //
  2045.     //  We do something different here according to whether we found the
  2046.     //  element or not.
  2047.     //
  2048.     if (wasAdded)
  2049.     {
  2050.         // If validating then emit an error
  2051.         if (fValidate)
  2052.         {
  2053.             // This is to tell the reuse Validator that this element was
  2054.             // faulted-in, was not an element in the validator pool originally
  2055.             elemDecl->setCreateReason(XMLElementDecl::JustFaultIn);
  2056.             fValidator->emitError
  2057.             (
  2058.                 XMLValid::ElementNotDefined
  2059.                 , elemDecl->getFullName()
  2060.             );
  2061.         }
  2062.         //
  2063.         //  If we are not validating, then mark it as declared since it makes
  2064.         //  things simpler and we aren't going to do do the validation checks
  2065.         //  that need to know if it was really declared or not anyway.
  2066.         //
  2067.         if (!fValidate)
  2068.             elemDecl->setCreateReason(XMLElementDecl::Declared);
  2069.     }
  2070.      else
  2071.     {
  2072.         // If its not marked declared and validating, then emit an error
  2073.         if (!elemDecl->isDeclared() && fValidate)
  2074.         {
  2075.             fValidator->emitError
  2076.             (
  2077.                 XMLValid::ElementNotDefined
  2078.                 , elemDecl->getFullName()
  2079.             );
  2080.         }
  2081.     }
  2082.     // See if its the root element
  2083.     const bool isRoot = fElemStack.isEmpty();
  2084.     // Expand the element stack and add the new element
  2085.     fElemStack.addLevel(elemDecl, fReaderMgr.getCurrentReaderNum());
  2086.     fElemStack.setValidationFlag(fValidate);
  2087.     //  Validate the element
  2088.     if (fValidate)
  2089.         fValidator->validateElement(elemDecl);
  2090.     //
  2091.     //  If this is the first element and we are validating, check the root
  2092.     //  element.
  2093.     //
  2094.     if (isRoot)
  2095.     {
  2096.         if (fValidate)
  2097.         {
  2098.             //  If a DocType exists, then check if it matches the root name there.
  2099.             if (fRootElemName && XMLString::compareString(fQNameBuf.getRawBuffer(), fRootElemName))
  2100.                 fValidator->emitError(XMLValid::RootElemNotLikeDocType);
  2101.             //  Some validators may also want to check the root, call the
  2102.             //  XMLValidator::checkRootElement
  2103.             if (fValidatorFromUser && !fValidator->checkRootElement(elemDecl->getId()))
  2104.                 fValidator->emitError(XMLValid::RootElemNotLikeDocType);
  2105.         }
  2106.     }
  2107.      else
  2108.     {
  2109.         //
  2110.         //  If the element stack is not empty, then add this element as a
  2111.         //  child of the previous top element. If its empty, this is the root
  2112.         //  elem and is not the child of anything.
  2113.         //
  2114.         fElemStack.addChild(elemDecl->getElementName(), true);
  2115.     }
  2116.     //
  2117.     //  Ask the element decl to clear out the 'provided' flag on all of its
  2118.     //  att defs.
  2119.     //
  2120.     elemDecl->resetDefs();
  2121.     // Skip any whitespace after the name
  2122.     fReaderMgr.skipPastSpaces();
  2123.     //
  2124.     //  We loop until we either see a /> or >, handling attribute/value
  2125.     //  pairs until we get there.
  2126.     //
  2127.     unsigned int    attCount = 0;
  2128.     unsigned int    curAttListSize = fAttrList->size();
  2129.     while (true)
  2130.     {
  2131.         // And get the next non-space character
  2132.         XMLCh nextCh = fReaderMgr.peekNextChar();
  2133.         //
  2134.         //  If the next character is not a slash or closed angle bracket,
  2135.         //  then it must be whitespace, since whitespace is required
  2136.         //  between the end of the last attribute and the name of the next
  2137.         //  one.
  2138.         //
  2139.         if (attCount)
  2140.         {
  2141.             if ((nextCh != chForwardSlash) && (nextCh != chCloseAngle))
  2142.             {
  2143.                 if (XMLReader::isWhitespace(nextCh))
  2144.                 {
  2145.                     // Ok, skip by them and peek another char
  2146.                     fReaderMgr.skipPastSpaces();
  2147.                     nextCh = fReaderMgr.peekNextChar();
  2148.                 }
  2149.                  else
  2150.                 {
  2151.                     // Emit the error but keep on going
  2152.                     emitError(XMLErrs::ExpectedWhitespace);
  2153.                 }
  2154.             }
  2155.         }
  2156.         //
  2157.         //  Ok, here we first check for any of the special case characters.
  2158.         //  If its not one, then we do the normal case processing, which
  2159.         //  assumes that we've hit an attribute value, Otherwise, we do all
  2160.         //  the special case checks.
  2161.         //
  2162.         if (!XMLReader::isSpecialStartTagChar(nextCh))
  2163.         {
  2164.             //
  2165.             //  Assume its going to be an attribute, so get a name from
  2166.             //  the input.
  2167.             //
  2168.             if (!fReaderMgr.getName(fAttNameBuf))
  2169.             {
  2170.                 emitError(XMLErrs::ExpectedAttrName);
  2171.                 fReaderMgr.skipPastChar(chCloseAngle);
  2172.                 return false;
  2173.             }
  2174.             // And next must be an equal sign
  2175.             if (!scanEq())
  2176.             {
  2177.                 static const XMLCh tmpList[] =
  2178.                 {
  2179.                     chSingleQuote, chDoubleQuote, chCloseAngle
  2180.                     , chOpenAngle, chForwardSlash, chNull
  2181.                 };
  2182.                 emitError(XMLErrs::ExpectedEqSign);
  2183.                 //
  2184.                 //  Try to sync back up by skipping forward until we either
  2185.                 //  hit something meaningful.
  2186.                 //
  2187.                 const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);
  2188.                 if ((chFound == chCloseAngle) || (chFound == chForwardSlash))
  2189.                 {
  2190.                     // Jump back to top for normal processing of these
  2191.                     continue;
  2192.                 }
  2193.                  else if ((chFound == chSingleQuote)
  2194.                       ||  (chFound == chDoubleQuote)
  2195.                       ||  XMLReader::isWhitespace(chFound))
  2196.                 {
  2197.                     // Just fall through assuming that the value is to follow
  2198.                 }
  2199.                  else if (chFound == chOpenAngle)
  2200.                 {
  2201.                     // Assume a malformed tag and that new one is starting
  2202.                     emitError(XMLErrs::UnterminatedStartTag, elemDecl->getFullName());
  2203.                     return false;
  2204.                 }
  2205.                  else
  2206.                 {
  2207.                     // Something went really wrong
  2208.                     return false;
  2209.                 }
  2210.             }
  2211.             //
  2212.             //  See if this attribute is declared for this element. If we are
  2213.             //  not validating of course it will not be at first, but we will
  2214.             //  fault it into the pool (to avoid lots of redundant errors.)
  2215.             //
  2216.             wasAdded = false;
  2217.             XMLAttDef* attDef = elemDecl->findAttr
  2218.             (
  2219.                 fAttNameBuf.getRawBuffer()
  2220.                 , 0
  2221.                 , 0
  2222.                 , 0
  2223.                 , XMLElementDecl::AddIfNotFound
  2224.                 , wasAdded
  2225.             );
  2226.             if (wasAdded)
  2227.             {
  2228.                 //
  2229.                 //  If there is a validation handler, then we are validating
  2230.                 //  so emit an error.
  2231.                 //
  2232.                 if (fValidate)
  2233.                 {
  2234.                     // This is to tell the Validator that this attribute was
  2235.                     // faulted-in, was not an attribute in the attdef originally
  2236.                     attDef->setCreateReason(XMLAttDef::JustFaultIn);
  2237.                     fValidator->emitError
  2238.                     (
  2239.                         XMLValid::AttNotDefinedForElement
  2240.                         , fAttNameBuf.getRawBuffer()
  2241.                         , elemDecl->getFullName()
  2242.                     );
  2243.                 }
  2244.             }
  2245.             else
  2246.             {
  2247.                 // If this attribute was faulted-in and first occurence,
  2248.                 // then emit an error
  2249.                 if (fValidate && attDef->getCreateReason() == XMLAttDef::JustFaultIn
  2250.                     && !attDef->getProvided())
  2251.                 {
  2252.                     fValidator->emitError
  2253.                     (
  2254.                         XMLValid::AttNotDefinedForElement
  2255.                         , fAttNameBuf.getRawBuffer()
  2256.                         , elemDecl->getFullName()
  2257.                     );
  2258.                 }
  2259.             }
  2260.             //
  2261.             //  If its already provided, then there are more than one of
  2262.             //  this attribute in this start tag, so emit an error.
  2263.             //
  2264.             if (attDef->getProvided())
  2265.             {
  2266.                 emitError
  2267.                 (
  2268.                     XMLErrs::AttrAlreadyUsedInSTag
  2269.                     , attDef->getFullName()
  2270.                     , elemDecl->getFullName()
  2271.                 );
  2272.             }
  2273.              else
  2274.             {
  2275.                 // Mark this one as already seen
  2276.                 attDef->setProvided(true);
  2277.             }
  2278.             //
  2279.             //  Skip any whitespace before the value and then scan the att
  2280.             //  value. This will come back normalized with entity refs and
  2281.             //  char refs expanded.
  2282.             //
  2283.             fReaderMgr.skipPastSpaces();
  2284.             if (!scanAttValue(attDef, fAttValueBuf))
  2285.             {
  2286.                 static const XMLCh tmpList[] =
  2287.                 {
  2288.                     chCloseAngle, chOpenAngle, chForwardSlash, chNull
  2289.                 };
  2290.                 emitError(XMLErrs::ExpectedAttrValue);
  2291.                 //
  2292.                 //  It failed, so lets try to get synced back up. We skip
  2293.                 //  forward until we find some whitespace or one of the
  2294.                 //  chars in our list.
  2295.                 //
  2296.                 const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);
  2297.                 if ((chFound == chCloseAngle)
  2298.                 ||  (chFound == chForwardSlash)
  2299.                 ||  XMLReader::isWhitespace(chFound))
  2300.                 {
  2301.                     //
  2302.                     //  Just fall through and process this attribute, though
  2303.                     //  the value will be "".
  2304.                     //
  2305.                 }
  2306.                  else if (chFound == chOpenAngle)
  2307.                 {
  2308.                     // Assume a malformed tag and that new one is starting
  2309.                     emitError(XMLErrs::UnterminatedStartTag, elemDecl->getFullName());
  2310.                     return false;
  2311.                 }
  2312.                  else
  2313.                 {
  2314.                     // Something went really wrong
  2315.                     return false;
  2316.                 }
  2317.             }
  2318.             //
  2319.             //  Now that its all stretched out, lets look at its type and
  2320.             //  determine if it has a valid value. It will output any needed
  2321.             //  errors, but we just keep going. We only need to do this if
  2322.             //  we are validating.
  2323.             //
  2324.             if (!wasAdded && attDef->getCreateReason() != XMLAttDef::JustFaultIn)
  2325.             {
  2326.                 // Let the validator pass judgement on the attribute value
  2327.                 if (fValidate)
  2328.                 {
  2329.                     fValidator->validateAttrValue
  2330.                     (
  2331.                         attDef
  2332.                         , fAttValueBuf.getRawBuffer()
  2333.                     );
  2334.                 }
  2335.             }
  2336.             //
  2337.             //  Add this attribute to the attribute list that we use to
  2338.             //  pass them to the handler. We reuse its existing elements
  2339.             //  but expand it as required.
  2340.             //
  2341.             XMLAttr* curAtt;
  2342.             if (attCount >= curAttListSize)
  2343.             {
  2344.                 curAtt = new XMLAttr
  2345.                 (
  2346.                     -1
  2347.                     , fAttNameBuf.getRawBuffer()
  2348.                     , XMLUni::fgZeroLenString
  2349.                     , fAttValueBuf.getRawBuffer()
  2350.                     , attDef->getType()
  2351.                     , true
  2352.                 );
  2353.                 fAttrList->addElement(curAtt);
  2354.             }
  2355.              else
  2356.             {
  2357.                 curAtt = fAttrList->elementAt(attCount);
  2358.                 curAtt->set
  2359.                 (
  2360.                     -1
  2361.                     , fAttNameBuf.getRawBuffer()
  2362.                     , XMLUni::fgZeroLenString
  2363.                     , fAttValueBuf.getRawBuffer()
  2364.                     , attDef->getType()
  2365.                 );
  2366.                 curAtt->setSpecified(true);
  2367.             }
  2368.             attCount++;
  2369.             // And jump back to the top of the loop
  2370.             continue;
  2371.         }
  2372.         //
  2373.         //  It was some special case character so do all of the checks and
  2374.         //  deal with it.
  2375.         //
  2376.         if (!nextCh)
  2377.             ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
  2378.         if (nextCh == chForwardSlash)
  2379.         {
  2380.             fReaderMgr.getNextChar();
  2381.             isEmpty = true;
  2382.             if (!fReaderMgr.skippedChar(chCloseAngle))
  2383.                 emitError(XMLErrs::UnterminatedStartTag, elemDecl->getFullName());
  2384.             break;
  2385.         }
  2386.          else if (nextCh == chCloseAngle)
  2387.         {
  2388.             fReaderMgr.getNextChar();
  2389.             break;
  2390.         }
  2391.          else if (nextCh == chOpenAngle)
  2392.         {
  2393.             //
  2394.             //  Check for this one specially, since its going to be common
  2395.             //  and it is kind of auto-recovering since we've already hit the
  2396.             //  next open bracket, which is what we would have seeked to (and
  2397.             //  skipped this whole tag.)
  2398.             //
  2399.             emitError(XMLErrs::UnterminatedStartTag, elemDecl->getFullName());
  2400.             break;
  2401.         }
  2402.          else if ((nextCh == chSingleQuote) || (nextCh == chDoubleQuote))
  2403.         {
  2404.             //
  2405.             //  Check for this one specially, which is probably a missing
  2406.             //  attribute name, e.g. ="value". Just issue expected name
  2407.             //  error and eat the quoted string, then jump back to the
  2408.             //  top again.
  2409.             //
  2410.             emitError(XMLErrs::ExpectedAttrName);
  2411.             fReaderMgr.getNextChar();
  2412.             fReaderMgr.skipQuotedString(nextCh);
  2413.             fReaderMgr.skipPastSpaces();
  2414.             continue;
  2415.         }
  2416.     }
  2417.     //
  2418.     //  Ok, so lets get an enumerator for the attributes of this element
  2419.     //  and run through them for well formedness and validity checks. But
  2420.     //  make sure that we had any attributes before we do it, since the list
  2421.     //  would have have gotten faulted in anyway.
  2422.     //
  2423.     if (elemDecl->hasAttDefs())
  2424.     {
  2425.         XMLAttDefList& attDefList = elemDecl->getAttDefList();
  2426.         while (attDefList.hasMoreElements())
  2427.         {
  2428.             // Get the current att def, for convenience and its def type
  2429.             const XMLAttDef& curDef = attDefList.nextElement();
  2430.             const XMLAttDef::DefAttTypes defType = curDef.getDefaultType();
  2431.             if (!curDef.getProvided())
  2432.             {
  2433.                 if (fValidate)
  2434.                 {
  2435.                     // If we are validating and its required, then an error
  2436.                     if (defType == XMLAttDef::Required)
  2437.                     {
  2438.                         fValidator->emitError
  2439.                         (
  2440.                             XMLValid::RequiredAttrNotProvided
  2441.                             , curDef.getFullName()
  2442.                         );
  2443.                     }
  2444.                     else if ((defType == XMLAttDef::Default) ||
  2445.                        (defType == XMLAttDef::Fixed)  )
  2446.                     {
  2447.                         if (fStandalone && curDef.isExternal())
  2448.                         {
  2449.                             //
  2450.                             // XML 1.0 Section 2.9
  2451.                             // Document is standalone, so attributes must not be defaulted.
  2452.                             //
  2453.                             fValidator->emitError(XMLValid::NoDefAttForStandalone, curDef.getFullName(), elemDecl->getFullName());
  2454.                         }
  2455.                     }
  2456.                 }
  2457.                 // Fault in the value if needed, and bump the att count
  2458.                 if ((defType == XMLAttDef::Default)
  2459.                 ||  (defType == XMLAttDef::Fixed))
  2460.                 {
  2461.                     XMLAttr* curAtt;
  2462.                     if (attCount >= curAttListSize)
  2463.                     {
  2464.                         curAtt = new XMLAttr
  2465.                         (
  2466.                             -1
  2467.                             , curDef.getFullName()
  2468.                             , XMLUni::fgZeroLenString
  2469.                             , curDef.getValue()
  2470.                             , curDef.getType()
  2471.                             , false
  2472.                         );
  2473.                         fAttrList->addElement(curAtt);
  2474.                         curAttListSize++;
  2475.                     }
  2476.                      else
  2477.                     {
  2478.                         curAtt = fAttrList->elementAt(attCount);
  2479.                         curAtt->set
  2480.                         (
  2481.                             -1
  2482.                             , curDef.getFullName()
  2483.                             , XMLUni::fgZeroLenString
  2484.                             , curDef.getValue()
  2485.                             , curDef.getType()
  2486.                         );
  2487.                         curAtt->setSpecified(false);
  2488.                     }
  2489.                     attCount++;
  2490.                 }
  2491.             }
  2492.         }
  2493.     }
  2494.     //
  2495.     //  If empty, validate content right now if we are validating and then
  2496.     //  pop the element stack top. Else, we have to update the current stack
  2497.     //  top's namespace mapping elements.
  2498.     //
  2499.     if (isEmpty)
  2500.     {
  2501.         // If validating, then insure that its legal to have no content
  2502.         if (fValidate)
  2503.         {
  2504.             const int res = fValidator->checkContent(elemDecl, 0, 0);
  2505.             if (res >= 0)
  2506.             {
  2507.                 fValidator->emitError
  2508.                 (
  2509.                     XMLValid::ElementNotValidForContent
  2510.                     , elemDecl->getFullName()
  2511.                     , elemDecl->getFormattedContentModel()
  2512.                 );
  2513.             }
  2514.         }
  2515.         // Pop the element stack back off since it'll never be used now
  2516.         fElemStack.popTop();
  2517.         // If the elem stack is empty, then it was an empty root
  2518.         if (isRoot)
  2519.             gotData = false;
  2520.         else {
  2521.             // Restore the validation flag
  2522.             fValidate = fElemStack.getValidationFlag();
  2523.         }
  2524.     }
  2525.     //
  2526.     //  If we have a document handler, then tell it about this start tag. We
  2527.     //  don't have any URI id to send along, so send fEmptyNamespaceId. We also do not send
  2528.     //  any prefix since its just one big name if we are not doing namespaces.
  2529.     //
  2530.     if (fDocHandler)
  2531.     {
  2532.         fDocHandler->startElement
  2533.         (
  2534.             *elemDecl
  2535.             , fEmptyNamespaceId
  2536.             , 0
  2537.             , *fAttrList
  2538.             , attCount
  2539.             , isEmpty
  2540.             , isRoot
  2541.         );
  2542.     }
  2543.     return true;
  2544. }
  2545. //
  2546. //
  2547. //  This method is called to scan a start tag when we are processing
  2548. //  namespaces. There are two different versions of this method, one for
  2549. //  namespace aware processing an done for non-namespace aware processing.
  2550. //
  2551. //  This method is called after we've scanned the < of a start tag. So we
  2552. //  have to get the element name, then scan the attributes, after which
  2553. //  we are either going to see >, />, or attributes followed by one of those
  2554. //  sequences.
  2555. //
  2556. bool XMLScanner::scanStartTagNS(bool& gotData)
  2557. {
  2558.     //
  2559.     //  Assume we will still have data until proven otherwise. It will only
  2560.     //  ever be false if this is the root and its empty.
  2561.     //
  2562.     gotData = true;
  2563.     //
  2564.     //  The current position is after the open bracket, so we need to read in
  2565.     //  in the element name.
  2566.     //
  2567.     if (!fReaderMgr.getName(fQNameBuf))
  2568.     {
  2569.         emitError(XMLErrs::ExpectedElementName);
  2570.         fReaderMgr.skipToChar(chOpenAngle);
  2571.         return false;
  2572.     }
  2573.     //
  2574.     //  Do a little sanity check here. One common problem is that
  2575.     //  badly encoded files cause getName() to exit above on a
  2576.     //  non-name char (an invalid XML char), then the scan start
  2577.     //  tag below fails. This is misleading, so check here that
  2578.     //  we are looking at a valid XML char.
  2579.     //
  2580.     if (!XMLReader::isXMLChar(fReaderMgr.peekNextChar()))
  2581.     {
  2582.         XMLCh tmpBuf[9];
  2583.         XMLString::binToText
  2584.         (
  2585.             fReaderMgr.getNextChar()
  2586.             , tmpBuf
  2587.             , 8
  2588.             , 16
  2589.         );
  2590.         emitError(XMLErrs::InvalidCharacter, tmpBuf);
  2591.     }
  2592.     // See if its the root element
  2593.     const bool isRoot = fElemStack.isEmpty();
  2594.     // Skip any whitespace after the name
  2595.     fReaderMgr.skipPastSpaces();
  2596.     //
  2597.     //  First we have to do the rawest attribute scan. We don't do any
  2598.     //  normalization of them at all, since we don't know yet what type they
  2599.     //  might be (since we need the element decl in order to do that.)
  2600.     //
  2601.     bool isEmpty;
  2602.     unsigned int attCount = rawAttrScan
  2603.     (
  2604.         fQNameBuf.getRawBuffer()
  2605.         , *fRawAttrList
  2606.         , isEmpty
  2607.     );
  2608.     const bool gotAttrs = (attCount != 0);
  2609.     // save the contentleafname and currentscope before addlevel, for later use
  2610.     ContentLeafNameTypeVector* cv = 0;
  2611.     XMLContentModel* cm = 0;
  2612.     int currentScope = Grammar::TOP_LEVEL_SCOPE;
  2613.     if (!isRoot && fGrammarType == Grammar::SchemaGrammarType) {
  2614.         SchemaElementDecl* tempElement = (SchemaElementDecl*) fElemStack.topElement()->fThisElement;
  2615.         SchemaElementDecl::ModelTypes modelType = tempElement->getModelType();
  2616.         if ((modelType == SchemaElementDecl::Mixed_Simple)
  2617.           ||  (modelType == SchemaElementDecl::Mixed_Complex)
  2618.           ||  (modelType == SchemaElementDecl::Children))
  2619.         {
  2620.             cm = tempElement->getContentModel();
  2621.             cv = cm->getContentLeafNameTypeVector();
  2622.             currentScope = fElemStack.getCurrentScope();
  2623.         }
  2624.     }
  2625.     //
  2626.     //  Now, since we might have to update the namespace map for this element,
  2627.     //  but we don't have the element decl yet, we just tell the element stack
  2628.     //  to expand up to get ready.
  2629.     //
  2630.     unsigned int elemDepth = fElemStack.addLevel();
  2631.     fElemStack.setValidationFlag(fValidate);
  2632.     //  Check if there is any external schema location specified, and if we are at root,
  2633.     //  go through them first before scanning those specified in the instance document
  2634.     if (isRoot
  2635.         && fDoSchema
  2636.         && !fReuseGrammar
  2637.         && (fExternalSchemaLocation || fExternalNoNamespaceSchemaLocation)) {
  2638.         if (fExternalSchemaLocation)
  2639.             parseSchemaLocation(fExternalSchemaLocation);
  2640.         if (fExternalNoNamespaceSchemaLocation)
  2641.             resolveSchemaGrammar(fExternalNoNamespaceSchemaLocation, XMLUni::fgZeroLenString);
  2642.     }
  2643.     //
  2644.     //  Make an initial pass through the list and find any xmlns attributes or
  2645.     //  schema attributes.
  2646.     //
  2647.     if (attCount)
  2648.       scanRawAttrListforNameSpaces(fRawAttrList, attCount);
  2649.     //
  2650.     //  Also find any default or fixed xmlns attributes in DTD defined for
  2651.     //  this element.
  2652.     //
  2653.     if (fGrammarType == Grammar::DTDGrammarType) {
  2654.         XMLElementDecl* elemDecl = fGrammar->getElemDecl
  2655.         (
  2656.             fEmptyNamespaceId
  2657.             , 0
  2658.             , fQNameBuf.getRawBuffer()
  2659.             , Grammar::TOP_LEVEL_SCOPE
  2660.         );
  2661.         if (elemDecl) {
  2662.             if (elemDecl->hasAttDefs()) {
  2663.                 XMLAttDefList& attDefList = elemDecl->getAttDefList();
  2664.                 while (attDefList.hasMoreElements())
  2665.                 {
  2666.                     // Get the current att def, for convenience and its def type
  2667.                     const XMLAttDef& curDef = attDefList.nextElement();
  2668.                     const XMLAttDef::DefAttTypes defType = curDef.getDefaultType();
  2669.                     // update the NSMap if there are any default/fixed xmlns attributes
  2670.                     if ((defType == XMLAttDef::Default)
  2671.                     ||  (defType == XMLAttDef::Fixed))
  2672.                     {
  2673.                         const XMLCh* rawPtr = curDef.getFullName();
  2674.                         if (!XMLString::compareNString(rawPtr, XMLUni::fgXMLNSColonString, 6)
  2675.                         ||  !XMLString::compareString(rawPtr, XMLUni::fgXMLNSString))
  2676.                             updateNSMap(rawPtr, curDef.getValue());
  2677.                     }
  2678.                 }
  2679.             }
  2680.         }
  2681.     }
  2682.     //
  2683.     //  Resolve the qualified name to a URI and name so that we can look up
  2684.     //  the element decl for this element. We have now update the prefix to
  2685.     //  namespace map so we should get the correct element now.
  2686.     //
  2687.     unsigned int uriId = resolveQName
  2688.         (
  2689.             fQNameBuf.getRawBuffer()
  2690.             , fNameBuf
  2691.             , fPrefixBuf
  2692.             , ElemStack::Mode_Element
  2693.         );
  2694.     //if schema, check if we should lax or skip the validation of this element
  2695.     bool laxThisOne = false;
  2696.     if (cv) {
  2697.         QName element(fPrefixBuf.getRawBuffer(), fNameBuf.getRawBuffer(), uriId);
  2698.         // elementDepth will be > 0, as cv is only constructed if element is not
  2699.         // root.
  2700.         laxThisOne = laxElementValidation(&element, cv, cm, elemDepth - 1);
  2701.     }
  2702.     //
  2703.     //  Look up the element now in the grammar. This will get us back a
  2704.     //  generic element decl object. We tell him to fault one in if he does
  2705.     //  not find it.
  2706.     //
  2707.     bool wasAdded = false;
  2708.     XMLElementDecl* elemDecl;
  2709.     const XMLCh* nameRawBuf = fNameBuf.getRawBuffer();
  2710.     const XMLCh* qnameRawBuf = fQNameBuf.getRawBuffer();
  2711.     if (uriId != fEmptyNamespaceId) {
  2712.         // Check in current grammar before switching if necessary
  2713.         elemDecl = fGrammar->getElemDecl
  2714.         (
  2715.           uriId
  2716.           , nameRawBuf
  2717.           , qnameRawBuf
  2718.           , currentScope
  2719.         );
  2720.         if (!elemDecl && (fURIStringPool->getId(fGrammar->getTargetNamespace()) != uriId)) {
  2721.             // not found, switch to the specified grammar
  2722.             const XMLCh* uriStr = getURIText(uriId);
  2723.             if (!switchGrammar(uriStr) && fValidate && !laxThisOne)
  2724.             {
  2725.                 fValidator->emitError
  2726.                 (
  2727.                     XMLValid::GrammarNotFound
  2728.                     ,uriStr
  2729.                 );
  2730.             }
  2731.             elemDecl = fGrammar->getElemDecl
  2732.             (
  2733.               uriId
  2734.               , nameRawBuf
  2735.               , qnameRawBuf
  2736.               , currentScope
  2737.             );
  2738.         }
  2739.         if (!elemDecl && currentScope != Grammar::TOP_LEVEL_SCOPE) {
  2740.             // if not found, then it may be a reference, try TOP_LEVEL_SCOPE
  2741.             elemDecl = fGrammar->getElemDecl
  2742.                        (
  2743.                            uriId
  2744.                            , nameRawBuf
  2745.                            , qnameRawBuf
  2746.                            , Grammar::TOP_LEVEL_SCOPE
  2747.                        );
  2748.             if(!elemDecl) {
  2749.                 // still not found in specified uri
  2750.                 // try emptyNamesapce see if element should be un-qualified.
  2751.                 elemDecl = fGrammar->getElemDecl
  2752.                            (
  2753.                                fEmptyNamespaceId
  2754.                                , nameRawBuf
  2755.                                , qnameRawBuf
  2756.                                , currentScope
  2757.                            );
  2758.                 if (elemDecl && elemDecl->getCreateReason() != XMLElementDecl::JustFaultIn && fValidate) {
  2759.                     fValidator->emitError
  2760.                     (
  2761.                         XMLValid::ElementNotUnQualified
  2762.                         , elemDecl->getFullName()
  2763.                     );
  2764.                 }
  2765.             }
  2766.         }
  2767.         if (!elemDecl) {
  2768.             // still not found, fault this in and issue error later
  2769.             elemDecl = fGrammar->putElemDecl(uriId
  2770.                         , nameRawBuf
  2771.                         , fPrefixBuf.getRawBuffer()
  2772.                         , qnameRawBuf
  2773.                         , currentScope);
  2774.             wasAdded = true;
  2775.         }
  2776.     }
  2777.     else
  2778.     {
  2779.         //the element has no prefix,
  2780.         //thus it is either a non-qualified element defined in current targetNS
  2781.         //or an element that is defined in the globalNS
  2782.         //try unqualifed first
  2783.         elemDecl = fGrammar->getElemDecl
  2784.                    (
  2785.                       uriId
  2786.                     , nameRawBuf
  2787.                     , qnameRawBuf
  2788.                     , currentScope
  2789.                     );
  2790.         unsigned orgGrammarUri = fURIStringPool->getId(fGrammar->getTargetNamespace());
  2791.         if (!elemDecl && orgGrammarUri != fEmptyNamespaceId) {
  2792.             //not found, switch grammar and try globalNS
  2793.             if (!switchGrammar(XMLUni::fgZeroLenString) && fValidate && !laxThisOne)
  2794.             {
  2795.                 fValidator->emitError
  2796.                 (
  2797.                     XMLValid::GrammarNotFound
  2798.                   , XMLUni::fgZeroLenString
  2799.                 );
  2800.             }
  2801.             elemDecl = fGrammar->getElemDecl
  2802.             (
  2803.               uriId
  2804.               , nameRawBuf
  2805.               , qnameRawBuf
  2806.               , currentScope
  2807.             );
  2808.         }
  2809.         if (!elemDecl && currentScope != Grammar::TOP_LEVEL_SCOPE) {
  2810.             // if not found, then it may be a reference, try TOP_LEVEL_SCOPE
  2811.             elemDecl = fGrammar->getElemDecl
  2812.                        (
  2813.                            uriId
  2814.                            , nameRawBuf
  2815.                            , qnameRawBuf
  2816.                            , Grammar::TOP_LEVEL_SCOPE
  2817.                        );
  2818.             if (!elemDecl && orgGrammarUri != fEmptyNamespaceId) {
  2819.                 // still Not found in specified uri
  2820.                 // go to original Grammar again to see if element needs to be fully qualified.
  2821.                 const XMLCh* uriStr = getURIText(orgGrammarUri);
  2822.                 if (!switchGrammar(uriStr) && fValidate && !laxThisOne)
  2823.                 {
  2824.                     fValidator->emitError
  2825.                     (
  2826.                         XMLValid::GrammarNotFound
  2827.                         ,uriStr
  2828.                     );
  2829.                 }
  2830.                 elemDecl = fGrammar->getElemDecl
  2831.                            (
  2832.                                orgGrammarUri
  2833.                                , nameRawBuf
  2834.                                , qnameRawBuf
  2835.                                , currentScope
  2836.                            );
  2837.                 if (elemDecl && elemDecl->getCreateReason() != XMLElementDecl::JustFaultIn && fValidate) {
  2838.                     fValidator->emitError
  2839.                     (
  2840.                         XMLValid::ElementNotQualified
  2841.                         , elemDecl->getFullName()
  2842.                     );
  2843.                 }
  2844.             }
  2845.         }
  2846.         if (!elemDecl) {
  2847.             // still not found, fault this in and issue error later
  2848.             elemDecl = fGrammar->putElemDecl(uriId
  2849.                         , nameRawBuf
  2850.                         , fPrefixBuf.getRawBuffer()
  2851.                         , qnameRawBuf
  2852.                         , currentScope);
  2853.             wasAdded = true;
  2854.         }
  2855.     }
  2856.     //
  2857.     //  We do something different here according to whether we found the
  2858.     //  element or not.
  2859.     //
  2860.     if (wasAdded)
  2861.     {
  2862.         if (laxThisOne) {
  2863.             fValidate = false;
  2864.             fElemStack.setValidationFlag(fValidate);
  2865.         }
  2866.         // If validating then emit an error
  2867.         if (fValidate)
  2868.         {
  2869.             // This is to tell the reuse Validator that this element was
  2870.             // faulted-in, was not an element in the grammar pool originally
  2871.             elemDecl->setCreateReason(XMLElementDecl::JustFaultIn);
  2872.             fValidator->emitError
  2873.             (
  2874.                 XMLValid::ElementNotDefined
  2875.                 , elemDecl->getFullName()
  2876.             );
  2877.         }
  2878.         //
  2879.         //  If we are not validating, then mark it as declared since it makes
  2880.         //  things simpler and we aren't going to do do the validation checks
  2881.         //  that need to know if it was really declared or not anyway.
  2882.         //
  2883.         if (!fValidate)
  2884.             elemDecl->setCreateReason(XMLElementDecl::Declared);
  2885.     }
  2886.      else
  2887.     {
  2888.         // If its not marked declared and validating, then emit an error
  2889.         if (!elemDecl->isDeclared()) {
  2890.             if (laxThisOne) {
  2891.                 fValidate = false;
  2892.                 fElemStack.setValidationFlag(fValidate);
  2893.             }
  2894.              if (fValidate)
  2895.             {
  2896.                 fValidator->emitError
  2897.                 (
  2898.                     XMLValid::ElementNotDefined
  2899.                     , elemDecl->getFullName()
  2900.                 );
  2901.             }
  2902.         }
  2903.     }
  2904.     //
  2905.     //  Now we can update the element stack to set the current element
  2906.     //  decl. We expanded the stack above, but couldn't store the element
  2907.     //  decl because we didn't know it yet.
  2908.     //
  2909.     fElemStack.setElement(elemDecl, fReaderMgr.getCurrentReaderNum());
  2910.     fElemStack.setCurrentURI(uriId);
  2911.     //  Validate the element
  2912.     if (fValidate)
  2913.         fValidator->validateElement(elemDecl);
  2914.     if (fGrammarType == Grammar::SchemaGrammarType) {
  2915.         ComplexTypeInfo* typeinfo = ((SchemaElementDecl*)elemDecl)->getComplexTypeInfo();
  2916.         if (typeinfo) {
  2917.             currentScope = typeinfo->getScopeDefined();
  2918.             // switch grammar if the typeinfo has a different grammar (happens when there is xsi:type)
  2919.             XMLCh* typeName = typeinfo->getTypeName();
  2920.             const XMLCh poundStr[] = {chPound, chNull};
  2921.             if (!XMLString::startsWith(typeName, poundStr)) {
  2922.                 const int comma = XMLString::indexOf(typeName, chComma);
  2923.                 if (comma != -1) {
  2924.                     XMLBuffer prefixBuf(comma+1);
  2925.                     prefixBuf.append(typeName, comma);
  2926.                     const XMLCh* uriStr = prefixBuf.getRawBuffer();
  2927.                     if (!switchGrammar(uriStr) && fValidate && !laxThisOne)
  2928.                     {
  2929.                         fValidator->emitError
  2930.                         (
  2931.                             XMLValid::GrammarNotFound
  2932.                             , prefixBuf.getRawBuffer()
  2933.                         );
  2934.                     }
  2935.                 }
  2936.             }
  2937.         }
  2938.         fElemStack.setCurrentScope(currentScope);
  2939.         // Set element next state
  2940.         if (elemDepth >= fElemStateSize) {
  2941.             resizeElemState();
  2942.         }
  2943.         fElemState[elemDepth] = 0;
  2944.     }
  2945.     fElemStack.setCurrentGrammar(fGrammar);
  2946.     //
  2947.     //  If this is the first element and we are validating, check the root
  2948.     //  element.
  2949.     //
  2950.     if (isRoot)
  2951.     {
  2952.         if (fValidate)
  2953.         {
  2954.             //  If a DocType exists, then check if it matches the root name there.
  2955.             if (fRootElemName && XMLString::compareString(qnameRawBuf, fRootElemName))
  2956.                 fValidator->emitError(XMLValid::RootElemNotLikeDocType);
  2957.             //  Some validators may also want to check the root, call the
  2958.             //  XMLValidator::checkRootElement
  2959.             if (fValidatorFromUser && !fValidator->checkRootElement(elemDecl->getId()))
  2960.                 fValidator->emitError(XMLValid::RootElemNotLikeDocType);
  2961.         }
  2962.     }
  2963.      else
  2964.     {
  2965.         //
  2966.         //  If the element stack is not empty, then add this element as a
  2967.         //  child of the previous top element. If its empty, this is the root
  2968.         //  elem and is not the child of anything.
  2969.         //
  2970.         fElemStack.addChild(elemDecl->getElementName(), true);
  2971.     }
  2972.     //
  2973.     //  Now lets get the fAttrList filled in. This involves faulting in any
  2974.     //  defaulted and fixed attributes and normalizing the values of any that
  2975.     //  we got explicitly.
  2976.     //
  2977.     //  We update the attCount value with the total number of attributes, but
  2978.     //  it goes in with the number of values we got during the raw scan of
  2979.     //  explictly provided attrs above.
  2980.     //
  2981.     attCount = buildAttList(*fRawAttrList, attCount, elemDecl, *fAttrList);
  2982.     //
  2983.     // activate identity constraints
  2984.     //
  2985.     if (fValidate && fGrammar && fGrammarType == Grammar::SchemaGrammarType) {
  2986.         unsigned int count = ((SchemaElementDecl*) elemDecl)->getIdentityConstraintCount();
  2987.         if (count || fMatcherStack->getMatcherCount()) {
  2988.             fValueStoreCache->startElement();
  2989.             fMatcherStack->pushContext();
  2990.             fValueStoreCache->initValueStoresFor((SchemaElementDecl*) elemDecl);
  2991.             for (unsigned int i = 0; i < count; i++) {
  2992.                 activateSelectorFor(((SchemaElementDecl*) elemDecl)->getIdentityConstraintAt(i));
  2993.             }
  2994.             // call all active identity constraints
  2995.             count = fMatcherStack->getMatcherCount();
  2996.             for (unsigned int j = 0; j < count; j++) {
  2997.                 XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
  2998.                 matcher->startElement(*elemDecl, uriId, fPrefixBuf.getRawBuffer(), *fAttrList, attCount);
  2999.             }
  3000.         }
  3001.     }
  3002.     //
  3003.     //  If empty, validate content right now if we are validating and then
  3004.     //  pop the element stack top. Else, we have to update the current stack
  3005.     //  top's namespace mapping elements.
  3006.     //
  3007.     if (isEmpty)
  3008.     {
  3009.         // Pop the element stack back off since it'll never be used now
  3010.         fElemStack.popTop();
  3011.         // If validating, then insure that its legal to have no content
  3012.         if (fValidate)
  3013.         {
  3014.             const int res = fValidator->checkContent(elemDecl, 0, 0);
  3015.             if (res >= 0)
  3016.             {
  3017.                 fValidator->emitError
  3018.                 (
  3019.                     XMLValid::ElementNotValidForContent
  3020.                     , elemDecl->getFullName()
  3021.                     , elemDecl->getFormattedContentModel()
  3022.                 );
  3023.             }
  3024.             if (fGrammarType == Grammar::SchemaGrammarType) {
  3025.                 // reset xsi:type ComplexTypeInfo
  3026.                 ((SchemaElementDecl*)elemDecl)->setXsiComplexTypeInfo(0);
  3027.                 // call matchers and de-activate context
  3028.                 int oldCount = fMatcherStack->getMatcherCount();
  3029.                 if (oldCount || ((SchemaElementDecl*) elemDecl)->getIdentityConstraintCount()) {
  3030.                     for (int i = oldCount - 1; i >= 0; i--) {
  3031.                         XPathMatcher* matcher = fMatcherStack->getMatcherAt(i);
  3032.                         matcher->endElement(*elemDecl);
  3033.                     }
  3034.                     if (fMatcherStack->size() > 0) {
  3035.                         fMatcherStack->popContext();
  3036.                     }
  3037.                     // handle everything *but* keyref's.
  3038.                     int newCount = fMatcherStack->getMatcherCount();
  3039.                     for (int j = oldCount - 1; j >= newCount; j--) {
  3040.                         XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
  3041.                         IdentityConstraint* ic = matcher->getIdentityConstraint();
  3042.                         if (ic  && (ic->getType() != IdentityConstraint::KEYREF)) {
  3043.                             matcher->endDocumentFragment();
  3044.                             fValueStoreCache->transplant(ic);
  3045.                         }
  3046.                         else if (!ic) {
  3047.                             matcher->endDocumentFragment();
  3048.                         }
  3049.                     }
  3050.                     // now handle keyref's...
  3051.                     for (int k = oldCount - 1; k >= newCount; k--) {
  3052.                         XPathMatcher* matcher = fMatcherStack->getMatcherAt(k);
  3053.                         IdentityConstraint* ic = matcher->getIdentityConstraint();
  3054.                         if (ic && (ic->getType() == IdentityConstraint::KEYREF)) {
  3055.                             ValueStore* values = fValueStoreCache->getValueStoreFor(ic);
  3056.                             if (values) { // nothing to do if nothing matched!
  3057.                                 values->endDcocumentFragment(fValueStoreCache);
  3058.                             }
  3059.                             matcher->endDocumentFragment();
  3060.                         }
  3061.                     }
  3062.                     fValueStoreCache->endElement();
  3063.                 }
  3064.             }
  3065.         }
  3066.         // If the elem stack is empty, then it was an empty root
  3067.         if (isRoot)
  3068.             gotData = false;
  3069.         else
  3070.         {
  3071.             // Restore the grammar
  3072.             fGrammar = fElemStack.getCurrentGrammar();
  3073.             fGrammarType = fGrammar->getGrammarType();
  3074.             if (fGrammarType == Grammar::SchemaGrammarType && !fValidator->handlesSchema()) {
  3075.                 if (fValidatorFromUser)
  3076.                     ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
  3077.                 else {
  3078.                     fValidator = fSchemaValidator;
  3079.                 }
  3080.             }
  3081.             else if (fGrammarType == Grammar::DTDGrammarType && !fValidator->handlesDTD()) {
  3082.                 if (fValidatorFromUser)
  3083.                     ThrowXML(RuntimeException, XMLExcepts::Gen_NoDTDValidator);
  3084.                 else {
  3085.                     fValidator = fDTDValidator;
  3086.                 }
  3087.             }
  3088.             fValidator->setGrammar(fGrammar);
  3089.             // Restore the validation flag
  3090.             fValidate = fElemStack.getValidationFlag();
  3091.         }
  3092.     }
  3093.     // If we have a document handler, then tell it about this start tag
  3094.     if (fDocHandler)
  3095.     {
  3096.         fDocHandler->startElement
  3097.         (
  3098.             *elemDecl
  3099.             , uriId
  3100.             , fPrefixBuf.getRawBuffer()
  3101.             , *fAttrList
  3102.             , attCount
  3103.             , isEmpty
  3104.             , isRoot
  3105.         );
  3106.     }
  3107.     return true;
  3108. }
  3109. //
  3110. //  Scans the <?xml .... ?> line. This stuff is all sequential so we don't
  3111. //  do any state machine loop here. We just bull straight through it. It ends
  3112. //  past the closing bracket. If there is a document handler, then its called
  3113. //  on the XMLDecl callback.
  3114. //
  3115. //  On entry, the <?xml has been scanned, and we pick it up from there.
  3116. //
  3117. //  NOTE: In order to provide good recovery from bad XML here, we try to be
  3118. //  very flexible. No matter what order the stuff is in, we'll keep going
  3119. //  though we'll issue errors.
  3120. //
  3121. //  The parameter tells us which type of decl we should expect, Text or XML.
  3122. //    [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
  3123. //    [77] TextDecl::= '<?xml' VersionInfo? EncodingDecl S? '?>'
  3124. //
  3125. void XMLScanner::scanXMLDecl(const DeclTypes type)
  3126. {
  3127.     // Get us some buffers to use
  3128.     XMLBufBid bbVersion(&fBufMgr);
  3129.     XMLBufBid bbEncoding(&fBufMgr);
  3130.     XMLBufBid bbStand(&fBufMgr);
  3131.     XMLBufBid bbDummy(&fBufMgr);
  3132.     XMLBufBid bbName(&fBufMgr);
  3133.     //
  3134.     //  We use this little enum and array to keep up with what we found
  3135.     //  and what order we found them in. This lets us get them free form
  3136.     //  without too much overhead, but still know that they were in the
  3137.     //  wrong order.
  3138.     //
  3139.     enum Strings
  3140.     {
  3141.         VersionString
  3142.         , EncodingString
  3143.         , StandaloneString
  3144.         , UnknownString
  3145.         , StringCount
  3146.     };
  3147.     int flags[StringCount] = { -1, -1, -1, -1 };
  3148.     //
  3149.     //  Also set up a list of buffers in the right order so that we know
  3150.     //  where to put stuff.
  3151.     //
  3152.     XMLBuffer* buffers[StringCount] ;
  3153.     buffers[0] = &bbVersion.getBuffer();
  3154.     buffers[1] = &bbEncoding.getBuffer();
  3155.     buffers[2] = &bbStand.getBuffer();
  3156.     buffers[3] = &bbDummy.getBuffer();
  3157.     int curCount = 0;
  3158.     Strings curString;
  3159.     XMLBuffer& nameBuf = bbName.getBuffer();
  3160.     while (true)
  3161.     {
  3162.         // Skip any spaces
  3163.         const unsigned int spaceCount = fReaderMgr.skipPastSpaces();
  3164.         // If we are looking at a question mark, then break out
  3165.         if (fReaderMgr.lookingAtChar(chQuestion))
  3166.             break;
  3167.         // If this is not the first string, then we require the spaces
  3168.         if (!spaceCount && curCount)
  3169.             emitError(XMLErrs::ExpectedWhitespace);
  3170.         //
  3171.         //  Get characters up to the next whitespace or equal's sign.
  3172.         //
  3173.         if (!scanUpToWSOr(nameBuf, chEqual))
  3174.             emitError(XMLErrs::ExpectedDeclString);
  3175.         // See if it matches any of our expected strings
  3176.         if (!XMLString::compareString(nameBuf.getRawBuffer(), XMLUni::fgVersionString))
  3177.             curString = VersionString;
  3178.         else if (!XMLString::compareString(nameBuf.getRawBuffer(), XMLUni::fgEncodingString))
  3179.             curString = EncodingString;
  3180.         else if (!XMLString::compareString(nameBuf.getRawBuffer(), XMLUni::fgStandaloneString))
  3181.             curString = StandaloneString;
  3182.         else
  3183.             curString = UnknownString;
  3184.         //
  3185.         //  If its an unknown string, then give that error. Else check to
  3186.         //  see if this one has been done already and give that error.
  3187.         //
  3188.         if (curString == UnknownString)
  3189.             emitError(XMLErrs::ExpectedDeclString, nameBuf.getRawBuffer());
  3190.         else if (flags[curString] != -1)
  3191.             emitError(XMLErrs::DeclStringRep, nameBuf.getRawBuffer());
  3192.         else if (flags[curString] == -1)
  3193.             flags[curString] = ++curCount;
  3194.         //
  3195.         //  Scan for an equal's sign. If we don't find it, issue an error
  3196.         //  but keep trying to go on.
  3197.         //
  3198.         if (!scanEq())
  3199.             emitError(XMLErrs::ExpectedEqSign);
  3200.         //
  3201.         //  Get a quote string into the buffer for the string that we are
  3202.         //  currently working on.
  3203.         //
  3204.         if (!getQuotedString(*buffers[curString]))
  3205.         {
  3206.             emitError(XMLErrs::ExpectedQuotedString);
  3207.             fReaderMgr.skipPastChar(chCloseAngle);
  3208.             return;
  3209.         }
  3210.         // And validate the value according which one it was
  3211.         const XMLCh* rawValue = buffers[curString]->getRawBuffer();
  3212.         if (curString == VersionString)
  3213.         {
  3214.             if (XMLString::compareString(rawValue, XMLUni::fgSupportedVersion))
  3215.                 emitError(XMLErrs::UnsupportedXMLVersion, rawValue);
  3216.         }
  3217.          else if (curString == EncodingString)
  3218.         {
  3219.             if (!XMLString::isValidEncName(rawValue))
  3220.                 emitError(XMLErrs::BadXMLEncoding, rawValue);
  3221.         }
  3222.          else if (curString == StandaloneString)
  3223.         {
  3224.             if (!XMLString::compareString(rawValue, XMLUni::fgYesString))
  3225.                 fStandalone = true;
  3226.             else if (!XMLString::compareString(rawValue, XMLUni::fgNoString))
  3227.                 fStandalone = false;
  3228.             else
  3229.             {
  3230.                 emitError(XMLErrs::BadStandalone);
  3231.                 if (!XMLString::compareIString(rawValue, XMLUni::fgYesString))
  3232.                     fStandalone = true;
  3233.                 else if (!XMLString::compareIString(rawValue, XMLUni::fgNoString))
  3234.                     fStandalone = false;
  3235.             }
  3236.         }
  3237.     }
  3238.     //
  3239.     //  Make sure that the strings present are in order. We don't care about
  3240.     //  which ones are present at this point, just that any there are in the
  3241.     //  right order.
  3242.     //
  3243.     int curTop = 0;
  3244.     for (int index = VersionString; index < StandaloneString; index++)
  3245.     {
  3246.         if (flags[index] != -1)
  3247.         {
  3248.             if (flags[index] !=  curTop + 1)
  3249.             {
  3250.                 emitError(XMLErrs::DeclStringsInWrongOrder);
  3251.                 break;
  3252.             }
  3253.             curTop = flags[index];
  3254.         }
  3255.     }
  3256.     //
  3257.     //  If its an XML decl, the version must be present.
  3258.     //  If its a Text decl, then encoding must be present AND standalone must not be present.
  3259.     //
  3260.     if ((type == Decl_XML) && (flags[VersionString] == -1))
  3261.         emitError(XMLErrs::XMLVersionRequired);
  3262.     else if (type == Decl_Text) {
  3263.         if (flags[StandaloneString] != -1)
  3264.             emitError(XMLErrs::StandaloneNotLegal);
  3265.         if (flags[EncodingString] == -1)
  3266.             emitError(XMLErrs::EncodingRequired);
  3267.     }
  3268.     if (!fReaderMgr.skippedChar(chQuestion))
  3269.     {
  3270.         emitError(XMLErrs::UnterminatedXMLDecl);
  3271.         fReaderMgr.skipPastChar(chCloseAngle);
  3272.     }
  3273.      else if (!fReaderMgr.skippedChar(chCloseAngle))
  3274.     {
  3275.         emitError(XMLErrs::UnterminatedXMLDecl);
  3276.         fReaderMgr.skipPastChar(chCloseAngle);
  3277.     }
  3278.     //
  3279.     //  If we have a document handler then call the XML Decl callback.
  3280.     //
  3281.     //  !NOTE! Do this before we possibly update the reader with the
  3282.     //  actual encoding string. Otherwise, we will pass the wrong thing
  3283.     //  for the last parameter!
  3284.     //
  3285.     if (fDocHandler)
  3286.     {
  3287.         fDocHandler->XMLDecl
  3288.         (
  3289.             bbVersion.getRawBuffer()
  3290.             , bbEncoding.getRawBuffer()
  3291.             , bbStand.getRawBuffer()
  3292.             , fReaderMgr.getCurrentEncodingStr()
  3293.         );
  3294.     }
  3295.     //
  3296.     //  Ok, we've now seen the real encoding string, if there was one, so
  3297.     //  lets call back on the current reader and tell it what the real
  3298.     //  encoding string was. If it fails, that's because it represents some
  3299.     //  sort of contradiction with the autosensed format, and it keeps the
  3300.     //  original encoding.
  3301.     //
  3302.     //  NOTE: This can fail for a number of reasons, such as a bogus encoding
  3303.     //  name or because its in flagrant contradiction of the auto-sensed
  3304.     //  format.
  3305.     //
  3306.     if (flags[EncodingString] != -1)
  3307.     {
  3308.         if (!fReaderMgr.getCurrentReader()->setEncoding(bbEncoding.getRawBuffer()))
  3309.             emitError(XMLErrs::ContradictoryEncoding, bbEncoding.getRawBuffer());
  3310.     }
  3311. }
  3312. const XMLCh* XMLScanner::getURIText(const   unsigned int    uriId) const
  3313. {
  3314.     if (fURIStringPool->exists(uriId)) {
  3315.         // Look up the URI in the string pool and return its id
  3316.         const XMLCh* value = fURIStringPool->getValueForId(uriId);
  3317.         if (!value)
  3318.             return XMLUni::fgZeroLenString;
  3319.         return value;
  3320.     }
  3321.     else
  3322.         return XMLUni::fgZeroLenString;
  3323. }
  3324. bool XMLScanner::getURIText(  const   unsigned int    uriId
  3325.                       ,       XMLBuffer&      uriBufToFill) const
  3326. {
  3327.     if (fURIStringPool->exists(uriId)) {
  3328.         // Look up the URI in the string pool and return its id
  3329.         const XMLCh* value = fURIStringPool->getValueForId(uriId);
  3330.         if (!value)
  3331.             return false;
  3332.         uriBufToFill.set(value);
  3333.         return true;
  3334.     }
  3335.     else
  3336.         return false;
  3337. }
  3338. unsigned int
  3339. XMLScanner::resolveQName(   const   XMLCh* const        qName
  3340.                             ,       XMLBuffer&          nameBuf
  3341.                             ,       XMLBuffer&          prefixBuf
  3342.                             , const ElemStack::MapModes mode)
  3343. {
  3344.     // Reset both target buffers in case we don't get anything for either
  3345.     nameBuf.reset();
  3346.     prefixBuf.reset();
  3347.     //
  3348.     //  Lets split out the qName into a URI and name buffer first. The URI
  3349.     //  can be empty.
  3350.     //
  3351.     const int colonPos = XMLString::indexOf(qName, chColon);
  3352.     unsigned int uriId = 0;
  3353.     if (colonPos == -1)
  3354.     {
  3355.         //
  3356.         //  Its all name with no prefix, so put the whole thing into the name
  3357.         //  buffer. Then map the empty string to a URI, since the empty string
  3358.         //  represents the default namespace. This will either return some
  3359.         //  explicit URI which the default namespace is mapped to, or the
  3360.         //  the default global namespace.
  3361.         //
  3362.         nameBuf.append(qName);
  3363.         bool unknown;
  3364.         uriId = fElemStack.mapPrefixToURI(prefixBuf.getRawBuffer(), mode, unknown);
  3365.         #if defined(XERCES_DEBUG)
  3366.         if (unknown)
  3367.         {
  3368.             // <TBD> This one should never be unknown
  3369.         }
  3370.         #endif
  3371.     }
  3372.      else
  3373.     {
  3374.         //
  3375.         //  Copy the chars up to but not including the colon into the prefix
  3376.         //  buffer.
  3377.         //
  3378.         prefixBuf.append(qName, colonPos);
  3379.         // And copy over the rest of the chars to the name buffer
  3380.         nameBuf.append(&qName[colonPos+1]);
  3381.         //
  3382.         //  Watch for the special namespace prefixes. We always map these to
  3383.         //  special URIs. 'xml' gets mapped to the official URI that its defined
  3384.         //  to map to by the NS spec. xmlns gets mapped to a special place holder
  3385.         //  URI that we define (so that it maps to something checkable.)
  3386.         //
  3387.         if (!XMLString::compareString(prefixBuf.getRawBuffer(), XMLUni::fgXMLNSString))
  3388.             uriId = fXMLNSNamespaceId;
  3389.         else if (!XMLString::compareString(prefixBuf.getRawBuffer(), XMLUni::fgXMLString))
  3390.             uriId = fXMLNamespaceId;
  3391.         else
  3392.         {
  3393.             bool unknown;
  3394.             uriId = fElemStack.mapPrefixToURI(prefixBuf.getRawBuffer(), mode, unknown);
  3395.             if (unknown)
  3396.                 emitError(XMLErrs::UnknownPrefix, prefixBuf.getRawBuffer());
  3397.         }
  3398.     }
  3399.     return uriId;
  3400. }
  3401. bool XMLScanner::checkXMLDecl(bool startWithAngle) {
  3402.     //
  3403.     // [23] XMLDecl     ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
  3404.     // [24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"')
  3405.     //
  3406.     // [3]  S           ::= (#x20 | #x9 | #xD | #xA)+
  3407.     //
  3408.     if (startWithAngle) {
  3409.         if (fReaderMgr.peekString(XMLUni::fgXMLDeclString)) {
  3410.             if (fReaderMgr.skippedString(XMLUni::fgXMLDeclStringSpace)
  3411.                || fReaderMgr.skippedString(XMLUni::fgXMLDeclStringHTab)
  3412.                || fReaderMgr.skippedString(XMLUni::fgXMLDeclStringLF)
  3413.                || fReaderMgr.skippedString(XMLUni::fgXMLDeclStringCR))
  3414.             {
  3415.                 return true;
  3416.             }
  3417.             else if (fReaderMgr.skippedString(XMLUni::fgXMLDeclStringSpaceU)
  3418.                || fReaderMgr.skippedString(XMLUni::fgXMLDeclStringHTabU)
  3419.                || fReaderMgr.skippedString(XMLUni::fgXMLDeclStringLFU)
  3420.                || fReaderMgr.skippedString(XMLUni::fgXMLDeclStringCRU))
  3421.             {
  3422.                 //
  3423.                 //  Just in case, check for upper case. If found, issue
  3424.                 //  an error, but keep going.
  3425.                 //
  3426.                 emitError(XMLErrs::XMLDeclMustBeLowerCase);
  3427.                 return true;
  3428.             }
  3429.         }
  3430.     }
  3431.     else {
  3432.         if (fReaderMgr.peekString(XMLUni::fgXMLString)) {
  3433.             if (fReaderMgr.skippedString(XMLUni::fgXMLStringSpace)
  3434.                || fReaderMgr.skippedString(XMLUni::fgXMLStringHTab)
  3435.                || fReaderMgr.skippedString(XMLUni::fgXMLStringLF)
  3436.                || fReaderMgr.skippedString(XMLUni::fgXMLStringCR))
  3437.             {
  3438.                 return true;
  3439.             }
  3440.             else if (fReaderMgr.skippedString(XMLUni::fgXMLStringSpaceU)
  3441.                || fReaderMgr.skippedString(XMLUni::fgXMLStringHTabU)
  3442.                || fReaderMgr.skippedString(XMLUni::fgXMLStringLFU)
  3443.                || fReaderMgr.skippedString(XMLUni::fgXMLStringCRU))
  3444.             {
  3445.                 //
  3446.                 //  Just in case, check for upper case. If found, issue
  3447.                 //  an error, but keep going.
  3448.                 //
  3449.                 emitError(XMLErrs::XMLDeclMustBeLowerCase);
  3450.                 return true;
  3451.             }
  3452.         }
  3453.     }
  3454.     return false;
  3455. }
  3456. // ---------------------------------------------------------------------------
  3457. //  XMLScanner: Helper methos
  3458. // ---------------------------------------------------------------------------
  3459. void XMLScanner::resizeElemState() {
  3460.     unsigned int newSize = fElemStateSize * 2;
  3461.     unsigned int* newElemState = new unsigned int[newSize];
  3462.     // Copy the existing values
  3463.     unsigned int index = 0;
  3464.     for (; index < fElemStateSize; index++)
  3465.         newElemState[index] = fElemState[index];
  3466.     for (; index < newSize; index++)
  3467.         newElemState[index] = 0;
  3468.     // Delete the old array and udpate our members
  3469.     delete [] fElemState;
  3470.     fElemState = newElemState;
  3471.     fElemStateSize = newSize;
  3472. }
  3473. // ---------------------------------------------------------------------------
  3474. //  XMLScanner: IC activation methos
  3475. // ---------------------------------------------------------------------------
  3476. void XMLScanner::activateSelectorFor(IdentityConstraint* const ic) {
  3477.     IC_Selector* selector = ic->getSelector();
  3478.     if (!selector)
  3479.         return;
  3480.     XPathMatcher* matcher = selector->createMatcher(fFieldActivator);
  3481.     fMatcherStack->addMatcher(matcher);
  3482.     matcher->startDocumentFragment();
  3483. }