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

词法分析

开发平台:

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: IGXMLScanner2.cpp,v 1.20 2003/05/18 14:02:04 knoaman Exp $
  58.  */
  59. // ---------------------------------------------------------------------------
  60. //  This file holds some of the grunt work methods of IGXMLScanner.cpp to keep
  61. //  it a little more readable.
  62. // ---------------------------------------------------------------------------
  63. // ---------------------------------------------------------------------------
  64. //  Includes
  65. // ---------------------------------------------------------------------------
  66. #include <xercesc/internal/IGXMLScanner.hpp>
  67. #include <xercesc/internal/EndOfEntityException.hpp>
  68. #include <xercesc/util/UnexpectedEOFException.hpp>
  69. #include <xercesc/framework/LocalFileInputSource.hpp>
  70. #include <xercesc/framework/URLInputSource.hpp>
  71. #include <xercesc/framework/XMLDocumentHandler.hpp>
  72. #include <xercesc/framework/XMLEntityHandler.hpp>
  73. #include <xercesc/framework/XMLPScanToken.hpp>
  74. #include <xercesc/framework/XMLRefInfo.hpp>
  75. #include <xercesc/validators/common/ContentLeafNameTypeVector.hpp>
  76. #include <xercesc/validators/DTD/DTDGrammar.hpp>
  77. #include <xercesc/validators/DTD/DTDValidator.hpp>
  78. #include <xercesc/validators/datatype/DatatypeValidator.hpp>
  79. #include <xercesc/validators/schema/SchemaGrammar.hpp>
  80. #include <xercesc/validators/schema/SchemaValidator.hpp>
  81. #include <xercesc/validators/schema/TraverseSchema.hpp>
  82. #include <xercesc/validators/schema/SubstitutionGroupComparator.hpp>
  83. #include <xercesc/validators/schema/identity/XPathMatcherStack.hpp>
  84. #include <xercesc/validators/schema/XSDDOMParser.hpp>
  85. #include <xercesc/validators/schema/identity/ValueStoreCache.hpp>
  86. XERCES_CPP_NAMESPACE_BEGIN
  87. // ---------------------------------------------------------------------------
  88. //  IGXMLScanner: Private helper methods
  89. // ---------------------------------------------------------------------------
  90. //  This method is called from scanStartTagNS() to build up the list of
  91. //  XMLAttr objects that will be passed out in the start tag callout. We
  92. //  get the key/value pairs from the raw scan of explicitly provided attrs,
  93. //  which have not been normalized. And we get the element declaration from
  94. //  which we will get any defaulted or fixed attribute defs and add those
  95. //  in as well.
  96. unsigned int
  97. IGXMLScanner::buildAttList(const  RefVectorOf<KVStringPair>&  providedAttrs
  98.                           , const unsigned int                attCount
  99.                           ,       XMLElementDecl*             elemDecl
  100.                           ,       RefVectorOf<XMLAttr>&       toFill)
  101. {
  102.     //  Ask the element to clear the 'provided' flag on all of the att defs
  103.     //  that it owns, and to return us a boolean indicating whether it has
  104.     //  any defs.
  105.     const bool hasDefs = elemDecl->resetDefs();
  106.     //  If there are no expliclitily provided attributes and there are no
  107.     //  defined attributes for the element, the we don't have anything to do.
  108.     //  So just return zero in this case.
  109.     if (!hasDefs && !attCount)
  110.         return 0;
  111.     // Keep up with how many attrs we end up with total
  112.     unsigned int retCount = 0;
  113.     //  And get the current size of the output vector. This lets us use
  114.     //  existing elements until we fill it, then start adding new ones.
  115.     const unsigned int curAttListSize = toFill.size();
  116.     //  We need a buffer into which raw scanned attribute values will be
  117.     //  normalized.
  118.     XMLBufBid bbNormal(&fBufMgr);
  119.     XMLBuffer& normBuf = bbNormal.getBuffer();
  120.     //  Loop through our explicitly provided attributes, which are in the raw
  121.     //  scanned form, and build up XMLAttr objects.
  122.     unsigned int index;
  123.     for (index = 0; index < attCount; index++)
  124.     {
  125.         const KVStringPair* curPair = providedAttrs.elementAt(index);
  126.         //  We have to split the name into its prefix and name parts. Then
  127.         //  we map the prefix to its URI.
  128.         const XMLCh* const namePtr = curPair->getKey();
  129.         ArrayJanitor<XMLCh> janName(0);
  130.         // use a stack-based buffer when possible.
  131.         XMLCh tempBuffer[100];
  132.         const int colonInd = XMLString::indexOf(namePtr, chColon);
  133.         const XMLCh* prefPtr = XMLUni::fgZeroLenString;
  134.         const XMLCh* suffPtr = XMLUni::fgZeroLenString;
  135.         if (colonInd != -1)
  136.         {
  137.             // We have to split the string, so make a copy.
  138.             if (XMLString::stringLen(namePtr) < sizeof(tempBuffer) / sizeof(tempBuffer[0]))
  139.             {
  140.                 XMLString::copyString(tempBuffer, namePtr);
  141.                 tempBuffer[colonInd] = chNull;
  142.                 prefPtr = tempBuffer;
  143.             }
  144.             else
  145.             {
  146.                 janName.reset(XMLString::replicate(namePtr, fMemoryManager), fMemoryManager);
  147.                 janName[colonInd] = chNull;
  148.                 prefPtr = janName.get();
  149.             }
  150.             suffPtr = prefPtr + colonInd + 1;
  151.         }
  152.         else
  153.         {
  154.             // No colon, so we just have a name with no prefix
  155.             suffPtr = namePtr;
  156.         }
  157.         //  Map the prefix to a URI id. We tell him that we are mapping an
  158.         //  attr prefix, so any xmlns attrs at this level will not affect it.
  159.         const unsigned int uriId = resolvePrefix(prefPtr, ElemStack::Mode_Attribute);
  160.         //  If the uri comes back as the xmlns or xml URI or its just a name
  161.         //  and that name is 'xmlns', then we handle it specially. So set a
  162.         //  boolean flag that lets us quickly below know which we are dealing
  163.         //  with.
  164.         const bool isNSAttr = (uriId == fXMLNSNamespaceId)
  165.                               || (uriId == fXMLNamespaceId)
  166.                               || XMLString::equals(suffPtr, XMLUni::fgXMLNSString)
  167.                               || XMLString::equals(getURIText(uriId), SchemaSymbols::fgURI_XSI);
  168.         //  If its not a special case namespace attr of some sort, then we
  169.         //  do normal checking and processing.
  170.         XMLAttDef::AttTypes attType;
  171.         if (!isNSAttr || fGrammarType == Grammar::DTDGrammarType)
  172.         {
  173.             // Some checking for attribute wild card first (for schema)
  174.             bool laxThisOne = false;
  175.             bool skipThisOne = false;
  176.             XMLAttDef* attDefForWildCard = 0;
  177.             XMLAttDef*  attDef = 0;
  178.             if (fGrammarType == Grammar::SchemaGrammarType) {
  179.                 //retrieve the att def
  180.                 attDef = ((SchemaElementDecl*)elemDecl)->getAttDef(suffPtr, uriId);
  181.                 // if not found or faulted in - check for a matching wildcard attribute
  182.                 // if no matching wildcard attribute, check (un)qualifed cases and flag
  183.                 // appropriate errors
  184.                 if (!attDef || (attDef->getCreateReason() == XMLAttDef::JustFaultIn)) {
  185.                     SchemaAttDef* attWildCard = ((SchemaElementDecl*)elemDecl)->getAttWildCard();
  186.                     if (attWildCard) {
  187.                         //if schema, see if we should lax or skip the validation of this attribute
  188.                         if (anyAttributeValidation(attWildCard, uriId, skipThisOne, laxThisOne)) {
  189.                             SchemaGrammar* sGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(getURIText(uriId));
  190.                             if (sGrammar && sGrammar->getGrammarType() == Grammar::SchemaGrammarType) {
  191.                                 RefHashTableOf<XMLAttDef>* attRegistry = sGrammar->getAttributeDeclRegistry();
  192.                                 if (attRegistry) {
  193.                                     attDefForWildCard = attRegistry->get(suffPtr);
  194.                                 }
  195.                             }
  196.                         }
  197.                     }
  198.                     else {
  199.                         // not found, see if the attDef should be qualified or not
  200.                         if (uriId == fEmptyNamespaceId) {
  201.                             attDef = ((SchemaElementDecl*)elemDecl)->getAttDef(suffPtr, fURIStringPool->getId(fGrammar->getTargetNamespace()));
  202.                             if (fValidate
  203.                                 && attDef
  204.                                 && attDef->getCreateReason() != XMLAttDef::JustFaultIn) {
  205.                                 // the attribute should be qualified
  206.                                 fValidator->emitError
  207.                                 (
  208.                                     XMLValid::AttributeNotQualified
  209.                                     , attDef->getFullName()
  210.                                 );
  211.                                 if(fGrammarType == Grammar::SchemaGrammarType) {
  212.                                     ((SchemaAttDef *)(attDef))->setValidity(PSVIDefs::INVALID);
  213.                                 }
  214.                             }
  215.                         }
  216.                         else {
  217.                             attDef = ((SchemaElementDecl*)elemDecl)->getAttDef(suffPtr, fEmptyNamespaceId);
  218.                             if (fValidate
  219.                                 && attDef
  220.                                 && attDef->getCreateReason() != XMLAttDef::JustFaultIn) {
  221.                                 // the attribute should be qualified
  222.                                 fValidator->emitError
  223.                                 (
  224.                                     XMLValid::AttributeNotUnQualified
  225.                                     , attDef->getFullName()
  226.                                 );
  227.                                 if(fGrammarType == Grammar::SchemaGrammarType) {
  228.                                     ((SchemaAttDef *)(attDef))->setValidity(PSVIDefs::INVALID);
  229.                                 }
  230.                             }
  231.                         }
  232.                     }
  233.                 }
  234.             }
  235.             //  Find this attribute within the parent element. We pass both
  236.             //  the uriID/name and the raw QName buffer, since we don't know
  237.             //  how the derived validator and its elements store attributes.
  238.             bool wasAdded = false;
  239.             if (!attDef) {
  240.                 attDef = elemDecl->findAttr
  241.                 (
  242.                     curPair->getKey()
  243.                     , uriId
  244.                     , suffPtr
  245.                     , prefPtr
  246.                     , XMLElementDecl::AddIfNotFound
  247.                     , wasAdded
  248.                 );
  249.             }
  250.             if(!skipThisOne && fGrammarType == Grammar::SchemaGrammarType) {
  251.                 //we may have set it to invalid already, but this is the first time we are guarenteed to have the attDef
  252.                 if(((SchemaAttDef *)(attDef))->getValidity() != PSVIDefs::INVALID)
  253.                     ((SchemaAttDef *)(attDef))->setValidity(PSVIDefs::VALID);
  254.                     
  255.                 ((SchemaAttDef *)(attDef))->setValidationAttempted(PSVIDefs::FULL);
  256.             }
  257.             if (wasAdded)
  258.             {
  259.                 // This is to tell the Validator that this attribute was
  260.                 // faulted-in, was not an attribute in the attdef originally
  261.                 attDef->setCreateReason(XMLAttDef::JustFaultIn);
  262.             }
  263.             bool errorCondition = fValidate && !attDefForWildCard && 
  264.                 attDef->getCreateReason() == XMLAttDef::JustFaultIn && !attDef->getProvided();
  265.             if (errorCondition && !skipThisOne && !laxThisOne)
  266.             {
  267.                 //
  268.                 //  Its not valid for this element, so issue an error if we are
  269.                 //  validating.
  270.                 //
  271.                 XMLBufBid bbMsg(&fBufMgr);
  272.                 XMLBuffer& bufMsg = bbMsg.getBuffer();
  273.                 if (uriId != fEmptyNamespaceId) {
  274.                     XMLBufBid bbURI(&fBufMgr);
  275.                     XMLBuffer& bufURI = bbURI.getBuffer();
  276.                     getURIText(uriId, bufURI);
  277.                     bufMsg.append(chOpenCurly);
  278.                     bufMsg.append(bufURI.getRawBuffer());
  279.                     bufMsg.append(chCloseCurly);
  280.                 }
  281.                 bufMsg.append(suffPtr);
  282.                 fValidator->emitError
  283.                 (
  284.                     XMLValid::AttNotDefinedForElement
  285.                     , bufMsg.getRawBuffer()
  286.                     , elemDecl->getFullName()
  287.                 );
  288.                 if(fGrammarType == Grammar::SchemaGrammarType) {
  289.                     ((SchemaAttDef *)(attDef))->setValidity(PSVIDefs::INVALID);
  290.                 }
  291.             }
  292.             else if(errorCondition && laxThisOne && fGrammarType == Grammar::SchemaGrammarType) {
  293.                 ((SchemaAttDef *)(attDef))->setValidationAttempted(PSVIDefs::NONE);
  294.                 ((SchemaAttDef *)(attDef))->setValidity(PSVIDefs::UNKNOWN);
  295.             }
  296.             //  If its already provided, then there are more than one of
  297.             //  this attribute in this start tag, so emit an error.
  298.             if (attDef->getProvided())
  299.             {
  300.                 emitError
  301.                 ( 
  302.                     XMLErrs::AttrAlreadyUsedInSTag
  303.                     , attDef->getFullName()
  304.                     , elemDecl->getFullName()
  305.                 );
  306.                 if(fGrammarType == Grammar::SchemaGrammarType) {
  307.                     ((SchemaAttDef *)(attDef))->setValidity(PSVIDefs::INVALID);
  308.                 }
  309.             }
  310.             else
  311.             {
  312.                 attDef->setProvided(true);
  313.             }
  314.             //  Now normalize the raw value since we have the attribute type. We
  315.             //  don't care about the return status here. If it failed, an error
  316.             //  was issued, which is all we care about.
  317.             if (attDefForWildCard) {
  318.                 ((SchemaAttDef*)attDef)->setAnyDatatypeValidator(((SchemaAttDef*) attDefForWildCard)->getDatatypeValidator());
  319.                 normalizeAttValue
  320.                 (
  321.                     attDefForWildCard
  322.                     , curPair->getValue()
  323.                     , normBuf
  324.                 );
  325.                 //  If we found an attdef for this one, then lets validate it.
  326.                 if (fNormalizeData)
  327.                 {
  328.                     // normalize the attribute according to schema whitespace facet
  329.                     XMLBufBid bbtemp(&fBufMgr);
  330.                     XMLBuffer& tempBuf = bbtemp.getBuffer();
  331.                     DatatypeValidator* tempDV = ((SchemaAttDef*) attDefForWildCard)->getDatatypeValidator();
  332.                     ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, normBuf.getRawBuffer(), tempBuf);
  333.                     normBuf.set(tempBuf.getRawBuffer());
  334.                 }
  335.                 if (fValidate && !skipThisOne) {
  336.                     fValidator->validateAttrValue
  337.                     (
  338.                         attDefForWildCard
  339.                         , normBuf.getRawBuffer()
  340.                         , false
  341.                         , elemDecl
  342.                     );
  343.                 }
  344.                 // Save the type for later use
  345.                 attType = attDefForWildCard->getType();
  346.                 if(fGrammarType == Grammar::SchemaGrammarType) {
  347.                     ((SchemaElementDecl *)(elemDecl))->updateValidityFromAttribute((SchemaAttDef *)attDef);
  348.                     DatatypeValidator* tempDV = ((SchemaAttDef*) attDefForWildCard)->getDatatypeValidator();
  349.                     if(tempDV && tempDV->getType() == DatatypeValidator::Union)
  350.                         ((SchemaAttDef*)attDef)->setMembertypeValidator(((UnionDatatypeValidator *)tempDV)->getMemberTypeValidator());
  351.                 }
  352.             }
  353.             else {
  354.                 normalizeAttValue
  355.                 (
  356.                     attDef
  357.                     , curPair->getValue()
  358.                     , normBuf
  359.                 );
  360.                 //  If we found an attdef for this one, then lets validate it.
  361.                 if (attDef->getCreateReason() != XMLAttDef::JustFaultIn)
  362.                 {
  363.                     if (fNormalizeData && (fGrammarType == Grammar::SchemaGrammarType))
  364.                     {
  365.                         // normalize the attribute according to schema whitespace facet
  366.                         XMLBufBid bbtemp(&fBufMgr);
  367.                         XMLBuffer& tempBuf = bbtemp.getBuffer();
  368.                         DatatypeValidator* tempDV = ((SchemaAttDef*) attDef)->getDatatypeValidator();
  369.                         ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, normBuf.getRawBuffer(), tempBuf);
  370.                         normBuf.set(tempBuf.getRawBuffer());
  371.                     }
  372.                     if (fValidate && !skipThisOne)
  373.                     {
  374.                         fValidator->validateAttrValue
  375.                         (
  376.                             attDef
  377.                             , normBuf.getRawBuffer()
  378.                             , false
  379.                             , elemDecl
  380.                         );
  381.                     }
  382.                 }
  383.                 // Save the type for later use
  384.                 attType = attDef->getType();
  385.                 if(fGrammarType == Grammar::SchemaGrammarType)
  386.                     ((SchemaElementDecl *)(elemDecl))->updateValidityFromAttribute((SchemaAttDef *)attDef);
  387.             }
  388.         }
  389.         else
  390.         {
  391.             // Just normalize as CDATA
  392.             attType = XMLAttDef::CData;
  393.             normalizeAttRawValue
  394.             (
  395.                 curPair->getKey()
  396.                 , curPair->getValue()
  397.                 , normBuf
  398.             );
  399.         }
  400.         //  Add this attribute to the attribute list that we use to pass them
  401.         //  to the handler. We reuse its existing elements but expand it as
  402.         //  required.
  403.         XMLAttr* curAttr;
  404.         if (retCount >= curAttListSize)
  405.         {
  406.             curAttr = new (fMemoryManager) XMLAttr
  407.             (
  408.                 uriId
  409.                 , suffPtr
  410.                 , prefPtr
  411.                 , normBuf.getRawBuffer()
  412.                 , attType
  413.                 , true
  414.                 , fMemoryManager
  415.             );
  416.             toFill.addElement(curAttr);
  417.         }
  418.         else
  419.         {
  420.             curAttr = toFill.elementAt(retCount);
  421.             curAttr->set
  422.             (
  423.                 uriId
  424.                 , suffPtr
  425.                 , prefPtr
  426.                 , normBuf.getRawBuffer()
  427.                 , attType
  428.             );
  429.             curAttr->setSpecified(true);
  430.         }
  431.         // Bump the count of attrs in the list
  432.         retCount++;
  433.     }
  434.     //  Now, if there are any attributes declared by this element, let's
  435.     //  go through them and make sure that any required ones are provided,
  436.     //  and fault in any fixed ones and defaulted ones that are not provided
  437.     //  literally.
  438.     if (hasDefs)
  439.     {
  440.         // Check after all specified attrs are scanned
  441.         // (1) report error for REQUIRED attrs that are missing (V_TAGc)
  442.         // (2) add default attrs if missing (FIXED and NOT_FIXED)
  443.         XMLAttDefList& attDefList = elemDecl->getAttDefList();
  444.         while (attDefList.hasMoreElements())
  445.         {
  446.             // Get the current att def, for convenience and its def type
  447.             const XMLAttDef *curDef = &attDefList.nextElement();
  448.             const XMLAttDef::DefAttTypes defType = curDef->getDefaultType();
  449.             if (!curDef->getProvided())
  450.             {
  451.                 if(fGrammarType == Grammar::SchemaGrammarType) {
  452.                     ((SchemaAttDef *)curDef)->setValidationAttempted(PSVIDefs::FULL);
  453.                     ((SchemaAttDef *)curDef)->setValidity(PSVIDefs::VALID);
  454.                 }
  455.                 //the attributes is not provided
  456.                 if (fValidate)
  457.                 {
  458.                     // If we are validating and its required, then an error
  459.                     if ((defType == XMLAttDef::Required) ||
  460.                         (defType == XMLAttDef::Required_And_Fixed)  )
  461.                     {
  462.                         fValidator->emitError
  463.                         (
  464.                             XMLValid::RequiredAttrNotProvided
  465.                             , curDef->getFullName()
  466.                         );
  467.                         if(fGrammarType == Grammar::SchemaGrammarType) 
  468.                             ((SchemaAttDef *)(curDef))->setValidity(PSVIDefs::INVALID);
  469.                     }
  470.                     else if ((defType == XMLAttDef::Default) ||
  471.                              (defType == XMLAttDef::Fixed)  )
  472.                     {
  473.                         if (fStandalone && curDef->isExternal())
  474.                         {
  475.                             // XML 1.0 Section 2.9
  476.                             // Document is standalone, so attributes must not be defaulted.
  477.                             fValidator->emitError(XMLValid::NoDefAttForStandalone, curDef->getFullName(), elemDecl->getFullName());                                                        
  478.                             if(fGrammarType == Grammar::SchemaGrammarType)
  479.                                 ((SchemaAttDef *)(curDef))->setValidity(PSVIDefs::INVALID);
  480.                         }
  481.                     }
  482.                 }
  483.                 //  Fault in the value if needed, and bump the att count.
  484.                 //  We have to
  485.                 if ((defType == XMLAttDef::Default)
  486.                 ||  (defType == XMLAttDef::Fixed))
  487.                 {
  488.                     // Let the validator pass judgement on the attribute value
  489.                     if (fValidate)
  490.                     {
  491.                         fValidator->validateAttrValue
  492.                         (
  493.                             curDef
  494.                             , curDef->getValue()
  495.                             , false
  496.                             , elemDecl
  497.                         );
  498.                     }
  499.                     XMLAttr* curAtt;
  500.                     if (retCount >= curAttListSize)
  501.                     {
  502.                         curAtt = new (fMemoryManager) XMLAttr(fMemoryManager);
  503.                         fValidator->faultInAttr(*curAtt, *curDef);
  504.                         fAttrList->addElement(curAtt);
  505.                     }
  506.                     else
  507.                     {
  508.                         curAtt = fAttrList->elementAt(retCount);
  509.                         fValidator->faultInAttr(*curAtt, *curDef);
  510.                     }
  511.                     if (fGrammarType == Grammar::DTDGrammarType)
  512.                     {
  513.                         //  Map the new attribute's prefix to a URI id and store
  514.                         //  that in the attribute object.
  515.                         curAtt->setURIId
  516.                         (
  517.                             resolvePrefix(curAtt->getPrefix(), ElemStack::Mode_Attribute)
  518.                         );
  519.                     }
  520.                     // Indicate it was not explicitly specified and bump count
  521.                     curAtt->setSpecified(false);
  522.                     retCount++;
  523.                 }
  524.                 if(fGrammarType == Grammar::SchemaGrammarType)
  525.                     ((SchemaElementDecl *)elemDecl)->updateValidityFromAttribute((SchemaAttDef *)curDef);
  526.             }
  527.             else
  528.             {
  529.                 //attribute is provided
  530.                 // (schema) report error for PROHIBITED attrs that are present (V_TAGc)
  531.                 if (defType == XMLAttDef::Prohibited && fValidate) {
  532.                     fValidator->emitError
  533.                     (
  534.                         XMLValid::ProhibitedAttributePresent
  535.                         , curDef->getFullName()
  536.                     );
  537.                     if(fGrammarType == Grammar::SchemaGrammarType) {
  538.                         ((SchemaAttDef *)(curDef))->setValidity(PSVIDefs::INVALID);
  539.                         ((SchemaElementDecl *)elemDecl)->updateValidityFromAttribute((SchemaAttDef *)curDef);
  540.                     }
  541.                 }
  542.             }
  543.         }
  544.     }
  545.     return retCount;
  546. }
  547. //  This method will take a raw attribute value and normalize it according to
  548. //  the rules of the attribute type. It will put the resulting value into the
  549. //  passed buffer.
  550. //
  551. //  This code assumes that escaped characters in the original value (via char
  552. //  refs) are prefixed by a 0xFFFF character. This is because some characters
  553. //  are legal if escaped only. And some escape chars are not subject to
  554. //  normalization rules.
  555. bool IGXMLScanner::normalizeAttValue( const   XMLAttDef* const    attDef
  556.                                       , const XMLCh* const        value
  557.                                       ,       XMLBuffer&          toFill)
  558. {
  559.     // A simple state value for a whitespace processing state machine
  560.     enum States
  561.     {
  562.         InWhitespace
  563.         , InContent
  564.     };
  565.     // Get the type and name
  566.     const XMLAttDef::AttTypes type = attDef->getType();
  567.     const XMLCh* const attrName = attDef->getFullName();
  568.     // Assume its going to go fine, and empty the target buffer in preperation
  569.     bool retVal = true;
  570.     toFill.reset();
  571.     // Get attribute def - to check to see if it's declared externally or not
  572.     bool  isAttExternal = attDef->isExternal();
  573.     //  Loop through the chars of the source value and normalize it according
  574.     //  to the type.
  575.     States curState = InContent;
  576.     bool escaped;
  577.     bool firstNonWS = false;
  578.     XMLCh nextCh;
  579.     const XMLCh* srcPtr = value;
  580.     while (*srcPtr)
  581.     {
  582.         //  Get the next character from the source. We have to watch for
  583.         //  escaped characters (which are indicated by a 0xFFFF value followed
  584.         //  by the char that was escaped.)
  585.         nextCh = *srcPtr;
  586.         escaped = (nextCh == 0xFFFF);
  587.         if (escaped)
  588.             nextCh = *++srcPtr;
  589.         //  If its not escaped, then make sure its not a < character, which is
  590.         //  not allowed in attribute values.
  591.         if (!escaped && (*srcPtr == chOpenAngle))
  592.         {
  593.             emitError(XMLErrs::BracketInAttrValue, attrName);
  594.             retVal = false;
  595.         }
  596.         if (type == XMLAttDef::CData || type > XMLAttDef::Notation)
  597.         {
  598.             if (!escaped)
  599.             {
  600.                 if ((nextCh == 0x09) || (nextCh == 0x0A) || (nextCh == 0x0D))
  601.                 {
  602.                     // Check Validity Constraint for Standalone document declaration
  603.                     // XML 1.0, Section 2.9
  604.                     if (fStandalone && fValidate && isAttExternal)
  605.                     {
  606.                          // Can't have a standalone document declaration of "yes" if  attribute
  607.                          // values are subject to normalisation
  608.                          fValidator->emitError(XMLValid::NoAttNormForStandalone, attrName);
  609.                          if(fGrammarType == Grammar::SchemaGrammarType) {
  610.                              ((SchemaAttDef *)(attDef))->setValidity(PSVIDefs::INVALID);
  611.                          }
  612.                     }
  613.                     nextCh = chSpace;
  614.                 }
  615.             }
  616.         }
  617.         else
  618.         {
  619.             if (curState == InWhitespace)
  620.             {
  621.                 if (!fReaderMgr.getCurrentReader()->isWhitespace(nextCh))
  622.                 {
  623.                     if (firstNonWS)
  624.                         toFill.append(chSpace);
  625.                     curState = InContent;
  626.                     firstNonWS = true;
  627.                 }
  628.                 else
  629.                 {
  630.                     srcPtr++;
  631.                     continue;
  632.                 }
  633.             }
  634.             else if (curState == InContent)
  635.             {
  636.                 if (fReaderMgr.getCurrentReader()->isWhitespace(nextCh))
  637.                 {
  638.                     curState = InWhitespace;
  639.                     srcPtr++;
  640.                     // Check Validity Constraint for Standalone document declaration
  641.                     // XML 1.0, Section 2.9
  642.                     if (fStandalone && fValidate && isAttExternal)
  643.                     {
  644.                         if (!firstNonWS || (nextCh != chSpace) || (!*srcPtr) || fReaderMgr.getCurrentReader()->isWhitespace(*srcPtr))
  645.                         {
  646.                             // Can't have a standalone document declaration of "yes" if  attribute
  647.                             // values are subject to normalisation
  648.                             fValidator->emitError(XMLValid::NoAttNormForStandalone, attrName);
  649.                             if(fGrammarType == Grammar::SchemaGrammarType) {
  650.                                 ((SchemaAttDef *)(attDef))->setValidity(PSVIDefs::INVALID);
  651.                             }
  652.                         }
  653.                     }
  654.                     continue;
  655.                 }
  656.                 firstNonWS = true;
  657.             }
  658.         }
  659.         // Add this char to the target buffer
  660.         toFill.append(nextCh);
  661.         // And move up to the next character in the source
  662.         srcPtr++;
  663.     }
  664.     if(fGrammarType == Grammar::SchemaGrammarType)
  665.         ((SchemaElementDecl *)fElemStack.topElement()->fThisElement)->updateValidityFromAttribute((SchemaAttDef *)attDef);
  666.     return retVal;
  667. }
  668. //  This method will just normalize the input value as CDATA without
  669. //  any standalone checking.
  670. bool IGXMLScanner::normalizeAttRawValue( const   XMLCh* const        attrName
  671.                                       , const XMLCh* const        value
  672.                                       ,       XMLBuffer&          toFill)
  673. {
  674.     // Assume its going to go fine, and empty the target buffer in preperation
  675.     bool retVal = true;
  676.     toFill.reset();
  677.     //  Loop through the chars of the source value and normalize it according
  678.     //  to the type.
  679.     bool escaped;
  680.     XMLCh nextCh;
  681.     const XMLCh* srcPtr = value;
  682.     while (*srcPtr)
  683.     {
  684.         //  Get the next character from the source. We have to watch for
  685.         //  escaped characters (which are indicated by a 0xFFFF value followed
  686.         //  by the char that was escaped.)
  687.         nextCh = *srcPtr;
  688.         escaped = (nextCh == 0xFFFF);
  689.         if (escaped)
  690.             nextCh = *++srcPtr;
  691.         //  If its not escaped, then make sure its not a < character, which is
  692.         //  not allowed in attribute values.
  693.         if (!escaped && (*srcPtr == chOpenAngle))
  694.         {
  695.             emitError(XMLErrs::BracketInAttrValue, attrName);
  696.             retVal = false;
  697.         }
  698.         if (!escaped)
  699.         {
  700.             //  NOTE: Yes this is a little redundant in that a 0x20 is
  701.             //  replaced with an 0x20. But its faster to do this (I think)
  702.             //  than checking for 9, A, and D separately.
  703.             if (fReaderMgr.getCurrentReader()->isWhitespace(nextCh))
  704.                 nextCh = chSpace;
  705.         }
  706.         // Add this char to the target buffer
  707.         toFill.append(nextCh);
  708.         // And move up to the next character in the source
  709.         srcPtr++;
  710.     }
  711.     return retVal;
  712. }
  713. unsigned int
  714. IGXMLScanner::resolvePrefix(  const   XMLCh* const        prefix
  715.                               , const ElemStack::MapModes mode)
  716. {
  717.     //  Watch for the special namespace prefixes. We always map these to
  718.     //  special URIs. 'xml' gets mapped to the official URI that its defined
  719.     //  to map to by the NS spec. xmlns gets mapped to a special place holder
  720.     //  URI that we define (so that it maps to something checkable.)
  721.     if (XMLString::equals(prefix, XMLUni::fgXMLNSString))
  722.         return fXMLNSNamespaceId;
  723.     else if (XMLString::equals(prefix, XMLUni::fgXMLString))
  724.         return fXMLNamespaceId;
  725.     //  Ask the element stack to search up itself for a mapping for the
  726.     //  passed prefix.
  727.     bool unknown;
  728.     unsigned int uriId = fElemStack.mapPrefixToURI(prefix, mode, unknown);
  729.     // If it was unknown, then the URI was faked in but we have to issue an error
  730.     if (unknown)
  731.         emitError(XMLErrs::UnknownPrefix, prefix);
  732.     return uriId;
  733. }
  734. unsigned int
  735. IGXMLScanner::resolvePrefix(  const   XMLCh* const        prefix
  736.                               ,       XMLBuffer&          bufToFill
  737.                               , const ElemStack::MapModes mode)
  738. {
  739.     //  Watch for the special namespace prefixes. We always map these to
  740.     //  special URIs. 'xml' gets mapped to the official URI that its defined
  741.     //  to map to by the NS spec. xmlns gets mapped to a special place holder
  742.     //  URI that we define (so that it maps to something checkable.)
  743.     if (XMLString::equals(prefix, XMLUni::fgXMLNSString))
  744.         return fXMLNSNamespaceId;
  745.     else if (XMLString::equals(prefix, XMLUni::fgXMLString))
  746.         return fXMLNamespaceId;
  747.     //  Ask the element stack to search up itself for a mapping for the
  748.     //  passed prefix.
  749.     bool unknown;
  750.     unsigned int uriId = fElemStack.mapPrefixToURI(prefix, mode, unknown);
  751.     // If it was unknown, then the URI was faked in but we have to issue an error
  752.     if (unknown)
  753.         emitError(XMLErrs::UnknownPrefix, prefix);
  754.     getURIText(uriId,bufToFill);
  755.     return uriId;
  756. }
  757. //  This method will reset the scanner data structures, and related plugged
  758. //  in stuff, for a new scan session. We get the input source for the primary
  759. //  XML entity, create the reader for it, and push it on the stack so that
  760. //  upon successful return from here we are ready to go.
  761. void IGXMLScanner::scanReset(const InputSource& src)
  762. {
  763.     //  This call implicitly tells us that we are going to reuse the scanner
  764.     //  if it was previously used. So tell the validator to reset itself.
  765.     //
  766.     //  But, if the fUseCacheGrammar flag is set, then don't reset it.
  767.     //
  768.     //  NOTE:   The ReaderMgr is flushed on the way out, because that is
  769.     //          required to insure that files are closed.
  770.     fGrammarResolver->cacheGrammarFromParse(fToCacheGrammar);
  771.     fGrammarResolver->useCachedGrammarInParse(fUseCachedGrammar);
  772.     fDTDGrammar = new (fMemoryManager) DTDGrammar(fMemoryManager);
  773.     fGrammarResolver->putGrammar(XMLUni::fgDTDEntityString, fDTDGrammar);
  774.     fGrammar = fDTDGrammar;
  775.     fGrammarType = fGrammar->getGrammarType();
  776.     fRootGrammar = 0;
  777.     if (fValidatorFromUser) {
  778.         if (fValidator->handlesDTD())
  779.             fValidator->setGrammar(fGrammar);
  780.         else if (fValidator->handlesSchema()) {
  781.             ((SchemaValidator*) fValidator)->setErrorReporter(fErrorReporter);
  782.             ((SchemaValidator*) fValidator)->setGrammarResolver(fGrammarResolver);
  783.             ((SchemaValidator*) fValidator)->setExitOnFirstFatal(fExitOnFirstFatal);
  784.         }
  785.     }
  786.     else {
  787.         // set fValidator as fDTDValidator
  788.         fValidator = fDTDValidator;
  789.         fValidator->setGrammar(fGrammar);
  790.     }
  791.     // Reset validation
  792.     fValidate = (fValScheme == Val_Always) ? true : false;
  793.     //  And for all installed handlers, send reset events. This gives them
  794.     //  a chance to flush any cached data.
  795.     if (fDocHandler)
  796.         fDocHandler->resetDocument();
  797.     if (fEntityHandler)
  798.         fEntityHandler->resetEntities();
  799.     if (fErrorReporter)
  800.         fErrorReporter->resetErrors();
  801.     // Clear out the id reference list
  802.     fIDRefList->removeAll();
  803.     // Reset the Root Element Name
  804.     fMemoryManager->deallocate(fRootElemName);//delete [] fRootElemName;
  805.     fRootElemName = 0;
  806.     // Reset IdentityConstraints
  807.     fValueStoreCache->startDocument();
  808.     fMatcherStack->clear();
  809.     //  Reset the element stack, and give it the latest ids for the special
  810.     //  URIs it has to know about.
  811.     fElemStack.reset
  812.     (
  813.         fEmptyNamespaceId
  814.         , fUnknownNamespaceId
  815.         , fXMLNamespaceId
  816.         , fXMLNSNamespaceId
  817.     );
  818.     if (!fSchemaNamespaceId)
  819.         fSchemaNamespaceId  = fURIStringPool->addOrFind(SchemaSymbols::fgURI_XSI);
  820.     // Reset some status flags
  821.     fInException = false;
  822.     fStandalone = false;
  823.     fErrorCount = 0;
  824.     fHasNoDTD = true;
  825.     fSeeXsi = false;
  826.     // Reset the validators
  827.     fDTDValidator->reset();
  828.     fDTDValidator->setErrorReporter(fErrorReporter);
  829.     fSchemaValidator->reset();
  830.     fSchemaValidator->setErrorReporter(fErrorReporter);
  831.     fSchemaValidator->setExitOnFirstFatal(fExitOnFirstFatal);
  832.     fSchemaValidator->setGrammarResolver(fGrammarResolver);
  833.     if (fValidatorFromUser)
  834.         fValidator->reset();
  835.     //  Handle the creation of the XML reader object for this input source.
  836.     //  This will provide us with transcoding and basic lexing services.
  837.     XMLReader* newReader = fReaderMgr.createReader
  838.     (
  839.         src
  840.         , true
  841.         , XMLReader::RefFrom_NonLiteral
  842.         , XMLReader::Type_General
  843.         , XMLReader::Source_External
  844.         , fCalculateSrcOfs
  845.     );
  846.     if (!newReader) {
  847.         if (src.getIssueFatalErrorIfNotFound())
  848.             ThrowXML1(RuntimeException, XMLExcepts::Scan_CouldNotOpenSource, src.getSystemId());
  849.         else
  850.             ThrowXML1(RuntimeException, XMLExcepts::Scan_CouldNotOpenSource_Warning, src.getSystemId());
  851.     }
  852.     // Push this read onto the reader manager
  853.     fReaderMgr.pushReader(newReader, 0);
  854.     // and reset security-related things if necessary:
  855.     if(fSecurityManager != 0) 
  856.     {
  857.         fEntityExpansionLimit = fSecurityManager->getEntityExpansionLimit();
  858.         fEntityExpansionCount = 0;
  859.     }
  860. }
  861. //  This method is called between markup in content. It scans for character
  862. //  data that is sent to the document handler. It watches for any markup
  863. //  characters that would indicate that the character data has ended. It also
  864. //  handles expansion of general and character entities.
  865. //
  866. //  sendData() is a local static helper for this method which handles some
  867. //  code that must be done in three different places here.
  868. void IGXMLScanner::sendCharData(XMLBuffer& toSend)
  869. {
  870.     // If no data in the buffer, then nothing to do
  871.     if (toSend.isEmpty())
  872.         return;
  873.     //  We do different things according to whether we are validating or
  874.     //  not. If not, its always just characters; else, it depends on the
  875.     //  current element's content model.
  876.     if (fValidate)
  877.     {
  878.         // Get the raw data we need for the callback
  879.         const XMLCh* const rawBuf = toSend.getRawBuffer();
  880.         const unsigned int len = toSend.getLen();
  881.         // And see if the current element is a 'Children' style content model
  882.         const ElemStack::StackElem* topElem = fElemStack.topElement();
  883.         // Get the character data opts for the current element
  884.         XMLElementDecl::CharDataOpts charOpts = topElem->fThisElement->getCharDataOpts();
  885.         if (charOpts == XMLElementDecl::NoCharData)
  886.         {
  887.             // They definitely cannot handle any type of char data
  888.             fValidator->emitError(XMLValid::NoCharDataInCM);
  889.             if(fGrammarType == Grammar::SchemaGrammarType) 
  890.                 ((SchemaElementDecl *)topElem->fThisElement)->setValidity(PSVIDefs::INVALID);
  891.         }
  892.         else if (fReaderMgr.getCurrentReader()->isAllSpaces(rawBuf, len))
  893.         {
  894.             //  Its all spaces. So, if they can take spaces, then send it
  895.             //  as ignorable whitespace. If they can handle any char data
  896.             //  send it as characters.
  897.             if (charOpts == XMLElementDecl::SpacesOk) {
  898.                 if (fDocHandler)
  899.                     fDocHandler->ignorableWhitespace(rawBuf, len, false);
  900.             }
  901.             else if (charOpts == XMLElementDecl::AllCharData)
  902.             {
  903.                 if (fGrammarType != Grammar::SchemaGrammarType)
  904.                 {
  905.                     if (fDocHandler)
  906.                         fDocHandler->docCharacters(rawBuf, len, false);
  907.                 }
  908.                 else
  909.                 {
  910.                     // The normalized data can only be as large as the
  911.                     // original size, so this will avoid allocating way
  912.                     // too much or too little memory.
  913.                     XMLBuffer toFill(len+1, fMemoryManager);
  914.                     toFill.set(rawBuf);
  915.                     if (fNormalizeData) {
  916.                         // normalize the character according to schema whitespace facet
  917.                         XMLBufBid bbtemp(&fBufMgr);
  918.                         XMLBuffer& tempBuf = bbtemp.getBuffer();
  919.                         DatatypeValidator* tempDV = ((SchemaElementDecl*) topElem->fThisElement)->getDatatypeValidator();
  920.                         ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, toFill.getRawBuffer(),  tempBuf);
  921.                         toFill.set(tempBuf.getRawBuffer());
  922.                     }
  923.                     // tell the schema validation about the character data for checkContent later
  924.                     ((SchemaValidator*) fValidator)->setDatatypeBuffer(toFill.getRawBuffer());
  925.                     // call all active identity constraints
  926.                     if (fMatcherStack->getMatcherCount())
  927.                         fContent.append(toFill.getRawBuffer(), toFill.getLen());
  928.                     if (fDocHandler)
  929.                         fDocHandler->docCharacters(toFill.getRawBuffer(), toFill.getLen(), false);
  930.                 }
  931.             }
  932.         }
  933.         else
  934.         {
  935.             //  If they can take any char data, then send it. Otherwise, they
  936.             //  can only handle whitespace and can't handle this stuff so
  937.             //  issue an error.
  938.             if (charOpts == XMLElementDecl::AllCharData)
  939.             {
  940.                 if (fGrammarType != Grammar::SchemaGrammarType)
  941.                 {
  942.                     if (fDocHandler)
  943.                         fDocHandler->docCharacters(rawBuf, len, false);
  944.                 }
  945.                 else
  946.                 {
  947.                     // The normalized data can only be as large as the
  948.                     // original size, so this will avoid allocating way
  949.                     // too much or too little memory.
  950.                     XMLBuffer toFill(len+1, fMemoryManager);
  951.                     toFill.set(rawBuf);
  952.                     if (fNormalizeData) {
  953.                         // normalize the character according to schema whitespace facet
  954.                         XMLBufBid bbtemp(&fBufMgr);
  955.                         XMLBuffer& tempBuf = bbtemp.getBuffer();
  956.                         DatatypeValidator* tempDV = ((SchemaElementDecl*) topElem->fThisElement)->getDatatypeValidator();
  957.                         ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, toFill.getRawBuffer(),  tempBuf);
  958.                         toFill.set(tempBuf.getRawBuffer());
  959.                     }
  960.                     // tell the schema validation about the character data for checkContent later
  961.                     ((SchemaValidator*) fValidator)->setDatatypeBuffer(toFill.getRawBuffer());
  962.                     // call all active identity constraints
  963.                     if (fMatcherStack->getMatcherCount())
  964.                         fContent.append(toFill.getRawBuffer(), toFill.getLen());
  965.                     if (fDocHandler)
  966.                         fDocHandler->docCharacters(toFill.getRawBuffer(), toFill.getLen(), false);
  967.                 }
  968.             }
  969.             else
  970.             {
  971.                 fValidator->emitError(XMLValid::NoCharDataInCM);
  972.                 if(fGrammarType == Grammar::SchemaGrammarType) 
  973.                     ((SchemaElementDecl *)topElem->fThisElement)->setValidity(PSVIDefs::INVALID);
  974.             }
  975.         }
  976.     }
  977.     else
  978.     {
  979.         // call all active identity constraints
  980.         if (fGrammarType == Grammar::SchemaGrammarType) {
  981.             if (fMatcherStack->getMatcherCount())
  982.                 fContent.append(toSend.getRawBuffer(), toSend.getLen());
  983.         }
  984.         // Always assume its just char data if not validating
  985.         if (fDocHandler)
  986.             fDocHandler->docCharacters(toSend.getRawBuffer(), toSend.getLen(), false);
  987.     }
  988.     // Reset buffer
  989.     toSend.reset();
  990. }
  991. //  This method is called with a key/value string pair that represents an
  992. //  xmlns="yyy" or xmlns:xxx="yyy" attribute. This method will update the
  993. //  current top of the element stack based on this data. We know that when
  994. //  we get here, that it is one of these forms, so we don't bother confirming
  995. //  it.
  996. //
  997. //  But we have to ensure
  998. //      1. xxx is not xmlns
  999. //      2. if xxx is xml, then yyy must match XMLUni::fgXMLURIName, and vice versa
  1000. //      3. yyy is not XMLUni::fgXMLNSURIName
  1001. //      4. if xxx is not null, then yyy cannot be an empty string.
  1002. void IGXMLScanner::updateNSMap(const  XMLCh* const    attrName
  1003.                             , const XMLCh* const    attrValue)
  1004. {
  1005.     // We need a buffer to normalize the attribute value into
  1006.     XMLBufBid bbNormal(&fBufMgr);
  1007.     XMLBuffer& normalBuf = bbNormal.getBuffer();
  1008.     //  Normalize the value into the passed buffer. In this case, we don't
  1009.     //  care about the return value. An error was issued for the error, which
  1010.     //  is all we care about here.
  1011.     normalizeAttRawValue(attrName, attrValue, normalBuf);
  1012.     XMLCh* namespaceURI = normalBuf.getRawBuffer();
  1013.     //  We either have the default prefix (""), or we point it into the attr
  1014.     //  name parameter. Note that the xmlns is not the prefix we care about
  1015.     //  here. To us, the 'prefix' is really the local part of the attrName
  1016.     //  parameter.
  1017.     //
  1018.     //  Check 1. xxx is not xmlns
  1019.     //        2. if xxx is xml, then yyy must match XMLUni::fgXMLURIName, and vice versa
  1020.     //        3. yyy is not XMLUni::fgXMLNSURIName
  1021.     //        4. if xxx is not null, then yyy cannot be an empty string.
  1022.     const XMLCh* prefPtr = XMLUni::fgZeroLenString;
  1023.     const int colonOfs = XMLString::indexOf(attrName, chColon);
  1024.     if (colonOfs != -1) {
  1025.         prefPtr = &attrName[colonOfs + 1];
  1026.         if (XMLString::equals(prefPtr, XMLUni::fgXMLNSString))
  1027.             emitError(XMLErrs::NoUseOfxmlnsAsPrefix);
  1028.         else if (XMLString::equals(prefPtr, XMLUni::fgXMLString)) {
  1029.             if (!XMLString::equals(namespaceURI, XMLUni::fgXMLURIName))
  1030.                 emitError(XMLErrs::PrefixXMLNotMatchXMLURI);
  1031.         }
  1032.         if (!namespaceURI)
  1033.             emitError(XMLErrs::NoEmptyStrNamespace, attrName);
  1034.         else if(!*namespaceURI && fXMLVersion == XMLReader::XMLV1_0)
  1035.             emitError(XMLErrs::NoEmptyStrNamespace, attrName);
  1036.     }
  1037.     if (XMLString::equals(namespaceURI, XMLUni::fgXMLNSURIName))
  1038.         emitError(XMLErrs::NoUseOfxmlnsURI);
  1039.     else if (XMLString::equals(namespaceURI, XMLUni::fgXMLURIName)) {
  1040.         if (!XMLString::equals(prefPtr, XMLUni::fgXMLString))
  1041.             emitError(XMLErrs::XMLURINotMatchXMLPrefix);
  1042.     }
  1043.     //  Ok, we have to get the unique id for the attribute value, which is the
  1044.     //  URI that this value should be mapped to. The validator has the
  1045.     //  namespace string pool, so we ask him to find or add this new one. Then
  1046.     //  we ask the element stack to add this prefix to URI Id mapping.
  1047.     fElemStack.addPrefix
  1048.     (
  1049.         prefPtr
  1050.         , fURIStringPool->addOrFind(namespaceURI)
  1051.     );
  1052. }
  1053. void IGXMLScanner::scanRawAttrListforNameSpaces(const RefVectorOf<KVStringPair>* theRawAttrList, int attCount)
  1054. {
  1055.     //  Make an initial pass through the list and find any xmlns attributes or
  1056.     //  schema attributes.
  1057.     //  When we find one, send it off to be used to update the element stack's
  1058.     //  namespace mappings.
  1059.     int index = 0;
  1060.     for (index = 0; index < attCount; index++)
  1061.     {
  1062.         // each attribute has the prefix:suffix="value"
  1063.         const KVStringPair* curPair = fRawAttrList->elementAt(index);
  1064.         const XMLCh* rawPtr = curPair->getKey();
  1065.         //  If either the key begins with "xmlns:" or its just plain
  1066.         //  "xmlns", then use it to update the map.
  1067.         if (!XMLString::compareNString(rawPtr, XMLUni::fgXMLNSColonString, 6)
  1068.         ||  XMLString::equals(rawPtr, XMLUni::fgXMLNSString))
  1069.         {
  1070.             const XMLCh* valuePtr = curPair->getValue();
  1071.             updateNSMap(rawPtr, valuePtr);
  1072.             // if the schema URI is seen in the the valuePtr, set the boolean seeXsi
  1073.             if (XMLString::equals(valuePtr, SchemaSymbols::fgURI_XSI)) {
  1074.                 fSeeXsi = true;
  1075.             }
  1076.         }
  1077.     }
  1078.     // walk through the list again to deal with "xsi:...."
  1079.     if (fDoSchema && fSeeXsi)
  1080.     {
  1081.         //  Schema Xsi Type yyyy (e.g. xsi:type="yyyyy")
  1082.         XMLBufBid bbXsi(&fBufMgr);
  1083.         XMLBuffer& fXsiType = bbXsi.getBuffer();
  1084.         QName attName(fMemoryManager);
  1085.         for (index = 0; index < attCount; index++)
  1086.         {
  1087.             // each attribute has the prefix:suffix="value"
  1088.             const KVStringPair* curPair = fRawAttrList->elementAt(index);
  1089.             const XMLCh* rawPtr = curPair->getKey();
  1090.             attName.setName(rawPtr, fEmptyNamespaceId);
  1091.             const XMLCh* prefPtr = attName.getPrefix();
  1092.             // if schema URI has been seen, scan for the schema location and uri
  1093.             // and resolve the schema grammar; or scan for schema type
  1094.             if (resolvePrefix(prefPtr, ElemStack::Mode_Attribute) == fSchemaNamespaceId) {
  1095.                 const XMLCh* valuePtr = curPair->getValue();
  1096.                 const XMLCh* suffPtr = attName.getLocalPart();
  1097.                 if (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_SCHEMALOCACTION))
  1098.                     parseSchemaLocation(valuePtr);
  1099.                 else if (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCACTION))
  1100.                     resolveSchemaGrammar(valuePtr, XMLUni::fgZeroLenString);
  1101.                 if (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_TYPE)) {
  1102.                         fXsiType.set(valuePtr);
  1103.                 }
  1104.                 else if (XMLString::equals(suffPtr, SchemaSymbols::fgATT_NILL)
  1105.                          && fValidator && fValidator->handlesSchema()
  1106.                          && XMLString::equals(valuePtr, SchemaSymbols::fgATTVAL_TRUE)) {
  1107.                             ((SchemaValidator*)fValidator)->setNillable(true);
  1108.                 }
  1109.             }
  1110.         }
  1111.         if (fValidator && fValidator->handlesSchema()) {
  1112.             if (!fXsiType.isEmpty()) {
  1113.                 int colonPos = -1;
  1114.                 unsigned int uriId = resolveQName (
  1115.                       fXsiType.getRawBuffer()
  1116.                     , fPrefixBuf
  1117.                     , ElemStack::Mode_Element
  1118.                     , colonPos
  1119.                 );
  1120.                 ((SchemaValidator*)fValidator)->setXsiType(fPrefixBuf.getRawBuffer(), fXsiType.getRawBuffer() + colonPos + 1, uriId);
  1121.             }
  1122.         }
  1123.     }
  1124. }
  1125. void IGXMLScanner::parseSchemaLocation(const XMLCh* const schemaLocationStr)
  1126. {
  1127.     BaseRefVectorOf<XMLCh>* schemaLocation = XMLString::tokenizeString(schemaLocationStr);
  1128.     unsigned int size = schemaLocation->size();
  1129.     if (size % 2 != 0 ) {
  1130.         emitError(XMLErrs::BadSchemaLocation);
  1131.     } else {
  1132.         for(unsigned int i=0; i<size; i=i+2) {
  1133.             resolveSchemaGrammar(schemaLocation->elementAt(i+1), schemaLocation->elementAt(i));
  1134.         }
  1135.     }
  1136.     delete schemaLocation;
  1137. }
  1138. void IGXMLScanner::resolveSchemaGrammar(const XMLCh* const loc, const XMLCh* const uri) {
  1139.     Grammar* grammar = fGrammarResolver->getGrammar(uri);
  1140.     if (!grammar || grammar->getGrammarType() == Grammar::DTDGrammarType) {
  1141.         XSDDOMParser parser(0, fMemoryManager);
  1142.         parser.setValidationScheme(XercesDOMParser::Val_Never);
  1143.         parser.setDoNamespaces(true);
  1144.         parser.setUserEntityHandler(fEntityHandler);
  1145.         parser.setUserErrorReporter(fErrorReporter);
  1146.         // Create a buffer for expanding the system id
  1147.         XMLBufBid bbSys(&fBufMgr);
  1148.         XMLBuffer& expSysId = bbSys.getBuffer();
  1149.         XMLBuffer& normalizedSysId = bbSys.getBuffer();
  1150.         normalizeURI(loc, normalizedSysId);
  1151.         //  Allow the entity handler to expand the system id if they choose
  1152.         //  to do so.
  1153.         InputSource* srcToFill = 0;
  1154.         const XMLCh* normalizedURI = normalizedSysId.getRawBuffer();
  1155.         if (fEntityHandler)
  1156.         {
  1157.             if (!fEntityHandler->expandSystemId(normalizedURI, expSysId))
  1158.                 expSysId.set(normalizedURI);
  1159.             srcToFill = fEntityHandler->resolveEntity( XMLUni::fgZeroLenString
  1160.                                                      , expSysId.getRawBuffer());
  1161.         }
  1162.         else
  1163.         {
  1164.             expSysId.set(normalizedURI);
  1165.         }
  1166.         //  If they didn't create a source via the entity handler, then we
  1167.         //  have to create one on our own.
  1168.         if (!srcToFill)
  1169.         {
  1170.             ReaderMgr::LastExtEntityInfo lastInfo;
  1171.             fReaderMgr.getLastExtEntityInfo(lastInfo);
  1172.             try
  1173.             {
  1174.                 XMLURL urlTmp(lastInfo.systemId, expSysId.getRawBuffer());
  1175.                 if (urlTmp.isRelative())
  1176.                 {
  1177.                     ThrowXML
  1178.                     (
  1179.                         MalformedURLException
  1180.                         , XMLExcepts::URL_NoProtocolPresent
  1181.                     );
  1182.                 }
  1183.                 else {
  1184.                     if (fStandardUriConformant && urlTmp.hasInvalidChar())
  1185.                         ThrowXML(MalformedURLException, XMLExcepts::URL_MalformedURL);
  1186.                     srcToFill = new (fMemoryManager) URLInputSource(urlTmp, fMemoryManager);
  1187.                 }
  1188.             }
  1189.             catch(const MalformedURLException& e)
  1190.             {
  1191.                 // Its not a URL, so lets assume its a local file name if non-standard uri is allowed
  1192.                 if (!fStandardUriConformant)
  1193.                     srcToFill = new (fMemoryManager) LocalFileInputSource
  1194.                     (
  1195.                         lastInfo.systemId
  1196.                         , expSysId.getRawBuffer()
  1197.                         , fMemoryManager
  1198.                     );
  1199.                 else
  1200.                     throw e;
  1201.             }
  1202.         }
  1203.         // Put a janitor on the input source
  1204.         Janitor<InputSource> janSrc(srcToFill);
  1205.         // Should just issue warning if the schema is not found
  1206.         const bool flag = srcToFill->getIssueFatalErrorIfNotFound();
  1207.         srcToFill->setIssueFatalErrorIfNotFound(false);
  1208.         parser.parse(*srcToFill);
  1209.         // Reset the InputSource
  1210.         srcToFill->setIssueFatalErrorIfNotFound(flag);
  1211.         if (parser.getSawFatal() && fExitOnFirstFatal)
  1212.             emitError(XMLErrs::SchemaScanFatalError);
  1213.         DOMDocument* document = parser.getDocument(); //Our Grammar
  1214.         if (document != 0) {
  1215.             DOMElement* root = document->getDocumentElement();// This is what we pass to TraverserSchema
  1216.             if (root != 0)
  1217.             {
  1218.                 const XMLCh* newUri = root->getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE);
  1219.                 if (!XMLString::equals(newUri, uri)) {
  1220.                     if (fValidate || fValScheme == Val_Auto) {
  1221.                         fValidator->emitError(XMLValid::WrongTargetNamespace, loc, uri);
  1222.                     }
  1223.                     grammar = fGrammarResolver->getGrammar(newUri);
  1224.                 }
  1225.                 if (!grammar || grammar->getGrammarType() == Grammar::DTDGrammarType) {
  1226.                     //  Since we have seen a grammar, set our validation flag
  1227.                     //  at this point if the validation scheme is auto
  1228.                     if (fValScheme == Val_Auto && !fValidate) {
  1229.                         fValidate = true;
  1230.                         fElemStack.setValidationFlag(fValidate);
  1231.                     }
  1232.                     // we have seen a schema, so set up the fValidator as fSchemaValidator
  1233.                     if (!fValidator->handlesSchema())
  1234.                     {
  1235.                         if (fValidatorFromUser) {
  1236.                             // the fValidator is from user
  1237.                             ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
  1238.                         }
  1239.                         else {
  1240.                             fValidator = fSchemaValidator;
  1241.                         }
  1242.                     }
  1243.                     grammar = new (fMemoryManager) SchemaGrammar(fMemoryManager);
  1244.                     TraverseSchema traverseSchema
  1245.                     (
  1246.                         root
  1247.                         , fURIStringPool
  1248.                         , (SchemaGrammar*) grammar
  1249.                         , fGrammarResolver
  1250.                         , this
  1251.                         , srcToFill->getSystemId()
  1252.                         , fEntityHandler
  1253.                         , fErrorReporter
  1254.                         , fMemoryManager
  1255.                     );
  1256.                     if (fGrammarType == Grammar::DTDGrammarType) {
  1257.                         fGrammar = grammar;
  1258.                         fGrammarType = Grammar::SchemaGrammarType;
  1259.                         fValidator->setGrammar(fGrammar);
  1260.                     }
  1261.                     if (fValidate) {
  1262.                         //  validate the Schema scan so far
  1263.                         fValidator->preContentValidation(false);
  1264.                     }
  1265.                 }
  1266.             }
  1267.         }
  1268.     }
  1269.     else {
  1270.         //  Since we have seen a grammar, set our validation flag
  1271.         //  at this point if the validation scheme is auto
  1272.         if (fValScheme == Val_Auto && !fValidate) {
  1273.             fValidate = true;
  1274.             fElemStack.setValidationFlag(fValidate);
  1275.         }
  1276.         // we have seen a schema, so set up the fValidator as fSchemaValidator
  1277.         if (!fValidator->handlesSchema())
  1278.         {
  1279.             if (fValidatorFromUser) {
  1280.                 // the fValidator is from user
  1281.                 ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
  1282.             }
  1283.             else {
  1284.                 fValidator = fSchemaValidator;
  1285.             }
  1286.         }
  1287.         if (fGrammarType == Grammar::DTDGrammarType) {
  1288.             fGrammar = grammar;
  1289.             fGrammarType = Grammar::SchemaGrammarType;
  1290.             fValidator->setGrammar(fGrammar);
  1291.         }
  1292.     }
  1293. }
  1294. InputSource* IGXMLScanner::resolveSystemId(const XMLCh* const sysId)
  1295. {
  1296.     // Create a buffer for expanding the system id
  1297.     XMLBufBid bbSys(&fBufMgr);
  1298.     XMLBuffer& expSysId = bbSys.getBuffer();
  1299.     //  Allow the entity handler to expand the system id if they choose
  1300.     //  to do so.
  1301.     InputSource* srcToFill = 0;
  1302.     if (fEntityHandler)
  1303.     {
  1304.         if (!fEntityHandler->expandSystemId(sysId, expSysId))
  1305.             expSysId.set(sysId);
  1306.         srcToFill = fEntityHandler->resolveEntity( XMLUni::fgZeroLenString
  1307.                                                  , expSysId.getRawBuffer());
  1308.     }
  1309.     else
  1310.     {
  1311.         expSysId.set(sysId);
  1312.     }
  1313.     //  If they didn't create a source via the entity handler, then we
  1314.     //  have to create one on our own.
  1315.     if (!srcToFill)
  1316.     {
  1317.         ReaderMgr::LastExtEntityInfo lastInfo;
  1318.         fReaderMgr.getLastExtEntityInfo(lastInfo);
  1319.         try
  1320.         {
  1321.             XMLURL urlTmp(lastInfo.systemId, expSysId.getRawBuffer());
  1322.             if (urlTmp.isRelative())
  1323.             {
  1324.                 ThrowXML
  1325.                 (
  1326.                     MalformedURLException
  1327.                     , XMLExcepts::URL_NoProtocolPresent
  1328.                 );
  1329.             }
  1330.             else {
  1331.                 if (fStandardUriConformant && urlTmp.hasInvalidChar())
  1332.                     ThrowXML(MalformedURLException, XMLExcepts::URL_MalformedURL);
  1333.                 srcToFill = new (fMemoryManager) URLInputSource(urlTmp, fMemoryManager);
  1334.             }
  1335.         }
  1336.         catch(const MalformedURLException& e)
  1337.         {
  1338.             // Its not a URL, so lets assume its a local file name if non-standard uri is allowed
  1339.             if (!fStandardUriConformant)
  1340.                 srcToFill = new (fMemoryManager) LocalFileInputSource
  1341.                 (
  1342.                     lastInfo.systemId
  1343.                     , expSysId.getRawBuffer()
  1344.                     , fMemoryManager
  1345.                 );
  1346.             else
  1347.                 throw e;
  1348.         }
  1349.     }
  1350.     return srcToFill;
  1351. }
  1352. // ---------------------------------------------------------------------------
  1353. //  IGXMLScanner: Private grammar preparsing methods
  1354. // ---------------------------------------------------------------------------
  1355. Grammar* IGXMLScanner::loadXMLSchemaGrammar(const InputSource& src,
  1356.                                           const bool toCache)
  1357. {
  1358.    // Reset the validators
  1359.     fSchemaValidator->reset();
  1360.     fSchemaValidator->setErrorReporter(fErrorReporter);
  1361.     fSchemaValidator->setExitOnFirstFatal(fExitOnFirstFatal);
  1362.     fSchemaValidator->setGrammarResolver(fGrammarResolver);
  1363.     if (fValidatorFromUser)
  1364.         fValidator->reset();
  1365.     if (!fValidator->handlesSchema()) {
  1366.         if (fValidatorFromUser && fValidate)
  1367.             ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
  1368.         else {
  1369.             fValidator = fSchemaValidator;
  1370.         }
  1371.     }
  1372.     XSDDOMParser parser(0, fMemoryManager);
  1373.     parser.setValidationScheme(XercesDOMParser::Val_Never);
  1374.     parser.setDoNamespaces(true);
  1375.     parser.setUserEntityHandler(fEntityHandler);
  1376.     parser.setUserErrorReporter(fErrorReporter);
  1377.     // Should just issue warning if the schema is not found
  1378.     const bool flag = src.getIssueFatalErrorIfNotFound();
  1379.     ((InputSource&) src).setIssueFatalErrorIfNotFound(false);
  1380.     parser.parse(src);
  1381.     // Reset the InputSource
  1382.     ((InputSource&) src).setIssueFatalErrorIfNotFound(flag);
  1383.     if (parser.getSawFatal() && fExitOnFirstFatal)
  1384.         emitError(XMLErrs::SchemaScanFatalError);
  1385.     DOMDocument* document = parser.getDocument(); //Our Grammar
  1386.     if (document != 0) {
  1387.         DOMElement* root = document->getDocumentElement();// This is what we pass to TraverserSchema
  1388.         if (root != 0)
  1389.         {
  1390.             SchemaGrammar* grammar = new (fMemoryManager) SchemaGrammar(fMemoryManager);
  1391.             TraverseSchema traverseSchema
  1392.             (
  1393.                 root
  1394.                 , fURIStringPool
  1395.                 , (SchemaGrammar*) grammar
  1396.                 , fGrammarResolver
  1397.                 , this
  1398.                 , src.getSystemId()
  1399.                 , fEntityHandler
  1400.                 , fErrorReporter
  1401.                 , fMemoryManager
  1402.             );
  1403.             if (fValidate) {
  1404.                 //  validate the Schema scan so far
  1405.                 fValidator->setGrammar(grammar);
  1406.                 fValidator->preContentValidation(false, true);
  1407.             }
  1408.             if (toCache) {
  1409.                 fGrammarResolver->cacheGrammars();
  1410.             }
  1411.             return grammar;
  1412.         }
  1413.     }
  1414.     return 0;
  1415. }
  1416. // ---------------------------------------------------------------------------
  1417. //  IGXMLScanner: Private parsing methods
  1418. // ---------------------------------------------------------------------------
  1419. //  This method is called to do a raw scan of an attribute value. It does not
  1420. //  do normalization (since we don't know their types yet.) It just scans the
  1421. //  value and does entity expansion.
  1422. //
  1423. //  End of entity's must be dealt with here. During DTD scan, they can come
  1424. //  from external entities. During content, they can come from any entity.
  1425. //  We just eat the end of entity and continue with our scan until we come
  1426. //  to the closing quote. If an unterminated value causes us to go through
  1427. //  subsequent entities, that will cause errors back in the calling code,
  1428. //  but there's little we can do about it here.
  1429. bool IGXMLScanner::basicAttrValueScan(const XMLCh* const attrName, XMLBuffer& toFill)
  1430. {
  1431.     // Reset the target buffer
  1432.     toFill.reset();
  1433.     // Get the next char which must be a single or double quote
  1434.     XMLCh quoteCh;
  1435.     if (!fReaderMgr.skipIfQuote(quoteCh))
  1436.         return false;
  1437.     //  We have to get the current reader because we have to ignore closing
  1438.     //  quotes until we hit the same reader again.
  1439.     const unsigned int curReader = fReaderMgr.getCurrentReaderNum();
  1440.     //  Loop until we get the attribute value. Note that we use a double
  1441.     //  loop here to avoid the setup/teardown overhead of the exception
  1442.     //  handler on every round.
  1443.     XMLCh   nextCh;
  1444.     XMLCh   secondCh = 0;
  1445.     bool    gotLeadingSurrogate = false;
  1446.     bool    escaped;
  1447.     while (true)
  1448.     {
  1449.         try
  1450.         {
  1451.             while(true)
  1452.             {
  1453.                 nextCh = fReaderMgr.getNextChar();
  1454.                 if (!nextCh)
  1455.                     ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
  1456.                 //  Check for our ending quote. It has to be in the same entity
  1457.                 //  as where we started. Quotes in nested entities are ignored.
  1458.                 if (nextCh == quoteCh)
  1459.                 {
  1460.                     if (curReader == fReaderMgr.getCurrentReaderNum())
  1461.                         return true;
  1462.                     // Watch for spillover into a previous entity
  1463.                     if (curReader > fReaderMgr.getCurrentReaderNum())
  1464.                     {
  1465.                         emitError(XMLErrs::PartialMarkupInEntity);
  1466.                         return false;
  1467.                     }
  1468.                 }
  1469.                 //  Check for an entity ref . We ignore the empty flag in
  1470.                 //  this one.
  1471.                 escaped = false;
  1472.                 if (nextCh == chAmpersand)
  1473.                 {
  1474.                     // If it was not returned directly, then jump back up
  1475.                     if (scanEntityRef(true, nextCh, secondCh, escaped) != EntityExp_Returned)
  1476.                     {
  1477.                         gotLeadingSurrogate = false;
  1478.                         continue;
  1479.                     }
  1480.                 }
  1481.                 else if ((nextCh >= 0xD800) && (nextCh <= 0xDBFF))
  1482.                 {
  1483.                     // Deal with surrogate pairs
  1484.                     //  Its a leading surrogate. If we already got one, then
  1485.                     //  issue an error, else set leading flag to make sure that
  1486.                     //  we look for a trailing next time.
  1487.                     if (gotLeadingSurrogate)
  1488.                     {
  1489.                         emitError(XMLErrs::Expected2ndSurrogateChar);
  1490.                     }
  1491.                     else
  1492.                         gotLeadingSurrogate = true;
  1493.                 }
  1494.                 else
  1495.                 {
  1496.                     //  If its a trailing surrogate, make sure that we are
  1497.                     //  prepared for that. Else, its just a regular char so make
  1498.                     //  sure that we were not expected a trailing surrogate.
  1499.                     if ((nextCh >= 0xDC00) && (nextCh <= 0xDFFF))
  1500.                     {
  1501.                         // Its trailing, so make sure we were expecting it
  1502.                         if (!gotLeadingSurrogate)
  1503.                             emitError(XMLErrs::Unexpected2ndSurrogateChar);
  1504.                     }
  1505.                     else
  1506.                     {
  1507.                         //  Its just a char, so make sure we were not expecting a
  1508.                         //  trailing surrogate.
  1509.                         if (gotLeadingSurrogate) {
  1510.                             emitError(XMLErrs::Expected2ndSurrogateChar);
  1511.                         }
  1512.                         // Its got to at least be a valid XML character
  1513.                         else if (!fReaderMgr.getCurrentReader()->isXMLChar(nextCh))
  1514.                         {
  1515.                             XMLCh tmpBuf[9];
  1516.                             XMLString::binToText
  1517.                             (
  1518.                                 nextCh
  1519.                                 , tmpBuf
  1520.                                 , 8
  1521.                                 , 16
  1522.                             );
  1523.                             emitError(XMLErrs::InvalidCharacterInAttrValue, attrName, tmpBuf);
  1524.                         }
  1525.                     }
  1526.                     gotLeadingSurrogate = false;
  1527.                 }
  1528.                 //  If it was escaped, then put in a 0xFFFF value. This will
  1529.                 //  be used later during validation and normalization of the
  1530.                 //  value to know that the following character was via an
  1531.                 //  escape char.
  1532.                 if (escaped)
  1533.                     toFill.append(0xFFFF);
  1534.                 // Else add it to the buffer
  1535.                 toFill.append(nextCh);
  1536.                 if (secondCh)
  1537.                     toFill.append(secondCh);
  1538.             }
  1539.         }
  1540.         catch(const EndOfEntityException&)
  1541.         {
  1542.             // Just eat it and continue.
  1543.             gotLeadingSurrogate = false;
  1544.             escaped = false;
  1545.         }
  1546.     }
  1547.     return true;
  1548. }
  1549. bool IGXMLScanner::scanAttValue(  const   XMLAttDef* const    attDef
  1550.                                   ,       XMLBuffer&          toFill)
  1551. {
  1552.     enum States
  1553.     {
  1554.         InWhitespace
  1555.         , InContent
  1556.     };
  1557.     // Get the type and name
  1558.     const XMLAttDef::AttTypes type = attDef->getType();
  1559.     const XMLCh* const attrName = attDef->getFullName();
  1560.     // Reset the target buffer
  1561.     toFill.reset();
  1562.     // Get the next char which must be a single or double quote
  1563.     XMLCh quoteCh;
  1564.     if (!fReaderMgr.skipIfQuote(quoteCh))
  1565.         return false;
  1566.     //  We have to get the current reader because we have to ignore closing
  1567.     //  quotes until we hit the same reader again.
  1568.     const unsigned int curReader = fReaderMgr.getCurrentReaderNum();
  1569.     // Get attribute def - to check to see if it's declared externally or not
  1570.     bool  isAttExternal = attDef->isExternal();
  1571.     //  Loop until we get the attribute value. Note that we use a double
  1572.     //  loop here to avoid the setup/teardown overhead of the exception
  1573.     //  handler on every round.
  1574.     XMLCh   nextCh;
  1575.     XMLCh   secondCh = 0;
  1576.     States  curState = InContent;
  1577.     bool    firstNonWS = false;
  1578.     bool    gotLeadingSurrogate = false;
  1579.     bool    escaped;
  1580.     while (true)
  1581.     {
  1582.     try
  1583.     {
  1584.         while(true)
  1585.         {
  1586.             nextCh = fReaderMgr.getNextChar();
  1587.             if (!nextCh)
  1588.                 ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
  1589.             // Check for our ending quote in the same entity
  1590.             if (nextCh == quoteCh)
  1591.             {
  1592.                 if (curReader == fReaderMgr.getCurrentReaderNum())
  1593.                     return true;
  1594.                 // Watch for spillover into a previous entity
  1595.                 if (curReader > fReaderMgr.getCurrentReaderNum())
  1596.                 {
  1597.                     emitError(XMLErrs::PartialMarkupInEntity);
  1598.                     return false;
  1599.                 }
  1600.             }
  1601.             //  Check for an entity ref now, before we let it affect our
  1602.             //  whitespace normalization logic below. We ignore the empty flag
  1603.             //  in this one.
  1604.             escaped = false;
  1605.             if (nextCh == chAmpersand)
  1606.             {
  1607.                 if (scanEntityRef(true, nextCh, secondCh, escaped) != EntityExp_Returned)
  1608.                 {
  1609.                     gotLeadingSurrogate = false;
  1610.                     continue;
  1611.                 }
  1612.             }
  1613.             else if ((nextCh >= 0xD800) && (nextCh <= 0xDBFF))
  1614.             {
  1615.                 // Deal with surrogate pairs
  1616.                 //  Its a leading surrogate. If we already got one, then
  1617.                 //  issue an error, else set leading flag to make sure that
  1618.                 //  we look for a trailing next time.
  1619.                 if (gotLeadingSurrogate)
  1620.                     emitError(XMLErrs::Expected2ndSurrogateChar);
  1621.                  else
  1622.                     gotLeadingSurrogate = true;
  1623.             }
  1624.             else
  1625.             {
  1626.                 //  If its a trailing surrogate, make sure that we are
  1627.                 //  prepared for that. Else, its just a regular char so make
  1628.                 //  sure that we were not expected a trailing surrogate.
  1629.                 if ((nextCh >= 0xDC00) && (nextCh <= 0xDFFF))
  1630.                 {
  1631.                     // Its trailing, so make sure we were expecting it
  1632.                     if (!gotLeadingSurrogate)
  1633.                         emitError(XMLErrs::Unexpected2ndSurrogateChar);
  1634.                 }
  1635.                 else
  1636.                 {
  1637.                     //  Its just a char, so make sure we were not expecting a
  1638.                     //  trailing surrogate.
  1639.                     if (gotLeadingSurrogate)
  1640.                         emitError(XMLErrs::Expected2ndSurrogateChar);
  1641.                     // Its got to at least be a valid XML character
  1642.                     if (!fReaderMgr.getCurrentReader()->isXMLChar(nextCh))
  1643.                     {
  1644.                         XMLCh tmpBuf[9];
  1645.                         XMLString::binToText
  1646.                         (
  1647.                             nextCh
  1648.                             , tmpBuf
  1649.                             , 8
  1650.                             , 16
  1651.                         );
  1652.                         emitError(XMLErrs::InvalidCharacterInAttrValue, attrName, tmpBuf);
  1653.                     }
  1654.                 }
  1655.                 gotLeadingSurrogate = false;
  1656.             }
  1657.             //  If its not escaped, then make sure its not a < character, which
  1658.             //  is not allowed in attribute values.
  1659.             if (!escaped && (nextCh == chOpenAngle))
  1660.                 emitError(XMLErrs::BracketInAttrValue, attrName);
  1661.             //  If the attribute is a CDATA type we do simple replacement of
  1662.             //  tabs and new lines with spaces, if the character is not escaped
  1663.             //  by way of a char ref.
  1664.             //
  1665.             //  Otherwise, we do the standard non-CDATA normalization of
  1666.             //  compressing whitespace to single spaces and getting rid of leading
  1667.             //  and trailing whitespace.
  1668.             if (type == XMLAttDef::CData)
  1669.             {
  1670.                 if (!escaped)
  1671.                 {
  1672.                     if ((nextCh == 0x09) || (nextCh == 0x0A) || (nextCh == 0x0D))
  1673.                     {
  1674.                         // Check Validity Constraint for Standalone document declaration
  1675.                         // XML 1.0, Section 2.9
  1676.                         if (fStandalone && fValidate && isAttExternal)
  1677.                         {
  1678.                              // Can't have a standalone document declaration of "yes" if  attribute
  1679.                              // values are subject to normalisation
  1680.                              fValidator->emitError(XMLValid::NoAttNormForStandalone, attrName);
  1681.                              if(fGrammarType == Grammar::SchemaGrammarType) {
  1682.                                  ((SchemaAttDef *)attDef)->setValidity(PSVIDefs::INVALID);
  1683.                              }
  1684.                         }
  1685.                         nextCh = chSpace;
  1686.                     }
  1687.                 }
  1688.             }
  1689.             else
  1690.             {
  1691.                 if (curState == InWhitespace)
  1692.                 {
  1693.                     if ((escaped && nextCh != chSpace) || !fReaderMgr.getCurrentReader()->isWhitespace(nextCh))
  1694.                     {
  1695.                         if (firstNonWS)
  1696.                             toFill.append(chSpace);
  1697.                         curState = InContent;
  1698.                         firstNonWS = true;
  1699.                     }
  1700.                     else
  1701.                     {
  1702.                         continue;
  1703.                     }
  1704.                 }
  1705.                 else if (curState == InContent)
  1706.                 {
  1707.                     if ((nextCh == chSpace) ||
  1708.                         (fReaderMgr.getCurrentReader()->isWhitespace(nextCh) && !escaped))
  1709.                     {
  1710.                         curState = InWhitespace;
  1711.                         // Check Validity Constraint for Standalone document declaration
  1712.                         // XML 1.0, Section 2.9
  1713.                         if (fStandalone && fValidate && isAttExternal)
  1714.                         {
  1715.                             if (!firstNonWS || (nextCh != chSpace) || (fReaderMgr.lookingAtSpace()))
  1716.                             {
  1717.                                  // Can't have a standalone document declaration of "yes" if  attribute
  1718.                                  // values are subject to normalisation
  1719.                                  fValidator->emitError(XMLValid::NoAttNormForStandalone, attrName);
  1720.                             }
  1721.                         }
  1722.                         continue;
  1723.                     }
  1724.                     firstNonWS = true;
  1725.                 }
  1726.             }
  1727.             // Else add it to the buffer
  1728.             toFill.append(nextCh);
  1729.             if (secondCh)
  1730.                toFill.append(secondCh);
  1731.             if(fGrammarType == Grammar::SchemaGrammarType)
  1732.                 ((SchemaElementDecl *)fElemStack.topElement()->fThisElement)->updateValidityFromAttribute((SchemaAttDef *)attDef);
  1733.         }
  1734.     }
  1735.     catch(const EndOfEntityException&)
  1736.     {
  1737.         // Just eat it and continue.
  1738.         gotLeadingSurrogate = false;
  1739.         escaped = false;
  1740.     }
  1741.     }
  1742.     return true;
  1743. }
  1744. //  This method scans a CDATA section. It collects the character into one
  1745. //  of the temp buffers and calls the document handler, if any, with the
  1746. //  characters. It assumes that the <![CDATA string has been scanned before
  1747. //  this call.
  1748. void IGXMLScanner::scanCDSection()
  1749. {
  1750.     //  This is the CDATA section opening sequence, minus the '<' character.
  1751.     //  We use this to watch for nested CDATA sections, which are illegal.
  1752.     static const XMLCh CDataPrefix[] =
  1753.     {
  1754.             chBang, chOpenSquare, chLatin_C, chLatin_D, chLatin_A
  1755.         ,   chLatin_T, chLatin_A, chOpenSquare, chNull
  1756.     };
  1757.     static const XMLCh CDataClose[] =
  1758.     {
  1759.             chCloseSquare, chCloseAngle, chNull
  1760.     };
  1761.     //  The next character should be the opening square bracket. If not
  1762.     //  issue an error, but then try to recover by skipping any whitespace
  1763.     //  and checking again.
  1764.     if (!fReaderMgr.skippedChar(chOpenSquare))
  1765.     {
  1766.         emitError(XMLErrs::ExpectedOpenSquareBracket);
  1767.         fReaderMgr.skipPastSpaces();
  1768.         // If we still don't find it, then give up, else keep going
  1769.         if (!fReaderMgr.skippedChar(chOpenSquare))
  1770.             return;
  1771.     }
  1772.     // Get a buffer for this
  1773.     XMLBufBid bbCData(&fBufMgr);
  1774.     //  We just scan forward until we hit the end of CDATA section sequence.
  1775.     //  CDATA is effectively a big escape mechanism so we don't treat markup
  1776.     //  characters specially here.
  1777.     bool            emittedError = false;
  1778.     bool    gotLeadingSurrogate = false;
  1779.     // Get the character data opts for the current element
  1780.     const ElemStack::StackElem* topElem = fElemStack.topElement();
  1781.     XMLElementDecl::CharDataOpts charOpts = topElem->fThisElement->getCharDataOpts();
  1782.     while (true)
  1783.     {
  1784.         const XMLCh nextCh = fReaderMgr.getNextChar();
  1785.         // Watch for unexpected end of file
  1786.         if (!nextCh)
  1787.         {
  1788.             emitError(XMLErrs::UnterminatedCDATASection);
  1789.             ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
  1790.         }
  1791.         if (fValidate && fStandalone && (fReaderMgr.getCurrentReader()->isWhitespace(nextCh)))
  1792.         {
  1793.             // This document is standalone; this ignorable CDATA whitespace is forbidden.
  1794.             // XML 1.0, Section 2.9
  1795.             // And see if the current element is a 'Children' style content model
  1796.             if (topElem->fThisElement->isExternal()) {
  1797.                 if (charOpts == XMLElementDecl::SpacesOk) // Element Content
  1798.                 {
  1799.                     // Error - standalone should have a value of "no" as whitespace detected in an
  1800.                     // element type with element content whose element declaration was external
  1801.                     fValidator->emitError(XMLValid::NoWSForStandalone);
  1802.                     if(fGrammarType == Grammar::SchemaGrammarType) 
  1803.                         ((SchemaElementDecl *)topElem->fThisElement)->setValidity(PSVIDefs::INVALID);
  1804.                 }
  1805.             }
  1806.         }
  1807.         //  If this is a close square bracket it could be our closing
  1808.         //  sequence.
  1809.         if (nextCh == chCloseSquare && fReaderMgr.skippedString(CDataClose))
  1810.         {
  1811.             //  make sure we were not expecting a trailing surrogate.
  1812.             if (gotLeadingSurrogate)
  1813.                 emitError(XMLErrs::Expected2ndSurrogateChar);
  1814.             if (fGrammarType == Grammar::SchemaGrammarType) {
  1815.                 if (fNormalizeData) {
  1816.                     // normalize the character according to schema whitespace facet
  1817.                     XMLBufBid bbtemp(&fBufMgr);
  1818.                     XMLBuffer& tempBuf = bbtemp.getBuffer();
  1819.                     DatatypeValidator* tempDV = ((SchemaElementDecl*) topElem->fThisElement)->getDatatypeValidator();
  1820.                     ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, bbCData.getRawBuffer(),  tempBuf);
  1821.                     bbCData.set(tempBuf.getRawBuffer());
  1822.                 }
  1823.                 if (fValidate) {
  1824.                     // tell the schema validation about the character data for checkContent later
  1825.                     ((SchemaValidator*) fValidator)->setDatatypeBuffer(bbCData.getRawBuffer());
  1826.                     if (charOpts != XMLElementDecl::AllCharData)
  1827.                     {
  1828.                         // They definitely cannot handle any type of char data
  1829.                         fValidator->emitError(XMLValid::NoCharDataInCM);
  1830.                         ((SchemaElementDecl *)topElem->fThisElement)->setValidity(PSVIDefs::INVALID);
  1831.                     }
  1832.                 }
  1833.                 if (fMatcherStack->getMatcherCount())
  1834.                     fContent.append(bbCData.getRawBuffer(), bbCData.getLen());
  1835.             }
  1836.             else {
  1837.                 if (fValidate) {
  1838.                     if (charOpts != XMLElementDecl::AllCharData)
  1839.                     {
  1840.                         // They definitely cannot handle any type of char data
  1841.                         fValidator->emitError(XMLValid::NoCharDataInCM);
  1842.                     }
  1843.                 }
  1844.             }
  1845.             // If we have a doc handler, call it
  1846.             if (fDocHandler)
  1847.             {
  1848.                 fDocHandler->docCharacters
  1849.                     (
  1850.                     bbCData.getRawBuffer()
  1851.                     , bbCData.getLen()
  1852.                     , true
  1853.                     );
  1854.             }
  1855.             // And we are done
  1856.             break;
  1857.         }
  1858.         //  Make sure its a valid character. But if we've emitted an error
  1859.         //  already, don't bother with the overhead since we've already told
  1860.         //  them about it.
  1861.         if (!emittedError)
  1862.         {
  1863.             // Deal with surrogate pairs
  1864.             if ((nextCh >= 0xD800) && (nextCh <= 0xDBFF))
  1865.             {
  1866.                 //  Its a leading surrogate. If we already got one, then
  1867.                 //  issue an error, else set leading flag to make sure that
  1868.                 //  we look for a trailing next time.
  1869.                 if (gotLeadingSurrogate)
  1870.                     emitError(XMLErrs::Expected2ndSurrogateChar);
  1871.                 else
  1872.                     gotLeadingSurrogate = true;
  1873.             }
  1874.             else
  1875.             {
  1876.                 //  If its a trailing surrogate, make sure that we are
  1877.                 //  prepared for that. Else, its just a regular char so make
  1878.                 //  sure that we were not expected a trailing surrogate.
  1879.                 if ((nextCh >= 0xDC00) && (nextCh <= 0xDFFF))
  1880.                 {
  1881.                     // Its trailing, so make sure we were expecting it
  1882.                     if (!gotLeadingSurrogate)
  1883.                         emitError(XMLErrs::Unexpected2ndSurrogateChar);
  1884.                 }
  1885.                 else
  1886.                 {
  1887.                     //  Its just a char, so make sure we were not expecting a
  1888.                     //  trailing surrogate.
  1889.                     if (gotLeadingSurrogate)
  1890.                         emitError(XMLErrs::Expected2ndSurrogateChar);
  1891.                     // Its got to at least be a valid XML character
  1892.                     else if (!fReaderMgr.getCurrentReader()->isXMLChar(nextCh))
  1893.                     {
  1894.                         XMLCh tmpBuf[9];
  1895.                         XMLString::binToText
  1896.                         (
  1897.                             nextCh
  1898.                             , tmpBuf
  1899.                             , 8
  1900.                             , 16
  1901.                         );
  1902.                         emitError(XMLErrs::InvalidCharacter, tmpBuf);
  1903.                         emittedError = true;
  1904.                     }
  1905.                 }
  1906.                 gotLeadingSurrogate = false;
  1907.             }
  1908.         }
  1909.         // Add it to the buffer
  1910.         bbCData.append(nextCh);
  1911.     }
  1912. }
  1913. void IGXMLScanner::scanCharData(XMLBuffer& toUse)
  1914. {
  1915.     //  We have to watch for the stupid ]]> sequence, which is illegal in
  1916.     //  character data. So this is a little state machine that handles that.
  1917.     enum States
  1918.     {
  1919.         State_Waiting
  1920.         , State_GotOne
  1921.         , State_GotTwo
  1922.     };
  1923.     // Reset the buffer before we start
  1924.     toUse.reset();
  1925.     // Turn on the 'throw at end' flag of the reader manager
  1926.     ThrowEOEJanitor jan(&fReaderMgr, true);
  1927.     //  In order to be more efficient we have to use kind of a deeply nested
  1928.     //  set of blocks here. The outer block puts on a try and catches end of
  1929.     //  entity exceptions. The inner loop is the per-character loop. If we
  1930.     //  put the try inside the inner loop, it would work but would require
  1931.     //  the exception handling code setup/teardown code to be invoked for
  1932.     //  each character.
  1933.     XMLCh   nextCh;
  1934.     XMLCh   secondCh = 0;
  1935.     States  curState = State_Waiting;
  1936.     bool    escaped = false;
  1937.     bool    gotLeadingSurrogate = false;
  1938.     bool    notDone = true;
  1939.     while (notDone)
  1940.     {
  1941.         try
  1942.         {
  1943.             while (true)
  1944.             {
  1945.                 //  Eat through as many plain content characters as possible without
  1946.                 //  needing special handling.  Moving most content characters here,
  1947.                 //  in this one call, rather than running the overall loop once
  1948.                 //  per content character, is a speed optimization.
  1949.                 if (curState == State_Waiting  &&  !gotLeadingSurrogate)
  1950.                 {
  1951.                      fReaderMgr.movePlainContentChars(toUse);
  1952.                 }
  1953.                 // Try to get another char from the source
  1954.                 //   The code from here on down covers all contengencies,
  1955.                 if (!fReaderMgr.getNextCharIfNot(chOpenAngle, nextCh))
  1956.                 {
  1957.                     // If we were waiting for a trailing surrogate, its an error
  1958.                     if (gotLeadingSurrogate)
  1959.                         emitError(XMLErrs::Expected2ndSurrogateChar);
  1960.                     notDone = false;
  1961.                     break;
  1962.                 }
  1963.                 //  Watch for a reference. Note that the escapement mechanism
  1964.                 //  is ignored in this content.
  1965.                 escaped = false;
  1966.                 if (nextCh == chAmpersand)
  1967.                 {
  1968.                     sendCharData(toUse);
  1969.                     // Turn off the throwing at the end of entity during this
  1970.                     ThrowEOEJanitor jan(&fReaderMgr, false);
  1971.                     if (scanEntityRef(false, nextCh, secondCh, escaped) != EntityExp_Returned)
  1972.                     {
  1973.                         gotLeadingSurrogate = false;
  1974.                         continue;
  1975.                     }
  1976.                 }
  1977.                 else if ((nextCh >= 0xD800) && (nextCh <= 0xDBFF))
  1978.                 {
  1979.                     // Deal with surrogate pairs
  1980.                     //  Its a leading surrogate. If we already got one, then
  1981.                     //  issue an error, else set leading flag to make sure that
  1982.                     //  we look for a trailing next time.
  1983.                     if (gotLeadingSurrogate)
  1984.                         emitError(XMLErrs::Expected2ndSurrogateChar);
  1985.                     else
  1986.                         gotLeadingSurrogate = true;
  1987.                 }
  1988.                 else
  1989.                 {
  1990.                     //  If its a trailing surrogate, make sure that we are
  1991.                     //  prepared for that. Else, its just a regular char so make
  1992.                     //  sure that we were not expected a trailing surrogate.
  1993.                     if ((nextCh >= 0xDC00) && (nextCh <= 0xDFFF))
  1994.                     {
  1995.                         // Its trailing, so make sure we were expecting it
  1996.                         if (!gotLeadingSurrogate)
  1997.                             emitError(XMLErrs::Unexpected2ndSurrogateChar);
  1998.                     }
  1999.                     else
  2000.                     {
  2001.                         //  Its just a char, so make sure we were not expecting a
  2002.                         //  trailing surrogate.
  2003.                         if (gotLeadingSurrogate)
  2004.                             emitError(XMLErrs::Expected2ndSurrogateChar);
  2005.                         // Make sure the returned char is a valid XML char
  2006.                         if (!fReaderMgr.getCurrentReader()->isXMLChar(nextCh))
  2007.                         {
  2008.                             XMLCh tmpBuf[9];
  2009.                             XMLString::binToText
  2010.                             (
  2011.                                 nextCh
  2012.                                 , tmpBuf
  2013.                                 , 8
  2014.                                 , 16
  2015.                             );
  2016.                             emitError(XMLErrs::InvalidCharacter, tmpBuf);
  2017.                         }
  2018.                     }
  2019.                     gotLeadingSurrogate = false;
  2020.                 }
  2021.                  // Keep the state machine up to date
  2022.                 if (!escaped)
  2023.                 {
  2024.                     if (nextCh == chCloseSquare)
  2025.                     {
  2026.                         if (curState == State_Waiting)
  2027.                             curState = State_GotOne;
  2028.                         else if (curState == State_GotOne)
  2029.                             curState = State_GotTwo;
  2030.                     }
  2031.                     else if (nextCh == chCloseAngle)
  2032.                     {
  2033.                         if (curState == State_GotTwo)
  2034.                             emitError(XMLErrs::BadSequenceInCharData);
  2035.                         curState = State_Waiting;
  2036.                     }
  2037.                     else
  2038.                     {
  2039.                         curState = State_Waiting;
  2040.                     }
  2041.                 }
  2042.                 else
  2043.                 {
  2044.                     curState = State_Waiting;
  2045.                 }
  2046.                 // Add this char to the buffer
  2047.                 toUse.append(nextCh);
  2048.                 if (secondCh)
  2049.                     toUse.append(secondCh);
  2050.             }
  2051.         }
  2052.         catch(const EndOfEntityException& toCatch)
  2053.         {
  2054.             //  Some entity ended, so we have to send any accumulated
  2055.             //  chars and send an end of entity event.
  2056.             sendCharData(toUse);
  2057.             gotLeadingSurrogate = false;
  2058.             if (fDocHandler)
  2059.                 fDocHandler->endEntityReference(toCatch.getEntity());
  2060.         }
  2061.     }
  2062.     // Check the validity constraints as per XML 1.0 Section 2.9
  2063.     if (fValidate && fStandalone)
  2064.     {
  2065.         // See if the text contains whitespace
  2066.         // Get the raw data we need for the callback
  2067.         const XMLCh* rawBuf = toUse.getRawBuffer();
  2068.         const unsigned int len = toUse.getLen();
  2069.         const bool isSpaces = fReaderMgr.getCurrentReader()->containsWhiteSpace(rawBuf, len);
  2070.         if (isSpaces)
  2071.         {
  2072.             // And see if the current element is a 'Children' style content model
  2073.             const ElemStack::StackElem* topElem = fElemStack.topElement();
  2074.             if (topElem->fThisElement->isExternal()) {
  2075.                 // Get the character data opts for the current element
  2076.                 XMLElementDecl::CharDataOpts charOpts =  topElem->fThisElement->getCharDataOpts();
  2077.                 if (charOpts == XMLElementDecl::SpacesOk)  // => Element Content
  2078.                 {
  2079.                     // Error - standalone should have a value of "no" as whitespace detected in an
  2080.                     // element type with element content whose element declaration was external
  2081.                     //
  2082.                     fValidator->emitError(XMLValid::NoWSForStandalone);
  2083.                     if(fGrammarType == Grammar::SchemaGrammarType) 
  2084.                         ((SchemaElementDecl *)fElemStack.topElement()->fThisElement)->setValidity(PSVIDefs::INVALID);
  2085.                 }
  2086.             }
  2087.         }
  2088.     }
  2089.     // Send any char data that we accumulated into the buffer
  2090.     sendCharData(toUse);
  2091. }
  2092. //  This method will scan a general/character entity ref. It will either
  2093. //  expand a char ref and return it directly, or push a reader for a general
  2094. //  entity.
  2095. //
  2096. //  The return value indicates whether the char parameters hold the value
  2097. //  or whether the value was pushed as a reader, or that it failed.
  2098. //
  2099. //  The escaped flag tells the caller whether the returned parameter resulted
  2100. //  from a character reference, which escapes the character in some cases. It
  2101. //  only makes any difference if the return value indicates the value was
  2102. //  returned directly.
  2103. IGXMLScanner::EntityExpRes
  2104. IGXMLScanner::scanEntityRef(  const   bool    inAttVal
  2105.                             ,       XMLCh&  firstCh
  2106.                             ,       XMLCh&  secondCh
  2107.                             ,       bool&   escaped)
  2108. {
  2109.     // Assume no escape
  2110.     secondCh = 0;
  2111.     escaped = false;
  2112.     // We have to insure that its all in one entity
  2113.     const unsigned int curReader = fReaderMgr.getCurrentReaderNum();
  2114.     //  If the next char is a pound, then its a character reference and we
  2115.     //  need to expand it always.
  2116.     if (fReaderMgr.skippedChar(chPound))
  2117.     {
  2118.         //  Its a character reference, so scan it and get back the numeric
  2119.         //  value it represents.
  2120.         if (!scanCharRef(firstCh, secondCh))
  2121.             return EntityExp_Failed;
  2122.         escaped = true;
  2123.         if (curReader != fReaderMgr.getCurrentReaderNum())
  2124.             emitError(XMLErrs::PartialMarkupInEntity);
  2125.         return EntityExp_Returned;
  2126.     }
  2127.     // Expand it since its a normal entity ref
  2128.     XMLBufBid bbName(&fBufMgr);
  2129.     if (!fReaderMgr.getName(bbName.getBuffer()))
  2130.     {
  2131.         emitError(XMLErrs::ExpectedEntityRefName);
  2132.         return EntityExp_Failed;
  2133.     }
  2134.     //  Next char must be a semi-colon. But if its not, just emit
  2135.     //  an error and try to continue.
  2136.     if (!fReaderMgr.skippedChar(chSemiColon))
  2137.         emitError(XMLErrs::UnterminatedEntityRef, bbName.getRawBuffer());
  2138.     // Make sure we ended up on the same entity reader as the & char
  2139.     if (curReader != fReaderMgr.getCurrentReaderNum())
  2140.         emitError(XMLErrs::PartialMarkupInEntity);
  2141.     // Look up the name in the general entity pool
  2142.     XMLEntityDecl* decl = fDTDGrammar->getEntityDecl(bbName.getRawBuffer());
  2143.     // If it does not exist, then obviously an error
  2144.     if (!decl)
  2145.     {
  2146.         // XML 1.0 Section 4.1
  2147.         // Well-formedness Constraint for entity not found:
  2148.         //   In a document without any DTD, a document with only an internal DTD subset which contains no parameter entity references,
  2149.         //      or a document with "standalone='yes'", for an entity reference that does not occur within the external subset
  2150.         //      or a parameter entity
  2151.         //
  2152.         // Else it's Validity Constraint
  2153.         if (fStandalone || fHasNoDTD)
  2154.             emitError(XMLErrs::EntityNotFound, bbName.getRawBuffer());
  2155.         else {
  2156.             if (fValidate)
  2157.                 fValidator->emitError(XMLValid::VC_EntityNotFound, bbName.getRawBuffer());
  2158.         }
  2159.         return EntityExp_Failed;
  2160.     }
  2161.     // XML 1.0 Section 4.1
  2162.     //  If we are a standalone document, then it has to have been declared
  2163.     //  in the internal subset.
  2164.     if (fStandalone && !decl->getDeclaredInIntSubset())
  2165.         emitError(XMLErrs::IllegalRefInStandalone, bbName.getRawBuffer());
  2166.     if (decl->isExternal())
  2167.     {
  2168.         // If its unparsed, then its not valid here
  2169.         if (decl->isUnparsed())
  2170.         {
  2171.             emitError(XMLErrs::NoUnparsedEntityRefs, bbName.getRawBuffer());
  2172.             return EntityExp_Failed;
  2173.         }
  2174.         // If we are in an attribute value, then not valid but keep going
  2175.         if (inAttVal)
  2176.             emitError(XMLErrs::NoExtRefsInAttValue);
  2177.         // And now create a reader to read this entity
  2178.         InputSource* srcUsed;
  2179.         XMLReader* reader = fReaderMgr.createReader
  2180.         (
  2181.             decl->getBaseURI()
  2182.             , decl->getSystemId()
  2183.             , decl->getPublicId()
  2184.             , false
  2185.             , XMLReader::RefFrom_NonLiteral
  2186.             , XMLReader::Type_General
  2187.             , XMLReader::Source_External
  2188.             , srcUsed
  2189.             , fCalculateSrcOfs
  2190.         );
  2191.         // Put a janitor on the source so it gets cleaned up on exit
  2192.         Janitor<InputSource> janSrc(srcUsed);
  2193.         //  If the creation failed, and its not because the source was empty,
  2194.         //  then emit an error and return.
  2195.         if (!reader)
  2196.             ThrowXML1(RuntimeException, XMLExcepts::Gen_CouldNotOpenExtEntity, srcUsed->getSystemId());
  2197.         //  Push the reader. If its a recursive expansion, then emit an error
  2198.         //  and return an failure.
  2199.         if (!fReaderMgr.pushReader(reader, decl))
  2200.         {
  2201.             emitError(XMLErrs::RecursiveEntity, decl->getName());
  2202.             return EntityExp_Failed;
  2203.         }
  2204.         // here's where we need to check if there's a SecurityManager,
  2205.         // how many entity references we've had
  2206.         if(fSecurityManager != 0 && ++fEntityExpansionCount > fEntityExpansionLimit) {
  2207.             XMLCh expLimStr[16];
  2208.             XMLString::binToText(fEntityExpansionLimit, expLimStr, 15, 10);
  2209.             emitError
  2210.             ( 
  2211.                 XMLErrs::EntityExpansionLimitExceeded
  2212.                 , expLimStr
  2213.             );
  2214.             // there seems nothing  better to be done than to reset the entity expansion counter
  2215.             fEntityExpansionCount = 0;
  2216.         }
  2217.         //  Do a start entity reference event.
  2218.         //
  2219.         //  <TBD> For now, we supress them in att values. Later, when
  2220.         //  the stuff is in place to correctly allow DOM to handle them
  2221.         //  we'll turn this back on.
  2222.         if (fDocHandler && !inAttVal)
  2223.             fDocHandler->startEntityReference(*decl);
  2224.         // If it starts with the XML string, then parse a text decl
  2225.         if (checkXMLDecl(true))
  2226.             scanXMLDecl(Decl_Text);
  2227.     }
  2228.     else
  2229.     {
  2230.         //  If its one of the special char references, then we can return
  2231.         //  it as a character, and its considered escaped.
  2232.         if (decl->getIsSpecialChar())
  2233.         {
  2234.             firstCh = decl->getValue()[0];
  2235.             escaped = true;
  2236.             return EntityExp_Returned;
  2237.         }
  2238.         //  Create a reader over a memory stream over the entity value
  2239.         //  We force it to assume UTF-16 by passing in an encoding
  2240.         //  string. This way it won't both trying to predecode the
  2241.         //  first line, looking for an XML/TextDecl.
  2242.         XMLReader* valueReader = fReaderMgr.createIntEntReader
  2243.         (
  2244.             decl->getName()
  2245.             , XMLReader::RefFrom_NonLiteral
  2246.             , XMLReader::Type_General
  2247.             , decl->getValue()
  2248.             , decl->getValueLen()
  2249.             , false
  2250.         );
  2251.         //  Try to push the entity reader onto the reader manager stack,
  2252.         //  where it will become the subsequent input. If it fails, that
  2253.         //  means the entity is recursive, so issue an error. The reader
  2254.         //  will have just been discarded, but we just keep going.
  2255.         if (!fReaderMgr.pushReader(valueReader, decl))
  2256.             emitError(XMLErrs::RecursiveEntity, decl->getName());
  2257.         // here's where we need to check if there's a SecurityManager,
  2258.         // how many entity references we've had
  2259.         if(fSecurityManager != 0 && ++fEntityExpansionCount > fEntityExpansionLimit) {
  2260.             XMLCh expLimStr[16];
  2261.             XMLString::binToText(fEntityExpansionLimit, expLimStr, 15, 10);
  2262.             emitError
  2263.             ( 
  2264.                 XMLErrs::EntityExpansionLimitExceeded
  2265.                 , expLimStr
  2266.             );
  2267.         }
  2268.         //  Do a start entity reference event.
  2269.         //
  2270.         //  <TBD> For now, we supress them in att values. Later, when
  2271.         //  the stuff is in place to correctly allow DOM to handle them
  2272.         //  we'll turn this back on.
  2273.         if (fDocHandler && !inAttVal)
  2274.             fDocHandler->startEntityReference(*decl);
  2275.         // If it starts with the XML string, then it's an error
  2276.         if (checkXMLDecl(true)) {
  2277.             emitError(XMLErrs::TextDeclNotLegalHere);
  2278.             fReaderMgr.skipPastChar(chCloseAngle);
  2279.         }
  2280.     }
  2281.     return EntityExp_Pushed;
  2282. }
  2283. bool IGXMLScanner::switchGrammar(const XMLCh* const newGrammarNameSpace)
  2284. {
  2285.     Grammar* tempGrammar = fGrammarResolver->getGrammar(newGrammarNameSpace);
  2286.     if (!tempGrammar) {
  2287.         // This is a case where namespaces is on with a DTD grammar.
  2288.         tempGrammar = fDTDGrammar;
  2289.     }
  2290.     if (!tempGrammar) {
  2291.         return false;
  2292.     }
  2293.     else {
  2294.         fGrammar = tempGrammar;
  2295.         fGrammarType = fGrammar->getGrammarType();
  2296.         if (fGrammarType == Grammar::SchemaGrammarType && !fValidator->handlesSchema()) {
  2297.             if (fValidatorFromUser)
  2298.                 ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
  2299.             else {
  2300.                 fValidator = fSchemaValidator;
  2301.             }
  2302.         }
  2303.         else if (fGrammarType == Grammar::DTDGrammarType && !fValidator->handlesDTD()) {
  2304.             if (fValidatorFromUser)
  2305.                 ThrowXML(RuntimeException, XMLExcepts::Gen_NoDTDValidator);
  2306.             else {
  2307.                 fValidator = fDTDValidator;
  2308.             }
  2309.         }
  2310.         fValidator->setGrammar(fGrammar);
  2311.         return true;
  2312.     }
  2313. }
  2314. // check if we should skip or lax the validation of the element
  2315. // if skip - no validation
  2316. // if lax - validate only if the element if found
  2317. bool IGXMLScanner::laxElementValidation(QName* element, ContentLeafNameTypeVector* cv,
  2318.                                         const XMLContentModel* const cm,
  2319.                                         const unsigned int parentElemDepth)
  2320. {
  2321.     bool skipThisOne = false;
  2322.     bool laxThisOne = false;
  2323.     unsigned int elementURI = element->getURI();
  2324.     unsigned int currState = fElemState[parentElemDepth];
  2325.     if (currState == XMLContentModel::gInvalidTrans) {
  2326.         return laxThisOne;
  2327.     }
  2328.     SubstitutionGroupComparator comparator(fGrammarResolver, fURIStringPool);
  2329.     if (cv) {
  2330.         unsigned int i = 0;
  2331.         unsigned int leafCount = cv->getLeafCount();
  2332.         for (; i < leafCount; i++) {
  2333.             QName* fElemMap = cv->getLeafNameAt(i);
  2334.             unsigned int uri = fElemMap->getURI();
  2335.             unsigned int nextState;
  2336.             bool anyEncountered = false;
  2337.             ContentSpecNode::NodeTypes type = cv->getLeafTypeAt(i);
  2338.             if (type == ContentSpecNode::Leaf) {
  2339.                 if (((uri == elementURI)
  2340.                       && XMLString::equals(fElemMap->getLocalPart(), element->getLocalPart()))
  2341.                     || comparator.isEquivalentTo(element, fElemMap)) {
  2342.                     nextState = cm->getNextState(currState, i);
  2343.                     if (nextState != XMLContentModel::gInvalidTrans) {
  2344.                         fElemState[parentElemDepth] = nextState;
  2345.                         break;
  2346.                     }
  2347.                 }
  2348.             } else if ((type & 0x0f) == ContentSpecNode::Any) {
  2349.                 anyEncountered = true;
  2350.             }
  2351.             else if ((type & 0x0f) == ContentSpecNode::Any_Other) {
  2352.                 if (uri != elementURI) {
  2353.                     anyEncountered = true;
  2354.                 }
  2355.             }
  2356.             else if ((type & 0x0f) == ContentSpecNode::Any_NS) {
  2357.                 if (uri == elementURI) {
  2358.                     anyEncountered = true;
  2359.                 }
  2360.             }
  2361.             if (anyEncountered) {
  2362.                 nextState = cm->getNextState(currState, i);
  2363.                 if (nextState != XMLContentModel::gInvalidTrans) {
  2364.                     fElemState[parentElemDepth] = nextState;
  2365.                     if (type == ContentSpecNode::Any_Skip ||
  2366.                         type == ContentSpecNode::Any_NS_Skip ||
  2367.                         type == ContentSpecNode::Any_Other_Skip) {
  2368.                         skipThisOne = true;
  2369.                     }
  2370.                     else if (type == ContentSpecNode::Any_Lax ||
  2371.                              type == ContentSpecNode::Any_NS_Lax ||
  2372.                              type == ContentSpecNode::Any_Other_Lax) {
  2373.                         laxThisOne = true;
  2374.                     }
  2375.                     break;
  2376.                 }
  2377.             }
  2378.         } // for
  2379.         if (i == leafCount) { // no match
  2380.             fElemState[parentElemDepth] = XMLContentModel::gInvalidTrans;
  2381.             return laxThisOne;
  2382.         }
  2383.     } // if
  2384.     if (skipThisOne) {
  2385.         fValidate = false;
  2386.         fElemStack.setValidationFlag(fValidate);
  2387.     }
  2388.     return laxThisOne;
  2389. }
  2390. // check if there is an AnyAttribute, and if so, see if we should lax or skip
  2391. // if skip - no validation
  2392. // if lax - validate only if the attribute if found
  2393. bool IGXMLScanner::anyAttributeValidation(SchemaAttDef* attWildCard, unsigned int uriId, bool& skipThisOne, bool& laxThisOne)
  2394. {
  2395.     XMLAttDef::AttTypes wildCardType = attWildCard->getType();
  2396.     bool anyEncountered = false;
  2397.     skipThisOne = false;
  2398.     laxThisOne = false;
  2399.     if (wildCardType == XMLAttDef::Any_Any)
  2400.         anyEncountered = true;
  2401.     else if (wildCardType == XMLAttDef::Any_Other) {
  2402.         if (attWildCard->getAttName()->getURI() != uriId
  2403.             && uriId != fEmptyNamespaceId)
  2404.             anyEncountered = true;
  2405.     }
  2406.     else if (wildCardType == XMLAttDef::Any_List) {
  2407.         ValueVectorOf<unsigned int>* nameURIList = attWildCard->getNamespaceList();
  2408.         unsigned int listSize = (nameURIList) ? nameURIList->size() : 0;
  2409.         if (listSize) {
  2410.             for (unsigned int i=0; i < listSize; i++) {
  2411.                 if (nameURIList->elementAt(i) == uriId)
  2412.                     anyEncountered = true;
  2413.             }
  2414.         }
  2415.     }
  2416.     if (anyEncountered) {
  2417.         XMLAttDef::DefAttTypes   defType   = attWildCard->getDefaultType();
  2418.         if (defType == XMLAttDef::ProcessContents_Skip) {
  2419.             // attribute should just be bypassed,
  2420.             skipThisOne = true;
  2421.         }
  2422.         else if (defType == XMLAttDef::ProcessContents_Lax) {
  2423.             laxThisOne = true;
  2424.         }
  2425.     }
  2426.     return anyEncountered;
  2427. }
  2428. void IGXMLScanner::normalizeURI(const XMLCh* const systemURI,
  2429.                                 XMLBuffer& normalizedURI)
  2430. {
  2431.     const XMLCh* pszSrc = systemURI;
  2432.     normalizedURI.reset();
  2433.     while (*pszSrc) {
  2434.         if ((*(pszSrc) == chPercent)
  2435.         &&  (*(pszSrc+1) == chDigit_2)
  2436.         &&  (*(pszSrc+2) == chDigit_0))
  2437.         {
  2438.             pszSrc += 3;
  2439.             normalizedURI.append(chSpace);
  2440.         }
  2441.         else if (*pszSrc == 0xFFFF) { //escaped character
  2442.             pszSrc++;
  2443.         }
  2444.         else {
  2445.             normalizedURI.append(*pszSrc);
  2446.             pszSrc++;
  2447.         }
  2448.     }
  2449. }
  2450. XERCES_CPP_NAMESPACE_END