diff --git a/src/xercesc/validators/common/ContentSpecNode.cpp b/src/xercesc/validators/common/ContentSpecNode.cpp index 3da2c08b3d728c21d28877450231b0ee80297abe..b7fb41ba3b2a1d010d5131eaf5e89fb7d784a0d4 100644 --- a/src/xercesc/validators/common/ContentSpecNode.cpp +++ b/src/xercesc/validators/common/ContentSpecNode.cpp @@ -69,6 +69,7 @@ #include <xercesc/framework/XMLBuffer.hpp> #include <xercesc/validators/common/ContentSpecNode.hpp> #include <xercesc/validators/DTD/DTDValidator.hpp> +#include <xercesc/validators/schema/SchemaSymbols.hpp> // --------------------------------------------------------------------------- // ContentSpecNode: Copy Constructor @@ -228,3 +229,75 @@ void ContentSpecNode::formatSpec(XMLBuffer& bufToFill) const if (fType == ContentSpecNode::Leaf) bufToFill.append(chCloseParen); } + +int ContentSpecNode::getMinTotalRange() const { + + int min = fMinOccurs; + + if (fType == ContentSpecNode::Sequence + || fType == ContentSpecNode::All + || fType == ContentSpecNode::Choice) { + + int minFirst = fFirst->getMinTotalRange(); + + if (fSecond) { + + int minSecond = fSecond->getMinTotalRange(); + + if (fType == ContentSpecNode::Choice) { + min = min * ((minFirst < minSecond)? minFirst : minSecond); + } + else { + min = min * (minFirst + minSecond); + } + } + else + min = min * minFirst; + } + + return min; +} + +int ContentSpecNode::getMaxTotalRange() const { + + int max = fMaxOccurs; + + if (max == SchemaSymbols::UNBOUNDED) { + return SchemaSymbols::UNBOUNDED; + } + + if (fType == ContentSpecNode::Sequence + || fType == ContentSpecNode::All + || fType == ContentSpecNode::Choice) { + + int maxFirst = fFirst->getMaxTotalRange(); + + if (maxFirst == SchemaSymbols::UNBOUNDED) { + return SchemaSymbols::UNBOUNDED; + } + + if (fSecond) { + + int maxSecond = fSecond->getMaxTotalRange(); + + if (maxSecond == SchemaSymbols::UNBOUNDED) { + return SchemaSymbols::UNBOUNDED; + } + else { + + if (fType == ContentSpecNode::Choice) { + max = max * (maxFirst > maxSecond) ? maxFirst : maxSecond; + } + else { + max = max * (maxFirst + maxSecond); + } + } + } + else { + max = max * maxFirst; + } + } + + return max; +} + diff --git a/src/xercesc/validators/common/ContentSpecNode.hpp b/src/xercesc/validators/common/ContentSpecNode.hpp index e09d938ee1bbcfb1bc832e6e38894f4cfdd9e6cd..52a0e1353eac609f61b59db1af086f694e56abfc 100644 --- a/src/xercesc/validators/common/ContentSpecNode.hpp +++ b/src/xercesc/validators/common/ContentSpecNode.hpp @@ -56,8 +56,11 @@ /* * $Log$ - * Revision 1.1 2002/02/01 22:22:38 peiyongz - * Initial revision + * Revision 1.2 2002/03/21 15:41:48 knoaman + * Move behavior from TraverseSchema. + * + * Revision 1.1.1.1 2002/02/01 22:22:38 peiyongz + * sane_include * * Revision 1.19 2001/12/06 17:50:42 tng * Performance Enhancement. The ContentSpecNode constructor always copied the QName @@ -234,6 +237,9 @@ public : // Miscellaneous // ----------------------------------------------------------------------- void formatSpec (XMLBuffer& bufToFill) const; + bool hasAllContent(); + int getMinTotalRange() const; + int getMaxTotalRange() const; private : @@ -501,4 +507,16 @@ inline void ContentSpecNode::setAdoptSecond(bool newState) fAdoptSecond = newState; } +// --------------------------------------------------------------------------- +// ContentSpecNode: Miscellaneous +// --------------------------------------------------------------------------- +inline bool ContentSpecNode::hasAllContent() { + + if (fType == ContentSpecNode::ZeroOrOne) { + return (fFirst->getType() == ContentSpecNode::All); + } + + return (fType == ContentSpecNode::All); +} + #endif