Added Xerces-C++ 3.1.2
This commit is contained in:
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: AllContentModel.cpp 676911 2008-07-15 13:27:32Z amassari $
|
||||
*/
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Includes
|
||||
// ---------------------------------------------------------------------------
|
||||
#include <xercesc/util/Janitor.hpp>
|
||||
#include <xercesc/util/RuntimeException.hpp>
|
||||
#include <xercesc/framework/XMLElementDecl.hpp>
|
||||
#include <xercesc/framework/XMLValidator.hpp>
|
||||
#include <xercesc/validators/common/ContentSpecNode.hpp>
|
||||
#include <xercesc/validators/common/AllContentModel.hpp>
|
||||
#include <xercesc/validators/schema/SubstitutionGroupComparator.hpp>
|
||||
#include <xercesc/validators/schema/XercesElementWildcard.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// AllContentModel: Constructors and Destructor
|
||||
// ---------------------------------------------------------------------------
|
||||
AllContentModel::AllContentModel( ContentSpecNode* const parentContentSpec
|
||||
, const bool isMixed
|
||||
, MemoryManager* const manager) :
|
||||
fMemoryManager(manager)
|
||||
, fCount(0)
|
||||
, fChildren(0)
|
||||
, fChildOptional(0)
|
||||
, fNumRequired(0)
|
||||
, fIsMixed(isMixed)
|
||||
, fHasOptionalContent(false)
|
||||
{
|
||||
//
|
||||
// Create a vector of unsigned ints that will be filled in with the
|
||||
// ids of the child nodes. It will be expanded as needed but we give
|
||||
// it an initial capacity of 64 which should be more than enough for
|
||||
// 99% of the scenarios.
|
||||
//
|
||||
|
||||
ValueVectorOf<QName*> children(64, fMemoryManager);
|
||||
ValueVectorOf<bool> childOptional(64, fMemoryManager);
|
||||
|
||||
//
|
||||
// Get the parent element's content spec. This is the head of the tree
|
||||
// of nodes that describes the content model. We will iterate this
|
||||
// tree.
|
||||
//
|
||||
ContentSpecNode* curNode = parentContentSpec;
|
||||
if (!curNode)
|
||||
ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_NoParentCSN, fMemoryManager);
|
||||
|
||||
// And now call the private recursive method that iterates the tree
|
||||
if (curNode->getType() == ContentSpecNode::All
|
||||
&& curNode->getMinOccurs() == 0) {
|
||||
fHasOptionalContent = true;
|
||||
}
|
||||
buildChildList(curNode, children, childOptional);
|
||||
|
||||
//
|
||||
// And now we know how many elements we need in our member list. So
|
||||
// fill them in.
|
||||
//
|
||||
fCount = children.size();
|
||||
fChildren = (QName**) fMemoryManager->allocate(fCount * sizeof(QName*)); //new QName*[fCount];
|
||||
fChildOptional = (bool*) fMemoryManager->allocate(fCount * sizeof(bool)); //new bool[fCount];
|
||||
for (unsigned int index = 0; index < fCount; index++) {
|
||||
fChildren[index] = new (fMemoryManager) QName(*(children.elementAt(index)));
|
||||
fChildOptional[index] = childOptional.elementAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
AllContentModel::~AllContentModel()
|
||||
{
|
||||
for (XMLSize_t index = 0; index < fCount; index++)
|
||||
delete fChildren[index];
|
||||
fMemoryManager->deallocate(fChildren); //delete [] fChildren;
|
||||
fMemoryManager->deallocate(fChildOptional); //delete [] fChildOptional;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// AllContentModel: Implementation of the ContentModel virtual interface
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
//Under the XML Schema mixed model,
|
||||
//the order and number of child elements appearing in an instance
|
||||
//must agree with
|
||||
//the order and number of child elements specified in the model.
|
||||
//
|
||||
bool
|
||||
AllContentModel::validateContent( QName** const children
|
||||
, XMLSize_t childCount
|
||||
, unsigned int
|
||||
, XMLSize_t* indexFailingChild
|
||||
, MemoryManager* const manager) const
|
||||
{
|
||||
// If <all> had minOccurs of zero and there are
|
||||
// no children to validate, trivially validate
|
||||
if (childCount == 0 && (fHasOptionalContent || !fNumRequired))
|
||||
return true;
|
||||
|
||||
// keep track of the required element seen
|
||||
XMLSize_t numRequiredSeen = 0;
|
||||
|
||||
if(childCount > 0)
|
||||
{
|
||||
// Check for duplicate element
|
||||
bool* elementSeen = (bool*) manager->allocate(fCount*sizeof(bool)); //new bool[fCount];
|
||||
|
||||
const ArrayJanitor<bool> jan(elementSeen, manager);
|
||||
|
||||
// initialize the array
|
||||
for (XMLSize_t i = 0; i < fCount; i++)
|
||||
elementSeen[i] = false;
|
||||
|
||||
for (XMLSize_t outIndex = 0; outIndex < childCount; outIndex++) {
|
||||
// Get the current child out of the source index
|
||||
const QName* curChild = children[outIndex];
|
||||
|
||||
// If it's PCDATA, then we just accept that
|
||||
if (fIsMixed && curChild->getURI() == XMLElementDecl::fgPCDataElemId)
|
||||
continue;
|
||||
|
||||
// And try to find it in our list
|
||||
XMLSize_t inIndex = 0;
|
||||
for (; inIndex < fCount; inIndex++)
|
||||
{
|
||||
const QName* inChild = fChildren[inIndex];
|
||||
if ((inChild->getURI() == curChild->getURI()) &&
|
||||
(XMLString::equals(inChild->getLocalPart(), curChild->getLocalPart()))) {
|
||||
// found it
|
||||
// If this element was seen already, indicate an error was
|
||||
// found at the duplicate index.
|
||||
if (elementSeen[inIndex]) {
|
||||
*indexFailingChild=outIndex;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
elementSeen[inIndex] = true;
|
||||
|
||||
if (!fChildOptional[inIndex])
|
||||
numRequiredSeen++;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We did not find this one, so the validation failed
|
||||
if (inIndex == fCount) {
|
||||
*indexFailingChild=outIndex;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Were all the required elements of the <all> encountered?
|
||||
if (numRequiredSeen != fNumRequired) {
|
||||
*indexFailingChild=childCount;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Everything seems to be ok, so return success
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AllContentModel::validateContentSpecial(QName** const children
|
||||
, XMLSize_t childCount
|
||||
, unsigned int
|
||||
, GrammarResolver* const pGrammarResolver
|
||||
, XMLStringPool* const pStringPool
|
||||
, XMLSize_t* indexFailingChild
|
||||
, MemoryManager* const manager) const
|
||||
{
|
||||
// If <all> had minOccurs of zero and there are
|
||||
// no children to validate, trivially validate
|
||||
if (childCount == 0 && (fHasOptionalContent || !fNumRequired))
|
||||
return true;
|
||||
|
||||
// keep track of the required element seen
|
||||
XMLSize_t numRequiredSeen = 0;
|
||||
|
||||
if(childCount > 0)
|
||||
{
|
||||
SubstitutionGroupComparator comparator(pGrammarResolver, pStringPool);
|
||||
|
||||
// Check for duplicate element
|
||||
bool* elementSeen = (bool*) manager->allocate(fCount*sizeof(bool)); //new bool[fCount];
|
||||
|
||||
const ArrayJanitor<bool> jan(elementSeen, manager);
|
||||
|
||||
// initialize the array
|
||||
for (XMLSize_t i = 0; i < fCount; i++)
|
||||
elementSeen[i] = false;
|
||||
|
||||
for (XMLSize_t outIndex = 0; outIndex < childCount; outIndex++) {
|
||||
// Get the current child out of the source index
|
||||
QName* const curChild = children[outIndex];
|
||||
|
||||
// If it's PCDATA, then we just accept that
|
||||
if (fIsMixed && curChild->getURI() == XMLElementDecl::fgPCDataElemId)
|
||||
continue;
|
||||
|
||||
// And try to find it in our list
|
||||
XMLSize_t inIndex = 0;
|
||||
for (; inIndex < fCount; inIndex++)
|
||||
{
|
||||
QName* const inChild = fChildren[inIndex];
|
||||
if ( comparator.isEquivalentTo(curChild, inChild)) {
|
||||
// match
|
||||
// If this element was seen already, indicate an error was
|
||||
// found at the duplicate index.
|
||||
if (elementSeen[inIndex]) {
|
||||
*indexFailingChild=outIndex;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
elementSeen[inIndex] = true;
|
||||
|
||||
if (!fChildOptional[inIndex])
|
||||
numRequiredSeen++;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We did not find this one, so the validation failed
|
||||
if (inIndex == fCount) {
|
||||
*indexFailingChild=outIndex;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Were all the required elements of the <all> encountered?
|
||||
if (numRequiredSeen != fNumRequired) {
|
||||
*indexFailingChild=childCount;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Everything seems to be ok, so return success
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void AllContentModel::checkUniqueParticleAttribution
|
||||
(
|
||||
SchemaGrammar* const pGrammar
|
||||
, GrammarResolver* const pGrammarResolver
|
||||
, XMLStringPool* const pStringPool
|
||||
, XMLValidator* const pValidator
|
||||
, unsigned int* const pContentSpecOrgURI
|
||||
, const XMLCh* pComplexTypeName /*= 0*/
|
||||
)
|
||||
{
|
||||
SubstitutionGroupComparator comparator(pGrammarResolver, pStringPool);
|
||||
|
||||
XMLSize_t i, j;
|
||||
|
||||
// rename back
|
||||
for (i = 0; i < fCount; i++) {
|
||||
unsigned int orgURIIndex = fChildren[i]->getURI();
|
||||
fChildren[i]->setURI(pContentSpecOrgURI[orgURIIndex]);
|
||||
}
|
||||
|
||||
// check whether there is conflict between any two leaves
|
||||
for (i = 0; i < fCount; i++) {
|
||||
for (j = i+1; j < fCount; j++) {
|
||||
// If this is text in a Schema mixed content model, skip it.
|
||||
if ( fIsMixed &&
|
||||
(( fChildren[i]->getURI() == XMLElementDecl::fgPCDataElemId) ||
|
||||
( fChildren[j]->getURI() == XMLElementDecl::fgPCDataElemId)))
|
||||
continue;
|
||||
|
||||
if (XercesElementWildcard::conflict(pGrammar,
|
||||
ContentSpecNode::Leaf,
|
||||
fChildren[i],
|
||||
ContentSpecNode::Leaf,
|
||||
fChildren[j],
|
||||
&comparator)) {
|
||||
pValidator->emitError(XMLValid::UniqueParticleAttributionFail,
|
||||
pComplexTypeName,
|
||||
fChildren[i]->getRawName(),
|
||||
fChildren[j]->getRawName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// AllContentModel: Private helper methods
|
||||
// ---------------------------------------------------------------------------
|
||||
void
|
||||
AllContentModel::buildChildList(ContentSpecNode* const curNode
|
||||
, ValueVectorOf<QName*>& toFill
|
||||
, ValueVectorOf<bool>& toOptional)
|
||||
{
|
||||
// Get the type of spec node our current node is
|
||||
const ContentSpecNode::NodeTypes curType = curNode->getType();
|
||||
|
||||
if (curType == ContentSpecNode::All)
|
||||
{
|
||||
// Get both the child node pointers
|
||||
ContentSpecNode* leftNode = curNode->getFirst();
|
||||
ContentSpecNode* rightNode = curNode->getSecond();
|
||||
|
||||
// Recurse on the left and right nodes
|
||||
buildChildList(leftNode, toFill, toOptional);
|
||||
if(rightNode)
|
||||
buildChildList(rightNode, toFill, toOptional);
|
||||
}
|
||||
else if (curType == ContentSpecNode::Leaf)
|
||||
{
|
||||
// At leaf, add the element to list of elements permitted in the all
|
||||
toFill.addElement(curNode->getElement());
|
||||
toOptional.addElement(false);
|
||||
fNumRequired++;
|
||||
}
|
||||
else if (curType == ContentSpecNode::ZeroOrOne)
|
||||
{
|
||||
// At ZERO_OR_ONE node, subtree must be an element
|
||||
// that was specified with minOccurs=0, maxOccurs=1
|
||||
ContentSpecNode* leftNode = curNode->getFirst();
|
||||
if (leftNode->getType() != ContentSpecNode::Leaf)
|
||||
ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
|
||||
|
||||
toFill.addElement(leftNode->getElement());
|
||||
toOptional.addElement(true);
|
||||
}
|
||||
// only allow ZeroOrMore when it's the father of a Loop
|
||||
else if (curType == ContentSpecNode::ZeroOrMore &&
|
||||
curNode->getFirst()!=0 &&
|
||||
curNode->getFirst()->getType()==ContentSpecNode::Loop)
|
||||
{
|
||||
ContentSpecNode* leftNode = curNode->getFirst();
|
||||
buildChildList(leftNode, toFill, toOptional);
|
||||
}
|
||||
else if (curType == ContentSpecNode::Loop)
|
||||
{
|
||||
// At leaf, add the element to list of elements permitted in the all
|
||||
int i;
|
||||
for(i=0;i<curNode->getMinOccurs();i++)
|
||||
{
|
||||
toFill.addElement(curNode->getElement());
|
||||
toOptional.addElement(false);
|
||||
fNumRequired++;
|
||||
}
|
||||
if(curNode->getMaxOccurs()!=-1)
|
||||
for(i=0;i<(curNode->getMaxOccurs() - curNode->getMinOccurs());i++)
|
||||
{
|
||||
toFill.addElement(curNode->getElement());
|
||||
toOptional.addElement(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: AllContentModel.hpp 901107 2010-01-20 08:45:02Z borisk $
|
||||
*/
|
||||
|
||||
#if !defined(XERCESC_INCLUDE_GUARD_ALLCONTENTMODEL_HPP)
|
||||
#define XERCESC_INCLUDE_GUARD_ALLCONTENTMODEL_HPP
|
||||
|
||||
#include <xercesc/framework/XMLContentModel.hpp>
|
||||
#include <xercesc/util/ValueVectorOf.hpp>
|
||||
#include <xercesc/validators/common/ContentLeafNameTypeVector.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
class ContentSpecNode;
|
||||
|
||||
//
|
||||
// AllContentModel is a derivative of the abstract content model base
|
||||
// class that handles the special case of <all> feature in schema. If a model
|
||||
// is <all>, all non-optional children must appear
|
||||
//
|
||||
// So, all we have to do is to keep an array of the possible children and
|
||||
// validate by just looking up each child being validated by looking it up
|
||||
// in the list, and make sure all non-optional children appear.
|
||||
//
|
||||
class AllContentModel : public XMLContentModel
|
||||
{
|
||||
public :
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors and Destructor
|
||||
// -----------------------------------------------------------------------
|
||||
AllContentModel
|
||||
(
|
||||
ContentSpecNode* const parentContentSpec
|
||||
, const bool isMixed
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
|
||||
~AllContentModel();
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Implementation of the ContentModel virtual interface
|
||||
// -----------------------------------------------------------------------
|
||||
virtual bool validateContent
|
||||
(
|
||||
QName** const children
|
||||
, XMLSize_t childCount
|
||||
, unsigned int emptyNamespaceId
|
||||
, XMLSize_t* indexFailingChild
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
) const;
|
||||
|
||||
virtual bool validateContentSpecial
|
||||
(
|
||||
QName** const children
|
||||
, XMLSize_t childCount
|
||||
, unsigned int emptyNamespaceId
|
||||
, GrammarResolver* const pGrammarResolver
|
||||
, XMLStringPool* const pStringPool
|
||||
, XMLSize_t* indexFailingChild
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
) const;
|
||||
|
||||
virtual ContentLeafNameTypeVector* getContentLeafNameTypeVector() const ;
|
||||
|
||||
virtual unsigned int getNextState(unsigned int currentState,
|
||||
XMLSize_t elementIndex) const;
|
||||
|
||||
virtual bool handleRepetitions( const QName* const curElem,
|
||||
unsigned int curState,
|
||||
unsigned int currentLoop,
|
||||
unsigned int& nextState,
|
||||
unsigned int& nextLoop,
|
||||
XMLSize_t elementIndex,
|
||||
SubstitutionGroupComparator * comparator) const;
|
||||
|
||||
virtual void checkUniqueParticleAttribution
|
||||
(
|
||||
SchemaGrammar* const pGrammar
|
||||
, GrammarResolver* const pGrammarResolver
|
||||
, XMLStringPool* const pStringPool
|
||||
, XMLValidator* const pValidator
|
||||
, unsigned int* const pContentSpecOrgURI
|
||||
, const XMLCh* pComplexTypeName = 0
|
||||
) ;
|
||||
|
||||
private :
|
||||
// -----------------------------------------------------------------------
|
||||
// Private helper methods
|
||||
// -----------------------------------------------------------------------
|
||||
void buildChildList
|
||||
(
|
||||
ContentSpecNode* const curNode
|
||||
, ValueVectorOf<QName*>& toFill
|
||||
, ValueVectorOf<bool>& toType
|
||||
);
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
AllContentModel();
|
||||
AllContentModel(const AllContentModel&);
|
||||
AllContentModel& operator=(const AllContentModel&);
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Private data members
|
||||
//
|
||||
// fCount
|
||||
// The count of possible children in the fChildren member.
|
||||
//
|
||||
// fChildren
|
||||
// The list of possible children that we have to accept. This array
|
||||
// is allocated as large as needed in the constructor.
|
||||
//
|
||||
// fChildOptional
|
||||
// The corresponding list of optional state of each child in fChildren
|
||||
// True if the child is optional (i.e. minOccurs = 0).
|
||||
//
|
||||
// fNumRequired
|
||||
// The number of required children in <all> (i.e. minOccurs = 1)
|
||||
//
|
||||
// fIsMixed
|
||||
// AllContentModel with mixed PCDATA.
|
||||
// -----------------------------------------------------------------------
|
||||
MemoryManager* fMemoryManager;
|
||||
XMLSize_t fCount;
|
||||
QName** fChildren;
|
||||
bool* fChildOptional;
|
||||
unsigned int fNumRequired;
|
||||
bool fIsMixed;
|
||||
bool fHasOptionalContent;
|
||||
};
|
||||
|
||||
inline ContentLeafNameTypeVector* AllContentModel::getContentLeafNameTypeVector() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline unsigned int
|
||||
AllContentModel::getNextState(unsigned int,
|
||||
XMLSize_t) const {
|
||||
|
||||
return XMLContentModel::gInvalidTrans;
|
||||
}
|
||||
|
||||
inline bool
|
||||
AllContentModel::handleRepetitions( const QName* const /*curElem*/,
|
||||
unsigned int /*curState*/,
|
||||
unsigned int /*currentLoop*/,
|
||||
unsigned int& /*nextState*/,
|
||||
unsigned int& /*nextLoop*/,
|
||||
XMLSize_t /*elementIndex*/,
|
||||
SubstitutionGroupComparator * /*comparator*/) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: CMAny.cpp 677396 2008-07-16 19:36:20Z amassari $
|
||||
*/
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Includes
|
||||
// ---------------------------------------------------------------------------
|
||||
#include <xercesc/util/XercesDefs.hpp>
|
||||
#include <xercesc/util/RuntimeException.hpp>
|
||||
#include <xercesc/validators/common/CMStateSet.hpp>
|
||||
#include <xercesc/validators/common/CMAny.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CMUnaryOp: Constructors and Destructor
|
||||
// ---------------------------------------------------------------------------
|
||||
CMAny::CMAny( ContentSpecNode::NodeTypes type
|
||||
, unsigned int URI
|
||||
, unsigned int position
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager) :
|
||||
CMNode(type, maxStates, manager)
|
||||
, fURI(URI)
|
||||
, fPosition(position)
|
||||
{
|
||||
if ((type & 0x0f) != ContentSpecNode::Any
|
||||
&& (type & 0x0f) != ContentSpecNode::Any_Other
|
||||
&& (type & 0x0f) != ContentSpecNode::Any_NS)
|
||||
{
|
||||
ThrowXMLwithMemMgr1(RuntimeException, XMLExcepts::CM_NotValidSpecTypeForNode,
|
||||
"CMAny", manager);
|
||||
}
|
||||
// Leaf nodes are never nullable unless its an epsilon node
|
||||
fIsNullable=(fPosition == epsilonNode);
|
||||
}
|
||||
|
||||
CMAny::~CMAny()
|
||||
{
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Getter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
unsigned int CMAny::getURI() const
|
||||
{
|
||||
return fURI;
|
||||
}
|
||||
|
||||
unsigned int CMAny::getPosition() const
|
||||
{
|
||||
return fPosition;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Setter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
void CMAny::setPosition(const unsigned int newPosition)
|
||||
{
|
||||
fPosition = newPosition;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Implementation of public CMNode virtual interface
|
||||
// ---------------------------------------------------------------------------
|
||||
void CMAny::orphanChild()
|
||||
{
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Implementation of protected CMNode virtual interface
|
||||
// ---------------------------------------------------------------------------
|
||||
void CMAny::calcFirstPos(CMStateSet& toSet) const
|
||||
{
|
||||
// If we are an epsilon node, then the first pos is an empty set
|
||||
if (isNullable())
|
||||
toSet.zeroBits();
|
||||
else
|
||||
// Otherwise, its just the one bit of our position
|
||||
toSet.setBit(fPosition);
|
||||
}
|
||||
|
||||
void CMAny::calcLastPos(CMStateSet& toSet) const
|
||||
{
|
||||
// If we are an epsilon node, then the last pos is an empty set
|
||||
if (isNullable())
|
||||
toSet.zeroBits();
|
||||
// Otherwise, its just the one bit of our position
|
||||
else
|
||||
toSet.setBit(fPosition);
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: CMAny.hpp 677396 2008-07-16 19:36:20Z amassari $
|
||||
*/
|
||||
|
||||
#if !defined(XERCESC_INCLUDE_GUARD_CMANY_HPP)
|
||||
#define XERCESC_INCLUDE_GUARD_CMANY_HPP
|
||||
|
||||
#include <xercesc/validators/common/CMNode.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
class CMStateSet;
|
||||
|
||||
class CMAny : public CMNode
|
||||
{
|
||||
public :
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors
|
||||
// -----------------------------------------------------------------------
|
||||
CMAny
|
||||
(
|
||||
ContentSpecNode::NodeTypes type
|
||||
, unsigned int URI
|
||||
, unsigned int position
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
~CMAny();
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Getter methods
|
||||
// -----------------------------------------------------------------------
|
||||
unsigned int getURI() const;
|
||||
|
||||
unsigned int getPosition() const;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Setter methods
|
||||
// -----------------------------------------------------------------------
|
||||
void setPosition(const unsigned int newPosition);
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Implementation of the public CMNode virtual interface
|
||||
// -----------------------------------------------------------------------
|
||||
virtual void orphanChild();
|
||||
|
||||
|
||||
protected :
|
||||
// -----------------------------------------------------------------------
|
||||
// Implementation of the protected CMNode virtual interface
|
||||
// -----------------------------------------------------------------------
|
||||
void calcFirstPos(CMStateSet& toSet) const;
|
||||
void calcLastPos(CMStateSet& toSet) const;
|
||||
|
||||
private :
|
||||
// -----------------------------------------------------------------------
|
||||
// Private data members
|
||||
//
|
||||
// fURI;
|
||||
// URI of the any content model. This value is set if the type is
|
||||
// of the following:
|
||||
// XMLContentSpec.CONTENTSPECNODE_ANY,
|
||||
// XMLContentSpec.CONTENTSPECNODE_ANY_OTHER.
|
||||
//
|
||||
// fPosition
|
||||
// Part of the algorithm to convert a regex directly to a DFA
|
||||
// numbers each leaf sequentially. If its -1, that means its an
|
||||
// epsilon node. Zero and greater are non-epsilon positions.
|
||||
// -----------------------------------------------------------------------
|
||||
unsigned int fURI;
|
||||
unsigned int fPosition;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
CMAny(const CMAny&);
|
||||
CMAny& operator=(const CMAny&);
|
||||
};
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: CMBinaryOp.cpp 677396 2008-07-16 19:36:20Z amassari $
|
||||
*/
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Includes
|
||||
// ---------------------------------------------------------------------------
|
||||
#include <xercesc/util/XercesDefs.hpp>
|
||||
#include <xercesc/util/RuntimeException.hpp>
|
||||
#include <xercesc/validators/common/ContentSpecNode.hpp>
|
||||
#include <xercesc/validators/common/CMBinaryOp.hpp>
|
||||
#include <xercesc/validators/common/CMStateSet.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CMBinaryOp: Constructors
|
||||
// ---------------------------------------------------------------------------
|
||||
CMBinaryOp::CMBinaryOp( ContentSpecNode::NodeTypes type
|
||||
, CMNode* const leftToAdopt
|
||||
, CMNode* const rightToAdopt
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager) :
|
||||
CMNode(type, maxStates, manager)
|
||||
, fLeftChild(leftToAdopt)
|
||||
, fRightChild(rightToAdopt)
|
||||
{
|
||||
// Insure that its one of the types we require
|
||||
if (((type & 0x0f) != ContentSpecNode::Choice)
|
||||
&& ((type & 0x0f) != ContentSpecNode::Sequence))
|
||||
{
|
||||
ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_BinOpHadUnaryType, manager);
|
||||
}
|
||||
//
|
||||
// If its an alternation, then if either child is nullable then
|
||||
// this node is nullable. If its a concatenation, then both of
|
||||
// them have to be nullable.
|
||||
//
|
||||
if ((type & 0x0f) == ContentSpecNode::Choice)
|
||||
fIsNullable=(fLeftChild->isNullable() || fRightChild->isNullable());
|
||||
else
|
||||
fIsNullable=(fLeftChild->isNullable() && fRightChild->isNullable());
|
||||
}
|
||||
|
||||
CMBinaryOp::~CMBinaryOp()
|
||||
{
|
||||
delete fLeftChild;
|
||||
delete fRightChild;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CMBinaryOp: Getter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
const CMNode* CMBinaryOp::getLeft() const
|
||||
{
|
||||
return fLeftChild;
|
||||
}
|
||||
|
||||
CMNode* CMBinaryOp::getLeft()
|
||||
{
|
||||
return fLeftChild;
|
||||
}
|
||||
|
||||
const CMNode* CMBinaryOp::getRight() const
|
||||
{
|
||||
return fRightChild;
|
||||
}
|
||||
|
||||
CMNode* CMBinaryOp::getRight()
|
||||
{
|
||||
return fRightChild;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CMBinaryOp: Implementation of the public CMNode virtual interface
|
||||
// ---------------------------------------------------------------------------
|
||||
void CMBinaryOp::orphanChild()
|
||||
{
|
||||
delete fLeftChild;
|
||||
fLeftChild=0;
|
||||
delete fRightChild;
|
||||
fRightChild=0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CMBinaryOp: Implementation of the protected CMNode virtual interface
|
||||
// ---------------------------------------------------------------------------
|
||||
void CMBinaryOp::calcFirstPos(CMStateSet& toSet) const
|
||||
{
|
||||
if ((getType() & 0x0f) == ContentSpecNode::Choice)
|
||||
{
|
||||
// Its the the union of the first positions of our children.
|
||||
toSet = fLeftChild->getFirstPos();
|
||||
toSet |= fRightChild->getFirstPos();
|
||||
}
|
||||
else if ((getType() & 0x0f) == ContentSpecNode::Sequence)
|
||||
{
|
||||
//
|
||||
// If our left child is nullable, then its the union of our
|
||||
// children's first positions. Else is our left child's first
|
||||
// positions.
|
||||
//
|
||||
toSet = fLeftChild->getFirstPos();
|
||||
if (fLeftChild->isNullable())
|
||||
toSet |= fRightChild->getFirstPos();
|
||||
}
|
||||
}
|
||||
|
||||
void CMBinaryOp::calcLastPos(CMStateSet& toSet) const
|
||||
{
|
||||
if ((getType() & 0x0f) == ContentSpecNode::Choice)
|
||||
{
|
||||
// Its the the union of the first positions of our children.
|
||||
toSet = fLeftChild->getLastPos();
|
||||
toSet |= fRightChild->getLastPos();
|
||||
}
|
||||
else if ((getType() & 0x0f) == ContentSpecNode::Sequence)
|
||||
{
|
||||
//
|
||||
// If our right child is nullable, then its the union of our
|
||||
// children's last positions. Else is our right child's last
|
||||
// positions.
|
||||
//
|
||||
toSet = fRightChild->getLastPos();
|
||||
if (fRightChild->isNullable())
|
||||
toSet |= fLeftChild->getLastPos();
|
||||
}
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: CMBinaryOp.hpp 677396 2008-07-16 19:36:20Z amassari $
|
||||
*/
|
||||
|
||||
#if !defined(XERCESC_INCLUDE_GUARD_CMBINARYOP_HPP)
|
||||
#define XERCESC_INCLUDE_GUARD_CMBINARYOP_HPP
|
||||
|
||||
#include <xercesc/validators/common/CMNode.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
class CMStateSet;
|
||||
|
||||
class CMBinaryOp : public CMNode
|
||||
{
|
||||
public :
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors
|
||||
// -----------------------------------------------------------------------
|
||||
CMBinaryOp
|
||||
(
|
||||
ContentSpecNode::NodeTypes type
|
||||
, CMNode* const leftToAdopt
|
||||
, CMNode* const rightToAdopt
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
~CMBinaryOp();
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Getter methods
|
||||
// -----------------------------------------------------------------------
|
||||
const CMNode* getLeft() const;
|
||||
CMNode* getLeft();
|
||||
const CMNode* getRight() const;
|
||||
CMNode* getRight();
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Implementation of the public CMNode virtual interface
|
||||
// -----------------------------------------------------------------------
|
||||
virtual void orphanChild();
|
||||
|
||||
|
||||
protected :
|
||||
// -----------------------------------------------------------------------
|
||||
// Implementation of the protected CMNode virtual interface
|
||||
// -----------------------------------------------------------------------
|
||||
void calcFirstPos(CMStateSet& toSet) const;
|
||||
void calcLastPos(CMStateSet& toSet) const;
|
||||
|
||||
|
||||
private :
|
||||
// -----------------------------------------------------------------------
|
||||
// Private data members
|
||||
//
|
||||
// fLeftChild
|
||||
// fRightChild
|
||||
// These are the references to the two nodes that are on either side
|
||||
// of this binary operation. We own them both.
|
||||
// -----------------------------------------------------------------------
|
||||
CMNode* fLeftChild;
|
||||
CMNode* fRightChild;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
CMBinaryOp(const CMBinaryOp&);
|
||||
CMBinaryOp& operator=(const CMBinaryOp&);
|
||||
};
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: CMLeaf.hpp 677396 2008-07-16 19:36:20Z amassari $
|
||||
*/
|
||||
|
||||
#if !defined(XERCESC_INCLUDE_GUARD_CMLEAF_HPP)
|
||||
#define XERCESC_INCLUDE_GUARD_CMLEAF_HPP
|
||||
|
||||
#include <xercesc/validators/common/CMNode.hpp>
|
||||
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
//
|
||||
// This class represents a leaf in the content spec node tree of an
|
||||
// element's content model. It just has an element qname and a position value,
|
||||
// the latter of which is used during the building of a DFA.
|
||||
//
|
||||
class CMLeaf : public CMNode
|
||||
{
|
||||
public :
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors
|
||||
// -----------------------------------------------------------------------
|
||||
CMLeaf
|
||||
(
|
||||
QName* const element
|
||||
, unsigned int position
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
CMLeaf
|
||||
(
|
||||
QName* const element
|
||||
, unsigned int position
|
||||
, bool adopt
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
~CMLeaf();
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Getter methods
|
||||
// -----------------------------------------------------------------------
|
||||
QName* getElement();
|
||||
const QName* getElement() const;
|
||||
unsigned int getPosition() const;
|
||||
|
||||
virtual bool isRepeatableLeaf() const;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Setter methods
|
||||
// -----------------------------------------------------------------------
|
||||
void setPosition(const unsigned int newPosition);
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Implementation of public CMNode virtual interface
|
||||
// -----------------------------------------------------------------------
|
||||
virtual void orphanChild();
|
||||
|
||||
protected :
|
||||
// -----------------------------------------------------------------------
|
||||
// Implementation of protected CMNode virtual interface
|
||||
// -----------------------------------------------------------------------
|
||||
void calcFirstPos(CMStateSet& toSet) const;
|
||||
void calcLastPos(CMStateSet& toSet) const;
|
||||
|
||||
|
||||
private :
|
||||
// -----------------------------------------------------------------------
|
||||
// Private data members
|
||||
//
|
||||
// fElement
|
||||
// This is the element that this leaf represents.
|
||||
//
|
||||
// fPosition
|
||||
// Part of the algorithm to convert a regex directly to a DFA
|
||||
// numbers each leaf sequentially. If its -1, that means its an
|
||||
// epsilon node. All others are non-epsilon positions.
|
||||
//
|
||||
// fAdopt
|
||||
// This node is responsible for the storage of the fElement QName.
|
||||
// -----------------------------------------------------------------------
|
||||
QName* fElement;
|
||||
unsigned int fPosition;
|
||||
bool fAdopt;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
CMLeaf(const CMLeaf&);
|
||||
CMLeaf& operator=(const CMLeaf&);
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors
|
||||
// -----------------------------------------------------------------------
|
||||
inline CMLeaf::CMLeaf( QName* const element
|
||||
, unsigned int position
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager) :
|
||||
CMNode(ContentSpecNode::Leaf, maxStates, manager)
|
||||
, fElement(0)
|
||||
, fPosition(position)
|
||||
, fAdopt(false)
|
||||
{
|
||||
if (!element)
|
||||
{
|
||||
fElement = new (fMemoryManager) QName
|
||||
(
|
||||
XMLUni::fgZeroLenString
|
||||
, XMLUni::fgZeroLenString
|
||||
, XMLElementDecl::fgInvalidElemId
|
||||
, fMemoryManager
|
||||
);
|
||||
// We have to be responsible for this QName - override default fAdopt
|
||||
fAdopt = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fElement = element;
|
||||
}
|
||||
// Leaf nodes are never nullable unless its an epsilon node
|
||||
fIsNullable=(fPosition == epsilonNode);
|
||||
}
|
||||
|
||||
inline CMLeaf::CMLeaf( QName* const element
|
||||
, unsigned int position
|
||||
, bool adopt
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager) :
|
||||
CMNode(ContentSpecNode::Leaf, maxStates, manager)
|
||||
, fElement(0)
|
||||
, fPosition(position)
|
||||
, fAdopt(adopt)
|
||||
{
|
||||
if (!element)
|
||||
{
|
||||
fElement = new (fMemoryManager) QName
|
||||
(
|
||||
XMLUni::fgZeroLenString
|
||||
, XMLUni::fgZeroLenString
|
||||
, XMLElementDecl::fgInvalidElemId
|
||||
, fMemoryManager
|
||||
);
|
||||
// We have to be responsible for this QName - override adopt parameter
|
||||
fAdopt = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fElement = element;
|
||||
}
|
||||
// Leaf nodes are never nullable unless its an epsilon node
|
||||
fIsNullable=(fPosition == epsilonNode);
|
||||
}
|
||||
|
||||
inline CMLeaf::~CMLeaf()
|
||||
{
|
||||
if (fAdopt)
|
||||
delete fElement;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Getter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
inline QName* CMLeaf::getElement()
|
||||
{
|
||||
return fElement;
|
||||
}
|
||||
|
||||
inline const QName* CMLeaf::getElement() const
|
||||
{
|
||||
return fElement;
|
||||
}
|
||||
|
||||
inline unsigned int CMLeaf::getPosition() const
|
||||
{
|
||||
return fPosition;
|
||||
}
|
||||
|
||||
inline bool CMLeaf::isRepeatableLeaf() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Setter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
inline void CMLeaf::setPosition(const unsigned int newPosition)
|
||||
{
|
||||
fPosition = newPosition;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Implementation of public CMNode virtual interface
|
||||
// ---------------------------------------------------------------------------
|
||||
inline void CMLeaf::orphanChild()
|
||||
{
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Implementation of protected CMNode virtual interface
|
||||
// ---------------------------------------------------------------------------
|
||||
inline void CMLeaf::calcFirstPos(CMStateSet& toSet) const
|
||||
{
|
||||
// If we are an epsilon node, then the first pos is an empty set
|
||||
if (isNullable())
|
||||
{
|
||||
toSet.zeroBits();
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, its just the one bit of our position
|
||||
toSet.setBit(fPosition);
|
||||
}
|
||||
|
||||
inline void CMLeaf::calcLastPos(CMStateSet& toSet) const
|
||||
{
|
||||
// If we are an epsilon node, then the last pos is an empty set
|
||||
if (isNullable())
|
||||
{
|
||||
toSet.zeroBits();
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, its just the one bit of our position
|
||||
toSet.setBit(fPosition);
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: CMNode.hpp 677430 2008-07-16 21:05:31Z borisk $
|
||||
*/
|
||||
|
||||
#if !defined(XERCESC_INCLUDE_GUARD_CMNODE_HPP)
|
||||
#define XERCESC_INCLUDE_GUARD_CMNODE_HPP
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <xercesc/validators/common/ContentSpecNode.hpp>
|
||||
#include <xercesc/validators/common/CMStateSet.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
class CMNode : public XMemory
|
||||
{
|
||||
public :
|
||||
enum {
|
||||
// Special value to indicate a nullable node
|
||||
epsilonNode = UINT_MAX - 1
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors and Destructors
|
||||
// -----------------------------------------------------------------------
|
||||
CMNode
|
||||
(
|
||||
const ContentSpecNode::NodeTypes type
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
virtual ~CMNode();
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Virtual methods to be provided derived node classes
|
||||
// -----------------------------------------------------------------------
|
||||
virtual void orphanChild() = 0;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Getter methods
|
||||
// -----------------------------------------------------------------------
|
||||
ContentSpecNode::NodeTypes getType() const;
|
||||
const CMStateSet& getFirstPos();
|
||||
const CMStateSet& getLastPos();
|
||||
bool isNullable() const;
|
||||
|
||||
protected :
|
||||
// -----------------------------------------------------------------------
|
||||
// Protected, abstract methods
|
||||
// -----------------------------------------------------------------------
|
||||
virtual void calcFirstPos(CMStateSet& toUpdate) const = 0;
|
||||
virtual void calcLastPos(CMStateSet& toUpdate) const = 0;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Protected data members
|
||||
//
|
||||
// fMemoryManager
|
||||
// Pluggable memory manager for dynamic allocation/deallocation.
|
||||
// -----------------------------------------------------------------------
|
||||
MemoryManager* fMemoryManager;
|
||||
|
||||
|
||||
private :
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
CMNode();
|
||||
CMNode(const CMNode&);
|
||||
CMNode& operator=(const CMNode&);
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Private data members
|
||||
//
|
||||
// fType
|
||||
// The type of node. This indicates whether its a leaf or an
|
||||
// operation.
|
||||
//
|
||||
// fFirstPos
|
||||
// The set of NFA states that represent the entry states of this
|
||||
// node in the DFA.
|
||||
//
|
||||
// fLastPos
|
||||
// The set of NFA states that represent the final states of this
|
||||
// node in the DFA.
|
||||
//
|
||||
// fMaxStates
|
||||
// The maximum number of states that the NFA has, which means the
|
||||
// max number of NFA states that have to be traced in the state
|
||||
// sets during the building of the DFA. Its unfortunate that it
|
||||
// has to be stored redundantly, but we need to fault in the
|
||||
// state set members and they have to be sized to this size.
|
||||
//
|
||||
// fIsNullable
|
||||
// Whether the node can be empty
|
||||
// -----------------------------------------------------------------------
|
||||
ContentSpecNode::NodeTypes fType;
|
||||
CMStateSet* fFirstPos;
|
||||
CMStateSet* fLastPos;
|
||||
unsigned int fMaxStates;
|
||||
|
||||
protected:
|
||||
bool fIsNullable;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CMNode: Constructors and Destructors
|
||||
// ---------------------------------------------------------------------------
|
||||
inline CMNode::CMNode(const ContentSpecNode::NodeTypes type
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager) :
|
||||
|
||||
fMemoryManager(manager)
|
||||
, fType(type)
|
||||
, fFirstPos(0)
|
||||
, fLastPos(0)
|
||||
, fMaxStates(maxStates)
|
||||
, fIsNullable(false)
|
||||
{
|
||||
}
|
||||
|
||||
inline CMNode::~CMNode()
|
||||
{
|
||||
// Clean up any position sets that got created
|
||||
delete fFirstPos;
|
||||
delete fLastPos;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CMNode: Getter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
inline ContentSpecNode::NodeTypes CMNode::getType() const
|
||||
{
|
||||
return fType;
|
||||
}
|
||||
|
||||
inline const CMStateSet& CMNode::getFirstPos()
|
||||
{
|
||||
//
|
||||
// Fault in the state set if needed. Since we can't use mutable members
|
||||
// cast off the const'ness.
|
||||
//
|
||||
if (!fFirstPos)
|
||||
{
|
||||
fFirstPos = new (fMemoryManager) CMStateSet(fMaxStates, fMemoryManager);
|
||||
calcFirstPos(*fFirstPos);
|
||||
}
|
||||
return *fFirstPos;
|
||||
}
|
||||
|
||||
inline const CMStateSet& CMNode::getLastPos()
|
||||
{
|
||||
//
|
||||
// Fault in the state set if needed. Since we can't use mutable members
|
||||
// cast off the const'ness.
|
||||
//
|
||||
if (!fLastPos)
|
||||
{
|
||||
fLastPos = new (fMemoryManager) CMStateSet(fMaxStates, fMemoryManager);
|
||||
calcLastPos(*fLastPos);
|
||||
}
|
||||
return *fLastPos;
|
||||
}
|
||||
|
||||
inline bool CMNode::isNullable() const
|
||||
{
|
||||
return fIsNullable;
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: CMRepeatingLeaf.hpp 677396 2008-07-16 19:36:20Z amassari $
|
||||
*/
|
||||
|
||||
#if !defined(XERCESC_INCLUDE_GUARD_CMREPEATINGLEAF_HPP)
|
||||
#define XERCESC_INCLUDE_GUARD_CMREPEATINGLEAF_HPP
|
||||
|
||||
#include <xercesc/validators/common/CMLeaf.hpp>
|
||||
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
//
|
||||
// A compound content model leaf node which carries occurence information.
|
||||
//
|
||||
class CMRepeatingLeaf : public CMLeaf
|
||||
{
|
||||
public :
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors
|
||||
// -----------------------------------------------------------------------
|
||||
CMRepeatingLeaf
|
||||
(
|
||||
QName* const element
|
||||
, int minOccurs
|
||||
, int maxOccurs
|
||||
, unsigned int position
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
CMRepeatingLeaf
|
||||
(
|
||||
QName* const element
|
||||
, int minOccurs
|
||||
, int maxOccurs
|
||||
, unsigned int position
|
||||
, bool adopt
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Getter methods
|
||||
// -----------------------------------------------------------------------
|
||||
int getMinOccurs() const;
|
||||
int getMaxOccurs() const;
|
||||
|
||||
virtual bool isRepeatableLeaf() const;
|
||||
|
||||
private :
|
||||
// -----------------------------------------------------------------------
|
||||
// Private data members
|
||||
//
|
||||
// fMinOccurs
|
||||
// fMaxOccurs
|
||||
// The cardinality of the repeating leaf
|
||||
//
|
||||
// -----------------------------------------------------------------------
|
||||
int fMinOccurs;
|
||||
int fMaxOccurs;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
CMRepeatingLeaf(const CMRepeatingLeaf&);
|
||||
CMRepeatingLeaf& operator=(const CMRepeatingLeaf&);
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors
|
||||
// -----------------------------------------------------------------------
|
||||
inline CMRepeatingLeaf::CMRepeatingLeaf( QName* const element
|
||||
, int minOccurs
|
||||
, int maxOccurs
|
||||
, unsigned int position
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager) :
|
||||
CMLeaf(element, position, maxStates, manager)
|
||||
, fMinOccurs(minOccurs)
|
||||
, fMaxOccurs(maxOccurs)
|
||||
{
|
||||
}
|
||||
|
||||
inline CMRepeatingLeaf::CMRepeatingLeaf( QName* const element
|
||||
, int minOccurs
|
||||
, int maxOccurs
|
||||
, unsigned int position
|
||||
, bool adopt
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager) :
|
||||
CMLeaf(element, position, adopt, maxStates, manager)
|
||||
, fMinOccurs(minOccurs)
|
||||
, fMaxOccurs(maxOccurs)
|
||||
{
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Getter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
inline int CMRepeatingLeaf::getMinOccurs() const
|
||||
{
|
||||
return fMinOccurs;
|
||||
}
|
||||
|
||||
inline int CMRepeatingLeaf::getMaxOccurs() const
|
||||
{
|
||||
return fMaxOccurs;
|
||||
}
|
||||
|
||||
inline bool CMRepeatingLeaf::isRepeatableLeaf() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,627 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: CMStateSet.hpp 901107 2010-01-20 08:45:02Z borisk $
|
||||
*/
|
||||
|
||||
#if !defined(XERCESC_INCLUDE_GUARD_CMSTATESET_HPP)
|
||||
#define XERCESC_INCLUDE_GUARD_CMSTATESET_HPP
|
||||
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// This class is a specialized bitset class for the content model code of
|
||||
// the validator. It assumes that its never called with two objects of
|
||||
// different bit counts, and that bit sets smaller than a threshold are far
|
||||
// and away the most common. So it can be a lot more optimized than a general
|
||||
// purpose utility bitset class
|
||||
//
|
||||
|
||||
#include <xercesc/util/ArrayIndexOutOfBoundsException.hpp>
|
||||
#include <xercesc/util/RuntimeException.hpp>
|
||||
#include <xercesc/util/PlatformUtils.hpp>
|
||||
#include <xercesc/framework/MemoryManager.hpp>
|
||||
#include <string.h>
|
||||
|
||||
#if XERCES_HAVE_EMMINTRIN_H
|
||||
# include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
class CMStateSetEnumerator;
|
||||
|
||||
// This value must be 4 in order to use the SSE2 instruction set
|
||||
#define CMSTATE_CACHED_INT32_SIZE 4
|
||||
|
||||
// This value must be a multiple of 128 in order to use the SSE2 instruction set
|
||||
#define CMSTATE_BITFIELD_CHUNK 1024
|
||||
#define CMSTATE_BITFIELD_INT32_SIZE (1024 / 32)
|
||||
|
||||
struct CMDynamicBuffer
|
||||
{
|
||||
// fArraySize
|
||||
// This indicates the number of elements of the fBitArray vector
|
||||
//
|
||||
// fBitArray
|
||||
// A vector of arrays of XMLInt32; each array is allocated on demand
|
||||
// if a bit needs to be set in that range
|
||||
//
|
||||
// fMemoryManager
|
||||
// The memory manager used to allocate and deallocate memory
|
||||
//
|
||||
XMLSize_t fArraySize;
|
||||
XMLInt32** fBitArray;
|
||||
MemoryManager* fMemoryManager;
|
||||
};
|
||||
|
||||
class CMStateSet : public XMemory
|
||||
{
|
||||
public :
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors and Destructor
|
||||
// -----------------------------------------------------------------------
|
||||
CMStateSet( const XMLSize_t bitCount
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager) :
|
||||
|
||||
fBitCount(bitCount)
|
||||
, fDynamicBuffer(0)
|
||||
{
|
||||
//
|
||||
// See if we need to allocate the byte array or whether we can live
|
||||
// within the cached bit high performance scheme.
|
||||
//
|
||||
if (fBitCount > (CMSTATE_CACHED_INT32_SIZE * 32))
|
||||
{
|
||||
fDynamicBuffer = (CMDynamicBuffer*)manager->allocate(sizeof(CMDynamicBuffer));
|
||||
fDynamicBuffer->fMemoryManager = manager;
|
||||
// allocate an array of vectors, each one containing CMSTATE_BITFIELD_CHUNK bits
|
||||
fDynamicBuffer->fArraySize = fBitCount / CMSTATE_BITFIELD_CHUNK;
|
||||
if (fBitCount % CMSTATE_BITFIELD_CHUNK)
|
||||
fDynamicBuffer->fArraySize++;
|
||||
fDynamicBuffer->fBitArray = (XMLInt32**) fDynamicBuffer->fMemoryManager->allocate(fDynamicBuffer->fArraySize*sizeof(XMLInt32*));
|
||||
for(XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
|
||||
fDynamicBuffer->fBitArray[index]=NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
|
||||
fBits[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CMStateSet(const CMStateSet& toCopy) :
|
||||
XMemory(toCopy)
|
||||
, fBitCount(toCopy.fBitCount)
|
||||
, fDynamicBuffer(0)
|
||||
{
|
||||
//
|
||||
// See if we need to allocate the byte array or whether we can live
|
||||
// within the cahced bit high performance scheme.
|
||||
//
|
||||
if (fBitCount > (CMSTATE_CACHED_INT32_SIZE * 32))
|
||||
{
|
||||
fDynamicBuffer = (CMDynamicBuffer*) toCopy.fDynamicBuffer->fMemoryManager->allocate(sizeof(CMDynamicBuffer));
|
||||
fDynamicBuffer->fMemoryManager = toCopy.fDynamicBuffer->fMemoryManager;
|
||||
fDynamicBuffer->fArraySize = fBitCount / CMSTATE_BITFIELD_CHUNK;
|
||||
if (fBitCount % CMSTATE_BITFIELD_CHUNK)
|
||||
fDynamicBuffer->fArraySize++;
|
||||
fDynamicBuffer->fBitArray = (XMLInt32**) fDynamicBuffer->fMemoryManager->allocate(fDynamicBuffer->fArraySize*sizeof(XMLInt32*));
|
||||
for(XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
|
||||
{
|
||||
if(toCopy.fDynamicBuffer->fBitArray[index]!=NULL)
|
||||
{
|
||||
allocateChunk(index);
|
||||
memcpy((void *) fDynamicBuffer->fBitArray[index],
|
||||
(const void *) toCopy.fDynamicBuffer->fBitArray[index],
|
||||
CMSTATE_BITFIELD_INT32_SIZE * sizeof(XMLInt32));
|
||||
}
|
||||
else
|
||||
fDynamicBuffer->fBitArray[index]=NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy((void *) fBits,
|
||||
(const void *) toCopy.fBits,
|
||||
CMSTATE_CACHED_INT32_SIZE * sizeof(XMLInt32));
|
||||
}
|
||||
}
|
||||
|
||||
~CMStateSet()
|
||||
{
|
||||
if(fDynamicBuffer)
|
||||
{
|
||||
for(XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
|
||||
if(fDynamicBuffer->fBitArray[index]!=NULL)
|
||||
deallocateChunk(index);
|
||||
fDynamicBuffer->fMemoryManager->deallocate(fDynamicBuffer->fBitArray);
|
||||
fDynamicBuffer->fMemoryManager->deallocate(fDynamicBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Set manipulation methods
|
||||
// -----------------------------------------------------------------------
|
||||
void operator|=(const CMStateSet& setToOr)
|
||||
{
|
||||
if(fDynamicBuffer==0)
|
||||
{
|
||||
#ifdef XERCES_HAVE_SSE2_INTRINSIC
|
||||
if(XMLPlatformUtils::fgSSE2ok)
|
||||
{
|
||||
__m128i xmm1 = _mm_loadu_si128((__m128i*)fBits);
|
||||
__m128i xmm2 = _mm_loadu_si128((__m128i*)setToOr.fBits);
|
||||
__m128i xmm3 = _mm_or_si128(xmm1, xmm2); // OR 4 32-bit words
|
||||
_mm_storeu_si128((__m128i*)fBits, xmm3);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
|
||||
if(setToOr.fBits[index])
|
||||
{
|
||||
if(fBits[index])
|
||||
fBits[index] |= setToOr.fBits[index];
|
||||
else
|
||||
fBits[index] = setToOr.fBits[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
|
||||
{
|
||||
XMLInt32 *& other = setToOr.fDynamicBuffer->fBitArray[index];
|
||||
if(other!=NULL)
|
||||
{
|
||||
// if we haven't allocated the subvector yet, allocate it and copy
|
||||
if(fDynamicBuffer->fBitArray[index]==NULL)
|
||||
{
|
||||
allocateChunk(index);
|
||||
memcpy((void *) fDynamicBuffer->fBitArray[index],
|
||||
(const void *) other,
|
||||
CMSTATE_BITFIELD_INT32_SIZE * sizeof(XMLInt32));
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise, merge them
|
||||
XMLInt32*& mine = fDynamicBuffer->fBitArray[index];
|
||||
#ifdef XERCES_HAVE_SSE2_INTRINSIC
|
||||
if(XMLPlatformUtils::fgSSE2ok)
|
||||
{
|
||||
for(XMLSize_t subIndex = 0; subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex+=4)
|
||||
{
|
||||
__m128i xmm1 = _mm_load_si128((__m128i*)&other[subIndex]);
|
||||
__m128i xmm2 = _mm_load_si128((__m128i*)&mine[subIndex]);
|
||||
__m128i xmm3 = _mm_or_si128(xmm1, xmm2); // OR 4 32-bit words
|
||||
_mm_store_si128((__m128i*)&mine[subIndex], xmm3);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for(XMLSize_t subIndex = 0; subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
|
||||
if(setToOr.fDynamicBuffer->fBitArray[index][subIndex])
|
||||
{
|
||||
if(fDynamicBuffer->fBitArray[index][subIndex])
|
||||
fDynamicBuffer->fBitArray[index][subIndex] |= setToOr.fDynamicBuffer->fBitArray[index][subIndex];
|
||||
else
|
||||
fDynamicBuffer->fBitArray[index][subIndex] = setToOr.fDynamicBuffer->fBitArray[index][subIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const CMStateSet& setToCompare) const
|
||||
{
|
||||
if (fBitCount != setToCompare.fBitCount)
|
||||
return false;
|
||||
|
||||
if(fDynamicBuffer==0)
|
||||
{
|
||||
for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
|
||||
{
|
||||
if (fBits[index] != setToCompare.fBits[index])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
|
||||
{
|
||||
XMLInt32 *& other = setToCompare.fDynamicBuffer->fBitArray[index],
|
||||
*& mine = fDynamicBuffer->fBitArray[index];
|
||||
if(mine==NULL && other==NULL)
|
||||
continue;
|
||||
else if(mine==NULL || other==NULL) // the other should have been empty too
|
||||
return false;
|
||||
else
|
||||
{
|
||||
for(XMLSize_t subIndex = 0; subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
|
||||
if(mine[subIndex]!=other[subIndex])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CMStateSet& operator=(const CMStateSet& srcSet)
|
||||
{
|
||||
if (this == &srcSet)
|
||||
return *this;
|
||||
|
||||
// They have to be the same size
|
||||
if (fBitCount != srcSet.fBitCount)
|
||||
{
|
||||
if(fDynamicBuffer)
|
||||
ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::Bitset_NotEqualSize, fDynamicBuffer->fMemoryManager);
|
||||
else
|
||||
ThrowXML(RuntimeException, XMLExcepts::Bitset_NotEqualSize);
|
||||
}
|
||||
|
||||
if(fDynamicBuffer==0)
|
||||
{
|
||||
for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
|
||||
fBits[index] = srcSet.fBits[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
|
||||
if(srcSet.fDynamicBuffer->fBitArray[index]==NULL)
|
||||
{
|
||||
// delete this subentry
|
||||
if(fDynamicBuffer->fBitArray[index]!=NULL)
|
||||
deallocateChunk(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we haven't allocated the subvector yet, allocate it and copy
|
||||
if(fDynamicBuffer->fBitArray[index]==NULL)
|
||||
allocateChunk(index);
|
||||
memcpy((void *) fDynamicBuffer->fBitArray[index],
|
||||
(const void *) srcSet.fDynamicBuffer->fBitArray[index],
|
||||
CMSTATE_BITFIELD_INT32_SIZE * sizeof(XMLInt32));
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
XMLSize_t getBitCountInRange(XMLSize_t start, XMLSize_t end) const
|
||||
{
|
||||
XMLSize_t count = 0;
|
||||
end /= 32;
|
||||
if(fDynamicBuffer==0)
|
||||
{
|
||||
if(end > CMSTATE_CACHED_INT32_SIZE)
|
||||
end = CMSTATE_CACHED_INT32_SIZE;
|
||||
for (XMLSize_t index = start / 32; index < end; index++)
|
||||
{
|
||||
if (fBits[index] != 0)
|
||||
for(int i=0;i<32;i++)
|
||||
{
|
||||
const XMLInt32 mask = 1UL << i;
|
||||
if(fBits[index] & mask)
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(end > fDynamicBuffer->fArraySize)
|
||||
end = fDynamicBuffer->fArraySize;
|
||||
for (XMLSize_t index = start / 32; index < end; index++)
|
||||
{
|
||||
if(fDynamicBuffer->fBitArray[index]==NULL)
|
||||
continue;
|
||||
for(XMLSize_t subIndex=0;subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
|
||||
{
|
||||
if (fDynamicBuffer->fBitArray[index][subIndex] != 0)
|
||||
for(int i=0;i<32;i++)
|
||||
{
|
||||
const XMLInt32 mask = 1UL << i;
|
||||
if(fDynamicBuffer->fBitArray[index][subIndex] & mask)
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bool getBit(const XMLSize_t bitToGet) const
|
||||
{
|
||||
if (bitToGet >= fBitCount)
|
||||
{
|
||||
if(fDynamicBuffer)
|
||||
ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Bitset_BadIndex, fDynamicBuffer->fMemoryManager);
|
||||
else
|
||||
ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Bitset_BadIndex);
|
||||
}
|
||||
|
||||
// And access the right bit and byte
|
||||
if(fDynamicBuffer==0)
|
||||
{
|
||||
const XMLInt32 mask = 1UL << (bitToGet % 32);
|
||||
const XMLSize_t byteOfs = bitToGet / 32;
|
||||
return (fBits[byteOfs]!=0 && (fBits[byteOfs] & mask) != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
const XMLSize_t vectorOfs = bitToGet / CMSTATE_BITFIELD_CHUNK;
|
||||
if(fDynamicBuffer->fBitArray[vectorOfs]==NULL)
|
||||
return false;
|
||||
const XMLInt32 mask = 1UL << (bitToGet % 32);
|
||||
const XMLSize_t byteOfs = (bitToGet % CMSTATE_BITFIELD_CHUNK) / 32;
|
||||
return (fDynamicBuffer->fBitArray[vectorOfs][byteOfs]!=0 && (fDynamicBuffer->fBitArray[vectorOfs][byteOfs] & mask) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool isEmpty() const
|
||||
{
|
||||
if(fDynamicBuffer==0)
|
||||
{
|
||||
for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
|
||||
{
|
||||
if (fBits[index] != 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
|
||||
{
|
||||
if(fDynamicBuffer->fBitArray[index]==NULL)
|
||||
continue;
|
||||
for(XMLSize_t subIndex=0;subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
|
||||
{
|
||||
if (fDynamicBuffer->fBitArray[index][subIndex] != 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void setBit(const XMLSize_t bitToSet)
|
||||
{
|
||||
if (bitToSet >= fBitCount)
|
||||
{
|
||||
if(fDynamicBuffer)
|
||||
ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Bitset_BadIndex, fDynamicBuffer->fMemoryManager);
|
||||
else
|
||||
ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Bitset_BadIndex);
|
||||
}
|
||||
|
||||
const XMLInt32 mask = 1UL << (bitToSet % 32);
|
||||
|
||||
// And access the right bit and byte
|
||||
if(fDynamicBuffer==0)
|
||||
{
|
||||
const XMLSize_t byteOfs = bitToSet / 32;
|
||||
fBits[byteOfs] &= ~mask;
|
||||
fBits[byteOfs] |= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
const XMLSize_t vectorOfs = bitToSet / CMSTATE_BITFIELD_CHUNK;
|
||||
if(fDynamicBuffer->fBitArray[vectorOfs]==NULL)
|
||||
{
|
||||
allocateChunk(vectorOfs);
|
||||
for(XMLSize_t index=0;index < CMSTATE_BITFIELD_INT32_SIZE; index++)
|
||||
fDynamicBuffer->fBitArray[vectorOfs][index]=0;
|
||||
}
|
||||
const XMLSize_t byteOfs = (bitToSet % CMSTATE_BITFIELD_CHUNK) / 32;
|
||||
fDynamicBuffer->fBitArray[vectorOfs][byteOfs] &= ~mask;
|
||||
fDynamicBuffer->fBitArray[vectorOfs][byteOfs] |= mask;
|
||||
}
|
||||
}
|
||||
|
||||
void zeroBits()
|
||||
{
|
||||
if(fDynamicBuffer==0)
|
||||
{
|
||||
for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
|
||||
fBits[index] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
|
||||
// delete this subentry
|
||||
if(fDynamicBuffer->fBitArray[index]!=NULL)
|
||||
deallocateChunk(index);
|
||||
}
|
||||
}
|
||||
|
||||
XMLSize_t hashCode() const
|
||||
{
|
||||
XMLSize_t hash = 0;
|
||||
if(fDynamicBuffer==0)
|
||||
{
|
||||
for (XMLSize_t index = 0; index<CMSTATE_CACHED_INT32_SIZE; index++)
|
||||
hash = fBits[index] + hash * 31;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (XMLSize_t index = 0; index<fDynamicBuffer->fArraySize; index++)
|
||||
{
|
||||
if(fDynamicBuffer->fBitArray[index]==NULL)
|
||||
// simulates the iteration on the missing bits
|
||||
for(XMLSize_t subIndex=0;subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
|
||||
hash *= 31;
|
||||
else
|
||||
for(XMLSize_t subIndex=0;subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
|
||||
hash = fDynamicBuffer->fBitArray[index][subIndex] + hash * 31;
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
private :
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
CMStateSet();
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helpers
|
||||
// -----------------------------------------------------------------------
|
||||
void allocateChunk(const XMLSize_t index)
|
||||
{
|
||||
#ifdef XERCES_HAVE_SSE2_INTRINSIC
|
||||
if(XMLPlatformUtils::fgSSE2ok)
|
||||
fDynamicBuffer->fBitArray[index]=(XMLInt32*)_mm_malloc(CMSTATE_BITFIELD_INT32_SIZE * sizeof(XMLInt32), 16);
|
||||
else
|
||||
#endif
|
||||
fDynamicBuffer->fBitArray[index]=(XMLInt32*)fDynamicBuffer->fMemoryManager->allocate(CMSTATE_BITFIELD_INT32_SIZE * sizeof(XMLInt32));
|
||||
}
|
||||
|
||||
void deallocateChunk(const XMLSize_t index)
|
||||
{
|
||||
#ifdef XERCES_HAVE_SSE2_INTRINSIC
|
||||
if(XMLPlatformUtils::fgSSE2ok)
|
||||
_mm_free(fDynamicBuffer->fBitArray[index]);
|
||||
else
|
||||
#endif
|
||||
fDynamicBuffer->fMemoryManager->deallocate(fDynamicBuffer->fBitArray[index]);
|
||||
fDynamicBuffer->fBitArray[index]=NULL;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Private data members
|
||||
//
|
||||
// fBitCount
|
||||
// The count of bits that the outside world wants to support,
|
||||
// so its the max bit index plus one.
|
||||
//
|
||||
// fBits
|
||||
// When the bit count is less than a threshold (very common), these hold the bits.
|
||||
// Otherwise, the fDynamicBuffer member holds htem.
|
||||
//
|
||||
// fDynamicBuffer
|
||||
// If the bit count is greater than the threshold, then we allocate this structure to
|
||||
// store the bits, the length, and the memory manager to allocate/deallocate
|
||||
// the memory
|
||||
//
|
||||
// -----------------------------------------------------------------------
|
||||
XMLSize_t fBitCount;
|
||||
XMLInt32 fBits[CMSTATE_CACHED_INT32_SIZE];
|
||||
CMDynamicBuffer* fDynamicBuffer;
|
||||
|
||||
friend class CMStateSetEnumerator;
|
||||
};
|
||||
|
||||
class CMStateSetEnumerator : public XMemory
|
||||
{
|
||||
public:
|
||||
CMStateSetEnumerator(const CMStateSet* toEnum, XMLSize_t start = 0) :
|
||||
fToEnum(toEnum),
|
||||
fIndexCount((XMLSize_t)-1),
|
||||
fLastValue(0)
|
||||
{
|
||||
// if a starting bit is specified, place fIndexCount at the beginning of the previous 32 bit area
|
||||
// so the findNext moves to the one where 'start' is located
|
||||
if(start > 32)
|
||||
fIndexCount = (start/32 - 1) * 32;
|
||||
findNext();
|
||||
// if we found data, and fIndexCount is still pointing to the area where 'start' is located, erase the bits before 'start'
|
||||
if(hasMoreElements() && fIndexCount < start)
|
||||
{
|
||||
for(XMLSize_t i=0;i< (start - fIndexCount);i++)
|
||||
{
|
||||
XMLInt32 mask=1UL << i;
|
||||
if(fLastValue & mask)
|
||||
fLastValue &= ~mask;
|
||||
}
|
||||
// in case the 32 bit area contained only bits before 'start', advance
|
||||
if(fLastValue==0)
|
||||
findNext();
|
||||
}
|
||||
}
|
||||
|
||||
bool hasMoreElements()
|
||||
{
|
||||
return fLastValue!=0;
|
||||
}
|
||||
|
||||
unsigned int nextElement()
|
||||
{
|
||||
for(int i=0;i<32;i++)
|
||||
{
|
||||
XMLInt32 mask=1UL << i;
|
||||
if(fLastValue & mask)
|
||||
{
|
||||
fLastValue &= ~mask;
|
||||
unsigned int retVal=(unsigned int)fIndexCount+i;
|
||||
if(fLastValue==0)
|
||||
findNext();
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
void findNext()
|
||||
{
|
||||
if(fToEnum->fDynamicBuffer==0)
|
||||
{
|
||||
XMLSize_t nOffset=((fIndexCount==(XMLSize_t)-1)?0:(fIndexCount/32)+1);
|
||||
for(XMLSize_t index=nOffset;index<CMSTATE_CACHED_INT32_SIZE;index++)
|
||||
{
|
||||
if(fToEnum->fBits[index]!=0)
|
||||
{
|
||||
fIndexCount=index*32;
|
||||
fLastValue=fToEnum->fBits[index];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
XMLSize_t nOffset=((fIndexCount==(XMLSize_t)-1)?0:(fIndexCount/CMSTATE_BITFIELD_CHUNK));
|
||||
XMLSize_t nSubOffset=((fIndexCount==(XMLSize_t)-1)?0:((fIndexCount % CMSTATE_BITFIELD_CHUNK) /32)+1);
|
||||
for (XMLSize_t index = nOffset; index<fToEnum->fDynamicBuffer->fArraySize; index++)
|
||||
{
|
||||
if(fToEnum->fDynamicBuffer->fBitArray[index]!=NULL)
|
||||
{
|
||||
for(XMLSize_t subIndex=nSubOffset;subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
|
||||
if(fToEnum->fDynamicBuffer->fBitArray[index][subIndex]!=0)
|
||||
{
|
||||
fIndexCount=index*CMSTATE_BITFIELD_CHUNK + subIndex*32;
|
||||
fLastValue=fToEnum->fDynamicBuffer->fBitArray[index][subIndex];
|
||||
return;
|
||||
}
|
||||
}
|
||||
nSubOffset = 0; // next chunks will be processed from the beginning
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const CMStateSet* fToEnum;
|
||||
XMLSize_t fIndexCount;
|
||||
XMLInt32 fLastValue;
|
||||
};
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: CMUnaryOp.cpp 677396 2008-07-16 19:36:20Z amassari $
|
||||
*/
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Includes
|
||||
// ---------------------------------------------------------------------------
|
||||
#include <xercesc/util/RuntimeException.hpp>
|
||||
#include <xercesc/validators/common/CMStateSet.hpp>
|
||||
#include <xercesc/validators/common/CMUnaryOp.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CMUnaryOp: Constructors and Destructor
|
||||
// ---------------------------------------------------------------------------
|
||||
CMUnaryOp::CMUnaryOp( ContentSpecNode::NodeTypes type
|
||||
, CMNode* const nodeToAdopt
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager) :
|
||||
CMNode(type, maxStates, manager)
|
||||
, fChild(nodeToAdopt)
|
||||
{
|
||||
// Insure that its one of the types we require
|
||||
if ((type != ContentSpecNode::ZeroOrOne)
|
||||
&& (type != ContentSpecNode::ZeroOrMore)
|
||||
&& (type != ContentSpecNode::OneOrMore))
|
||||
{
|
||||
ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnaryOpHadBinType, manager);
|
||||
}
|
||||
if (type == ContentSpecNode::OneOrMore)
|
||||
fIsNullable=fChild->isNullable();
|
||||
else
|
||||
fIsNullable=true;
|
||||
}
|
||||
|
||||
CMUnaryOp::~CMUnaryOp()
|
||||
{
|
||||
delete fChild;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CMUnaryOp: Getter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
const CMNode* CMUnaryOp::getChild() const
|
||||
{
|
||||
return fChild;
|
||||
}
|
||||
|
||||
CMNode* CMUnaryOp::getChild()
|
||||
{
|
||||
return fChild;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CMUnaryOp: Implementation of the public CMNode virtual interface
|
||||
// ---------------------------------------------------------------------------
|
||||
void CMUnaryOp::orphanChild()
|
||||
{
|
||||
delete fChild;
|
||||
fChild=0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CMUnaryOp: Implementation of the protected CMNode virtual interface
|
||||
// ---------------------------------------------------------------------------
|
||||
void CMUnaryOp::calcFirstPos(CMStateSet& toSet) const
|
||||
{
|
||||
// Its just based on our child node's first pos
|
||||
toSet = fChild->getFirstPos();
|
||||
}
|
||||
|
||||
void CMUnaryOp::calcLastPos(CMStateSet& toSet) const
|
||||
{
|
||||
// Its just based on our child node's last pos
|
||||
toSet = fChild->getLastPos();
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: CMUnaryOp.hpp 677396 2008-07-16 19:36:20Z amassari $
|
||||
*/
|
||||
|
||||
#if !defined(XERCESC_INCLUDE_GUARD_CMUNARYOP_HPP)
|
||||
#define XERCESC_INCLUDE_GUARD_CMUNARYOP_HPP
|
||||
|
||||
#include <xercesc/validators/common/CMNode.hpp>
|
||||
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
class CMStateSet;
|
||||
|
||||
class CMUnaryOp : public CMNode
|
||||
{
|
||||
public :
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors and Destructor
|
||||
// -----------------------------------------------------------------------
|
||||
CMUnaryOp
|
||||
(
|
||||
ContentSpecNode::NodeTypes type
|
||||
, CMNode* const nodeToAdopt
|
||||
, unsigned int maxStates
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
~CMUnaryOp();
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Getter methods
|
||||
// -----------------------------------------------------------------------
|
||||
const CMNode* getChild() const;
|
||||
CMNode* getChild();
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Implementation of the public CMNode virtual interface
|
||||
// -----------------------------------------------------------------------
|
||||
virtual void orphanChild();
|
||||
|
||||
|
||||
protected :
|
||||
// -----------------------------------------------------------------------
|
||||
// Implementation of the protected CMNode virtual interface
|
||||
// -----------------------------------------------------------------------
|
||||
void calcFirstPos(CMStateSet& toSet) const;
|
||||
void calcLastPos(CMStateSet& toSet) const;
|
||||
|
||||
|
||||
private :
|
||||
// -----------------------------------------------------------------------
|
||||
// Private data members
|
||||
//
|
||||
// fChild
|
||||
// This is the reference to the one child that we have for this
|
||||
// unary operation. We own it.
|
||||
// -----------------------------------------------------------------------
|
||||
CMNode* fChild;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
CMUnaryOp(const CMUnaryOp&);
|
||||
CMUnaryOp& operator=(const CMUnaryOp&);
|
||||
};
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: ContentLeafNameTypeVector.cpp 676911 2008-07-15 13:27:32Z amassari $
|
||||
*/
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Includes
|
||||
// ---------------------------------------------------------------------------
|
||||
#include <xercesc/validators/common/ContentLeafNameTypeVector.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ContentLeafNameTypeVector: Constructors and Destructor
|
||||
// ---------------------------------------------------------------------------
|
||||
ContentLeafNameTypeVector::ContentLeafNameTypeVector
|
||||
(
|
||||
MemoryManager* const manager
|
||||
)
|
||||
: fMemoryManager(manager)
|
||||
, fLeafNames(0)
|
||||
, fLeafTypes(0)
|
||||
, fLeafCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
ContentLeafNameTypeVector::ContentLeafNameTypeVector
|
||||
(
|
||||
QName** const names
|
||||
, ContentSpecNode::NodeTypes* const types
|
||||
, const XMLSize_t count
|
||||
, MemoryManager* const manager
|
||||
)
|
||||
: fMemoryManager(manager)
|
||||
, fLeafNames(0)
|
||||
, fLeafTypes(0)
|
||||
, fLeafCount(0)
|
||||
{
|
||||
setValues(names, types, count);
|
||||
}
|
||||
|
||||
/***
|
||||
copy ctor
|
||||
***/
|
||||
ContentLeafNameTypeVector::ContentLeafNameTypeVector
|
||||
(
|
||||
const ContentLeafNameTypeVector& toCopy
|
||||
)
|
||||
: XMemory(toCopy)
|
||||
, fMemoryManager(toCopy.fMemoryManager)
|
||||
, fLeafNames(0)
|
||||
, fLeafTypes(0)
|
||||
, fLeafCount(0)
|
||||
{
|
||||
fLeafCount=toCopy.getLeafCount();
|
||||
init(fLeafCount);
|
||||
|
||||
for (XMLSize_t i=0; i<this->fLeafCount; i++)
|
||||
{
|
||||
fLeafNames[i] = toCopy.getLeafNameAt(i);
|
||||
fLeafTypes[i] = toCopy.getLeafTypeAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
ContentLeafNameTypeVector::~ContentLeafNameTypeVector()
|
||||
{
|
||||
cleanUp();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ContentSpecType: Setter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
void ContentLeafNameTypeVector::setValues
|
||||
(
|
||||
QName** const names
|
||||
, ContentSpecNode::NodeTypes* const types
|
||||
, const XMLSize_t count
|
||||
)
|
||||
{
|
||||
cleanUp();
|
||||
init(count);
|
||||
|
||||
for (XMLSize_t i=0; i<count; i++)
|
||||
{
|
||||
fLeafNames[i] = names[i];
|
||||
fLeafTypes[i] = types[i];
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ContentLeafNameTypeVector: Getter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
QName* ContentLeafNameTypeVector::getLeafNameAt(const XMLSize_t pos) const
|
||||
{
|
||||
if (pos >= fLeafCount)
|
||||
ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Vector_BadIndex, fMemoryManager);
|
||||
|
||||
return fLeafNames[pos];
|
||||
}
|
||||
|
||||
ContentSpecNode::NodeTypes ContentLeafNameTypeVector::getLeafTypeAt
|
||||
(const XMLSize_t pos) const
|
||||
{
|
||||
if (pos >= fLeafCount)
|
||||
ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Vector_BadIndex, fMemoryManager);
|
||||
|
||||
return fLeafTypes[pos];
|
||||
}
|
||||
|
||||
XMLSize_t ContentLeafNameTypeVector::getLeafCount() const
|
||||
{
|
||||
return fLeafCount;
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: ContentLeafNameTypeVector.hpp 676911 2008-07-15 13:27:32Z amassari $
|
||||
*/
|
||||
|
||||
#if !defined(XERCESC_INCLUDE_GUARD_CONTENTLEAFNAMETYPEVECTOR_HPP)
|
||||
#define XERCESC_INCLUDE_GUARD_CONTENTLEAFNAMETYPEVECTOR_HPP
|
||||
|
||||
#include <xercesc/validators/common/ContentSpecNode.hpp>
|
||||
#include <xercesc/framework/MemoryManager.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
class XMLPARSER_EXPORT ContentLeafNameTypeVector : public XMemory
|
||||
{
|
||||
public :
|
||||
// -----------------------------------------------------------------------
|
||||
// Class specific types
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors and Destructor
|
||||
// -----------------------------------------------------------------------
|
||||
ContentLeafNameTypeVector
|
||||
(
|
||||
MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
ContentLeafNameTypeVector
|
||||
(
|
||||
QName** const qName
|
||||
, ContentSpecNode::NodeTypes* const types
|
||||
, const XMLSize_t count
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
|
||||
~ContentLeafNameTypeVector();
|
||||
|
||||
ContentLeafNameTypeVector(const ContentLeafNameTypeVector&);
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Getter methods
|
||||
// -----------------------------------------------------------------------
|
||||
QName* getLeafNameAt(const XMLSize_t pos) const;
|
||||
|
||||
ContentSpecNode::NodeTypes getLeafTypeAt(const XMLSize_t pos) const;
|
||||
XMLSize_t getLeafCount() const;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Setter methods
|
||||
// -----------------------------------------------------------------------
|
||||
void setValues
|
||||
(
|
||||
QName** const qName
|
||||
, ContentSpecNode::NodeTypes* const types
|
||||
, const XMLSize_t count
|
||||
);
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Miscellaneous
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
private :
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
ContentLeafNameTypeVector& operator=(const ContentLeafNameTypeVector&);
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// helper methods
|
||||
// -----------------------------------------------------------------------
|
||||
void cleanUp();
|
||||
void init(const XMLSize_t size);
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Private Data Members
|
||||
//
|
||||
// -----------------------------------------------------------------------
|
||||
MemoryManager* fMemoryManager;
|
||||
QName** fLeafNames;
|
||||
ContentSpecNode::NodeTypes *fLeafTypes;
|
||||
XMLSize_t fLeafCount;
|
||||
};
|
||||
|
||||
inline void ContentLeafNameTypeVector::cleanUp()
|
||||
{
|
||||
fMemoryManager->deallocate(fLeafNames); //delete [] fLeafNames;
|
||||
fMemoryManager->deallocate(fLeafTypes); //delete [] fLeafTypes;
|
||||
}
|
||||
|
||||
inline void ContentLeafNameTypeVector::init(const XMLSize_t size)
|
||||
{
|
||||
fLeafNames = (QName**) fMemoryManager->allocate(size * sizeof(QName*));//new QName*[size];
|
||||
fLeafTypes = (ContentSpecNode::NodeTypes *) fMemoryManager->allocate
|
||||
(
|
||||
size * sizeof(ContentSpecNode::NodeTypes)
|
||||
); //new ContentSpecNode::NodeTypes [size];
|
||||
fLeafCount = size;
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: ContentSpecNode.cpp 1662870 2015-02-28 00:56:55Z scantor $
|
||||
*/
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Includes
|
||||
// ---------------------------------------------------------------------------
|
||||
#include <xercesc/framework/XMLBuffer.hpp>
|
||||
#include <xercesc/validators/common/ContentSpecNode.hpp>
|
||||
#include <xercesc/validators/schema/SchemaSymbols.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ContentSpecNode: Copy Constructor
|
||||
//
|
||||
// Note: this copy constructor has dependency on various get*() methods
|
||||
// and shall be placed after those method's declaration.
|
||||
// aka inline function compilation error on AIX 4.2, xlC 3 r ev.1
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
ContentSpecNode::ContentSpecNode(const ContentSpecNode& toCopy) :
|
||||
XSerializable(toCopy)
|
||||
, XMemory(toCopy)
|
||||
, fMemoryManager(toCopy.fMemoryManager)
|
||||
, fElement(0)
|
||||
, fElementDecl(toCopy.fElementDecl)
|
||||
, fFirst(0)
|
||||
, fSecond(0)
|
||||
, fType(toCopy.fType)
|
||||
, fAdoptFirst(true)
|
||||
, fAdoptSecond(true)
|
||||
, fMinOccurs(toCopy.fMinOccurs)
|
||||
, fMaxOccurs(toCopy.fMaxOccurs)
|
||||
{
|
||||
const QName* tempElement = toCopy.getElement();
|
||||
if (tempElement)
|
||||
fElement = new (fMemoryManager) QName(*tempElement);
|
||||
|
||||
const ContentSpecNode *tmp = toCopy.getFirst();
|
||||
if (tmp)
|
||||
fFirst = new (fMemoryManager) ContentSpecNode(*tmp);
|
||||
|
||||
tmp = toCopy.getSecond();
|
||||
if (tmp)
|
||||
fSecond = new (fMemoryManager) ContentSpecNode(*tmp);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Local methods
|
||||
// ---------------------------------------------------------------------------
|
||||
static void formatNode( const ContentSpecNode* const curNode
|
||||
, const ContentSpecNode::NodeTypes parentType
|
||||
, XMLBuffer& bufToFill)
|
||||
{
|
||||
if (!curNode)
|
||||
return;
|
||||
|
||||
const ContentSpecNode* first = curNode->getFirst();
|
||||
const ContentSpecNode* second = curNode->getSecond();
|
||||
const ContentSpecNode::NodeTypes curType = curNode->getType();
|
||||
|
||||
// Get the type of the first node
|
||||
const ContentSpecNode::NodeTypes firstType = first ?
|
||||
first->getType() :
|
||||
ContentSpecNode::Leaf;
|
||||
|
||||
// Calculate the parens flag for the rep nodes
|
||||
bool doRepParens = false;
|
||||
if (((firstType != ContentSpecNode::Leaf)
|
||||
&& (parentType != ContentSpecNode::UnknownType))
|
||||
|| ((firstType == ContentSpecNode::Leaf)
|
||||
&& (parentType == ContentSpecNode::UnknownType)))
|
||||
{
|
||||
doRepParens = true;
|
||||
}
|
||||
|
||||
// Now handle our type
|
||||
switch(curType & 0x0f)
|
||||
{
|
||||
case ContentSpecNode::Leaf :
|
||||
if (curNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)
|
||||
bufToFill.append(XMLElementDecl::fgPCDataElemName);
|
||||
else
|
||||
{
|
||||
bufToFill.append(curNode->getElement()->getRawName());
|
||||
// show the + and * modifiers also when we have a non-infinite number of repetitions
|
||||
if(curNode->getMinOccurs()==0 && (curNode->getMaxOccurs()==-1 || curNode->getMaxOccurs()>1))
|
||||
bufToFill.append(chAsterisk);
|
||||
else if(curNode->getMinOccurs()==0 && curNode->getMaxOccurs()==1)
|
||||
bufToFill.append(chQuestion);
|
||||
else if(curNode->getMinOccurs()==1 && (curNode->getMaxOccurs()==-1 || curNode->getMaxOccurs()>1))
|
||||
bufToFill.append(chPlus);
|
||||
}
|
||||
break;
|
||||
|
||||
case ContentSpecNode::ZeroOrOne :
|
||||
if (doRepParens)
|
||||
bufToFill.append(chOpenParen);
|
||||
formatNode(first, curType, bufToFill);
|
||||
if (doRepParens)
|
||||
bufToFill.append(chCloseParen);
|
||||
bufToFill.append(chQuestion);
|
||||
break;
|
||||
|
||||
case ContentSpecNode::ZeroOrMore :
|
||||
if (doRepParens)
|
||||
bufToFill.append(chOpenParen);
|
||||
formatNode(first, curType, bufToFill);
|
||||
if (doRepParens)
|
||||
bufToFill.append(chCloseParen);
|
||||
bufToFill.append(chAsterisk);
|
||||
break;
|
||||
|
||||
case ContentSpecNode::OneOrMore :
|
||||
if (doRepParens)
|
||||
bufToFill.append(chOpenParen);
|
||||
formatNode(first, curType, bufToFill);
|
||||
if (doRepParens)
|
||||
bufToFill.append(chCloseParen);
|
||||
bufToFill.append(chPlus);
|
||||
break;
|
||||
|
||||
case ContentSpecNode::Choice :
|
||||
if ((parentType & 0x0f) != (curType & 0x0f))
|
||||
bufToFill.append(chOpenParen);
|
||||
formatNode(first, curType, bufToFill);
|
||||
if(second!=NULL)
|
||||
{
|
||||
bufToFill.append(chPipe);
|
||||
formatNode(second, curType, bufToFill);
|
||||
}
|
||||
if ((parentType & 0x0f) != (curType & 0x0f))
|
||||
bufToFill.append(chCloseParen);
|
||||
break;
|
||||
|
||||
case ContentSpecNode::Sequence :
|
||||
if ((parentType & 0x0f) != (curType & 0x0f))
|
||||
bufToFill.append(chOpenParen);
|
||||
formatNode(first, curType, bufToFill);
|
||||
if(second!=NULL)
|
||||
{
|
||||
bufToFill.append(chComma);
|
||||
formatNode(second, curType, bufToFill);
|
||||
}
|
||||
if ((parentType & 0x0f) != (curType & 0x0f))
|
||||
bufToFill.append(chCloseParen);
|
||||
break;
|
||||
|
||||
case ContentSpecNode::All :
|
||||
if ((parentType & 0x0f) != (curType & 0x0f))
|
||||
{
|
||||
bufToFill.append(chLatin_A);
|
||||
bufToFill.append(chLatin_l);
|
||||
bufToFill.append(chLatin_l);
|
||||
bufToFill.append(chOpenParen);
|
||||
}
|
||||
formatNode(first, curType, bufToFill);
|
||||
bufToFill.append(chComma);
|
||||
formatNode(second, curType, bufToFill);
|
||||
if ((parentType & 0x0f) != (curType & 0x0f))
|
||||
bufToFill.append(chCloseParen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ContentSpecNode: Miscellaneous
|
||||
// ---------------------------------------------------------------------------
|
||||
void ContentSpecNode::formatSpec(XMLBuffer& bufToFill) const
|
||||
{
|
||||
// Clean out the buffer first
|
||||
bufToFill.reset();
|
||||
|
||||
if (fType == ContentSpecNode::Leaf)
|
||||
bufToFill.append(chOpenParen);
|
||||
formatNode
|
||||
(
|
||||
this
|
||||
, UnknownType
|
||||
, bufToFill
|
||||
);
|
||||
if (fType == ContentSpecNode::Leaf)
|
||||
bufToFill.append(chCloseParen);
|
||||
}
|
||||
|
||||
int ContentSpecNode::getMinTotalRange() const {
|
||||
|
||||
int min = fMinOccurs;
|
||||
|
||||
if ((fType & 0x0f) == ContentSpecNode::Sequence
|
||||
|| fType == ContentSpecNode::All
|
||||
|| (fType & 0x0f) == ContentSpecNode::Choice) {
|
||||
|
||||
int minFirst = fFirst->getMinTotalRange();
|
||||
|
||||
if (fSecond) {
|
||||
|
||||
int minSecond = fSecond->getMinTotalRange();
|
||||
|
||||
if ((fType & 0x0f) == 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::XSD_UNBOUNDED) {
|
||||
return SchemaSymbols::XSD_UNBOUNDED;
|
||||
}
|
||||
|
||||
if ((fType & 0x0f) == ContentSpecNode::Sequence
|
||||
|| fType == ContentSpecNode::All
|
||||
|| (fType & 0x0f) == ContentSpecNode::Choice) {
|
||||
|
||||
int maxFirst = fFirst->getMaxTotalRange();
|
||||
|
||||
if (maxFirst == SchemaSymbols::XSD_UNBOUNDED) {
|
||||
return SchemaSymbols::XSD_UNBOUNDED;
|
||||
}
|
||||
|
||||
if (fSecond) {
|
||||
|
||||
int maxSecond = fSecond->getMaxTotalRange();
|
||||
|
||||
if (maxSecond == SchemaSymbols::XSD_UNBOUNDED) {
|
||||
return SchemaSymbols::XSD_UNBOUNDED;
|
||||
}
|
||||
else {
|
||||
|
||||
if ((fType & 0x0f) == ContentSpecNode::Choice) {
|
||||
max = max * ((maxFirst > maxSecond) ? maxFirst : maxSecond);
|
||||
}
|
||||
else {
|
||||
max = max * (maxFirst + maxSecond);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
max = max * maxFirst;
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
/***
|
||||
* Support for Serialization/De-serialization
|
||||
***/
|
||||
|
||||
IMPL_XSERIALIZABLE_TOCREATE(ContentSpecNode)
|
||||
|
||||
void ContentSpecNode::serialize(XSerializeEngine& serEng)
|
||||
{
|
||||
/***
|
||||
* Since fElement, fFirst, fSecond are NOT created by the default
|
||||
* constructor, we need to create them dynamically.
|
||||
***/
|
||||
|
||||
if (serEng.isStoring())
|
||||
{
|
||||
serEng<<fElement;
|
||||
XMLElementDecl::storeElementDecl(serEng, fElementDecl);
|
||||
serEng<<fFirst;
|
||||
serEng<<fSecond;
|
||||
|
||||
serEng<<(int)fType;
|
||||
serEng<<fAdoptFirst;
|
||||
serEng<<fAdoptSecond;
|
||||
serEng<<fMinOccurs;
|
||||
serEng<<fMaxOccurs;
|
||||
}
|
||||
else
|
||||
{
|
||||
serEng>>fElement;
|
||||
fElementDecl = XMLElementDecl::loadElementDecl(serEng);
|
||||
serEng>>fFirst;
|
||||
serEng>>fSecond;
|
||||
|
||||
int type;
|
||||
serEng>>type;
|
||||
fType = (NodeTypes)type;
|
||||
|
||||
serEng>>fAdoptFirst;
|
||||
serEng>>fAdoptSecond;
|
||||
serEng>>fMinOccurs;
|
||||
serEng>>fMaxOccurs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
@@ -0,0 +1,467 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: ContentSpecNode.hpp 932887 2010-04-11 13:04:59Z borisk $
|
||||
*/
|
||||
|
||||
#if !defined(XERCESC_INCLUDE_GUARD_CONTENTSPECNODE_HPP)
|
||||
#define XERCESC_INCLUDE_GUARD_CONTENTSPECNODE_HPP
|
||||
|
||||
#include <xercesc/framework/XMLElementDecl.hpp>
|
||||
#include <xercesc/framework/MemoryManager.hpp>
|
||||
|
||||
#include <xercesc/internal/XSerializable.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
class XMLBuffer;
|
||||
class Grammar;
|
||||
|
||||
|
||||
class XMLUTIL_EXPORT ContentSpecNode : public XSerializable, public XMemory
|
||||
{
|
||||
public :
|
||||
// -----------------------------------------------------------------------
|
||||
// Class specific types
|
||||
// -----------------------------------------------------------------------
|
||||
enum NodeTypes
|
||||
{
|
||||
Leaf = 0
|
||||
, ZeroOrOne
|
||||
, ZeroOrMore
|
||||
, OneOrMore
|
||||
, Choice
|
||||
, Sequence
|
||||
, Any
|
||||
, Any_Other
|
||||
, Any_NS = 8
|
||||
, All = 9
|
||||
, Loop = 10
|
||||
, Any_NS_Choice = 20 // 16 + 4 (Choice)
|
||||
, ModelGroupSequence = 21 // 16 + 5 (Sequence)
|
||||
, Any_Lax = 22 // 16 + 6 (Any)
|
||||
, Any_Other_Lax = 23 // 16 + 7 (Any_Other)
|
||||
, Any_NS_Lax = 24 // 16 + 8 (Any_NS)
|
||||
, ModelGroupChoice = 36 // 32 + 4 (Choice)
|
||||
, Any_Skip = 38 // 32 + 6 (Any)
|
||||
, Any_Other_Skip = 39 // 32 + 7 (Any_Other)
|
||||
, Any_NS_Skip = 40 // 32 + 8 (Any_NS)
|
||||
|
||||
, UnknownType = -1
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors and Destructor
|
||||
// -----------------------------------------------------------------------
|
||||
ContentSpecNode(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
|
||||
ContentSpecNode
|
||||
(
|
||||
QName* const toAdopt
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
ContentSpecNode
|
||||
(
|
||||
XMLElementDecl* const elemDecl
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
ContentSpecNode
|
||||
(
|
||||
QName* const toAdopt
|
||||
, const bool copyQName
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
ContentSpecNode
|
||||
(
|
||||
const NodeTypes type
|
||||
, ContentSpecNode* const firstToAdopt
|
||||
, ContentSpecNode* const secondToAdopt
|
||||
, const bool adoptFirst = true
|
||||
, const bool adoptSecond = true
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
ContentSpecNode(const ContentSpecNode&);
|
||||
~ContentSpecNode();
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Getter methods
|
||||
// -----------------------------------------------------------------------
|
||||
QName* getElement();
|
||||
const QName* getElement() const;
|
||||
XMLElementDecl* getElementDecl();
|
||||
const XMLElementDecl* getElementDecl() const;
|
||||
ContentSpecNode* getFirst();
|
||||
const ContentSpecNode* getFirst() const;
|
||||
ContentSpecNode* getSecond();
|
||||
const ContentSpecNode* getSecond() const;
|
||||
NodeTypes getType() const;
|
||||
ContentSpecNode* orphanFirst();
|
||||
ContentSpecNode* orphanSecond();
|
||||
int getMinOccurs() const;
|
||||
int getMaxOccurs() const;
|
||||
bool isFirstAdopted() const;
|
||||
bool isSecondAdopted() const;
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Setter methods
|
||||
// -----------------------------------------------------------------------
|
||||
void setElement(QName* const toAdopt);
|
||||
void setFirst(ContentSpecNode* const toAdopt);
|
||||
void setSecond(ContentSpecNode* const toAdopt);
|
||||
void setType(const NodeTypes type);
|
||||
void setMinOccurs(int min);
|
||||
void setMaxOccurs(int max);
|
||||
void setAdoptFirst(bool adoptFirst);
|
||||
void setAdoptSecond(bool adoptSecond);
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Miscellaneous
|
||||
// -----------------------------------------------------------------------
|
||||
void formatSpec (XMLBuffer& bufToFill) const;
|
||||
bool hasAllContent();
|
||||
int getMinTotalRange() const;
|
||||
int getMaxTotalRange() const;
|
||||
|
||||
/***
|
||||
* Support for Serialization/De-serialization
|
||||
***/
|
||||
DECL_XSERIALIZABLE(ContentSpecNode)
|
||||
|
||||
private :
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
ContentSpecNode& operator=(const ContentSpecNode&);
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Private Data Members
|
||||
//
|
||||
// fElement
|
||||
// If the type is Leaf/Any*, then this is the qName of the element. If the URI
|
||||
// is fgPCDataElemId, then its a PCData node. Else, it is zero.
|
||||
//
|
||||
// fFirst
|
||||
// fSecond
|
||||
// The optional first and second nodes. The fType field indicates
|
||||
// which of these are valid. The validity constraints are:
|
||||
//
|
||||
// Leaf = Neither valid
|
||||
// ZeroOrOne, ZeroOrMore = First
|
||||
// Choice, Sequence, All = First and Second
|
||||
// Any* = Neither valid
|
||||
//
|
||||
// fType
|
||||
// The type of node. This controls how many of the child node fields
|
||||
// are used.
|
||||
//
|
||||
// fAdoptFirst
|
||||
// Indicate if this ContentSpecNode adopts the fFirst, and is responsible
|
||||
// for deleting it.
|
||||
//
|
||||
// fAdoptSecond
|
||||
// Indicate if this ContentSpecNode adopts the fSecond, and is responsible
|
||||
// for deleting it.
|
||||
//
|
||||
// fMinOccurs
|
||||
// Indicate the minimum times that this node can occur
|
||||
//
|
||||
// fMaxOccurs
|
||||
// Indicate the maximum times that this node can occur
|
||||
// -1 (Unbounded), default (1)
|
||||
// -----------------------------------------------------------------------
|
||||
MemoryManager* fMemoryManager;
|
||||
QName* fElement;
|
||||
XMLElementDecl* fElementDecl;
|
||||
ContentSpecNode* fFirst;
|
||||
ContentSpecNode* fSecond;
|
||||
NodeTypes fType;
|
||||
bool fAdoptFirst;
|
||||
bool fAdoptSecond;
|
||||
int fMinOccurs;
|
||||
int fMaxOccurs;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ContentSpecNode: Constructors and Destructor
|
||||
// ---------------------------------------------------------------------------
|
||||
inline ContentSpecNode::ContentSpecNode(MemoryManager* const manager) :
|
||||
|
||||
fMemoryManager(manager)
|
||||
, fElement(0)
|
||||
, fElementDecl(0)
|
||||
, fFirst(0)
|
||||
, fSecond(0)
|
||||
, fType(ContentSpecNode::Leaf)
|
||||
, fAdoptFirst(true)
|
||||
, fAdoptSecond(true)
|
||||
, fMinOccurs(1)
|
||||
, fMaxOccurs(1)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
ContentSpecNode::ContentSpecNode(QName* const element,
|
||||
MemoryManager* const manager) :
|
||||
|
||||
fMemoryManager(manager)
|
||||
, fElement(0)
|
||||
, fElementDecl(0)
|
||||
, fFirst(0)
|
||||
, fSecond(0)
|
||||
, fType(ContentSpecNode::Leaf)
|
||||
, fAdoptFirst(true)
|
||||
, fAdoptSecond(true)
|
||||
, fMinOccurs(1)
|
||||
, fMaxOccurs(1)
|
||||
{
|
||||
if (element)
|
||||
fElement = new (fMemoryManager) QName(*element);
|
||||
}
|
||||
|
||||
inline
|
||||
ContentSpecNode::ContentSpecNode(XMLElementDecl* const elemDecl,
|
||||
MemoryManager* const manager) :
|
||||
|
||||
fMemoryManager(manager)
|
||||
, fElement(0)
|
||||
, fElementDecl(elemDecl)
|
||||
, fFirst(0)
|
||||
, fSecond(0)
|
||||
, fType(ContentSpecNode::Leaf)
|
||||
, fAdoptFirst(true)
|
||||
, fAdoptSecond(true)
|
||||
, fMinOccurs(1)
|
||||
, fMaxOccurs(1)
|
||||
{
|
||||
if (elemDecl)
|
||||
fElement = new (manager) QName(*(elemDecl->getElementName()));
|
||||
}
|
||||
|
||||
inline
|
||||
ContentSpecNode::ContentSpecNode( QName* const element
|
||||
, const bool copyQName
|
||||
, MemoryManager* const manager) :
|
||||
|
||||
fMemoryManager(manager)
|
||||
, fElement(0)
|
||||
, fElementDecl(0)
|
||||
, fFirst(0)
|
||||
, fSecond(0)
|
||||
, fType(ContentSpecNode::Leaf)
|
||||
, fAdoptFirst(true)
|
||||
, fAdoptSecond(true)
|
||||
, fMinOccurs(1)
|
||||
, fMaxOccurs(1)
|
||||
{
|
||||
if (copyQName)
|
||||
{
|
||||
if (element)
|
||||
fElement = new (fMemoryManager) QName(*element);
|
||||
}
|
||||
else
|
||||
{
|
||||
fElement = element;
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
ContentSpecNode::ContentSpecNode(const NodeTypes type
|
||||
, ContentSpecNode* const firstAdopt
|
||||
, ContentSpecNode* const secondAdopt
|
||||
, const bool adoptFirst
|
||||
, const bool adoptSecond
|
||||
, MemoryManager* const manager) :
|
||||
|
||||
fMemoryManager(manager)
|
||||
, fElement(0)
|
||||
, fElementDecl(0)
|
||||
, fFirst(firstAdopt)
|
||||
, fSecond(secondAdopt)
|
||||
, fType(type)
|
||||
, fAdoptFirst(adoptFirst)
|
||||
, fAdoptSecond(adoptSecond)
|
||||
, fMinOccurs(1)
|
||||
, fMaxOccurs(1)
|
||||
{
|
||||
}
|
||||
|
||||
inline ContentSpecNode::~ContentSpecNode()
|
||||
{
|
||||
// Delete our children, which cause recursive cleanup
|
||||
if (fAdoptFirst) {
|
||||
delete fFirst;
|
||||
}
|
||||
|
||||
if (fAdoptSecond) {
|
||||
delete fSecond;
|
||||
}
|
||||
|
||||
delete fElement;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ContentSpecNode: Getter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
inline QName* ContentSpecNode::getElement()
|
||||
{
|
||||
return fElement;
|
||||
}
|
||||
|
||||
inline const QName* ContentSpecNode::getElement() const
|
||||
{
|
||||
return fElement;
|
||||
}
|
||||
|
||||
inline XMLElementDecl* ContentSpecNode::getElementDecl()
|
||||
{
|
||||
return fElementDecl;
|
||||
}
|
||||
|
||||
inline const XMLElementDecl* ContentSpecNode::getElementDecl() const
|
||||
{
|
||||
return fElementDecl;
|
||||
}
|
||||
|
||||
inline ContentSpecNode* ContentSpecNode::getFirst()
|
||||
{
|
||||
return fFirst;
|
||||
}
|
||||
|
||||
inline const ContentSpecNode* ContentSpecNode::getFirst() const
|
||||
{
|
||||
return fFirst;
|
||||
}
|
||||
|
||||
inline ContentSpecNode* ContentSpecNode::getSecond()
|
||||
{
|
||||
return fSecond;
|
||||
}
|
||||
|
||||
inline const ContentSpecNode* ContentSpecNode::getSecond() const
|
||||
{
|
||||
return fSecond;
|
||||
}
|
||||
|
||||
inline ContentSpecNode::NodeTypes ContentSpecNode::getType() const
|
||||
{
|
||||
return fType;
|
||||
}
|
||||
|
||||
inline ContentSpecNode* ContentSpecNode::orphanFirst()
|
||||
{
|
||||
ContentSpecNode* retNode = fFirst;
|
||||
fFirst = 0;
|
||||
return retNode;
|
||||
}
|
||||
|
||||
inline ContentSpecNode* ContentSpecNode::orphanSecond()
|
||||
{
|
||||
ContentSpecNode* retNode = fSecond;
|
||||
fSecond = 0;
|
||||
return retNode;
|
||||
}
|
||||
|
||||
inline int ContentSpecNode::getMinOccurs() const
|
||||
{
|
||||
return fMinOccurs;
|
||||
}
|
||||
|
||||
inline int ContentSpecNode::getMaxOccurs() const
|
||||
{
|
||||
return fMaxOccurs;
|
||||
}
|
||||
|
||||
inline bool ContentSpecNode::isFirstAdopted() const
|
||||
{
|
||||
return fAdoptFirst;
|
||||
}
|
||||
|
||||
inline bool ContentSpecNode::isSecondAdopted() const
|
||||
{
|
||||
return fAdoptSecond;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ContentSpecType: Setter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
inline void ContentSpecNode::setElement(QName* const element)
|
||||
{
|
||||
delete fElement;
|
||||
fElement = 0;
|
||||
if (element)
|
||||
fElement = new (fMemoryManager) QName(*element);
|
||||
}
|
||||
|
||||
inline void ContentSpecNode::setFirst(ContentSpecNode* const toAdopt)
|
||||
{
|
||||
if (fAdoptFirst)
|
||||
delete fFirst;
|
||||
fFirst = toAdopt;
|
||||
}
|
||||
|
||||
inline void ContentSpecNode::setSecond(ContentSpecNode* const toAdopt)
|
||||
{
|
||||
if (fAdoptSecond)
|
||||
delete fSecond;
|
||||
fSecond = toAdopt;
|
||||
}
|
||||
|
||||
inline void ContentSpecNode::setType(const NodeTypes type)
|
||||
{
|
||||
fType = type;
|
||||
}
|
||||
|
||||
inline void ContentSpecNode::setMinOccurs(int min)
|
||||
{
|
||||
fMinOccurs = min;
|
||||
}
|
||||
|
||||
inline void ContentSpecNode::setMaxOccurs(int max)
|
||||
{
|
||||
fMaxOccurs = max;
|
||||
}
|
||||
|
||||
inline void ContentSpecNode::setAdoptFirst(bool newState)
|
||||
{
|
||||
fAdoptFirst = newState;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: DFAContentModel.hpp 677705 2008-07-17 20:15:32Z amassari $
|
||||
*/
|
||||
|
||||
#if !defined(XERCESC_INCLUDE_GUARD_DFACONTENTMODEL_HPP)
|
||||
#define XERCESC_INCLUDE_GUARD_DFACONTENTMODEL_HPP
|
||||
|
||||
#include <xercesc/util/XercesDefs.hpp>
|
||||
#include <xercesc/util/ArrayIndexOutOfBoundsException.hpp>
|
||||
#include <xercesc/framework/XMLContentModel.hpp>
|
||||
#include <xercesc/validators/common/ContentLeafNameTypeVector.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
class ContentSpecNode;
|
||||
class CMLeaf;
|
||||
class CMRepeatingLeaf;
|
||||
class CMNode;
|
||||
class CMStateSet;
|
||||
|
||||
//
|
||||
// DFAContentModel is the heavy weight derivative of ContentModel that does
|
||||
// all of the non-trivial element content validation. This guy does the full
|
||||
// bore regular expression to DFA conversion to create a DFA that it then
|
||||
// uses in its validation algorithm.
|
||||
//
|
||||
// NOTE: Upstream work insures that this guy will never see a content model
|
||||
// with PCDATA in it. Any model with PCDATA is 'mixed' and is handled
|
||||
// via the MixedContentModel class, since mixed models are very
|
||||
// constrained in form and easily handled via a special case. This
|
||||
// also makes our life much easier here.
|
||||
//
|
||||
class DFAContentModel : public XMLContentModel
|
||||
{
|
||||
public:
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors and Destructor
|
||||
// -----------------------------------------------------------------------
|
||||
DFAContentModel
|
||||
(
|
||||
const bool dtd
|
||||
, ContentSpecNode* const elemContentSpec
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
DFAContentModel
|
||||
(
|
||||
const bool dtd
|
||||
, ContentSpecNode* const elemContentSpec
|
||||
, const bool isMixed
|
||||
, MemoryManager* const manager
|
||||
);
|
||||
|
||||
virtual ~DFAContentModel();
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Implementation of the virtual content model interface
|
||||
// -----------------------------------------------------------------------
|
||||
virtual bool validateContent
|
||||
(
|
||||
QName** const children
|
||||
, XMLSize_t childCount
|
||||
, unsigned int emptyNamespaceId
|
||||
, XMLSize_t* indexFailingChild
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
) const;
|
||||
|
||||
virtual bool validateContentSpecial
|
||||
(
|
||||
QName** const children
|
||||
, XMLSize_t childCount
|
||||
, unsigned int emptyNamespaceId
|
||||
, GrammarResolver* const pGrammarResolver
|
||||
, XMLStringPool* const pStringPool
|
||||
, XMLSize_t* indexFailingChild
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
) const;
|
||||
|
||||
virtual void checkUniqueParticleAttribution
|
||||
(
|
||||
SchemaGrammar* const pGrammar
|
||||
, GrammarResolver* const pGrammarResolver
|
||||
, XMLStringPool* const pStringPool
|
||||
, XMLValidator* const pValidator
|
||||
, unsigned int* const pContentSpecOrgURI
|
||||
, const XMLCh* pComplexTypeName = 0
|
||||
) ;
|
||||
|
||||
virtual ContentLeafNameTypeVector* getContentLeafNameTypeVector() const ;
|
||||
|
||||
virtual unsigned int getNextState(unsigned int currentState,
|
||||
XMLSize_t elementIndex) const;
|
||||
|
||||
virtual bool handleRepetitions( const QName* const curElem,
|
||||
unsigned int curState,
|
||||
unsigned int currentLoop,
|
||||
unsigned int& nextState,
|
||||
unsigned int& nextLoop,
|
||||
XMLSize_t elementIndex,
|
||||
SubstitutionGroupComparator * comparator) const;
|
||||
|
||||
private :
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
DFAContentModel();
|
||||
DFAContentModel(const DFAContentModel&);
|
||||
DFAContentModel& operator=(const DFAContentModel&);
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Private helper methods
|
||||
// -----------------------------------------------------------------------
|
||||
void buildDFA(ContentSpecNode* const curNode);
|
||||
CMNode* buildSyntaxTree(ContentSpecNode* const curNode, unsigned int& curIndex);
|
||||
unsigned int* makeDefStateList() const;
|
||||
unsigned int countLeafNodes(ContentSpecNode* const curNode);
|
||||
|
||||
class Occurence : public XMemory
|
||||
{
|
||||
public:
|
||||
Occurence(int minOcc, int maxOcc, int eltIndex);
|
||||
|
||||
int minOccurs;
|
||||
int maxOccurs;
|
||||
int elemIndex;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Private data members
|
||||
//
|
||||
// fElemMap
|
||||
// fElemMapSize
|
||||
// This is the map of unique input symbol elements to indices into
|
||||
// each state's per-input symbol transition table entry. This is part
|
||||
// of the built DFA information that must be kept around to do the
|
||||
// actual validation.
|
||||
//
|
||||
// fElemMapType
|
||||
// This is a map of whether the element map contains information
|
||||
// related to ANY models.
|
||||
//
|
||||
// fEmptyOk
|
||||
// This is an optimization. While building the transition table we
|
||||
// can see whether this content model would approve of an empty
|
||||
// content (which could happen if everything was optional.) So we
|
||||
// set this flag and short circuit that check, which would otherwise
|
||||
// be ugly and time consuming if we tried to determine it at each
|
||||
// validation call.
|
||||
//
|
||||
// fEOCPos
|
||||
// The NFA position of the special EOC (end of content) node. This
|
||||
// is saved away since its used during the DFA build.
|
||||
//
|
||||
// fFinalStateFlags
|
||||
// This is an array of booleans, one per state (there are
|
||||
// fTransTableSize states in the DFA) that indicates whether that
|
||||
// state is a final state.
|
||||
//
|
||||
// fFollowList
|
||||
// The list of follow positions for each NFA position (i.e. for each
|
||||
// non-epsilon leaf node.) This is only used during the building of
|
||||
// the DFA, and is let go afterwards.
|
||||
//
|
||||
// fHeadNode
|
||||
// This is the head node of our intermediate representation. It is
|
||||
// only non-null during the building of the DFA (just so that it
|
||||
// does not have to be passed all around.) Once the DFA is built,
|
||||
// this is no longer required so its deleted.
|
||||
//
|
||||
// fLeafCount
|
||||
// The count of leaf nodes. This is an important number that set some
|
||||
// limits on the sizes of data structures in the DFA process.
|
||||
//
|
||||
// fLeafList
|
||||
// An array of non-epsilon leaf nodes, which is used during the DFA
|
||||
// build operation, then dropped. These are just references to nodes
|
||||
// pointed to by fHeadNode, so we don't have to clean them up, just
|
||||
// the actually leaf list array itself needs cleanup.
|
||||
//
|
||||
// fLeafListType
|
||||
// Array mapping ANY types to the leaf list.
|
||||
//
|
||||
// fTransTable
|
||||
// fTransTableSize
|
||||
// This is the transition table that is the main by product of all
|
||||
// of the effort here. It is an array of arrays of ints. The first
|
||||
// dimension is the number of states we end up with in the DFA. The
|
||||
// second dimensions is the number of unique elements in the content
|
||||
// model (fElemMapSize). Each entry in the second dimension indicates
|
||||
// the new state given that input for the first dimension's start
|
||||
// state.
|
||||
//
|
||||
// The fElemMap array handles mapping from element indexes to
|
||||
// positions in the second dimension of the transition table.
|
||||
//
|
||||
// fTransTableSize is the number of valid entries in the transition
|
||||
// table, and in the other related tables such as fFinalStateFlags.
|
||||
//
|
||||
// fCountingStates
|
||||
// This is the table holding the minOccurs/maxOccurs for elements
|
||||
// that can be repeated a finite number of times.
|
||||
//
|
||||
// fDTD
|
||||
// Boolean to allow DTDs to validate even with namespace support.
|
||||
//
|
||||
// fIsMixed
|
||||
// DFA ContentModel with mixed PCDATA.
|
||||
// -----------------------------------------------------------------------
|
||||
QName** fElemMap;
|
||||
ContentSpecNode::NodeTypes* fElemMapType;
|
||||
unsigned int fElemMapSize;
|
||||
bool fEmptyOk;
|
||||
unsigned int fEOCPos;
|
||||
bool* fFinalStateFlags;
|
||||
CMStateSet** fFollowList;
|
||||
CMNode* fHeadNode;
|
||||
unsigned int fLeafCount;
|
||||
CMLeaf** fLeafList;
|
||||
ContentSpecNode::NodeTypes* fLeafListType;
|
||||
unsigned int** fTransTable;
|
||||
unsigned int fTransTableSize;
|
||||
Occurence** fCountingStates;
|
||||
bool fDTD;
|
||||
bool fIsMixed;
|
||||
ContentLeafNameTypeVector * fLeafNameTypeVector;
|
||||
MemoryManager* fMemoryManager;
|
||||
};
|
||||
|
||||
|
||||
inline unsigned int
|
||||
DFAContentModel::getNextState(unsigned int currentState,
|
||||
XMLSize_t elementIndex) const {
|
||||
|
||||
if (currentState == XMLContentModel::gInvalidTrans) {
|
||||
return XMLContentModel::gInvalidTrans;
|
||||
}
|
||||
|
||||
if (currentState >= fTransTableSize || elementIndex >= fElemMapSize) {
|
||||
ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Array_BadIndex, fMemoryManager);
|
||||
}
|
||||
|
||||
return fTransTable[currentState][elementIndex];
|
||||
}
|
||||
|
||||
inline
|
||||
DFAContentModel::Occurence::Occurence(int minOcc, int maxOcc, int eltIndex)
|
||||
{
|
||||
minOccurs = minOcc;
|
||||
maxOccurs = maxOcc;
|
||||
elemIndex = eltIndex;
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: Grammar.cpp 471747 2006-11-06 14:31:56Z amassari $
|
||||
*/
|
||||
|
||||
#include <xercesc/validators/common/Grammar.hpp>
|
||||
|
||||
//since we need to dynamically created each and every derivatives
|
||||
//during deserialization by XSerializeEngine>>Derivative, we got
|
||||
//to include all hpp
|
||||
|
||||
#include <xercesc/validators/DTD/DTDGrammar.hpp>
|
||||
#include <xercesc/validators/schema/SchemaGrammar.hpp>
|
||||
#include <xercesc/framework/psvi/XSAnnotation.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
/***
|
||||
* Support for Serialization/De-serialization
|
||||
***/
|
||||
|
||||
IMPL_XSERIALIZABLE_NOCREATE(Grammar)
|
||||
|
||||
void Grammar::serialize(XSerializeEngine&)
|
||||
{
|
||||
//no data
|
||||
}
|
||||
|
||||
void Grammar::storeGrammar(XSerializeEngine& serEng
|
||||
, Grammar* const grammar)
|
||||
{
|
||||
if (grammar)
|
||||
{
|
||||
serEng<<(int) grammar->getGrammarType();
|
||||
serEng<<grammar;
|
||||
}
|
||||
else
|
||||
{
|
||||
serEng<<(int) UnKnown;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Grammar* Grammar::loadGrammar(XSerializeEngine& serEng)
|
||||
{
|
||||
|
||||
int type;
|
||||
serEng>>type;
|
||||
|
||||
switch((GrammarType)type)
|
||||
{
|
||||
case DTDGrammarType:
|
||||
DTDGrammar* dtdGrammar;
|
||||
serEng>>dtdGrammar;
|
||||
return dtdGrammar;
|
||||
case SchemaGrammarType:
|
||||
SchemaGrammar* schemaGrammar;
|
||||
serEng>>schemaGrammar;
|
||||
return schemaGrammar;
|
||||
case UnKnown:
|
||||
return 0;
|
||||
default: //we treat this same as UnKnown
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: Grammar.hpp 676911 2008-07-15 13:27:32Z amassari $
|
||||
*/
|
||||
|
||||
#if !defined(XERCESC_INCLUDE_GUARD_GRAMMAR_HPP)
|
||||
#define XERCESC_INCLUDE_GUARD_GRAMMAR_HPP
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <xercesc/framework/XMLElementDecl.hpp>
|
||||
#include <xercesc/framework/XMLEntityDecl.hpp>
|
||||
#include <xercesc/framework/XMLNotationDecl.hpp>
|
||||
|
||||
#include <xercesc/internal/XSerializable.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
class XMLGrammarDescription;
|
||||
|
||||
//
|
||||
// This abstract class specifies the interface for a Grammar
|
||||
//
|
||||
|
||||
class VALIDATORS_EXPORT Grammar : public XSerializable, public XMemory
|
||||
{
|
||||
public:
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Class Specific Types
|
||||
//
|
||||
// DTDGrammarType - Indicate this Grammar is built from a DTD.
|
||||
// SchemaGrammarType - Indicate this Grammar is built from a Schema.
|
||||
//
|
||||
// TOP_LEVEL_SCOPE - outermost scope level (i.e. global) of a declaration.
|
||||
// For DTD, all element decls and attribute decls always
|
||||
// have TOP_LEVEL_SCOPE. For schema, it may vary if
|
||||
// it is inside a complex type.
|
||||
//
|
||||
// UNKNOWN_SCOPE - unknown scope level. None of the decls should have this.
|
||||
//
|
||||
// -----------------------------------------------------------------------
|
||||
enum GrammarType {
|
||||
DTDGrammarType
|
||||
, SchemaGrammarType
|
||||
, UnKnown
|
||||
};
|
||||
|
||||
enum {
|
||||
// These are well-known values that must simply be larger
|
||||
// than any reasonable scope
|
||||
UNKNOWN_SCOPE = UINT_MAX - 0
|
||||
, TOP_LEVEL_SCOPE = UINT_MAX - 1
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors and Destructor
|
||||
// -----------------------------------------------------------------------
|
||||
virtual ~Grammar(){};
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Virtual Getter methods
|
||||
// -----------------------------------------------------------------------
|
||||
virtual GrammarType getGrammarType() const =0;
|
||||
virtual const XMLCh* getTargetNamespace() const =0;
|
||||
virtual bool getValidated() const = 0;
|
||||
|
||||
// Element Decl
|
||||
|
||||
// this method should only be used while the grammar is being
|
||||
// constructed, not while it is being used
|
||||
// in a validation episode!
|
||||
virtual XMLElementDecl* findOrAddElemDecl
|
||||
(
|
||||
const unsigned int uriId
|
||||
, const XMLCh* const baseName
|
||||
, const XMLCh* const prefixName
|
||||
, const XMLCh* const qName
|
||||
, unsigned int scope
|
||||
, bool& wasAdded
|
||||
) = 0;
|
||||
|
||||
virtual XMLSize_t getElemId
|
||||
(
|
||||
const unsigned int uriId
|
||||
, const XMLCh* const baseName
|
||||
, const XMLCh* const qName
|
||||
, unsigned int scope
|
||||
) const = 0;
|
||||
|
||||
virtual const XMLElementDecl* getElemDecl
|
||||
(
|
||||
const unsigned int uriId
|
||||
, const XMLCh* const baseName
|
||||
, const XMLCh* const qName
|
||||
, unsigned int scope
|
||||
) const = 0;
|
||||
|
||||
virtual XMLElementDecl* getElemDecl
|
||||
(
|
||||
const unsigned int uriId
|
||||
, const XMLCh* const baseName
|
||||
, const XMLCh* const qName
|
||||
, unsigned int scope
|
||||
) = 0;
|
||||
|
||||
virtual const XMLElementDecl* getElemDecl
|
||||
(
|
||||
const unsigned int elemId
|
||||
) const = 0;
|
||||
|
||||
virtual XMLElementDecl* getElemDecl
|
||||
(
|
||||
const unsigned int elemId
|
||||
) = 0;
|
||||
|
||||
// Notation
|
||||
virtual const XMLNotationDecl* getNotationDecl
|
||||
(
|
||||
const XMLCh* const notName
|
||||
) const=0;
|
||||
|
||||
virtual XMLNotationDecl* getNotationDecl
|
||||
(
|
||||
const XMLCh* const notName
|
||||
)=0;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Virtual Setter methods
|
||||
// -----------------------------------------------------------------------
|
||||
virtual XMLElementDecl* putElemDecl
|
||||
(
|
||||
const unsigned int uriId
|
||||
, const XMLCh* const baseName
|
||||
, const XMLCh* const prefixName
|
||||
, const XMLCh* const qName
|
||||
, unsigned int scope
|
||||
, const bool notDeclared = false
|
||||
) = 0;
|
||||
|
||||
virtual XMLSize_t putElemDecl
|
||||
(
|
||||
XMLElementDecl* const elemDecl
|
||||
, const bool notDeclared = false
|
||||
) = 0;
|
||||
|
||||
virtual XMLSize_t putNotationDecl
|
||||
(
|
||||
XMLNotationDecl* const notationDecl
|
||||
) const=0;
|
||||
|
||||
virtual void setValidated(const bool newState) = 0;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Virtual methods
|
||||
// -----------------------------------------------------------------------
|
||||
virtual void reset()=0;
|
||||
|
||||
virtual void setGrammarDescription( XMLGrammarDescription*) = 0;
|
||||
virtual XMLGrammarDescription* getGrammarDescription() const = 0;
|
||||
|
||||
/***
|
||||
* Support for Serialization/De-serialization
|
||||
***/
|
||||
DECL_XSERIALIZABLE(Grammar)
|
||||
|
||||
static void storeGrammar(XSerializeEngine& serEng
|
||||
, Grammar* const grammar);
|
||||
|
||||
static Grammar* loadGrammar(XSerializeEngine& serEng);
|
||||
|
||||
protected :
|
||||
// -----------------------------------------------------------------------
|
||||
// Hidden constructors
|
||||
// -----------------------------------------------------------------------
|
||||
Grammar(){};
|
||||
|
||||
private:
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
Grammar(const Grammar&);
|
||||
Grammar& operator=(const Grammar&);
|
||||
};
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,445 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id $
|
||||
*/
|
||||
|
||||
#include <xercesc/validators/common/GrammarResolver.hpp>
|
||||
#include <xercesc/validators/schema/SchemaSymbols.hpp>
|
||||
#include <xercesc/validators/schema/SchemaGrammar.hpp>
|
||||
#include <xercesc/validators/schema/XMLSchemaDescriptionImpl.hpp>
|
||||
#include <xercesc/validators/DTD/XMLDTDDescriptionImpl.hpp>
|
||||
#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
|
||||
#include <xercesc/framework/psvi/XSAnnotation.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GrammarResolver: Constructor and Destructor
|
||||
// ---------------------------------------------------------------------------
|
||||
GrammarResolver::GrammarResolver(XMLGrammarPool* const gramPool
|
||||
, MemoryManager* const manager)
|
||||
:fCacheGrammar(false)
|
||||
,fUseCachedGrammar(false)
|
||||
,fGrammarPoolFromExternalApplication(true)
|
||||
,fStringPool(0)
|
||||
,fGrammarBucket(0)
|
||||
,fGrammarFromPool(0)
|
||||
,fDataTypeReg(0)
|
||||
,fMemoryManager(manager)
|
||||
,fGrammarPool(gramPool)
|
||||
,fXSModel(0)
|
||||
,fGrammarPoolXSModel(0)
|
||||
,fGrammarsToAddToXSModel(0)
|
||||
{
|
||||
fGrammarBucket = new (manager) RefHashTableOf<Grammar>(29, true, manager);
|
||||
|
||||
/***
|
||||
* Grammars in this set are not owned
|
||||
*/
|
||||
fGrammarFromPool = new (manager) RefHashTableOf<Grammar>(29, false, manager);
|
||||
|
||||
if (!gramPool)
|
||||
{
|
||||
/***
|
||||
* We need to instantiate a default grammar pool object so that
|
||||
* all grammars and grammar components could be created through
|
||||
* the Factory methods
|
||||
*/
|
||||
fGrammarPool = new (manager) XMLGrammarPoolImpl(manager);
|
||||
fGrammarPoolFromExternalApplication=false;
|
||||
}
|
||||
fStringPool = fGrammarPool->getURIStringPool();
|
||||
|
||||
// REVISIT: size
|
||||
fGrammarsToAddToXSModel = new (manager) ValueVectorOf<SchemaGrammar*> (29, manager);
|
||||
}
|
||||
|
||||
GrammarResolver::~GrammarResolver()
|
||||
{
|
||||
delete fGrammarBucket;
|
||||
delete fGrammarFromPool;
|
||||
|
||||
if (fDataTypeReg)
|
||||
delete fDataTypeReg;
|
||||
|
||||
/***
|
||||
* delete the grammar pool iff it is created by this resolver
|
||||
*/
|
||||
if (!fGrammarPoolFromExternalApplication)
|
||||
delete fGrammarPool;
|
||||
|
||||
if (fXSModel)
|
||||
delete fXSModel;
|
||||
// don't delete fGrammarPoolXSModel! we don't own it!
|
||||
delete fGrammarsToAddToXSModel;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GrammarResolver: Getter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
DatatypeValidator*
|
||||
GrammarResolver::getDatatypeValidator(const XMLCh* const uriStr,
|
||||
const XMLCh* const localPartStr) {
|
||||
|
||||
DatatypeValidator* dv = 0;
|
||||
|
||||
if (XMLString::equals(uriStr, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {
|
||||
|
||||
if (!fDataTypeReg) {
|
||||
|
||||
fDataTypeReg = new (fMemoryManager) DatatypeValidatorFactory(fMemoryManager);
|
||||
}
|
||||
|
||||
dv = fDataTypeReg->getDatatypeValidator(localPartStr);
|
||||
}
|
||||
else {
|
||||
|
||||
Grammar* grammar = getGrammar(uriStr);
|
||||
|
||||
if (grammar && grammar->getGrammarType() == Grammar::SchemaGrammarType) {
|
||||
|
||||
XMLBuffer nameBuf(128, fMemoryManager);
|
||||
|
||||
nameBuf.set(uriStr);
|
||||
nameBuf.append(chComma);
|
||||
nameBuf.append(localPartStr);
|
||||
|
||||
dv = ((SchemaGrammar*) grammar)->getDatatypeRegistry()->getDatatypeValidator(nameBuf.getRawBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
return dv;
|
||||
}
|
||||
|
||||
Grammar* GrammarResolver::getGrammar( const XMLCh* const namespaceKey)
|
||||
{
|
||||
if (!namespaceKey)
|
||||
return 0;
|
||||
|
||||
Grammar* grammar = fGrammarBucket->get(namespaceKey);
|
||||
|
||||
if (grammar)
|
||||
return grammar;
|
||||
|
||||
if (fUseCachedGrammar)
|
||||
{
|
||||
grammar = fGrammarFromPool->get(namespaceKey);
|
||||
if (grammar)
|
||||
{
|
||||
return grammar;
|
||||
}
|
||||
else
|
||||
{
|
||||
XMLSchemaDescription* gramDesc = fGrammarPool->createSchemaDescription(namespaceKey);
|
||||
Janitor<XMLGrammarDescription> janName(gramDesc);
|
||||
grammar = fGrammarPool->retrieveGrammar(gramDesc);
|
||||
if (grammar)
|
||||
{
|
||||
fGrammarFromPool->put((void*) grammar->getGrammarDescription()->getGrammarKey(), grammar);
|
||||
}
|
||||
return grammar;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Grammar* GrammarResolver::getGrammar( XMLGrammarDescription* const gramDesc)
|
||||
{
|
||||
if (!gramDesc)
|
||||
return 0;
|
||||
|
||||
Grammar* grammar = fGrammarBucket->get(gramDesc->getGrammarKey());
|
||||
|
||||
if (grammar)
|
||||
return grammar;
|
||||
|
||||
if (fUseCachedGrammar)
|
||||
{
|
||||
grammar = fGrammarFromPool->get(gramDesc->getGrammarKey());
|
||||
if (grammar)
|
||||
{
|
||||
return grammar;
|
||||
}
|
||||
else
|
||||
{
|
||||
grammar = fGrammarPool->retrieveGrammar(gramDesc);
|
||||
if (grammar)
|
||||
{
|
||||
fGrammarFromPool->put((void*) grammar->getGrammarDescription()->getGrammarKey(), grammar);
|
||||
}
|
||||
return grammar;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
RefHashTableOfEnumerator<Grammar>
|
||||
GrammarResolver::getGrammarEnumerator() const
|
||||
{
|
||||
return RefHashTableOfEnumerator<Grammar>(fGrammarBucket, false, fMemoryManager);
|
||||
}
|
||||
|
||||
RefHashTableOfEnumerator<Grammar>
|
||||
GrammarResolver::getReferencedGrammarEnumerator() const
|
||||
{
|
||||
return RefHashTableOfEnumerator<Grammar>(fGrammarFromPool, false, fMemoryManager);
|
||||
}
|
||||
|
||||
RefHashTableOfEnumerator<Grammar>
|
||||
GrammarResolver::getCachedGrammarEnumerator() const
|
||||
{
|
||||
return fGrammarPool->getGrammarEnumerator();
|
||||
}
|
||||
|
||||
bool GrammarResolver::containsNameSpace( const XMLCh* const nameSpaceKey )
|
||||
{
|
||||
if (!nameSpaceKey)
|
||||
return false;
|
||||
if (fGrammarBucket->containsKey(nameSpaceKey))
|
||||
return true;
|
||||
if (fUseCachedGrammar)
|
||||
{
|
||||
if (fGrammarFromPool->containsKey(nameSpaceKey))
|
||||
return true;
|
||||
|
||||
// Lastly, need to check in fGrammarPool
|
||||
XMLSchemaDescription* gramDesc = fGrammarPool->createSchemaDescription(nameSpaceKey);
|
||||
Janitor<XMLGrammarDescription> janName(gramDesc);
|
||||
Grammar* grammar = fGrammarPool->retrieveGrammar(gramDesc);
|
||||
if (grammar)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GrammarResolver::putGrammar(Grammar* const grammarToAdopt)
|
||||
{
|
||||
if (!grammarToAdopt)
|
||||
return;
|
||||
|
||||
/***
|
||||
* the grammar will be either in the grammarpool, or in the grammarbucket
|
||||
*/
|
||||
if (!fCacheGrammar || !fGrammarPool->cacheGrammar(grammarToAdopt))
|
||||
{
|
||||
// either we aren't caching or the grammar pool doesn't want it
|
||||
// so we need to look after it
|
||||
fGrammarBucket->put( (void*) grammarToAdopt->getGrammarDescription()->getGrammarKey(), grammarToAdopt );
|
||||
if (grammarToAdopt->getGrammarType() == Grammar::SchemaGrammarType)
|
||||
{
|
||||
fGrammarsToAddToXSModel->addElement((SchemaGrammar*) grammarToAdopt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GrammarResolver: methods
|
||||
// ---------------------------------------------------------------------------
|
||||
void GrammarResolver::reset() {
|
||||
fGrammarBucket->removeAll();
|
||||
fGrammarsToAddToXSModel->removeAllElements();
|
||||
delete fXSModel;
|
||||
fXSModel = 0;
|
||||
}
|
||||
|
||||
void GrammarResolver::resetCachedGrammar()
|
||||
{
|
||||
//REVISIT: if the pool is locked this will fail... should throw an exception?
|
||||
fGrammarPool->clear();
|
||||
// Even though fXSModel and fGrammarPoolXSModel will be invalid don't touch
|
||||
// them here as getXSModel will handle this.
|
||||
|
||||
//to clear all other references to the grammars just deleted from fGrammarPool
|
||||
fGrammarFromPool->removeAll();
|
||||
|
||||
}
|
||||
|
||||
void GrammarResolver::cacheGrammars()
|
||||
{
|
||||
RefHashTableOfEnumerator<Grammar> grammarEnum(fGrammarBucket, false, fMemoryManager);
|
||||
ValueVectorOf<XMLCh*> keys(8, fMemoryManager);
|
||||
unsigned int keyCount = 0;
|
||||
|
||||
// Build key set
|
||||
while (grammarEnum.hasMoreElements())
|
||||
{
|
||||
XMLCh* grammarKey = (XMLCh*) grammarEnum.nextElementKey();
|
||||
keys.addElement(grammarKey);
|
||||
keyCount++;
|
||||
}
|
||||
|
||||
// PSVI: assume everything will be added, if caching fails add grammar back
|
||||
// into vector
|
||||
fGrammarsToAddToXSModel->removeAllElements();
|
||||
|
||||
// Cache
|
||||
for (unsigned int i = 0; i < keyCount; i++)
|
||||
{
|
||||
XMLCh* grammarKey = keys.elementAt(i);
|
||||
|
||||
/***
|
||||
* It is up to the GrammarPool implementation to handle duplicated grammar
|
||||
*/
|
||||
Grammar* grammar = fGrammarBucket->get(grammarKey);
|
||||
if(fGrammarPool->cacheGrammar(grammar))
|
||||
{
|
||||
// only orphan grammar if grammar pool accepts caching of it
|
||||
fGrammarBucket->orphanKey(grammarKey);
|
||||
}
|
||||
else if (grammar->getGrammarType() == Grammar::SchemaGrammarType)
|
||||
{
|
||||
// add it back to list of grammars not in grammar pool
|
||||
fGrammarsToAddToXSModel->addElement((SchemaGrammar*) grammar);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GrammarResolver: Setter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
void GrammarResolver::cacheGrammarFromParse(const bool aValue)
|
||||
{
|
||||
reset();
|
||||
fCacheGrammar = aValue;
|
||||
}
|
||||
|
||||
Grammar* GrammarResolver::orphanGrammar(const XMLCh* const nameSpaceKey)
|
||||
{
|
||||
if (fCacheGrammar)
|
||||
{
|
||||
Grammar* grammar = fGrammarPool->orphanGrammar(nameSpaceKey);
|
||||
if (grammar)
|
||||
{
|
||||
if (fGrammarFromPool->containsKey(nameSpaceKey))
|
||||
fGrammarFromPool->removeKey(nameSpaceKey);
|
||||
}
|
||||
// Check to see if it's in fGrammarBucket, since
|
||||
// we put it there if the grammar pool refused to
|
||||
// cache it.
|
||||
else if (fGrammarBucket->containsKey(nameSpaceKey))
|
||||
{
|
||||
grammar = fGrammarBucket->orphanKey(nameSpaceKey);
|
||||
}
|
||||
|
||||
return grammar;
|
||||
}
|
||||
else
|
||||
{
|
||||
return fGrammarBucket->orphanKey(nameSpaceKey);
|
||||
}
|
||||
}
|
||||
|
||||
XSModel *GrammarResolver::getXSModel()
|
||||
{
|
||||
XSModel* xsModel;
|
||||
if (fCacheGrammar || fUseCachedGrammar)
|
||||
{
|
||||
// We know if the grammarpool changed thru caching, orphaning and erasing
|
||||
// but NOT by other mechanisms such as lockPool() or unlockPool() so it
|
||||
// is safest to always get it. The grammarPool XSModel will only be
|
||||
// regenerated if something changed.
|
||||
bool XSModelWasChanged;
|
||||
// The grammarpool will always return an xsmodel, even if it is just
|
||||
// the schema for schema xsmodel...
|
||||
xsModel = fGrammarPool->getXSModel(XSModelWasChanged);
|
||||
if (XSModelWasChanged)
|
||||
{
|
||||
// we know the grammarpool XSModel has changed or this is the
|
||||
// first call to getXSModel
|
||||
if (!fGrammarPoolXSModel && (fGrammarsToAddToXSModel->size() == 0) &&
|
||||
!fXSModel)
|
||||
{
|
||||
fGrammarPoolXSModel = xsModel;
|
||||
return fGrammarPoolXSModel;
|
||||
}
|
||||
else
|
||||
{
|
||||
fGrammarPoolXSModel = xsModel;
|
||||
// We had previously augmented the grammar pool XSModel
|
||||
// with our our grammars or we would like to upate it now
|
||||
// so we have to regenerate the XSModel
|
||||
fGrammarsToAddToXSModel->removeAllElements();
|
||||
RefHashTableOfEnumerator<Grammar> grammarEnum(fGrammarBucket, false, fMemoryManager);
|
||||
while (grammarEnum.hasMoreElements())
|
||||
{
|
||||
Grammar& grammar = (Grammar&) grammarEnum.nextElement();
|
||||
if (grammar.getGrammarType() == Grammar::SchemaGrammarType)
|
||||
fGrammarsToAddToXSModel->addElement((SchemaGrammar*)&grammar);
|
||||
}
|
||||
delete fXSModel;
|
||||
if (fGrammarsToAddToXSModel->size())
|
||||
{
|
||||
fXSModel = new (fMemoryManager) XSModel(fGrammarPoolXSModel, this, fMemoryManager);
|
||||
fGrammarsToAddToXSModel->removeAllElements();
|
||||
return fXSModel;
|
||||
}
|
||||
fXSModel = 0;
|
||||
return fGrammarPoolXSModel;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// we know that the grammar pool XSModel is the same as before
|
||||
if (fGrammarsToAddToXSModel->size())
|
||||
{
|
||||
// we need to update our fXSModel with the new grammars
|
||||
if (fXSModel)
|
||||
{
|
||||
xsModel = new (fMemoryManager) XSModel(fXSModel, this, fMemoryManager);
|
||||
fXSModel = xsModel;
|
||||
}
|
||||
else
|
||||
{
|
||||
fXSModel = new (fMemoryManager) XSModel(fGrammarPoolXSModel, this, fMemoryManager);
|
||||
}
|
||||
fGrammarsToAddToXSModel->removeAllElements();
|
||||
return fXSModel;
|
||||
}
|
||||
// Nothing has changed!
|
||||
if (fXSModel)
|
||||
{
|
||||
return fXSModel;
|
||||
}
|
||||
else if (fGrammarPoolXSModel)
|
||||
{
|
||||
return fGrammarPoolXSModel;
|
||||
}
|
||||
fXSModel = new (fMemoryManager) XSModel(0, this, fMemoryManager);
|
||||
return fXSModel;
|
||||
}
|
||||
}
|
||||
// Not Caching...
|
||||
if (fGrammarsToAddToXSModel->size())
|
||||
{
|
||||
xsModel = new (fMemoryManager) XSModel(fXSModel, this, fMemoryManager);
|
||||
fGrammarsToAddToXSModel->removeAllElements();
|
||||
fXSModel = xsModel;
|
||||
}
|
||||
else if (!fXSModel)
|
||||
{
|
||||
// create a new model only if we didn't have one already
|
||||
fXSModel = new (fMemoryManager) XSModel(0, this, fMemoryManager);
|
||||
}
|
||||
return fXSModel;
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: GrammarResolver.hpp 932887 2010-04-11 13:04:59Z borisk $
|
||||
*/
|
||||
|
||||
#if !defined(XERCESC_INCLUDE_GUARD_GRAMMARRESOLVER_HPP)
|
||||
#define XERCESC_INCLUDE_GUARD_GRAMMARRESOLVER_HPP
|
||||
|
||||
#include <xercesc/framework/XMLGrammarPool.hpp>
|
||||
#include <xercesc/util/RefHashTableOf.hpp>
|
||||
#include <xercesc/util/StringPool.hpp>
|
||||
#include <xercesc/validators/common/Grammar.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
class DatatypeValidator;
|
||||
class DatatypeValidatorFactory;
|
||||
class XMLGrammarDescription;
|
||||
|
||||
/**
|
||||
* This class embodies the representation of a Grammar pool Resolver.
|
||||
* This class is called from the validator.
|
||||
*
|
||||
*/
|
||||
|
||||
class VALIDATORS_EXPORT GrammarResolver : public XMemory
|
||||
{
|
||||
public:
|
||||
|
||||
/** @name Constructor and Destructor */
|
||||
//@{
|
||||
/**
|
||||
*
|
||||
* Default Constructor
|
||||
*/
|
||||
GrammarResolver(
|
||||
XMLGrammarPool* const gramPool
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~GrammarResolver();
|
||||
|
||||
//@}
|
||||
|
||||
/** @name Getter methods */
|
||||
//@{
|
||||
/**
|
||||
* Retrieve the DatatypeValidator
|
||||
*
|
||||
* @param uriStr the namespace URI
|
||||
* @param typeName the type name
|
||||
* @return the DatatypeValidator associated with namespace & type name
|
||||
*/
|
||||
DatatypeValidator* getDatatypeValidator(const XMLCh* const uriStr,
|
||||
const XMLCh* const typeName);
|
||||
|
||||
/**
|
||||
* Retrieve the DatatypeValidatorFactory used for built-in schema types
|
||||
*
|
||||
* @return the DatatypeValidator associated with namespace for XMLSchema
|
||||
*/
|
||||
DatatypeValidatorFactory* getBuiltinDatatypeValidatorFactory();
|
||||
|
||||
/**
|
||||
* Retrieve the grammar that is associated with the specified namespace key
|
||||
*
|
||||
* @param gramDesc grammar description for the grammar
|
||||
* @return Grammar abstraction associated with the grammar description
|
||||
*/
|
||||
Grammar* getGrammar( XMLGrammarDescription* const gramDesc ) ;
|
||||
|
||||
/**
|
||||
* Retrieve the grammar that is associated with the specified namespace key
|
||||
*
|
||||
* @param namespaceKey Namespace key into Grammar pool
|
||||
* @return Grammar abstraction associated with the NameSpace key.
|
||||
*/
|
||||
Grammar* getGrammar( const XMLCh* const namespaceKey ) ;
|
||||
|
||||
/**
|
||||
* Get an enumeration of Grammar in the Grammar pool
|
||||
*
|
||||
* @return enumeration of Grammar in Grammar pool
|
||||
*/
|
||||
RefHashTableOfEnumerator<Grammar> getGrammarEnumerator() const;
|
||||
|
||||
/**
|
||||
* Get an enumeration of the referenced Grammars
|
||||
*
|
||||
* @return enumeration of referenced Grammars
|
||||
*/
|
||||
RefHashTableOfEnumerator<Grammar> getReferencedGrammarEnumerator() const;
|
||||
|
||||
/**
|
||||
* Get an enumeration of the cached Grammars in the Grammar pool
|
||||
*
|
||||
* @return enumeration of the cached Grammars in Grammar pool
|
||||
*/
|
||||
RefHashTableOfEnumerator<Grammar> getCachedGrammarEnumerator() const;
|
||||
|
||||
/**
|
||||
* Get a string pool of schema grammar element/attribute names/prefixes
|
||||
* (used by TraverseSchema)
|
||||
*
|
||||
* @return a string pool of schema grammar element/attribute names/prefixes
|
||||
*/
|
||||
XMLStringPool* getStringPool();
|
||||
|
||||
/**
|
||||
* Is the specified Namespace key in Grammar pool?
|
||||
*
|
||||
* @param nameSpaceKey Namespace key
|
||||
* @return True if Namespace key association is in the Grammar pool.
|
||||
*/
|
||||
bool containsNameSpace( const XMLCh* const nameSpaceKey );
|
||||
|
||||
inline XMLGrammarPool* getGrammarPool() const;
|
||||
|
||||
inline MemoryManager* getGrammarPoolMemoryManager() const;
|
||||
|
||||
//@}
|
||||
|
||||
/** @name Setter methods */
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Set the 'Grammar caching' flag
|
||||
*/
|
||||
void cacheGrammarFromParse(const bool newState);
|
||||
|
||||
/**
|
||||
* Set the 'Use cached grammar' flag
|
||||
*/
|
||||
void useCachedGrammarInParse(const bool newState);
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
/** @name GrammarResolver methods */
|
||||
//@{
|
||||
/**
|
||||
* Add the Grammar with Namespace Key associated to the Grammar Pool.
|
||||
* The Grammar will be owned by the Grammar Pool.
|
||||
*
|
||||
* @param grammarToAdopt Grammar abstraction used by validator.
|
||||
*/
|
||||
void putGrammar(Grammar* const grammarToAdopt );
|
||||
|
||||
/**
|
||||
* Returns the Grammar with Namespace Key associated from the Grammar Pool
|
||||
* The Key entry is removed from the table (grammar is not deleted if
|
||||
* adopted - now owned by caller).
|
||||
*
|
||||
* @param nameSpaceKey Key to associate with Grammar abstraction
|
||||
*/
|
||||
Grammar* orphanGrammar(const XMLCh* const nameSpaceKey);
|
||||
|
||||
/**
|
||||
* Cache the grammars in fGrammarBucket to fCachedGrammarRegistry.
|
||||
* If a grammar with the same key is already cached, an exception is
|
||||
* thrown and none of the grammars will be cached.
|
||||
*/
|
||||
void cacheGrammars();
|
||||
|
||||
/**
|
||||
* Reset internal Namespace/Grammar registry.
|
||||
*/
|
||||
void reset();
|
||||
void resetCachedGrammar();
|
||||
|
||||
/**
|
||||
* Returns an XSModel, either from the GrammarPool or by creating one
|
||||
*/
|
||||
XSModel* getXSModel();
|
||||
|
||||
|
||||
ValueVectorOf<SchemaGrammar*>* getGrammarsToAddToXSModel();
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
GrammarResolver(const GrammarResolver&);
|
||||
GrammarResolver& operator=(const GrammarResolver&);
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Private data members
|
||||
//
|
||||
// fStringPool The string pool used by TraverseSchema to store
|
||||
// element/attribute names and prefixes.
|
||||
// Always owned by Grammar pool implementation
|
||||
//
|
||||
// fGrammarBucket The parsed Grammar Pool, if no caching option.
|
||||
//
|
||||
// fGrammarFromPool Referenced Grammar Set, not owned
|
||||
//
|
||||
// fGrammarPool The Grammar Set either plugged or created.
|
||||
//
|
||||
// fDataTypeReg DatatypeValidatorFactory registry
|
||||
//
|
||||
// fMemoryManager Pluggable memory manager for dynamic memory
|
||||
// allocation/deallocation
|
||||
// -----------------------------------------------------------------------
|
||||
bool fCacheGrammar;
|
||||
bool fUseCachedGrammar;
|
||||
bool fGrammarPoolFromExternalApplication;
|
||||
XMLStringPool* fStringPool;
|
||||
RefHashTableOf<Grammar>* fGrammarBucket;
|
||||
RefHashTableOf<Grammar>* fGrammarFromPool;
|
||||
DatatypeValidatorFactory* fDataTypeReg;
|
||||
MemoryManager* fMemoryManager;
|
||||
XMLGrammarPool* fGrammarPool;
|
||||
XSModel* fXSModel;
|
||||
XSModel* fGrammarPoolXSModel;
|
||||
ValueVectorOf<SchemaGrammar*>* fGrammarsToAddToXSModel;
|
||||
};
|
||||
|
||||
inline XMLStringPool* GrammarResolver::getStringPool() {
|
||||
|
||||
return fStringPool;
|
||||
}
|
||||
|
||||
|
||||
inline void GrammarResolver::useCachedGrammarInParse(const bool aValue)
|
||||
{
|
||||
fUseCachedGrammar = aValue;
|
||||
}
|
||||
|
||||
inline XMLGrammarPool* GrammarResolver::getGrammarPool() const
|
||||
{
|
||||
return fGrammarPool;
|
||||
}
|
||||
|
||||
inline MemoryManager* GrammarResolver::getGrammarPoolMemoryManager() const
|
||||
{
|
||||
return fGrammarPool->getMemoryManager();
|
||||
}
|
||||
|
||||
inline ValueVectorOf<SchemaGrammar*>* GrammarResolver::getGrammarsToAddToXSModel()
|
||||
{
|
||||
return fGrammarsToAddToXSModel;
|
||||
}
|
||||
|
||||
inline DatatypeValidatorFactory* GrammarResolver::getBuiltinDatatypeValidatorFactory()
|
||||
{
|
||||
return fDataTypeReg;
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: MixedContentModel.cpp 676911 2008-07-15 13:27:32Z amassari $
|
||||
*/
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Includes
|
||||
// ---------------------------------------------------------------------------
|
||||
#include <string.h>
|
||||
#include <xercesc/util/RuntimeException.hpp>
|
||||
#include <xercesc/framework/XMLElementDecl.hpp>
|
||||
#include <xercesc/validators/common/ContentSpecNode.hpp>
|
||||
#include <xercesc/validators/common/MixedContentModel.hpp>
|
||||
#include <xercesc/validators/common/CMStateSet.hpp>
|
||||
#include <xercesc/validators/common/Grammar.hpp>
|
||||
#include <xercesc/validators/schema/SubstitutionGroupComparator.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// MixedContentModel: Constructors and Destructor
|
||||
// ---------------------------------------------------------------------------
|
||||
MixedContentModel::MixedContentModel(const bool dtd
|
||||
, ContentSpecNode* const parentContentSpec
|
||||
, const bool ordered
|
||||
, MemoryManager* const manager) :
|
||||
fCount(0)
|
||||
, fChildren(0)
|
||||
, fChildTypes(0)
|
||||
, fOrdered(ordered)
|
||||
, fDTD(dtd)
|
||||
, fMemoryManager(manager)
|
||||
{
|
||||
//
|
||||
// Create a vector of unsigned ints that will be filled in with the
|
||||
// ids of the child nodes. It will be expanded as needed but we give
|
||||
// it an initial capacity of 64 which should be more than enough for
|
||||
// 99% of the scenarios.
|
||||
//
|
||||
ValueVectorOf<QName*> children(64, fMemoryManager);
|
||||
ValueVectorOf<ContentSpecNode::NodeTypes> childTypes(64, fMemoryManager);
|
||||
|
||||
//
|
||||
// Get the parent element's content spec. This is the head of the tree
|
||||
// of nodes that describes the content model. We will iterate this
|
||||
// tree.
|
||||
//
|
||||
ContentSpecNode* curNode = parentContentSpec;
|
||||
if (!curNode)
|
||||
ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_NoParentCSN, fMemoryManager);
|
||||
|
||||
// And now call the private recursive method that iterates the tree
|
||||
buildChildList(curNode, children, childTypes);
|
||||
|
||||
//
|
||||
// And now we know how many elements we need in our member list. So
|
||||
// fill them in.
|
||||
//
|
||||
fCount = children.size();
|
||||
fChildren = (QName**) fMemoryManager->allocate(fCount * sizeof(QName*)); //new QName*[fCount];
|
||||
fChildTypes = (ContentSpecNode::NodeTypes*) fMemoryManager->allocate
|
||||
(
|
||||
fCount * sizeof(ContentSpecNode::NodeTypes)
|
||||
); //new ContentSpecNode::NodeTypes[fCount];
|
||||
for (XMLSize_t index = 0; index < fCount; index++) {
|
||||
fChildren[index] = new (fMemoryManager) QName(*children.elementAt(index));
|
||||
fChildTypes[index] = childTypes.elementAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
MixedContentModel::~MixedContentModel()
|
||||
{
|
||||
for (XMLSize_t index = 0; index < fCount; index++) {
|
||||
delete fChildren[index];
|
||||
}
|
||||
fMemoryManager->deallocate(fChildren); //delete [] fChildren;
|
||||
fMemoryManager->deallocate(fChildTypes); //delete [] fChildTypes;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// MixedContentModel: Getter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
bool MixedContentModel::hasDups() const
|
||||
{
|
||||
// Can't have dups if only one child
|
||||
if (fCount == 1)
|
||||
return false;
|
||||
|
||||
for (XMLSize_t index = 0; index < fCount; index++)
|
||||
{
|
||||
const QName* curVal = fChildren[index];
|
||||
for (XMLSize_t iIndex = 0; iIndex < fCount; iIndex++)
|
||||
{
|
||||
if (iIndex == index)
|
||||
continue;
|
||||
|
||||
if (fDTD) {
|
||||
if (XMLString::equals(curVal->getRawName(), fChildren[iIndex]->getRawName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((curVal->getURI() == fChildren[iIndex]->getURI()) &&
|
||||
(XMLString::equals(curVal->getLocalPart(), fChildren[iIndex]->getLocalPart()))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// MixedContentModel: Implementation of the ContentModel virtual interface
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
//Under the XML Schema mixed model,
|
||||
//the order and number of child elements appearing in an instance
|
||||
//must agree with
|
||||
//the order and number of child elements specified in the model.
|
||||
//
|
||||
bool
|
||||
MixedContentModel::validateContent( QName** const children
|
||||
, XMLSize_t childCount
|
||||
, unsigned int
|
||||
, XMLSize_t* indexFailingChild
|
||||
, MemoryManager* const) const
|
||||
{
|
||||
// must match order
|
||||
if (fOrdered) {
|
||||
unsigned int inIndex = 0;
|
||||
for (unsigned int outIndex = 0; outIndex < childCount; outIndex++) {
|
||||
|
||||
// Get the current child out of the source index
|
||||
const QName* curChild = children[outIndex];
|
||||
|
||||
// If its PCDATA, then we just accept that
|
||||
if (curChild->getURI() == XMLElementDecl::fgPCDataElemId)
|
||||
continue;
|
||||
|
||||
ContentSpecNode::NodeTypes type = fChildTypes[inIndex];
|
||||
const QName* inChild = fChildren[inIndex];
|
||||
|
||||
if (type == ContentSpecNode::Leaf) {
|
||||
if (fDTD) {
|
||||
if (!XMLString::equals(inChild->getRawName(), curChild->getRawName())) {
|
||||
*indexFailingChild=outIndex;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((inChild->getURI() != curChild->getURI()) ||
|
||||
(!XMLString::equals(inChild->getLocalPart(), curChild->getLocalPart()))) {
|
||||
*indexFailingChild=outIndex;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == ContentSpecNode::Any) {
|
||||
}
|
||||
else if (type == ContentSpecNode::Any_NS) {
|
||||
if (inChild->getURI() != curChild->getURI())
|
||||
{
|
||||
*indexFailingChild=outIndex;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (type == ContentSpecNode::Any_Other)
|
||||
{
|
||||
// Here we assume that empty string has id 1.
|
||||
//
|
||||
unsigned int uriId = curChild->getURI();
|
||||
if (uriId == 1 || uriId == inChild->getURI())
|
||||
{
|
||||
*indexFailingChild=outIndex;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// advance index
|
||||
inIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// can appear in any order
|
||||
else {
|
||||
for (unsigned int outIndex = 0; outIndex < childCount; outIndex++) {
|
||||
// Get the current child out of the source index
|
||||
const QName* curChild = children[outIndex];
|
||||
|
||||
// If its PCDATA, then we just accept that
|
||||
if (curChild->getURI() == XMLElementDecl::fgPCDataElemId)
|
||||
continue;
|
||||
|
||||
// And try to find it in our list
|
||||
unsigned int inIndex = 0;
|
||||
for (; inIndex < fCount; inIndex++)
|
||||
{
|
||||
ContentSpecNode::NodeTypes type = fChildTypes[inIndex];
|
||||
const QName* inChild = fChildren[inIndex];
|
||||
|
||||
if (type == ContentSpecNode::Leaf) {
|
||||
if (fDTD) {
|
||||
if (XMLString::equals(inChild->getRawName(), curChild->getRawName())) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((inChild->getURI() == curChild->getURI()) &&
|
||||
(XMLString::equals(inChild->getLocalPart(), curChild->getLocalPart()))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == ContentSpecNode::Any) {
|
||||
break;
|
||||
}
|
||||
else if (type == ContentSpecNode::Any_NS) {
|
||||
if (inChild->getURI() == curChild->getURI())
|
||||
break;
|
||||
}
|
||||
else if (type == ContentSpecNode::Any_Other)
|
||||
{
|
||||
// Here we assume that empty string has id 1.
|
||||
//
|
||||
unsigned int uriId = curChild->getURI();
|
||||
if (uriId != 1 && uriId != inChild->getURI())
|
||||
break;
|
||||
}
|
||||
|
||||
// REVISIT: What about checking for multiple ANY matches?
|
||||
// The content model ambiguity *could* be checked
|
||||
// by the caller before constructing the mixed
|
||||
// content model.
|
||||
}
|
||||
// We did not find this one, so the validation failed
|
||||
if (inIndex == fCount)
|
||||
{
|
||||
*indexFailingChild=outIndex;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Everything seems to be in order, so return success
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MixedContentModel::validateContentSpecial(QName** const children
|
||||
, XMLSize_t childCount
|
||||
, unsigned int
|
||||
, GrammarResolver* const pGrammarResolver
|
||||
, XMLStringPool* const pStringPool
|
||||
, XMLSize_t* indexFailingChild
|
||||
, MemoryManager* const) const
|
||||
{
|
||||
|
||||
SubstitutionGroupComparator comparator(pGrammarResolver, pStringPool);
|
||||
|
||||
// must match order
|
||||
if (fOrdered) {
|
||||
unsigned int inIndex = 0;
|
||||
for (unsigned int outIndex = 0; outIndex < childCount; outIndex++) {
|
||||
|
||||
// Get the current child out of the source index
|
||||
QName* curChild = children[outIndex];
|
||||
|
||||
// If its PCDATA, then we just accept that
|
||||
if (curChild->getURI() == XMLElementDecl::fgPCDataElemId)
|
||||
continue;
|
||||
|
||||
ContentSpecNode::NodeTypes type = fChildTypes[inIndex];
|
||||
QName* inChild = fChildren[inIndex];
|
||||
|
||||
if (type == ContentSpecNode::Leaf) {
|
||||
if ( !comparator.isEquivalentTo(curChild, inChild))
|
||||
{
|
||||
*indexFailingChild=outIndex;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (type == ContentSpecNode::Any) {
|
||||
}
|
||||
else if (type == ContentSpecNode::Any_NS) {
|
||||
if (inChild->getURI() != curChild->getURI())
|
||||
{
|
||||
*indexFailingChild=outIndex;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (type == ContentSpecNode::Any_Other)
|
||||
{
|
||||
// Here we assume that empty string has id 1.
|
||||
//
|
||||
unsigned int uriId = curChild->getURI();
|
||||
if (uriId == 1 || uriId == inChild->getURI())
|
||||
{
|
||||
*indexFailingChild=outIndex;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// advance index
|
||||
inIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// can appear in any order
|
||||
else {
|
||||
for (unsigned int outIndex = 0; outIndex < childCount; outIndex++) {
|
||||
// Get the current child out of the source index
|
||||
QName* curChild = children[outIndex];
|
||||
|
||||
// If its PCDATA, then we just accept that
|
||||
if (curChild->getURI() == XMLElementDecl::fgPCDataElemId)
|
||||
continue;
|
||||
|
||||
// And try to find it in our list
|
||||
unsigned int inIndex = 0;
|
||||
for (; inIndex < fCount; inIndex++)
|
||||
{
|
||||
ContentSpecNode::NodeTypes type = fChildTypes[inIndex];
|
||||
QName* inChild = fChildren[inIndex];
|
||||
|
||||
if (type == ContentSpecNode::Leaf) {
|
||||
if ( comparator.isEquivalentTo(curChild, inChild))
|
||||
break;
|
||||
}
|
||||
else if (type == ContentSpecNode::Any) {
|
||||
break;
|
||||
}
|
||||
else if (type == ContentSpecNode::Any_NS) {
|
||||
if (inChild->getURI() == curChild->getURI())
|
||||
break;
|
||||
}
|
||||
else if (type == ContentSpecNode::Any_Other)
|
||||
{
|
||||
// Here we assume that empty string has id 1.
|
||||
//
|
||||
unsigned int uriId = curChild->getURI();
|
||||
if (uriId != 1 && uriId != inChild->getURI())
|
||||
break;
|
||||
}
|
||||
|
||||
// REVISIT: What about checking for multiple ANY matches?
|
||||
// The content model ambiguity *could* be checked
|
||||
// by the caller before constructing the mixed
|
||||
// content model.
|
||||
}
|
||||
// We did not find this one, so the validation failed
|
||||
if (inIndex == fCount)
|
||||
{
|
||||
*indexFailingChild=outIndex;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Everything seems to be in order, so return success
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// MixedContentModel: Private helper methods
|
||||
// ---------------------------------------------------------------------------
|
||||
void
|
||||
MixedContentModel::buildChildList( ContentSpecNode* const curNode
|
||||
, ValueVectorOf<QName*>& toFill
|
||||
, ValueVectorOf<ContentSpecNode::NodeTypes>& toType)
|
||||
{
|
||||
// Get the type of spec node our current node is
|
||||
const ContentSpecNode::NodeTypes curType = curNode->getType();
|
||||
|
||||
// If its a leaf, then store its id in the target list
|
||||
if ((curType == ContentSpecNode::Leaf) ||
|
||||
(curType == ContentSpecNode::Any) ||
|
||||
(curType == ContentSpecNode::Any_Other) ||
|
||||
(curType == ContentSpecNode::Any_NS) )
|
||||
{
|
||||
toFill.addElement(curNode->getElement());
|
||||
toType.addElement(curType);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get both the child node pointers
|
||||
ContentSpecNode* leftNode = curNode->getFirst();
|
||||
ContentSpecNode* rightNode = curNode->getSecond();
|
||||
|
||||
// And recurse according to the type of node
|
||||
if (((curType & 0x0f) == ContentSpecNode::Choice)
|
||||
|| ((curType & 0x0f) == ContentSpecNode::Sequence))
|
||||
{
|
||||
// Recurse on the left and right nodes
|
||||
buildChildList(leftNode, toFill, toType);
|
||||
|
||||
// The last node of a choice or sequence has a null right
|
||||
if (rightNode)
|
||||
buildChildList(rightNode, toFill, toType);
|
||||
}
|
||||
else if ((curType == ContentSpecNode::OneOrMore)
|
||||
|| (curType == ContentSpecNode::ZeroOrOne)
|
||||
|| (curType == ContentSpecNode::ZeroOrMore))
|
||||
{
|
||||
// Just do the left node on this one
|
||||
buildChildList(leftNode, toFill, toType);
|
||||
}
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: MixedContentModel.hpp 901107 2010-01-20 08:45:02Z borisk $
|
||||
*/
|
||||
|
||||
#if !defined(XERCESC_INCLUDE_GUARD_MIXEDCONTENTMODEL_HPP)
|
||||
#define XERCESC_INCLUDE_GUARD_MIXEDCONTENTMODEL_HPP
|
||||
|
||||
#include <xercesc/util/ValueVectorOf.hpp>
|
||||
#include <xercesc/framework/XMLContentModel.hpp>
|
||||
#include <xercesc/validators/common/ContentLeafNameTypeVector.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
class ContentSpecNode;
|
||||
|
||||
//
|
||||
// MixedContentModel is a derivative of the abstract content model base
|
||||
// class that handles the special case of mixed model elements. If an element
|
||||
// is mixed model, it has PCDATA as its first possible content, followed
|
||||
// by an alternation of the possible children. The children cannot have any
|
||||
// numeration or order, so it must look like this:
|
||||
//
|
||||
// <!ELEMENT Foo ((#PCDATA|a|b|c|)*)>
|
||||
//
|
||||
// So, all we have to do is to keep an array of the possible children and
|
||||
// validate by just looking up each child being validated by looking it up
|
||||
// in the list.
|
||||
//
|
||||
class MixedContentModel : public XMLContentModel
|
||||
{
|
||||
public :
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors and Destructor
|
||||
// -----------------------------------------------------------------------
|
||||
MixedContentModel
|
||||
(
|
||||
const bool dtd
|
||||
, ContentSpecNode* const parentContentSpec
|
||||
, const bool ordered = false
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
|
||||
~MixedContentModel();
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Getter methods
|
||||
// -----------------------------------------------------------------------
|
||||
bool hasDups() const;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Implementation of the ContentModel virtual interface
|
||||
// -----------------------------------------------------------------------
|
||||
virtual bool validateContent
|
||||
(
|
||||
QName** const children
|
||||
, XMLSize_t childCount
|
||||
, unsigned int emptyNamespaceId
|
||||
, XMLSize_t* indexFailingChild
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
) const;
|
||||
|
||||
virtual bool validateContentSpecial
|
||||
(
|
||||
QName** const children
|
||||
, XMLSize_t childCount
|
||||
, unsigned int emptyNamespaceId
|
||||
, GrammarResolver* const pGrammarResolver
|
||||
, XMLStringPool* const pStringPool
|
||||
, XMLSize_t* indexFailingChild
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
) const;
|
||||
|
||||
virtual ContentLeafNameTypeVector* getContentLeafNameTypeVector() const ;
|
||||
|
||||
virtual unsigned int getNextState(unsigned int currentState,
|
||||
XMLSize_t elementIndex) const;
|
||||
|
||||
virtual bool handleRepetitions( const QName* const curElem,
|
||||
unsigned int curState,
|
||||
unsigned int currentLoop,
|
||||
unsigned int& nextState,
|
||||
unsigned int& nextLoop,
|
||||
XMLSize_t elementIndex,
|
||||
SubstitutionGroupComparator * comparator) const;
|
||||
|
||||
virtual void checkUniqueParticleAttribution
|
||||
(
|
||||
SchemaGrammar* const pGrammar
|
||||
, GrammarResolver* const pGrammarResolver
|
||||
, XMLStringPool* const pStringPool
|
||||
, XMLValidator* const pValidator
|
||||
, unsigned int* const pContentSpecOrgURI
|
||||
, const XMLCh* pComplexTypeName = 0
|
||||
) ;
|
||||
|
||||
private :
|
||||
// -----------------------------------------------------------------------
|
||||
// Private helper methods
|
||||
// -----------------------------------------------------------------------
|
||||
void buildChildList
|
||||
(
|
||||
ContentSpecNode* const curNode
|
||||
, ValueVectorOf<QName*>& toFill
|
||||
, ValueVectorOf<ContentSpecNode::NodeTypes>& toType
|
||||
);
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
MixedContentModel();
|
||||
MixedContentModel(const MixedContentModel&);
|
||||
MixedContentModel& operator=(const MixedContentModel&);
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Private data members
|
||||
//
|
||||
// fCount
|
||||
// The count of possible children in the fChildren member.
|
||||
//
|
||||
// fChildren
|
||||
// The list of possible children that we have to accept. This array
|
||||
// is allocated as large as needed in the constructor.
|
||||
//
|
||||
// fChildTypes
|
||||
// The type of the children to support ANY.
|
||||
//
|
||||
// fOrdered
|
||||
// True if mixed content model is ordered. DTD mixed content models
|
||||
// are <em>always</em> unordered.
|
||||
//
|
||||
// fDTD
|
||||
// Boolean to allow DTDs to validate even with namespace support.
|
||||
//
|
||||
// -----------------------------------------------------------------------
|
||||
XMLSize_t fCount;
|
||||
QName** fChildren;
|
||||
ContentSpecNode::NodeTypes* fChildTypes;
|
||||
bool fOrdered;
|
||||
bool fDTD;
|
||||
MemoryManager* fMemoryManager;
|
||||
};
|
||||
|
||||
inline ContentLeafNameTypeVector* MixedContentModel::getContentLeafNameTypeVector() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline unsigned int
|
||||
MixedContentModel::getNextState(unsigned int,
|
||||
XMLSize_t) const {
|
||||
|
||||
return XMLContentModel::gInvalidTrans;
|
||||
}
|
||||
|
||||
inline bool
|
||||
MixedContentModel::handleRepetitions( const QName* const /*curElem*/,
|
||||
unsigned int /*curState*/,
|
||||
unsigned int /*currentLoop*/,
|
||||
unsigned int& /*nextState*/,
|
||||
unsigned int& /*nextLoop*/,
|
||||
XMLSize_t /*elementIndex*/,
|
||||
SubstitutionGroupComparator * /*comparator*/) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void MixedContentModel::checkUniqueParticleAttribution
|
||||
(
|
||||
SchemaGrammar* const
|
||||
, GrammarResolver* const
|
||||
, XMLStringPool* const
|
||||
, XMLValidator* const
|
||||
, unsigned int* const pContentSpecOrgURI
|
||||
, const XMLCh* /*pComplexTypeName*/ /*= 0*/
|
||||
)
|
||||
{
|
||||
// rename back
|
||||
unsigned int i = 0;
|
||||
for (i = 0; i < fCount; i++) {
|
||||
unsigned int orgURIIndex = fChildren[i]->getURI();
|
||||
if ((orgURIIndex != XMLContentModel::gEOCFakeId) &&
|
||||
(orgURIIndex != XMLElementDecl::fgInvalidElemId) &&
|
||||
(orgURIIndex != XMLElementDecl::fgPCDataElemId))
|
||||
fChildren[i]->setURI(pContentSpecOrgURI[orgURIIndex]);
|
||||
}
|
||||
|
||||
// for mixed content model, it's only a sequence
|
||||
// UPA checking is not necessary
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,534 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: SimpleContentModel.cpp 799211 2009-07-30 09:06:43Z amassari $
|
||||
*/
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Includes
|
||||
// ---------------------------------------------------------------------------
|
||||
#include <xercesc/util/RuntimeException.hpp>
|
||||
#include <xercesc/framework/XMLValidator.hpp>
|
||||
#include <xercesc/validators/common/SimpleContentModel.hpp>
|
||||
#include <xercesc/validators/schema/SubstitutionGroupComparator.hpp>
|
||||
#include <xercesc/validators/schema/XercesElementWildcard.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SimpleContentModel: Implementation of the ContentModel virtual interface
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// This method is called to validate our content. For this one, its just a
|
||||
// pretty simple 'bull your way through it' test according to what kind of
|
||||
// operation it is for.
|
||||
//
|
||||
bool
|
||||
SimpleContentModel::validateContent(QName** const children
|
||||
, XMLSize_t childCount
|
||||
, unsigned int
|
||||
, XMLSize_t* indexFailingChild
|
||||
, MemoryManager* const) const
|
||||
{
|
||||
//
|
||||
// According to the type of operation, we do the correct type of
|
||||
// content check.
|
||||
//
|
||||
XMLSize_t index;
|
||||
switch(fOp & 0x0f)
|
||||
{
|
||||
case ContentSpecNode::Leaf :
|
||||
//
|
||||
// There can only be one child and it has to be of the
|
||||
// element type we stored.
|
||||
//
|
||||
if (!childCount)
|
||||
{
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the 0th child is not the right kind, report an error at 0
|
||||
if (fDTD) {
|
||||
if (!XMLString::equals(children[0]->getRawName(), fFirstChild->getRawName())) {
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((children[0]->getURI() != fFirstChild->getURI()) ||
|
||||
!XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())) {
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (childCount > 1)
|
||||
{
|
||||
*indexFailingChild=1;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ContentSpecNode::ZeroOrOne :
|
||||
//
|
||||
// If the child count is greater than one, then obviously
|
||||
// bad. Otherwise, if its one, then the one child must be
|
||||
// of the type we stored.
|
||||
//
|
||||
if (childCount == 1) {
|
||||
if (fDTD) {
|
||||
if (!XMLString::equals(children[0]->getRawName(), fFirstChild->getRawName())) {
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((children[0]->getURI() != fFirstChild->getURI()) ||
|
||||
(!XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart()))) {
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (childCount > 1)
|
||||
{
|
||||
*indexFailingChild=1;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ContentSpecNode::ZeroOrMore :
|
||||
//
|
||||
// If the child count is zero, that's fine. If its more than
|
||||
// zero, then make sure that all children are of the element
|
||||
// type that we stored.
|
||||
//
|
||||
if (childCount > 0)
|
||||
{
|
||||
if (fDTD) {
|
||||
for (index = 0; index < childCount; index++) {
|
||||
if (!XMLString::equals(children[index]->getRawName(), fFirstChild->getRawName())) {
|
||||
*indexFailingChild=index;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (index = 0; index < childCount; index++) {
|
||||
if ((children[index]->getURI() != fFirstChild->getURI()) ||
|
||||
!XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart())) {
|
||||
*indexFailingChild=index;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ContentSpecNode::OneOrMore :
|
||||
//
|
||||
// If the child count is zero, that's an error. If its more
|
||||
// than zero, then make sure that all children are of the
|
||||
// element type that we stored.
|
||||
//
|
||||
if (childCount == 0)
|
||||
{
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fDTD) {
|
||||
for (index = 0; index < childCount; index++) {
|
||||
if (!XMLString::equals(children[index]->getRawName(), fFirstChild->getRawName())) {
|
||||
*indexFailingChild=index;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (index = 0; index < childCount; index++) {
|
||||
if ((children[index]->getURI() != fFirstChild->getURI()) ||
|
||||
!XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart())) {
|
||||
*indexFailingChild=index;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ContentSpecNode::Choice :
|
||||
//
|
||||
// There can only be one child, and it must be one of the
|
||||
// two types we stored.
|
||||
//
|
||||
if (!childCount)
|
||||
{
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fDTD) {
|
||||
if (!XMLString::equals(children[0]->getRawName(), fFirstChild->getRawName()) &&
|
||||
!XMLString::equals(children[0]->getRawName(), fSecondChild->getRawName())) {
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (((children[0]->getURI() != fFirstChild->getURI()) ||
|
||||
!XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())) &&
|
||||
((children[0]->getURI() != fSecondChild->getURI()) ||
|
||||
!XMLString::equals(children[0]->getLocalPart(), fSecondChild->getLocalPart()))) {
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (childCount > 1)
|
||||
{
|
||||
*indexFailingChild=1;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ContentSpecNode::Sequence :
|
||||
//
|
||||
// There must be two children and they must be the two values
|
||||
// we stored, in the stored order. So first check the obvious
|
||||
// problem of an empty content, which would never be valid
|
||||
// in this content mode.
|
||||
//
|
||||
if (!childCount)
|
||||
{
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// test first child
|
||||
if (fDTD) {
|
||||
if (!XMLString::equals(children[0]->getRawName(), fFirstChild->getRawName())) {
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((children[0]->getURI() != fFirstChild->getURI()) ||
|
||||
!XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())) {
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// test second child, if present
|
||||
if( childCount == 1)
|
||||
{
|
||||
// missing second child
|
||||
*indexFailingChild=1;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fDTD) {
|
||||
if (!XMLString::equals(children[1]->getRawName(), fSecondChild->getRawName())) {
|
||||
*indexFailingChild=1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((children[1]->getURI() != fSecondChild->getURI()) ||
|
||||
!XMLString::equals(children[1]->getLocalPart(), fSecondChild->getLocalPart())) {
|
||||
*indexFailingChild=1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (childCount > 2) {
|
||||
*indexFailingChild=2;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SimpleContentModel::validateContentSpecial(QName** const children
|
||||
, XMLSize_t childCount
|
||||
, unsigned int
|
||||
, GrammarResolver* const pGrammarResolver
|
||||
, XMLStringPool* const pStringPool
|
||||
, XMLSize_t* indexFailingChild
|
||||
, MemoryManager* const) const
|
||||
{
|
||||
|
||||
SubstitutionGroupComparator comparator(pGrammarResolver, pStringPool);
|
||||
|
||||
//
|
||||
// According to the type of operation, we do the correct type of
|
||||
// content check.
|
||||
//
|
||||
unsigned int index;
|
||||
switch(fOp & 0x0f)
|
||||
{
|
||||
case ContentSpecNode::Leaf :
|
||||
//
|
||||
// There can only be one child and it has to be of the
|
||||
// element type we stored.
|
||||
//
|
||||
if (!childCount)
|
||||
{
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((children[0]->getURI() != fFirstChild->getURI()) ||
|
||||
!XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart()))
|
||||
{
|
||||
if (!comparator.isEquivalentTo(children[0], fFirstChild))
|
||||
{
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (childCount > 1)
|
||||
{
|
||||
*indexFailingChild=1;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ContentSpecNode::ZeroOrOne :
|
||||
//
|
||||
// If the child count is greater than one, then obviously
|
||||
// bad. Otherwise, if its one, then the one child must be
|
||||
// of the type we stored.
|
||||
//
|
||||
if ((childCount == 1) &&
|
||||
((children[0]->getURI() != fFirstChild->getURI()) ||
|
||||
!XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())))
|
||||
{
|
||||
if(!comparator.isEquivalentTo(children[0], fFirstChild))
|
||||
{
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (childCount > 1)
|
||||
{
|
||||
*indexFailingChild=1;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ContentSpecNode::ZeroOrMore :
|
||||
//
|
||||
// If the child count is zero, that's fine. If its more than
|
||||
// zero, then make sure that all children are of the element
|
||||
// type that we stored.
|
||||
//
|
||||
if (childCount > 0)
|
||||
{
|
||||
for (index = 0; index < childCount; index++)
|
||||
{
|
||||
if ((children[index]->getURI() != fFirstChild->getURI()) ||
|
||||
!XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart()))
|
||||
{
|
||||
if (!comparator.isEquivalentTo(children[index], fFirstChild))
|
||||
{
|
||||
*indexFailingChild=index;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ContentSpecNode::OneOrMore :
|
||||
//
|
||||
// If the child count is zero, that's an error. If its more
|
||||
// than zero, then make sure that all children are of the
|
||||
// element type that we stored.
|
||||
//
|
||||
if (childCount == 0)
|
||||
{
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (index = 0; index < childCount; index++)
|
||||
{
|
||||
if ((children[index]->getURI() != fFirstChild->getURI()) ||
|
||||
!XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart()))
|
||||
{
|
||||
if (!comparator.isEquivalentTo(children[index], fFirstChild))
|
||||
{
|
||||
*indexFailingChild=index;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ContentSpecNode::Choice :
|
||||
//
|
||||
// There can only be one child, and it must be one of the
|
||||
// two types we stored.
|
||||
//
|
||||
if (!childCount)
|
||||
{
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (((children[0]->getURI() != fFirstChild->getURI()) ||
|
||||
!XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())) &&
|
||||
((children[0]->getURI() != fSecondChild->getURI()) ||
|
||||
!XMLString::equals(children[0]->getLocalPart(), fSecondChild->getLocalPart())))
|
||||
{
|
||||
|
||||
if (!comparator.isEquivalentTo(children[0], fFirstChild) &&
|
||||
!comparator.isEquivalentTo(children[0], fSecondChild) )
|
||||
{
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (childCount > 1)
|
||||
{
|
||||
*indexFailingChild=1;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ContentSpecNode::Sequence :
|
||||
//
|
||||
// There must be two children and they must be the two values
|
||||
// we stored, in the stored order. So first check the obvious
|
||||
// problem of an empty content, which would never be valid
|
||||
// in this content mode.
|
||||
//
|
||||
if (!childCount)
|
||||
{
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// test first child
|
||||
if ((children[0]->getURI() != fFirstChild->getURI()) ||
|
||||
!XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart()))
|
||||
{
|
||||
if(!comparator.isEquivalentTo(children[0], fFirstChild))
|
||||
{
|
||||
*indexFailingChild=0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// test second child, if present
|
||||
if( childCount == 1)
|
||||
{
|
||||
// missing second child
|
||||
*indexFailingChild=1;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((children[1]->getURI() != fSecondChild->getURI()) ||
|
||||
!XMLString::equals(children[1]->getLocalPart(), fSecondChild->getLocalPart()))
|
||||
{
|
||||
if (!comparator.isEquivalentTo(children[1], fSecondChild))
|
||||
{
|
||||
*indexFailingChild=1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (childCount > 2) {
|
||||
*indexFailingChild=2;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ContentLeafNameTypeVector* SimpleContentModel::getContentLeafNameTypeVector() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SimpleContentModel::checkUniqueParticleAttribution
|
||||
(
|
||||
SchemaGrammar* const pGrammar
|
||||
, GrammarResolver* const pGrammarResolver
|
||||
, XMLStringPool* const pStringPool
|
||||
, XMLValidator* const pValidator
|
||||
, unsigned int* const pContentSpecOrgURI
|
||||
, const XMLCh* pComplexTypeName /*= 0*/
|
||||
)
|
||||
{
|
||||
// rename back
|
||||
unsigned int orgURIIndex = 0;
|
||||
|
||||
orgURIIndex = fFirstChild->getURI();
|
||||
if ((orgURIIndex != XMLContentModel::gEOCFakeId) &&
|
||||
(orgURIIndex != XMLElementDecl::fgInvalidElemId) &&
|
||||
(orgURIIndex != XMLElementDecl::fgPCDataElemId))
|
||||
fFirstChild->setURI(pContentSpecOrgURI[orgURIIndex]);
|
||||
|
||||
orgURIIndex = fSecondChild->getURI();
|
||||
if ((orgURIIndex != XMLContentModel::gEOCFakeId) &&
|
||||
(orgURIIndex != XMLElementDecl::fgInvalidElemId) &&
|
||||
(orgURIIndex != XMLElementDecl::fgPCDataElemId))
|
||||
fSecondChild->setURI(pContentSpecOrgURI[orgURIIndex]);
|
||||
|
||||
// only possible violation is when it's a choice
|
||||
if ((fOp & 0x0f) == ContentSpecNode::Choice) {
|
||||
|
||||
SubstitutionGroupComparator comparator(pGrammarResolver, pStringPool);
|
||||
|
||||
if (XercesElementWildcard::conflict(pGrammar,
|
||||
ContentSpecNode::Leaf,
|
||||
fFirstChild,
|
||||
ContentSpecNode::Leaf,
|
||||
fSecondChild,
|
||||
&comparator))
|
||||
|
||||
pValidator->emitError(XMLValid::UniqueParticleAttributionFail,
|
||||
pComplexTypeName,
|
||||
fFirstChild->getRawName(),
|
||||
fSecondChild->getRawName());
|
||||
}
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: SimpleContentModel.hpp 901107 2010-01-20 08:45:02Z borisk $
|
||||
*/
|
||||
|
||||
#if !defined(XERCESC_INCLUDE_GUARD_SIMPLECONTENTMODEL_HPP)
|
||||
#define XERCESC_INCLUDE_GUARD_SIMPLECONTENTMODEL_HPP
|
||||
|
||||
#include <xercesc/framework/XMLContentModel.hpp>
|
||||
#include <xercesc/validators/common/ContentSpecNode.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
//
|
||||
// SimpleContentModel is a derivative of the abstract content model base
|
||||
// class that handles a small set of simple content models that are just
|
||||
// way overkill to give the DFA treatment.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// This guy handles the following scenarios:
|
||||
//
|
||||
// a
|
||||
// a?
|
||||
// a*
|
||||
// a+
|
||||
// a,b
|
||||
// a|b
|
||||
//
|
||||
// These all involve a unary operation with one element type, or a binary
|
||||
// operation with two elements. These are very simple and can be checked
|
||||
// in a simple way without a DFA and without the overhead of setting up a
|
||||
// DFA for such a simple check.
|
||||
//
|
||||
// NOTE: Pass the XMLElementDecl::fgPCDataElemId value to represent a
|
||||
// PCData node. Pass XMLElementDecl::fgInvalidElemId for unused element
|
||||
//
|
||||
class SimpleContentModel : public XMLContentModel
|
||||
{
|
||||
public :
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructors and Destructor
|
||||
// -----------------------------------------------------------------------
|
||||
SimpleContentModel
|
||||
(
|
||||
const bool dtd
|
||||
, QName* const firstChild
|
||||
, QName* const secondChild
|
||||
, const ContentSpecNode::NodeTypes cmOp
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
);
|
||||
|
||||
~SimpleContentModel();
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Implementation of the ContentModel virtual interface
|
||||
// -----------------------------------------------------------------------
|
||||
virtual bool validateContent
|
||||
(
|
||||
QName** const children
|
||||
, XMLSize_t childCount
|
||||
, unsigned int emptyNamespaceId
|
||||
, XMLSize_t* indexFailingChild
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
) const;
|
||||
|
||||
virtual bool validateContentSpecial
|
||||
(
|
||||
QName** const children
|
||||
, XMLSize_t childCount
|
||||
, unsigned int emptyNamespaceId
|
||||
, GrammarResolver* const pGrammarResolver
|
||||
, XMLStringPool* const pStringPool
|
||||
, XMLSize_t* indexFailingChild
|
||||
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
||||
) const;
|
||||
|
||||
virtual ContentLeafNameTypeVector *getContentLeafNameTypeVector() const;
|
||||
|
||||
virtual unsigned int getNextState(unsigned int currentState,
|
||||
XMLSize_t elementIndex) const;
|
||||
|
||||
virtual bool handleRepetitions( const QName* const curElem,
|
||||
unsigned int curState,
|
||||
unsigned int currentLoop,
|
||||
unsigned int& nextState,
|
||||
unsigned int& nextLoop,
|
||||
XMLSize_t elementIndex,
|
||||
SubstitutionGroupComparator * comparator) const;
|
||||
|
||||
virtual void checkUniqueParticleAttribution
|
||||
(
|
||||
SchemaGrammar* const pGrammar
|
||||
, GrammarResolver* const pGrammarResolver
|
||||
, XMLStringPool* const pStringPool
|
||||
, XMLValidator* const pValidator
|
||||
, unsigned int* const pContentSpecOrgURI
|
||||
, const XMLCh* pComplexTypeName = 0
|
||||
) ;
|
||||
|
||||
private :
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
SimpleContentModel();
|
||||
SimpleContentModel(const SimpleContentModel&);
|
||||
SimpleContentModel& operator=(const SimpleContentModel&);
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Private data members
|
||||
//
|
||||
// fFirstChild
|
||||
// fSecondChild
|
||||
// The first (and optional second) child node. The
|
||||
// operation code tells us whether the second child is used or not.
|
||||
//
|
||||
// fOp
|
||||
// The operation that this object represents. Since this class only
|
||||
// does simple contents, there is only ever a single operation
|
||||
// involved (i.e. the children of the operation are always one or
|
||||
// two leafs.)
|
||||
//
|
||||
// fDTD
|
||||
// Boolean to allow DTDs to validate even with namespace support. */
|
||||
//
|
||||
// -----------------------------------------------------------------------
|
||||
QName* fFirstChild;
|
||||
QName* fSecondChild;
|
||||
ContentSpecNode::NodeTypes fOp;
|
||||
bool fDTD;
|
||||
MemoryManager* const fMemoryManager;
|
||||
};
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SimpleContentModel: Constructors and Destructor
|
||||
// ---------------------------------------------------------------------------
|
||||
inline SimpleContentModel::SimpleContentModel
|
||||
(
|
||||
const bool dtd
|
||||
, QName* const firstChild
|
||||
, QName* const secondChild
|
||||
, const ContentSpecNode::NodeTypes cmOp
|
||||
, MemoryManager* const manager
|
||||
)
|
||||
: fFirstChild(0)
|
||||
, fSecondChild(0)
|
||||
, fOp(cmOp)
|
||||
, fDTD(dtd)
|
||||
, fMemoryManager(manager)
|
||||
{
|
||||
if (firstChild)
|
||||
fFirstChild = new (manager) QName(*firstChild);
|
||||
else
|
||||
fFirstChild = new (manager) QName(XMLUni::fgZeroLenString, XMLUni::fgZeroLenString, XMLElementDecl::fgInvalidElemId, manager);
|
||||
|
||||
if (secondChild)
|
||||
fSecondChild = new (manager) QName(*secondChild);
|
||||
else
|
||||
fSecondChild = new (manager) QName(XMLUni::fgZeroLenString, XMLUni::fgZeroLenString, XMLElementDecl::fgInvalidElemId, manager);
|
||||
}
|
||||
|
||||
inline SimpleContentModel::~SimpleContentModel()
|
||||
{
|
||||
delete fFirstChild;
|
||||
delete fSecondChild;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SimpleContentModel: Virtual methods
|
||||
// ---------------------------------------------------------------------------
|
||||
inline unsigned int
|
||||
SimpleContentModel::getNextState(unsigned int,
|
||||
XMLSize_t) const {
|
||||
|
||||
return XMLContentModel::gInvalidTrans;
|
||||
}
|
||||
|
||||
inline bool
|
||||
SimpleContentModel::handleRepetitions( const QName* const /*curElem*/,
|
||||
unsigned int /*curState*/,
|
||||
unsigned int /*currentLoop*/,
|
||||
unsigned int& /*nextState*/,
|
||||
unsigned int& /*nextLoop*/,
|
||||
XMLSize_t /*elementIndex*/,
|
||||
SubstitutionGroupComparator * /*comparator*/) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user