IGXMLScanner.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:106k
源码类别:

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2002 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: IGXMLScanner.cpp,v 1.13 2003/05/18 14:02:04 knoaman Exp $
  58.  */
  59. // ---------------------------------------------------------------------------
  60. //  Includes
  61. // ---------------------------------------------------------------------------
  62. #include <xercesc/internal/IGXMLScanner.hpp>
  63. #include <xercesc/util/RuntimeException.hpp>
  64. #include <xercesc/util/UnexpectedEOFException.hpp>
  65. #include <xercesc/sax/InputSource.hpp>
  66. #include <xercesc/framework/XMLDocumentHandler.hpp>
  67. #include <xercesc/framework/XMLEntityHandler.hpp>
  68. #include <xercesc/framework/XMLPScanToken.hpp>
  69. #include <xercesc/internal/EndOfEntityException.hpp>
  70. #include <xercesc/framework/MemoryManager.hpp>
  71. #include <xercesc/validators/common/GrammarResolver.hpp>
  72. #include <xercesc/validators/DTD/DocTypeHandler.hpp>
  73. #include <xercesc/validators/DTD/DTDScanner.hpp>
  74. #include <xercesc/validators/DTD/DTDValidator.hpp>
  75. #include <xercesc/validators/schema/SchemaValidator.hpp>
  76. #include <xercesc/validators/schema/identity/FieldActivator.hpp>
  77. #include <xercesc/validators/schema/identity/XPathMatcherStack.hpp>
  78. #include <xercesc/validators/schema/identity/ValueStoreCache.hpp>
  79. #include <xercesc/validators/schema/identity/IC_Selector.hpp>
  80. #include <xercesc/validators/schema/identity/ValueStore.hpp>
  81. XERCES_CPP_NAMESPACE_BEGIN
  82. // ---------------------------------------------------------------------------
  83. //  IGXMLScanner: Constructors and Destructor
  84. // ---------------------------------------------------------------------------
  85. IGXMLScanner::IGXMLScanner( XMLValidator* const  valToAdopt
  86.                           , MemoryManager* const manager) :
  87.     XMLScanner(valToAdopt, manager)
  88.     , fSeeXsi(false)
  89.     , fElemStateSize(16)
  90.     , fElemState(0)
  91.     , fElemStack(manager)
  92.     , fContent(1023, manager)
  93.     , fRawAttrList(0)
  94.     , fDTDValidator(0)
  95.     , fSchemaValidator(0)
  96.     , fDTDGrammar(0)
  97.     , fMatcherStack(0)
  98.     , fValueStoreCache(0)
  99.     , fFieldActivator(0)
  100. {
  101.     try
  102.     {
  103.          commonInit();
  104.          // use fDTDValidator as the default validator
  105.          if (!valToAdopt)
  106.              fValidator = fDTDValidator;
  107.     }
  108.     catch(...)
  109.     {
  110.         cleanUp();
  111.         throw;
  112.     }
  113. }
  114. IGXMLScanner::IGXMLScanner( XMLDocumentHandler* const docHandler
  115.                           , DocTypeHandler* const     docTypeHandler
  116.                           , XMLEntityHandler* const   entityHandler
  117.                           , XMLErrorReporter* const   errHandler
  118.                           , XMLValidator* const       valToAdopt
  119.                           , MemoryManager* const      manager) :
  120.     XMLScanner(docHandler, docTypeHandler, entityHandler, errHandler, valToAdopt, manager)
  121.     , fSeeXsi(false)
  122.     , fElemStateSize(16)
  123.     , fElemState(0)
  124.     , fElemStack(manager)
  125.     , fContent(1023, manager)
  126.     , fRawAttrList(0)
  127.     , fDTDValidator(0)
  128.     , fSchemaValidator(0)
  129.     , fDTDGrammar(0)
  130.     , fMatcherStack(0)
  131.     , fValueStoreCache(0)
  132.     , fFieldActivator(0)
  133. {
  134.     try
  135.     {
  136.         commonInit();
  137.         //use fDTDValidator as the default validator
  138.         if (!valToAdopt)
  139.             fValidator = fDTDValidator;
  140.     }
  141.     catch(...)
  142.     {
  143.         cleanUp();
  144.         throw;
  145.     }
  146. }
  147. IGXMLScanner::~IGXMLScanner()
  148. {
  149.     cleanUp();
  150. }
  151. // ---------------------------------------------------------------------------
  152. //  XMLScanner: Getter methods
  153. // ---------------------------------------------------------------------------
  154. NameIdPool<DTDEntityDecl>* IGXMLScanner::getEntityDeclPool()
  155. {
  156.     return fDTDGrammar->getEntityDeclPool();
  157. }
  158. const NameIdPool<DTDEntityDecl>* IGXMLScanner::getEntityDeclPool() const
  159. {
  160.     return fDTDGrammar->getEntityDeclPool();
  161. }
  162. // ---------------------------------------------------------------------------
  163. //  IGXMLScanner: Main entry point to scan a document
  164. // ---------------------------------------------------------------------------
  165. void IGXMLScanner::scanDocument(const InputSource& src)
  166. {
  167.     //  Bump up the sequence id for this parser instance. This will invalidate
  168.     //  any previous progressive scan tokens.
  169.     fSequenceId++;
  170.     try
  171.     {
  172.         //  Reset the scanner and its plugged in stuff for a new run. This
  173.         //  resets all the data structures, creates the initial reader and
  174.         //  pushes it on the stack, and sets up the base document path.
  175.         scanReset(src);
  176.         // If we have a document handler, then call the start document
  177.         if (fDocHandler)
  178.             fDocHandler->startDocument();
  179.         //  Scan the prolog part, which is everything before the root element
  180.         //  including the DTD subsets.
  181.         scanProlog();
  182.         //  If we got to the end of input, then its not a valid XML file.
  183.         //  Else, go on to scan the content.
  184.         if (fReaderMgr.atEOF())
  185.         {
  186.             emitError(XMLErrs::EmptyMainEntity);
  187.         }
  188.         else
  189.         {
  190.             // Scan content, and tell it its not an external entity
  191.             if (scanContent(false))
  192.             {
  193.                 // Do post-parse validation if required
  194.                 if (fValidate)
  195.                 {
  196.                     //  We handle ID reference semantics at this level since
  197.                     //  its required by XML 1.0.
  198.                     checkIDRefs();
  199.                     // Then allow the validator to do any extra stuff it wants
  200. //                    fValidator->postParseValidation();
  201.                 }
  202.                 // That went ok, so scan for any miscellaneous stuff
  203.                 if (!fReaderMgr.atEOF())
  204.                     scanMiscellaneous();
  205.             }
  206.         }
  207.         // If we have a document handler, then call the end document
  208.         if (fDocHandler)
  209.             fDocHandler->endDocument();
  210.         // Reset the reader manager to close all files, sockets, etc...
  211.         fReaderMgr.reset();
  212.     }
  213.     //  NOTE:
  214.     //
  215.     //  In all of the error processing below, the emitError() call MUST come
  216.     //  before the flush of the reader mgr, or it will fail because it tries
  217.     //  to find out the position in the XML source of the error.
  218.     catch(const XMLErrs::Codes)
  219.     {
  220.         // This is a 'first fatal error' type exit, so reset and fall through
  221.         fReaderMgr.reset();
  222.     }
  223.     catch(const XMLValid::Codes)
  224.     {
  225.         // This is a 'first fatal error' type exit, so reset and fall through
  226.         fReaderMgr.reset();
  227.     }
  228.     catch(const XMLException& excToCatch)
  229.     {
  230.         //  Emit the error and catch any user exception thrown from here. Make
  231.         //  sure in all cases we flush the reader manager.
  232.         fInException = true;
  233.         try
  234.         {
  235.             if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning)
  236.                 emitError
  237.                 (
  238.                     XMLErrs::XMLException_Warning
  239.                     , excToCatch.getType()
  240.                     , excToCatch.getMessage()
  241.                 );
  242.             else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal)
  243.                 emitError
  244.                 (
  245.                     XMLErrs::XMLException_Fatal
  246.                     , excToCatch.getType()
  247.                     , excToCatch.getMessage()
  248.                 );
  249.             else
  250.                 emitError
  251.                 (
  252.                     XMLErrs::XMLException_Error
  253.                     , excToCatch.getType()
  254.                     , excToCatch.getMessage()
  255.                 );
  256.         }
  257.         catch(...)
  258.         {
  259.             // Flush the reader manager and rethrow user's error
  260.             fReaderMgr.reset();
  261.             throw;
  262.         }
  263.         // If it returned, then reset the reader manager and fall through
  264.         fReaderMgr.reset();
  265.     }
  266.     catch(...)
  267.     {
  268.         // Reset and rethrow
  269.         fReaderMgr.reset();
  270.         throw;
  271.     }
  272. }
  273. bool IGXMLScanner::scanNext(XMLPScanToken& token)
  274. {
  275.     // Make sure this token is still legal
  276.     if (!isLegalToken(token))
  277.         ThrowXML(RuntimeException, XMLExcepts::Scan_BadPScanToken);
  278.     // Find the next token and remember the reader id
  279.     unsigned int orgReader;
  280.     XMLTokens curToken;
  281.     bool retVal = true;
  282.     try
  283.     {
  284.         while (true)
  285.         {
  286.             //  We have to handle any end of entity exceptions that happen here.
  287.             //  We could be at the end of X nested entities, each of which will
  288.             //  generate an end of entity exception as we try to move forward.
  289.             try
  290.             {
  291.                 curToken = senseNextToken(orgReader);
  292.                 break;
  293.             }
  294.             catch(const EndOfEntityException& toCatch)
  295.             {
  296.                 // Send an end of entity reference event
  297.                 if (fDocHandler)
  298.                     fDocHandler->endEntityReference(toCatch.getEntity());
  299.             }
  300.         }
  301.         if (curToken == Token_CharData)
  302.         {
  303.             scanCharData(fCDataBuf);
  304.         }
  305.         else if (curToken == Token_EOF)
  306.         {
  307.             if (!fElemStack.isEmpty())
  308.             {
  309.                 const ElemStack::StackElem* topElem = fElemStack.popTop();
  310.                 emitError
  311.                 (
  312.                     XMLErrs::EndedWithTagsOnStack
  313.                     , topElem->fThisElement->getFullName()
  314.                 );
  315.             }
  316.             retVal = false;
  317.         }
  318.         else
  319.         {
  320.             // Its some sort of markup
  321.             bool gotData = true;
  322.             switch(curToken)
  323.             {
  324.                 case Token_CData :
  325.                     // Make sure we are within content
  326.                     if (fElemStack.isEmpty())
  327.                         emitError(XMLErrs::CDATAOutsideOfContent);
  328.                     scanCDSection();
  329.                     break;
  330.                 case Token_Comment :
  331.                     scanComment();
  332.                     break;
  333.                 case Token_EndTag :
  334.                     scanEndTag(gotData);
  335.                     break;
  336.                 case Token_PI :
  337.                     scanPI();
  338.                     break;
  339.                 case Token_StartTag :
  340.                     if (fDoNamespaces)
  341.                         scanStartTagNS(gotData);
  342.                     else
  343.                         scanStartTag(gotData);
  344.                     break;
  345.                 default :
  346.                     fReaderMgr.skipToChar(chOpenAngle);
  347.                     break;
  348.             }
  349.             if (orgReader != fReaderMgr.getCurrentReaderNum())
  350.                 emitError(XMLErrs::PartialMarkupInEntity);
  351.             // If we hit the end, then do the miscellaneous part
  352.             if (!gotData)
  353.             {
  354.                 // Do post-parse validation if required
  355.                 if (fValidate)
  356.                 {
  357.                     //  We handle ID reference semantics at this level since
  358.                     //  its required by XML 1.0.
  359.                     checkIDRefs();
  360.                     // Then allow the validator to do any extra stuff it wants
  361. //                    fValidator->postParseValidation();
  362.                 }
  363.                 // That went ok, so scan for any miscellaneous stuff
  364.                 scanMiscellaneous();
  365.                 if (fValidate)
  366.                     fValueStoreCache->endDocument();
  367.                 if (fDocHandler)
  368.                     fDocHandler->endDocument();
  369.             }
  370.         }
  371.     }
  372.     //  NOTE:
  373.     //
  374.     //  In all of the error processing below, the emitError() call MUST come
  375.     //  before the flush of the reader mgr, or it will fail because it tries
  376.     //  to find out the position in the XML source of the error.
  377.     catch(const XMLErrs::Codes)
  378.     {
  379.         // This is a 'first failure' exception, so reset and return failure
  380.         fReaderMgr.reset();
  381.         return false;
  382.     }
  383.     catch(const XMLValid::Codes)
  384.     {
  385.         // This is a 'first fatal error' type exit, so reset and reuturn failure
  386.         fReaderMgr.reset();
  387.         return false;
  388.     }
  389.     catch(const XMLException& excToCatch)
  390.     {
  391.         //  Emit the error and catch any user exception thrown from here. Make
  392.         //  sure in all cases we flush the reader manager.
  393.         fInException = true;
  394.         try
  395.         {
  396.             if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning)
  397.                 emitError
  398.                 (
  399.                     XMLErrs::XMLException_Warning
  400.                     , excToCatch.getType()
  401.                     , excToCatch.getMessage()
  402.                 );
  403.             else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal)
  404.                 emitError
  405.                 (
  406.                     XMLErrs::XMLException_Fatal
  407.                     , excToCatch.getType()
  408.                     , excToCatch.getMessage()
  409.                 );
  410.             else
  411.                 emitError
  412.                 (
  413.                     XMLErrs::XMLException_Error
  414.                     , excToCatch.getType()
  415.                     , excToCatch.getMessage()
  416.                 );
  417.         }
  418.         catch(...)
  419.         {
  420.             // Reset and rethrow user error
  421.             fReaderMgr.reset();
  422.             throw;
  423.         }
  424.         // Reset and return failure
  425.         fReaderMgr.reset();
  426.         return false;
  427.     }
  428.     catch(...)
  429.     {
  430.         // Reset and rethrow original error
  431.         fReaderMgr.reset();
  432.         throw;
  433.     }
  434.     // If we hit the end, then flush the reader manager
  435.     if (!retVal)
  436.         fReaderMgr.reset();
  437.     return retVal;
  438. }
  439. // ---------------------------------------------------------------------------
  440. //  IGXMLScanner: Private helper methods. Most of these are implemented in
  441. //  IGXMLScanner2.Cpp.
  442. // ---------------------------------------------------------------------------
  443. //  This method handles the common initialization, to avoid having to do
  444. //  it redundantly in multiple constructors.
  445. void IGXMLScanner::commonInit()
  446. {
  447.     //  Create the element state array
  448.     fElemState = (unsigned int*) fMemoryManager->allocate
  449.     (
  450.         fElemStateSize * sizeof(unsigned int)
  451.     ); //new unsigned int[fElemStateSize];
  452.     //  And we need one for the raw attribute scan. This just stores key/
  453.     //  value string pairs (prior to any processing.)
  454.     fRawAttrList = new (fMemoryManager) RefVectorOf<KVStringPair>(32, true, fMemoryManager);
  455.     //  Create the Validator and init them
  456.     fDTDValidator = new (fMemoryManager) DTDValidator();
  457.     initValidator(fDTDValidator);
  458.     fSchemaValidator = new (fMemoryManager) SchemaValidator(0, fMemoryManager);
  459.     initValidator(fSchemaValidator);
  460.     // Create IdentityConstraint info
  461.     fMatcherStack = new (fMemoryManager) XPathMatcherStack(fMemoryManager);
  462.     fValueStoreCache = new (fMemoryManager) ValueStoreCache(fMemoryManager);
  463.     fFieldActivator = new (fMemoryManager) FieldActivator(fValueStoreCache, fMatcherStack, fMemoryManager);
  464.     fValueStoreCache->setScanner(this);
  465. }
  466. void IGXMLScanner::cleanUp()
  467. {
  468.     fMemoryManager->deallocate(fElemState); //delete [] fElemState;
  469.     delete fRawAttrList;
  470.     delete fDTDValidator;
  471.     delete fSchemaValidator;
  472.     delete fFieldActivator;
  473.     delete fMatcherStack;
  474.     delete fValueStoreCache;
  475. }
  476. // ---------------------------------------------------------------------------
  477. //  IGXMLScanner: Private scanning methods
  478. // ---------------------------------------------------------------------------
  479. //  This method is called from scanStartTag() to handle the very raw initial
  480. //  scan of the attributes. It just fills in the passed collection with
  481. //  key/value pairs for each attribute. No processing is done on them at all.
  482. unsigned int
  483. IGXMLScanner::rawAttrScan(const   XMLCh* const                elemName
  484.                           ,       RefVectorOf<KVStringPair>&  toFill
  485.                           ,       bool&                       isEmpty)
  486. {
  487.     //  Keep up with how many attributes we've seen so far, and how many
  488.     //  elements are available in the vector. This way we can reuse old
  489.     //  elements until we run out and then expand it.
  490.     unsigned int attCount = 0;
  491.     unsigned int curVecSize = toFill.size();
  492.     // Assume it is not empty
  493.     isEmpty = false;
  494.     //  We loop until we either see a /> or >, handling key/value pairs util
  495.     //  we get there. We place them in the passed vector, which we will expand
  496.     //  as required to hold them.
  497.     while (true)
  498.     {
  499.         // Get the next character, which should be non-space
  500.         XMLCh nextCh = fReaderMgr.peekNextChar();
  501.         //  If the next character is not a slash or closed angle bracket,
  502.         //  then it must be whitespace, since whitespace is required
  503.         //  between the end of the last attribute and the name of the next
  504.         //  one.
  505.         //
  506.         if (attCount)
  507.         {
  508.             if ((nextCh != chForwardSlash) && (nextCh != chCloseAngle))
  509.             {
  510.                 if (fReaderMgr.getCurrentReader()->isWhitespace(nextCh))
  511.                 {
  512.                     // Ok, skip by them and get another char
  513.                     fReaderMgr.getNextChar();
  514.                     fReaderMgr.skipPastSpaces();
  515.                     nextCh = fReaderMgr.peekNextChar();
  516.                 }
  517.                  else
  518.                 {
  519.                     // Emit the error but keep on going
  520.                     emitError(XMLErrs::ExpectedWhitespace);
  521.                 }
  522.             }
  523.         }
  524.         //  Ok, here we first check for any of the special case characters.
  525.         //  If its not one, then we do the normal case processing, which
  526.         //  assumes that we've hit an attribute value, Otherwise, we do all
  527.         //  the special case checks.
  528.         if (!fReaderMgr.getCurrentReader()->isSpecialStartTagChar(nextCh))
  529.         {
  530.             //  Assume its going to be an attribute, so get a name from
  531.             //  the input.
  532.             if (!fReaderMgr.getName(fAttNameBuf))
  533.             {
  534.                 emitError(XMLErrs::ExpectedAttrName);
  535.                 fReaderMgr.skipPastChar(chCloseAngle);
  536.                 return attCount;
  537.             }
  538.             // And next must be an equal sign
  539.             if (!scanEq())
  540.             {
  541.                 static const XMLCh tmpList[] =
  542.                 {
  543.                     chSingleQuote, chDoubleQuote, chCloseAngle
  544.                     , chOpenAngle, chForwardSlash, chNull
  545.                 };
  546.                 emitError(XMLErrs::ExpectedEqSign);
  547.                 //  Try to sync back up by skipping forward until we either
  548.                 //  hit something meaningful.
  549.                 const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);
  550.                 if ((chFound == chCloseAngle) || (chFound == chForwardSlash))
  551.                 {
  552.                     // Jump back to top for normal processing of these
  553.                     continue;
  554.                 }
  555.                 else if ((chFound == chSingleQuote)
  556.                       ||  (chFound == chDoubleQuote)
  557.                       ||  fReaderMgr.getCurrentReader()->isWhitespace(chFound))
  558.                 {
  559.                     // Just fall through assuming that the value is to follow
  560.                 }
  561.                 else if (chFound == chOpenAngle)
  562.                 {
  563.                     // Assume a malformed tag and that new one is starting
  564.                     emitError(XMLErrs::UnterminatedStartTag, elemName);
  565.                     return attCount;
  566.                 }
  567.                 else
  568.                 {
  569.                     // Something went really wrong
  570.                     return attCount;
  571.                 }
  572.             }
  573.             //  Next should be the quoted attribute value. We just do a simple
  574.             //  and stupid scan of this value. The only thing we do here
  575.             //  is to expand entity references.
  576.             if (!basicAttrValueScan(fAttNameBuf.getRawBuffer(), fAttValueBuf))
  577.             {
  578.                 static const XMLCh tmpList[] =
  579.                 {
  580.                     chCloseAngle, chOpenAngle, chForwardSlash, chNull
  581.                 };
  582.                 emitError(XMLErrs::ExpectedAttrValue);
  583.                 //  It failed, so lets try to get synced back up. We skip
  584.                 //  forward until we find some whitespace or one of the
  585.                 //  chars in our list.
  586.                 const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);
  587.                 if ((chFound == chCloseAngle)
  588.                 ||  (chFound == chForwardSlash)
  589.                 ||  fReaderMgr.getCurrentReader()->isWhitespace(chFound))
  590.                 {
  591.                     //  Just fall through and process this attribute, though
  592.                     //  the value will be "".
  593.                 }
  594.                 else if (chFound == chOpenAngle)
  595.                 {
  596.                     // Assume a malformed tag and that new one is starting
  597.                     emitError(XMLErrs::UnterminatedStartTag, elemName);
  598.                     return attCount;
  599.                 }
  600.                 else
  601.                 {
  602.                     // Something went really wrong
  603.                     return attCount;
  604.                 }
  605.             }
  606.             //  Make sure that the name is basically well formed for namespace
  607.             //  enabled rules. It either has no colons, or it has one which
  608.             //  is neither the first or last char.
  609.             const int colonFirst = XMLString::indexOf(fAttNameBuf.getRawBuffer(), chColon);
  610.             if (colonFirst != -1)
  611.             {
  612.                 const int colonLast = XMLString::lastIndexOf(fAttNameBuf.getRawBuffer(), chColon);
  613.                 if (colonFirst != colonLast)
  614.                 {
  615.                     emitError(XMLErrs::TooManyColonsInName);
  616.                     continue;
  617.                 }
  618.                 else if ((colonFirst == 0)
  619.                       ||  (colonLast == (int)fAttNameBuf.getLen() - 1))
  620.                 {
  621.                     emitError(XMLErrs::InvalidColonPos);
  622.                     continue;
  623.                 }
  624.             }
  625.             //  And now lets add it to the passed collection. If we have not
  626.             //  filled it up yet, then we use the next element. Else we add
  627.             //  a new one.
  628.             KVStringPair* curPair = 0;
  629.             if (attCount >= curVecSize)
  630.             {
  631.                 curPair = new (fMemoryManager) KVStringPair
  632.                 (
  633.                     fAttNameBuf.getRawBuffer()
  634.                     , fAttValueBuf.getRawBuffer()
  635.                     , fMemoryManager
  636.                 );
  637.                 toFill.addElement(curPair);
  638.             }
  639.              else
  640.             {
  641.                 curPair = toFill.elementAt(attCount);
  642.                 curPair->set(fAttNameBuf.getRawBuffer(), fAttValueBuf.getRawBuffer());
  643.             }
  644.             // And bump the count of attributes we've gotten
  645.             attCount++;
  646.             // And go to the top again for another attribute
  647.             continue;
  648.         }
  649.         //  It was some special case character so do all of the checks and
  650.         //  deal with it.
  651.         if (!nextCh)
  652.             ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
  653.         if (nextCh == chForwardSlash)
  654.         {
  655.             fReaderMgr.getNextChar();
  656.             isEmpty = true;
  657.             if (!fReaderMgr.skippedChar(chCloseAngle))
  658.                 emitError(XMLErrs::UnterminatedStartTag, elemName);
  659.             break;
  660.         }
  661.         else if (nextCh == chCloseAngle)
  662.         {
  663.             fReaderMgr.getNextChar();
  664.             break;
  665.         }
  666.         else if (nextCh == chOpenAngle)
  667.         {
  668.             //  Check for this one specially, since its going to be common
  669.             //  and it is kind of auto-recovering since we've already hit the
  670.             //  next open bracket, which is what we would have seeked to (and
  671.             //  skipped this whole tag.)
  672.             emitError(XMLErrs::UnterminatedStartTag, elemName);
  673.             break;
  674.         }
  675.         else if ((nextCh == chSingleQuote) || (nextCh == chDoubleQuote))
  676.         {
  677.             //  Check for this one specially, which is probably a missing
  678.             //  attribute name, e.g. ="value". Just issue expected name
  679.             //  error and eat the quoted string, then jump back to the
  680.             //  top again.
  681.             emitError(XMLErrs::ExpectedAttrName);
  682.             fReaderMgr.getNextChar();
  683.             fReaderMgr.skipQuotedString(nextCh);
  684.             fReaderMgr.skipPastSpaces();
  685.             continue;
  686.         }
  687.     }
  688.     return attCount;
  689. }
  690. //  This method will kick off the scanning of the primary content of the
  691. //  document, i.e. the elements.
  692. bool IGXMLScanner::scanContent(const bool extEntity)
  693. {
  694.     //  Go into a loop until we hit the end of the root element, or we fall
  695.     //  out because there is no root element.
  696.     //
  697.     //  We have to do kind of a deeply nested double loop here in order to
  698.     //  avoid doing the setup/teardown of the exception handler on each
  699.     //  round. Doing it this way we only do it when an exception actually
  700.     //  occurs.
  701.     bool gotData = true;
  702.     bool inMarkup = false;
  703.     while (gotData)
  704.     {
  705.         try
  706.         {
  707.             while (gotData)
  708.             {
  709.                 //  Sense what the next top level token is. According to what
  710.                 //  this tells us, we will call something to handle that kind
  711.                 //  of thing.
  712.                 unsigned int orgReader;
  713.                 const XMLTokens curToken = senseNextToken(orgReader);
  714.                 //  Handle character data and end of file specially. Char data
  715.                 //  is not markup so we don't want to handle it in the loop
  716.                 //  below.
  717.                 if (curToken == Token_CharData)
  718.                 {
  719.                     //  Scan the character data and call appropriate events. Let
  720.                     //  him use our local character data buffer for efficiency.
  721.                     scanCharData(fCDataBuf);
  722.                     continue;
  723.                 }
  724.                 else if (curToken == Token_EOF)
  725.                 {
  726.                     //  The element stack better be empty at this point or we
  727.                     //  ended prematurely before all elements were closed.
  728.                     if (!fElemStack.isEmpty())
  729.                     {
  730.                         const ElemStack::StackElem* topElem = fElemStack.popTop();
  731.                         emitError
  732.                         (
  733.                             XMLErrs::EndedWithTagsOnStack
  734.                             , topElem->fThisElement->getFullName()
  735.                         );
  736.                     }
  737.                     // Its the end of file, so clear the got data flag
  738.                     gotData = false;
  739.                     continue;
  740.                 }
  741.                 // We are in some sort of markup now
  742.                 inMarkup = true;
  743.                 //  According to the token we got, call the appropriate
  744.                 //  scanning method.
  745.                 switch(curToken)
  746.                 {
  747.                     case Token_CData :
  748.                         // Make sure we are within content
  749.                         if (fElemStack.isEmpty())
  750.                             emitError(XMLErrs::CDATAOutsideOfContent);
  751.                         scanCDSection();
  752.                         break;
  753.                     case Token_Comment :
  754.                         scanComment();
  755.                         break;
  756.                     case Token_EndTag :
  757.                         scanEndTag(gotData);
  758.                         break;
  759.                     case Token_PI :
  760.                         scanPI();
  761.                         break;
  762.                     case Token_StartTag :
  763.                         if (fDoNamespaces)
  764.                             scanStartTagNS(gotData);
  765.                         else
  766.                             scanStartTag(gotData);
  767.                         break;
  768.                     default :
  769.                         fReaderMgr.skipToChar(chOpenAngle);
  770.                         break;
  771.                 }
  772.                 if (orgReader != fReaderMgr.getCurrentReaderNum())
  773.                     emitError(XMLErrs::PartialMarkupInEntity);
  774.                 // And we are back out of markup again
  775.                 inMarkup = false;
  776.             }
  777.         }
  778.         catch(const EndOfEntityException& toCatch)
  779.         {
  780.             //  If we were in some markup when this happened, then its a
  781.             //  partial markup error.
  782.             if (inMarkup)
  783.                 emitError(XMLErrs::PartialMarkupInEntity);
  784.             // Send an end of entity reference event
  785.             if (fDocHandler)
  786.                 fDocHandler->endEntityReference(toCatch.getEntity());
  787.             inMarkup = false;
  788.         }
  789.     }
  790.     // It went ok, so return success
  791.     return true;
  792. }
  793. void IGXMLScanner::scanEndTag(bool& gotData)
  794. {
  795.     //  Assume we will still have data until proven otherwise. It will only
  796.     //  ever be false if this is the end of the root element.
  797.     gotData = true;
  798.     //  Check if the element stack is empty. If so, then this is an unbalanced
  799.     //  element (i.e. more ends than starts, perhaps because of bad text
  800.     //  causing one to be skipped.)
  801.     if (fElemStack.isEmpty())
  802.     {
  803.         emitError(XMLErrs::MoreEndThanStartTags);
  804.         fReaderMgr.skipPastChar(chCloseAngle);
  805.         ThrowXML(RuntimeException, XMLExcepts::Scan_UnbalancedStartEnd);
  806.     }
  807.     // After the </ is the element QName, so get a name from the input
  808.     if (!fReaderMgr.getName(fQNameBuf))
  809.     {
  810.         // It failed so we can't really do anything with it
  811.         emitError(XMLErrs::ExpectedElementName);
  812.         fReaderMgr.skipPastChar(chCloseAngle);
  813.         return;
  814.     }
  815.     unsigned int uriId = fEmptyNamespaceId;
  816.     int prefixColonPos = -1;
  817.     if (fDoNamespaces)
  818.     {
  819.         uriId = resolveQName
  820.         (
  821.             fQNameBuf.getRawBuffer()
  822.             , fPrefixBuf
  823.             , ElemStack::Mode_Element
  824.             , prefixColonPos
  825.         );
  826.     }
  827.     //  Pop the stack of the element we are supposed to be ending. Remember
  828.     //  that we don't own this. The stack just keeps them and reuses them.
  829.     //
  830.     //  NOTE: We CANNOT do this until we've resolved the element name because
  831.     //  the element stack top contains the prefix to URI mappings for this
  832.     //  element.
  833.     unsigned int topUri = fElemStack.getCurrentURI();
  834.     const ElemStack::StackElem* topElem = fElemStack.popTop();
  835.     // See if it was the root element, to avoid multiple calls below
  836.     const bool isRoot = fElemStack.isEmpty();
  837.     // Make sure that its the end of the element that we expect
  838.     XMLElementDecl* tempElement = topElem->fThisElement;
  839.     if (fDoNamespaces && fGrammarType == Grammar::SchemaGrammarType) {
  840.         const XMLCh* rawNameBuf = fQNameBuf.getRawBuffer();
  841.         if ((topUri != uriId) || (!XMLString::equals(tempElement->getBaseName(), &rawNameBuf[prefixColonPos + 1])))
  842.         {
  843.             emitError
  844.             (
  845.                 XMLErrs::ExpectedEndOfTagX
  846.                 , topElem->fThisElement->getFullName()
  847.             );
  848.         }
  849.     }
  850.     else {
  851.         if (!XMLString::equals(tempElement->getFullName(), fQNameBuf.getRawBuffer()))
  852.         {
  853.             emitError
  854.             (
  855.                 XMLErrs::ExpectedEndOfTagX
  856.                 , topElem->fThisElement->getFullName()
  857.             );
  858.         }
  859.     }
  860.     // Make sure we are back on the same reader as where we started
  861.     if (topElem->fReaderNum != fReaderMgr.getCurrentReaderNum())
  862.         emitError(XMLErrs::PartialTagMarkupError);
  863.     // Skip optional whitespace
  864.     fReaderMgr.skipPastSpaces();
  865.     // Make sure we find the closing bracket
  866.     if (!fReaderMgr.skippedChar(chCloseAngle))
  867.     {
  868.         emitError
  869.         (
  870.             XMLErrs::UnterminatedEndTag
  871.             , topElem->fThisElement->getFullName()
  872.         );
  873.     }
  874.     //  If validation is enabled, then lets pass him the list of children and
  875.     //  this element and let him validate it.
  876.     if (fValidate)
  877.     {
  878.         int res = fValidator->checkContent
  879.         (
  880.             topElem->fThisElement
  881.             , topElem->fChildren
  882.             , topElem->fChildCount
  883.         );
  884.         if (res >= 0)
  885.         {
  886.             //  One of the elements is not valid for the content. NOTE that
  887.             //  if no children were provided but the content model requires
  888.             //  them, it comes back with a zero value. But we cannot use that
  889.             //  to index the child array in this case, and have to put out a
  890.             //  special message.
  891.             if (!topElem->fChildCount)
  892.             {
  893.                 fValidator->emitError
  894.                 (
  895.                     XMLValid::EmptyNotValidForContent
  896.                     , topElem->fThisElement->getFormattedContentModel()
  897.                 );
  898.             }
  899.             else if ((unsigned int)res >= topElem->fChildCount)
  900.             {
  901.                 fValidator->emitError
  902.                 (
  903.                     XMLValid::NotEnoughElemsForCM
  904.                     , topElem->fThisElement->getFormattedContentModel()
  905.                 );
  906.             }
  907.             else
  908.             {
  909.                 fValidator->emitError
  910.                 (
  911.                     XMLValid::ElementNotValidForContent
  912.                     , topElem->fChildren[res]->getRawName()
  913.                     , topElem->fThisElement->getFormattedContentModel()
  914.                 );
  915.             }
  916.         }
  917.         if (fGrammarType == Grammar::SchemaGrammarType) {
  918.             // call matchers and de-activate context
  919.             int oldCount = fMatcherStack->getMatcherCount();
  920.             if (oldCount ||
  921.                 ((SchemaElementDecl*)topElem->fThisElement)->getIdentityConstraintCount()) {
  922.                 for (int i = oldCount - 1; i >= 0; i--) {
  923.                     XPathMatcher* matcher = fMatcherStack->getMatcherAt(i);
  924.                     matcher->endElement(*(topElem->fThisElement), fContent.getRawBuffer());
  925.                 }
  926.                 if (fMatcherStack->size() > 0) {
  927.                     fMatcherStack->popContext();
  928.                 }
  929.                 // handle everything *but* keyref's.
  930.                 int newCount = fMatcherStack->getMatcherCount();
  931.                 for (int j = oldCount - 1; j >= newCount; j--) {
  932.                     XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
  933.                     IdentityConstraint* ic = matcher->getIdentityConstraint();
  934.                     if (ic  && (ic->getType() != IdentityConstraint::KEYREF))
  935.                         fValueStoreCache->transplant(ic, matcher->getInitialDepth());
  936.                 }
  937.                 // now handle keyref's...
  938.                 for (int k = oldCount - 1; k >= newCount; k--) {
  939.                     XPathMatcher* matcher = fMatcherStack->getMatcherAt(k);
  940.                     IdentityConstraint* ic = matcher->getIdentityConstraint();
  941.                     if (ic && (ic->getType() == IdentityConstraint::KEYREF)) {
  942.                         ValueStore* values = fValueStoreCache->getValueStoreFor(ic, matcher->getInitialDepth());
  943.                         if (values) { // nothing to do if nothing matched!
  944.                             values->endDcocumentFragment(fValueStoreCache);
  945.                         }
  946.                     }
  947.                 }
  948.                 fValueStoreCache->endElement();
  949.             }
  950.         }
  951.     }
  952.     if(!isRoot && fGrammarType == Grammar::SchemaGrammarType)
  953.         ((SchemaElementDecl *)fElemStack.topElement()->fThisElement)->updateValidityFromElement(topElem->fThisElement, fGrammarType);
  954.     // If we have a doc handler, tell it about the end tag
  955.     if (fDocHandler)
  956.     {
  957.         fDocHandler->endElement
  958.         (
  959.             *topElem->fThisElement
  960.             , uriId
  961.             , isRoot
  962.             , fPrefixBuf.getRawBuffer()
  963.         );
  964.     }
  965.     // reset xsi:type ComplexTypeInfo
  966.     if (fGrammarType == Grammar::SchemaGrammarType) {
  967.         ((SchemaElementDecl*)topElem->fThisElement)->reset();
  968.         if (!isRoot)
  969.             ((SchemaElementDecl*)(fElemStack.topElement()->fThisElement))->
  970.                 setXsiComplexTypeInfo(((SchemaValidator*)fValidator)->getCurrentTypeInfo());
  971.     }
  972.     // If this was the root, then done with content
  973.     gotData = !isRoot;
  974.     if (gotData) {
  975.         if (fDoNamespaces) {
  976.             // Restore the grammar
  977.             fGrammar = fElemStack.getCurrentGrammar();
  978.             fGrammarType = fGrammar->getGrammarType();
  979.             if (fGrammarType == Grammar::SchemaGrammarType && !fValidator->handlesSchema()) {
  980.                 if (fValidatorFromUser)
  981.                     ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
  982.                 else {
  983.                     fValidator = fSchemaValidator;
  984.                 }
  985.             }
  986.             else if (fGrammarType == Grammar::DTDGrammarType && !fValidator->handlesDTD()) {
  987.                 if (fValidatorFromUser)
  988.                     ThrowXML(RuntimeException, XMLExcepts::Gen_NoDTDValidator);
  989.                 else {
  990.                     fValidator = fDTDValidator;
  991.                 }
  992.             }
  993.             fValidator->setGrammar(fGrammar);
  994.         }
  995.         // Restore the validation flag
  996.         fValidate = fElemStack.getValidationFlag();
  997.     }
  998. }
  999. //  This method handles the high level logic of scanning the DOCType
  1000. //  declaration. This calls the DTDScanner and kicks off both the scanning of
  1001. //  the internal subset and the scanning of the external subset, if any.
  1002. //
  1003. //  When we get here the '<!DOCTYPE' part has already been scanned, which is
  1004. //  what told us that we had a doc type decl to parse.
  1005. void IGXMLScanner::scanDocTypeDecl()
  1006. {
  1007.     //  We have a doc type. So, switch the Grammar.
  1008.     switchGrammar(XMLUni::fgDTDEntityString);
  1009.     if (fDocTypeHandler)
  1010.         fDocTypeHandler->resetDocType();
  1011.     // There must be some space after DOCTYPE
  1012.     if (!fReaderMgr.skipPastSpaces())
  1013.     {
  1014.         emitError(XMLErrs::ExpectedWhitespace);
  1015.         // Just skip the Doctype declaration and return
  1016.         fReaderMgr.skipPastChar(chCloseAngle);
  1017.         return;
  1018.     }
  1019.     // Get a buffer for the root element
  1020.     XMLBufBid bbRootName(&fBufMgr);
  1021.     //  Get a name from the input, which should be the name of the root
  1022.     //  element of the upcoming content.
  1023.     fReaderMgr.getName(bbRootName.getBuffer());
  1024.     if (bbRootName.isEmpty())
  1025.     {
  1026.         emitError(XMLErrs::NoRootElemInDOCTYPE);
  1027.         fReaderMgr.skipPastChar(chCloseAngle);
  1028.         return;
  1029.     }
  1030.     //  Store the root element name for later check
  1031.     setRootElemName(bbRootName.getRawBuffer());
  1032.     //  This element obviously is not going to exist in the element decl
  1033.     //  pool yet, but we need to call docTypeDecl. So force it into
  1034.     //  the element decl pool, marked as being there because it was in
  1035.     //  the DOCTYPE. Later, when its declared, the status will be updated.
  1036.     //
  1037.     //  Only do this if we are not reusing the validator! If we are reusing,
  1038.     //  then look it up instead. It has to exist!
  1039.     DTDElementDecl* rootDecl = new (fMemoryManager) DTDElementDecl
  1040.     (
  1041.         bbRootName.getRawBuffer()
  1042.         , fEmptyNamespaceId
  1043.         , DTDElementDecl::Any
  1044.         , fMemoryManager
  1045.     );
  1046.     rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
  1047.     rootDecl->setExternalElemDeclaration(true);
  1048.     ((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl));
  1049.     // Skip any spaces after the name
  1050.     fReaderMgr.skipPastSpaces();
  1051.     //  And now if we are looking at a >, then we are done. It is not
  1052.     //  required to have an internal or external subset, though why you
  1053.     //  would not escapes me.
  1054.     if (fReaderMgr.skippedChar(chCloseAngle)) {
  1055.         //  If we have a doc type handler and advanced callbacks are enabled,
  1056.         //  call the doctype event.
  1057.         if (fDocTypeHandler)
  1058.             fDocTypeHandler->doctypeDecl(*rootDecl, 0, 0, false);
  1059.         return;
  1060.     }
  1061.     // either internal/external subset
  1062.     if (fValScheme == Val_Auto && !fValidate)
  1063.         fValidate = true;
  1064.     bool    hasIntSubset = false;
  1065.     bool    hasExtSubset = false;
  1066.     XMLCh*  sysId = 0;
  1067.     XMLCh*  pubId = 0;
  1068.     DTDScanner dtdScanner
  1069.     (
  1070.         (DTDGrammar*) fGrammar
  1071.         , fDocTypeHandler
  1072.         , fMemoryManager
  1073.     );
  1074.     dtdScanner.setScannerInfo(this, &fReaderMgr, &fBufMgr);
  1075.     //  If the next character is '[' then we have no external subset cause
  1076.     //  there is no system id, just the opening character of the internal
  1077.     //  subset. Else, has to be an id.
  1078.     //
  1079.     // Just look at the next char, don't eat it.
  1080.     if (fReaderMgr.peekNextChar() == chOpenSquare)
  1081.     {
  1082.         hasIntSubset = true;
  1083.     }
  1084.     else
  1085.     {
  1086.         // Indicate we have an external subset
  1087.         hasExtSubset = true;
  1088.         fHasNoDTD = false;
  1089.         // Get buffers for the ids
  1090.         XMLBufBid bbPubId(&fBufMgr);
  1091.         XMLBufBid bbSysId(&fBufMgr);
  1092.         // Get the external subset id
  1093.         if (!dtdScanner.scanId(bbPubId.getBuffer(), bbSysId.getBuffer(), DTDScanner::IDType_External))
  1094.         {
  1095.             fReaderMgr.skipPastChar(chCloseAngle);
  1096.             return;
  1097.         }
  1098.         // Get copies of the ids we got
  1099.         pubId = XMLString::replicate(bbPubId.getRawBuffer(), fMemoryManager);
  1100.         sysId = XMLString::replicate(bbSysId.getRawBuffer(), fMemoryManager);
  1101.         // Skip spaces and check again for the opening of an internal subset
  1102.         fReaderMgr.skipPastSpaces();
  1103.         // Just look at the next char, don't eat it.
  1104.         if (fReaderMgr.peekNextChar() == chOpenSquare) {
  1105.             hasIntSubset = true;
  1106.         }
  1107.     }
  1108.     // Insure that the ids get cleaned up, if they got allocated
  1109.     ArrayJanitor<XMLCh> janSysId(sysId, fMemoryManager);
  1110.     ArrayJanitor<XMLCh> janPubId(pubId, fMemoryManager);
  1111.     //  If we have a doc type handler and advanced callbacks are enabled,
  1112.     //  call the doctype event.
  1113.     if (fDocTypeHandler)
  1114.         fDocTypeHandler->doctypeDecl(*rootDecl, pubId, sysId, hasIntSubset, hasExtSubset);
  1115.     //  Ok, if we had an internal subset, we are just past the [ character
  1116.     //  and need to parse that first.
  1117.     if (hasIntSubset)
  1118.     {
  1119.         // Eat the opening square bracket
  1120.         fReaderMgr.getNextChar();
  1121.         // We can't have any internal subset if we are reusing the validator
  1122.         if (fUseCachedGrammar || fToCacheGrammar)
  1123.             ThrowXML(RuntimeException, XMLExcepts::Val_CantHaveIntSS);
  1124.         //  And try to scan the internal subset. If we fail, try to recover
  1125.         //  by skipping forward tot he close angle and returning.
  1126.         if (!dtdScanner.scanInternalSubset())
  1127.         {
  1128.             fReaderMgr.skipPastChar(chCloseAngle);
  1129.             return;
  1130.         }
  1131.         //  Do a sanity check that some expanded PE did not propogate out of
  1132.         //  the doctype. This could happen if it was terminated early by bad
  1133.         //  syntax.
  1134.         if (fReaderMgr.getReaderDepth() > 1)
  1135.         {
  1136.             emitError(XMLErrs::PEPropogated);
  1137.             // Ask the reader manager to pop back down to the main level
  1138.             fReaderMgr.cleanStackBackTo(1);
  1139.         }
  1140.         fReaderMgr.skipPastSpaces();
  1141.     }
  1142.     // And that should leave us at the closing > of the DOCTYPE line
  1143.     if (!fReaderMgr.skippedChar(chCloseAngle))
  1144.     {
  1145.         //  Do a special check for the common scenario of an extra ] char at
  1146.         //  the end. This is easy to recover from.
  1147.         if (fReaderMgr.skippedChar(chCloseSquare)
  1148.         &&  fReaderMgr.skippedChar(chCloseAngle))
  1149.         {
  1150.             emitError(XMLErrs::ExtraCloseSquare);
  1151.         }
  1152.          else
  1153.         {
  1154.             emitError(XMLErrs::UnterminatedDOCTYPE);
  1155.             fReaderMgr.skipPastChar(chCloseAngle);
  1156.         }
  1157.     }
  1158.     //  If we had an external subset, then we need to deal with that one
  1159.     //  next. If we are reusing the validator, then don't scan it.
  1160.     if (hasExtSubset) {
  1161.         if (fUseCachedGrammar)
  1162.         {
  1163.             InputSource* sysIdSrc = resolveSystemId(sysId);
  1164.             Janitor<InputSource> janSysIdSrc(sysIdSrc);
  1165.             Grammar* grammar = fGrammarResolver->getGrammar(sysIdSrc->getSystemId());
  1166.             if (grammar && grammar->getGrammarType() == Grammar::DTDGrammarType) {
  1167.                 fDTDGrammar = (DTDGrammar*) grammar;
  1168.                 fGrammar = fDTDGrammar;
  1169.                 fValidator->setGrammar(fGrammar);
  1170.                 rootDecl = (DTDElementDecl*) fGrammar->getElemDecl(fEmptyNamespaceId, 0, bbRootName.getRawBuffer(), Grammar::TOP_LEVEL_SCOPE);
  1171.                 if (rootDecl)
  1172.                     ((DTDGrammar*)fGrammar)->setRootElemId(rootDecl->getId());
  1173.                 else {
  1174.                     rootDecl = new (fMemoryManager) DTDElementDecl
  1175.                     (
  1176.                         bbRootName.getRawBuffer()
  1177.                         , fEmptyNamespaceId
  1178.                         , DTDElementDecl::Any
  1179.                         , fMemoryManager
  1180.                     );
  1181.                     rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
  1182.                     rootDecl->setExternalElemDeclaration(true);
  1183.                     ((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl));
  1184.                 }
  1185.                 return;
  1186.             }
  1187.         }
  1188.         if (fLoadExternalDTD || fValidate)
  1189.         {
  1190.             // And now create a reader to read this entity
  1191.             InputSource* srcUsed;
  1192.             XMLReader* reader = fReaderMgr.createReader
  1193.             (
  1194.                 sysId
  1195.                 , pubId
  1196.                 , false
  1197.                 , XMLReader::RefFrom_NonLiteral
  1198.                 , XMLReader::Type_General
  1199.                 , XMLReader::Source_External
  1200.                 , srcUsed
  1201.                 , fCalculateSrcOfs
  1202.             );
  1203.             // Put a janitor on the input source
  1204.             Janitor<InputSource> janSrc(srcUsed);
  1205.             //  If it failed then throw an exception
  1206.             if (!reader)
  1207.                 ThrowXML1(RuntimeException, XMLExcepts::Gen_CouldNotOpenDTD, srcUsed->getSystemId());
  1208.             if (fToCacheGrammar) {
  1209.                 unsigned int stringId = fGrammarResolver->getStringPool()->addOrFind(srcUsed->getSystemId());
  1210.                 const XMLCh* sysIdStr = fGrammarResolver->getStringPool()->getValueForId(stringId);
  1211.                 fGrammarResolver->orphanGrammar(XMLUni::fgDTDEntityString);
  1212.                 fGrammarResolver->putGrammar(sysIdStr, fGrammar);
  1213.             }
  1214.             //  In order to make the processing work consistently, we have to
  1215.             //  make this look like an external entity. So create an entity
  1216.             //  decl and fill it in and push it with the reader, as happens
  1217.             //  with an external entity. Put a janitor on it to insure it gets
  1218.             //  cleaned up. The reader manager does not adopt them.
  1219.             const XMLCh gDTDStr[] = { chLatin_D, chLatin_T, chLatin_D , chNull };
  1220.             DTDEntityDecl* declDTD = new (fMemoryManager) DTDEntityDecl(gDTDStr, false, fMemoryManager);
  1221.             declDTD->setSystemId(sysId);
  1222.             Janitor<DTDEntityDecl> janDecl(declDTD);
  1223.             // Mark this one as a throw at end
  1224.             reader->setThrowAtEnd(true);
  1225.             // And push it onto the stack, with its pseudo name
  1226.             fReaderMgr.pushReader(reader, declDTD);
  1227.             // Tell it its not in an include section
  1228.             dtdScanner.scanExtSubsetDecl(false, true);
  1229.         }
  1230.     }
  1231. }
  1232. bool IGXMLScanner::scanStartTag(bool& gotData)
  1233. {
  1234.     //  Assume we will still have data until proven otherwise. It will only
  1235.     //  ever be false if this is the root and its empty.
  1236.     gotData = true;
  1237.     //  Get the QName. In this case, we are not doing namespaces, so we just
  1238.     //  use it as is and don't have to break it into parts.
  1239.     if (!fReaderMgr.getName(fQNameBuf))
  1240.     {
  1241.         emitError(XMLErrs::ExpectedElementName);
  1242.         fReaderMgr.skipToChar(chOpenAngle);
  1243.         return false;
  1244.     }
  1245.     // Assume it won't be an empty tag
  1246.     bool isEmpty = false;
  1247.     //  Lets try to look up the element in the validator's element decl pool
  1248.     //  We can pass bogus values for the URI id and the base name. We know that
  1249.     //  this can only be called if we are doing a DTD style validator and that
  1250.     //  he will only look at the QName.
  1251.     //
  1252.     //  We tell him to fault in a decl if he does not find one.
  1253.     bool wasAdded = false;
  1254.     XMLElementDecl* elemDecl = fGrammar->findOrAddElemDecl
  1255.     (
  1256.         fEmptyNamespaceId
  1257.         , 0
  1258.         , 0
  1259.         , fQNameBuf.getRawBuffer()
  1260.         , Grammar::TOP_LEVEL_SCOPE
  1261.         , wasAdded
  1262.     );
  1263.     //  We do something different here according to whether we found the
  1264.     //  element or not.
  1265.     if (wasAdded)
  1266.     {
  1267.         // If validating then emit an error
  1268.         if (fValidate)
  1269.         {
  1270.             // This is to tell the reuse Validator that this element was
  1271.             // faulted-in, was not an element in the validator pool originally
  1272.             elemDecl->setCreateReason(XMLElementDecl::JustFaultIn);
  1273.             fValidator->emitError
  1274.             (
  1275.                 XMLValid::ElementNotDefined
  1276.                 , elemDecl->getFullName()
  1277.             );
  1278.         }
  1279.     }
  1280.     else
  1281.     {
  1282.         // If its not marked declared and validating, then emit an error
  1283.         if (fValidate && !elemDecl->isDeclared())
  1284.         {
  1285.             fValidator->emitError
  1286.             (
  1287.                 XMLValid::ElementNotDefined
  1288.                 , elemDecl->getFullName()
  1289.             );
  1290.         }
  1291.     }
  1292.     // See if its the root element
  1293.     const bool isRoot = fElemStack.isEmpty();
  1294.     // Expand the element stack and add the new element
  1295.     fElemStack.addLevel(elemDecl, fReaderMgr.getCurrentReaderNum());
  1296.     fElemStack.setValidationFlag(fValidate);
  1297.     //  Validate the element
  1298.     if (fValidate)
  1299.         fValidator->validateElement(elemDecl);
  1300.     //  If this is the first element and we are validating, check the root
  1301.     //  element.
  1302.     if (isRoot)
  1303.     {
  1304.         fRootGrammar = fGrammar;
  1305.         if (fValidate)
  1306.         {
  1307.             //  If a DocType exists, then check if it matches the root name there.
  1308.             if (fRootElemName && !XMLString::equals(fQNameBuf.getRawBuffer(), fRootElemName))
  1309.                 fValidator->emitError(XMLValid::RootElemNotLikeDocType);
  1310.             //  Some validators may also want to check the root, call the
  1311.             //  XMLValidator::checkRootElement
  1312.             if (fValidatorFromUser && !fValidator->checkRootElement(elemDecl->getId()))
  1313.                 fValidator->emitError(XMLValid::RootElemNotLikeDocType);
  1314.         }
  1315.     }
  1316.     else
  1317.     {
  1318.         //  If the element stack is not empty, then add this element as a
  1319.         //  child of the previous top element. If its empty, this is the root
  1320.         //  elem and is not the child of anything.
  1321.         fElemStack.addChild(elemDecl->getElementName(), true);
  1322.     }
  1323.     //  Ask the element decl to clear out the 'provided' flag on all of its
  1324.     //  att defs.
  1325.     elemDecl->resetDefs();
  1326.     // Skip any whitespace after the name
  1327.     fReaderMgr.skipPastSpaces();
  1328.     //  We loop until we either see a /> or >, handling attribute/value
  1329.     //  pairs until we get there.
  1330.     unsigned int    attCount = 0;
  1331.     unsigned int    curAttListSize = fAttrList->size();
  1332.     while (true)
  1333.     {
  1334.         // And get the next non-space character
  1335.         XMLCh nextCh = fReaderMgr.peekNextChar();
  1336.         //  If the next character is not a slash or closed angle bracket,
  1337.         //  then it must be whitespace, since whitespace is required
  1338.         //  between the end of the last attribute and the name of the next
  1339.         //  one.
  1340.         if (attCount)
  1341.         {
  1342.             if ((nextCh != chForwardSlash) && (nextCh != chCloseAngle))
  1343.             {
  1344.                 if (fReaderMgr.getCurrentReader()->isWhitespace(nextCh))
  1345.                 {
  1346.                     // Ok, skip by them and peek another char
  1347.                     fReaderMgr.skipPastSpaces();
  1348.                     nextCh = fReaderMgr.peekNextChar();
  1349.                 }
  1350.                  else
  1351.                 {
  1352.                     // Emit the error but keep on going
  1353.                     emitError(XMLErrs::ExpectedWhitespace);
  1354.                 }
  1355.             }
  1356.         }
  1357.         //  Ok, here we first check for any of the special case characters.
  1358.         //  If its not one, then we do the normal case processing, which
  1359.         //  assumes that we've hit an attribute value, Otherwise, we do all
  1360.         //  the special case checks.
  1361.         if (!fReaderMgr.getCurrentReader()->isSpecialStartTagChar(nextCh))
  1362.         {
  1363.             //  Assume its going to be an attribute, so get a name from
  1364.             //  the input.
  1365.             if (!fReaderMgr.getName(fAttNameBuf))
  1366.             {
  1367.                 emitError(XMLErrs::ExpectedAttrName);
  1368.                 fReaderMgr.skipPastChar(chCloseAngle);
  1369.                 return false;
  1370.             }
  1371.             // And next must be an equal sign
  1372.             if (!scanEq())
  1373.             {
  1374.                 static const XMLCh tmpList[] =
  1375.                 {
  1376.                     chSingleQuote, chDoubleQuote, chCloseAngle
  1377.                     , chOpenAngle, chForwardSlash, chNull
  1378.                 };
  1379.                 emitError(XMLErrs::ExpectedEqSign);
  1380.                 //  Try to sync back up by skipping forward until we either
  1381.                 //  hit something meaningful.
  1382.                 const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);
  1383.                 if ((chFound == chCloseAngle) || (chFound == chForwardSlash))
  1384.                 {
  1385.                     // Jump back to top for normal processing of these
  1386.                     continue;
  1387.                 }
  1388.                 else if ((chFound == chSingleQuote)
  1389.                       ||  (chFound == chDoubleQuote)
  1390.                       ||  fReaderMgr.getCurrentReader()->isWhitespace(chFound))
  1391.                 {
  1392.                     // Just fall through assuming that the value is to follow
  1393.                 }
  1394.                 else if (chFound == chOpenAngle)
  1395.                 {
  1396.                     // Assume a malformed tag and that new one is starting
  1397.                     emitError(XMLErrs::UnterminatedStartTag, elemDecl->getFullName());
  1398.                     return false;
  1399.                 }
  1400.                 else
  1401.                 {
  1402.                     // Something went really wrong
  1403.                     return false;
  1404.                 }
  1405.             }
  1406.             //  See if this attribute is declared for this element. If we are
  1407.             //  not validating of course it will not be at first, but we will
  1408.             //  fault it into the pool (to avoid lots of redundant errors.)
  1409.             wasAdded = false;
  1410.             XMLAttDef* attDef = elemDecl->findAttr
  1411.             (
  1412.                 fAttNameBuf.getRawBuffer()
  1413.                 , 0
  1414.                 , 0
  1415.                 , 0
  1416.                 , XMLElementDecl::AddIfNotFound
  1417.                 , wasAdded
  1418.             );
  1419.             if (wasAdded)
  1420.             {
  1421.                 //  If there is a validation handler, then we are validating
  1422.                 //  so emit an error.
  1423.                 if (fValidate)
  1424.                 {
  1425.                     // This is to tell the Validator that this attribute was
  1426.                     // faulted-in, was not an attribute in the attdef originally
  1427.                     attDef->setCreateReason(XMLAttDef::JustFaultIn);
  1428.                     fValidator->emitError
  1429.                     (
  1430.                         XMLValid::AttNotDefinedForElement
  1431.                         , fAttNameBuf.getRawBuffer()
  1432.                         , elemDecl->getFullName()
  1433.                     );
  1434.                 }
  1435.             }
  1436.             else
  1437.             {
  1438.                 // If this attribute was faulted-in and first occurence,
  1439.                 // then emit an error
  1440.                 if (fValidate && attDef->getCreateReason() == XMLAttDef::JustFaultIn
  1441.                     && !attDef->getProvided())
  1442.                 {
  1443.                     fValidator->emitError
  1444.                     (
  1445.                         XMLValid::AttNotDefinedForElement
  1446.                         , fAttNameBuf.getRawBuffer()
  1447.                         , elemDecl->getFullName()
  1448.                     );
  1449.                 }
  1450.             }
  1451.             //  If its already provided, then there are more than one of
  1452.             //  this attribute in this start tag, so emit an error.
  1453.             if (attDef->getProvided())
  1454.             {
  1455.                 emitError
  1456.                 (
  1457.                     XMLErrs::AttrAlreadyUsedInSTag
  1458.                     , attDef->getFullName()
  1459.                     , elemDecl->getFullName()
  1460.                 );
  1461.             }
  1462.             else
  1463.             {
  1464.                 // Mark this one as already seen
  1465.                 attDef->setProvided(true);
  1466.             }
  1467.             //  Skip any whitespace before the value and then scan the att
  1468.             //  value. This will come back normalized with entity refs and
  1469.             //  char refs expanded.
  1470.             fReaderMgr.skipPastSpaces();
  1471.             if (!scanAttValue(attDef, fAttValueBuf))
  1472.             {
  1473.                 static const XMLCh tmpList[] =
  1474.                 {
  1475.                     chCloseAngle, chOpenAngle, chForwardSlash, chNull
  1476.                 };
  1477.                 emitError(XMLErrs::ExpectedAttrValue);
  1478.                 //  It failed, so lets try to get synced back up. We skip
  1479.                 //  forward until we find some whitespace or one of the
  1480.                 //  chars in our list.
  1481.                 const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);
  1482.                 if ((chFound == chCloseAngle)
  1483.                 ||  (chFound == chForwardSlash)
  1484.                 ||  fReaderMgr.getCurrentReader()->isWhitespace(chFound))
  1485.                 {
  1486.                     //  Just fall through and process this attribute, though
  1487.                     //  the value will be "".
  1488.                 }
  1489.                 else if (chFound == chOpenAngle)
  1490.                 {
  1491.                     // Assume a malformed tag and that new one is starting
  1492.                     emitError(XMLErrs::UnterminatedStartTag, elemDecl->getFullName());
  1493.                     return false;
  1494.                 }
  1495.                 else
  1496.                 {
  1497.                     // Something went really wrong
  1498.                     return false;
  1499.                 }
  1500.             }
  1501.             //  Now that its all stretched out, lets look at its type and
  1502.             //  determine if it has a valid value. It will output any needed
  1503.             //  errors, but we just keep going. We only need to do this if
  1504.             //  we are validating.
  1505.             if (!wasAdded && attDef->getCreateReason() != XMLAttDef::JustFaultIn)
  1506.             {
  1507.                 // Let the validator pass judgement on the attribute value
  1508.                 if (fValidate)
  1509.                 {
  1510.                     fValidator->validateAttrValue
  1511.                     (
  1512.                         attDef
  1513.                         , fAttValueBuf.getRawBuffer()
  1514.                         , false
  1515.                         , elemDecl
  1516.                     );
  1517.                 }
  1518.             }
  1519.             //  Add this attribute to the attribute list that we use to
  1520.             //  pass them to the handler. We reuse its existing elements
  1521.             //  but expand it as required.
  1522.             XMLAttr* curAtt;
  1523.             if (attCount >= curAttListSize)
  1524.             {
  1525.                 curAtt = new (fMemoryManager) XMLAttr
  1526.                 (
  1527.                     -1
  1528.                     , fAttNameBuf.getRawBuffer()
  1529.                     , XMLUni::fgZeroLenString
  1530.                     , fAttValueBuf.getRawBuffer()
  1531.                     , attDef->getType()
  1532.                     , true
  1533.                     , fMemoryManager
  1534.                 );
  1535.                 fAttrList->addElement(curAtt);
  1536.             }
  1537.             else
  1538.             {
  1539.                 curAtt = fAttrList->elementAt(attCount);
  1540.                 curAtt->set
  1541.                 (
  1542.                     -1
  1543.                     , fAttNameBuf.getRawBuffer()
  1544.                     , XMLUni::fgZeroLenString
  1545.                     , fAttValueBuf.getRawBuffer()
  1546.                     , attDef->getType()
  1547.                 );
  1548.                 curAtt->setSpecified(true);
  1549.             }
  1550.             attCount++;
  1551.             // And jump back to the top of the loop
  1552.             continue;
  1553.         }
  1554.         //  It was some special case character so do all of the checks and
  1555.         //  deal with it.
  1556.         if (!nextCh)
  1557.             ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
  1558.         if (nextCh == chForwardSlash)
  1559.         {
  1560.             fReaderMgr.getNextChar();
  1561.             isEmpty = true;
  1562.             if (!fReaderMgr.skippedChar(chCloseAngle))
  1563.                 emitError(XMLErrs::UnterminatedStartTag, elemDecl->getFullName());
  1564.             break;
  1565.         }
  1566.         else if (nextCh == chCloseAngle)
  1567.         {
  1568.             fReaderMgr.getNextChar();
  1569.             break;
  1570.         }
  1571.         else if (nextCh == chOpenAngle)
  1572.         {
  1573.             //  Check for this one specially, since its going to be common
  1574.             //  and it is kind of auto-recovering since we've already hit the
  1575.             //  next open bracket, which is what we would have seeked to (and
  1576.             //  skipped this whole tag.)
  1577.             emitError(XMLErrs::UnterminatedStartTag, elemDecl->getFullName());
  1578.             break;
  1579.         }
  1580.         else if ((nextCh == chSingleQuote) || (nextCh == chDoubleQuote))
  1581.         {
  1582.             //  Check for this one specially, which is probably a missing
  1583.             //  attribute name, e.g. ="value". Just issue expected name
  1584.             //  error and eat the quoted string, then jump back to the
  1585.             //  top again.
  1586.             emitError(XMLErrs::ExpectedAttrName);
  1587.             fReaderMgr.getNextChar();
  1588.             fReaderMgr.skipQuotedString(nextCh);
  1589.             fReaderMgr.skipPastSpaces();
  1590.             continue;
  1591.         }
  1592.     }
  1593.     //  Ok, so lets get an enumerator for the attributes of this element
  1594.     //  and run through them for well formedness and validity checks. But
  1595.     //  make sure that we had any attributes before we do it, since the list
  1596.     //  would have have gotten faulted in anyway.
  1597.     if (elemDecl->hasAttDefs())
  1598.     {
  1599.         XMLAttDefList& attDefList = elemDecl->getAttDefList();
  1600.         while (attDefList.hasMoreElements())
  1601.         {
  1602.             // Get the current att def, for convenience and its def type
  1603.             const XMLAttDef& curDef = attDefList.nextElement();
  1604.             const XMLAttDef::DefAttTypes defType = curDef.getDefaultType();
  1605.             if (!curDef.getProvided())
  1606.             {
  1607.                 if (fValidate)
  1608.                 {
  1609.                     // If we are validating and its required, then an error
  1610.                     if (defType == XMLAttDef::Required)
  1611.                     {
  1612.                         fValidator->emitError
  1613.                         (
  1614.                             XMLValid::RequiredAttrNotProvided
  1615.                             , curDef.getFullName()
  1616.                         );
  1617.                     }
  1618.                     else if ((defType == XMLAttDef::Default) ||
  1619.                        (defType == XMLAttDef::Fixed)  )
  1620.                     {
  1621.                         if (fStandalone && curDef.isExternal())
  1622.                         {
  1623.                             // XML 1.0 Section 2.9
  1624.                             // Document is standalone, so attributes must not be defaulted.
  1625.                             fValidator->emitError(XMLValid::NoDefAttForStandalone, curDef.getFullName(), elemDecl->getFullName());
  1626.                         }
  1627.                     }
  1628.                 }
  1629.                 // Fault in the value if needed, and bump the att count
  1630.                 if ((defType == XMLAttDef::Default)
  1631.                 ||  (defType == XMLAttDef::Fixed))
  1632.                 {
  1633.                     // Let the validator pass judgement on the attribute value
  1634.                     if (fValidate)
  1635.                     {
  1636.                         fValidator->validateAttrValue
  1637.                         (
  1638.                             &curDef
  1639.                             , curDef.getValue()
  1640.                             , false
  1641.                             , elemDecl
  1642.                         );
  1643.                     }
  1644.                     XMLAttr* curAtt;
  1645.                     if (attCount >= curAttListSize)
  1646.                     {
  1647.                         curAtt = new (fMemoryManager) XMLAttr
  1648.                         (
  1649.                             -1
  1650.                             , curDef.getFullName()
  1651.                             , XMLUni::fgZeroLenString
  1652.                             , curDef.getValue()
  1653.                             , curDef.getType()
  1654.                             , false
  1655.                             , fMemoryManager
  1656.                         );
  1657.                         fAttrList->addElement(curAtt);
  1658.                         curAttListSize++;
  1659.                     }
  1660.                     else
  1661.                     {
  1662.                         curAtt = fAttrList->elementAt(attCount);
  1663.                         curAtt->set
  1664.                         (
  1665.                             -1
  1666.                             , curDef.getFullName()
  1667.                             , XMLUni::fgZeroLenString
  1668.                             , curDef.getValue()
  1669.                             , curDef.getType()
  1670.                         );
  1671.                         curAtt->setSpecified(false);
  1672.                     }
  1673.                     attCount++;
  1674.                 }
  1675.             }
  1676.         }
  1677.     }
  1678.     //  If empty, validate content right now if we are validating and then
  1679.     //  pop the element stack top. Else, we have to update the current stack
  1680.     //  top's namespace mapping elements.
  1681.     if (isEmpty)
  1682.     {
  1683.         // If validating, then insure that its legal to have no content
  1684.         if (fValidate)
  1685.         {
  1686.             const int res = fValidator->checkContent(elemDecl, 0, 0);
  1687.             if (res >= 0)
  1688.             {
  1689.                 fValidator->emitError
  1690.                 (
  1691.                     XMLValid::ElementNotValidForContent
  1692.                     , elemDecl->getFullName()
  1693.                     , elemDecl->getFormattedContentModel()
  1694.                 );
  1695.             }
  1696.         }
  1697.         // Pop the element stack back off since it'll never be used now
  1698.         fElemStack.popTop();
  1699.         // If the elem stack is empty, then it was an empty root
  1700.         if (isRoot)
  1701.             gotData = false;
  1702.         else {
  1703.             // Restore the validation flag
  1704.             fValidate = fElemStack.getValidationFlag();
  1705.         }
  1706.     }
  1707.     //  If we have a document handler, then tell it about this start tag. We
  1708.     //  don't have any URI id to send along, so send fEmptyNamespaceId. We also do not send
  1709.     //  any prefix since its just one big name if we are not doing namespaces.
  1710.     if (fDocHandler)
  1711.     {
  1712.         fDocHandler->startElement
  1713.         (
  1714.             *elemDecl
  1715.             , fEmptyNamespaceId
  1716.             , 0
  1717.             , *fAttrList
  1718.             , attCount
  1719.             , isEmpty
  1720.             , isRoot
  1721.         );
  1722.     }
  1723.     return true;
  1724. }
  1725. //  This method is called to scan a start tag when we are processing
  1726. //  namespaces. There are two different versions of this method, one for
  1727. //  namespace aware processing an done for non-namespace aware processing.
  1728. //
  1729. //  This method is called after we've scanned the < of a start tag. So we
  1730. //  have to get the element name, then scan the attributes, after which
  1731. //  we are either going to see >, />, or attributes followed by one of those
  1732. //  sequences.
  1733. bool IGXMLScanner::scanStartTagNS(bool& gotData)
  1734. {
  1735.     //  Assume we will still have data until proven otherwise. It will only
  1736.     //  ever be false if this is the root and its empty.
  1737.     gotData = true;
  1738.     // Reset element content buffer
  1739.     fContent.reset();
  1740.     //  The current position is after the open bracket, so we need to read in
  1741.     //  in the element name.
  1742.     if (!fReaderMgr.getName(fQNameBuf))
  1743.     {
  1744.         emitError(XMLErrs::ExpectedElementName);
  1745.         fReaderMgr.skipToChar(chOpenAngle);
  1746.         return false;
  1747.     }
  1748.     // See if its the root element
  1749.     const bool isRoot = fElemStack.isEmpty();
  1750.     // Skip any whitespace after the name
  1751.     fReaderMgr.skipPastSpaces();
  1752.     //  First we have to do the rawest attribute scan. We don't do any
  1753.     //  normalization of them at all, since we don't know yet what type they
  1754.     //  might be (since we need the element decl in order to do that.)
  1755.     bool isEmpty;
  1756.     unsigned int attCount = rawAttrScan
  1757.     (
  1758.         fQNameBuf.getRawBuffer()
  1759.         , *fRawAttrList
  1760.         , isEmpty
  1761.     );
  1762.     const bool gotAttrs = (attCount != 0);
  1763.     // save the contentleafname and currentscope before addlevel, for later use
  1764.     ContentLeafNameTypeVector* cv = 0;
  1765.     XMLContentModel* cm = 0;
  1766.     int currentScope = Grammar::TOP_LEVEL_SCOPE;
  1767.     bool laxThisOne = false;
  1768.     if (!isRoot && fGrammarType == Grammar::SchemaGrammarType) {
  1769.         SchemaElementDecl* tempElement = (SchemaElementDecl*) fElemStack.topElement()->fThisElement;
  1770.         SchemaElementDecl::ModelTypes modelType = tempElement->getModelType();
  1771.         if ((modelType == SchemaElementDecl::Mixed_Simple)
  1772.           ||  (modelType == SchemaElementDecl::Mixed_Complex)
  1773.           ||  (modelType == SchemaElementDecl::Children))
  1774.         {
  1775.             cm = tempElement->getContentModel();
  1776.             cv = cm->getContentLeafNameTypeVector();
  1777.             currentScope = fElemStack.getCurrentScope();
  1778.         }
  1779.         else if (modelType == SchemaElementDecl::Any) {
  1780.             laxThisOne = true;
  1781.         }
  1782.     }
  1783.     //  Now, since we might have to update the namespace map for this element,
  1784.     //  but we don't have the element decl yet, we just tell the element stack
  1785.     //  to expand up to get ready.
  1786.     unsigned int elemDepth = fElemStack.addLevel();
  1787.     fElemStack.setValidationFlag(fValidate);
  1788.     //  Check if there is any external schema location specified, and if we are at root,
  1789.     //  go through them first before scanning those specified in the instance document
  1790.     if (isRoot
  1791.         && fDoSchema
  1792.         && (fExternalSchemaLocation || fExternalNoNamespaceSchemaLocation)) {
  1793.         if (fExternalSchemaLocation)
  1794.             parseSchemaLocation(fExternalSchemaLocation);
  1795.         if (fExternalNoNamespaceSchemaLocation)
  1796.             resolveSchemaGrammar(fExternalNoNamespaceSchemaLocation, XMLUni::fgZeroLenString);
  1797.     }
  1798.     //  Make an initial pass through the list and find any xmlns attributes or
  1799.     //  schema attributes.
  1800.     if (attCount)
  1801.       scanRawAttrListforNameSpaces(fRawAttrList, attCount);
  1802.     //  Also find any default or fixed xmlns attributes in DTD defined for
  1803.     //  this element.
  1804.     XMLElementDecl* elemDecl = 0;
  1805.     if (fGrammarType == Grammar::DTDGrammarType) {
  1806.         elemDecl = fGrammar->getElemDecl
  1807.         (
  1808.             fEmptyNamespaceId
  1809.             , 0
  1810.             , fQNameBuf.getRawBuffer()
  1811.             , Grammar::TOP_LEVEL_SCOPE
  1812.         );
  1813.         if (elemDecl) {
  1814.             if (elemDecl->hasAttDefs()) {
  1815.                 XMLAttDefList& attDefList = elemDecl->getAttDefList();
  1816.                 while (attDefList.hasMoreElements())
  1817.                 {
  1818.                     // Get the current att def, for convenience and its def type
  1819.                     const XMLAttDef& curDef = attDefList.nextElement();
  1820.                     const XMLAttDef::DefAttTypes defType = curDef.getDefaultType();
  1821.                     // update the NSMap if there are any default/fixed xmlns attributes
  1822.                     if ((defType == XMLAttDef::Default)
  1823.                     ||  (defType == XMLAttDef::Fixed))
  1824.                     {
  1825.                         const XMLCh* rawPtr = curDef.getFullName();
  1826.                         if (!XMLString::compareNString(rawPtr, XMLUni::fgXMLNSColonString, 6)
  1827.                         ||  XMLString::equals(rawPtr, XMLUni::fgXMLNSString))
  1828.                             updateNSMap(rawPtr, curDef.getValue());
  1829.                     }
  1830.                 }
  1831.             }
  1832.         }
  1833.     }
  1834.     //  Resolve the qualified name to a URI and name so that we can look up
  1835.     //  the element decl for this element. We have now update the prefix to
  1836.     //  namespace map so we should get the correct element now.
  1837.     int prefixColonPos = -1;
  1838.     const XMLCh* qnameRawBuf = fQNameBuf.getRawBuffer();
  1839.     unsigned int uriId = resolveQName
  1840.     (
  1841.         qnameRawBuf
  1842.         , fPrefixBuf
  1843.         , ElemStack::Mode_Element
  1844.         , prefixColonPos
  1845.     );
  1846.     //if schema, check if we should lax or skip the validation of this element
  1847.     bool parentValidation = fValidate;
  1848.     if (cv) {
  1849.         QName element(fPrefixBuf.getRawBuffer(), &qnameRawBuf[prefixColonPos + 1], uriId, fMemoryManager);
  1850.         // elementDepth will be > 0, as cv is only constructed if element is not
  1851.         // root.
  1852.         laxThisOne = laxElementValidation(&element, cv, cm, elemDepth - 1);
  1853.     }
  1854.     //  Look up the element now in the grammar. This will get us back a
  1855.     //  generic element decl object. We tell him to fault one in if he does
  1856.     //  not find it.
  1857.     bool wasAdded = false;
  1858.     bool errorBeforeElementFound = false;
  1859.     bool laxBeforeElementFound = false;
  1860.     const XMLCh* nameRawBuf = &qnameRawBuf[prefixColonPos + 1];
  1861.     const XMLCh* original_uriStr = fGrammar->getTargetNamespace();
  1862.     unsigned orgGrammarUri = fURIStringPool->getId(original_uriStr);
  1863.     if (uriId != fEmptyNamespaceId) {
  1864.         // Check in current grammar before switching if necessary
  1865.         elemDecl = fGrammar->getElemDecl
  1866.         (
  1867.           uriId
  1868.           , nameRawBuf
  1869.           , qnameRawBuf
  1870.           , currentScope
  1871.         );
  1872.         if (!elemDecl && (orgGrammarUri != uriId)) {
  1873.             // not found, switch to the specified grammar
  1874.             const XMLCh* uriStr = getURIText(uriId);
  1875.             bool errorCondition = !switchGrammar(uriStr) && fValidate;
  1876.             if (errorCondition && !laxThisOne)
  1877.             {
  1878.                 fValidator->emitError
  1879.                 (
  1880.                     XMLValid::GrammarNotFound
  1881.                     ,uriStr
  1882.                 );
  1883.                 errorBeforeElementFound = true;
  1884.             }
  1885.             else if(errorCondition)
  1886.                 laxBeforeElementFound = true;
  1887.             elemDecl = fGrammar->getElemDecl
  1888.             (
  1889.               uriId
  1890.               , nameRawBuf
  1891.               , qnameRawBuf
  1892.               , currentScope
  1893.             );
  1894.         }
  1895.         if (!elemDecl && currentScope != Grammar::TOP_LEVEL_SCOPE) {
  1896.             // if not found, then it may be a reference, try TOP_LEVEL_SCOPE
  1897.             elemDecl = fGrammar->getElemDecl
  1898.                        (
  1899.                            uriId
  1900.                            , nameRawBuf
  1901.                            , qnameRawBuf
  1902.                            , Grammar::TOP_LEVEL_SCOPE
  1903.                        );
  1904.             if(!elemDecl) {
  1905.                 // still not found in specified uri
  1906.                 // try emptyNamesapce see if element should be un-qualified.
  1907.                 elemDecl = fGrammar->getElemDecl
  1908.                            (
  1909.                                fEmptyNamespaceId
  1910.                                , nameRawBuf
  1911.                                , qnameRawBuf
  1912.                                , currentScope
  1913.                            );
  1914.                 bool errorCondition = elemDecl && elemDecl->getCreateReason() != XMLElementDecl::JustFaultIn;
  1915.                 if (errorCondition && fValidate) {
  1916.                     fValidator->emitError
  1917.                     (
  1918.                         XMLValid::ElementNotUnQualified
  1919.                         , elemDecl->getFullName()
  1920.                     );
  1921.                     errorBeforeElementFound = true;
  1922.                 }
  1923.                 else if(errorCondition)
  1924.                     laxBeforeElementFound = true;
  1925.             }
  1926.         }
  1927.         if (!elemDecl) {
  1928.             // still not found, fault this in and issue error later
  1929.             // switch back to original grammar first
  1930.             switchGrammar(original_uriStr);
  1931.             elemDecl = fGrammar->putElemDecl(uriId
  1932.                         , nameRawBuf
  1933.                         , fPrefixBuf.getRawBuffer()
  1934.                         , qnameRawBuf
  1935.                         , currentScope
  1936.                         , true);
  1937.             wasAdded = true;
  1938.         }
  1939.     }
  1940.     else if (!elemDecl)
  1941.     {
  1942.         //the element has no prefix,
  1943.         //thus it is either a non-qualified element defined in current targetNS
  1944.         //or an element that is defined in the globalNS
  1945.         //try unqualifed first
  1946.         elemDecl = fGrammar->getElemDecl
  1947.                    (
  1948.                       uriId
  1949.                     , nameRawBuf
  1950.                     , qnameRawBuf
  1951.                     , currentScope
  1952.                     );
  1953.         if (!elemDecl && orgGrammarUri != fEmptyNamespaceId) {
  1954.             //not found, switch grammar and try globalNS
  1955.             bool errorCondition = !switchGrammar(XMLUni::fgZeroLenString) && fValidate;
  1956.             if (errorCondition && !laxThisOne)
  1957.             {
  1958.                 fValidator->emitError
  1959.                 (
  1960.                     XMLValid::GrammarNotFound
  1961.                   , XMLUni::fgZeroLenString
  1962.                 );
  1963.                 errorBeforeElementFound = true;
  1964.             }
  1965.             else if(errorCondition)
  1966.                 laxBeforeElementFound = true;
  1967.             elemDecl = fGrammar->getElemDecl
  1968.             (
  1969.               uriId
  1970.               , nameRawBuf
  1971.               , qnameRawBuf
  1972.               , currentScope
  1973.             );
  1974.         }
  1975.         if (!elemDecl && currentScope != Grammar::TOP_LEVEL_SCOPE) {
  1976.             // if not found, then it may be a reference, try TOP_LEVEL_SCOPE
  1977.             elemDecl = fGrammar->getElemDecl
  1978.                        (
  1979.                            uriId
  1980.                            , nameRawBuf
  1981.                            , qnameRawBuf
  1982.                            , Grammar::TOP_LEVEL_SCOPE
  1983.                        );
  1984.             if (!elemDecl && orgGrammarUri != fEmptyNamespaceId) {
  1985.                 // still Not found in specified uri
  1986.                 // go to original Grammar again to see if element needs to be fully qualified.
  1987.                 const XMLCh* uriStr = getURIText(orgGrammarUri);
  1988.                 bool errorCondition = !switchGrammar(original_uriStr) && fValidate;
  1989.                 if (errorCondition && !laxThisOne)
  1990.                 if (errorCondition && !laxThisOne)
  1991.                 {
  1992.                     fValidator->emitError
  1993.                     (
  1994.                         XMLValid::GrammarNotFound
  1995.                         ,original_uriStr
  1996.                     );
  1997.                     errorBeforeElementFound = true;
  1998.                 }
  1999.                 else if(errorCondition)
  2000.                     laxBeforeElementFound = true;
  2001.                 elemDecl = fGrammar->getElemDecl
  2002.                            (
  2003.                                orgGrammarUri
  2004.                                , nameRawBuf
  2005.                                , qnameRawBuf
  2006.                                , currentScope
  2007.                            );
  2008.                 if (elemDecl && elemDecl->getCreateReason() != XMLElementDecl::JustFaultIn && fValidate) {
  2009.                     fValidator->emitError
  2010.                     (
  2011.                         XMLValid::ElementNotQualified
  2012.                         , elemDecl->getFullName()
  2013.                     );
  2014.                     errorBeforeElementFound = true;
  2015.                 }
  2016.             }
  2017.         }
  2018.         if (!elemDecl) {
  2019.             // still not found, fault this in and issue error later
  2020.             // switch back to original grammar first
  2021.             switchGrammar(original_uriStr);
  2022.             elemDecl = fGrammar->putElemDecl(uriId
  2023.                         , nameRawBuf
  2024.                         , fPrefixBuf.getRawBuffer()
  2025.                         , qnameRawBuf
  2026.                         , currentScope
  2027.                         , true);
  2028.             wasAdded = true;
  2029.         }
  2030.     }
  2031.     //  We do something different here according to whether we found the
  2032.     //  element or not.
  2033.     if (wasAdded)
  2034.     {
  2035.         if (laxThisOne) {
  2036.             fValidate = false;
  2037.             fElemStack.setValidationFlag(fValidate);
  2038.         }
  2039.         else if(fGrammarType == Grammar::SchemaGrammarType && fValidate) {
  2040.             ((SchemaElementDecl *)(elemDecl))->setValidationAttempted(PSVIDefs::FULL);
  2041.         }
  2042.         // If validating then emit an error
  2043.         if (fValidate)
  2044.         {
  2045.             // This is to tell the reuse Validator that this element was
  2046.             // faulted-in, was not an element in the grammar pool originally
  2047.             elemDecl->setCreateReason(XMLElementDecl::JustFaultIn);
  2048.             fValidator->emitError
  2049.             (
  2050.                 XMLValid::ElementNotDefined
  2051.                 , elemDecl->getFullName()
  2052.             );
  2053.             if(fGrammarType == Grammar::SchemaGrammarType)
  2054.                 ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  2055.         }
  2056.     }
  2057.     else
  2058.     {
  2059.         if(!laxBeforeElementFound && fGrammarType == Grammar::SchemaGrammarType) {
  2060.             if (fValidate) {
  2061.                 ((SchemaElementDecl *)(elemDecl))->setValidationAttempted(PSVIDefs::FULL);
  2062.                 ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::VALID);
  2063.             }
  2064.         }
  2065.         // If its not marked declared and validating, then emit an error
  2066.         if (!elemDecl->isDeclared()) {
  2067.             if (laxThisOne) {
  2068.                 fValidate = false;
  2069.                 fElemStack.setValidationFlag(fValidate);
  2070.             }
  2071.             if (fValidate)
  2072.             {
  2073.                 fValidator->emitError
  2074.                 (
  2075.                     XMLValid::ElementNotDefined
  2076.                     , elemDecl->getFullName()
  2077.                 );
  2078.                 if(fGrammarType == Grammar::SchemaGrammarType) {
  2079.                     ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  2080.                     ((SchemaElementDecl *)(elemDecl))->setValidationAttempted(PSVIDefs::FULL);
  2081.                 }
  2082.             }
  2083.         }
  2084.         if (fGrammarType == Grammar::SchemaGrammarType) {
  2085.             ((SchemaElementDecl*)elemDecl)->setXsiComplexTypeInfo(0);
  2086.             ((SchemaElementDecl*)elemDecl)->setXsiSimpleTypeInfo(0);
  2087.         }
  2088.     }
  2089.     if(errorBeforeElementFound && fGrammarType == Grammar::SchemaGrammarType) {
  2090.         ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  2091.     }
  2092.     //  Now we can update the element stack to set the current element
  2093.     //  decl. We expanded the stack above, but couldn't store the element
  2094.     //  decl because we didn't know it yet.
  2095.     fElemStack.setElement(elemDecl, fReaderMgr.getCurrentReaderNum());
  2096.     fElemStack.setCurrentURI(uriId);
  2097.     if (isRoot)
  2098.         fRootGrammar = fGrammar;
  2099.     //  Validate the element
  2100.     if (fValidate)
  2101.         fValidator->validateElement(elemDecl);
  2102.     if (fGrammarType == Grammar::SchemaGrammarType) {
  2103.         ComplexTypeInfo* typeinfo = ((SchemaElementDecl*)elemDecl)->getComplexTypeInfo();
  2104.         if (typeinfo) {
  2105.             currentScope = typeinfo->getScopeDefined();
  2106.             // switch grammar if the typeinfo has a different grammar (happens when there is xsi:type)
  2107.             XMLCh* typeName = typeinfo->getTypeName();
  2108.             const XMLCh poundStr[] = {chPound, chNull};
  2109.             if (!XMLString::startsWith(typeName, poundStr)) {
  2110.                 const int comma = XMLString::indexOf(typeName, chComma);
  2111.                 if (comma > 0) {
  2112.                     XMLBuffer prefixBuf(comma+1, fMemoryManager);
  2113.                     prefixBuf.append(typeName, comma);
  2114.                     const XMLCh* uriStr = prefixBuf.getRawBuffer();
  2115.                     bool errorCondition = !switchGrammar(uriStr) && fValidate;
  2116.                     if (errorCondition && !laxThisOne)
  2117.                     {
  2118.                         fValidator->emitError
  2119.                         (
  2120.                             XMLValid::GrammarNotFound
  2121.                             , prefixBuf.getRawBuffer()
  2122.                         );
  2123.                         if(fGrammarType == Grammar::SchemaGrammarType)
  2124.                             ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  2125.                     }
  2126.                     else if(errorCondition) {
  2127.                         if(fGrammarType == Grammar::SchemaGrammarType) {
  2128.                             ((SchemaElementDecl *)(elemDecl))->setValidationAttempted(PSVIDefs::NONE);
  2129.                             ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::UNKNOWN);
  2130.                         }
  2131.                     }
  2132.                 }
  2133.             }
  2134.         }
  2135.         fElemStack.setCurrentScope(currentScope);
  2136.         // Set element next state
  2137.         if (elemDepth >= fElemStateSize) {
  2138.             resizeElemState();
  2139.         }
  2140.         fElemState[elemDepth] = 0;
  2141.     }
  2142.     fElemStack.setCurrentGrammar(fGrammar);
  2143.     //  If this is the first element and we are validating, check the root
  2144.     //  element.
  2145.     if (isRoot)
  2146.     {
  2147.         if (fValidate)
  2148.         {
  2149.             //  If a DocType exists, then check if it matches the root name there.
  2150.             if (fRootElemName && !XMLString::equals(qnameRawBuf, fRootElemName))
  2151.                 fValidator->emitError(XMLValid::RootElemNotLikeDocType);
  2152.             //  Some validators may also want to check the root, call the
  2153.             //  XMLValidator::checkRootElement
  2154.             if (fValidatorFromUser && !fValidator->checkRootElement(elemDecl->getId()))
  2155.                 fValidator->emitError(XMLValid::RootElemNotLikeDocType);
  2156.             if(fGrammarType == Grammar::SchemaGrammarType)
  2157.                 ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  2158.         }
  2159.     }
  2160.     else if (parentValidation)
  2161.     {
  2162.         //  If the element stack is not empty, then add this element as a
  2163.         //  child of the previous top element. If its empty, this is the root
  2164.         //  elem and is not the child of anything.
  2165.         fElemStack.addChild(elemDecl->getElementName(), true);
  2166.     }
  2167.     //  Now lets get the fAttrList filled in. This involves faulting in any
  2168.     //  defaulted and fixed attributes and normalizing the values of any that
  2169.     //  we got explicitly.
  2170.     //
  2171.     //  We update the attCount value with the total number of attributes, but
  2172.     //  it goes in with the number of values we got during the raw scan of
  2173.     //  explictly provided attrs above.
  2174.     attCount = buildAttList(*fRawAttrList, attCount, elemDecl, *fAttrList);
  2175.     // activate identity constraints
  2176.     if (fValidate && fGrammar && fGrammarType == Grammar::SchemaGrammarType) {
  2177.         unsigned int count = ((SchemaElementDecl*) elemDecl)->getIdentityConstraintCount();
  2178.         if (count || fMatcherStack->getMatcherCount()) {
  2179.             fValueStoreCache->startElement();
  2180.             fMatcherStack->pushContext();
  2181.             fValueStoreCache->initValueStoresFor((SchemaElementDecl*) elemDecl, (int) elemDepth);
  2182.             for (unsigned int i = 0; i < count; i++) {
  2183.                 activateSelectorFor(((SchemaElementDecl*) elemDecl)->getIdentityConstraintAt(i), (int) elemDepth);
  2184.             }
  2185.             // call all active identity constraints
  2186.             count = fMatcherStack->getMatcherCount();
  2187.             for (unsigned int j = 0; j < count; j++) {
  2188.                 XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
  2189.                 matcher->startElement(*elemDecl, uriId, fPrefixBuf.getRawBuffer(), *fAttrList, attCount);
  2190.             }
  2191.         }
  2192.     }
  2193.     // Since the element may have default values, call start tag now regardless if it is empty or not
  2194.     // If we have a document handler, then tell it about this start tag
  2195.     if (fDocHandler)
  2196.     {
  2197.         fDocHandler->startElement
  2198.         (
  2199.             *elemDecl
  2200.             , uriId
  2201.             , fPrefixBuf.getRawBuffer()
  2202.             , *fAttrList
  2203.             , attCount
  2204.             , false
  2205.             , isRoot
  2206.         );
  2207.     }
  2208.     //  If empty, validate content right now if we are validating and then
  2209.     //  pop the element stack top. Else, we have to update the current stack
  2210.     //  top's namespace mapping elements.
  2211.     if (isEmpty)
  2212.     {
  2213.         // Pop the element stack back off since it'll never be used now
  2214.         fElemStack.popTop();
  2215.         // If validating, then insure that its legal to have no content
  2216.         if (fValidate)
  2217.         {
  2218.             const int res = fValidator->checkContent(elemDecl, 0, 0);
  2219.             if (res >= 0)
  2220.             {
  2221.                 fValidator->emitError
  2222.                 (
  2223.                     XMLValid::ElementNotValidForContent
  2224.                     , elemDecl->getFullName()
  2225.                     , elemDecl->getFormattedContentModel()
  2226.                 );
  2227.                 if(fGrammarType == Grammar::SchemaGrammarType)
  2228.                     ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  2229.             }
  2230.             if (fGrammarType == Grammar::SchemaGrammarType) {
  2231.                 // call matchers and de-activate context
  2232.                 int oldCount = fMatcherStack->getMatcherCount();
  2233.                 if (oldCount || ((SchemaElementDecl*) elemDecl)->getIdentityConstraintCount()) {
  2234.                     for (int i = oldCount - 1; i >= 0; i--) {
  2235.                         XPathMatcher* matcher = fMatcherStack->getMatcherAt(i);
  2236.                         matcher->endElement(*elemDecl, fContent.getRawBuffer());
  2237.                     }
  2238.                     if (fMatcherStack->size() > 0) {
  2239.                         fMatcherStack->popContext();
  2240.                     }
  2241.                     // handle everything *but* keyref's.
  2242.                     int newCount = fMatcherStack->getMatcherCount();
  2243.                     for (int j = oldCount - 1; j >= newCount; j--) {
  2244.                         XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
  2245.                         IdentityConstraint* ic = matcher->getIdentityConstraint();
  2246.                         if (ic  && (ic->getType() != IdentityConstraint::KEYREF))
  2247.                             fValueStoreCache->transplant(ic, matcher->getInitialDepth());
  2248.                     }
  2249.                     // now handle keyref's...
  2250.                     for (int k = oldCount - 1; k >= newCount; k--) {
  2251.                         XPathMatcher* matcher = fMatcherStack->getMatcherAt(k);
  2252.                         IdentityConstraint* ic = matcher->getIdentityConstraint();
  2253.                         if (ic && (ic->getType() == IdentityConstraint::KEYREF)) {
  2254.                             ValueStore* values = fValueStoreCache->getValueStoreFor(ic, matcher->getInitialDepth());
  2255.                             if (values) { // nothing to do if nothing matched!
  2256.                                 values->endDcocumentFragment(fValueStoreCache);
  2257.                             }
  2258.                         }
  2259.                     }
  2260.                     fValueStoreCache->endElement();
  2261.                 }
  2262.             }
  2263.         }
  2264.         if(!isRoot && fGrammarType == Grammar::SchemaGrammarType)
  2265.            ((SchemaElementDecl *)fElemStack.topElement()->fThisElement)->updateValidityFromElement(elemDecl, fGrammarType);
  2266.         // If we have a doc handler, tell it about the end tag
  2267.         if (fDocHandler)
  2268.         {
  2269.             fDocHandler->endElement
  2270.             (
  2271.                 *elemDecl
  2272.                 , uriId
  2273.                 , isRoot
  2274.                 , fPrefixBuf.getRawBuffer()
  2275.             );
  2276.         }
  2277.         // reset xsi:type ComplexTypeInfo
  2278.         if (fGrammarType == Grammar::SchemaGrammarType) {
  2279.             ((SchemaElementDecl*)elemDecl)->reset();
  2280.             if (!isRoot)
  2281.                 ((SchemaElementDecl*)(fElemStack.topElement()->fThisElement))->
  2282.                     setXsiComplexTypeInfo(((SchemaValidator*)fValidator)->getCurrentTypeInfo());
  2283.         }
  2284.         // If the elem stack is empty, then it was an empty root
  2285.         if (isRoot)
  2286.             gotData = false;
  2287.         else
  2288.         {
  2289.             // Restore the grammar
  2290.             fGrammar = fElemStack.getCurrentGrammar();
  2291.             fGrammarType = fGrammar->getGrammarType();
  2292.             if (fGrammarType == Grammar::SchemaGrammarType && !fValidator->handlesSchema()) {
  2293.                 if (fValidatorFromUser)
  2294.                     ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
  2295.                 else {
  2296.                     fValidator = fSchemaValidator;
  2297.                 }
  2298.             }
  2299.             else if (fGrammarType == Grammar::DTDGrammarType && !fValidator->handlesDTD()) {
  2300.                 if (fValidatorFromUser)
  2301.                     ThrowXML(RuntimeException, XMLExcepts::Gen_NoDTDValidator);
  2302.                 else {
  2303.                     fValidator = fDTDValidator;
  2304.                 }
  2305.             }
  2306.             fValidator->setGrammar(fGrammar);
  2307.             // Restore the validation flag
  2308.             fValidate = fElemStack.getValidationFlag();
  2309.         }
  2310.     }
  2311.     return true;
  2312. }
  2313. unsigned int
  2314. IGXMLScanner::resolveQName(const   XMLCh* const qName
  2315.                            ,       XMLBuffer&   prefixBuf
  2316.                            , const short        mode
  2317.                            ,       int&         prefixColonPos)
  2318. {
  2319.     //  Lets split out the qName into a URI and name buffer first. The URI
  2320.     //  can be empty.
  2321.     prefixColonPos = XMLString::indexOf(qName, chColon);
  2322.     if (prefixColonPos == -1)
  2323.     {
  2324.         //  Its all name with no prefix, so put the whole thing into the name
  2325.         //  buffer. Then map the empty string to a URI, since the empty string
  2326.         //  represents the default namespace. This will either return some
  2327.         //  explicit URI which the default namespace is mapped to, or the
  2328.         //  the default global namespace.
  2329.         bool unknown = false;
  2330.         prefixBuf.reset();
  2331.         return fElemStack.mapPrefixToURI(XMLUni::fgZeroLenString, (ElemStack::MapModes) mode, unknown);
  2332.     }
  2333.     else
  2334.     {
  2335.         //  Copy the chars up to but not including the colon into the prefix
  2336.         //  buffer.
  2337.         prefixBuf.set(qName, prefixColonPos);
  2338.         //  Watch for the special namespace prefixes. We always map these to
  2339.         //  special URIs. 'xml' gets mapped to the official URI that its defined
  2340.         //  to map to by the NS spec. xmlns gets mapped to a special place holder
  2341.         //  URI that we define (so that it maps to something checkable.)
  2342.         const XMLCh* prefixRawBuf = prefixBuf.getRawBuffer();
  2343.         if (XMLString::equals(prefixRawBuf, XMLUni::fgXMLNSString)) {
  2344.             // if this is an element, it is an error to have xmlns as prefix
  2345.             if (mode == ElemStack::Mode_Element)
  2346.                 emitError(XMLErrs::NoXMLNSAsElementPrefix, qName);
  2347.             return fXMLNSNamespaceId;
  2348.         }
  2349.         else if (XMLString::equals(prefixRawBuf, XMLUni::fgXMLString)) {
  2350.             return  fXMLNamespaceId;
  2351.         }
  2352.         else
  2353.         {
  2354.             bool unknown = false;
  2355.             unsigned int uriId = fElemStack.mapPrefixToURI(prefixRawBuf, (ElemStack::MapModes) mode, unknown);
  2356.             if (unknown)
  2357.                 emitError(XMLErrs::UnknownPrefix, prefixRawBuf);
  2358.             return uriId;
  2359.         }
  2360.     }
  2361. }
  2362. // ---------------------------------------------------------------------------
  2363. //  IGXMLScanner: Helper methos
  2364. // ---------------------------------------------------------------------------
  2365. void IGXMLScanner::resizeElemState() {
  2366.     unsigned int newSize = fElemStateSize * 2;
  2367.     unsigned int* newElemState = (unsigned int*) fMemoryManager->allocate
  2368.     (
  2369.         newSize * sizeof(unsigned int)
  2370.     ); //new unsigned int[newSize];
  2371.     // Copy the existing values
  2372.     unsigned int index = 0;
  2373.     for (; index < fElemStateSize; index++)
  2374.         newElemState[index] = fElemState[index];
  2375.     for (; index < newSize; index++)
  2376.         newElemState[index] = 0;
  2377.     // Delete the old array and udpate our members
  2378.     fMemoryManager->deallocate(fElemState); //delete [] fElemState;
  2379.     fElemState = newElemState;
  2380.     fElemStateSize = newSize;
  2381. }
  2382. // ---------------------------------------------------------------------------
  2383. //  IGXMLScanner: IC activation methos
  2384. // ---------------------------------------------------------------------------
  2385. void IGXMLScanner::activateSelectorFor(IdentityConstraint* const ic, const int initialDepth) {
  2386.     IC_Selector* selector = ic->getSelector();
  2387.     if (!selector)
  2388.         return;
  2389.     XPathMatcher* matcher = selector->createMatcher(fFieldActivator, initialDepth, fMemoryManager);
  2390.     fMatcherStack->addMatcher(matcher);
  2391.     matcher->startDocumentFragment();
  2392. }
  2393. // ---------------------------------------------------------------------------
  2394. //  IGXMLScanner: Grammar preparsing
  2395. // ---------------------------------------------------------------------------
  2396. Grammar* IGXMLScanner::loadGrammar(const   InputSource& src
  2397.                                    , const short        grammarType
  2398.                                    , const bool         toCache)
  2399. {
  2400.     Grammar* loadedGrammar = 0;
  2401.     try
  2402.     {
  2403.         fGrammarResolver->cacheGrammarFromParse(false);
  2404.         fGrammarResolver->useCachedGrammarInParse(false);
  2405.         fRootGrammar = 0;
  2406.         if (fValScheme == Val_Auto) {
  2407.             fValidate = true;
  2408.         }
  2409.         // Reset some status flags
  2410.         fInException = false;
  2411.         fStandalone = false;
  2412.         fErrorCount = 0;
  2413.         fHasNoDTD = true;
  2414.         fSeeXsi = false;
  2415.         if (grammarType == Grammar::SchemaGrammarType) {
  2416.             loadedGrammar = loadXMLSchemaGrammar(src, toCache);
  2417.         }
  2418.         else if (grammarType == Grammar::DTDGrammarType) {
  2419.             loadedGrammar = loadDTDGrammar(src, toCache);
  2420.         }
  2421.         // Reset the reader manager to close all files, sockets, etc...
  2422.         fReaderMgr.reset();
  2423.     }
  2424.     //  NOTE:
  2425.     //
  2426.     //  In all of the error processing below, the emitError() call MUST come
  2427.     //  before the flush of the reader mgr, or it will fail because it tries
  2428.     //  to find out the position in the XML source of the error.
  2429.     catch(const XMLErrs::Codes)
  2430.     {
  2431.         // This is a 'first fatal error' type exit, so reset and fall through
  2432.         fReaderMgr.reset();
  2433.     }
  2434.     catch(const XMLValid::Codes)
  2435.     {
  2436.         // This is a 'first fatal error' type exit, so reset and fall through
  2437.         fReaderMgr.reset();
  2438.     }
  2439.     catch(const XMLException& excToCatch)
  2440.     {
  2441.         //  Emit the error and catch any user exception thrown from here. Make
  2442.         //  sure in all cases we flush the reader manager.
  2443.         fInException = true;
  2444.         try
  2445.         {
  2446.             if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning)
  2447.                 emitError
  2448.                 (
  2449.                     XMLErrs::DisplayErrorMessage
  2450.                     , excToCatch.getMessage()
  2451.                 );
  2452.             else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal)
  2453.                 emitError
  2454.                 (
  2455.                     XMLErrs::XMLException_Fatal
  2456.                     , excToCatch.getType()
  2457.                     , excToCatch.getMessage()
  2458.                 );
  2459.             else
  2460.                 emitError
  2461.                 (
  2462.                     XMLErrs::XMLException_Error
  2463.                     , excToCatch.getType()
  2464.                     , excToCatch.getMessage()
  2465.                 );
  2466.         }
  2467.         catch(...)
  2468.         {
  2469.             // Flush the reader manager and rethrow user's error
  2470.             fReaderMgr.reset();
  2471.             throw;
  2472.         }
  2473.         // If it returned, then reset the reader manager and fall through
  2474.         fReaderMgr.reset();
  2475.     }
  2476.     catch(...)
  2477.     {
  2478.         // Reset and rethrow
  2479.         fReaderMgr.reset();
  2480.         throw;
  2481.     }
  2482.     return loadedGrammar;
  2483. }
  2484. Grammar* IGXMLScanner::loadDTDGrammar(const InputSource& src,
  2485.                                       const bool toCache)
  2486. {
  2487.     // Reset the validators
  2488.     fDTDValidator->reset();
  2489.     if (fValidatorFromUser)
  2490.         fValidator->reset();
  2491.     if (!fValidator->handlesDTD()) {
  2492.         if (fValidatorFromUser && fValidate)
  2493.             ThrowXML(RuntimeException, XMLExcepts::Gen_NoDTDValidator);
  2494.         else {
  2495.             fValidator = fDTDValidator;
  2496.         }
  2497.     }
  2498.     fDTDGrammar = new (fMemoryManager) DTDGrammar(fMemoryManager);
  2499.     fGrammarResolver->putGrammar(XMLUni::fgDTDEntityString, fDTDGrammar);
  2500.     fGrammar = fDTDGrammar;
  2501.     fGrammarType = fGrammar->getGrammarType();
  2502.     fValidator->setGrammar(fGrammar);
  2503.     //  And for all installed handlers, send reset events. This gives them
  2504.     //  a chance to flush any cached data.
  2505.     if (fDocHandler)
  2506.         fDocHandler->resetDocument();
  2507.     if (fEntityHandler)
  2508.         fEntityHandler->resetEntities();
  2509.     if (fErrorReporter)
  2510.         fErrorReporter->resetErrors();
  2511.     // Clear out the id reference list
  2512.     fIDRefList->removeAll();
  2513.     if (toCache) {
  2514.         unsigned int sysId = fGrammarResolver->getStringPool()->addOrFind(src.getSystemId());
  2515.         const XMLCh* sysIdStr = fGrammarResolver->getStringPool()->getValueForId(sysId);
  2516.         fGrammarResolver->orphanGrammar(XMLUni::fgDTDEntityString);
  2517.         fGrammarResolver->putGrammar(sysIdStr, fGrammar);
  2518.     }
  2519.     //  Handle the creation of the XML reader object for this input source.
  2520.     //  This will provide us with transcoding and basic lexing services.
  2521.     XMLReader* newReader = fReaderMgr.createReader
  2522.     (
  2523.         src
  2524.         , false
  2525.         , XMLReader::RefFrom_NonLiteral
  2526.         , XMLReader::Type_General
  2527.         , XMLReader::Source_External
  2528.         , fCalculateSrcOfs
  2529.     );
  2530.     if (!newReader) {
  2531.         if (src.getIssueFatalErrorIfNotFound())
  2532.             ThrowXML1(RuntimeException, XMLExcepts::Scan_CouldNotOpenSource, src.getSystemId());
  2533.         else
  2534.             ThrowXML1(RuntimeException, XMLExcepts::Scan_CouldNotOpenSource_Warning, src.getSystemId());
  2535.     }
  2536.     //  In order to make the processing work consistently, we have to
  2537.     //  make this look like an external entity. So create an entity
  2538.     //  decl and fill it in and push it with the reader, as happens
  2539.     //  with an external entity. Put a janitor on it to insure it gets
  2540.     //  cleaned up. The reader manager does not adopt them.
  2541.     const XMLCh gDTDStr[] = { chLatin_D, chLatin_T, chLatin_D , chNull };
  2542.     DTDEntityDecl* declDTD = new (fMemoryManager) DTDEntityDecl(gDTDStr, false, fMemoryManager);
  2543.     declDTD->setSystemId(src.getSystemId());
  2544.     Janitor<DTDEntityDecl> janDecl(declDTD);
  2545.     // Mark this one as a throw at end
  2546.     newReader->setThrowAtEnd(true);
  2547.     // And push it onto the stack, with its pseudo name
  2548.     fReaderMgr.pushReader(newReader, declDTD);
  2549.     //  If we have a doc type handler and advanced callbacks are enabled,
  2550.     //  call the doctype event.
  2551.     if (fDocTypeHandler) {
  2552.         // Create a dummy root
  2553.         DTDElementDecl* rootDecl = new (fMemoryManager) DTDElementDecl
  2554.         (
  2555.             gDTDStr
  2556.             , fEmptyNamespaceId
  2557.             , DTDElementDecl::Any
  2558.             , fMemoryManager
  2559.         );
  2560.         rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
  2561.         rootDecl->setExternalElemDeclaration(true);
  2562.         Janitor<DTDElementDecl> janSrc(rootDecl);
  2563.         fDocTypeHandler->doctypeDecl(*rootDecl, src.getPublicId(), src.getSystemId(), false, true);
  2564.     }
  2565.     // Create DTDScanner
  2566.     DTDScanner dtdScanner
  2567.     (
  2568.         (DTDGrammar*) fGrammar
  2569.         , fDocTypeHandler
  2570.         , fMemoryManager
  2571.     );
  2572.     dtdScanner.setScannerInfo(this, &fReaderMgr, &fBufMgr);
  2573.     // Tell it its not in an include section
  2574.     dtdScanner.scanExtSubsetDecl(false, true);
  2575.     if (fValidate) {
  2576.         //  validate the DTD scan so far
  2577.         fValidator->preContentValidation(false, true);
  2578.     }
  2579.     if (toCache)
  2580.         fGrammarResolver->cacheGrammars();
  2581.     return fDTDGrammar;
  2582. }
  2583. XERCES_CPP_NAMESPACE_END