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

词法分析

开发平台:

Visual C++

  1.                                 // the attribute should be qualified
  2.                                 fValidator->emitError
  3.                                 (
  4.                                     XMLValid::AttributeNotUnQualified
  5.                                     , attDef->getFullName()
  6.                                 );
  7.                                 ((SchemaAttDef *)(attDef))->setValidity(PSVIDefs::INVALID);
  8.                             }
  9.                         }
  10.                     }
  11.                 }
  12.             }
  13.             //  Find this attribute within the parent element. We pass both
  14.             //  the uriID/name and the raw QName buffer, since we don't know
  15.             //  how the derived validator and its elements store attributes.
  16.             bool wasAdded = false;
  17.             if (!attDef) {
  18.                 attDef = elemDecl->findAttr
  19.                 (
  20.                     curPair->getKey()
  21.                     , uriId
  22.                     , suffPtr
  23.                     , prefPtr
  24.                     , XMLElementDecl::AddIfNotFound
  25.                     , wasAdded
  26.                 );
  27.             }
  28.             if(!skipThisOne && fGrammarType == Grammar::SchemaGrammarType) {
  29.                 //we may have set it to invalid already, but this is the first time we are guarenteed to have the attDef
  30.                 if(((SchemaAttDef *)(attDef))->getValidity() != PSVIDefs::INVALID)
  31.                     ((SchemaAttDef *)(attDef))->setValidity(PSVIDefs::VALID);
  32.                     
  33.                 ((SchemaAttDef *)(attDef))->setValidationAttempted(PSVIDefs::FULL);
  34.             }
  35.             if (wasAdded)
  36.             {
  37.                 // This is to tell the Validator that this attribute was
  38.                 // faulted-in, was not an attribute in the attdef originally
  39.                 attDef->setCreateReason(XMLAttDef::JustFaultIn);
  40.             }
  41.             bool errorCondition = fValidate && !attDefForWildCard && 
  42.                 attDef->getCreateReason() == XMLAttDef::JustFaultIn && !attDef->getProvided();
  43.             if (errorCondition && !skipThisOne && !laxThisOne)
  44.             {
  45.                 //
  46.                 //  Its not valid for this element, so issue an error if we are
  47.                 //  validating.
  48.                 //
  49.                 XMLBufBid bbMsg(&fBufMgr);
  50.                 XMLBuffer& bufMsg = bbMsg.getBuffer();
  51.                 if (uriId != fEmptyNamespaceId) {
  52.                     XMLBufBid bbURI(&fBufMgr);
  53.                     XMLBuffer& bufURI = bbURI.getBuffer();
  54.                     getURIText(uriId, bufURI);
  55.                     bufMsg.append(chOpenCurly);
  56.                     bufMsg.append(bufURI.getRawBuffer());
  57.                     bufMsg.append(chCloseCurly);
  58.                 }
  59.                 bufMsg.append(suffPtr);
  60.                 fValidator->emitError
  61.                 (
  62.                     XMLValid::AttNotDefinedForElement
  63.                     , bufMsg.getRawBuffer()
  64.                     , elemDecl->getFullName()
  65.                 );
  66.                 ((SchemaAttDef *)attDef)->setValidity(PSVIDefs::INVALID);
  67.             }
  68.             else if(errorCondition && laxThisOne) {
  69.                 ((SchemaAttDef *)(attDef))->setValidationAttempted(PSVIDefs::NONE);
  70.                 ((SchemaAttDef *)(attDef))->setValidity(PSVIDefs::UNKNOWN);
  71.             }
  72.             //  If its already provided, then there are more than one of
  73.             //  this attribute in this start tag, so emit an error.
  74.             if (attDef->getProvided())
  75.             {
  76.                 emitError
  77.                 (
  78.                     XMLErrs::AttrAlreadyUsedInSTag
  79.                     , attDef->getFullName()
  80.                     , elemDecl->getFullName()
  81.                 );
  82.                 ((SchemaAttDef *)(attDef))->setValidity(PSVIDefs::INVALID);
  83.             }
  84.             else
  85.             {
  86.                 attDef->setProvided(true);
  87.             }
  88.             //  Now normalize the raw value since we have the attribute type. We
  89.             //  don't care about the return status here. If it failed, an error
  90.             //  was issued, which is all we care about.
  91.             if (attDefForWildCard) {
  92.                 ((SchemaAttDef*)attDef)->setAnyDatatypeValidator(((SchemaAttDef*) attDefForWildCard)->getDatatypeValidator());
  93.                 normalizeAttValue
  94.                 (
  95.                     attDefForWildCard
  96.                     , curPair->getValue()
  97.                     , normBuf
  98.                 );
  99.                 //  If we found an attdef for this one, then lets validate it.
  100.                 if (fNormalizeData)
  101.                 {
  102.                     // normalize the attribute according to schema whitespace facet
  103.                     XMLBufBid bbtemp(&fBufMgr);
  104.                     XMLBuffer& tempBuf = bbtemp.getBuffer();
  105.                     DatatypeValidator* tempDV = ((SchemaAttDef*) attDefForWildCard)->getDatatypeValidator();
  106.                     ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, normBuf.getRawBuffer(), tempBuf);
  107.                     normBuf.set(tempBuf.getRawBuffer());
  108.                 }
  109.                 if (fValidate && !skipThisOne) {
  110.                     fValidator->validateAttrValue
  111.                     (
  112.                         attDefForWildCard
  113.                         , normBuf.getRawBuffer()
  114.                         , false
  115.                         , elemDecl
  116.                     );
  117.                 }
  118.                 // Save the type for later use
  119.                 attType = attDefForWildCard->getType();
  120.                 ((SchemaElementDecl *)(elemDecl))->updateValidityFromAttribute((SchemaAttDef *)attDef);
  121.                 DatatypeValidator* tempDV = ((SchemaAttDef*) attDefForWildCard)->getDatatypeValidator();
  122.                 if(tempDV && tempDV->getType() == DatatypeValidator::Union)
  123.                     ((SchemaAttDef*)attDef)->setMembertypeValidator(((UnionDatatypeValidator *)tempDV)->getMemberTypeValidator());
  124.             }
  125.             else {
  126.                 normalizeAttValue
  127.                 (
  128.                     attDef
  129.                     , curPair->getValue()
  130.                     , normBuf
  131.                 );
  132.                 //  If we found an attdef for this one, then lets validate it.
  133.                 if (attDef->getCreateReason() != XMLAttDef::JustFaultIn)
  134.                 {
  135.                     if (fNormalizeData && (fGrammarType == Grammar::SchemaGrammarType))
  136.                     {
  137.                         // normalize the attribute according to schema whitespace facet
  138.                         XMLBufBid bbtemp(&fBufMgr);
  139.                         XMLBuffer& tempBuf = bbtemp.getBuffer();
  140.                         DatatypeValidator* tempDV = ((SchemaAttDef*) attDef)->getDatatypeValidator();
  141.                         ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, normBuf.getRawBuffer(), tempBuf);
  142.                         normBuf.set(tempBuf.getRawBuffer());
  143.                     }
  144.                     if (fValidate && !skipThisOne)
  145.                     {
  146.                         fValidator->validateAttrValue
  147.                         (
  148.                             attDef
  149.                             , normBuf.getRawBuffer()
  150.                             , false
  151.                             , elemDecl
  152.                         );
  153.                     }
  154.                 }
  155.                 // Save the type for later use
  156.                 attType = attDef->getType();
  157.                 ((SchemaElementDecl *)(elemDecl))->updateValidityFromAttribute((SchemaAttDef *)attDef);
  158.             }
  159.         }
  160.         else
  161.         {
  162.             // Just normalize as CDATA
  163.             attType = XMLAttDef::CData;
  164.             normalizeAttRawValue
  165.             (
  166.                 curPair->getKey()
  167.                 , curPair->getValue()
  168.                 , normBuf
  169.             );
  170.         }
  171.         //  Add this attribute to the attribute list that we use to pass them
  172.         //  to the handler. We reuse its existing elements but expand it as
  173.         //  required.
  174.         XMLAttr* curAttr;
  175.         if (retCount >= curAttListSize)
  176.         {
  177.             curAttr = new (fMemoryManager) XMLAttr
  178.             (
  179.                 uriId
  180.                 , suffPtr
  181.                 , prefPtr
  182.                 , normBuf.getRawBuffer()
  183.                 , attType
  184.                 , true
  185.                 , fMemoryManager
  186.             );
  187.             toFill.addElement(curAttr);
  188.         }
  189.         else
  190.         {
  191.             curAttr = toFill.elementAt(retCount);
  192.             curAttr->set
  193.             (
  194.                 uriId
  195.                 , suffPtr
  196.                 , prefPtr
  197.                 , normBuf.getRawBuffer()
  198.                 , attType
  199.             );
  200.             curAttr->setSpecified(true);
  201.         }
  202.         // Bump the count of attrs in the list
  203.         retCount++;
  204.     }
  205.     //  Now, if there are any attributes declared by this element, let's
  206.     //  go through them and make sure that any required ones are provided,
  207.     //  and fault in any fixed ones and defaulted ones that are not provided
  208.     //  literally.
  209.     if (hasDefs)
  210.     {
  211.         // Check after all specified attrs are scanned
  212.         // (1) report error for REQUIRED attrs that are missing (V_TAGc)
  213.         // (2) add default attrs if missing (FIXED and NOT_FIXED)
  214.         XMLAttDefList& attDefList = elemDecl->getAttDefList();
  215.         while (attDefList.hasMoreElements())
  216.         {
  217.             // Get the current att def, for convenience and its def type
  218.             XMLAttDef *curDef = &attDefList.nextElement();
  219.             const XMLAttDef::DefAttTypes defType = curDef->getDefaultType();
  220.             if (!curDef->getProvided())
  221.             {
  222.                 ((SchemaAttDef *)curDef)->setValidationAttempted(PSVIDefs::FULL);
  223.                 ((SchemaAttDef *)curDef)->setValidity(PSVIDefs::VALID);
  224.                 //the attributes is not provided
  225.                 if (fValidate)
  226.                 {
  227.                     // If we are validating and its required, then an error
  228.                     if ((defType == XMLAttDef::Required) ||
  229.                         (defType == XMLAttDef::Required_And_Fixed)  )
  230.                     {
  231.                         fValidator->emitError
  232.                         (
  233.                             XMLValid::RequiredAttrNotProvided
  234.                             , curDef->getFullName()
  235.                         );
  236.                         ((SchemaAttDef *)(curDef))->setValidity(PSVIDefs::INVALID);
  237.                     }
  238.                     else if ((defType == XMLAttDef::Default) ||
  239.                              (defType == XMLAttDef::Fixed)  )
  240.                     {
  241.                         if (fStandalone && curDef->isExternal())
  242.                         {
  243.                             // XML 1.0 Section 2.9
  244.                             // Document is standalone, so attributes must not be defaulted.
  245.                             fValidator->emitError(XMLValid::NoDefAttForStandalone, curDef->getFullName(), elemDecl->getFullName());
  246.                             ((SchemaAttDef *)(curDef))->setValidity(PSVIDefs::INVALID);
  247.                         }
  248.                     }
  249.                 }
  250.                 //  Fault in the value if needed, and bump the att count.
  251.                 //  We have to
  252.                 if ((defType == XMLAttDef::Default)
  253.                 ||  (defType == XMLAttDef::Fixed))
  254.                 {
  255.                     // Let the validator pass judgement on the attribute value
  256.                     if (fValidate)
  257.                     {
  258.                         fValidator->validateAttrValue
  259.                         (
  260.                             curDef
  261.                             , curDef->getValue()
  262.                             , false
  263.                             , elemDecl
  264.                         );
  265.                     }
  266.                     XMLAttr* curAtt;
  267.                     if (retCount >= curAttListSize)
  268.                     {
  269.                         curAtt = new (fMemoryManager) XMLAttr(fMemoryManager);
  270.                         fValidator->faultInAttr(*curAtt, *curDef);
  271.                         fAttrList->addElement(curAtt);
  272.                     }
  273.                     else
  274.                     {
  275.                         curAtt = fAttrList->elementAt(retCount);
  276.                         fValidator->faultInAttr(*curAtt, *curDef);
  277.                     }
  278.                     // Indicate it was not explicitly specified and bump count
  279.                     curAtt->setSpecified(false);
  280.                     retCount++;
  281.                 }
  282.                 ((SchemaElementDecl *)elemDecl)->updateValidityFromAttribute((SchemaAttDef *)curDef);
  283.             }
  284.             else
  285.             {
  286.                 //attribute is provided
  287.                 // (schema) report error for PROHIBITED attrs that are present (V_TAGc)
  288.                 if (defType == XMLAttDef::Prohibited && fValidate) {
  289.                     fValidator->emitError
  290.                     (
  291.                         XMLValid::ProhibitedAttributePresent
  292.                         , curDef->getFullName()
  293.                     );
  294.                     ((SchemaAttDef *)curDef)->setValidity(PSVIDefs::INVALID);         
  295.                 }
  296.                 ((SchemaElementDecl *)elemDecl)->updateValidityFromAttribute((SchemaAttDef *)curDef);
  297.             }
  298.         }
  299.     }
  300.     return retCount;
  301. }
  302. //  This method will take a raw attribute value and normalize it according to
  303. //  the rules of the attribute type. It will put the resulting value into the
  304. //  passed buffer.
  305. //
  306. //  This code assumes that escaped characters in the original value (via char
  307. //  refs) are prefixed by a 0xFFFF character. This is because some characters
  308. //  are legal if escaped only. And some escape chars are not subject to
  309. //  normalization rules.
  310. bool SGXMLScanner::normalizeAttValue( const   XMLAttDef* const    attDef
  311.                                       , const XMLCh* const        value
  312.                                       ,       XMLBuffer&          toFill)
  313. {
  314.     // A simple state value for a whitespace processing state machine
  315.     enum States
  316.     {
  317.         InWhitespace
  318.         , InContent
  319.     };
  320.     // Get the type and name
  321.     const XMLAttDef::AttTypes type = attDef->getType();
  322.     const XMLCh* const attrName = attDef->getFullName();
  323.     // Assume its going to go fine, and empty the target buffer in preperation
  324.     bool retVal = true;
  325.     toFill.reset();
  326.     // Get attribute def - to check to see if it's declared externally or not
  327.     bool  isAttExternal = attDef->isExternal();
  328.     //  Loop through the chars of the source value and normalize it according
  329.     //  to the type.
  330.     States curState = InContent;
  331.     bool escaped;
  332.     bool firstNonWS = false;
  333.     XMLCh nextCh;
  334.     const XMLCh* srcPtr = value;
  335.     while (*srcPtr)
  336.     {
  337.         //  Get the next character from the source. We have to watch for
  338.         //  escaped characters (which are indicated by a 0xFFFF value followed
  339.         //  by the char that was escaped.)
  340.         nextCh = *srcPtr;
  341.         escaped = (nextCh == 0xFFFF);
  342.         if (escaped)
  343.             nextCh = *++srcPtr;
  344.         //  If its not escaped, then make sure its not a < character, which is
  345.         //  not allowed in attribute values.
  346.         if (!escaped && (*srcPtr == chOpenAngle))
  347.         {
  348.             emitError(XMLErrs::BracketInAttrValue, attrName);
  349.             retVal = false;
  350.         }
  351.         if (type == XMLAttDef::CData || type > XMLAttDef::Notation)
  352.         {
  353.             if (!escaped)
  354.             {
  355.                 if ((nextCh == 0x09) || (nextCh == 0x0A) || (nextCh == 0x0D))
  356.                 {
  357.                     // Check Validity Constraint for Standalone document declaration
  358.                     // XML 1.0, Section 2.9
  359.                     if (fStandalone && fValidate && isAttExternal)
  360.                     {
  361.                          // Can't have a standalone document declaration of "yes" if  attribute
  362.                          // values are subject to normalisation
  363.                          fValidator->emitError(XMLValid::NoAttNormForStandalone, attrName);
  364.                          ((SchemaAttDef *)attDef)->setValidity(PSVIDefs::INVALID);     
  365.                     }
  366.                     nextCh = chSpace;
  367.                 }
  368.             }
  369.         }
  370.         else
  371.         {
  372.             if (curState == InWhitespace)
  373.             {
  374.                 if (!fReaderMgr.getCurrentReader()->isWhitespace(nextCh))
  375.                 {
  376.                     if (firstNonWS)
  377.                         toFill.append(chSpace);
  378.                     curState = InContent;
  379.                     firstNonWS = true;
  380.                 }
  381.                 else
  382.                 {
  383.                     srcPtr++;
  384.                     continue;
  385.                 }
  386.             }
  387.             else if (curState == InContent)
  388.             {
  389.                 if (fReaderMgr.getCurrentReader()->isWhitespace(nextCh))
  390.                 {
  391.                     curState = InWhitespace;
  392.                     srcPtr++;
  393.                     // Check Validity Constraint for Standalone document declaration
  394.                     // XML 1.0, Section 2.9
  395.                     if (fStandalone && fValidate && isAttExternal)
  396.                     {
  397.                         if (!firstNonWS || (nextCh != chSpace) || (!*srcPtr) || fReaderMgr.getCurrentReader()->isWhitespace(*srcPtr))
  398.                         {
  399.                              // Can't have a standalone document declaration of "yes" if  attribute
  400.                              // values are subject to normalisation
  401.                              fValidator->emitError(XMLValid::NoAttNormForStandalone, attrName);
  402.                              ((SchemaAttDef *)attDef)->setValidity(PSVIDefs::INVALID);
  403.                         }
  404.                     }
  405.                     continue;
  406.                 }
  407.                 firstNonWS = true;
  408.             }
  409.         }
  410.         // Add this char to the target buffer
  411.         toFill.append(nextCh);
  412.         // And move up to the next character in the source
  413.         srcPtr++;
  414.     }
  415.     ((SchemaElementDecl *)fElemStack.topElement()->fThisElement)->updateValidityFromAttribute((SchemaAttDef *)attDef);
  416.     return retVal;
  417. }
  418. //  This method will just normalize the input value as CDATA without
  419. //  any standalone checking.
  420. bool SGXMLScanner::normalizeAttRawValue( const   XMLCh* const        attrName
  421.                                       , const XMLCh* const        value
  422.                                       ,       XMLBuffer&          toFill)
  423. {
  424.     // Assume its going to go fine, and empty the target buffer in preperation
  425.     bool retVal = true;
  426.     toFill.reset();
  427.     //  Loop through the chars of the source value and normalize it according
  428.     //  to the type.
  429.     bool escaped;
  430.     XMLCh nextCh;
  431.     const XMLCh* srcPtr = value;
  432.     while (*srcPtr)
  433.     {
  434.         //  Get the next character from the source. We have to watch for
  435.         //  escaped characters (which are indicated by a 0xFFFF value followed
  436.         //  by the char that was escaped.)
  437.         nextCh = *srcPtr;
  438.         escaped = (nextCh == 0xFFFF);
  439.         if (escaped)
  440.             nextCh = *++srcPtr;
  441.         //  If its not escaped, then make sure its not a < character, which is
  442.         //  not allowed in attribute values.
  443.         if (!escaped && (*srcPtr == chOpenAngle))
  444.         {
  445.             emitError(XMLErrs::BracketInAttrValue, attrName);
  446.             retVal = false;
  447.         }
  448.         if (!escaped)
  449.         {
  450.             //  NOTE: Yes this is a little redundant in that a 0x20 is
  451.             //  replaced with an 0x20. But its faster to do this (I think)
  452.             //  than checking for 9, A, and D separately.
  453.             if (fReaderMgr.getCurrentReader()->isWhitespace(nextCh))
  454.                 nextCh = chSpace;
  455.         }
  456.         // Add this char to the target buffer
  457.         toFill.append(nextCh);
  458.         // And move up to the next character in the source
  459.         srcPtr++;
  460.     }
  461.     return retVal;
  462. }
  463. unsigned int
  464. SGXMLScanner::resolvePrefix(  const   XMLCh* const        prefix
  465.                               , const ElemStack::MapModes mode)
  466. {
  467.     //  Watch for the special namespace prefixes. We always map these to
  468.     //  special URIs. 'xml' gets mapped to the official URI that its defined
  469.     //  to map to by the NS spec. xmlns gets mapped to a special place holder
  470.     //  URI that we define (so that it maps to something checkable.)
  471.     if (XMLString::equals(prefix, XMLUni::fgXMLNSString))
  472.         return fXMLNSNamespaceId;
  473.     else if (XMLString::equals(prefix, XMLUni::fgXMLString))
  474.         return fXMLNamespaceId;
  475.     //  Ask the element stack to search up itself for a mapping for the
  476.     //  passed prefix.
  477.     bool unknown;
  478.     unsigned int uriId = fElemStack.mapPrefixToURI(prefix, mode, unknown);
  479.     // If it was unknown, then the URI was faked in but we have to issue an error
  480.     if (unknown)
  481.         emitError(XMLErrs::UnknownPrefix, prefix);
  482.     return uriId;
  483. }
  484. unsigned int
  485. SGXMLScanner::resolvePrefix(  const   XMLCh* const        prefix
  486.                               ,       XMLBuffer&          bufToFill
  487.                               , const ElemStack::MapModes mode)
  488. {
  489.     //  Watch for the special namespace prefixes. We always map these to
  490.     //  special URIs. 'xml' gets mapped to the official URI that its defined
  491.     //  to map to by the NS spec. xmlns gets mapped to a special place holder
  492.     //  URI that we define (so that it maps to something checkable.)
  493.     if (XMLString::equals(prefix, XMLUni::fgXMLNSString))
  494.         return fXMLNSNamespaceId;
  495.     else if (XMLString::equals(prefix, XMLUni::fgXMLString))
  496.         return fXMLNamespaceId;
  497.     //  Ask the element stack to search up itself for a mapping for the
  498.     //  passed prefix.
  499.     bool unknown;
  500.     unsigned int uriId = fElemStack.mapPrefixToURI(prefix, mode, unknown);
  501.     // If it was unknown, then the URI was faked in but we have to issue an error
  502.     if (unknown)
  503.         emitError(XMLErrs::UnknownPrefix, prefix);
  504.     getURIText(uriId,bufToFill);
  505.     return uriId;
  506. }
  507. //  This method will reset the scanner data structures, and related plugged
  508. //  in stuff, for a new scan session. We get the input source for the primary
  509. //  XML entity, create the reader for it, and push it on the stack so that
  510. //  upon successful return from here we are ready to go.
  511. void SGXMLScanner::scanReset(const InputSource& src)
  512. {
  513.     //  This call implicitly tells us that we are going to reuse the scanner
  514.     //  if it was previously used. So tell the validator to reset itself.
  515.     //
  516.     //  But, if the fUseCacheGrammar flag is set, then don't reset it.
  517.     //
  518.     //  NOTE:   The ReaderMgr is flushed on the way out, because that is
  519.     //          required to insure that files are closed.
  520.     fGrammarResolver->cacheGrammarFromParse(fToCacheGrammar);
  521.     fGrammarResolver->useCachedGrammarInParse(fUseCachedGrammar);
  522.     fGrammar = fSchemaGrammar;
  523.     fGrammarType = Grammar::DTDGrammarType;
  524.     fRootGrammar = 0;
  525.     fValidator->setGrammar(fGrammar);
  526.     if (fValidatorFromUser) {
  527.         ((SchemaValidator*) fValidator)->setErrorReporter(fErrorReporter);
  528.         ((SchemaValidator*) fValidator)->setGrammarResolver(fGrammarResolver);
  529.         ((SchemaValidator*) fValidator)->setExitOnFirstFatal(fExitOnFirstFatal);
  530.     }
  531.     // Reset validation
  532.     fValidate = (fValScheme == Val_Always) ? true : false;
  533.     //  And for all installed handlers, send reset events. This gives them
  534.     //  a chance to flush any cached data.
  535.     if (fDocHandler)
  536.         fDocHandler->resetDocument();
  537.     if (fEntityHandler)
  538.         fEntityHandler->resetEntities();
  539.     if (fErrorReporter)
  540.         fErrorReporter->resetErrors();
  541.     // Clear out the id reference list
  542.     fIDRefList->removeAll();
  543.     // Reset IdentityConstraints
  544.     fValueStoreCache->startDocument();
  545.     fMatcherStack->clear();
  546.     //  Reset the element stack, and give it the latest ids for the special
  547.     //  URIs it has to know about.
  548.     fElemStack.reset
  549.     (
  550.         fEmptyNamespaceId
  551.         , fUnknownNamespaceId
  552.         , fXMLNamespaceId
  553.         , fXMLNSNamespaceId
  554.     );
  555.     if (!fSchemaNamespaceId)
  556.         fSchemaNamespaceId  = fURIStringPool->addOrFind(SchemaSymbols::fgURI_XSI);
  557.     // Reset some status flags
  558.     fInException = false;
  559.     fStandalone = false;
  560.     fErrorCount = 0;
  561.     fHasNoDTD = true;
  562.     fSeeXsi = false;
  563.     fDoNamespaces = true;
  564.     fDoSchema = true;
  565.     // Reset the validators
  566.     fSchemaValidator->reset();
  567.     fSchemaValidator->setErrorReporter(fErrorReporter);
  568.     fSchemaValidator->setExitOnFirstFatal(fExitOnFirstFatal);
  569.     fSchemaValidator->setGrammarResolver(fGrammarResolver);
  570.     if (fValidatorFromUser)
  571.         fValidator->reset();
  572.     //  Handle the creation of the XML reader object for this input source.
  573.     //  This will provide us with transcoding and basic lexing services.
  574.     XMLReader* newReader = fReaderMgr.createReader
  575.     (
  576.         src
  577.         , true
  578.         , XMLReader::RefFrom_NonLiteral
  579.         , XMLReader::Type_General
  580.         , XMLReader::Source_External
  581.         , fCalculateSrcOfs
  582.     );
  583.     if (!newReader) {
  584.         if (src.getIssueFatalErrorIfNotFound())
  585.             ThrowXML1(RuntimeException, XMLExcepts::Scan_CouldNotOpenSource, src.getSystemId());
  586.         else
  587.             ThrowXML1(RuntimeException, XMLExcepts::Scan_CouldNotOpenSource_Warning, src.getSystemId());
  588.     }
  589.     // Push this read onto the reader manager
  590.     fReaderMgr.pushReader(newReader, 0);
  591.     // and reset security-related things if necessary:
  592.     if(fSecurityManager != 0) 
  593.     {
  594.         fEntityExpansionLimit = fSecurityManager->getEntityExpansionLimit();
  595.         fEntityExpansionCount = 0;
  596.     }
  597. }
  598. //  This method is called between markup in content. It scans for character
  599. //  data that is sent to the document handler. It watches for any markup
  600. //  characters that would indicate that the character data has ended. It also
  601. //  handles expansion of general and character entities.
  602. //
  603. //  sendData() is a local static helper for this method which handles some
  604. //  code that must be done in three different places here.
  605. void SGXMLScanner::sendCharData(XMLBuffer& toSend)
  606. {
  607.     // If no data in the buffer, then nothing to do
  608.     if (toSend.isEmpty())
  609.         return;
  610.     //  We do different things according to whether we are validating or
  611.     //  not. If not, its always just characters; else, it depends on the
  612.     //  current element's content model.
  613.     if (fValidate)
  614.     {
  615.         // Get the raw data we need for the callback
  616.         const XMLCh* const rawBuf = toSend.getRawBuffer();
  617.         const unsigned int len = toSend.getLen();
  618.         // And see if the current element is a 'Children' style content model
  619.         const ElemStack::StackElem* topElem = fElemStack.topElement();
  620.         // Get the character data opts for the current element
  621.         XMLElementDecl::CharDataOpts charOpts = topElem->fThisElement->getCharDataOpts();
  622.         if (charOpts == XMLElementDecl::NoCharData)
  623.         {
  624.             // They definitely cannot handle any type of char data
  625.             fValidator->emitError(XMLValid::NoCharDataInCM);
  626.             ((SchemaElementDecl *)topElem->fThisElement)->setValidity(PSVIDefs::INVALID);
  627.         }
  628.         else if (fReaderMgr.getCurrentReader()->isAllSpaces(rawBuf, len))
  629.         {
  630.             //  Its all spaces. So, if they can take spaces, then send it
  631.             //  as ignorable whitespace. If they can handle any char data
  632.             //  send it as characters.
  633.             if (charOpts == XMLElementDecl::SpacesOk) {
  634.                 if (fDocHandler)
  635.                     fDocHandler->ignorableWhitespace(rawBuf, len, false);
  636.             }
  637.             else if (charOpts == XMLElementDecl::AllCharData)
  638.             {
  639.                 // The normalized data can only be as large as the
  640.                 // original size, so this will avoid allocating way
  641.                 // too much or too little memory.
  642.                 XMLBuffer toFill(len+1, fMemoryManager);
  643.                 toFill.set(rawBuf);
  644.                 if (fNormalizeData) {
  645.                     // normalize the character according to schema whitespace facet
  646.                     XMLBufBid bbtemp(&fBufMgr);
  647.                     XMLBuffer& tempBuf = bbtemp.getBuffer();
  648.                     DatatypeValidator* tempDV = ((SchemaElementDecl*) topElem->fThisElement)->getDatatypeValidator();
  649.                     ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, toFill.getRawBuffer(),  tempBuf);
  650.                     toFill.set(tempBuf.getRawBuffer());
  651.                 }
  652.                 // tell the schema validation about the character data for checkContent later
  653.                 ((SchemaValidator*) fValidator)->setDatatypeBuffer(toFill.getRawBuffer());
  654.                 // call all active identity constraints
  655.                 if (fMatcherStack->getMatcherCount())
  656.                     fContent.append(toFill.getRawBuffer(), toFill.getLen());
  657.                 if (fDocHandler)
  658.                     fDocHandler->docCharacters(toFill.getRawBuffer(), toFill.getLen(), false);
  659.             }
  660.         }
  661.         else
  662.         {
  663.             //  If they can take any char data, then send it. Otherwise, they
  664.             //  can only handle whitespace and can't handle this stuff so
  665.             //  issue an error.
  666.             if (charOpts == XMLElementDecl::AllCharData)
  667.             {
  668.                 // The normalized data can only be as large as the
  669.                 // original size, so this will avoid allocating way
  670.                 // too much or too little memory.
  671.                 XMLBuffer toFill(len+1, fMemoryManager);
  672.                 toFill.set(rawBuf);
  673.                 if (fNormalizeData) {
  674.                     // normalize the character according to schema whitespace facet
  675.                     XMLBufBid bbtemp(&fBufMgr);
  676.                     XMLBuffer& tempBuf = bbtemp.getBuffer();
  677.                     DatatypeValidator* tempDV = ((SchemaElementDecl*) topElem->fThisElement)->getDatatypeValidator();
  678.                     ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, toFill.getRawBuffer(),  tempBuf);
  679.                     toFill.set(tempBuf.getRawBuffer());
  680.                 }
  681.                 // tell the schema validation about the character data for checkContent later
  682.                 ((SchemaValidator*) fValidator)->setDatatypeBuffer(toFill.getRawBuffer());
  683.                 // call all active identity constraints
  684.                 if (fMatcherStack->getMatcherCount())
  685.                     fContent.append(toFill.getRawBuffer(), toFill.getLen());
  686.                 if (fDocHandler)
  687.                     fDocHandler->docCharacters(toFill.getRawBuffer(), toFill.getLen(), false);
  688.             }
  689.             else
  690.             {
  691.                 fValidator->emitError(XMLValid::NoCharDataInCM);
  692.                 ((SchemaElementDecl *)topElem->fThisElement)->setValidity(PSVIDefs::INVALID);
  693.             }
  694.         }
  695.     }
  696.     else
  697.     {
  698.         // call all active identity constraints
  699.         if (fMatcherStack->getMatcherCount())
  700.             fContent.append(toSend.getRawBuffer(), toSend.getLen());
  701.         // Always assume its just char data if not validating
  702.         if (fDocHandler)
  703.             fDocHandler->docCharacters(toSend.getRawBuffer(), toSend.getLen(), false);
  704.     }
  705.     // Reset buffer
  706.     toSend.reset();
  707. }
  708. //  This method is called with a key/value string pair that represents an
  709. //  xmlns="yyy" or xmlns:xxx="yyy" attribute. This method will update the
  710. //  current top of the element stack based on this data. We know that when
  711. //  we get here, that it is one of these forms, so we don't bother confirming
  712. //  it.
  713. //
  714. //  But we have to ensure
  715. //      1. xxx is not xmlns
  716. //      2. if xxx is xml, then yyy must match XMLUni::fgXMLURIName, and vice versa
  717. //      3. yyy is not XMLUni::fgXMLNSURIName
  718. //      4. if xxx is not null, then yyy cannot be an empty string.
  719. void SGXMLScanner::updateNSMap(const  XMLCh* const    attrName
  720.                               , const XMLCh* const    attrValue)
  721. {
  722.     // We need a buffer to normalize the attribute value into
  723.     XMLBufBid bbNormal(&fBufMgr);
  724.     XMLBuffer& normalBuf = bbNormal.getBuffer();
  725.     //  Normalize the value into the passed buffer. In this case, we don't
  726.     //  care about the return value. An error was issued for the error, which
  727.     //  is all we care about here.
  728.     normalizeAttRawValue(attrName, attrValue, normalBuf);
  729.     XMLCh* namespaceURI = normalBuf.getRawBuffer();
  730.     //  We either have the default prefix (""), or we point it into the attr
  731.     //  name parameter. Note that the xmlns is not the prefix we care about
  732.     //  here. To us, the 'prefix' is really the local part of the attrName
  733.     //  parameter.
  734.     //
  735.     //  Check 1. xxx is not xmlns
  736.     //        2. if xxx is xml, then yyy must match XMLUni::fgXMLURIName, and vice versa
  737.     //        3. yyy is not XMLUni::fgXMLNSURIName
  738.     //        4. if xxx is not null, then yyy cannot be an empty string.
  739.     const XMLCh* prefPtr = XMLUni::fgZeroLenString;
  740.     const int colonOfs = XMLString::indexOf(attrName, chColon);
  741.     if (colonOfs != -1) {
  742.         prefPtr = &attrName[colonOfs + 1];
  743.         if (XMLString::equals(prefPtr, XMLUni::fgXMLNSString))
  744.             emitError(XMLErrs::NoUseOfxmlnsAsPrefix);
  745.         else if (XMLString::equals(prefPtr, XMLUni::fgXMLString)) {
  746.             if (!XMLString::equals(namespaceURI, XMLUni::fgXMLURIName))
  747.                 emitError(XMLErrs::PrefixXMLNotMatchXMLURI);
  748.         }
  749.         if (!namespaceURI)
  750.             emitError(XMLErrs::NoEmptyStrNamespace, attrName);
  751.         else if(!*namespaceURI && fXMLVersion == XMLReader::XMLV1_0)
  752.             emitError(XMLErrs::NoEmptyStrNamespace, attrName);
  753.     }
  754.     if (XMLString::equals(namespaceURI, XMLUni::fgXMLNSURIName))
  755.         emitError(XMLErrs::NoUseOfxmlnsURI);
  756.     else if (XMLString::equals(namespaceURI, XMLUni::fgXMLURIName)) {
  757.         if (!XMLString::equals(prefPtr, XMLUni::fgXMLString))
  758.             emitError(XMLErrs::XMLURINotMatchXMLPrefix);
  759.     }
  760.     //  Ok, we have to get the unique id for the attribute value, which is the
  761.     //  URI that this value should be mapped to. The validator has the
  762.     //  namespace string pool, so we ask him to find or add this new one. Then
  763.     //  we ask the element stack to add this prefix to URI Id mapping.
  764.     fElemStack.addPrefix
  765.     (
  766.         prefPtr
  767.         , fURIStringPool->addOrFind(namespaceURI)
  768.     );
  769. }
  770. void SGXMLScanner::scanRawAttrListforNameSpaces(const RefVectorOf<KVStringPair>* theRawAttrList, int attCount)
  771. {
  772.     //  Make an initial pass through the list and find any xmlns attributes or
  773.     //  schema attributes.
  774.     //  When we find one, send it off to be used to update the element stack's
  775.     //  namespace mappings.
  776.     int index = 0;
  777.     for (index = 0; index < attCount; index++)
  778.     {
  779.         // each attribute has the prefix:suffix="value"
  780.         const KVStringPair* curPair = fRawAttrList->elementAt(index);
  781.         const XMLCh* rawPtr = curPair->getKey();
  782.         //  If either the key begins with "xmlns:" or its just plain
  783.         //  "xmlns", then use it to update the map.
  784.         if (!XMLString::compareNString(rawPtr, XMLUni::fgXMLNSColonString, 6)
  785.         ||  XMLString::equals(rawPtr, XMLUni::fgXMLNSString))
  786.         {
  787.             const XMLCh* valuePtr = curPair->getValue();
  788.             updateNSMap(rawPtr, valuePtr);
  789.             // if the schema URI is seen in the the valuePtr, set the boolean seeXsi
  790.             if (XMLString::equals(valuePtr, SchemaSymbols::fgURI_XSI)) {
  791.                 fSeeXsi = true;
  792.             }
  793.         }
  794.     }
  795.     // walk through the list again to deal with "xsi:...."
  796.     if (fSeeXsi)
  797.     {
  798.         //  Schema Xsi Type yyyy (e.g. xsi:type="yyyyy")
  799.         XMLBufBid bbXsi(&fBufMgr);
  800.         XMLBuffer& fXsiType = bbXsi.getBuffer();
  801.         QName attName(fMemoryManager);
  802.         for (index = 0; index < attCount; index++)
  803.         {
  804.             // each attribute has the prefix:suffix="value"
  805.             const KVStringPair* curPair = fRawAttrList->elementAt(index);
  806.             const XMLCh* rawPtr = curPair->getKey();
  807.             attName.setName(rawPtr, fEmptyNamespaceId);
  808.             const XMLCh* prefPtr = attName.getPrefix();
  809.             // if schema URI has been seen, scan for the schema location and uri
  810.             // and resolve the schema grammar; or scan for schema type
  811.             if (resolvePrefix(prefPtr, ElemStack::Mode_Attribute) == fSchemaNamespaceId) {
  812.                 const XMLCh* valuePtr = curPair->getValue();
  813.                 const XMLCh* suffPtr = attName.getLocalPart();
  814.                 if (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_SCHEMALOCACTION))
  815.                     parseSchemaLocation(valuePtr);
  816.                 else if (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCACTION))
  817.                     resolveSchemaGrammar(valuePtr, XMLUni::fgZeroLenString);
  818.                 if (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_TYPE)) {
  819.                         fXsiType.set(valuePtr);
  820.                 }
  821.                 else if (XMLString::equals(suffPtr, SchemaSymbols::fgATT_NILL)
  822.                          && fValidator && fValidator->handlesSchema()
  823.                          && XMLString::equals(valuePtr, SchemaSymbols::fgATTVAL_TRUE)) {
  824.                             ((SchemaValidator*)fValidator)->setNillable(true);
  825.                 }
  826.             }
  827.         }
  828.         if (fValidator && fValidator->handlesSchema()) {
  829.             if (!fXsiType.isEmpty()) {
  830.                 int colonPos = -1;
  831.                 unsigned int uriId = resolveQName (
  832.                       fXsiType.getRawBuffer()
  833.                     , fPrefixBuf
  834.                     , ElemStack::Mode_Element
  835.                     , colonPos
  836.                 );
  837.                 ((SchemaValidator*)fValidator)->setXsiType(fPrefixBuf.getRawBuffer(), fXsiType.getRawBuffer() + colonPos + 1, uriId);
  838.             }
  839.         }
  840.     }
  841. }
  842. void SGXMLScanner::parseSchemaLocation(const XMLCh* const schemaLocationStr)
  843. {
  844.     BaseRefVectorOf<XMLCh>* schemaLocation = XMLString::tokenizeString(schemaLocationStr);
  845.     unsigned int size = schemaLocation->size();
  846.     if (size % 2 != 0 ) {
  847.         emitError(XMLErrs::BadSchemaLocation);
  848.     } else {
  849.         for(unsigned int i=0; i<size; i=i+2) {
  850.             resolveSchemaGrammar(schemaLocation->elementAt(i+1), schemaLocation->elementAt(i));
  851.         }
  852.     }
  853.     delete schemaLocation;
  854. }
  855. void SGXMLScanner::resolveSchemaGrammar(const XMLCh* const loc, const XMLCh* const uri) {
  856.     Grammar* grammar = fGrammarResolver->getGrammar(uri);
  857.     if (!grammar || grammar->getGrammarType() == Grammar::DTDGrammarType) {
  858.         XSDDOMParser parser(0, fMemoryManager);
  859.         parser.setValidationScheme(XercesDOMParser::Val_Never);
  860.         parser.setDoNamespaces(true);
  861.         parser.setUserEntityHandler(fEntityHandler);
  862.         parser.setUserErrorReporter(fErrorReporter);
  863.         // Create a buffer for expanding the system id
  864.         XMLBufBid bbSys(&fBufMgr);
  865.         XMLBuffer& expSysId = bbSys.getBuffer();
  866.         XMLBuffer& normalizedSysId = bbSys.getBuffer();
  867.         normalizeURI(loc, normalizedSysId);
  868.         //  Allow the entity handler to expand the system id if they choose
  869.         //  to do so.
  870.         InputSource* srcToFill = 0;
  871.         const XMLCh* normalizedURI = normalizedSysId.getRawBuffer();
  872.         if (fEntityHandler)
  873.         {
  874.             if (!fEntityHandler->expandSystemId(normalizedURI, expSysId))
  875.                 expSysId.set(normalizedURI);
  876.             srcToFill = fEntityHandler->resolveEntity( XMLUni::fgZeroLenString
  877.                                                      , expSysId.getRawBuffer());
  878.         }
  879.         else
  880.         {
  881.             expSysId.set(normalizedURI);
  882.         }
  883.         //  If they didn't create a source via the entity handler, then we
  884.         //  have to create one on our own.
  885.         if (!srcToFill)
  886.         {
  887.             ReaderMgr::LastExtEntityInfo lastInfo;
  888.             fReaderMgr.getLastExtEntityInfo(lastInfo);
  889.             try
  890.             {
  891.                 XMLURL urlTmp(lastInfo.systemId, expSysId.getRawBuffer());
  892.                 if (urlTmp.isRelative())
  893.                 {
  894.                     ThrowXML
  895.                     (
  896.                         MalformedURLException
  897.                         , XMLExcepts::URL_NoProtocolPresent
  898.                     );
  899.                 }
  900.                 else {
  901.                     if (fStandardUriConformant && urlTmp.hasInvalidChar())
  902.                         ThrowXML(MalformedURLException, XMLExcepts::URL_MalformedURL);
  903.                     srcToFill = new (fMemoryManager) URLInputSource(urlTmp, fMemoryManager);
  904.                 }
  905.             }
  906.             catch(const MalformedURLException& e)
  907.             {
  908.                 // Its not a URL, so lets assume its a local file name if non-standard uri is allowed
  909.                 if (!fStandardUriConformant)
  910.                     srcToFill = new (fMemoryManager) LocalFileInputSource
  911.                     (
  912.                         lastInfo.systemId
  913.                         , expSysId.getRawBuffer()
  914.                         , fMemoryManager
  915.                     );
  916.                 else
  917.                     throw e;
  918.             }
  919.         }
  920.         // Put a janitor on the input source
  921.         Janitor<InputSource> janSrc(srcToFill);
  922.         // Should just issue warning if the schema is not found
  923.         const bool flag = srcToFill->getIssueFatalErrorIfNotFound();
  924.         srcToFill->setIssueFatalErrorIfNotFound(false);
  925.         parser.parse(*srcToFill);
  926.         // Reset the InputSource
  927.         srcToFill->setIssueFatalErrorIfNotFound(flag);
  928.         if (parser.getSawFatal() && fExitOnFirstFatal)
  929.             emitError(XMLErrs::SchemaScanFatalError);
  930.         DOMDocument* document = parser.getDocument(); //Our Grammar
  931.         if (document != 0) {
  932.             DOMElement* root = document->getDocumentElement();// This is what we pass to TraverserSchema
  933.             if (root != 0)
  934.             {
  935.                 const XMLCh* newUri = root->getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE);
  936.                 if (!XMLString::equals(newUri, uri)) {
  937.                     if (fValidate || fValScheme == Val_Auto) {
  938.                         fValidator->emitError(XMLValid::WrongTargetNamespace, loc, uri);
  939.                     }
  940.                     grammar = fGrammarResolver->getGrammar(newUri);
  941.                 }
  942.                 if (!grammar || grammar->getGrammarType() == Grammar::DTDGrammarType) {
  943.                     //  Since we have seen a grammar, set our validation flag
  944.                     //  at this point if the validation scheme is auto
  945.                     if (fValScheme == Val_Auto && !fValidate) {
  946.                         fValidate = true;
  947.                         fElemStack.setValidationFlag(fValidate);
  948.                     }
  949.                     grammar = new (fMemoryManager) SchemaGrammar(fMemoryManager);
  950.                     TraverseSchema traverseSchema
  951.                     (
  952.                         root
  953.                         , fURIStringPool
  954.                         , (SchemaGrammar*) grammar
  955.                         , fGrammarResolver
  956.                         , this
  957.                         , srcToFill->getSystemId()
  958.                         , fEntityHandler
  959.                         , fErrorReporter
  960.                         , fMemoryManager
  961.                     );
  962.                     if (fGrammarType == Grammar::DTDGrammarType) {
  963.                         fGrammar = grammar;
  964.                         fGrammarType = Grammar::SchemaGrammarType;
  965.                         fValidator->setGrammar(fGrammar);
  966.                     }
  967.                     if (fValidate) {
  968.                         //  validate the Schema scan so far
  969.                         fValidator->preContentValidation(false);
  970.                     }
  971.                 }
  972.             }
  973.         }
  974.     }
  975.     else {
  976.         //  Since we have seen a grammar, set our validation flag
  977.         //  at this point if the validation scheme is auto
  978.         if (fValScheme == Val_Auto && !fValidate) {
  979.             fValidate = true;
  980.             fElemStack.setValidationFlag(fValidate);
  981.         }
  982.         // we have seen a schema, so set up the fValidator as fSchemaValidator
  983.         if (fGrammarType == Grammar::DTDGrammarType) {
  984.             fGrammar = grammar;
  985.             fGrammarType = Grammar::SchemaGrammarType;
  986.             fValidator->setGrammar(fGrammar);
  987.         }
  988.     }
  989. }
  990. InputSource* SGXMLScanner::resolveSystemId(const XMLCh* const sysId)
  991. {
  992.     // Create a buffer for expanding the system id
  993.     XMLBufBid bbSys(&fBufMgr);
  994.     XMLBuffer& expSysId = bbSys.getBuffer();
  995.     //  Allow the entity handler to expand the system id if they choose
  996.     //  to do so.
  997.     InputSource* srcToFill = 0;
  998.     if (fEntityHandler)
  999.     {
  1000.         if (!fEntityHandler->expandSystemId(sysId, expSysId))
  1001.             expSysId.set(sysId);
  1002.         srcToFill = fEntityHandler->resolveEntity( XMLUni::fgZeroLenString
  1003.                                                  , expSysId.getRawBuffer());
  1004.     }
  1005.     else
  1006.     {
  1007.         expSysId.set(sysId);
  1008.     }
  1009.     //  If they didn't create a source via the entity handler, then we
  1010.     //  have to create one on our own.
  1011.     if (!srcToFill)
  1012.     {
  1013.         ReaderMgr::LastExtEntityInfo lastInfo;
  1014.         fReaderMgr.getLastExtEntityInfo(lastInfo);
  1015.         try
  1016.         {
  1017.             XMLURL urlTmp(lastInfo.systemId, expSysId.getRawBuffer());
  1018.             if (urlTmp.isRelative())
  1019.             {
  1020.                 ThrowXML
  1021.                 (
  1022.                     MalformedURLException
  1023.                     , XMLExcepts::URL_NoProtocolPresent
  1024.                 );
  1025.             }
  1026.             else {
  1027.                 if (fStandardUriConformant && urlTmp.hasInvalidChar())
  1028.                     ThrowXML(MalformedURLException, XMLExcepts::URL_MalformedURL);
  1029.                 srcToFill = new (fMemoryManager) URLInputSource(urlTmp, fMemoryManager);
  1030.             }
  1031.         }
  1032.         catch(const MalformedURLException& e)
  1033.         {
  1034.             // Its not a URL, so lets assume its a local file name if non-standard uri is allowed
  1035.             if (!fStandardUriConformant)
  1036.                 srcToFill = new (fMemoryManager) LocalFileInputSource
  1037.                 (
  1038.                     lastInfo.systemId
  1039.                     , expSysId.getRawBuffer()
  1040.                     , fMemoryManager
  1041.                 );
  1042.             else
  1043.                 throw e;
  1044.         }
  1045.     }
  1046.     return srcToFill;
  1047. }
  1048. // ---------------------------------------------------------------------------
  1049. //  SGXMLScanner: Private grammar preparsing methods
  1050. // ---------------------------------------------------------------------------
  1051. Grammar* SGXMLScanner::loadXMLSchemaGrammar(const InputSource& src,
  1052.                                           const bool toCache)
  1053. {
  1054.    // Reset the validators
  1055.     fSchemaValidator->reset();
  1056.     fSchemaValidator->setErrorReporter(fErrorReporter);
  1057.     fSchemaValidator->setExitOnFirstFatal(fExitOnFirstFatal);
  1058.     fSchemaValidator->setGrammarResolver(fGrammarResolver);
  1059.     if (fValidatorFromUser)
  1060.         fValidator->reset();
  1061.     XSDDOMParser parser(0, fMemoryManager);
  1062.     parser.setValidationScheme(XercesDOMParser::Val_Never);
  1063.     parser.setDoNamespaces(true);
  1064.     parser.setUserEntityHandler(fEntityHandler);
  1065.     parser.setUserErrorReporter(fErrorReporter);
  1066.     // Should just issue warning if the schema is not found
  1067.     const bool flag = src.getIssueFatalErrorIfNotFound();
  1068.     ((InputSource&) src).setIssueFatalErrorIfNotFound(false);
  1069.     parser.parse(src);
  1070.     // Reset the InputSource
  1071.     ((InputSource&) src).setIssueFatalErrorIfNotFound(flag);
  1072.     if (parser.getSawFatal() && fExitOnFirstFatal)
  1073.         emitError(XMLErrs::SchemaScanFatalError);
  1074.     DOMDocument* document = parser.getDocument(); //Our Grammar
  1075.     if (document != 0) {
  1076.         DOMElement* root = document->getDocumentElement();// This is what we pass to TraverserSchema
  1077.         if (root != 0)
  1078.         {
  1079.             SchemaGrammar* grammar = new (fMemoryManager) SchemaGrammar(fMemoryManager);
  1080.             TraverseSchema traverseSchema
  1081.             (
  1082.                 root
  1083.                 , fURIStringPool
  1084.                 , (SchemaGrammar*) grammar
  1085.                 , fGrammarResolver
  1086.                 , this
  1087.                 , src.getSystemId()
  1088.                 , fEntityHandler
  1089.                 , fErrorReporter
  1090.                 , fMemoryManager
  1091.             );
  1092.             if (fValidate) {
  1093.                 //  validate the Schema scan so far
  1094.                 fValidator->setGrammar(grammar);
  1095.                 fValidator->preContentValidation(false, true);
  1096.             }
  1097.             if (toCache) {
  1098.                 fGrammarResolver->cacheGrammars();
  1099.             }
  1100.             return grammar;
  1101.         }
  1102.     }
  1103.     return 0;
  1104. }
  1105. // ---------------------------------------------------------------------------
  1106. //  SGXMLScanner: Private parsing methods
  1107. // ---------------------------------------------------------------------------
  1108. //  This method is called to do a raw scan of an attribute value. It does not
  1109. //  do normalization (since we don't know their types yet.) It just scans the
  1110. //  value and does entity expansion.
  1111. //
  1112. //  End of entity's must be dealt with here. During DTD scan, they can come
  1113. //  from external entities. During content, they can come from any entity.
  1114. //  We just eat the end of entity and continue with our scan until we come
  1115. //  to the closing quote. If an unterminated value causes us to go through
  1116. //  subsequent entities, that will cause errors back in the calling code,
  1117. //  but there's little we can do about it here.
  1118. bool SGXMLScanner::basicAttrValueScan(const XMLCh* const attrName, XMLBuffer& toFill)
  1119. {
  1120.     // Reset the target buffer
  1121.     toFill.reset();
  1122.     // Get the next char which must be a single or double quote
  1123.     XMLCh quoteCh;
  1124.     if (!fReaderMgr.skipIfQuote(quoteCh))
  1125.         return false;
  1126.     //  We have to get the current reader because we have to ignore closing
  1127.     //  quotes until we hit the same reader again.
  1128.     const unsigned int curReader = fReaderMgr.getCurrentReaderNum();
  1129.     //  Loop until we get the attribute value. Note that we use a double
  1130.     //  loop here to avoid the setup/teardown overhead of the exception
  1131.     //  handler on every round.
  1132.     XMLCh   nextCh;
  1133.     XMLCh   secondCh = 0;
  1134.     bool    gotLeadingSurrogate = false;
  1135.     bool    escaped;
  1136.     while (true)
  1137.     {
  1138.         try
  1139.         {
  1140.             while(true)
  1141.             {
  1142.                 nextCh = fReaderMgr.getNextChar();
  1143.                 if (!nextCh)
  1144.                     ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
  1145.                 //  Check for our ending quote. It has to be in the same entity
  1146.                 //  as where we started. Quotes in nested entities are ignored.
  1147.                 if (nextCh == quoteCh)
  1148.                 {
  1149.                     if (curReader == fReaderMgr.getCurrentReaderNum())
  1150.                         return true;
  1151.                     // Watch for spillover into a previous entity
  1152.                     if (curReader > fReaderMgr.getCurrentReaderNum())
  1153.                     {
  1154.                         emitError(XMLErrs::PartialMarkupInEntity);
  1155.                         return false;
  1156.                     }
  1157.                 }
  1158.                 //  Check for an entity ref . We ignore the empty flag in
  1159.                 //  this one.
  1160.                 escaped = false;
  1161.                 if (nextCh == chAmpersand)
  1162.                 {
  1163.                     // If it was not returned directly, then jump back up
  1164.                     if (scanEntityRef(true, nextCh, secondCh, escaped) != EntityExp_Returned)
  1165.                     {
  1166.                         gotLeadingSurrogate = false;
  1167.                         continue;
  1168.                     }
  1169.                 }
  1170.                 else if ((nextCh >= 0xD800) && (nextCh <= 0xDBFF))
  1171.                 {
  1172.                     // Deal with surrogate pairs
  1173.                     //  Its a leading surrogate. If we already got one, then
  1174.                     //  issue an error, else set leading flag to make sure that
  1175.                     //  we look for a trailing next time.
  1176.                     if (gotLeadingSurrogate)
  1177.                     {
  1178.                         emitError(XMLErrs::Expected2ndSurrogateChar);
  1179.                     }
  1180.                     else
  1181.                         gotLeadingSurrogate = true;
  1182.                 }
  1183.                 else
  1184.                 {
  1185.                     //  If its a trailing surrogate, make sure that we are
  1186.                     //  prepared for that. Else, its just a regular char so make
  1187.                     //  sure that we were not expected a trailing surrogate.
  1188.                     if ((nextCh >= 0xDC00) && (nextCh <= 0xDFFF))
  1189.                     {
  1190.                         // Its trailing, so make sure we were expecting it
  1191.                         if (!gotLeadingSurrogate)
  1192.                             emitError(XMLErrs::Unexpected2ndSurrogateChar);
  1193.                     }
  1194.                     else
  1195.                     {
  1196.                         //  Its just a char, so make sure we were not expecting a
  1197.                         //  trailing surrogate.
  1198.                         if (gotLeadingSurrogate) {
  1199.                             emitError(XMLErrs::Expected2ndSurrogateChar);
  1200.                         }
  1201.                         // Its got to at least be a valid XML character
  1202.                         else if (!fReaderMgr.getCurrentReader()->isXMLChar(nextCh))
  1203.                         {
  1204.                             XMLCh tmpBuf[9];
  1205.                             XMLString::binToText
  1206.                             (
  1207.                                 nextCh
  1208.                                 , tmpBuf
  1209.                                 , 8
  1210.                                 , 16
  1211.                             );
  1212.                             emitError(XMLErrs::InvalidCharacterInAttrValue, attrName, tmpBuf);
  1213.                         }
  1214.                     }
  1215.                     gotLeadingSurrogate = false;
  1216.                 }
  1217.                 //  If it was escaped, then put in a 0xFFFF value. This will
  1218.                 //  be used later during validation and normalization of the
  1219.                 //  value to know that the following character was via an
  1220.                 //  escape char.
  1221.                 if (escaped)
  1222.                     toFill.append(0xFFFF);
  1223.                 // Else add it to the buffer
  1224.                 toFill.append(nextCh);
  1225.                 if (secondCh)
  1226.                     toFill.append(secondCh);
  1227.             }
  1228.         }
  1229.         catch(const EndOfEntityException&)
  1230.         {
  1231.             // Just eat it and continue.
  1232.             gotLeadingSurrogate = false;
  1233.             escaped = false;
  1234.         }
  1235.     }
  1236.     return true;
  1237. }
  1238. //  This method scans a CDATA section. It collects the character into one
  1239. //  of the temp buffers and calls the document handler, if any, with the
  1240. //  characters. It assumes that the <![CDATA string has been scanned before
  1241. //  this call.
  1242. void SGXMLScanner::scanCDSection()
  1243. {
  1244.     //  This is the CDATA section opening sequence, minus the '<' character.
  1245.     //  We use this to watch for nested CDATA sections, which are illegal.
  1246.     static const XMLCh CDataPrefix[] =
  1247.     {
  1248.             chBang, chOpenSquare, chLatin_C, chLatin_D, chLatin_A
  1249.         ,   chLatin_T, chLatin_A, chOpenSquare, chNull
  1250.     };
  1251.     static const XMLCh CDataClose[] =
  1252.     {
  1253.             chCloseSquare, chCloseAngle, chNull
  1254.     };
  1255.     //  The next character should be the opening square bracket. If not
  1256.     //  issue an error, but then try to recover by skipping any whitespace
  1257.     //  and checking again.
  1258.     if (!fReaderMgr.skippedChar(chOpenSquare))
  1259.     {
  1260.         emitError(XMLErrs::ExpectedOpenSquareBracket);
  1261.         fReaderMgr.skipPastSpaces();
  1262.         // If we still don't find it, then give up, else keep going
  1263.         if (!fReaderMgr.skippedChar(chOpenSquare))
  1264.             return;
  1265.     }
  1266.     // Get a buffer for this
  1267.     XMLBufBid bbCData(&fBufMgr);
  1268.     //  We just scan forward until we hit the end of CDATA section sequence.
  1269.     //  CDATA is effectively a big escape mechanism so we don't treat markup
  1270.     //  characters specially here.
  1271.     bool            emittedError = false;
  1272.     bool    gotLeadingSurrogate = false;
  1273.     // Get the character data opts for the current element
  1274.     const ElemStack::StackElem* topElem = fElemStack.topElement();
  1275.     XMLElementDecl::CharDataOpts charOpts =  topElem->fThisElement->getCharDataOpts();
  1276.     while (true)
  1277.     {
  1278.         const XMLCh nextCh = fReaderMgr.getNextChar();
  1279.         // Watch for unexpected end of file
  1280.         if (!nextCh)
  1281.         {
  1282.             emitError(XMLErrs::UnterminatedCDATASection);
  1283.             ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
  1284.         }
  1285.         if (fValidate && fStandalone && (fReaderMgr.getCurrentReader()->isWhitespace(nextCh)))
  1286.         {
  1287.             // This document is standalone; this ignorable CDATA whitespace is forbidden.
  1288.             // XML 1.0, Section 2.9
  1289.             // And see if the current element is a 'Children' style content model
  1290.             if (topElem->fThisElement->isExternal()) {
  1291.                 if (charOpts == XMLElementDecl::SpacesOk) // Element Content
  1292.                 {
  1293.                     // Error - standalone should have a value of "no" as whitespace detected in an
  1294.                     // element type with element content whose element declaration was external
  1295.                     fValidator->emitError(XMLValid::NoWSForStandalone);
  1296.                     ((SchemaElementDecl *)(topElem->fThisElement))->setValidity(PSVIDefs::INVALID);
  1297.                 }
  1298.             }
  1299.         }
  1300.         //  If this is a close square bracket it could be our closing
  1301.         //  sequence.
  1302.         if (nextCh == chCloseSquare && fReaderMgr.skippedString(CDataClose))
  1303.         {
  1304.             //  make sure we were not expecting a trailing surrogate.
  1305.             if (gotLeadingSurrogate)
  1306.                 emitError(XMLErrs::Expected2ndSurrogateChar);
  1307.             if (fValidate) {
  1308.                 if (fNormalizeData) {
  1309.                     // normalize the character according to schema whitespace facet
  1310.                     XMLBufBid bbtemp(&fBufMgr);
  1311.                     XMLBuffer& tempBuf = bbtemp.getBuffer();
  1312.                     DatatypeValidator* tempDV = ((SchemaElementDecl*) topElem->fThisElement)->getDatatypeValidator();
  1313.                     ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, bbCData.getRawBuffer(),  tempBuf);
  1314.                     bbCData.set(tempBuf.getRawBuffer());
  1315.                 }
  1316.                 // tell the schema validation about the character data for checkContent later
  1317.                 ((SchemaValidator*) fValidator)->setDatatypeBuffer(bbCData.getRawBuffer());
  1318.                 if (charOpts != XMLElementDecl::AllCharData)
  1319.                 {
  1320.                     // They definitely cannot handle any type of char data
  1321.                     fValidator->emitError(XMLValid::NoCharDataInCM);
  1322.                     ((SchemaElementDecl *)topElem->fThisElement)->setValidity(PSVIDefs::INVALID);
  1323.                 }
  1324.             }
  1325.             // call all active identity constraints
  1326.             if (fMatcherStack->getMatcherCount())
  1327.                 fContent.append(bbCData.getRawBuffer(), bbCData.getLen());
  1328.             // If we have a doc handler, call it
  1329.             if (fDocHandler)
  1330.             {
  1331.                 fDocHandler->docCharacters
  1332.                     (
  1333.                     bbCData.getRawBuffer()
  1334.                     , bbCData.getLen()
  1335.                     , true
  1336.                     );
  1337.             }
  1338.             // And we are done
  1339.             break;
  1340.         }
  1341.         //  Make sure its a valid character. But if we've emitted an error
  1342.         //  already, don't bother with the overhead since we've already told
  1343.         //  them about it.
  1344.         if (!emittedError)
  1345.         {
  1346.             // Deal with surrogate pairs
  1347.             if ((nextCh >= 0xD800) && (nextCh <= 0xDBFF))
  1348.             {
  1349.                 //  Its a leading surrogate. If we already got one, then
  1350.                 //  issue an error, else set leading flag to make sure that
  1351.                 //  we look for a trailing next time.
  1352.                 if (gotLeadingSurrogate)
  1353.                     emitError(XMLErrs::Expected2ndSurrogateChar);
  1354.                 else
  1355.                     gotLeadingSurrogate = true;
  1356.             }
  1357.             else
  1358.             {
  1359.                 //  If its a trailing surrogate, make sure that we are
  1360.                 //  prepared for that. Else, its just a regular char so make
  1361.                 //  sure that we were not expected a trailing surrogate.
  1362.                 if ((nextCh >= 0xDC00) && (nextCh <= 0xDFFF))
  1363.                 {
  1364.                     // Its trailing, so make sure we were expecting it
  1365.                     if (!gotLeadingSurrogate)
  1366.                         emitError(XMLErrs::Unexpected2ndSurrogateChar);
  1367.                 }
  1368.                 else
  1369.                 {
  1370.                     //  Its just a char, so make sure we were not expecting a
  1371.                     //  trailing surrogate.
  1372.                     if (gotLeadingSurrogate)
  1373.                         emitError(XMLErrs::Expected2ndSurrogateChar);
  1374.                     // Its got to at least be a valid XML character
  1375.                     else if (!fReaderMgr.getCurrentReader()->isXMLChar(nextCh))
  1376.                     {
  1377.                         XMLCh tmpBuf[9];
  1378.                         XMLString::binToText
  1379.                         (
  1380.                             nextCh
  1381.                             , tmpBuf
  1382.                             , 8
  1383.                             , 16
  1384.                         );
  1385.                         emitError(XMLErrs::InvalidCharacter, tmpBuf);
  1386.                         emittedError = true;
  1387.                     }
  1388.                 }
  1389.                 gotLeadingSurrogate = false;
  1390.             }
  1391.         }
  1392.         // Add it to the buffer
  1393.         bbCData.append(nextCh);
  1394.     }
  1395. }
  1396. void SGXMLScanner::scanCharData(XMLBuffer& toUse)
  1397. {
  1398.     //  We have to watch for the stupid ]]> sequence, which is illegal in
  1399.     //  character data. So this is a little state machine that handles that.
  1400.     enum States
  1401.     {
  1402.         State_Waiting
  1403.         , State_GotOne
  1404.         , State_GotTwo
  1405.     };
  1406.     // Reset the buffer before we start
  1407.     toUse.reset();
  1408.     // Turn on the 'throw at end' flag of the reader manager
  1409.     ThrowEOEJanitor jan(&fReaderMgr, true);
  1410.     //  In order to be more efficient we have to use kind of a deeply nested
  1411.     //  set of blocks here. The outer block puts on a try and catches end of
  1412.     //  entity exceptions. The inner loop is the per-character loop. If we
  1413.     //  put the try inside the inner loop, it would work but would require
  1414.     //  the exception handling code setup/teardown code to be invoked for
  1415.     //  each character.
  1416.     XMLCh   nextCh;
  1417.     XMLCh   secondCh = 0;
  1418.     States  curState = State_Waiting;
  1419.     bool    escaped = false;
  1420.     bool    gotLeadingSurrogate = false;
  1421.     bool    notDone = true;
  1422.     while (notDone)
  1423.     {
  1424.         try
  1425.         {
  1426.             while (true)
  1427.             {
  1428.                 //  Eat through as many plain content characters as possible without
  1429.                 //  needing special handling.  Moving most content characters here,
  1430.                 //  in this one call, rather than running the overall loop once
  1431.                 //  per content character, is a speed optimization.
  1432.                 if (curState == State_Waiting  &&  !gotLeadingSurrogate)
  1433.                 {
  1434.                      fReaderMgr.movePlainContentChars(toUse);
  1435.                 }
  1436.                 // Try to get another char from the source
  1437.                 //   The code from here on down covers all contengencies,
  1438.                 if (!fReaderMgr.getNextCharIfNot(chOpenAngle, nextCh))
  1439.                 {
  1440.                     // If we were waiting for a trailing surrogate, its an error
  1441.                     if (gotLeadingSurrogate)
  1442.                         emitError(XMLErrs::Expected2ndSurrogateChar);
  1443.                     notDone = false;
  1444.                     break;
  1445.                 }
  1446.                 //  Watch for a reference. Note that the escapement mechanism
  1447.                 //  is ignored in this content.
  1448.                 escaped = false;
  1449.                 if (nextCh == chAmpersand)
  1450.                 {
  1451.                     sendCharData(toUse);
  1452.                     // Turn off the throwing at the end of entity during this
  1453.                     ThrowEOEJanitor jan(&fReaderMgr, false);
  1454.                     if (scanEntityRef(false, nextCh, secondCh, escaped) != EntityExp_Returned)
  1455.                     {
  1456.                         gotLeadingSurrogate = false;
  1457.                         continue;
  1458.                     }
  1459.                 }
  1460.                 else if ((nextCh >= 0xD800) && (nextCh <= 0xDBFF))
  1461.                 {
  1462.                     // Deal with surrogate pairs
  1463.                     //  Its a leading surrogate. If we already got one, then
  1464.                     //  issue an error, else set leading flag to make sure that
  1465.                     //  we look for a trailing next time.
  1466.                     if (gotLeadingSurrogate)
  1467.                         emitError(XMLErrs::Expected2ndSurrogateChar);
  1468.                     else
  1469.                         gotLeadingSurrogate = true;
  1470.                 }
  1471.                 else
  1472.                 {
  1473.                     //  If its a trailing surrogate, make sure that we are
  1474.                     //  prepared for that. Else, its just a regular char so make
  1475.                     //  sure that we were not expected a trailing surrogate.
  1476.                     if ((nextCh >= 0xDC00) && (nextCh <= 0xDFFF))
  1477.                     {
  1478.                         // Its trailing, so make sure we were expecting it
  1479.                         if (!gotLeadingSurrogate)
  1480.                             emitError(XMLErrs::Unexpected2ndSurrogateChar);
  1481.                     }
  1482.                     else
  1483.                     {
  1484.                         //  Its just a char, so make sure we were not expecting a
  1485.                         //  trailing surrogate.
  1486.                         if (gotLeadingSurrogate)
  1487.                             emitError(XMLErrs::Expected2ndSurrogateChar);
  1488.                         // Make sure the returned char is a valid XML char
  1489.                         if (!fReaderMgr.getCurrentReader()->isXMLChar(nextCh))
  1490.                         {
  1491.                             XMLCh tmpBuf[9];
  1492.                             XMLString::binToText
  1493.                             (
  1494.                                 nextCh
  1495.                                 , tmpBuf
  1496.                                 , 8
  1497.                                 , 16
  1498.                             );
  1499.                             emitError(XMLErrs::InvalidCharacter, tmpBuf);
  1500.                         }
  1501.                     }
  1502.                     gotLeadingSurrogate = false;
  1503.                 }
  1504.                 // Keep the state machine up to date
  1505.                 if (!escaped)
  1506.                 {
  1507.                     if (nextCh == chCloseSquare)
  1508.                     {
  1509.                         if (curState == State_Waiting)
  1510.                             curState = State_GotOne;
  1511.                         else if (curState == State_GotOne)
  1512.                             curState = State_GotTwo;
  1513.                     }
  1514.                     else if (nextCh == chCloseAngle)
  1515.                     {
  1516.                         if (curState == State_GotTwo)
  1517.                             emitError(XMLErrs::BadSequenceInCharData);
  1518.                         curState = State_Waiting;
  1519.                     }
  1520.                     else
  1521.                     {
  1522.                         curState = State_Waiting;
  1523.                     }
  1524.                 }
  1525.                 else
  1526.                 {
  1527.                     curState = State_Waiting;
  1528.                 }
  1529.                 // Add this char to the buffer
  1530.                 toUse.append(nextCh);
  1531.                 if (secondCh)
  1532.                     toUse.append(secondCh);
  1533.             }
  1534.         }
  1535.         catch(const EndOfEntityException& toCatch)
  1536.         {
  1537.             //  Some entity ended, so we have to send any accumulated
  1538.             //  chars and send an end of entity event.
  1539.             sendCharData(toUse);
  1540.             gotLeadingSurrogate = false;
  1541.             if (fDocHandler)
  1542.                 fDocHandler->endEntityReference(toCatch.getEntity());
  1543.         }
  1544.     }
  1545.     // Check the validity constraints as per XML 1.0 Section 2.9
  1546.     if (fValidate && fStandalone)
  1547.     {
  1548.         // See if the text contains whitespace
  1549.         // Get the raw data we need for the callback
  1550.         const XMLCh* rawBuf = toUse.getRawBuffer();
  1551.         const unsigned int len = toUse.getLen();
  1552.         const bool isSpaces = fReaderMgr.getCurrentReader()->containsWhiteSpace(rawBuf, len);
  1553.         if (isSpaces)
  1554.         {
  1555.             // And see if the current element is a 'Children' style content model
  1556.             const ElemStack::StackElem* topElem = fElemStack.topElement();
  1557.             if (topElem->fThisElement->isExternal()) {
  1558.                 // Get the character data opts for the current element
  1559.                 XMLElementDecl::CharDataOpts charOpts =  topElem->fThisElement->getCharDataOpts();
  1560.                 if (charOpts == XMLElementDecl::SpacesOk)  // => Element Content
  1561.                 {
  1562.                     // Error - standalone should have a value of "no" as whitespace detected in an
  1563.                     // element type with element content whose element declaration was external
  1564.                     //
  1565.                     fValidator->emitError(XMLValid::NoWSForStandalone);
  1566.                     ((SchemaElementDecl *)fElemStack.topElement()->fThisElement)->setValidity(PSVIDefs::INVALID);
  1567.                 }
  1568.             }
  1569.         }
  1570.     }
  1571.     // Send any char data that we accumulated into the buffer
  1572.     sendCharData(toUse);
  1573. }
  1574. //  This method will scan a general/character entity ref. It will either
  1575. //  expand a char ref and return it directly, or push a reader for a general
  1576. //  entity.
  1577. //
  1578. //  The return value indicates whether the char parameters hold the value
  1579. //  or whether the value was pushed as a reader, or that it failed.
  1580. //
  1581. //  The escaped flag tells the caller whether the returned parameter resulted
  1582. //  from a character reference, which escapes the character in some cases. It
  1583. //  only makes any difference if the return value indicates the value was
  1584. //  returned directly.
  1585. SGXMLScanner::EntityExpRes
  1586. SGXMLScanner::scanEntityRef(  const   bool    inAttVal
  1587.                             ,       XMLCh&  firstCh
  1588.                             ,       XMLCh&  secondCh
  1589.                             ,       bool&   escaped)
  1590. {
  1591.     // Assume no escape
  1592.     secondCh = 0;
  1593.     escaped = false;
  1594.     // We have to insure that its all in one entity
  1595.     const unsigned int curReader = fReaderMgr.getCurrentReaderNum();
  1596.     //  If the next char is a pound, then its a character reference and we
  1597.     //  need to expand it always.
  1598.     if (fReaderMgr.skippedChar(chPound))
  1599.     {
  1600.         //  Its a character reference, so scan it and get back the numeric
  1601.         //  value it represents.
  1602.         if (!scanCharRef(firstCh, secondCh))
  1603.             return EntityExp_Failed;
  1604.         escaped = true;
  1605.         if (curReader != fReaderMgr.getCurrentReaderNum())
  1606.             emitError(XMLErrs::PartialMarkupInEntity);
  1607.         return EntityExp_Returned;
  1608.     }
  1609.     // Expand it since its a normal entity ref
  1610.     XMLBufBid bbName(&fBufMgr);
  1611.     if (!fReaderMgr.getName(bbName.getBuffer()))
  1612.     {
  1613.         emitError(XMLErrs::ExpectedEntityRefName);
  1614.         return EntityExp_Failed;
  1615.     }
  1616.     //  Next char must be a semi-colon. But if its not, just emit
  1617.     //  an error and try to continue.
  1618.     if (!fReaderMgr.skippedChar(chSemiColon))
  1619.         emitError(XMLErrs::UnterminatedEntityRef, bbName.getRawBuffer());
  1620.     // Make sure we ended up on the same entity reader as the & char
  1621.     if (curReader != fReaderMgr.getCurrentReaderNum())
  1622.         emitError(XMLErrs::PartialMarkupInEntity);
  1623.     // Look up the name in the general entity pool
  1624.     // If it does not exist, then obviously an error
  1625.     if (!fEntityTable->containsKey(bbName.getRawBuffer()))
  1626.     {
  1627.         // XML 1.0 Section 4.1
  1628.         // Well-formedness Constraint for entity not found:
  1629.         //   In a document without any DTD, a document with only an internal DTD subset which contains no parameter entity references,
  1630.         //      or a document with "standalone='yes'", for an entity reference that does not occur within the external subset
  1631.         //      or a parameter entity
  1632.         if (fStandalone || fHasNoDTD)
  1633.             emitError(XMLErrs::EntityNotFound, bbName.getRawBuffer());
  1634.         return EntityExp_Failed;
  1635.     }
  1636.     // here's where we need to check if there's a SecurityManager,
  1637.     // how many entity references we've had
  1638.     if(fSecurityManager != 0 && ++fEntityExpansionCount > fEntityExpansionLimit) {
  1639.         XMLCh expLimStr[16];
  1640.         XMLString::binToText(fEntityExpansionLimit, expLimStr, 15, 10);
  1641.         emitError
  1642.         ( 
  1643.             XMLErrs::EntityExpansionLimitExceeded
  1644.             , expLimStr
  1645.         );
  1646.         // there seems nothing better to be done than to reset the entity expansion limit
  1647.         fEntityExpansionCount = 0;
  1648.     }
  1649.     firstCh = fEntityTable->get(bbName.getRawBuffer());
  1650.     escaped = true;
  1651.     return EntityExp_Returned;
  1652. }
  1653. bool SGXMLScanner::switchGrammar(const XMLCh* const newGrammarNameSpace)
  1654. {
  1655.     Grammar* tempGrammar = fGrammarResolver->getGrammar(newGrammarNameSpace);
  1656.     if (!tempGrammar) {
  1657.         tempGrammar = fSchemaGrammar;
  1658.     }
  1659.     if (!tempGrammar)
  1660.         return false;
  1661.     else {
  1662.         fGrammar = tempGrammar;
  1663.         fGrammarType = fGrammar->getGrammarType();
  1664.         if (fGrammarType == Grammar::DTDGrammarType) {
  1665.             ThrowXML(RuntimeException, XMLExcepts::Gen_NoDTDValidator);
  1666.         }
  1667.         fValidator->setGrammar(fGrammar);
  1668.         return true;
  1669.     }
  1670. }
  1671. // check if we should skip or lax the validation of the element
  1672. // if skip - no validation
  1673. // if lax - validate only if the element if found
  1674. bool SGXMLScanner::laxElementValidation(QName* element, ContentLeafNameTypeVector* cv,
  1675.                                         const XMLContentModel* const cm,
  1676.                                         const unsigned int parentElemDepth)
  1677. {
  1678.     bool skipThisOne = false;
  1679.     bool laxThisOne = false;
  1680.     unsigned int elementURI = element->getURI();
  1681.     unsigned int currState = fElemState[parentElemDepth];
  1682.     if (currState == XMLContentModel::gInvalidTrans) {
  1683.         return laxThisOne;
  1684.     }
  1685.     SubstitutionGroupComparator comparator(fGrammarResolver, fURIStringPool);
  1686.     if (cv) {
  1687.         unsigned int i = 0;
  1688.         unsigned int leafCount = cv->getLeafCount();
  1689.         for (; i < leafCount; i++) {
  1690.             QName* fElemMap = cv->getLeafNameAt(i);
  1691.             unsigned int uri = fElemMap->getURI();
  1692.             unsigned int nextState;
  1693.             bool anyEncountered = false;
  1694.             ContentSpecNode::NodeTypes type = cv->getLeafTypeAt(i);
  1695.             if (type == ContentSpecNode::Leaf) {
  1696.                 if (((uri == elementURI)
  1697.                       && XMLString::equals(fElemMap->getLocalPart(), element->getLocalPart()))
  1698.                     || comparator.isEquivalentTo(element, fElemMap)) {
  1699.                     nextState = cm->getNextState(currState, i);
  1700.                     if (nextState != XMLContentModel::gInvalidTrans) {
  1701.                         fElemState[parentElemDepth] = nextState;
  1702.                         break;
  1703.                     }
  1704.                 }
  1705.             } else if ((type & 0x0f) == ContentSpecNode::Any) {
  1706.                 anyEncountered = true;
  1707.             }
  1708.             else if ((type & 0x0f) == ContentSpecNode::Any_Other) {
  1709.                 if (uri != elementURI) {
  1710.                     anyEncountered = true;
  1711.                 }
  1712.             }
  1713.             else if ((type & 0x0f) == ContentSpecNode::Any_NS) {
  1714.                 if (uri == elementURI) {
  1715.                     anyEncountered = true;
  1716.                 }
  1717.             }
  1718.             if (anyEncountered) {
  1719.                 nextState = cm->getNextState(currState, i);
  1720.                 if (nextState != XMLContentModel::gInvalidTrans) {
  1721.                     fElemState[parentElemDepth] = nextState;
  1722.                     if (type == ContentSpecNode::Any_Skip ||
  1723.                         type == ContentSpecNode::Any_NS_Skip ||
  1724.                         type == ContentSpecNode::Any_Other_Skip) {
  1725.                         skipThisOne = true;
  1726.                     }
  1727.                     else if (type == ContentSpecNode::Any_Lax ||
  1728.                              type == ContentSpecNode::Any_NS_Lax ||
  1729.                              type == ContentSpecNode::Any_Other_Lax) {
  1730.                         laxThisOne = true;
  1731.                     }
  1732.                     break;
  1733.                 }
  1734.             }
  1735.         } // for
  1736.         if (i == leafCount) { // no match
  1737.             fElemState[parentElemDepth] = XMLContentModel::gInvalidTrans;
  1738.             return laxThisOne;
  1739.         }
  1740.     } // if
  1741.     if (skipThisOne) {
  1742.         fValidate = false;
  1743.         fElemStack.setValidationFlag(fValidate);
  1744.     }
  1745.     return laxThisOne;
  1746. }
  1747. // check if there is an AnyAttribute, and if so, see if we should lax or skip
  1748. // if skip - no validation
  1749. // if lax - validate only if the attribute if found
  1750. bool SGXMLScanner::anyAttributeValidation(SchemaAttDef* attWildCard, unsigned int uriId, bool& skipThisOne, bool& laxThisOne)
  1751. {
  1752.     XMLAttDef::AttTypes wildCardType = attWildCard->getType();
  1753.     bool anyEncountered = false;
  1754.     skipThisOne = false;
  1755.     laxThisOne = false;
  1756.     if (wildCardType == XMLAttDef::Any_Any)
  1757.         anyEncountered = true;
  1758.     else if (wildCardType == XMLAttDef::Any_Other) {
  1759.         if (attWildCard->getAttName()->getURI() != uriId
  1760.             && uriId != fEmptyNamespaceId)
  1761.             anyEncountered = true;
  1762.     }
  1763.     else if (wildCardType == XMLAttDef::Any_List) {
  1764.         ValueVectorOf<unsigned int>* nameURIList = attWildCard->getNamespaceList();
  1765.         unsigned int listSize = (nameURIList) ? nameURIList->size() : 0;
  1766.         if (listSize) {
  1767.             for (unsigned int i=0; i < listSize; i++) {
  1768.                 if (nameURIList->elementAt(i) == uriId)
  1769.                     anyEncountered = true;
  1770.             }
  1771.         }
  1772.     }
  1773.     if (anyEncountered) {
  1774.         XMLAttDef::DefAttTypes   defType   = attWildCard->getDefaultType();
  1775.         if (defType == XMLAttDef::ProcessContents_Skip) {
  1776.             // attribute should just be bypassed,
  1777.             skipThisOne = true;
  1778.             attWildCard->setValidationAttempted(PSVIDefs::NONE);
  1779.         }
  1780.         else if (defType == XMLAttDef::ProcessContents_Lax) {
  1781.             laxThisOne = true;
  1782.         }
  1783.     }
  1784.     return anyEncountered;
  1785. }
  1786. void SGXMLScanner::normalizeURI(const XMLCh* const systemURI,
  1787.                                 XMLBuffer& normalizedURI)
  1788. {
  1789.     const XMLCh* pszSrc = systemURI;
  1790.     normalizedURI.reset();
  1791.     while (*pszSrc) {
  1792.         if ((*(pszSrc) == chPercent)
  1793.         &&  (*(pszSrc+1) == chDigit_2)
  1794.         &&  (*(pszSrc+2) == chDigit_0))
  1795.         {
  1796.             pszSrc += 3;
  1797.             normalizedURI.append(chSpace);
  1798.         }
  1799.         else if (*pszSrc == 0xFFFF) { //escaped character
  1800.             pszSrc++;
  1801.         }
  1802.         else {
  1803.             normalizedURI.append(*pszSrc);
  1804.             pszSrc++;
  1805.         }
  1806.     }
  1807. }
  1808. XERCES_CPP_NAMESPACE_END