neilg 2003/09/22 12:51:41
Modified: c/src/xercesc/internal DGXMLScanner.cpp DGXMLScanner.hpp
IGXMLScanner.cpp IGXMLScanner.hpp SGXMLScanner.cpp
SGXMLScanner.hpp
Log:
scanners should maintain their own pools of undeclared elements, rather than
requiring grammars to do this. This makes grammar objects stateless with regard to
validation.
Revision Changes Path
1.23 +43 -9 xml-xerces/c/src/xercesc/internal/DGXMLScanner.cpp
Index: DGXMLScanner.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/internal/DGXMLScanner.cpp,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- DGXMLScanner.cpp 31 Jul 2003 17:05:03 -0000 1.22
+++ DGXMLScanner.cpp 22 Sep 2003 19:51:41 -0000 1.23
@@ -93,6 +93,7 @@
, fAttrNSList(0)
, fDTDValidator(0)
, fDTDGrammar(0)
+ , fDTDElemNonDeclPool(0)
{
try
{
@@ -128,6 +129,7 @@
, fAttrNSList(0)
, fDTDValidator(0)
, fDTDGrammar(0)
+ , fDTDElemNonDeclPool(0)
{
try
{
@@ -778,11 +780,20 @@
, fEmptyNamespaceId
, DTDElementDecl::Any
, fGrammarPoolMemoryManager
- );
-
+ );
rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
rootDecl->setExternalElemDeclaration(true);
- ((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl));
+ if(!fUseCachedGrammar)
+ {
+ // this will break getRootElemId on DTDGrammar when
+ // cached grammars are in use, but
+ // why would one use this anyway???
+ ((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl));
+ } else
+ {
+ // put this in the undeclared pool so it gets deleted...
+ rootDecl->setId(fDTDElemNonDeclPool->put((DTDElementDecl*)rootDecl));
+ }
// Skip any spaces after the name
fReaderMgr.skipPastSpaces();
@@ -930,6 +941,10 @@
fDTDGrammar = (DTDGrammar*) grammar;
fGrammar = fDTDGrammar;
fValidator->setGrammar(fGrammar);
+ // we *cannot* identify the root element on
+ // cached grammars; else we risk breaking multithreaded
+ // applications. - NG
+ /*******
rootDecl = (DTDElementDecl*)
fGrammar->getElemDecl(fEmptyNamespaceId, 0, bbRootName.getRawBuffer(),
Grammar::TOP_LEVEL_SCOPE);
if (rootDecl)
@@ -946,6 +961,7 @@
rootDecl->setExternalElemDeclaration(true);
((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl));
}
+ *********/
return;
}
@@ -1032,18 +1048,34 @@
// this can only be called if we are doing a DTD style validator and that
// he will only look at the QName.
//
- // We tell him to fault in a decl if he does not find one.
+ // We *do not* tell him to fault in a decl if he does not find one - NG.
bool wasAdded = false;
- const XMLCh* qnameRawBuf = fQNameBuf.getRawBuffer();
- XMLElementDecl* elemDecl = fGrammar->findOrAddElemDecl
+ const XMLCh* qnameRawBuf = fQNameBuf.getRawBuffer();
+
+ XMLElementDecl* elemDecl = fGrammar->getElemDecl
(
fEmptyNamespaceId
, 0
- , 0
, qnameRawBuf
, Grammar::TOP_LEVEL_SCOPE
- , wasAdded
);
+ // look in the undeclared pool:
+ if(!elemDecl)
+ {
+ elemDecl = fDTDElemNonDeclPool->getByKey(qnameRawBuf);
+ }
+ if(!elemDecl)
+ {
+ wasAdded = true;
+ elemDecl = new (fMemoryManager) DTDElementDecl
+ (
+ qnameRawBuf
+ , fEmptyNamespaceId
+ , DTDElementDecl::Any
+ , fMemoryManager
+ );
+ elemDecl->setId(fDTDElemNonDeclPool->put((DTDElementDecl*)elemDecl));
+ }
if (fValidate) {
@@ -1802,12 +1834,14 @@
// Create the Validator and init them
fDTDValidator = new (fMemoryManager) DTDValidator();
initValidator(fDTDValidator);
+ fDTDElemNonDeclPool = new (fMemoryManager) NameIdPool<DTDElementDecl>(29, 128,
fMemoryManager);
}
void DGXMLScanner::cleanUp()
{
delete fAttrNSList;
delete fDTDValidator;
+ delete fDTDElemNonDeclPool;
}
1.9 +8 -17 xml-xerces/c/src/xercesc/internal/DGXMLScanner.hpp
Index: DGXMLScanner.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/internal/DGXMLScanner.hpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- DGXMLScanner.hpp 24 Jul 2003 09:19:09 -0000 1.8
+++ DGXMLScanner.hpp 22 Sep 2003 19:51:41 -0000 1.9
@@ -56,6 +56,9 @@
/*
* $Log$
+ * Revision 1.9 2003/09/22 19:51:41 neilg
+ * scanners should maintain their own pools of undeclared elements, rather than
requiring grammars to do this. This makes grammar objects stateless with regard to
validation.
+ *
* Revision 1.8 2003/07/24 09:19:09 gareth
* Patch for bug #20530 - Attributes which have the same expanded name are not
considered duplicates. Patch by cargilld.
*
@@ -90,10 +93,12 @@
#include <xercesc/internal/XMLScanner.hpp>
#include <xercesc/internal/ElemStack.hpp>
#include <xercesc/util/ValueVectorOf.hpp>
+#include <xercesc/util/NameIdPool.hpp>
#include <xercesc/validators/common/Grammar.hpp>
XERCES_CPP_NAMESPACE_BEGIN
+class DTDElementDecl;
class DTDGrammar;
class DTDValidator;
@@ -230,34 +235,20 @@
// fDTDValidator
// The DTD validator instance.
//
- // fSchemaValidator
- // The Schema validator instance.
- //
- // fSeeXsi
- // This flag indicates a schema has been seen.
- //
// fElemState
// fElemStateSize
// Stores an element next state from DFA content model - used for
// wildcard validation
//
- // fMatcherStack
- // Stack of active XPath matchers for identity constraints. All
- // active XPath matchers are notified of startElement, characters
- // and endElement callbacks in order to perform their matches.
- //
- // fValueStoreCache
- // Cache of value stores for identity constraint fields.
- //
- // fFieldActivator
- // Activates fields within a certain scope when a selector matches
- // its xpath.
+ // fDTDElemNonDeclPool
+ // registry of "faulted-in" DTD element decls
//
// -----------------------------------------------------------------------
ElemStack fElemStack;
ValueVectorOf<XMLAttr*>* fAttrNSList;
DTDValidator* fDTDValidator;
DTDGrammar* fDTDGrammar;
+ NameIdPool<DTDElementDecl>* fDTDElemNonDeclPool;
};
inline const XMLCh* DGXMLScanner::getName() const
1.23 +144 -27 xml-xerces/c/src/xercesc/internal/IGXMLScanner.cpp
Index: IGXMLScanner.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/internal/IGXMLScanner.cpp,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- IGXMLScanner.cpp 27 Aug 2003 13:19:14 -0000 1.22
+++ IGXMLScanner.cpp 22 Sep 2003 19:51:41 -0000 1.23
@@ -106,6 +106,8 @@
, fMatcherStack(0)
, fValueStoreCache(0)
, fFieldActivator(0)
+ , fDTDElemNonDeclPool(0)
+ , fSchemaElemNonDeclPool(0)
{
try
{
@@ -143,6 +145,8 @@
, fMatcherStack(0)
, fValueStoreCache(0)
, fFieldActivator(0)
+ , fDTDElemNonDeclPool(0)
+ , fSchemaElemNonDeclPool(0)
{
try
{
@@ -521,6 +525,9 @@
// Create schemaLocation pair info
fLocationPairs = new (fMemoryManager) ValueVectorOf<XMLCh*>(8, fMemoryManager);
+ // create pools for undeclared elements
+ fDTDElemNonDeclPool = new (fMemoryManager) NameIdPool<DTDElementDecl>(29, 128,
fMemoryManager);
+ fSchemaElemNonDeclPool = new (fMemoryManager)
RefHash3KeysIdPool<SchemaElementDecl>(29, true, 128, fMemoryManager);
}
void IGXMLScanner::cleanUp()
@@ -533,6 +540,8 @@
delete fMatcherStack;
delete fValueStoreCache;
delete fLocationPairs;
+ delete fDTDElemNonDeclPool;
+ delete fSchemaElemNonDeclPool;
}
// ---------------------------------------------------------------------------
@@ -1187,11 +1196,20 @@
, fEmptyNamespaceId
, DTDElementDecl::Any
, fGrammarPoolMemoryManager
- );
-
+ );
rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
rootDecl->setExternalElemDeclaration(true);
- ((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl));
+ if(!fUseCachedGrammar)
+ {
+ // this will break getRootElemId on DTDGrammar when
+ // cached grammars are in use, but
+ // why would one use this anyway???
+ ((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl));
+ } else
+ {
+ // attach this to the undeclared element pool so that it gets deleted
+ rootDecl->setId(fDTDElemNonDeclPool->put((DTDElementDecl*)rootDecl));
+ }
// Skip any spaces after the name
fReaderMgr.skipPastSpaces();
@@ -1339,6 +1357,8 @@
fDTDGrammar = (DTDGrammar*) grammar;
fGrammar = fDTDGrammar;
fValidator->setGrammar(fGrammar);
+ // should not be modifying cached grammars!
+ /********
rootDecl = (DTDElementDecl*)
fGrammar->getElemDecl(fEmptyNamespaceId, 0, bbRootName.getRawBuffer(),
Grammar::TOP_LEVEL_SCOPE);
if (rootDecl)
@@ -1355,6 +1375,7 @@
rootDecl->setExternalElemDeclaration(true);
((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl));
}
+ ********/
return;
}
@@ -1439,16 +1460,36 @@
// he will only look at the QName.
//
// We tell him to fault in a decl if he does not find one.
+ // Actually, we *don't* tell him to fault in a decl if he does not find one- NG
bool wasAdded = false;
- XMLElementDecl* elemDecl = fGrammar->findOrAddElemDecl
+ const XMLCh *rawQName = fQNameBuf.getRawBuffer();
+ XMLElementDecl* elemDecl = fGrammar->getElemDecl
(
fEmptyNamespaceId
, 0
- , 0
- , fQNameBuf.getRawBuffer()
+ , rawQName
, Grammar::TOP_LEVEL_SCOPE
- , wasAdded
);
+ // look for it in the undeclared pool:
+ if(!elemDecl)
+ {
+ elemDecl = fDTDElemNonDeclPool->getByKey(rawQName);
+ }
+ if(!elemDecl)
+ {
+ // we're assuming this must be a DTD element. DTD's can be
+ // used with or without namespaces, but schemas cannot be used without
+ // namespaces.
+ wasAdded = true;
+ elemDecl = new (fMemoryManager) DTDElementDecl
+ (
+ rawQName
+ , fEmptyNamespaceId
+ , DTDElementDecl::Any
+ , fMemoryManager
+ );
+ elemDecl->setId(fDTDElemNonDeclPool->put((DTDElementDecl*)elemDecl));
+ }
// We do something different here according to whether we found the
// element or not.
@@ -2047,13 +2088,16 @@
// this element.
XMLElementDecl* elemDecl = 0;
if (fGrammarType == Grammar::DTDGrammarType) {
+ const XMLCh *rawQName = fQNameBuf.getRawBuffer();
elemDecl = fGrammar->getElemDecl
(
fEmptyNamespaceId
, 0
- , fQNameBuf.getRawBuffer()
+ , rawQName
, Grammar::TOP_LEVEL_SCOPE
);
+ // may have not been declared:
+ elemDecl = fDTDElemNonDeclPool->getByKey(rawQName);
if (elemDecl) {
if (elemDecl->hasAttDefs()) {
XMLAttDefList& attDefList = elemDecl->getAttDefList();
@@ -2110,16 +2154,31 @@
const XMLCh* original_uriStr = fGrammar->getTargetNamespace();
unsigned orgGrammarUri = fURIStringPool->getId(original_uriStr);
+ // REVISIT: since all this code only really
+ // makes sense for schemas, why can DTD validation theoretically pass
+ // through it? - NG
if (uriId != fEmptyNamespaceId) {
// Check in current grammar before switching if necessary
+ const XMLCh *rawQName = fQNameBuf.getRawBuffer();
elemDecl = fGrammar->getElemDecl
(
uriId
, nameRawBuf
- , qnameRawBuf
+ , rawQName
, currentScope
);
+ // may have not been declared; must look everywhere:
+ if (!elemDecl)
+ if(fGrammarType == Grammar::DTDGrammarType)
+ {
+ // should never occur in practice
+ elemDecl = fDTDElemNonDeclPool->getByKey(rawQName);
+ }
+ else if (fGrammarType == Grammar::SchemaGrammarType)
+ {
+ elemDecl = fSchemaElemNonDeclPool->getByKey(nameRawBuf, uriId,
currentScope);
+ }
if (!elemDecl && (orgGrammarUri != uriId)) {
// not found, switch to the specified grammar
@@ -2156,6 +2215,12 @@
, Grammar::TOP_LEVEL_SCOPE
);
+ if(!elemDecl)
+ {
+ // look in the list of undeclared elements, as would have been done
+ // before we made grammars stateless:
+ elemDecl = fSchemaElemNonDeclPool->getByKey(nameRawBuf, uriId,
Grammar::TOP_LEVEL_SCOPE);
+ }
if(!elemDecl) {
// still not found in specified uri
// try emptyNamesapce see if element should be un-qualified.
@@ -2185,12 +2250,29 @@
// still not found, fault this in and issue error later
// switch back to original grammar first
switchGrammar(original_uriStr);
- elemDecl = fGrammar->putElemDecl(uriId
- , nameRawBuf
- , fPrefixBuf.getRawBuffer()
- , qnameRawBuf
- , currentScope
- , true);
+ if(fGrammarType == Grammar::DTDGrammarType)
+ {
+ elemDecl = new (fMemoryManager) DTDElementDecl
+ (
+ qnameRawBuf
+ , uriId
+ , DTDElementDecl::Any
+ , fMemoryManager
+ );
+
elemDecl->setId(fDTDElemNonDeclPool->put((DTDElementDecl*)elemDecl));
+ } else if (fGrammarType == Grammar::SchemaGrammarType)
+ {
+ elemDecl = new (fMemoryManager) SchemaElementDecl
+ (
+ fPrefixBuf.getRawBuffer()
+ , nameRawBuf
+ , uriId
+ , SchemaElementDecl::Any
+ , Grammar::TOP_LEVEL_SCOPE
+ , fMemoryManager
+ );
+
elemDecl->setId(fSchemaElemNonDeclPool->put((void*)elemDecl->getBaseName(), uriId,
currentScope, (SchemaElementDecl*)elemDecl));
+ }
wasAdded = true;
}
}
@@ -2200,7 +2282,7 @@
//thus it is either a non-qualified element defined in current targetNS
//or an element that is defined in the globalNS
- //try unqualifed first
+ //try unqualified first
elemDecl = fGrammar->getElemDecl
(
uriId
@@ -2209,6 +2291,19 @@
, currentScope
);
+ // may have not been declared; must look everywhere:
+ if(!elemDecl)
+ if (fGrammarType == Grammar::DTDGrammarType)
+ {
+ // should never happen in practice?
+ elemDecl = fDTDElemNonDeclPool->getByKey(qnameRawBuf);
+ }
+ else if (fGrammarType == Grammar::SchemaGrammarType)
+ {
+ // look in the list of undeclared elements, as would have been done
+ // before we made grammars stateless:
+ elemDecl = fSchemaElemNonDeclPool->getByKey(nameRawBuf, uriId,
currentScope);
+ }
if (!elemDecl && orgGrammarUri != fEmptyNamespaceId) {
//not found, switch grammar and try globalNS
bool errorCondition = !switchGrammar(XMLUni::fgZeroLenString) &&
fValidate;
@@ -2242,16 +2337,20 @@
, qnameRawBuf
, Grammar::TOP_LEVEL_SCOPE
);
+ if(!elemDecl)
+ {
+ // look in the list of undeclared elements, as would have been done
+ // before we made grammars stateless:
+ elemDecl = fSchemaElemNonDeclPool->getByKey(nameRawBuf, uriId,
Grammar::TOP_LEVEL_SCOPE);
+ }
if (!elemDecl && orgGrammarUri != fEmptyNamespaceId) {
// still Not found in specified uri
// go to original Grammar again to see if element needs to be fully
qualified.
- const XMLCh* uriStr = getURIText(orgGrammarUri);
bool errorCondition = !switchGrammar(original_uriStr) && fValidate;
if (errorCondition && !laxThisOne)
-
- if (errorCondition && !laxThisOne)
{
+ const XMLCh* uriStr = getURIText(orgGrammarUri);
fValidator->emitError
(
XMLValid::GrammarNotFound
@@ -2269,7 +2368,6 @@
, qnameRawBuf
, currentScope
);
-
if (elemDecl && elemDecl->getCreateReason() !=
XMLElementDecl::JustFaultIn && fValidate) {
fValidator->emitError
(
@@ -2285,12 +2383,29 @@
// still not found, fault this in and issue error later
// switch back to original grammar first
switchGrammar(original_uriStr);
- elemDecl = fGrammar->putElemDecl(uriId
- , nameRawBuf
- , fPrefixBuf.getRawBuffer()
- , qnameRawBuf
- , currentScope
- , true);
+ if(fGrammarType == Grammar::DTDGrammarType)
+ {
+ elemDecl = new (fMemoryManager) DTDElementDecl
+ (
+ qnameRawBuf
+ , uriId
+ , DTDElementDecl::Any
+ , fMemoryManager
+ );
+
elemDecl->setId(fDTDElemNonDeclPool->put((DTDElementDecl*)elemDecl));
+ } else if (fGrammarType == Grammar::SchemaGrammarType)
+ {
+ elemDecl = new (fMemoryManager) SchemaElementDecl
+ (
+ fPrefixBuf.getRawBuffer()
+ , nameRawBuf
+ , uriId
+ , SchemaElementDecl::Any
+ , Grammar::TOP_LEVEL_SCOPE
+ , fMemoryManager
+ );
+
elemDecl->setId(fSchemaElemNonDeclPool->put((void*)elemDecl->getBaseName(), uriId,
currentScope, (SchemaElementDecl*)elemDecl));
+ }
wasAdded = true;
}
}
@@ -2881,6 +2996,8 @@
// Clear out the id reference list
fIDRefList->removeAll();
+ // and clear out the darned undeclared DTD element pool...
+ fDTDElemNonDeclPool->removeAll();
if (toCache) {
1.10 +12 -0 xml-xerces/c/src/xercesc/internal/IGXMLScanner.hpp
Index: IGXMLScanner.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/internal/IGXMLScanner.hpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- IGXMLScanner.hpp 14 Aug 2003 02:56:41 -0000 1.9
+++ IGXMLScanner.hpp 22 Sep 2003 19:51:41 -0000 1.10
@@ -56,6 +56,9 @@
/*
* $Log$
+ * Revision 1.10 2003/09/22 19:51:41 neilg
+ * scanners should maintain their own pools of undeclared elements, rather than
requiring grammars to do this. This makes grammar objects stateless with regard to
validation.
+ *
* Revision 1.9 2003/08/14 02:56:41 knoaman
* Code refactoring to improve performance of validation.
*
@@ -93,11 +96,14 @@
#include <xercesc/internal/XMLScanner.hpp>
#include <xercesc/internal/ElemStack.hpp>
#include <xercesc/util/KVStringPair.hpp>
+#include <xercesc/util/NameIdPool.hpp>
+#include <xercesc/util/RefHash3KeysIdPool.hpp>
#include <xercesc/validators/common/Grammar.hpp>
#include <xercesc/validators/schema/SchemaElementDecl.hpp>
XERCES_CPP_NAMESPACE_BEGIN
+class DTDElementDecl;
class DTDGrammar;
class DTDValidator;
class SchemaValidator;
@@ -316,6 +322,10 @@
// fFieldActivator
// Activates fields within a certain scope when a selector matches
// its xpath.
+ // fDTDElemNonDeclPool
+ // registry of "faulted-in" DTD element decls
+ // fSchemaElemNonDeclPool
+ // registry for elements without decls in the grammar
//
// -----------------------------------------------------------------------
bool fSeeXsi;
@@ -332,6 +342,8 @@
ValueStoreCache* fValueStoreCache;
FieldActivator* fFieldActivator;
ValueVectorOf<XMLCh*>* fLocationPairs;
+ NameIdPool<DTDElementDecl>* fDTDElemNonDeclPool;
+ RefHash3KeysIdPool<SchemaElementDecl>* fSchemaElemNonDeclPool;
};
inline const XMLCh* IGXMLScanner::getName() const
1.35 +51 -22 xml-xerces/c/src/xercesc/internal/SGXMLScanner.cpp
Index: SGXMLScanner.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/internal/SGXMLScanner.cpp,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- SGXMLScanner.cpp 27 Aug 2003 13:19:14 -0000 1.34
+++ SGXMLScanner.cpp 22 Sep 2003 19:51:41 -0000 1.35
@@ -106,6 +106,7 @@
, fMatcherStack(0)
, fValueStoreCache(0)
, fFieldActivator(0)
+ , fElemNonDeclPool(0)
{
try
{
@@ -148,6 +149,7 @@
, fMatcherStack(0)
, fValueStoreCache(0)
, fFieldActivator(0)
+ , fElemNonDeclPool(0)
{
try
{
@@ -1205,7 +1207,12 @@
, qnameRawBuf
, currentScope
);
-
+ if(!elemDecl)
+ {
+ // look in the list of undeclared elements, as would have been done
+ // before we made grammars stateless:
+ elemDecl = fElemNonDeclPool->getByKey(nameRawBuf, uriId, currentScope);
+ }
if (!elemDecl && (orgGrammarUri != uriId)) {
// not found, switch to the specified grammar
const XMLCh* uriStr = getURIText(uriId);
@@ -1240,7 +1247,12 @@
, qnameRawBuf
, Grammar::TOP_LEVEL_SCOPE
);
-
+ if(!elemDecl)
+ {
+ // look in the list of undeclared elements, as would have been done
+ // before we made grammars stateless:
+ elemDecl = fElemNonDeclPool->getByKey(nameRawBuf, uriId,
Grammar::TOP_LEVEL_SCOPE);
+ }
if(!elemDecl) {
// still not found in specified uri
// try emptyNamesapce see if element should be un-qualified.
@@ -1250,8 +1262,7 @@
, nameRawBuf
, qnameRawBuf
, currentScope
- );
-
+ );
bool errorCondition = elemDecl && elemDecl->getCreateReason() !=
XMLElementDecl::JustFaultIn;
if (errorCondition && fValidate) {
fValidator->emitError
@@ -1271,12 +1282,16 @@
// still not found, fault this in and issue error later
// switch back to original grammar first
switchGrammar(original_uriStr);
- elemDecl = fGrammar->putElemDecl(uriId
- , nameRawBuf
- , fPrefixBuf.getRawBuffer()
- , qnameRawBuf
- , currentScope
- , true);
+ elemDecl = new (fMemoryManager) SchemaElementDecl
+ (
+ fPrefixBuf.getRawBuffer()
+ , nameRawBuf
+ , uriId
+ , SchemaElementDecl::Any
+ , Grammar::TOP_LEVEL_SCOPE
+ , fMemoryManager
+ );
+ elemDecl->setId(fElemNonDeclPool->put((void*)elemDecl->getBaseName(),
uriId, currentScope, (SchemaElementDecl*)elemDecl));
wasAdded = true;
}
}
@@ -1294,7 +1309,12 @@
, qnameRawBuf
, currentScope
);
-
+ if(!elemDecl)
+ {
+ // look in the list of undeclared elements, as would have been done
+ // before we made grammars stateless:
+ elemDecl = fElemNonDeclPool->getByKey(nameRawBuf, uriId, currentScope);
+ }
if (!elemDecl && orgGrammarUri != fEmptyNamespaceId) {
//not found, switch grammar and try globalNS
bool errorCondition = !switchGrammar(XMLUni::fgZeroLenString) &&
fValidate;
@@ -1329,7 +1349,12 @@
, qnameRawBuf
, Grammar::TOP_LEVEL_SCOPE
);
-
+ if(!elemDecl)
+ {
+ // look in the list of undeclared elements, as would have been done
+ // before we made grammars stateless:
+ elemDecl = fElemNonDeclPool->getByKey(nameRawBuf, uriId,
Grammar::TOP_LEVEL_SCOPE);
+ }
if (!elemDecl && orgGrammarUri != fEmptyNamespaceId) {
// still Not found in specified uri
// go to original Grammar again to see if element needs to be fully
qualified.
@@ -1354,7 +1379,6 @@
, qnameRawBuf
, currentScope
);
-
if (elemDecl && elemDecl->getCreateReason() !=
XMLElementDecl::JustFaultIn && fValidate) {
fValidator->emitError
(
@@ -1370,14 +1394,17 @@
// still not found, fault this in and issue error later
// switch back to original grammar first
switchGrammar(original_uriStr);
- elemDecl = fGrammar->putElemDecl(uriId
- , nameRawBuf
- , fPrefixBuf.getRawBuffer()
- , qnameRawBuf
- , currentScope
- , true);
+ elemDecl = new (fMemoryManager) SchemaElementDecl
+ (
+ fPrefixBuf.getRawBuffer()
+ , nameRawBuf
+ , uriId
+ , SchemaElementDecl::Any
+ , Grammar::TOP_LEVEL_SCOPE
+ , fMemoryManager
+ );
+ elemDecl->setId(fElemNonDeclPool->put((void*)elemDecl->getBaseName(),
uriId, currentScope, (SchemaElementDecl*)elemDecl));
wasAdded = true;
-
}
}
@@ -1578,7 +1605,7 @@
, false
, isRoot
);
- }
+ } // may be where we output something...
// If empty, validate content right now if we are validating and then
// pop the element stack top. Else, we have to update the current stack
@@ -1902,6 +1929,7 @@
fEntityTable->put((void*) XMLUni::fgGT, chCloseAngle);
fEntityTable->put((void*) XMLUni::fgQuot, chDoubleQuote);
fEntityTable->put((void*) XMLUni::fgApos, chSingleQuote);
+ fElemNonDeclPool = new (fMemoryManager)
RefHash3KeysIdPool<SchemaElementDecl>(29, true, 128, fMemoryManager);
}
void SGXMLScanner::cleanUp()
@@ -1914,6 +1942,7 @@
delete fFieldActivator;
delete fMatcherStack;
delete fValueStoreCache;
+ delete fElemNonDeclPool;
}
void SGXMLScanner::resizeElemState() {
1.9 +9 -1 xml-xerces/c/src/xercesc/internal/SGXMLScanner.hpp
Index: SGXMLScanner.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/internal/SGXMLScanner.hpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- SGXMLScanner.hpp 10 Jul 2003 19:47:23 -0000 1.8
+++ SGXMLScanner.hpp 22 Sep 2003 19:51:41 -0000 1.9
@@ -56,6 +56,9 @@
/*
* $Log$
+ * Revision 1.9 2003/09/22 19:51:41 neilg
+ * scanners should maintain their own pools of undeclared elements, rather than
requiring grammars to do this. This makes grammar objects stateless with regard to
validation.
+ *
* Revision 1.8 2003/07/10 19:47:23 peiyongz
* Stateless Grammar: Initialize scanner with grammarResolver,
* creating grammar through grammarPool
@@ -91,13 +94,14 @@
#include <xercesc/internal/ElemStack.hpp>
#include <xercesc/util/KVStringPair.hpp>
#include <xercesc/util/ValueHashTableOf.hpp>
+#include <xercesc/util/RefHash3KeysIdPool.hpp>
#include <xercesc/validators/common/Grammar.hpp>
#include <xercesc/validators/schema/SchemaElementDecl.hpp>
XERCES_CPP_NAMESPACE_BEGIN
-class SchemaValidator;
class SchemaGrammar;
+class SchemaValidator;
class ValueStoreCache;
class XPathMatcherStack;
class FieldActivator;
@@ -306,6 +310,8 @@
// fFieldActivator
// Activates fields within a certain scope when a selector matches
// its xpath.
+ // fElemNonDeclPool
+ // registry for elements without decls in the grammar
//
// -----------------------------------------------------------------------
bool fSeeXsi;
@@ -321,6 +327,7 @@
XPathMatcherStack* fMatcherStack;
ValueStoreCache* fValueStoreCache;
FieldActivator* fFieldActivator;
+ RefHash3KeysIdPool<SchemaElementDecl>* fElemNonDeclPool;
};
inline const XMLCh* SGXMLScanner::getName() const
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]