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

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2002, 2003 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: SGXMLScanner.cpp,v 1.26 2003/05/18 14:02:04 knoaman Exp $
  58.  */
  59. // ---------------------------------------------------------------------------
  60. //  Includes
  61. // ---------------------------------------------------------------------------
  62. #include <xercesc/internal/SGXMLScanner.hpp>
  63. #include <xercesc/util/RuntimeException.hpp>
  64. #include <xercesc/util/UnexpectedEOFException.hpp>
  65. #include <xercesc/framework/LocalFileInputSource.hpp>
  66. #include <xercesc/framework/URLInputSource.hpp>
  67. #include <xercesc/framework/XMLDocumentHandler.hpp>
  68. #include <xercesc/framework/XMLEntityHandler.hpp>
  69. #include <xercesc/framework/XMLPScanToken.hpp>
  70. #include <xercesc/framework/MemoryManager.hpp>
  71. #include <xercesc/internal/EndOfEntityException.hpp>
  72. #include <xercesc/validators/common/ContentLeafNameTypeVector.hpp>
  73. #include <xercesc/validators/schema/SchemaValidator.hpp>
  74. #include <xercesc/validators/schema/TraverseSchema.hpp>
  75. #include <xercesc/validators/schema/XSDDOMParser.hpp>
  76. #include <xercesc/validators/schema/SubstitutionGroupComparator.hpp>
  77. #include <xercesc/validators/schema/identity/FieldActivator.hpp>
  78. #include <xercesc/validators/schema/identity/XPathMatcherStack.hpp>
  79. #include <xercesc/validators/schema/identity/ValueStoreCache.hpp>
  80. #include <xercesc/validators/schema/identity/IC_Selector.hpp>
  81. #include <xercesc/validators/schema/identity/ValueStore.hpp>
  82. XERCES_CPP_NAMESPACE_BEGIN
  83. // ---------------------------------------------------------------------------
  84. //  SGXMLScanner: Constructors and Destructor
  85. // ---------------------------------------------------------------------------
  86. SGXMLScanner::SGXMLScanner( XMLValidator* const valToAdopt
  87.                           , MemoryManager* const manager) :
  88.     XMLScanner(valToAdopt, manager)
  89.     , fSeeXsi(false)
  90.     , fElemStateSize(16)
  91.     , fElemState(0)
  92.     , fElemStack(manager)
  93.     , fContent(1023, manager)
  94.     , fEntityTable(0)
  95.     , fRawAttrList(0)
  96.     , fSchemaValidator(0)
  97.     , fMatcherStack(0)
  98.     , fValueStoreCache(0)
  99.     , fFieldActivator(0)
  100. {
  101.     try
  102.     {
  103.          commonInit();
  104.          if (valToAdopt)
  105.          {
  106.              if (!valToAdopt->handlesSchema())
  107.                 ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
  108.          }
  109.          else
  110.          {
  111.              fValidator = fSchemaValidator;
  112.          }
  113.     }
  114.     catch(...)
  115.     {
  116.         cleanUp();
  117.         throw;
  118.     }
  119. }
  120. SGXMLScanner::SGXMLScanner( XMLDocumentHandler* const docHandler
  121.                           , DocTypeHandler* const     docTypeHandler
  122.                           , XMLEntityHandler* const   entityHandler
  123.                           , XMLErrorReporter* const   errHandler
  124.                           , XMLValidator* const       valToAdopt
  125.                           , MemoryManager* const      manager) :
  126.     XMLScanner(docHandler, docTypeHandler, entityHandler, errHandler, valToAdopt, manager)
  127.     , fSeeXsi(false)
  128.     , fElemStateSize(16)
  129.     , fElemState(0)
  130.     , fElemStack(manager)
  131.     , fContent(1023, manager)
  132.     , fEntityTable(0)
  133.     , fRawAttrList(0)
  134.     , fSchemaValidator(0)
  135.     , fMatcherStack(0)
  136.     , fValueStoreCache(0)
  137.     , fFieldActivator(0)
  138. {
  139.     try
  140.     {
  141.         commonInit();
  142.          if (valToAdopt)
  143.          {
  144.              if (!valToAdopt->handlesSchema())
  145.                 ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
  146.          }
  147.          else
  148.          {
  149.              fValidator = fSchemaValidator;
  150.          }
  151.     }
  152.     catch(...)
  153.     {
  154.         cleanUp();
  155.         throw;
  156.     }
  157. }
  158. SGXMLScanner::~SGXMLScanner()
  159. {
  160.     cleanUp();
  161. }
  162. // ---------------------------------------------------------------------------
  163. //  XMLScanner: Getter methods
  164. // ---------------------------------------------------------------------------
  165. NameIdPool<DTDEntityDecl>* SGXMLScanner::getEntityDeclPool()
  166. {
  167.     return 0;
  168. }
  169. const NameIdPool<DTDEntityDecl>* SGXMLScanner::getEntityDeclPool() const
  170. {
  171.     return 0;
  172. }
  173. // ---------------------------------------------------------------------------
  174. //  SGXMLScanner: Main entry point to scan a document
  175. // ---------------------------------------------------------------------------
  176. void SGXMLScanner::scanDocument(const InputSource& src)
  177. {
  178.     //  Bump up the sequence id for this parser instance. This will invalidate
  179.     //  any previous progressive scan tokens.
  180.     fSequenceId++;
  181.     try
  182.     {
  183.         //  Reset the scanner and its plugged in stuff for a new run. This
  184.         //  resets all the data structures, creates the initial reader and
  185.         //  pushes it on the stack, and sets up the base document path.
  186.         scanReset(src);
  187.         // If we have a document handler, then call the start document
  188.         if (fDocHandler)
  189.             fDocHandler->startDocument();
  190.         //  Scan the prolog part, which is everything before the root element
  191.         //  including the DTD subsets.
  192.         scanProlog();
  193.         //  If we got to the end of input, then its not a valid XML file.
  194.         //  Else, go on to scan the content.
  195.         if (fReaderMgr.atEOF())
  196.         {
  197.             emitError(XMLErrs::EmptyMainEntity);
  198.         }
  199.         else
  200.         {
  201.             // Scan content, and tell it its not an external entity
  202.             if (scanContent(false))
  203.             {
  204.                 // Do post-parse validation if required
  205.                 if (fValidate)
  206.                 {
  207.                     //  We handle ID reference semantics at this level since
  208.                     //  its required by XML 1.0.
  209.                     checkIDRefs();
  210.                     // Then allow the validator to do any extra stuff it wants
  211. //                    fValidator->postParseValidation();
  212.                 }
  213.                 // That went ok, so scan for any miscellaneous stuff
  214.                 if (!fReaderMgr.atEOF())
  215.                     scanMiscellaneous();
  216.             }
  217.         }
  218.         // If we have a document handler, then call the end document
  219.         if (fDocHandler)
  220.             fDocHandler->endDocument();
  221.         // Reset the reader manager to close all files, sockets, etc...
  222.         fReaderMgr.reset();
  223.     }
  224.     //  NOTE:
  225.     //
  226.     //  In all of the error processing below, the emitError() call MUST come
  227.     //  before the flush of the reader mgr, or it will fail because it tries
  228.     //  to find out the position in the XML source of the error.
  229.     catch(const XMLErrs::Codes)
  230.     {
  231.         // This is a 'first fatal error' type exit, so reset and fall through
  232.         fReaderMgr.reset();
  233.     }
  234.     catch(const XMLValid::Codes)
  235.     {
  236.         // This is a 'first fatal error' type exit, so reset and fall through
  237.         fReaderMgr.reset();
  238.     }
  239.     catch(const XMLException& excToCatch)
  240.     {
  241.         //  Emit the error and catch any user exception thrown from here. Make
  242.         //  sure in all cases we flush the reader manager.
  243.         fInException = true;
  244.         try
  245.         {
  246.             if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning)
  247.                 emitError
  248.                 (
  249.                     XMLErrs::XMLException_Warning
  250.                     , excToCatch.getType()
  251.                     , excToCatch.getMessage()
  252.                 );
  253.             else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal)
  254.                 emitError
  255.                 (
  256.                     XMLErrs::XMLException_Fatal
  257.                     , excToCatch.getType()
  258.                     , excToCatch.getMessage()
  259.                 );
  260.             else
  261.                 emitError
  262.                 (
  263.                     XMLErrs::XMLException_Error
  264.                     , excToCatch.getType()
  265.                     , excToCatch.getMessage()
  266.                 );
  267.         }
  268.         catch(...)
  269.         {
  270.             // Flush the reader manager and rethrow user's error
  271.             fReaderMgr.reset();
  272.             throw;
  273.         }
  274.         // If it returned, then reset the reader manager and fall through
  275.         fReaderMgr.reset();
  276.     }
  277.     catch(...)
  278.     {
  279.         // Reset and rethrow
  280.         fReaderMgr.reset();
  281.         throw;
  282.     }
  283. }
  284. bool SGXMLScanner::scanNext(XMLPScanToken& token)
  285. {
  286.     // Make sure this token is still legal
  287.     if (!isLegalToken(token))
  288.         ThrowXML(RuntimeException, XMLExcepts::Scan_BadPScanToken);
  289.     // Find the next token and remember the reader id
  290.     unsigned int orgReader;
  291.     XMLTokens curToken;
  292.     bool retVal = true;
  293.     try
  294.     {
  295.         while (true)
  296.         {
  297.             //  We have to handle any end of entity exceptions that happen here.
  298.             //  We could be at the end of X nested entities, each of which will
  299.             //  generate an end of entity exception as we try to move forward.
  300.             try
  301.             {
  302.                 curToken = senseNextToken(orgReader);
  303.                 break;
  304.             }
  305.             catch(const EndOfEntityException& toCatch)
  306.             {
  307.                 // Send an end of entity reference event
  308.                 if (fDocHandler)
  309.                     fDocHandler->endEntityReference(toCatch.getEntity());
  310.             }
  311.         }
  312.         if (curToken == Token_CharData)
  313.         {
  314.             scanCharData(fCDataBuf);
  315.         }
  316.         else if (curToken == Token_EOF)
  317.         {
  318.             if (!fElemStack.isEmpty())
  319.             {
  320.                 const ElemStack::StackElem* topElem = fElemStack.popTop();
  321.                 emitError
  322.                 (
  323.                     XMLErrs::EndedWithTagsOnStack
  324.                     , topElem->fThisElement->getFullName()
  325.                 );
  326.             }
  327.             retVal = false;
  328.         }
  329.         else
  330.         {
  331.             // Its some sort of markup
  332.             bool gotData = true;
  333.             switch(curToken)
  334.             {
  335.                 case Token_CData :
  336.                     // Make sure we are within content
  337.                     if (fElemStack.isEmpty())
  338.                         emitError(XMLErrs::CDATAOutsideOfContent);
  339.                     scanCDSection();
  340.                     break;
  341.                 case Token_Comment :
  342.                     scanComment();
  343.                     break;
  344.                 case Token_EndTag :
  345.                     scanEndTag(gotData);
  346.                     break;
  347.                 case Token_PI :
  348.                     scanPI();
  349.                     break;
  350.                 case Token_StartTag :
  351.                     scanStartTag(gotData);
  352.                     break;
  353.                 default :
  354.                     fReaderMgr.skipToChar(chOpenAngle);
  355.                     break;
  356.             }
  357.             if (orgReader != fReaderMgr.getCurrentReaderNum())
  358.                 emitError(XMLErrs::PartialMarkupInEntity);
  359.             // If we hit the end, then do the miscellaneous part
  360.             if (!gotData)
  361.             {
  362.                 // Do post-parse validation if required
  363.                 if (fValidate)
  364.                 {
  365.                     //  We handle ID reference semantics at this level since
  366.                     //  its required by XML 1.0.
  367.                     checkIDRefs();
  368.                     // Then allow the validator to do any extra stuff it wants
  369. //                    fValidator->postParseValidation();
  370.                 }
  371.                 // That went ok, so scan for any miscellaneous stuff
  372.                 scanMiscellaneous();
  373.                 if (fValidate)
  374.                     fValueStoreCache->endDocument();
  375.                 if (fDocHandler)
  376.                     fDocHandler->endDocument();
  377.             }
  378.         }
  379.     }
  380.     //  NOTE:
  381.     //
  382.     //  In all of the error processing below, the emitError() call MUST come
  383.     //  before the flush of the reader mgr, or it will fail because it tries
  384.     //  to find out the position in the XML source of the error.
  385.     catch(const XMLErrs::Codes)
  386.     {
  387.         // This is a 'first failure' exception, so reset and return failure
  388.         fReaderMgr.reset();
  389.         return false;
  390.     }
  391.     catch(const XMLValid::Codes)
  392.     {
  393.         // This is a 'first fatal error' type exit, so reset and reuturn failure
  394.         fReaderMgr.reset();
  395.         return false;
  396.     }
  397.     catch(const XMLException& excToCatch)
  398.     {
  399.         //  Emit the error and catch any user exception thrown from here. Make
  400.         //  sure in all cases we flush the reader manager.
  401.         fInException = true;
  402.         try
  403.         {
  404.             if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning)
  405.                 emitError
  406.                 (
  407.                     XMLErrs::XMLException_Warning
  408.                     , excToCatch.getType()
  409.                     , excToCatch.getMessage()
  410.                 );
  411.             else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal)
  412.                 emitError
  413.                 (
  414.                     XMLErrs::XMLException_Fatal
  415.                     , excToCatch.getType()
  416.                     , excToCatch.getMessage()
  417.                 );
  418.             else
  419.                 emitError
  420.                 (
  421.                     XMLErrs::XMLException_Error
  422.                     , excToCatch.getType()
  423.                     , excToCatch.getMessage()
  424.                 );
  425.         }
  426.         catch(...)
  427.         {
  428.             // Reset and rethrow user error
  429.             fReaderMgr.reset();
  430.             throw;
  431.         }
  432.         // Reset and return failure
  433.         fReaderMgr.reset();
  434.         return false;
  435.     }
  436.     catch(...)
  437.     {
  438.         // Reset and rethrow original error
  439.         fReaderMgr.reset();
  440.         throw;
  441.     }
  442.     // If we hit the end, then flush the reader manager
  443.     if (!retVal)
  444.         fReaderMgr.reset();
  445.     return retVal;
  446. }
  447. // ---------------------------------------------------------------------------
  448. //  SGXMLScanner: Private scanning methods
  449. // ---------------------------------------------------------------------------
  450. //  This method is called from scanStartTag() to handle the very raw initial
  451. //  scan of the attributes. It just fills in the passed collection with
  452. //  key/value pairs for each attribute. No processing is done on them at all.
  453. unsigned int
  454. SGXMLScanner::rawAttrScan(const   XMLCh* const                elemName
  455.                           ,       RefVectorOf<KVStringPair>&  toFill
  456.                           ,       bool&                       isEmpty)
  457. {
  458.     //  Keep up with how many attributes we've seen so far, and how many
  459.     //  elements are available in the vector. This way we can reuse old
  460.     //  elements until we run out and then expand it.
  461.     unsigned int attCount = 0;
  462.     unsigned int curVecSize = toFill.size();
  463.     // Assume it is not empty
  464.     isEmpty = false;
  465.     //  We loop until we either see a /> or >, handling key/value pairs util
  466.     //  we get there. We place them in the passed vector, which we will expand
  467.     //  as required to hold them.
  468.     while (true)
  469.     {
  470.         // Get the next character, which should be non-space
  471.         XMLCh nextCh = fReaderMgr.peekNextChar();
  472.         //  If the next character is not a slash or closed angle bracket,
  473.         //  then it must be whitespace, since whitespace is required
  474.         //  between the end of the last attribute and the name of the next
  475.         //  one.
  476.         //
  477.         if (attCount)
  478.         {
  479.             if ((nextCh != chForwardSlash) && (nextCh != chCloseAngle))
  480.             {
  481.                 if (fReaderMgr.getCurrentReader()->isWhitespace(nextCh))
  482.                 {
  483.                     // Ok, skip by them and get another char
  484.                     fReaderMgr.getNextChar();
  485.                     fReaderMgr.skipPastSpaces();
  486.                     nextCh = fReaderMgr.peekNextChar();
  487.                 }
  488.                  else
  489.                 {
  490.                     // Emit the error but keep on going
  491.                     emitError(XMLErrs::ExpectedWhitespace);
  492.                 }
  493.             }
  494.         }
  495.         //  Ok, here we first check for any of the special case characters.
  496.         //  If its not one, then we do the normal case processing, which
  497.         //  assumes that we've hit an attribute value, Otherwise, we do all
  498.         //  the special case checks.
  499.         if (!fReaderMgr.getCurrentReader()->isSpecialStartTagChar(nextCh))
  500.         {
  501.             //  Assume its going to be an attribute, so get a name from
  502.             //  the input.
  503.             if (!fReaderMgr.getName(fAttNameBuf))
  504.             {
  505.                 emitError(XMLErrs::ExpectedAttrName);
  506.                 fReaderMgr.skipPastChar(chCloseAngle);
  507.                 return attCount;
  508.             }
  509.             // And next must be an equal sign
  510.             if (!scanEq())
  511.             {
  512.                 static const XMLCh tmpList[] =
  513.                 {
  514.                     chSingleQuote, chDoubleQuote, chCloseAngle
  515.                     , chOpenAngle, chForwardSlash, chNull
  516.                 };
  517.                 emitError(XMLErrs::ExpectedEqSign);
  518.                 //  Try to sync back up by skipping forward until we either
  519.                 //  hit something meaningful.
  520.                 const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);
  521.                 if ((chFound == chCloseAngle) || (chFound == chForwardSlash))
  522.                 {
  523.                     // Jump back to top for normal processing of these
  524.                     continue;
  525.                 }
  526.                 else if ((chFound == chSingleQuote)
  527.                       ||  (chFound == chDoubleQuote)
  528.                       ||  fReaderMgr.getCurrentReader()->isWhitespace(chFound))
  529.                 {
  530.                     // Just fall through assuming that the value is to follow
  531.                 }
  532.                 else if (chFound == chOpenAngle)
  533.                 {
  534.                     // Assume a malformed tag and that new one is starting
  535.                     emitError(XMLErrs::UnterminatedStartTag, elemName);
  536.                     return attCount;
  537.                 }
  538.                 else
  539.                 {
  540.                     // Something went really wrong
  541.                     return attCount;
  542.                 }
  543.             }
  544.             //  Next should be the quoted attribute value. We just do a simple
  545.             //  and stupid scan of this value. The only thing we do here
  546.             //  is to expand entity references.
  547.             if (!basicAttrValueScan(fAttNameBuf.getRawBuffer(), fAttValueBuf))
  548.             {
  549.                 static const XMLCh tmpList[] =
  550.                 {
  551.                     chCloseAngle, chOpenAngle, chForwardSlash, chNull
  552.                 };
  553.                 emitError(XMLErrs::ExpectedAttrValue);
  554.                 //  It failed, so lets try to get synced back up. We skip
  555.                 //  forward until we find some whitespace or one of the
  556.                 //  chars in our list.
  557.                 const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);
  558.                 if ((chFound == chCloseAngle)
  559.                 ||  (chFound == chForwardSlash)
  560.                 ||  fReaderMgr.getCurrentReader()->isWhitespace(chFound))
  561.                 {
  562.                     //  Just fall through and process this attribute, though
  563.                     //  the value will be "".
  564.                 }
  565.                 else if (chFound == chOpenAngle)
  566.                 {
  567.                     // Assume a malformed tag and that new one is starting
  568.                     emitError(XMLErrs::UnterminatedStartTag, elemName);
  569.                     return attCount;
  570.                 }
  571.                 else
  572.                 {
  573.                     // Something went really wrong
  574.                     return attCount;
  575.                 }
  576.             }
  577.             //  Make sure that the name is basically well formed for namespace
  578.             //  enabled rules. It either has no colons, or it has one which
  579.             //  is neither the first or last char.
  580.             const int colonFirst = XMLString::indexOf(fAttNameBuf.getRawBuffer(), chColon);
  581.             if (colonFirst != -1)
  582.             {
  583.                 const int colonLast = XMLString::lastIndexOf(fAttNameBuf.getRawBuffer(), chColon);
  584.                 if (colonFirst != colonLast)
  585.                 {
  586.                     emitError(XMLErrs::TooManyColonsInName);
  587.                     continue;
  588.                 }
  589.                 else if ((colonFirst == 0)
  590.                       ||  (colonLast == (int)fAttNameBuf.getLen() - 1))
  591.                 {
  592.                     emitError(XMLErrs::InvalidColonPos);
  593.                     continue;
  594.                 }
  595.             }
  596.             //  And now lets add it to the passed collection. If we have not
  597.             //  filled it up yet, then we use the next element. Else we add
  598.             //  a new one.
  599.             KVStringPair* curPair = 0;
  600.             if (attCount >= curVecSize)
  601.             {
  602.                 curPair = new (fMemoryManager) KVStringPair
  603.                 (
  604.                     fAttNameBuf.getRawBuffer()
  605.                     , fAttValueBuf.getRawBuffer()
  606.                     , fMemoryManager
  607.                 );
  608.                 toFill.addElement(curPair);
  609.             }
  610.              else
  611.             {
  612.                 curPair = toFill.elementAt(attCount);
  613.                 curPair->set(fAttNameBuf.getRawBuffer(), fAttValueBuf.getRawBuffer());
  614.             }
  615.             // And bump the count of attributes we've gotten
  616.             attCount++;
  617.             // And go to the top again for another attribute
  618.             continue;
  619.         }
  620.         //  It was some special case character so do all of the checks and
  621.         //  deal with it.
  622.         if (!nextCh)
  623.             ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
  624.         if (nextCh == chForwardSlash)
  625.         {
  626.             fReaderMgr.getNextChar();
  627.             isEmpty = true;
  628.             if (!fReaderMgr.skippedChar(chCloseAngle))
  629.                 emitError(XMLErrs::UnterminatedStartTag, elemName);
  630.             break;
  631.         }
  632.         else if (nextCh == chCloseAngle)
  633.         {
  634.             fReaderMgr.getNextChar();
  635.             break;
  636.         }
  637.         else if (nextCh == chOpenAngle)
  638.         {
  639.             //  Check for this one specially, since its going to be common
  640.             //  and it is kind of auto-recovering since we've already hit the
  641.             //  next open bracket, which is what we would have seeked to (and
  642.             //  skipped this whole tag.)
  643.             emitError(XMLErrs::UnterminatedStartTag, elemName);
  644.             break;
  645.         }
  646.         else if ((nextCh == chSingleQuote) || (nextCh == chDoubleQuote))
  647.         {
  648.             //  Check for this one specially, which is probably a missing
  649.             //  attribute name, e.g. ="value". Just issue expected name
  650.             //  error and eat the quoted string, then jump back to the
  651.             //  top again.
  652.             emitError(XMLErrs::ExpectedAttrName);
  653.             fReaderMgr.getNextChar();
  654.             fReaderMgr.skipQuotedString(nextCh);
  655.             fReaderMgr.skipPastSpaces();
  656.             continue;
  657.         }
  658.     }
  659.     return attCount;
  660. }
  661. //  This method will kick off the scanning of the primary content of the
  662. //  document, i.e. the elements.
  663. bool SGXMLScanner::scanContent(const bool extEntity)
  664. {
  665.     //  Go into a loop until we hit the end of the root element, or we fall
  666.     //  out because there is no root element.
  667.     //
  668.     //  We have to do kind of a deeply nested double loop here in order to
  669.     //  avoid doing the setup/teardown of the exception handler on each
  670.     //  round. Doing it this way we only do it when an exception actually
  671.     //  occurs.
  672.     bool gotData = true;
  673.     bool inMarkup = false;
  674.     while (gotData)
  675.     {
  676.         try
  677.         {
  678.             while (gotData)
  679.             {
  680.                 //  Sense what the next top level token is. According to what
  681.                 //  this tells us, we will call something to handle that kind
  682.                 //  of thing.
  683.                 unsigned int orgReader;
  684.                 const XMLTokens curToken = senseNextToken(orgReader);
  685.                 //  Handle character data and end of file specially. Char data
  686.                 //  is not markup so we don't want to handle it in the loop
  687.                 //  below.
  688.                 if (curToken == Token_CharData)
  689.                 {
  690.                     //  Scan the character data and call appropriate events. Let
  691.                     //  him use our local character data buffer for efficiency.
  692.                     scanCharData(fCDataBuf);
  693.                     continue;
  694.                 }
  695.                 else if (curToken == Token_EOF)
  696.                 {
  697.                     //  The element stack better be empty at this point or we
  698.                     //  ended prematurely before all elements were closed.
  699.                     if (!fElemStack.isEmpty())
  700.                     {
  701.                         const ElemStack::StackElem* topElem = fElemStack.popTop();
  702.                         emitError
  703.                         (
  704.                             XMLErrs::EndedWithTagsOnStack
  705.                             , topElem->fThisElement->getFullName()
  706.                         );
  707.                     }
  708.                     // Its the end of file, so clear the got data flag
  709.                     gotData = false;
  710.                     continue;
  711.                 }
  712.                 // We are in some sort of markup now
  713.                 inMarkup = true;
  714.                 //  According to the token we got, call the appropriate
  715.                 //  scanning method.
  716.                 switch(curToken)
  717.                 {
  718.                     case Token_CData :
  719.                         // Make sure we are within content
  720.                         if (fElemStack.isEmpty())
  721.                             emitError(XMLErrs::CDATAOutsideOfContent);
  722.                         scanCDSection();
  723.                         break;
  724.                     case Token_Comment :
  725.                         scanComment();
  726.                         break;
  727.                     case Token_EndTag :
  728.                         scanEndTag(gotData);
  729.                         break;
  730.                     case Token_PI :
  731.                         scanPI();
  732.                         break;
  733.                     case Token_StartTag :
  734.                         scanStartTag(gotData);
  735.                         break;
  736.                     default :
  737.                         fReaderMgr.skipToChar(chOpenAngle);
  738.                         break;
  739.                 }
  740.                 if (orgReader != fReaderMgr.getCurrentReaderNum())
  741.                     emitError(XMLErrs::PartialMarkupInEntity);
  742.                 // And we are back out of markup again
  743.                 inMarkup = false;
  744.             }
  745.         }
  746.         catch(const EndOfEntityException& toCatch)
  747.         {
  748.             //  If we were in some markup when this happened, then its a
  749.             //  partial markup error.
  750.             if (inMarkup)
  751.                 emitError(XMLErrs::PartialMarkupInEntity);
  752.             // Send an end of entity reference event
  753.             if (fDocHandler)
  754.                 fDocHandler->endEntityReference(toCatch.getEntity());
  755.             inMarkup = false;
  756.         }
  757.     }
  758.     // It went ok, so return success
  759.     return true;
  760. }
  761. void SGXMLScanner::scanEndTag(bool& gotData)
  762. {
  763.     //  Assume we will still have data until proven otherwise. It will only
  764.     //  ever be false if this is the end of the root element.
  765.     gotData = true;
  766.     //  Check if the element stack is empty. If so, then this is an unbalanced
  767.     //  element (i.e. more ends than starts, perhaps because of bad text
  768.     //  causing one to be skipped.)
  769.     if (fElemStack.isEmpty())
  770.     {
  771.         emitError(XMLErrs::MoreEndThanStartTags);
  772.         fReaderMgr.skipPastChar(chCloseAngle);
  773.         ThrowXML(RuntimeException, XMLExcepts::Scan_UnbalancedStartEnd);
  774.     }
  775.     // After the </ is the element QName, so get a name from the input
  776.     if (!fReaderMgr.getName(fQNameBuf))
  777.     {
  778.         // It failed so we can't really do anything with it
  779.         emitError(XMLErrs::ExpectedElementName);
  780.         fReaderMgr.skipPastChar(chCloseAngle);
  781.         return;
  782.     }
  783.     int prefixColonPos = -1;
  784.     unsigned int uriId = resolveQName
  785.     (
  786.         fQNameBuf.getRawBuffer()
  787.         , fPrefixBuf
  788.         , ElemStack::Mode_Element
  789.         , prefixColonPos
  790.     );
  791.     //  Pop the stack of the element we are supposed to be ending. Remember
  792.     //  that we don't own this. The stack just keeps them and reuses them.
  793.     //
  794.     //  NOTE: We CANNOT do this until we've resolved the element name because
  795.     //  the element stack top contains the prefix to URI mappings for this
  796.     //  element.
  797.     unsigned int topUri = fElemStack.getCurrentURI();
  798.     const ElemStack::StackElem* topElem = fElemStack.popTop();
  799.     // See if it was the root element, to avoid multiple calls below
  800.     const bool isRoot = fElemStack.isEmpty();
  801.     // Make sure that its the end of the element that we expect
  802.     XMLElementDecl* tempElement = topElem->fThisElement;
  803.     const XMLCh* rawNameBuf = fQNameBuf.getRawBuffer();
  804.     if ((topUri != uriId) ||
  805.         (!XMLString::equals(tempElement->getBaseName(), &rawNameBuf[prefixColonPos + 1])))
  806.     {
  807.         emitError
  808.         (
  809.             XMLErrs::ExpectedEndOfTagX
  810.             , topElem->fThisElement->getFullName()
  811.         );
  812.     }
  813.     // Make sure we are back on the same reader as where we started
  814.     if (topElem->fReaderNum != fReaderMgr.getCurrentReaderNum())
  815.         emitError(XMLErrs::PartialTagMarkupError);
  816.     // Skip optional whitespace
  817.     fReaderMgr.skipPastSpaces();
  818.     // Make sure we find the closing bracket
  819.     if (!fReaderMgr.skippedChar(chCloseAngle))
  820.     {
  821.         emitError
  822.         (
  823.             XMLErrs::UnterminatedEndTag
  824.             , topElem->fThisElement->getFullName()
  825.         );
  826.     }
  827.     //  If validation is enabled, then lets pass him the list of children and
  828.     //  this element and let him validate it.
  829.     if (fValidate)
  830.     {
  831.         int res = fValidator->checkContent
  832.         (
  833.             topElem->fThisElement
  834.             , topElem->fChildren
  835.             , topElem->fChildCount
  836.         );
  837.         if (res >= 0)
  838.         {
  839.             //  One of the elements is not valid for the content. NOTE that
  840.             //  if no children were provided but the content model requires
  841.             //  them, it comes back with a zero value. But we cannot use that
  842.             //  to index the child array in this case, and have to put out a
  843.             //  special message.
  844.             if (!topElem->fChildCount)
  845.             {
  846.                 fValidator->emitError
  847.                 (
  848.                     XMLValid::EmptyNotValidForContent
  849.                     , topElem->fThisElement->getFormattedContentModel()
  850.                 );
  851.             }
  852.             else if ((unsigned int)res >= topElem->fChildCount)
  853.             {
  854.                 fValidator->emitError
  855.                 (
  856.                     XMLValid::NotEnoughElemsForCM
  857.                     , topElem->fThisElement->getFormattedContentModel()
  858.                 );
  859.             }
  860.             else
  861.             {
  862.                 fValidator->emitError
  863.                 (
  864.                     XMLValid::ElementNotValidForContent
  865.                     , topElem->fChildren[res]->getRawName()
  866.                     , topElem->fThisElement->getFormattedContentModel()
  867.                 );
  868.             }
  869.             
  870.         }
  871.         // call matchers and de-activate context
  872.         int oldCount = fMatcherStack->getMatcherCount();
  873.         if (oldCount ||
  874.             ((SchemaElementDecl*)topElem->fThisElement)->getIdentityConstraintCount()) {
  875.             for (int i = oldCount - 1; i >= 0; i--) {
  876.                 XPathMatcher* matcher = fMatcherStack->getMatcherAt(i);
  877.                 matcher->endElement(*(topElem->fThisElement), fContent.getRawBuffer());
  878.             }
  879.             if (fMatcherStack->size() > 0) {
  880.                 fMatcherStack->popContext();
  881.             }
  882.             // handle everything *but* keyref's.
  883.             int newCount = fMatcherStack->getMatcherCount();
  884.             for (int j = oldCount - 1; j >= newCount; j--) {
  885.                 XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
  886.                 IdentityConstraint* ic = matcher->getIdentityConstraint();
  887.                 if (ic  && (ic->getType() != IdentityConstraint::KEYREF))
  888.                     fValueStoreCache->transplant(ic, matcher->getInitialDepth());
  889.             }
  890.             // now handle keyref's...
  891.             for (int k = oldCount - 1; k >= newCount; k--) {
  892.                 XPathMatcher* matcher = fMatcherStack->getMatcherAt(k);
  893.                 IdentityConstraint* ic = matcher->getIdentityConstraint();
  894.                 if (ic && (ic->getType() == IdentityConstraint::KEYREF)) {
  895.                     ValueStore* values = fValueStoreCache->getValueStoreFor(ic, matcher->getInitialDepth());
  896.                     if (values) { // nothing to do if nothing matched!
  897.                         values->endDcocumentFragment(fValueStoreCache);
  898.                     }
  899.                 }
  900.             }
  901.             fValueStoreCache->endElement();
  902.         }
  903.     }
  904.     if(!isRoot)
  905.         ((SchemaElementDecl *)fElemStack.topElement()->fThisElement)->updateValidityFromElement(topElem->fThisElement, fGrammarType);
  906.     // If we have a doc handler, tell it about the end tag
  907.     if (fDocHandler)
  908.     {
  909.         fDocHandler->endElement
  910.         (
  911.             *topElem->fThisElement
  912.             , uriId
  913.             , isRoot
  914.             , fPrefixBuf.getRawBuffer()
  915.         );
  916.     }
  917.     // reset xsi:type ComplexTypeInfo
  918.     ((SchemaElementDecl*)topElem->fThisElement)->reset();
  919.     if (!isRoot)
  920.         ((SchemaElementDecl*)(fElemStack.topElement()->fThisElement))->
  921.             setXsiComplexTypeInfo(((SchemaValidator*)fValidator)->getCurrentTypeInfo());
  922.     // If this was the root, then done with content
  923.     gotData = !isRoot;
  924.     if (gotData) {
  925.         // Restore the grammar
  926.         fGrammar = fElemStack.getCurrentGrammar();
  927.         fGrammarType = fGrammar->getGrammarType();
  928.         fValidator->setGrammar(fGrammar);
  929.         // Restore the validation flag
  930.         fValidate = fElemStack.getValidationFlag();
  931.     }
  932. }
  933. //  This method handles the high level logic of scanning the DOCType
  934. //  declaration. This calls the DTDScanner and kicks off both the scanning of
  935. //  the internal subset and the scanning of the external subset, if any.
  936. //
  937. //  When we get here the '<!DOCTYPE' part has already been scanned, which is
  938. //  what told us that we had a doc type decl to parse.
  939. void SGXMLScanner::scanDocTypeDecl()
  940. {
  941.     // Just skips over it
  942.     // REVISIT: Should we issue a warning
  943.     static const XMLCh doctypeIE[] =
  944.     {
  945.             chOpenSquare, chCloseAngle, chNull
  946.     };
  947.     XMLCh nextCh = fReaderMgr.skipUntilIn(doctypeIE);
  948.     if (nextCh == chOpenSquare)
  949.         fReaderMgr.skipPastChar(chCloseSquare);
  950.     fReaderMgr.skipPastChar(chCloseAngle);
  951. }
  952. //  This method is called to scan a start tag when we are processing
  953. //  namespaces. This method is called after we've scanned the < of a
  954. //  start tag. So we have to get the element name, then scan the attributes, 
  955. //  after which we are either going to see >, />, or attributes followed 
  956. //  by one of those sequences.
  957. bool SGXMLScanner::scanStartTag(bool& gotData)
  958. {
  959.     //  Assume we will still have data until proven otherwise. It will only
  960.     //  ever be false if this is the root and its empty.
  961.     gotData = true;
  962.     // Reset element content
  963.     fContent.reset();
  964.     //  The current position is after the open bracket, so we need to read in
  965.     //  in the element name.
  966.     if (!fReaderMgr.getName(fQNameBuf))
  967.     {
  968.         emitError(XMLErrs::ExpectedElementName);
  969.         fReaderMgr.skipToChar(chOpenAngle);
  970.         return false;
  971.     }
  972.     // See if its the root element
  973.     const bool isRoot = fElemStack.isEmpty();
  974.     // Skip any whitespace after the name
  975.     fReaderMgr.skipPastSpaces();
  976.     //  First we have to do the rawest attribute scan. We don't do any
  977.     //  normalization of them at all, since we don't know yet what type they
  978.     //  might be (since we need the element decl in order to do that.)
  979.     bool isEmpty;
  980.     unsigned int attCount = rawAttrScan
  981.     (
  982.         fQNameBuf.getRawBuffer()
  983.         , *fRawAttrList
  984.         , isEmpty
  985.     );
  986.     const bool gotAttrs = (attCount != 0);
  987.     // save the contentleafname and currentscope before addlevel, for later use
  988.     ContentLeafNameTypeVector* cv = 0;
  989.     XMLContentModel* cm = 0;
  990.     int currentScope = Grammar::TOP_LEVEL_SCOPE;
  991.     bool laxThisOne = false;
  992.     if (!isRoot) {
  993.         SchemaElementDecl* tempElement = (SchemaElementDecl*) fElemStack.topElement()->fThisElement;
  994.         SchemaElementDecl::ModelTypes modelType = tempElement->getModelType();
  995.         if ((modelType == SchemaElementDecl::Mixed_Simple)
  996.           ||  (modelType == SchemaElementDecl::Mixed_Complex)
  997.           ||  (modelType == SchemaElementDecl::Children))
  998.         {
  999.             cm = tempElement->getContentModel();
  1000.             cv = cm->getContentLeafNameTypeVector();
  1001.             currentScope = fElemStack.getCurrentScope();
  1002.         }
  1003.         else if (modelType == SchemaElementDecl::Any) {
  1004.             laxThisOne = true;
  1005.         }
  1006.     }
  1007.     //  Now, since we might have to update the namespace map for this element,
  1008.     //  but we don't have the element decl yet, we just tell the element stack
  1009.     //  to expand up to get ready.
  1010.     unsigned int elemDepth = fElemStack.addLevel();
  1011.     fElemStack.setValidationFlag(fValidate);
  1012.     //  Check if there is any external schema location specified, and if we are at root,
  1013.     //  go through them first before scanning those specified in the instance document
  1014.     if (isRoot
  1015.         && (fExternalSchemaLocation || fExternalNoNamespaceSchemaLocation)) {
  1016.         if (fExternalSchemaLocation)
  1017.             parseSchemaLocation(fExternalSchemaLocation);
  1018.         if (fExternalNoNamespaceSchemaLocation)
  1019.             resolveSchemaGrammar(fExternalNoNamespaceSchemaLocation, XMLUni::fgZeroLenString);
  1020.     }
  1021.     //  Make an initial pass through the list and find any xmlns attributes or
  1022.     //  schema attributes.
  1023.     if (attCount)
  1024.         scanRawAttrListforNameSpaces(fRawAttrList, attCount);
  1025.     //  Resolve the qualified name to a URI and name so that we can look up
  1026.     //  the element decl for this element. We have now update the prefix to
  1027.     //  namespace map so we should get the correct element now.
  1028.     int prefixColonPos = -1;
  1029.     const XMLCh* qnameRawBuf = fQNameBuf.getRawBuffer();
  1030.     unsigned int uriId = resolveQName
  1031.     (
  1032.         qnameRawBuf
  1033.         , fPrefixBuf
  1034.         , ElemStack::Mode_Element
  1035.         , prefixColonPos
  1036.     );
  1037.     //if schema, check if we should lax or skip the validation of this element
  1038.     bool parentValidation = fValidate;
  1039.     if (cv) {
  1040.         QName element(fPrefixBuf.getRawBuffer(), &qnameRawBuf[prefixColonPos + 1], uriId, fMemoryManager);
  1041.         // elementDepth will be > 0, as cv is only constructed if element is not
  1042.         // root.
  1043.         laxThisOne = laxElementValidation(&element, cv, cm, elemDepth - 1);
  1044.     }
  1045.     //  Look up the element now in the grammar. This will get us back a
  1046.     //  generic element decl object. We tell him to fault one in if he does
  1047.     //  not find it.
  1048.     XMLElementDecl* elemDecl = 0;
  1049.     bool wasAdded = false;
  1050.     bool errorBeforeElementFound = false;
  1051.     bool laxBeforeElementFound = false;
  1052.     const XMLCh* nameRawBuf = &qnameRawBuf[prefixColonPos + 1];
  1053.     const XMLCh* original_uriStr = fGrammar->getTargetNamespace();
  1054.     unsigned orgGrammarUri = fURIStringPool->getId(original_uriStr);
  1055.     if (uriId != fEmptyNamespaceId) {
  1056.         // Check in current grammar before switching if necessary
  1057.         elemDecl = fGrammar->getElemDecl
  1058.         (
  1059.           uriId
  1060.           , nameRawBuf
  1061.           , qnameRawBuf
  1062.           , currentScope
  1063.         );
  1064.         if (!elemDecl && (orgGrammarUri != uriId)) {
  1065.             // not found, switch to the specified grammar
  1066.             const XMLCh* uriStr = getURIText(uriId);
  1067.             bool errorCondition = !switchGrammar(uriStr) && fValidate;
  1068.             if (errorCondition && !laxThisOne)
  1069.             {
  1070.                 fValidator->emitError
  1071.                 (
  1072.                     XMLValid::GrammarNotFound
  1073.                     ,uriStr
  1074.                 );
  1075.                 errorBeforeElementFound = true;
  1076.             } 
  1077.             else if(errorCondition)
  1078.                 laxBeforeElementFound = true;
  1079.             elemDecl = fGrammar->getElemDecl
  1080.             (
  1081.               uriId
  1082.               , nameRawBuf
  1083.               , qnameRawBuf
  1084.               , currentScope
  1085.             );
  1086.         }
  1087.         if (!elemDecl && currentScope != Grammar::TOP_LEVEL_SCOPE) {
  1088.             // if not found, then it may be a reference, try TOP_LEVEL_SCOPE
  1089.             elemDecl = fGrammar->getElemDecl
  1090.                        (
  1091.                            uriId
  1092.                            , nameRawBuf
  1093.                            , qnameRawBuf
  1094.                            , Grammar::TOP_LEVEL_SCOPE
  1095.                        );
  1096.             if(!elemDecl) {
  1097.                 // still not found in specified uri
  1098.                 // try emptyNamesapce see if element should be un-qualified.
  1099.                 elemDecl = fGrammar->getElemDecl
  1100.                            (
  1101.                                fEmptyNamespaceId
  1102.                                , nameRawBuf
  1103.                                , qnameRawBuf
  1104.                                , currentScope
  1105.                            );
  1106.                 bool errorCondition = elemDecl && elemDecl->getCreateReason() != XMLElementDecl::JustFaultIn;
  1107.                 if (errorCondition && fValidate) {
  1108.                     fValidator->emitError
  1109.                     (
  1110.                         XMLValid::ElementNotUnQualified
  1111.                         , elemDecl->getFullName()
  1112.                     );
  1113.                     errorBeforeElementFound = true;
  1114.                 }
  1115.                 else if(errorCondition) 
  1116.                     laxBeforeElementFound = true;
  1117.             }
  1118.         }
  1119.         if (!elemDecl) {
  1120.             // still not found, fault this in and issue error later
  1121.             // switch back to original grammar first
  1122.             switchGrammar(original_uriStr);
  1123.             elemDecl = fGrammar->putElemDecl(uriId
  1124.                         , nameRawBuf
  1125.                         , fPrefixBuf.getRawBuffer()
  1126.                         , qnameRawBuf
  1127.                         , currentScope
  1128.                         , true);
  1129.             wasAdded = true;
  1130.         }
  1131.     }
  1132.     else if (!elemDecl)
  1133.     {
  1134.         //the element has no prefix,
  1135.         //thus it is either a non-qualified element defined in current targetNS
  1136.         //or an element that is defined in the globalNS
  1137.         //try unqualifed first
  1138.         elemDecl = fGrammar->getElemDecl
  1139.                    (
  1140.                       uriId
  1141.                     , nameRawBuf
  1142.                     , qnameRawBuf
  1143.                     , currentScope
  1144.                     );
  1145.         if (!elemDecl && orgGrammarUri != fEmptyNamespaceId) {
  1146.             //not found, switch grammar and try globalNS
  1147.             bool errorCondition = !switchGrammar(XMLUni::fgZeroLenString) && fValidate;
  1148.             if (errorCondition && !laxThisOne)
  1149.             {
  1150.                 fValidator->emitError
  1151.                 (
  1152.                     XMLValid::GrammarNotFound
  1153.                   , XMLUni::fgZeroLenString
  1154.                 );
  1155.                 errorBeforeElementFound = true;
  1156.                 
  1157.             }
  1158.             else if(errorCondition)
  1159.                 laxBeforeElementFound = true; 
  1160.             elemDecl = fGrammar->getElemDecl
  1161.             (
  1162.               uriId
  1163.               , nameRawBuf
  1164.               , qnameRawBuf
  1165.               , currentScope
  1166.             );
  1167.         }
  1168.         if (!elemDecl && currentScope != Grammar::TOP_LEVEL_SCOPE) {
  1169.             // if not found, then it may be a reference, try TOP_LEVEL_SCOPE
  1170.             elemDecl = fGrammar->getElemDecl
  1171.                        (
  1172.                            uriId
  1173.                            , nameRawBuf
  1174.                            , qnameRawBuf
  1175.                            , Grammar::TOP_LEVEL_SCOPE
  1176.                        );
  1177.             if (!elemDecl && orgGrammarUri != fEmptyNamespaceId) {
  1178.                 // still Not found in specified uri
  1179.                 // go to original Grammar again to see if element needs to be fully qualified.
  1180.                 const XMLCh* uriStr = getURIText(orgGrammarUri);
  1181.                 bool errorCondition = !switchGrammar(original_uriStr) && fValidate;
  1182.                 if (errorCondition && !laxThisOne)
  1183.                 {
  1184.                     fValidator->emitError
  1185.                     (
  1186.                         XMLValid::GrammarNotFound
  1187.                         ,original_uriStr
  1188.                     );
  1189.                     errorBeforeElementFound = true;
  1190.                 }
  1191.                 else if(errorCondition)
  1192.                     laxBeforeElementFound = true; 
  1193.                 elemDecl = fGrammar->getElemDecl
  1194.                            (
  1195.                                orgGrammarUri
  1196.                                , nameRawBuf
  1197.                                , qnameRawBuf
  1198.                                , currentScope
  1199.                            );
  1200.                 if (elemDecl && elemDecl->getCreateReason() != XMLElementDecl::JustFaultIn && fValidate) {
  1201.                     fValidator->emitError
  1202.                     (
  1203.                         XMLValid::ElementNotQualified
  1204.                         , elemDecl->getFullName()
  1205.                     );
  1206.                     errorBeforeElementFound = true;
  1207.                 }
  1208.             }
  1209.         }
  1210.         if (!elemDecl) {
  1211.             // still not found, fault this in and issue error later
  1212.             // switch back to original grammar first
  1213.             switchGrammar(original_uriStr);
  1214.             elemDecl = fGrammar->putElemDecl(uriId
  1215.                         , nameRawBuf
  1216.                         , fPrefixBuf.getRawBuffer()
  1217.                         , qnameRawBuf
  1218.                         , currentScope
  1219.                         , true);
  1220.             wasAdded = true;
  1221.         }
  1222.     }
  1223.     //  We do something different here according to whether we found the
  1224.     //  element or not.
  1225.     if (wasAdded)
  1226.     {
  1227.         if (laxThisOne) {
  1228.             fValidate = false;
  1229.             fElemStack.setValidationFlag(fValidate);
  1230.         }
  1231.         else if(fValidate) {
  1232.             ((SchemaElementDecl *)(elemDecl))->setValidationAttempted(PSVIDefs::FULL);
  1233.         }
  1234.         // If validating then emit an error
  1235.         if (fValidate)
  1236.         {
  1237.             // This is to tell the reuse Validator that this element was
  1238.             // faulted-in, was not an element in the grammar pool originally
  1239.             elemDecl->setCreateReason(XMLElementDecl::JustFaultIn);
  1240.             fValidator->emitError
  1241.             (
  1242.                 XMLValid::ElementNotDefined
  1243.                 , elemDecl->getFullName()
  1244.             );
  1245.             ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  1246.         }
  1247.     }
  1248.     else
  1249.     {
  1250.         if(!laxBeforeElementFound) {
  1251.             if (fValidate) {
  1252.                 ((SchemaElementDecl *)(elemDecl))->setValidationAttempted(PSVIDefs::FULL);
  1253.                 ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::VALID);
  1254.             }
  1255.         }
  1256.         // If its not marked declared and validating, then emit an error
  1257.         if (!elemDecl->isDeclared()) {
  1258.             if (laxThisOne) {
  1259.                 fValidate = false;
  1260.                 fElemStack.setValidationFlag(fValidate);                
  1261.             }
  1262.             
  1263.             if (fValidate)
  1264.                 {
  1265.                 fValidator->emitError
  1266.                 (
  1267.                     XMLValid::ElementNotDefined
  1268.                     , elemDecl->getFullName()
  1269.                 );
  1270.                 ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  1271.                 ((SchemaElementDecl *)(elemDecl))->setValidationAttempted(PSVIDefs::FULL);
  1272.             }
  1273.         }
  1274.         ((SchemaElementDecl*)elemDecl)->setXsiComplexTypeInfo(0);
  1275.         ((SchemaElementDecl*)elemDecl)->setXsiSimpleTypeInfo(0);
  1276.     }
  1277.     if(errorBeforeElementFound) {
  1278.         ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  1279.     }
  1280.     //  Now we can update the element stack to set the current element
  1281.     //  decl. We expanded the stack above, but couldn't store the element
  1282.     //  decl because we didn't know it yet.
  1283.     fElemStack.setElement(elemDecl, fReaderMgr.getCurrentReaderNum());
  1284.     fElemStack.setCurrentURI(uriId);
  1285.     if (isRoot)
  1286.         fRootGrammar = fGrammar;
  1287.     //  Validate the element
  1288.     if (fValidate)
  1289.         fValidator->validateElement(elemDecl);
  1290.     ComplexTypeInfo* typeinfo = ((SchemaElementDecl*)elemDecl)->getComplexTypeInfo();
  1291.     if (typeinfo) {
  1292.         currentScope = typeinfo->getScopeDefined();
  1293.         // switch grammar if the typeinfo has a different grammar (happens when there is xsi:type)
  1294.         XMLCh* typeName = typeinfo->getTypeName();
  1295.         const XMLCh poundStr[] = {chPound, chNull};
  1296.         if (!XMLString::startsWith(typeName, poundStr)) {
  1297.             const int comma = XMLString::indexOf(typeName, chComma);
  1298.             if (comma > 0) {
  1299.                 XMLBuffer prefixBuf(comma+1, fMemoryManager);
  1300.                 prefixBuf.append(typeName, comma);
  1301.                 const XMLCh* uriStr = prefixBuf.getRawBuffer();
  1302.                 bool errorCondition = !switchGrammar(uriStr) && fValidate;
  1303.                 if (errorCondition && !laxThisOne)
  1304.                 {
  1305.                     fValidator->emitError
  1306.                     (
  1307.                         XMLValid::GrammarNotFound
  1308.                         , prefixBuf.getRawBuffer()
  1309.                     );
  1310.                     ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  1311.                 }
  1312.                 else if(errorCondition) {
  1313.                     ((SchemaElementDecl *)(elemDecl))->setValidationAttempted(PSVIDefs::NONE);
  1314.                     ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::UNKNOWN);
  1315.                 }
  1316.             }
  1317.         }
  1318.     }
  1319.     fElemStack.setCurrentScope(currentScope);
  1320.     // Set element next state
  1321.     if (elemDepth >= fElemStateSize) {
  1322.         resizeElemState();
  1323.     }
  1324.     fElemState[elemDepth] = 0;
  1325.     fElemStack.setCurrentGrammar(fGrammar);
  1326.     //  If this is the first element and we are validating, check the root
  1327.     //  element.
  1328.     if (isRoot)
  1329.     {
  1330.         if (fValidate)
  1331.         {
  1332.             //  Some validators may also want to check the root, call the
  1333.             //  XMLValidator::checkRootElement
  1334.             if (fValidatorFromUser && !fValidator->checkRootElement(elemDecl->getId())) {
  1335.                 fValidator->emitError(XMLValid::RootElemNotLikeDocType);
  1336.                 ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  1337.             }
  1338.         }
  1339.     }
  1340.     else if (parentValidation)
  1341.     {
  1342.         //  If the element stack is not empty, then add this element as a
  1343.         //  child of the previous top element. If its empty, this is the root
  1344.         //  elem and is not the child of anything.
  1345.         fElemStack.addChild(elemDecl->getElementName(), true);
  1346.     }
  1347.     //  Now lets get the fAttrList filled in. This involves faulting in any
  1348.     //  defaulted and fixed attributes and normalizing the values of any that
  1349.     //  we got explicitly.
  1350.     //
  1351.     //  We update the attCount value with the total number of attributes, but
  1352.     //  it goes in with the number of values we got during the raw scan of
  1353.     //  explictly provided attrs above.
  1354.     attCount = buildAttList(*fRawAttrList, attCount, elemDecl, *fAttrList);
  1355.     // activate identity constraints
  1356.     if (fValidate) {
  1357.         unsigned int count = ((SchemaElementDecl*) elemDecl)->getIdentityConstraintCount();
  1358.         if (count || fMatcherStack->getMatcherCount()) {
  1359.             fValueStoreCache->startElement();
  1360.             fMatcherStack->pushContext();
  1361.             fValueStoreCache->initValueStoresFor((SchemaElementDecl*) elemDecl, (int) elemDepth);
  1362.             for (unsigned int i = 0; i < count; i++) {
  1363.                 activateSelectorFor(((SchemaElementDecl*) elemDecl)->getIdentityConstraintAt(i), (int) elemDepth);
  1364.             }
  1365.             // call all active identity constraints
  1366.             count = fMatcherStack->getMatcherCount();
  1367.             for (unsigned int j = 0; j < count; j++) {
  1368.                 XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
  1369.                 matcher->startElement(*elemDecl, uriId, fPrefixBuf.getRawBuffer(), *fAttrList, attCount);
  1370.             }
  1371.         }
  1372.     }
  1373.     // Since the element may have default values, call start tag now regardless if it is empty or not
  1374.     // If we have a document handler, then tell it about this start tag
  1375.     if (fDocHandler)
  1376.     {
  1377.         fDocHandler->startElement
  1378.         (
  1379.             *elemDecl
  1380.             , uriId
  1381.             , fPrefixBuf.getRawBuffer()
  1382.             , *fAttrList
  1383.             , attCount
  1384.             , false
  1385.             , isRoot
  1386.         );
  1387.     }
  1388.     //  If empty, validate content right now if we are validating and then
  1389.     //  pop the element stack top. Else, we have to update the current stack
  1390.     //  top's namespace mapping elements.
  1391.     if (isEmpty)
  1392.     {
  1393.         // Pop the element stack back off since it'll never be used now
  1394.         fElemStack.popTop();
  1395.         // If validating, then insure that its legal to have no content
  1396.         if (fValidate)
  1397.         {
  1398.             const int res = fValidator->checkContent(elemDecl, 0, 0);
  1399.             if (res >= 0)
  1400.             {
  1401.                 fValidator->emitError
  1402.                 (
  1403.                     XMLValid::ElementNotValidForContent
  1404.                     , elemDecl->getFullName()
  1405.                     , elemDecl->getFormattedContentModel()
  1406.                 );
  1407.                 ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  1408.             }
  1409.             // call matchers and de-activate context
  1410.             int oldCount = fMatcherStack->getMatcherCount();
  1411.             if (oldCount || ((SchemaElementDecl*) elemDecl)->getIdentityConstraintCount()) {
  1412.                 for (int i = oldCount - 1; i >= 0; i--) {
  1413.                     XPathMatcher* matcher = fMatcherStack->getMatcherAt(i);
  1414.                     matcher->endElement(*elemDecl, fContent.getRawBuffer());
  1415.                 }
  1416.                 if (fMatcherStack->size() > 0) {
  1417.                     fMatcherStack->popContext();
  1418.                 }
  1419.                 // handle everything *but* keyref's.
  1420.                 int newCount = fMatcherStack->getMatcherCount();
  1421.                 for (int j = oldCount - 1; j >= newCount; j--) {
  1422.                     XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
  1423.                     IdentityConstraint* ic = matcher->getIdentityConstraint();
  1424.                     if (ic  && (ic->getType() != IdentityConstraint::KEYREF))
  1425.                         fValueStoreCache->transplant(ic, matcher->getInitialDepth());
  1426.                 }
  1427.                 // now handle keyref's...
  1428.                 for (int k = oldCount - 1; k >= newCount; k--) {
  1429.                     XPathMatcher* matcher = fMatcherStack->getMatcherAt(k);
  1430.                     IdentityConstraint* ic = matcher->getIdentityConstraint();
  1431.                     if (ic && (ic->getType() == IdentityConstraint::KEYREF)) {
  1432.                         ValueStore* values = fValueStoreCache->getValueStoreFor(ic, matcher->getInitialDepth());
  1433.                         if (values) { // nothing to do if nothing matched!
  1434.                             values->endDcocumentFragment(fValueStoreCache);
  1435.                         }
  1436.                     }
  1437.                 }
  1438.                 fValueStoreCache->endElement();
  1439.             }
  1440.         }
  1441.         if(!isRoot)
  1442.            ((SchemaElementDecl *)fElemStack.topElement()->fThisElement)->updateValidityFromElement(elemDecl, fGrammarType);
  1443.         // If we have a doc handler, tell it about the end tag
  1444.         if (fDocHandler)
  1445.         {
  1446.             fDocHandler->endElement
  1447.             (
  1448.                 *elemDecl
  1449.                 , uriId
  1450.                 , isRoot
  1451.                 , fPrefixBuf.getRawBuffer()
  1452.             );
  1453.         }
  1454.         // reset xsi:type ComplexTypeInfo
  1455.         ((SchemaElementDecl*)elemDecl)->reset();
  1456.         if (!isRoot)
  1457.             ((SchemaElementDecl*)(fElemStack.topElement()->fThisElement))->
  1458.                 setXsiComplexTypeInfo(((SchemaValidator*)fValidator)->getCurrentTypeInfo());
  1459.         // If the elem stack is empty, then it was an empty root
  1460.         if (isRoot)
  1461.             gotData = false;
  1462.         else
  1463.         {
  1464.             // Restore the grammar
  1465.             fGrammar = fElemStack.getCurrentGrammar();
  1466.             fGrammarType = fGrammar->getGrammarType();
  1467.             fValidator->setGrammar(fGrammar);
  1468.             // Restore the validation flag
  1469.             fValidate = fElemStack.getValidationFlag();
  1470.         }
  1471.     }
  1472.     return true;
  1473. }
  1474. unsigned int
  1475. SGXMLScanner::resolveQName(const   XMLCh* const qName
  1476.                            ,       XMLBuffer&   prefixBuf
  1477.                            , const short        mode
  1478.                            ,       int&         prefixColonPos)
  1479. {
  1480.     //  Lets split out the qName into a URI and name buffer first. The URI
  1481.     //  can be empty.
  1482.     prefixColonPos = XMLString::indexOf(qName, chColon);
  1483.     if (prefixColonPos == -1)
  1484.     {
  1485.         //  Its all name with no prefix, so put the whole thing into the name
  1486.         //  buffer. Then map the empty string to a URI, since the empty string
  1487.         //  represents the default namespace. This will either return some
  1488.         //  explicit URI which the default namespace is mapped to, or the
  1489.         //  the default global namespace.
  1490.         bool unknown = false;
  1491.         prefixBuf.reset();
  1492.         return fElemStack.mapPrefixToURI(XMLUni::fgZeroLenString, (ElemStack::MapModes) mode, unknown);
  1493.     }
  1494.     else
  1495.     {
  1496.         //  Copy the chars up to but not including the colon into the prefix
  1497.         //  buffer.
  1498.         prefixBuf.set(qName, prefixColonPos);
  1499.         //  Watch for the special namespace prefixes. We always map these to
  1500.         //  special URIs. 'xml' gets mapped to the official URI that its defined
  1501.         //  to map to by the NS spec. xmlns gets mapped to a special place holder
  1502.         //  URI that we define (so that it maps to something checkable.)
  1503.         const XMLCh* prefixRawBuf = prefixBuf.getRawBuffer();
  1504.         if (XMLString::equals(prefixRawBuf, XMLUni::fgXMLNSString)) {
  1505.             // if this is an element, it is an error to have xmlns as prefix
  1506.             if (mode == ElemStack::Mode_Element)
  1507.                 emitError(XMLErrs::NoXMLNSAsElementPrefix, qName);
  1508.             return fXMLNSNamespaceId;
  1509.         }
  1510.         else if (XMLString::equals(prefixRawBuf, XMLUni::fgXMLString)) {
  1511.             return  fXMLNamespaceId;
  1512.         }
  1513.         else
  1514.         {
  1515.             bool unknown = false;
  1516.             unsigned int uriId = fElemStack.mapPrefixToURI(prefixRawBuf, (ElemStack::MapModes) mode, unknown);
  1517.             if (unknown)
  1518.                 emitError(XMLErrs::UnknownPrefix, prefixRawBuf);
  1519.             return uriId;
  1520.         }
  1521.     }
  1522. }
  1523. // ---------------------------------------------------------------------------
  1524. //  SGXMLScanner: IC activation methos
  1525. // ---------------------------------------------------------------------------
  1526. void SGXMLScanner::activateSelectorFor(IdentityConstraint* const ic, const int initialDepth) {
  1527.     IC_Selector* selector = ic->getSelector();
  1528.     if (!selector)
  1529.         return;
  1530.     XPathMatcher* matcher = selector->createMatcher
  1531.     (
  1532.         fFieldActivator
  1533.         , initialDepth
  1534.         , fMemoryManager
  1535.     );
  1536.     fMatcherStack->addMatcher(matcher);
  1537.     matcher->startDocumentFragment();
  1538. }
  1539. // ---------------------------------------------------------------------------
  1540. //  SGXMLScanner: Grammar preparsing
  1541. // ---------------------------------------------------------------------------
  1542. Grammar* SGXMLScanner::loadGrammar(const   InputSource& src
  1543.                                    , const short        grammarType
  1544.                                    , const bool         toCache)
  1545. {
  1546.     Grammar* loadedGrammar = 0;
  1547.     try
  1548.     {
  1549.         fGrammarResolver->cacheGrammarFromParse(false);
  1550.         fGrammarResolver->useCachedGrammarInParse(false);
  1551.         fRootGrammar = 0;
  1552.         if (fValScheme == Val_Auto) {
  1553.             fValidate = true;
  1554.         }
  1555.         // Reset some status flags
  1556.         fInException = false;
  1557.         fStandalone = false;
  1558.         fErrorCount = 0;
  1559.         fHasNoDTD = true;
  1560.         fSeeXsi = false;
  1561.         if (grammarType == Grammar::SchemaGrammarType) {
  1562.             loadedGrammar = loadXMLSchemaGrammar(src, toCache);
  1563.         }
  1564.         // Reset the reader manager to close all files, sockets, etc...
  1565.         fReaderMgr.reset();
  1566.     }
  1567.     //  NOTE:
  1568.     //
  1569.     //  In all of the error processing below, the emitError() call MUST come
  1570.     //  before the flush of the reader mgr, or it will fail because it tries
  1571.     //  to find out the position in the XML source of the error.
  1572.     catch(const XMLErrs::Codes)
  1573.     {
  1574.         // This is a 'first fatal error' type exit, so reset and fall through
  1575.         fReaderMgr.reset();
  1576.     }
  1577.     catch(const XMLValid::Codes)
  1578.     {
  1579.         // This is a 'first fatal error' type exit, so reset and fall through
  1580.         fReaderMgr.reset();
  1581.     }
  1582.     catch(const XMLException& excToCatch)
  1583.     {
  1584.         //  Emit the error and catch any user exception thrown from here. Make
  1585.         //  sure in all cases we flush the reader manager.
  1586.         fInException = true;
  1587.         try
  1588.         {
  1589.             if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning)
  1590.                 emitError
  1591.                 (
  1592.                     XMLErrs::DisplayErrorMessage
  1593.                     , excToCatch.getMessage()
  1594.                 );
  1595.             else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal)
  1596.                 emitError
  1597.                 (
  1598.                     XMLErrs::XMLException_Fatal
  1599.                     , excToCatch.getType()
  1600.                     , excToCatch.getMessage()
  1601.                 );
  1602.             else
  1603.                 emitError
  1604.                 (
  1605.                     XMLErrs::XMLException_Error
  1606.                     , excToCatch.getType()
  1607.                     , excToCatch.getMessage()
  1608.                 );
  1609.         }
  1610.         catch(...)
  1611.         {
  1612.             // Flush the reader manager and rethrow user's error
  1613.             fReaderMgr.reset();
  1614.             throw;
  1615.         }
  1616.         // If it returned, then reset the reader manager and fall through
  1617.         fReaderMgr.reset();
  1618.     }
  1619.     catch(...)
  1620.     {
  1621.         // Reset and rethrow
  1622.         fReaderMgr.reset();
  1623.         throw;
  1624.     }
  1625.     return loadedGrammar;
  1626. }
  1627. // ---------------------------------------------------------------------------
  1628. //  SGXMLScanner: Private helper methods
  1629. // ---------------------------------------------------------------------------
  1630. //  This method handles the common initialization, to avoid having to do
  1631. //  it redundantly in multiple constructors.
  1632. void SGXMLScanner::commonInit()
  1633. {
  1634.     //  Create the element state array
  1635.     fElemState = (unsigned int*) fMemoryManager->allocate
  1636.     (
  1637.         fElemStateSize * sizeof(unsigned int)
  1638.     ); //new unsigned int[fElemStateSize];
  1639.     //  And we need one for the raw attribute scan. This just stores key/
  1640.     //  value string pairs (prior to any processing.)
  1641.     fRawAttrList = new (fMemoryManager) RefVectorOf<KVStringPair>(32, true, fMemoryManager);
  1642.     // Create dummy schema grammar
  1643.     fSchemaGrammar = new (fMemoryManager) SchemaGrammar(fMemoryManager);
  1644.     //  Create the Validator and init them
  1645.     fSchemaValidator = new (fMemoryManager) SchemaValidator(0, fMemoryManager);
  1646.     initValidator(fSchemaValidator);
  1647.     // Create IdentityConstraint info
  1648.     fMatcherStack = new (fMemoryManager) XPathMatcherStack(fMemoryManager);
  1649.     fValueStoreCache = new (fMemoryManager) ValueStoreCache(fMemoryManager);
  1650.     fFieldActivator = new (fMemoryManager) FieldActivator(fValueStoreCache, fMatcherStack, fMemoryManager);
  1651.     fValueStoreCache->setScanner(this);
  1652.     //  Add the default entity entries for the character refs that must always
  1653.     //  be present.
  1654.     fEntityTable = new (fMemoryManager) ValueHashTableOf<XMLCh>(11, fMemoryManager);
  1655.     fEntityTable->put((void*) XMLUni::fgAmp, chAmpersand);
  1656.     fEntityTable->put((void*) XMLUni::fgLT, chOpenAngle);
  1657.     fEntityTable->put((void*) XMLUni::fgGT, chCloseAngle);
  1658.     fEntityTable->put((void*) XMLUni::fgQuot, chDoubleQuote);
  1659.     fEntityTable->put((void*) XMLUni::fgApos, chSingleQuote);
  1660. }
  1661. void SGXMLScanner::cleanUp()
  1662. {
  1663.     fMemoryManager->deallocate(fElemState); //delete [] fElemState;
  1664.     delete fSchemaGrammar;
  1665.     delete fEntityTable;
  1666.     delete fRawAttrList;
  1667.     delete fSchemaValidator;
  1668.     delete fFieldActivator;
  1669.     delete fMatcherStack;
  1670.     delete fValueStoreCache;
  1671. }
  1672. void SGXMLScanner::resizeElemState() {
  1673.     unsigned int newSize = fElemStateSize * 2;
  1674.     unsigned int* newElemState = (unsigned int*) fMemoryManager->allocate
  1675.     (
  1676.         newSize * sizeof(unsigned int)
  1677.     ); //new unsigned int[newSize];
  1678.     // Copy the existing values
  1679.     unsigned int index = 0;
  1680.     for (; index < fElemStateSize; index++)
  1681.         newElemState[index] = fElemState[index];
  1682.     for (; index < newSize; index++)
  1683.         newElemState[index] = 0;
  1684.     // Delete the old array and udpate our members
  1685.     fMemoryManager->deallocate(fElemState); //delete [] fElemState;
  1686.     fElemState = newElemState;
  1687.     fElemStateSize = newSize;
  1688. }
  1689. //  This method is called from scanStartTag() to build up the list of
  1690. //  XMLAttr objects that will be passed out in the start tag callout. We
  1691. //  get the key/value pairs from the raw scan of explicitly provided attrs,
  1692. //  which have not been normalized. And we get the element declaration from
  1693. //  which we will get any defaulted or fixed attribute defs and add those
  1694. //  in as well.
  1695. unsigned int
  1696. SGXMLScanner::buildAttList(const  RefVectorOf<KVStringPair>&  providedAttrs
  1697.                           , const unsigned int                attCount
  1698.                           ,       XMLElementDecl*             elemDecl
  1699.                           ,       RefVectorOf<XMLAttr>&       toFill)
  1700. {
  1701.     //  Ask the element to clear the 'provided' flag on all of the att defs
  1702.     //  that it owns, and to return us a boolean indicating whether it has
  1703.     //  any defs.
  1704.     const bool hasDefs = elemDecl->resetDefs();
  1705.     //  If there are no expliclitily provided attributes and there are no
  1706.     //  defined attributes for the element, the we don't have anything to do.
  1707.     //  So just return zero in this case.
  1708.     if (!hasDefs && !attCount)
  1709.         return 0;
  1710.     // Keep up with how many attrs we end up with total
  1711.     unsigned int retCount = 0;
  1712.     //  And get the current size of the output vector. This lets us use
  1713.     //  existing elements until we fill it, then start adding new ones.
  1714.     const unsigned int curAttListSize = toFill.size();
  1715.     //  We need a buffer into which raw scanned attribute values will be
  1716.     //  normalized.
  1717.     XMLBufBid bbNormal(&fBufMgr);
  1718.     XMLBuffer& normBuf = bbNormal.getBuffer();
  1719.     //  Loop through our explicitly provided attributes, which are in the raw
  1720.     //  scanned form, and build up XMLAttr objects.
  1721.     unsigned int index;
  1722.     for (index = 0; index < attCount; index++)
  1723.     {
  1724.         const KVStringPair* curPair = providedAttrs.elementAt(index);
  1725.         //  We have to split the name into its prefix and name parts. Then
  1726.         //  we map the prefix to its URI.
  1727.         const XMLCh* const namePtr = curPair->getKey();
  1728.         ArrayJanitor<XMLCh> janName(0);
  1729.         // use a stack-based buffer when possible.
  1730.         XMLCh tempBuffer[100];
  1731.         const int colonInd = XMLString::indexOf(namePtr, chColon);
  1732.         const XMLCh* prefPtr = XMLUni::fgZeroLenString;
  1733.         const XMLCh* suffPtr = XMLUni::fgZeroLenString;
  1734.         if (colonInd != -1)
  1735.         {
  1736.             // We have to split the string, so make a copy.
  1737.             if (XMLString::stringLen(namePtr) < sizeof(tempBuffer) / sizeof(tempBuffer[0]))
  1738.             {
  1739.                 XMLString::copyString(tempBuffer, namePtr);
  1740.                 tempBuffer[colonInd] = chNull;
  1741.                 prefPtr = tempBuffer;
  1742.             }
  1743.             else
  1744.             {
  1745.                 janName.reset(XMLString::replicate(namePtr, fMemoryManager), fMemoryManager);
  1746.                 janName[colonInd] = chNull;
  1747.                 prefPtr = janName.get();
  1748.             }
  1749.             suffPtr = prefPtr + colonInd + 1;
  1750.         }
  1751.         else
  1752.         {
  1753.             // No colon, so we just have a name with no prefix
  1754.             suffPtr = namePtr;
  1755.         }
  1756.         //  Map the prefix to a URI id. We tell him that we are mapping an
  1757.         //  attr prefix, so any xmlns attrs at this level will not affect it.
  1758.         const unsigned int uriId = resolvePrefix(prefPtr, ElemStack::Mode_Attribute);
  1759.         //  If the uri comes back as the xmlns or xml URI or its just a name
  1760.         //  and that name is 'xmlns', then we handle it specially. So set a
  1761.         //  boolean flag that lets us quickly below know which we are dealing
  1762.         //  with.
  1763.         const bool isNSAttr = (uriId == fXMLNSNamespaceId)
  1764.                               || (uriId == fXMLNamespaceId)
  1765.                               || XMLString::equals(suffPtr, XMLUni::fgXMLNSString)
  1766.                               || XMLString::equals(getURIText(uriId), SchemaSymbols::fgURI_XSI);
  1767.         //  If its not a special case namespace attr of some sort, then we
  1768.         //  do normal checking and processing.
  1769.         XMLAttDef::AttTypes attType;
  1770.         if (!isNSAttr)
  1771.         {
  1772.             // Some checking for attribute wild card first (for schema)
  1773.             bool laxThisOne = false;
  1774.             bool skipThisOne = false;
  1775.             XMLAttDef* attDefForWildCard = 0;
  1776.             XMLAttDef*  attDef = 0;
  1777.             if (fGrammarType == Grammar::SchemaGrammarType) {
  1778.                 //retrieve the att def
  1779.                 attDef = ((SchemaElementDecl*)elemDecl)->getAttDef(suffPtr, uriId);
  1780.                 // if not found or faulted in - check for a matching wildcard attribute
  1781.                 // if no matching wildcard attribute, check (un)qualifed cases and flag
  1782.                 // appropriate errors
  1783.                 if (!attDef || (attDef->getCreateReason() == XMLAttDef::JustFaultIn)) {
  1784.                     SchemaAttDef* attWildCard = ((SchemaElementDecl*)elemDecl)->getAttWildCard();
  1785.                     if (attWildCard) {
  1786.                         //if schema, see if we should lax or skip the validation of this attribute
  1787.                         if (anyAttributeValidation(attWildCard, uriId, skipThisOne, laxThisOne)) {
  1788.                             SchemaGrammar* sGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(getURIText(uriId));
  1789.                             if (sGrammar && sGrammar->getGrammarType() == Grammar::SchemaGrammarType) {
  1790.                                 RefHashTableOf<XMLAttDef>* attRegistry = sGrammar->getAttributeDeclRegistry();
  1791.                                 if (attRegistry) {
  1792.                                     attDefForWildCard = attRegistry->get(suffPtr);
  1793.                                 }
  1794.                             }
  1795.                         }
  1796.                     }
  1797.                     else {
  1798.                         // not found, see if the attDef should be qualified or not
  1799.                         if (uriId == fEmptyNamespaceId) {
  1800.                             attDef = ((SchemaElementDecl*)elemDecl)->getAttDef(suffPtr, fURIStringPool->getId(fGrammar->getTargetNamespace()));
  1801.                             if (fValidate
  1802.                                 && attDef
  1803.                                 && attDef->getCreateReason() != XMLAttDef::JustFaultIn) {
  1804.                                 // the attribute should be qualified
  1805.                                 fValidator->emitError
  1806.                                 (
  1807.                                     XMLValid::AttributeNotQualified
  1808.                                     , attDef->getFullName()
  1809.                                 );
  1810.                                 ((SchemaAttDef *)(attDef))->setValidity(PSVIDefs::INVALID);
  1811.                             }
  1812.                         }
  1813.                         else {
  1814.                             attDef = ((SchemaElementDecl*)elemDecl)->getAttDef(suffPtr, fEmptyNamespaceId);
  1815.                             if (fValidate
  1816.                                 && attDef
  1817.                                 && attDef->getCreateReason() != XMLAttDef::JustFaultIn) {