You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by kn...@apache.org on 2002/07/11 20:22:14 UTC
cvs commit: xml-xerces/c/src/xercesc/internal XMLScanner2.cpp XMLScanner.hpp XMLScanner.cpp
knoaman 2002/07/11 11:22:14
Modified: c/src/xercesc/internal XMLScanner2.cpp XMLScanner.hpp
XMLScanner.cpp
Log:
Grammar caching/preparsing - initial implementation.
Revision Changes Path
1.12 +167 -91 xml-xerces/c/src/xercesc/internal/XMLScanner2.cpp
Index: XMLScanner2.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/internal/XMLScanner2.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- XMLScanner2.cpp 17 Jun 2002 18:09:20 -0000 1.11
+++ XMLScanner2.cpp 11 Jul 2002 18:22:13 -0000 1.12
@@ -532,6 +532,16 @@
if ((defType == XMLAttDef::Default)
|| (defType == XMLAttDef::Fixed))
{
+ // Let the validator pass judgement on the attribute value
+ if (fValidate)
+ {
+ fValidator->validateAttrValue
+ (
+ &curDef
+ , curDef.getValue()
+ );
+ }
+
XMLAttr* curAtt;
if (retCount >= curAttListSize)
{
@@ -892,61 +902,33 @@
// This call implicitly tells us that we are going to reuse the scanner
// if it was previously used. So tell the validator to reset itself.
//
- // But, if the fReuseGrammar flag is set, then don't reset it.
+ // But, if the fUseCacheGrammar flag is set, then don't reset it.
//
// NOTE: The ReaderMgr is flushed on the way out, because that is
// required to insure that files are closed.
//
- if (!fReuseGrammar) {
- fGrammarResolver->reset();
-
- resetEntityDeclPool();
- if (fDoNamespaces)
- resetURIStringPool();
+ fGrammarResolver->cacheGrammarFromParse(fToCacheGrammar);
+ fGrammarResolver->useCachedGrammarInParse(fUseCachedGrammar);
- // create a default grammar first
- fGrammar = new DTDGrammar();
+ fDTDGrammar = new DTDGrammar();
+ fGrammarResolver->putGrammar(XMLUni::fgDTDEntityString, fDTDGrammar);
+ fGrammar = fDTDGrammar;
+ fGrammarType = fGrammar->getGrammarType();
+ fRootGrammar = 0;
- //
- if (fValidatorFromUser) {
- if (fValidator->handlesDTD())
- fValidator->setGrammar(fGrammar);
- }
- else {
- // set fValidator as fDTDValidator
- fValidator = fDTDValidator;
+ if (fValidatorFromUser) {
+ if (fValidator->handlesDTD())
fValidator->setGrammar(fGrammar);
- }
-
- fGrammarType = fGrammar->getGrammarType();
- fGrammarResolver->putGrammar(XMLUni::fgZeroLenString, fGrammar);
-
- if (fValScheme == Val_Auto) {
- fValidate = false;
- }
}
else {
- // reusing grammar, thus the fGrammar must pre-exist already
- // make sure the validator handles this reuse grammar type
- if (fGrammarType == Grammar::SchemaGrammarType && !fValidator->handlesSchema()) {
- if (fValidatorFromUser)
- ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
- else {
- fValidator = fSchemaValidator;
- }
- }
- else if (fGrammarType == Grammar::DTDGrammarType && !fValidator->handlesDTD()) {
- if (fValidatorFromUser)
- ThrowXML(RuntimeException, XMLExcepts::Gen_NoDTDValidator);
- else {
- fValidator = fDTDValidator;
- }
- }
-
- if (!fValidator->getGrammar())
- fValidator->setGrammar(fGrammar);
+ // set fValidator as fDTDValidator
+ fValidator = fDTDValidator;
+ fValidator->setGrammar(fGrammar);
+ }
+
+ if (fValScheme == Val_Auto) {
+ fValidate = false;
}
-
//
// And for all installed handlers, send reset events. This gives them
@@ -1379,12 +1361,10 @@
const XMLCh* valuePtr = curPair->getValue();
const XMLCh* suffPtr = attName.getLocalPart();
- if (!fReuseGrammar) {
- if (!XMLString::compareString(suffPtr, SchemaSymbols::fgXSI_SCHEMALOCACTION))
- parseSchemaLocation(valuePtr);
- else if (!XMLString::compareString(suffPtr, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCACTION))
- resolveSchemaGrammar(valuePtr, XMLUni::fgZeroLenString);
- }
+ if (!XMLString::compareString(suffPtr, SchemaSymbols::fgXSI_SCHEMALOCACTION))
+ parseSchemaLocation(valuePtr);
+ else if (!XMLString::compareString(suffPtr, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCACTION))
+ resolveSchemaGrammar(valuePtr, XMLUni::fgZeroLenString);
if (!XMLString::compareString(suffPtr, SchemaSymbols::fgXSI_TYPE)) {
fXsiType.set(valuePtr);
@@ -1547,7 +1527,7 @@
}
grammar = new SchemaGrammar();
- TraverseSchema traverseSchema(root, fURIStringPool, (SchemaGrammar*) grammar, fGrammarResolver, this, fValidator, srcToFill->getSystemId(), fEntityHandler, fErrorReporter);
+ TraverseSchema traverseSchema(root, fURIStringPool, (SchemaGrammar*) grammar, fGrammarResolver, this, srcToFill->getSystemId(), fEntityHandler, fErrorReporter);
if (fGrammarType == Grammar::DTDGrammarType) {
fGrammar = grammar;
@@ -1555,9 +1535,9 @@
fValidator->setGrammar(fGrammar);
}
- if (!fReuseGrammar && fValidate) {
+ if (fValidate) {
// validate the Schema scan so far
- fValidator->preContentValidation(fReuseGrammar);
+ fValidator->preContentValidation(false);
}
}
}
@@ -1593,6 +1573,135 @@
}
}
+InputSource* XMLScanner::resolveSystemId(const XMLCh* const sysId)
+{
+ // Create a buffer for expanding the system id
+ XMLBufBid bbSys(&fBufMgr);
+ XMLBuffer& expSysId = bbSys.getBuffer();
+
+ //
+ // Allow the entity handler to expand the system id if they choose
+ // to do so.
+ //
+ InputSource* srcToFill = 0;
+ if (fEntityHandler)
+ {
+ if (!fEntityHandler->expandSystemId(sysId, expSysId))
+ expSysId.set(sysId);
+
+ srcToFill = fEntityHandler->resolveEntity( XMLUni::fgZeroLenString
+ , expSysId.getRawBuffer());
+ }
+ else
+ {
+ expSysId.set(sysId);
+ }
+
+ //
+ // If they didn't create a source via the entity handler, then we
+ // have to create one on our own.
+ //
+ if (!srcToFill)
+ {
+ ReaderMgr::LastExtEntityInfo lastInfo;
+ fReaderMgr.getLastExtEntityInfo(lastInfo);
+
+ try
+ {
+ XMLURL urlTmp(lastInfo.systemId, expSysId.getRawBuffer());
+ if (urlTmp.isRelative())
+ {
+ ThrowXML
+ (
+ MalformedURLException
+ , XMLExcepts::URL_NoProtocolPresent
+ );
+ }
+ srcToFill = new URLInputSource(urlTmp);
+ }
+
+ catch(const MalformedURLException&)
+ {
+ // Its not a URL, so lets assume its a local file name.
+ srcToFill = new LocalFileInputSource
+ (
+ lastInfo.systemId
+ , expSysId.getRawBuffer()
+ );
+ }
+ }
+
+ return srcToFill;
+}
+
+
+// ---------------------------------------------------------------------------
+// XMLScanner: Private grammar preparsing methods
+// ---------------------------------------------------------------------------
+Grammar* XMLScanner::loadXMLSchemaGrammar(const InputSource& src,
+ const bool toCache)
+{
+ // Reset the validators
+ fSchemaValidator->reset();
+ if (fValidatorFromUser)
+ fValidator->reset();
+
+ if (!fValidator->handlesSchema()) {
+ if (fValidatorFromUser && fValidate)
+ ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
+ else {
+ fValidator = fSchemaValidator;
+ }
+ }
+
+ XSDDOMParser parser;
+
+ parser.setValidationScheme(XercesDOMParser::Val_Never);
+ parser.setDoNamespaces(true);
+ parser.setUserEntityHandler(fEntityHandler);
+ parser.setUserErrorReporter(fErrorReporter);
+
+ // Should just issue warning if the schema is not found
+ const bool flag = src.getIssueFatalErrorIfNotFound();
+ ((InputSource&) src).setIssueFatalErrorIfNotFound(false);
+
+ parser.parse(src);
+
+ // Reset the InputSource
+ ((InputSource&) src).setIssueFatalErrorIfNotFound(flag);
+
+ if (parser.getSawFatal() && fExitOnFirstFatal)
+ emitError(XMLErrs::SchemaScanFatalError);
+
+ DOMDocument* document = parser.getDocument(); //Our Grammar
+
+ if (document != 0) {
+
+ DOMElement* root = document->getDocumentElement();// This is what we pass to TraverserSchema
+ if (root != 0)
+ {
+ SchemaGrammar* grammar = new SchemaGrammar();
+ TraverseSchema traverseSchema(root, fURIStringPool, (SchemaGrammar*) grammar, fGrammarResolver, this, src.getSystemId(), fEntityHandler, fErrorReporter);
+
+ if (fValidate) {
+ // validate the Schema scan so far
+ fValidator->setGrammar(grammar);
+ fValidator->preContentValidation(false, true);
+ }
+
+ if (toCache) {
+ fGrammarResolver->cacheGrammars();
+ }
+
+ return grammar;
+ }
+ }
+
+ return 0;
+}
+
+
+
// ---------------------------------------------------------------------------
// XMLScanner: Private parsing methods
// ---------------------------------------------------------------------------
@@ -2759,7 +2868,7 @@
emitError(XMLErrs::PartialMarkupInEntity);
// Look up the name in the general entity pool
- XMLEntityDecl* decl = fEntityDeclPool->getByKey(bbName.getRawBuffer());
+ XMLEntityDecl* decl = fDTDGrammar->getEntityDecl(bbName.getRawBuffer());
// If it does not exist, then obviously an error
if (!decl)
@@ -2915,47 +3024,14 @@
return toFill.getLen();
}
-bool XMLScanner::switchGrammar(unsigned int newGrammarNameSpaceIndex)
-{
- XMLBufBid bbURI(&fBufMgr);
- XMLBuffer& bufURI = bbURI.getBuffer();
- getURIText(newGrammarNameSpaceIndex, bufURI);
- Grammar* tempGrammar = fGrammarResolver->getGrammar(bufURI.getRawBuffer());
- if (!tempGrammar) {
- // This is a case where namespaces is on with a DTD grammar.
- tempGrammar = fGrammarResolver->getGrammar(XMLUni::fgZeroLenString);
- }
- if (!tempGrammar)
- return false;
- else {
- fGrammar = tempGrammar;
- fGrammarType = fGrammar->getGrammarType();
- if (fGrammarType == Grammar::SchemaGrammarType && !fValidator->handlesSchema()) {
- if (fValidatorFromUser)
- ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
- else {
- fValidator = fSchemaValidator;
- }
- }
- else if (fGrammarType == Grammar::DTDGrammarType && !fValidator->handlesDTD()) {
- if (fValidatorFromUser)
- ThrowXML(RuntimeException, XMLExcepts::Gen_NoDTDValidator);
- else {
- fValidator = fDTDValidator;
- }
- }
-
- fValidator->setGrammar(fGrammar);
- return true;
- }
-}
bool XMLScanner::switchGrammar(const XMLCh* const newGrammarNameSpace)
{
Grammar* tempGrammar = fGrammarResolver->getGrammar(newGrammarNameSpace);
+
if (!tempGrammar) {
// This is a case where namespaces is on with a DTD grammar.
- tempGrammar = fGrammarResolver->getGrammar(XMLUni::fgZeroLenString);
+ tempGrammar = fDTDGrammar;
}
if (!tempGrammar)
return false;
1.8 +87 -51 xml-xerces/c/src/xercesc/internal/XMLScanner.hpp
Index: XMLScanner.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/internal/XMLScanner.hpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- XMLScanner.hpp 17 Jun 2002 16:13:01 -0000 1.7
+++ XMLScanner.hpp 11 Jul 2002 18:22:13 -0000 1.8
@@ -56,6 +56,9 @@
/*
* $Log$
+ * Revision 1.8 2002/07/11 18:22:13 knoaman
+ * Grammar caching/preparsing - initial implementation.
+ *
* Revision 1.7 2002/06/17 16:13:01 tng
* DOM L3: Add the flag fNormalizeData so that datatype normalization defined by schema is done only if asked.
*
@@ -389,16 +392,6 @@
const XMLValidator* getValidator() const;
XMLValidator* getValidator();
int getErrorCount();
- const DTDEntityDecl* getEntityDecl
- (
- const XMLCh* const entName
- ) const;
-
- DTDEntityDecl* getEntityDecl
- (
- const XMLCh* const entName
- );
- NameIdPoolEnumerator<DTDEntityDecl> getEntityEnumerator() const;
NameIdPool<DTDEntityDecl>* getEntityDeclPool();
const NameIdPool<DTDEntityDecl>* getEntityDeclPool() const;
const XMLStringPool* getURIStringPool() const;
@@ -408,6 +401,9 @@
XMLCh* getExternalNoNamespaceSchemaLocation() const;
bool getLoadExternalDTD() const;
bool getNormalizeData() const;
+ bool isCachingGrammarFromParse() const;
+ bool isUsingCachedGrammarInParse() const;
+ Grammar* getRootGrammar() const;
// -----------------------------------------------------------------------
// Getter methods
@@ -479,6 +475,8 @@
, const ElemStack::MapModes mode
);
+ Grammar* getGrammar(const XMLCh* const nameSpaceKey);
+
/* tell if the validator comes from user */
bool isValidatorFromUser();
@@ -499,6 +497,8 @@
void setDoSchema(const bool doSchema);
void setValidationSchemaFullChecking(const bool schemaFullChecking);
void setHasNoDTD(const bool hasNoDTD);
+ void cacheGrammarFromParse(const bool newValue);
+ void useCachedGrammarInParse(const bool newValue);
void setRootElemName(XMLCh* rootElemName);
void setExternalSchemaLocation(const XMLCh* const schemaLocation);
void setExternalNoNamespaceSchemaLocation(const XMLCh* const noNamespaceSchemaLocation);
@@ -529,36 +529,30 @@
void scanDocument
(
const InputSource& src
- , const bool reuseGrammar = false
);
void scanDocument
(
const XMLCh* const systemId
- , const bool reuseGrammar = false
);
void scanDocument
(
const char* const systemId
- , const bool reuseGrammar = false
);
bool scanFirst
(
const InputSource& src
, XMLPScanToken& toFill
- , const bool reuseGrammar = false
);
bool scanFirst
(
const XMLCh* const systemId
, XMLPScanToken& toFill
- , const bool reuseGrammar = false
);
bool scanFirst
(
const char* const systemId
, XMLPScanToken& toFill
- , const bool reuseGrammar = false
);
bool scanNext(XMLPScanToken& toFill);
@@ -568,6 +562,33 @@
bool checkXMLDecl(bool startWithAngle);
// -----------------------------------------------------------------------
+ // Grammar preparsing methods
+ // -----------------------------------------------------------------------
+ Grammar* loadGrammar
+ (
+ const InputSource& src
+ , const short grammarType
+ , const bool toCache = false
+ );
+ Grammar* loadGrammar
+ (
+ const XMLCh* const systemId
+ , const short grammarType
+ , const bool toCache = false
+ );
+ Grammar* loadGrammar
+ (
+ const char* const systemId
+ , const short grammarType
+ , const bool toCache = false
+ );
+
+ // -----------------------------------------------------------------------
+ // Reset pool of cached grammars
+ // -----------------------------------------------------------------------
+ void resetCachedGrammarPool();
+
+ // -----------------------------------------------------------------------
// Notification that lazy data has been deleted
// -----------------------------------------------------------------------
static void reinitScannerMutex();
@@ -588,8 +609,8 @@
// -----------------------------------------------------------------------
void commonInit();
void initValidator(XMLValidator* theValidator);
- void resetEntityDeclPool();
void resetURIStringPool();
+ InputSource* resolveSystemId(const XMLCh* const sysId); // return owned by caller
// -----------------------------------------------------------------------
@@ -642,7 +663,6 @@
void scanRawAttrListforNameSpaces(const RefVectorOf<KVStringPair>* theRawAttrList, int attCount);
void parseSchemaLocation(const XMLCh* const schemaLocationStr);
void resolveSchemaGrammar(const XMLCh* const loc, const XMLCh* const uri);
- bool switchGrammar(unsigned int newGrammarNameSpaceIndex);
bool switchGrammar(const XMLCh* const newGrammarNameSpace);
bool laxElementValidation(QName* element, ContentLeafNameTypeVector* cv,
const XMLContentModel* const cm,
@@ -710,6 +730,12 @@
void activateSelectorFor(IdentityConstraint* const ic);
// -----------------------------------------------------------------------
+ // Grammar preparsing methods
+ // -----------------------------------------------------------------------
+ Grammar* loadXMLSchemaGrammar(const InputSource& src, const bool toCache = false);
+ Grammar* loadDTDGrammar(const InputSource& src, const bool toCache = false);
+
+ // -----------------------------------------------------------------------
// Data members
//
// fAttrList
@@ -782,13 +808,6 @@
// methods to do specialized checking for chars, sequences of chars,
// skipping chars, etc...
//
- // fReuseGrammar
- // This flag is set on a per-scan basis. So its provided in the
- // scanDocument() and scanFirst() methods, and applies for that
- // one pass. It indicates if the Grammar should be reused or not.
- // If so, then all the Grammar will be ignored.
- // There cannot be any internal subset.
- //
// fScannerId
// fSequenceId
// These are used for progressive parsing, to make sure that the
@@ -878,20 +897,21 @@
// wildcard validation
//
// fGrammarResolver
- // Grammar Pool that stores all the Grammar
+ // Grammar Pool that stores all the grammars. Key is namespace for
+ // schema and system id for external DTD. When caching a grammar, if
+ // a grammar is already in the pool, it will be replaced with the
+ // new parsed one.
//
// fGrammar
// Current Grammar used by the Scanner and Validator
//
+ // fRootGrammar
+ // The grammar where the root element is declared.
+ //
// fGrammarType
// Current Grammar Type. Store this value instead of calling getGrammarType
// all the time for faster performance.
//
- // fEntityDeclPool
- // This is a pool of EntityDecl objects, which contains all of the
- // general entities that are declared in the DTD subsets, plus the
- // default entities (such as > < ...) defined by the XML Standard.
- //
// fURIStringPool
// This is a pool for URIs with unique ids assigned. We use a standard
// string pool class. This pool is going to be shared by all Grammar.
@@ -935,7 +955,6 @@
bool fExitOnFirstFatal;
bool fValidationConstraintFatal;
bool fInException;
- bool fReuseGrammar;
bool fStandalone;
bool fHasNoDTD;
bool fValidate;
@@ -943,6 +962,8 @@
bool fDoSchema;
bool fSchemaFullChecking;
bool fSeeXsi;
+ bool fToCacheGrammar;
+ bool fUseCachedGrammar;
int fErrorCount;
unsigned int fEmptyNamespaceId;
unsigned int fUnknownNamespaceId;
@@ -977,8 +998,9 @@
XMLBuffer fURIBuf;
GrammarResolver* fGrammarResolver;
Grammar* fGrammar;
+ Grammar* fRootGrammar;
+ DTDGrammar* fDTDGrammar;
Grammar::GrammarType fGrammarType;
- NameIdPool<DTDEntityDecl>* fEntityDeclPool;
XMLStringPool* fURIStringPool;
XPathMatcherStack* fMatcherStack;
ValueStoreCache* fValueStoreCache;
@@ -1140,30 +1162,14 @@
return fXMLNSNamespaceId;
}
-inline NameIdPoolEnumerator<DTDEntityDecl>
-XMLScanner::getEntityEnumerator() const
-{
- return NameIdPoolEnumerator<DTDEntityDecl>(fEntityDeclPool);
-}
-
-inline const DTDEntityDecl* XMLScanner::getEntityDecl(const XMLCh* const entName) const
-{
- return fEntityDeclPool->getByKey(entName);
-}
-
-inline DTDEntityDecl* XMLScanner::getEntityDecl(const XMLCh* const entName)
-{
- return fEntityDeclPool->getByKey(entName);
-}
-
inline NameIdPool<DTDEntityDecl>* XMLScanner::getEntityDeclPool()
{
- return fEntityDeclPool;
+ return fDTDGrammar->getEntityDeclPool();
}
inline const NameIdPool<DTDEntityDecl>* XMLScanner::getEntityDeclPool() const
{
- return fEntityDeclPool;
+ return fDTDGrammar->getEntityDeclPool();
}
inline const XMLStringPool* XMLScanner::getURIStringPool() const
@@ -1201,6 +1207,26 @@
return fNormalizeData;
}
+inline bool XMLScanner::isCachingGrammarFromParse() const
+{
+ return fToCacheGrammar;
+}
+
+inline bool XMLScanner::isUsingCachedGrammarInParse() const
+{
+ return fUseCachedGrammar;
+}
+
+inline Grammar* XMLScanner::getRootGrammar() const
+{
+ return fRootGrammar;
+}
+
+inline Grammar* XMLScanner::getGrammar(const XMLCh* const nameSpaceKey)
+{
+ return fGrammarResolver->getGrammar(nameSpaceKey);
+}
+
// ---------------------------------------------------------------------------
// XMLScanner: Setter methods
// ---------------------------------------------------------------------------
@@ -1328,6 +1354,16 @@
inline void XMLScanner::setNormalizeData(const bool normalizeData)
{
fNormalizeData = normalizeData;
+}
+
+inline void XMLScanner::cacheGrammarFromParse(const bool newValue)
+{
+ fToCacheGrammar = newValue;
+}
+
+inline void XMLScanner::useCachedGrammarInParse(const bool newValue)
+{
+ fUseCachedGrammar = newValue;
}
1.14 +417 -150 xml-xerces/c/src/xercesc/internal/XMLScanner.cpp
Index: XMLScanner.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/internal/XMLScanner.cpp,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- XMLScanner.cpp 5 Jul 2002 18:42:44 -0000 1.13
+++ XMLScanner.cpp 11 Jul 2002 18:22:13 -0000 1.14
@@ -181,7 +181,6 @@
, fExitOnFirstFatal(true)
, fValidationConstraintFatal(false)
, fInException(false)
- , fReuseGrammar(false)
, fStandalone(false)
, fHasNoDTD(true)
, fValidate(false)
@@ -189,6 +188,8 @@
, fDoSchema(false)
, fSchemaFullChecking(false)
, fSeeXsi(false)
+ , fToCacheGrammar(false)
+ , fUseCachedGrammar(false)
, fErrorCount(0)
, fEmptyNamespaceId(0)
, fUnknownNamespaceId(0)
@@ -213,7 +214,8 @@
, fValScheme(Val_Never)
, fGrammarResolver(0)
, fGrammar(0)
- , fEntityDeclPool(0)
+ , fRootGrammar(0)
+ , fDTDGrammar(0)
, fURIStringPool(0)
, fMatcherStack(0)
, fValueStoreCache(0)
@@ -246,7 +248,6 @@
, fExitOnFirstFatal(true)
, fValidationConstraintFatal(false)
, fInException(false)
- , fReuseGrammar(false)
, fStandalone(false)
, fHasNoDTD(true)
, fValidate(false)
@@ -254,6 +255,8 @@
, fDoSchema(false)
, fSchemaFullChecking(false)
, fSeeXsi(false)
+ , fToCacheGrammar(false)
+ , fUseCachedGrammar(false)
, fErrorCount(0)
, fEmptyNamespaceId(0)
, fUnknownNamespaceId(0)
@@ -278,7 +281,8 @@
, fValScheme(Val_Never)
, fGrammarResolver(0)
, fGrammar(0)
- , fEntityDeclPool(0)
+ , fRootGrammar(0)
+ , fDTDGrammar(0)
, fURIStringPool(0)
, fMatcherStack(0)
, fValueStoreCache(0)
@@ -313,8 +317,6 @@
delete fDTDValidator;
delete fSchemaValidator;
- delete fEntityDeclPool;
-
//fGrammarResolver will delete the fGrammar as well
delete fGrammarResolver;
@@ -333,8 +335,7 @@
// ---------------------------------------------------------------------------
// XMLScanner: Main entry point to scan a document
// ---------------------------------------------------------------------------
-void XMLScanner::scanDocument( const XMLCh* const systemId
- , const bool reuseGrammar)
+void XMLScanner::scanDocument( const XMLCh* const systemId)
{
//
// First we try to parse it as a URL. If that fails, we assume its
@@ -403,20 +404,19 @@
}
Janitor<InputSource> janSrc(srcToUse);
- scanDocument(*srcToUse, reuseGrammar);
+ scanDocument(*srcToUse);
}
-void XMLScanner::scanDocument( const char* const systemId
- , const bool reuseGrammar)
+void XMLScanner::scanDocument( const char* const systemId)
{
// We just delegate this to the XMLCh version after transcoding
XMLCh* tmpBuf = XMLString::transcode(systemId);
ArrayJanitor<XMLCh> janBuf(tmpBuf);
- scanDocument(tmpBuf, reuseGrammar);
+ scanDocument(tmpBuf);
}
-void XMLScanner::scanDocument(const InputSource& src, const bool reuseGrammar)
+void XMLScanner::scanDocument(const InputSource& src)
{
//
// Bump up the sequence id for this parser instance. This will invalidate
@@ -424,9 +424,6 @@
//
fSequenceId++;
- // Store the reuse validator flag
- fReuseGrammar = reuseGrammar;
-
try
{
//
@@ -570,8 +567,7 @@
// going to work on subsequent scanNext() calls.
//
bool XMLScanner::scanFirst( const XMLCh* const systemId
- , XMLPScanToken& toFill
- , const bool reuseGrammar)
+ , XMLPScanToken& toFill)
{
//
// First we try to parse it as a URL. If that fails, we assume its
@@ -639,26 +635,21 @@
}
Janitor<InputSource> janSrc(srcToUse);
- return scanFirst(*srcToUse, toFill, reuseGrammar);
+ return scanFirst(*srcToUse, toFill);
}
bool XMLScanner::scanFirst( const char* const systemId
- , XMLPScanToken& toFill
- , const bool reuseGrammar)
+ , XMLPScanToken& toFill)
{
// We just delegate this to the XMLCh version after transcoding
XMLCh* tmpBuf = XMLString::transcode(systemId);
ArrayJanitor<XMLCh> janBuf(tmpBuf);
- return scanFirst(tmpBuf, toFill, reuseGrammar);
+ return scanFirst(tmpBuf, toFill);
}
bool XMLScanner::scanFirst( const InputSource& src
- , XMLPScanToken& toFill
- , const bool reuseGrammar)
+ , XMLPScanToken& toFill)
{
- // Store the reuse validator flag
- fReuseGrammar = reuseGrammar;
-
//
// Bump up the sequence id for this new scan cycle. This will invalidate
// any previous tokens we've returned.
@@ -1061,14 +1052,9 @@
//
fIDRefList = new RefHashTableOf<XMLRefInfo>(109);
- // Create the EntityDeclPool
- fEntityDeclPool = new NameIdPool<DTDEntityDecl>(109);
-
// Create the GrammarResolver
fGrammarResolver = new GrammarResolver();
- resetEntityDeclPool();
-
// Create the Validator and init them
fDTDValidator = new DTDValidator();
initValidator(fDTDValidator);
@@ -1099,25 +1085,6 @@
}
}
-void XMLScanner::resetEntityDeclPool() {
-
- fEntityDeclPool->removeAll();
- //
- // Add the default entity entries for the character refs that must always
- // be present. We indicate that they are from the internal subset. They
- // aren't really, but they have to look that way so that they are still
- // valid for use within a standalone document.
- //
- // We also mark them as special char entities, which allows them to be
- // used in places whether other non-numeric general entities cannot.
- //
- fEntityDeclPool->put(new DTDEntityDecl(gAmp, chAmpersand, true, true));
- fEntityDeclPool->put(new DTDEntityDecl(gLT, chOpenAngle, true, true));
- fEntityDeclPool->put(new DTDEntityDecl(gGT, chCloseAngle, true, true));
- fEntityDeclPool->put(new DTDEntityDecl(gQuot, chDoubleQuote, true, true));
- fEntityDeclPool->put(new DTDEntityDecl(gApos, chSingleQuote, true, true));
-}
-
void XMLScanner::resetURIStringPool() {
fURIStringPool->flushAll();
@@ -2290,9 +2257,9 @@
// if reusing grammar, this has been validated already in first scan
// skip for performance
- if (!fReuseGrammar && fValidate) {
+ if (fValidate && !fGrammar->getValidated()) {
// validate the DTD scan so far
- fValidator->preContentValidation(fReuseGrammar);
+ fValidator->preContentValidation(fUseCachedGrammar);
}
}
else
@@ -2358,27 +2325,10 @@
void XMLScanner::scanDocTypeDecl()
{
- if (!fReuseGrammar && fValidatorFromUser && !fValidator->handlesDTD())
- {
- ThrowXML(RuntimeException, XMLExcepts::Gen_NoDTDValidator);
- }
-
//
- // We have a doc type. So, create a DTDScanner and
- // switch the Grammar to the emptyNamespace one.
+ // We have a doc type. So, switch the Grammar.
//
-
- if (!switchGrammar(XMLUni::fgZeroLenString) && fValidate)
- {
- fValidator->emitError
- (
- XMLValid::GrammarNotFound
- , XMLUni::fgZeroLenString
- );
- }
-
- DTDScanner dtdScanner((DTDGrammar*)fGrammar, fEntityDeclPool, fDocTypeHandler);
- dtdScanner.setScannerInfo(this, &fReaderMgr, &fBufMgr);
+ switchGrammar(XMLUni::fgDTDEntityString);
if (fDocTypeHandler)
fDocTypeHandler->resetDocType();
@@ -2422,36 +2372,11 @@
// Only do this if we are not reusing the validator! If we are reusing,
// then look it up instead. It has to exist!
//
- DTDElementDecl* rootDecl;
- Janitor<DTDElementDecl> janSrc(0);
+ DTDElementDecl* rootDecl = new DTDElementDecl(bbRootName.getRawBuffer(), fEmptyNamespaceId);
- if (fReuseGrammar)
- {
- if (fGrammar->getGrammarType() == Grammar::DTDGrammarType) {
- rootDecl = (DTDElementDecl*) fGrammar->getElemDecl(fEmptyNamespaceId, 0, bbRootName.getRawBuffer(), Grammar::TOP_LEVEL_SCOPE);
- if (rootDecl)
- ((DTDGrammar*)fGrammar)->setRootElemId(rootDecl->getId());
- else {
- rootDecl = new DTDElementDecl(bbRootName.getRawBuffer(), fEmptyNamespaceId);
- rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
- rootDecl->setExternalElemDeclaration(true);
- ((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl));
- }
- }
- else {
- rootDecl = new DTDElementDecl(bbRootName.getRawBuffer(), fEmptyNamespaceId);
- rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
- rootDecl->setExternalElemDeclaration(true);
- janSrc.reset(rootDecl);
- }
- }
- else
- {
- rootDecl = new DTDElementDecl(bbRootName.getRawBuffer(), fEmptyNamespaceId);
- rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
- rootDecl->setExternalElemDeclaration(true);
- ((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl));
- }
+ rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
+ rootDecl->setExternalElemDeclaration(true);
+ ((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl));
// Skip any spaces after the name
fReaderMgr.skipPastSpaces();
@@ -2472,17 +2397,17 @@
}
// either internal/external subset
- if(!fReuseGrammar) {
- if (fValScheme == Val_Auto && !fValidate)
- fValidate = true;
- }
-
+ if (fValScheme == Val_Auto && !fValidate)
+ fValidate = true;
bool hasIntSubset = false;
bool hasExtSubset = false;
XMLCh* sysId = 0;
XMLCh* pubId = 0;
+ DTDScanner dtdScanner((DTDGrammar*)fGrammar, fDocTypeHandler);
+ dtdScanner.setScannerInfo(this, &fReaderMgr, &fBufMgr);
+
//
// If the next character is '[' then we have no external subset cause
// there is no system id, just the opening character of the internal
@@ -2544,7 +2469,7 @@
fReaderMgr.getNextChar();
// We can't have any internal subset if we are reusing the validator
- if (fReuseGrammar)
+ if (fUseCachedGrammar || fToCacheGrammar)
ThrowXML(RuntimeException, XMLExcepts::Val_CantHaveIntSS);
//
@@ -2596,50 +2521,88 @@
// If we had an external subset, then we need to deal with that one
// next. If we are reusing the validator, then don't scan it.
//
- if (hasExtSubset && !fReuseGrammar && (fLoadExternalDTD || fValidate))
- {
- // And now create a reader to read this entity
- InputSource* srcUsed;
- XMLReader* reader = fReaderMgr.createReader
- (
- sysId
- , pubId
- , false
- , XMLReader::RefFrom_NonLiteral
- , XMLReader::Type_General
- , XMLReader::Source_External
- , srcUsed
- );
+ if (hasExtSubset) {
+
+ if (fUseCachedGrammar)
+ {
+ InputSource* sysIdSrc = resolveSystemId(sysId);
+ Janitor<InputSource> janSysIdSrc(sysIdSrc);
+ Grammar* grammar = fGrammarResolver->getGrammar(sysIdSrc->getSystemId());
- // Put a janitor on the input source
- Janitor<InputSource> janSrc(srcUsed);
+ if (grammar && grammar->getGrammarType() == Grammar::DTDGrammarType) {
- //
- // If it failed then throw an exception
- //
- if (!reader)
- ThrowXML1(RuntimeException, XMLExcepts::Gen_CouldNotOpenDTD, srcUsed->getSystemId());
+ fDTDGrammar = (DTDGrammar*) grammar;
+ fGrammar = fDTDGrammar;
+ fValidator->setGrammar(fGrammar);
+ rootDecl = (DTDElementDecl*) fGrammar->getElemDecl(fEmptyNamespaceId, 0, bbRootName.getRawBuffer(), Grammar::TOP_LEVEL_SCOPE);
- //
- // In order to make the processing work consistently, we have to
- // make this look like an external entity. So create an entity
- // decl and fill it in and push it with the reader, as happens
- // with an external entity. Put a janitor on it to insure it gets
- // cleaned up. The reader manager does not adopt them.
- //
- const XMLCh gDTDStr[] = { chLatin_D, chLatin_T, chLatin_D , chNull };
- DTDEntityDecl* declDTD = new DTDEntityDecl(gDTDStr);
- declDTD->setSystemId(sysId);
- Janitor<DTDEntityDecl> janDecl(declDTD);
+ if (rootDecl)
+ ((DTDGrammar*)fGrammar)->setRootElemId(rootDecl->getId());
+ else {
+ rootDecl = new DTDElementDecl(bbRootName.getRawBuffer(), fEmptyNamespaceId);
+ rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
+ rootDecl->setExternalElemDeclaration(true);
+ ((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl));
+ }
+
+ return;
+ }
+ }
+
+ if (fLoadExternalDTD || fValidate)
+ {
+ // And now create a reader to read this entity
+ InputSource* srcUsed;
+ XMLReader* reader = fReaderMgr.createReader
+ (
+ sysId
+ , pubId
+ , false
+ , XMLReader::RefFrom_NonLiteral
+ , XMLReader::Type_General
+ , XMLReader::Source_External
+ , srcUsed
+ );
+
+ // Put a janitor on the input source
+ Janitor<InputSource> janSrc(srcUsed);
+
+ //
+ // If it failed then throw an exception
+ //
+ if (!reader)
+ ThrowXML1(RuntimeException, XMLExcepts::Gen_CouldNotOpenDTD, srcUsed->getSystemId());
+
+ if (fToCacheGrammar) {
+
+ unsigned int stringId = fGrammarResolver->getStringPool()->addOrFind(srcUsed->getSystemId());
+ const XMLCh* sysIdStr = fGrammarResolver->getStringPool()->getValueForId(stringId);
+
+ fGrammarResolver->orphanGrammar(XMLUni::fgDTDEntityString);
+ fGrammarResolver->putGrammar(sysIdStr, fGrammar);
+ }
+
+ //
+ // In order to make the processing work consistently, we have to
+ // make this look like an external entity. So create an entity
+ // decl and fill it in and push it with the reader, as happens
+ // with an external entity. Put a janitor on it to insure it gets
+ // cleaned up. The reader manager does not adopt them.
+ //
+ const XMLCh gDTDStr[] = { chLatin_D, chLatin_T, chLatin_D , chNull };
+ DTDEntityDecl* declDTD = new DTDEntityDecl(gDTDStr);
+ declDTD->setSystemId(sysId);
+ Janitor<DTDEntityDecl> janDecl(declDTD);
- // Mark this one as a throw at end
- reader->setThrowAtEnd(true);
+ // Mark this one as a throw at end
+ reader->setThrowAtEnd(true);
- // And push it onto the stack, with its pseudo name
- fReaderMgr.pushReader(reader, declDTD);
+ // And push it onto the stack, with its pseudo name
+ fReaderMgr.pushReader(reader, declDTD);
- // Tell it its not in an include section
- dtdScanner.scanExtSubsetDecl(false);
+ // Tell it its not in an include section
+ dtdScanner.scanExtSubsetDecl(false);
+ }
}
}
@@ -2734,6 +2697,8 @@
//
if (isRoot)
{
+ fRootGrammar = fGrammar;
+
if (fValidate)
{
// If a DocType exists, then check if it matches the root name there.
@@ -3125,6 +3090,16 @@
if ((defType == XMLAttDef::Default)
|| (defType == XMLAttDef::Fixed))
{
+ // Let the validator pass judgement on the attribute value
+ if (fValidate)
+ {
+ fValidator->validateAttrValue
+ (
+ &curDef
+ , curDef.getValue()
+ );
+ }
+
XMLAttr* curAtt;
if (attCount >= curAttListSize)
{
@@ -3316,7 +3291,6 @@
// go through them first before scanning those specified in the instance document
if (isRoot
&& fDoSchema
- && !fReuseGrammar
&& (fExternalSchemaLocation || fExternalNoNamespaceSchemaLocation)) {
if (fExternalSchemaLocation)
@@ -3468,7 +3442,8 @@
, nameRawBuf
, fPrefixBuf.getRawBuffer()
, qnameRawBuf
- , currentScope);
+ , currentScope
+ , true);
wasAdded = true;
}
}
@@ -3556,7 +3531,8 @@
, nameRawBuf
, fPrefixBuf.getRawBuffer()
, qnameRawBuf
- , currentScope);
+ , currentScope
+ , true);
wasAdded = true;
}
}
@@ -3617,6 +3593,9 @@
fElemStack.setElement(elemDecl, fReaderMgr.getCurrentReaderNum());
fElemStack.setCurrentURI(uriId);
+ if (isRoot)
+ fRootGrammar = fGrammar;
+
// Validate the element
if (fValidate)
fValidator->validateElement(elemDecl);
@@ -3631,7 +3610,7 @@
const XMLCh poundStr[] = {chPound, chNull};
if (!XMLString::startsWith(typeName, poundStr)) {
const int comma = XMLString::indexOf(typeName, chComma);
- if (comma != -1) {
+ if (comma > 0) {
XMLBuffer prefixBuf(comma+1);
prefixBuf.append(typeName, comma);
const XMLCh* uriStr = prefixBuf.getRawBuffer();
@@ -4289,3 +4268,291 @@
matcher->startDocumentFragment();
}
+// ---------------------------------------------------------------------------
+// XMLScanner: Grammar preparsing
+// ---------------------------------------------------------------------------
+Grammar* XMLScanner::loadGrammar(const XMLCh* const systemId
+ , const short grammarType
+ , const bool toCache)
+{
+ InputSource* srcToUse = 0;
+
+ if (fEntityHandler){
+ srcToUse = fEntityHandler->resolveEntity(XMLUni::fgZeroLenString, systemId);
+ }
+
+ //
+ // First we try to parse it as a URL. If that fails, we assume its
+ // a file and try it that way.
+ //
+ if (!srcToUse) {
+
+ try
+ {
+ //
+ // Create a temporary URL. Since this is the primary document,
+ // it has to be fully qualified. If not, then assume we are just
+ // mistaking a file for a URL.
+ //
+ XMLURL tmpURL(systemId);
+ if (tmpURL.isRelative()) {
+ srcToUse = new LocalFileInputSource(systemId);
+ }
+ else
+ {
+ srcToUse = new URLInputSource(tmpURL);
+ }
+ }
+ catch(const MalformedURLException&)
+ {
+ srcToUse = new LocalFileInputSource(systemId);
+ }
+ catch(...)
+ {
+ // Just rethrow this, since its not our problem
+ throw;
+ }
+ }
+
+ Janitor<InputSource> janSrc(srcToUse);
+ return loadGrammar(*srcToUse, grammarType, toCache);
+}
+
+Grammar* XMLScanner::loadGrammar(const char* const systemId
+ , const short grammarType
+ , const bool toCache)
+{
+ // We just delegate this to the XMLCh version after transcoding
+ XMLCh* tmpBuf = XMLString::transcode(systemId);
+ ArrayJanitor<XMLCh> janBuf(tmpBuf);
+ return loadGrammar(tmpBuf, grammarType, toCache);
+}
+
+
+Grammar* XMLScanner::loadGrammar(const InputSource& src
+ , const short grammarType
+ , const bool toCache)
+{
+ try
+ {
+ fGrammarResolver->cacheGrammarFromParse(false);
+ fGrammarResolver->useCachedGrammarInParse(false);
+ fRootGrammar = 0;
+
+ if (fValScheme == Val_Auto) {
+ fValidate = true;
+ }
+
+ // Reset some status flags
+ fInException = false;
+ fStandalone = false;
+ fErrorCount = 0;
+ fHasNoDTD = true;
+ fSeeXsi = false;
+
+ if (grammarType == Grammar::SchemaGrammarType) {
+ return loadXMLSchemaGrammar(src, toCache);
+ }
+ else if (grammarType == Grammar::DTDGrammarType) {
+ return loadDTDGrammar(src, toCache);
+ }
+
+ // Reset the reader manager to close all files, sockets, etc...
+ fReaderMgr.reset();
+ }
+
+ //
+ // NOTE:
+ //
+ // In all of the error processing below, the emitError() call MUST come
+ // before the flush of the reader mgr, or it will fail because it tries
+ // to find out the position in the XML source of the error.
+ //
+ catch(const XMLErrs::Codes)
+ {
+ // This is a 'first fatal error' type exit, so reset and fall through
+ fReaderMgr.reset();
+ }
+
+ catch(const XMLValid::Codes)
+ {
+ // This is a 'first fatal error' type exit, so reset and fall through
+ fReaderMgr.reset();
+
+ }
+
+ catch(const XMLException& excToCatch)
+ {
+ //
+ // Emit the error and catch any user exception thrown from here. Make
+ // sure in all cases we flush the reader manager.
+ //
+ fInException = true;
+ try
+ {
+ if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning)
+ emitError
+ (
+ XMLErrs::XMLException_Warning
+ , excToCatch.getType()
+ , excToCatch.getMessage()
+ );
+ else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal)
+ emitError
+ (
+ XMLErrs::XMLException_Fatal
+ , excToCatch.getType()
+ , excToCatch.getMessage()
+ );
+ else
+ emitError
+ (
+ XMLErrs::XMLException_Error
+ , excToCatch.getType()
+ , excToCatch.getMessage()
+ );
+ }
+
+ catch(...)
+ {
+ // Flush the reader manager and rethrow user's error
+ fReaderMgr.reset();
+ throw;
+ }
+
+ // If it returned, then reset the reader manager and fall through
+ fReaderMgr.reset();
+ }
+
+ catch(...)
+ {
+ // Reset and rethrow
+ fReaderMgr.reset();
+ throw;
+ }
+
+ return 0;
+}
+
+Grammar* XMLScanner::loadDTDGrammar(const InputSource& src,
+ const bool toCache)
+{
+ // Reset the validators
+ fDTDValidator->reset();
+ if (fValidatorFromUser)
+ fValidator->reset();
+
+ if (!fValidator->handlesDTD()) {
+ if (fValidatorFromUser && fValidate)
+ ThrowXML(RuntimeException, XMLExcepts::Gen_NoDTDValidator);
+ else {
+ fValidator = fDTDValidator;
+ }
+ }
+
+ fDTDGrammar = new DTDGrammar();
+ fGrammarResolver->putGrammar(XMLUni::fgDTDEntityString, fDTDGrammar);
+ fGrammar = fDTDGrammar;
+ fGrammarType = fGrammar->getGrammarType();
+ fValidator->setGrammar(fGrammar);
+
+ //
+ // And for all installed handlers, send reset events. This gives them
+ // a chance to flush any cached data.
+ //
+ if (fDocHandler)
+ fDocHandler->resetDocument();
+ if (fEntityHandler)
+ fEntityHandler->resetEntities();
+ if (fErrorReporter)
+ fErrorReporter->resetErrors();
+
+ // Clear out the id reference list
+ fIDRefList->removeAll();
+
+ if (toCache) {
+
+ unsigned int sysId = fGrammarResolver->getStringPool()->addOrFind(src.getSystemId());
+ const XMLCh* sysIdStr = fGrammarResolver->getStringPool()->getValueForId(sysId);
+
+ fGrammarResolver->orphanGrammar(XMLUni::fgDTDEntityString);
+ fGrammarResolver->putGrammar(sysIdStr, fGrammar);
+ }
+
+ //
+ // Handle the creation of the XML reader object for this input source.
+ // This will provide us with transcoding and basic lexing services.
+ //
+ XMLReader* newReader = fReaderMgr.createReader
+ (
+ src
+ , false
+ , XMLReader::RefFrom_NonLiteral
+ , XMLReader::Type_General
+ , XMLReader::Source_External
+ );
+ if (!newReader) {
+ if (src.getIssueFatalErrorIfNotFound())
+ ThrowXML1(RuntimeException, XMLExcepts::Scan_CouldNotOpenSource, src.getSystemId());
+ else
+ ThrowXML1(RuntimeException, XMLExcepts::Scan_CouldNotOpenSource_Warning, src.getSystemId());
+ }
+
+ //
+ // In order to make the processing work consistently, we have to
+ // make this look like an external entity. So create an entity
+ // decl and fill it in and push it with the reader, as happens
+ // with an external entity. Put a janitor on it to insure it gets
+ // cleaned up. The reader manager does not adopt them.
+ //
+ const XMLCh gDTDStr[] = { chLatin_D, chLatin_T, chLatin_D , chNull };
+ DTDEntityDecl* declDTD = new DTDEntityDecl(gDTDStr);
+ declDTD->setSystemId(src.getSystemId());
+ Janitor<DTDEntityDecl> janDecl(declDTD);
+
+ // Mark this one as a throw at end
+ newReader->setThrowAtEnd(true);
+
+ // And push it onto the stack, with its pseudo name
+ fReaderMgr.pushReader(newReader, declDTD);
+
+ //
+ // If we have a doc type handler and advanced callbacks are enabled,
+ // call the doctype event.
+ //
+ if (fDocTypeHandler) {
+
+ // Create a dummy root
+ DTDElementDecl* rootDecl = new DTDElementDecl(gDTDStr, fEmptyNamespaceId);
+ rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
+ rootDecl->setExternalElemDeclaration(true);
+ Janitor<DTDElementDecl> janSrc(rootDecl);
+
+ fDocTypeHandler->doctypeDecl(*rootDecl, src.getPublicId(), src.getSystemId(), false);
+ }
+
+ // Create DTDScanner
+ DTDScanner dtdScanner((DTDGrammar*)fGrammar, fDocTypeHandler);
+ dtdScanner.setScannerInfo(this, &fReaderMgr, &fBufMgr);
+
+ // Tell it its not in an include section
+ dtdScanner.scanExtSubsetDecl(false);
+
+ if (fValidate) {
+ // validate the DTD scan so far
+ fValidator->preContentValidation(false, true);
+ }
+
+ if (toCache)
+ fGrammarResolver->cacheGrammars();
+
+ return fDTDGrammar;
+}
+
+// ---------------------------------------------------------------------------
+// XMLScanner: Rest pool of cached grammars
+// ---------------------------------------------------------------------------
+void XMLScanner::resetCachedGrammarPool()
+{
+ fGrammarResolver->resetCachedGrammar();
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org