You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by tn...@apache.org on 2001/02/16 15:17:30 UTC
cvs commit: xml-xerces/c/src/validators/common CMBinaryOp.cpp CMBinaryOp.hpp CMLeaf.hpp CMNode.hpp CMStateSet.hpp CMUnaryOp.cpp CMUnaryOp.hpp ContentSpecNode.cpp ContentSpecNode.hpp DFAContentModel.cpp DFAContentModel.hpp MixedContentModel.cpp MixedContentModel.hpp SimpleContentModel.cpp SimpleContentModel.hpp
tng 01/02/16 06:17:30
Added: c/src/validators/common CMBinaryOp.cpp CMBinaryOp.hpp
CMLeaf.hpp CMNode.hpp CMStateSet.hpp CMUnaryOp.cpp
CMUnaryOp.hpp ContentSpecNode.cpp
ContentSpecNode.hpp DFAContentModel.cpp
DFAContentModel.hpp MixedContentModel.cpp
MixedContentModel.hpp SimpleContentModel.cpp
SimpleContentModel.hpp
Removed: c/src/validators/DTD CMBinaryOp.cpp CMBinaryOp.hpp
CMLeaf.hpp CMNode.hpp CMStateSet.hpp CMUnaryOp.cpp
CMUnaryOp.hpp ContentSpecNode.cpp
ContentSpecNode.hpp DFAContentModel.cpp
DFAContentModel.hpp MixedContentModel.cpp
MixedContentModel.hpp SimpleContentModel.cpp
SimpleContentModel.hpp
Log:
Schema: Move the common Content Model files that are shared by DTD
and schema from 'DTD' folder to 'common' folder. By Pei Yong Zhang.
Revision Changes Path
1.1 xml-xerces/c/src/validators/common/CMBinaryOp.cpp
Index: CMBinaryOp.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: CMBinaryOp.cpp,v $
* Revision 1.1 2001/02/16 14:17:29 tng
* Schema: Move the common Content Model files that are shared by DTD
* and schema from 'DTD' folder to 'common' folder. By Pei Yong Zhang.
*
* Revision 1.3 2000/03/02 19:55:37 roddey
* This checkin includes many changes done while waiting for the
* 1.1.0 code to be finished. I can't list them all here, but a list is
* available elsewhere.
*
* Revision 1.2 2000/02/09 21:42:36 abagchi
* Copyright swatswat
*
* Revision 1.1.1.1 1999/11/09 01:03:00 twl
* Initial checkin
*
* Revision 1.2 1999/11/08 20:45:35 rahul
* Swat for adding in Product name and CVS comment log variable.
*
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <util/XercesDefs.hpp>
#include <util/RuntimeException.hpp>
#include <validators/DTD/ContentSpecNode.hpp>
#include <validators/DTD/CMBinaryOp.hpp>
#include <validators/DTD/CMStateSet.hpp>
// ---------------------------------------------------------------------------
// CMBinaryOp: Constructors
// ---------------------------------------------------------------------------
CMBinaryOp::CMBinaryOp( const ContentSpecNode::NodeTypes type
, CMNode* const leftToAdopt
, CMNode* const rightToAdopt) :
CMNode(type)
, fLeftChild(leftToAdopt)
, fRightChild(rightToAdopt)
{
// Insure that its one of the types we require
if ((type != ContentSpecNode::Choice)
&& (type != ContentSpecNode::Sequence))
{
ThrowXML(RuntimeException, XMLExcepts::CM_BinOpHadUnaryType);
}
}
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
// ---------------------------------------------------------------------------
bool CMBinaryOp::isNullable() const
{
//
// 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 (getType() == ContentSpecNode::Choice)
return (fLeftChild->isNullable() || fRightChild->isNullable());
return (fLeftChild->isNullable() && fRightChild->isNullable());
}
// ---------------------------------------------------------------------------
// CMBinaryOp: Implementation of the protected CMNode virtual interface
// ---------------------------------------------------------------------------
void CMBinaryOp::calcFirstPos(CMStateSet& toSet) const
{
if (getType() == ContentSpecNode::Choice)
{
// Its the the union of the first positions of our children.
toSet = fLeftChild->getFirstPos();
toSet |= fRightChild->getFirstPos();
}
else if (getType() == 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() == ContentSpecNode::Choice)
{
// Its the the union of the first positions of our children.
toSet = fLeftChild->getLastPos();
toSet |= fRightChild->getLastPos();
}
else if (getType() == 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();
}
}
1.1 xml-xerces/c/src/validators/common/CMBinaryOp.hpp
Index: CMBinaryOp.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: CMBinaryOp.hpp,v $
* Revision 1.1 2001/02/16 14:17:29 tng
* Schema: Move the common Content Model files that are shared by DTD
* and schema from 'DTD' folder to 'common' folder. By Pei Yong Zhang.
*
* Revision 1.4 2000/03/02 19:55:37 roddey
* This checkin includes many changes done while waiting for the
* 1.1.0 code to be finished. I can't list them all here, but a list is
* available elsewhere.
*
* Revision 1.3 2000/02/24 20:16:47 abagchi
* Swat for removing Log from API docs
*
* Revision 1.2 2000/02/09 21:42:36 abagchi
* Copyright swat
*
* Revision 1.1.1.1 1999/11/09 01:03:02 twl
* Initial checkin
*
* Revision 1.2 1999/11/08 20:45:35 rahul
* Swat for adding in Product name and CVS comment log variable.
*
*/
#if !defined(CMBINARYOP_HPP)
#define CMBINARYOP_HPP
#include <util/XercesDefs.hpp>
#include <validators/DTD/CMNode.hpp>
class CMStateSet;
class CMBinaryOp : public CMNode
{
public :
// -----------------------------------------------------------------------
// Constructors
// -----------------------------------------------------------------------
CMBinaryOp
(
const ContentSpecNode::NodeTypes type
, CMNode* const leftToAdopt
, CMNode* const rightToAdopt
);
~CMBinaryOp();
// -----------------------------------------------------------------------
// Getter methods
// -----------------------------------------------------------------------
const CMNode* getLeft() const;
CMNode* getLeft();
const CMNode* getRight() const;
CMNode* getRight();
// -----------------------------------------------------------------------
// Implementation of the public CMNode virtual interface
// -----------------------------------------------------------------------
bool isNullable() const;
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;
};
#endif
1.1 xml-xerces/c/src/validators/common/CMLeaf.hpp
Index: CMLeaf.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: CMLeaf.hpp,v $
* Revision 1.1 2001/02/16 14:17:29 tng
* Schema: Move the common Content Model files that are shared by DTD
* and schema from 'DTD' folder to 'common' folder. By Pei Yong Zhang.
*
* Revision 1.5 2000/03/28 19:43:25 roddey
* Fixes for signed/unsigned warnings. New work for two way transcoding
* stuff.
*
* Revision 1.4 2000/03/02 19:55:37 roddey
* This checkin includes many changes done while waiting for the
* 1.1.0 code to be finished. I can't list them all here, but a list is
* available elsewhere.
*
* Revision 1.3 2000/02/24 20:16:47 abagchi
* Swat for removing Log from API docs
*
* Revision 1.2 2000/02/09 21:42:36 abagchi
* Copyright swat
*
* Revision 1.1.1.1 1999/11/09 01:03:04 twl
* Initial checkin
*
* Revision 1.2 1999/11/08 20:45:36 rahul
* Swat for adding in Product name and CVS comment log variable.
*
*/
#if !defined(CMLEAF_HPP)
#define CMLEAF_HPP
#include <util/XercesDefs.hpp>
#include <util/RuntimeException.hpp>
#include <validators/DTD/ContentSpecNode.hpp>
#include <validators/DTD/CMNode.hpp>
#include <validators/DTD/CMStateSet.hpp>
//
// This class represents a leaf in the content spec node tree of an
// element's content model. It just has an element id and a position value,
// the latter of which is used during the building of a DFA.
//
class CMLeaf : public CMNode
{
public :
// -----------------------------------------------------------------------
// Constructors
// -----------------------------------------------------------------------
CMLeaf
(
const unsigned int elemId
, const unsigned int position = ~0
);
~CMLeaf();
// -----------------------------------------------------------------------
// Getter methods
// -----------------------------------------------------------------------
unsigned int getId() const;
unsigned int getPosition() const;
// -----------------------------------------------------------------------
// Setter methods
// -----------------------------------------------------------------------
void setPosition(const unsigned int newPosition);
// -----------------------------------------------------------------------
// Implementation of public CMNode virtual interface
// -----------------------------------------------------------------------
bool isNullable() const;
protected :
// -----------------------------------------------------------------------
// Implementation of protected CMNode virtual interface
// -----------------------------------------------------------------------
void calcFirstPos(CMStateSet& toSet) const;
void calcLastPos(CMStateSet& toSet) const;
private :
// -----------------------------------------------------------------------
// Private data members
//
// fElemId
// This is the element id of 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.
// -----------------------------------------------------------------------
unsigned int fElemId;
unsigned int fPosition;
};
// -----------------------------------------------------------------------
// Constructors
// -----------------------------------------------------------------------
inline CMLeaf::CMLeaf( const unsigned int elemId
, const unsigned int position) :
CMNode(ContentSpecNode::Leaf)
, fElemId(elemId)
, fPosition(position)
{
}
inline CMLeaf::~CMLeaf()
{
}
// ---------------------------------------------------------------------------
// Getter methods
// ---------------------------------------------------------------------------
inline unsigned int CMLeaf::getId() const
{
return fElemId;
}
inline unsigned int CMLeaf::getPosition() const
{
return fPosition;
}
// ---------------------------------------------------------------------------
// Setter methods
// ---------------------------------------------------------------------------
inline void CMLeaf::setPosition(const unsigned int newPosition)
{
fPosition = newPosition;
}
// ---------------------------------------------------------------------------
// Implementation of public CMNode virtual interface
// ---------------------------------------------------------------------------
inline bool CMLeaf::isNullable() const
{
// Leaf nodes are never nullable unless its an epsilon node
return (fPosition == -1);
}
// ---------------------------------------------------------------------------
// 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 (fPosition == -1)
{
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 (fPosition == -1)
{
toSet.zeroBits();
return;
}
// Otherwise, its just the one bit of our position
toSet.setBit(fPosition);
}
#endif
1.1 xml-xerces/c/src/validators/common/CMNode.hpp
Index: CMNode.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: CMNode.hpp,v $
* Revision 1.1 2001/02/16 14:17:29 tng
* Schema: Move the common Content Model files that are shared by DTD
* and schema from 'DTD' folder to 'common' folder. By Pei Yong Zhang.
*
* Revision 1.5 2000/03/28 19:43:25 roddey
* Fixes for signed/unsigned warnings. New work for two way transcoding
* stuff.
*
* Revision 1.4 2000/03/02 19:55:37 roddey
* This checkin includes many changes done while waiting for the
* 1.1.0 code to be finished. I can't list them all here, but a list is
* available elsewhere.
*
* Revision 1.3 2000/02/24 20:16:48 abagchi
* Swat for removing Log from API docs
*
* Revision 1.2 2000/02/09 21:42:36 abagchi
* Copyright swat
*
* Revision 1.1.1.1 1999/11/09 01:03:05 twl
* Initial checkin
*
* Revision 1.2 1999/11/08 20:45:36 rahul
* Swat for adding in Product name and CVS comment log variable.
*
*/
#if !defined(CMNODE_HPP)
#define CMNODE_HPP
#include <util/XercesDefs.hpp>
#include <validators/DTD/ContentSpecNode.hpp>
#include <validators/DTD/CMStateSet.hpp>
class CMNode
{
public :
// -----------------------------------------------------------------------
// Constructors and Destructors
// -----------------------------------------------------------------------
CMNode(const ContentSpecNode::NodeTypes type);
virtual ~CMNode();
// -----------------------------------------------------------------------
// Virtual methods to be provided derived node classes
// -----------------------------------------------------------------------
virtual bool isNullable() const = 0;
// -----------------------------------------------------------------------
// Getter methods
// -----------------------------------------------------------------------
ContentSpecNode::NodeTypes getType() const;
const CMStateSet& getFirstPos() const;
const CMStateSet& getLastPos() const;
// -----------------------------------------------------------------------
// Setter methods
// -----------------------------------------------------------------------
void setMaxStates(const unsigned int maxStates);
protected :
// -----------------------------------------------------------------------
// Protected, abstract methods
// -----------------------------------------------------------------------
virtual void calcFirstPos(CMStateSet& toUpdate) const = 0;
virtual void calcLastPos(CMStateSet& toUpdate) const = 0;
private :
// -----------------------------------------------------------------------
// Unimplemented constructors and operators
// -----------------------------------------------------------------------
CMNode();
CMNode(const CMNode&);
void 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.
// -----------------------------------------------------------------------
ContentSpecNode::NodeTypes fType;
CMStateSet* fFirstPos;
CMStateSet* fLastPos;
unsigned int fMaxStates;
};
// ---------------------------------------------------------------------------
// CMNode: Constructors and Destructors
// ---------------------------------------------------------------------------
inline CMNode::CMNode(const ContentSpecNode::NodeTypes type) :
fType(type)
, fFirstPos(0)
, fLastPos(0)
, fMaxStates(~0)
{
}
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() const
{
//
// Fault in the state set if needed. Since we can't use mutable members
// cast off the const'ness.
//
if (!fFirstPos)
{
CMNode* unconstThis = (CMNode*)this;
unconstThis->fFirstPos = new CMStateSet(fMaxStates);
unconstThis->calcFirstPos(*fFirstPos);
}
return *fFirstPos;
}
inline const CMStateSet& CMNode::getLastPos() const
{
//
// Fault in the state set if needed. Since we can't use mutable members
// cast off the const'ness.
//
if (!fLastPos)
{
CMNode* unconstThis = (CMNode*)this;
unconstThis->fLastPos = new CMStateSet(fMaxStates);
unconstThis->calcLastPos(*fLastPos);
}
return *fLastPos;
}
// ---------------------------------------------------------------------------
// CMNode: Setter methods
// ---------------------------------------------------------------------------
inline void CMNode::setMaxStates(const unsigned int maxStates)
{
fMaxStates = maxStates;
}
#endif
1.1 xml-xerces/c/src/validators/common/CMStateSet.hpp
Index: CMStateSet.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: CMStateSet.hpp,v $
* Revision 1.1 2001/02/16 14:17:29 tng
* Schema: Move the common Content Model files that are shared by DTD
* and schema from 'DTD' folder to 'common' folder. By Pei Yong Zhang.
*
* Revision 1.4 2000/03/02 19:55:37 roddey
* This checkin includes many changes done while waiting for the
* 1.1.0 code to be finished. I can't list them all here, but a list is
* available elsewhere.
*
* Revision 1.3 2000/02/24 20:16:48 abagchi
* Swat for removing Log from API docs
*
* Revision 1.2 2000/02/09 21:42:36 abagchi
* Copyright swat
*
* Revision 1.1.1.1 1999/11/09 01:03:06 twl
* Initial checkin
*
* Revision 1.3 1999/11/08 20:45:36 rahul
* Swat for adding in Product name and CVS comment log variable.
*
*/
// 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 64 bits are far
// and away the most common. So it can be a lot more optimized than a general
// purpose utility bitset class
//
#if !defined(CMSTATESET_HPP)
#define CMSTATESET_HPP
#include <util/XercesDefs.hpp>
#include <util/ArrayIndexOutOfBoundsException.hpp>
#include <framework/XMLValidityCodes.hpp>
#include <string.h>
#include <memory.h>
class CMStateSet
{
public :
// -----------------------------------------------------------------------
// Constructors and Destructor
// -----------------------------------------------------------------------
CMStateSet(const unsigned int bitCount) :
fBitCount(bitCount)
, fByteArray(0)
{
//
// See if we need to allocate the byte array or whether we can live
// within the 64 bit high performance scheme.
//
if (fBitCount > 64)
{
fByteCount = fBitCount / 8;
if (fBitCount % 8)
fByteCount++;
fByteArray = new XMLByte[fByteCount];
}
// Init all the bits to zero
zeroBits();
}
/*
* This method with the 'for' statement (commented out) cannot be made inline
* because the antiquated CC (CFront) compiler under HPUX 10.20 does not allow
* the 'for' statement inside any inline method. Unfortunately,
* we have to support it. So instead, we use memcpy().
*/
CMStateSet(const CMStateSet& toCopy) :
fBitCount(toCopy.fBitCount)
, fByteArray(0)
{
//
// See if we need to allocate the byte array or whether we can live
// within the 64 bit high performance scheme.
//
if (fBitCount > 64)
{
fByteCount = fBitCount / 8;
if (fBitCount % 8)
fByteCount++;
fByteArray = new XMLByte[fByteCount];
memcpy((void *) fByteArray,
(const void *) toCopy.fByteArray,
fByteCount * sizeof(XMLByte));
// for (unsigned int index = 0; index < fByteCount; index++)
// fByteArray[index] = toCopy.fByteArray[index];
}
else
{
fBits1 = toCopy.fBits1;
fBits2 = toCopy.fBits2;
}
}
~CMStateSet()
{
if (fByteArray)
delete [] fByteArray;
}
// -----------------------------------------------------------------------
// Set manipulation methods
// -----------------------------------------------------------------------
void operator&=(const CMStateSet& setToAnd)
{
if (fBitCount < 65)
{
fBits1 &= setToAnd.fBits1;
fBits2 &= setToAnd.fBits2;
}
else
{
for (unsigned int index = 0; index < fByteCount; index++)
fByteArray[index] &= setToAnd.fByteArray[index];
}
}
void operator|=(const CMStateSet& setToOr)
{
if (fBitCount < 65)
{
fBits1 |= setToOr.fBits1;
fBits2 |= setToOr.fBits2;
}
else
{
for (unsigned int index = 0; index < fByteCount; index++)
fByteArray[index] |= setToOr.fByteArray[index];
}
}
bool operator==(const CMStateSet& setToCompare) const
{
if (fBitCount != setToCompare.fBitCount)
return false;
if (fBitCount < 65)
{
return ((fBits1 == setToCompare.fBits1)
&& (fBits2 == setToCompare.fBits2));
}
for (unsigned int index = 0; index < fByteCount; index++)
{
if (fByteArray[index] != setToCompare.fByteArray[index])
return false;
}
return true;
}
CMStateSet& operator=(const CMStateSet& srcSet)
{
if (this == &srcSet)
return *this;
if (fBitCount < 65)
{
fBits1 = srcSet.fBits1;
fBits2 = srcSet.fBits2;
}
else
{
for (unsigned int index = 0; index < fByteCount; index++)
fByteArray[index] = srcSet.fByteArray[index];
}
return *this;
}
bool getBit(const unsigned int bitToGet) const
{
if (bitToGet >= fBitCount)
ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Bitset_BadIndex);
if (fBitCount < 65)
{
unsigned int mask = (0x1UL << (bitToGet % 32));
if (bitToGet < 32)
return ((fBits1 & mask) != 0);
else
return ((fBits2 & mask) != 0);
}
// Create the mask and byte values
const XMLByte mask1 = XMLByte(0x1 << (bitToGet % 8));
const unsigned int byteOfs = bitToGet >> 3;
// And access the right bit and byte
return ((fByteArray[byteOfs] & mask1) != 0);
}
bool isEmpty() const
{
if (fBitCount < 65)
return ((fBits1 == 0) && (fBits2 == 0));
for (unsigned int index = 0; index < fByteCount; index++)
{
if (fByteArray[index] != 0)
return false;
}
return true;
}
void setBit(const unsigned int bitToSet)
{
if (bitToSet >= fBitCount)
ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Bitset_BadIndex);
if (fBitCount < 65)
{
const unsigned int mask = (0x1UL << (bitToSet % 32));
if (bitToSet < 32)
{
fBits1 &= ~mask;
fBits1 |= mask;
}
else
{
fBits2 &= ~mask;
fBits2 |= mask;
}
}
else
{
// Create the mask and byte values
const XMLByte mask1 = XMLByte(0x1 << (bitToSet % 8));
const unsigned int byteOfs = bitToSet >> 3;
// And access the right bit and byte
fByteArray[byteOfs] &= ~mask1;
fByteArray[byteOfs] |= mask1;
}
}
void zeroBits()
{
if (fBitCount < 65)
{
fBits1 = 0;
fBits2 = 0;
}
else
{
for (unsigned int index = 0; index < fByteCount; index++)
fByteArray[index] = 0;
}
}
private :
// -----------------------------------------------------------------------
// Unimplemented constructors and operators
// -----------------------------------------------------------------------
CMStateSet();
// -----------------------------------------------------------------------
// Private data members
//
// fBitCount
// The count of bits that the outside world wants to support,
// so its the max bit index plus one.
//
// fByteCount
// If the bit count is > 64, then we use the fByteArray member to
// store the bits, and this indicates its size in bytes. Otherwise
// its value is meaningless and unset.
//
// fBits1
// fBits2
// When the bit count is <= 64 (very common), these hold the bits.
// Otherwise, the fByteArray member holds htem.
//
// fByteArray
// The array of bytes used when the bit count is > 64. It is
// allocated as required.
// -----------------------------------------------------------------------
unsigned int fBitCount;
unsigned int fByteCount;
unsigned int fBits1;
unsigned int fBits2;
XMLByte* fByteArray;
};
#endif
1.1 xml-xerces/c/src/validators/common/CMUnaryOp.cpp
Index: CMUnaryOp.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: CMUnaryOp.cpp,v $
* Revision 1.1 2001/02/16 14:17:29 tng
* Schema: Move the common Content Model files that are shared by DTD
* and schema from 'DTD' folder to 'common' folder. By Pei Yong Zhang.
*
* Revision 1.3 2000/03/02 19:55:37 roddey
* This checkin includes many changes done while waiting for the
* 1.1.0 code to be finished. I can't list them all here, but a list is
* available elsewhere.
*
* Revision 1.2 2000/02/09 21:42:37 abagchi
* Copyright swatswat
*
* Revision 1.1.1.1 1999/11/09 01:03:08 twl
* Initial checkin
*
* Revision 1.2 1999/11/08 20:45:37 rahul
* Swat for adding in Product name and CVS comment log variable.
*
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <util/XercesDefs.hpp>
#include <util/RuntimeException.hpp>
#include <validators/DTD/CMStateSet.hpp>
#include <validators/DTD/CMUnaryOp.hpp>
// ---------------------------------------------------------------------------
// CMUnaryOp: Constructors and Destructor
// ---------------------------------------------------------------------------
CMUnaryOp::CMUnaryOp( const ContentSpecNode::NodeTypes type
, CMNode* const nodeToAdopt) :
CMNode(type)
, fChild(nodeToAdopt)
{
// Insure that its one of the types we require
if ((type != ContentSpecNode::ZeroOrOne)
&& (type != ContentSpecNode::ZeroOrMore)
&& (type != ContentSpecNode::OneOrMore))
{
ThrowXML(RuntimeException, XMLExcepts::CM_UnaryOpHadBinType);
}
}
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
// ---------------------------------------------------------------------------
bool CMUnaryOp::isNullable() const
{
// Repetition operations are always nullable
return true;
}
// ---------------------------------------------------------------------------
// 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();
}
1.1 xml-xerces/c/src/validators/common/CMUnaryOp.hpp
Index: CMUnaryOp.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: CMUnaryOp.hpp,v $
* Revision 1.1 2001/02/16 14:17:29 tng
* Schema: Move the common Content Model files that are shared by DTD
* and schema from 'DTD' folder to 'common' folder. By Pei Yong Zhang.
*
* Revision 1.4 2000/03/02 19:55:37 roddey
* This checkin includes many changes done while waiting for the
* 1.1.0 code to be finished. I can't list them all here, but a list is
* available elsewhere.
*
* Revision 1.3 2000/02/24 20:16:48 abagchi
* Swat for removing Log from API docs
*
* Revision 1.2 2000/02/09 21:42:37 abagchi
* Copyright swat
*
* Revision 1.1.1.1 1999/11/09 01:03:11 twl
* Initial checkin
*
* Revision 1.2 1999/11/08 20:45:37 rahul
* Swat for adding in Product name and CVS comment log variable.
*
*/
#if !defined(CMUNARYOP_HPP)
#define CMUNARYOP_HPP
#include <util/XercesDefs.hpp>
#include <validators/DTD/CMNode.hpp>
#include <validators/DTD/ContentSpecNode.hpp>
class CMStateSet;
class CMUnaryOp : public CMNode
{
public :
// -----------------------------------------------------------------------
// Constructors and Destructor
// -----------------------------------------------------------------------
CMUnaryOp
(
const ContentSpecNode::NodeTypes type
, CMNode* const nodeToAdopt
);
~CMUnaryOp();
// -----------------------------------------------------------------------
// Getter methods
// -----------------------------------------------------------------------
const CMNode* getChild() const;
CMNode* getChild();
// -----------------------------------------------------------------------
// Implementation of the public CMNode virtual interface
// -----------------------------------------------------------------------
bool isNullable() const;
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;
};
#endif
1.1 xml-xerces/c/src/validators/common/ContentSpecNode.cpp
Index: ContentSpecNode.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Id: ContentSpecNode.cpp,v 1.1 2001/02/16 14:17:29 tng Exp $
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <util/Janitor.hpp>
#include <util/XMLUniDefs.hpp>
#include <util/XMLUni.hpp>
#include <framework/XMLNotationDecl.hpp>
#include <framework/XMLBuffer.hpp>
#include <validators/DTD/ContentSpecNode.hpp>
#include <validators/DTD/DTDValidator.hpp>
// ---------------------------------------------------------------------------
// Local methods
// ---------------------------------------------------------------------------
static void formatNode( const ContentSpecNode* const curNode
, const ContentSpecNode::NodeTypes parentType
, const XMLValidator& validator
, XMLBuffer& bufToFill)
{
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
unsigned int tmpVal;
switch(curType)
{
case ContentSpecNode::Leaf :
tmpVal = curNode->getElemId();
if (tmpVal == XMLElementDecl::fgPCDataElemId)
bufToFill.append(XMLElementDecl::fgPCDataElemName);
else
bufToFill.append(validator.getElemDecl(tmpVal)->getFullName());
break;
case ContentSpecNode::ZeroOrOne :
if (doRepParens)
bufToFill.append(chOpenParen);
formatNode(first, curType, validator, bufToFill);
if (doRepParens)
bufToFill.append(chCloseParen);
bufToFill.append(chQuestion);
break;
case ContentSpecNode::ZeroOrMore :
if (doRepParens)
bufToFill.append(chOpenParen);
formatNode(first, curType, validator, bufToFill);
if (doRepParens)
bufToFill.append(chCloseParen);
bufToFill.append(chAsterisk);
break;
case ContentSpecNode::OneOrMore :
if (doRepParens)
bufToFill.append(chOpenParen);
formatNode(first, curType, validator, bufToFill);
if (doRepParens)
bufToFill.append(chCloseParen);
bufToFill.append(chPlus);
break;
case ContentSpecNode::Choice :
if (parentType != curType)
bufToFill.append(chOpenParen);
formatNode(first, curType, validator, bufToFill);
bufToFill.append(chPipe);
formatNode(second, curType, validator, bufToFill);
if (parentType != curType)
bufToFill.append(chCloseParen);
break;
case ContentSpecNode::Sequence :
if (parentType != curType)
bufToFill.append(chOpenParen);
formatNode(first, curType, validator, bufToFill);
bufToFill.append(chComma);
formatNode(second, curType, validator, bufToFill);
if (parentType != curType)
bufToFill.append(chCloseParen);
break;
}
}
// ---------------------------------------------------------------------------
// ContentSpecNode: Miscellaneous
// ---------------------------------------------------------------------------
void ContentSpecNode::formatSpec(const XMLValidator& validator
, XMLBuffer& bufToFill) const
{
// Clean out the buffer first
bufToFill.reset();
if (fType == ContentSpecNode::Leaf)
bufToFill.append(chOpenParen);
formatNode
(
this
, UnknownType
, validator
, bufToFill
);
if (fType == ContentSpecNode::Leaf)
bufToFill.append(chCloseParen);
}
1.1 xml-xerces/c/src/validators/common/ContentSpecNode.hpp
Index: ContentSpecNode.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: ContentSpecNode.hpp,v $
* Revision 1.1 2001/02/16 14:17:29 tng
* Schema: Move the common Content Model files that are shared by DTD
* and schema from 'DTD' folder to 'common' folder. By Pei Yong Zhang.
*
* Revision 1.4 2000/03/02 19:55:38 roddey
* This checkin includes many changes done while waiting for the
* 1.1.0 code to be finished. I can't list them all here, but a list is
* available elsewhere.
*
* Revision 1.3 2000/02/24 20:16:48 abagchi
* Swat for removing Log from API docs
*
* Revision 1.2 2000/02/09 21:42:37 abagchi
* Copyright swat
*
* Revision 1.1.1.1 1999/11/09 01:03:14 twl
* Initial checkin
*
* Revision 1.2 1999/11/08 20:45:38 rahul
* Swat for adding in Product name and CVS comment log variable.
*
*/
#if !defined(CONTENTSPECNODE_HPP)
#define CONTENTSPECNODE_HPP
#include <framework/XMLElementDecl.hpp>
#include <util/XercesDefs.hpp>
class XMLBuffer;
class XMLValidator;
class ContentSpecNode
{
public :
// -----------------------------------------------------------------------
// Class specific types
// -----------------------------------------------------------------------
enum NodeTypes
{
Leaf
, ZeroOrOne
, ZeroOrMore
, OneOrMore
, Choice
, Sequence
, UnknownType = -1
};
// -----------------------------------------------------------------------
// Constructors and Destructor
// -----------------------------------------------------------------------
ContentSpecNode();
ContentSpecNode(const unsigned int elemId);
ContentSpecNode
(
const NodeTypes type
, ContentSpecNode* const firstToAdopt
, ContentSpecNode* const secondToAdopt
);
~ContentSpecNode();
// -----------------------------------------------------------------------
// Getter methods
// -----------------------------------------------------------------------
unsigned int getElemId() const;
ContentSpecNode* getFirst();
const ContentSpecNode* getFirst() const;
ContentSpecNode* getSecond();
const ContentSpecNode* getSecond() const;
NodeTypes getType() const;
bool isPCData() const;
ContentSpecNode* orphanFirst();
ContentSpecNode* orphanSecond();
// -----------------------------------------------------------------------
// Setter methods
// -----------------------------------------------------------------------
void setElemId(const unsigned int elemId);
void setFirst(ContentSpecNode* const toAdopt);
void setSecond(ContentSpecNode* const toAdopt);
void setType(const NodeTypes type);
// -----------------------------------------------------------------------
// Miscellaneous
// -----------------------------------------------------------------------
void formatSpec
(
const XMLValidator& validator
, XMLBuffer& bufToFill
) const;
private :
// -----------------------------------------------------------------------
// Unimplemented constructors and operators
// -----------------------------------------------------------------------
ContentSpecNode(const ContentSpecNode&);
void operator=(const ContentSpecNode&);
// -----------------------------------------------------------------------
// Private Data Members
//
// fElemId
// If the type is Leaf, then this is the id of the element. If its
// fgPCDataElemId, then its a PCData node.
//
// fFirst
// fSecond
// The optional first and second nodes. The fType field indicates
// which of these are valid. The validaty constraints are:
//
// Leaf = Neither valid
// ZeroOrOne, ZeroOrMore = First
// Choice, Sequence = First and Second
//
// fType
// The type of node. This controls how many of the child node fields
// are used.
// -----------------------------------------------------------------------
unsigned int fElemId;
ContentSpecNode* fFirst;
ContentSpecNode* fSecond;
NodeTypes fType;
};
// ---------------------------------------------------------------------------
// ContentSpecNode: Constructors and Destructor
// ---------------------------------------------------------------------------
inline ContentSpecNode::ContentSpecNode() :
fElemId(XMLElementDecl::fgInvalidElemId)
, fFirst(0)
, fSecond(0)
, fType(ContentSpecNode::Leaf)
{
}
inline
ContentSpecNode::ContentSpecNode(const unsigned int elemId) :
fElemId(elemId)
, fFirst(0)
, fSecond(0)
, fType(ContentSpecNode::Leaf)
{
}
inline
ContentSpecNode::ContentSpecNode(const NodeTypes type
, ContentSpecNode* const firstToAdopt
, ContentSpecNode* const secondToAdopt) :
fElemId(XMLElementDecl::fgInvalidElemId)
, fFirst(firstToAdopt)
, fSecond(secondToAdopt)
, fType(type)
{
}
inline ContentSpecNode::~ContentSpecNode()
{
// Delete our children, which cause recursive cleanup
delete fFirst;
delete fSecond;
}
// ---------------------------------------------------------------------------
// ContentSpecNode: Getter methods
// ---------------------------------------------------------------------------
inline unsigned int ContentSpecNode::getElemId() const
{
return fElemId;
}
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 bool ContentSpecNode::isPCData() const
{
return ((fType == Leaf) && (fElemId == XMLElementDecl::fgPCDataElemId));
}
inline ContentSpecNode* ContentSpecNode::orphanFirst()
{
ContentSpecNode* retNode = fFirst;
fFirst = 0;
return retNode;
}
inline ContentSpecNode* ContentSpecNode::orphanSecond()
{
ContentSpecNode* retNode = fSecond;
fSecond = 0;
return retNode;
}
// ---------------------------------------------------------------------------
// ContentSpecType: Setter methods
// ---------------------------------------------------------------------------
inline void ContentSpecNode::setElemId(const unsigned int newId)
{
fElemId = newId;
}
inline void ContentSpecNode::setFirst(ContentSpecNode* const toAdopt)
{
delete fFirst;
fFirst = toAdopt;
}
inline void ContentSpecNode::setSecond(ContentSpecNode* const toAdopt)
{
delete fSecond;
fSecond = toAdopt;
}
inline void ContentSpecNode::setType(const NodeTypes type)
{
fType = type;
}
#endif
1.1 xml-xerces/c/src/validators/common/DFAContentModel.cpp
Index: DFAContentModel.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: DFAContentModel.cpp,v $
* Revision 1.1 2001/02/16 14:17:29 tng
* Schema: Move the common Content Model files that are shared by DTD
* and schema from 'DTD' folder to 'common' folder. By Pei Yong Zhang.
*
* Revision 1.5 2000/03/28 19:43:25 roddey
* Fixes for signed/unsigned warnings. New work for two way transcoding
* stuff.
*
* Revision 1.4 2000/03/08 23:52:34 roddey
* Got rid of the use of -1 to represent an invalid transition state,
* and just created a const value that is unsigned. This should make
* some compilers happier.
*
* Revision 1.3 2000/03/02 19:55:38 roddey
* This checkin includes many changes done while waiting for the
* 1.1.0 code to be finished. I can't list them all here, but a list is
* available elsewhere.
*
* Revision 1.2 2000/02/09 21:42:37 abagchi
* Copyright swatswat
*
* Revision 1.1.1.1 1999/11/09 01:03:17 twl
* Initial checkin
*
* Revision 1.2 1999/11/08 20:45:38 rahul
* Swat for adding in Product name and CVS comment log variable.
*
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <util/RuntimeException.hpp>
#include <framework/XMLValidator.hpp>
#include <validators/DTD/CMBinaryOp.hpp>
#include <validators/DTD/CMLeaf.hpp>
#include <validators/DTD/CMUnaryOp.hpp>
#include <validators/DTD/DFAContentModel.hpp>
#include <validators/DTD/ContentSpecNode.hpp>
#include <validators/DTD/DTDElementDecl.hpp>
// ---------------------------------------------------------------------------
// Local static data
//
// gInvalidTrans
// This value represents an invalid transition in each line of the
// transition table.
//
// gEOCFakeId
// gEpsilonFakeId
// We have to put in a couple of special CMLeaf nodes to represent
// special values, using fake element ids that we know won't conflict
// with real element ids.
// ---------------------------------------------------------------------------
static const unsigned int gInvalidTrans = 0xFFFFFFFF;
static const unsigned int gEOCFakeId = 0xFFFFFFF1;
static const unsigned int gEpsilonFakeId = 0xFFFFFFF2;
// ---------------------------------------------------------------------------
// DFAContentModel: Constructors and Destructor
// ---------------------------------------------------------------------------
DFAContentModel::DFAContentModel(const DTDElementDecl& elemDecl) :
fElemDecl(elemDecl)
, fElemMap(0)
, fElemMapSize(0)
, fEmptyOk(false)
, fEOCPos(0)
, fFinalStateFlags(0)
, fFollowList(0)
, fHeadNode(0)
, fLeafCount(0)
, fLeafList(0)
, fSpecNode(0)
, fTransTable(0)
, fTransTableSize(0)
{
//
// Store away our content spec node. This is used all over the place
// here so its easier to store a member pointer than to pass it around.
//
fSpecNode = elemDecl.getContentSpec();
// And build the DFA data structures
buildDFA();
}
DFAContentModel::~DFAContentModel()
{
//
// Clean up all the stuff that is not just temporary representation
// data that was cleaned up after building the DFA.
//
delete [] fFinalStateFlags;
unsigned index;
for (index = 0; index < fTransTableSize; index++)
delete [] fTransTable[index];
delete [] fTransTable;
delete [] fElemMap;
}
// ---------------------------------------------------------------------------
// DFAContentModel: Implementation of the ContentModel virtual interface
// ---------------------------------------------------------------------------
int
DFAContentModel::validateContent( const unsigned int* childIds
, const unsigned int childCount) const
{
//
// If there are no children, then either we fail on the 0th element
// or we return success. It depends upon whether this content model
// accepts empty content, which we determined earlier.
//
if (!childCount)
{
if (fEmptyOk)
return -1;
return 0;
}
//
// Lets loop through the children in the array and move our way
// through the states. Note that we use the fElemMap array to map
// an element index to a state index.
//
unsigned int curState = 0;
unsigned int childIndex = 0;
for (; childIndex < childCount; childIndex++)
{
// Get the current element index out
const unsigned int curElem = childIds[childIndex];
// Look up this child in our element map
unsigned int elemIndex = 0;
for (; elemIndex < fElemMapSize; elemIndex++)
{
if (fElemMap[elemIndex] == curElem)
break;
}
// If we didn't find it, then obviously not valid
if (elemIndex == fElemMapSize)
return childIndex;
//
// Look up the next state for this input symbol when in the
// current state.
//
curState = fTransTable[curState][elemIndex];
// If its not a legal transition then we failed.
if (curState == gInvalidTrans)
return childIndex;
}
//
// We transitioned all the way through the input list. However, that
// does not mean that we ended in a final state. So check whether
// our ending state is a final state.
//
if (!fFinalStateFlags[curState])
return childIndex;
return XMLValidator::Success;
}
// ---------------------------------------------------------------------------
// DFAContentModel: Private helper methods
// ---------------------------------------------------------------------------
void DFAContentModel::buildDFA()
{
unsigned int index;
//
// The first step we need to take is to rewrite the content model using
// our CMNode objects, and in the process get rid of any repetition short
// cuts, converting them into '*' style repetitions or getting rid of
// repetitions altogether.
//
// The conversions done are:
//
// x+ -> (x|x*)
// x? -> (x|epsilon)
//
// This is a relatively complex scenario. What is happening is that we
// create a top level binary node of which the special EOC value is set
// as the right side node. The the left side is set to the rewritten
// syntax tree. The source is the original content model info from the
// decl pool. The rewrite is done by buildSyntaxTree() which recurses the
// decl pool's content of the element and builds a new tree in the
// process.
//
// Note that, during this operation, we set each non-epsilon leaf node's
// DFA state position and count the number of such leafs, which is left
// in the fLeafCount member.
//
CMLeaf* nodeEOC = new CMLeaf(gEOCFakeId);
CMNode* nodeOrgContent = buildSyntaxTree(fElemDecl.getContentSpec());
fHeadNode = new CMBinaryOp
(
ContentSpecNode::Sequence
, nodeOrgContent
, nodeEOC
);
//
// And handle specially the EOC node, which also must be numbered and
// counted as a non-epsilon leaf node. It could not be handled in the
// above tree build because it was created before all that started. We
// save the EOC position since its used during the DFA building loop.
//
fEOCPos = fLeafCount;
nodeEOC->setPosition(fLeafCount++);
//
// Ok, so now we have to iterate the new tree and do a little more work
// now that we know the leaf count. One thing we need to do is to
// calculate the first and last position sets of each node. This is
// cached away in each of the nodes.
//
// Along the way we also set the leaf count in each node as the maximum
// state count. They must know this in order to create their first/last
// position sets.
//
// We also need to build an array of references to the non-epsilon
// leaf nodes. Since we iterate here the same way as we did during the
// initial tree build (which built their position numbers, we will put
// them in the array according to their position values.
//
fLeafList = new CMLeaf*[fLeafCount];
postTreeBuildInit(fHeadNode, 0);
//
// And, moving onward... We now need to build the follow position sets
// for all the nodes. So we allocate an array of pointers to state sets,
// one for each leaf node (i.e. each significant DFA position.)
//
fFollowList = new CMStateSet*[fLeafCount];
for (index = 0; index < fLeafCount; index++)
fFollowList[index] = new CMStateSet(fLeafCount);
calcFollowList(fHeadNode);
//
// Check the DFA for ambiguity. If it is ambiguous, then set the
// ambiguous flag member and keep going.
//
fIsAmbiguous = isAmbiguous();
//
// Check to see whether this content model can handle an empty content,
// which is something we need to optimize by looking now before we
// throw away the info that would tell us that.
//
// If the left node of the head (the top level of the original content)
// is nullable, then its true.
//
fEmptyOk = nodeOrgContent->isNullable();
//
// And finally the big push... Now we build the DFA using all the states
// and the tree we've built up. First we set up the various data
// structures we are going to use while we do this.
//
// First of all we need an array of unique element ids in our content
// model. For each transition table entry, we need a set of contiguous
// indices to represent the transitions for a particular input element.
// So we need to a zero based range of indexes that map to element types.
// This element map provides that mapping.
//
fElemMap = new unsigned int[fLeafCount];
fElemMapSize = 0;
for (unsigned int outIndex = 0; outIndex < fLeafCount; outIndex++)
{
// Get the current leaf's element index
const unsigned int elemId = fLeafList[outIndex]->getId();
// See if the current leaf node's element index is in the list
unsigned int inIndex = 0;
for (; inIndex < fElemMapSize; inIndex++)
{
if (fElemMap[inIndex] == elemId)
break;
}
// If it was not in the list, then add it and bump the map size
if (inIndex == fElemMapSize)
fElemMap[fElemMapSize++] = elemId;
}
//
// Next lets create some arrays, some that that hold transient info
// during the DFA build and some that are permament. These are kind of
// sticky since we cannot know how big they will get, but we don't want
// to use any collection type classes because of performance.
//
// Basically they will probably be about fLeafCount*2 on average, but can
// be as large as 2^(fLeafCount*2), worst case. So we start with
// fLeafCount*4 as a middle ground. This will be very unlikely to ever
// have to expand though, it if does, the overhead will be somewhat ugly.
//
unsigned int curArraySize = fLeafCount * 4;
const CMStateSet** statesToDo = new const CMStateSet*[curArraySize];
fFinalStateFlags = new bool[curArraySize];
fTransTable = new unsigned int*[curArraySize];
//
// Ok we start with the initial set as the first pos set of the head node
// (which is the seq node that holds the content model and the EOC node.)
//
const CMStateSet* setT = new CMStateSet(fHeadNode->getFirstPos());
//
// Init our two state flags. Basically the unmarked state counter is
// always chasing the current state counter. When it catches up, that
// means we made a pass through that did not add any new states to the
// lists, at which time we are done. We could have used a expanding array
// of flags which we used to mark off states as we complete them, but
// this is easier though less readable maybe.
//
unsigned int unmarkedState = 0;
unsigned int curState = 0;
//
// Init the first transition table entry, and put the initial state
// into the states to do list, then bump the current state.
//
fTransTable[curState] = makeDefStateList();
statesToDo[curState] = setT;
curState++;
//
// Ok, almost done with the algorithm from hell... We now enter the
// loop where we go until the states done counter catches up with
// the states to do counter.
//
CMStateSet* newSet = 0;
while (unmarkedState < curState)
{
//
// Get the next unmarked state out of the list of states to do.
// And get the associated transition table entry.
//
setT = statesToDo[unmarkedState];
unsigned int* transEntry = fTransTable[unmarkedState];
// Mark this one final if it contains the EOC state
fFinalStateFlags[unmarkedState] = setT->getBit(fEOCPos);
// Bump up the unmarked state count, marking this state done
unmarkedState++;
// Loop through each possible input symbol in the element map
for (unsigned int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++)
{
//
// Build up a set of states which is the union of all of the
// follow sets of DFA positions that are in the current state. If
// we gave away the new set last time through then create a new
// one. Otherwise, zero out the existing one.
//
if (!newSet)
newSet = new CMStateSet(fLeafCount);
else
newSet->zeroBits();
for (unsigned int leafIndex = 0; leafIndex < fLeafCount; leafIndex++)
{
// If this leaf index (DFA position) is in the current set...
if (setT->getBit(leafIndex))
{
//
// If this leaf is the current input symbol, then we want
// to add its follow list to the set of states to transition
// to from the current state.
//
if (fLeafList[leafIndex]->getId() == fElemMap[elemIndex])
*newSet |= *fFollowList[leafIndex];
}
}
//
// If this new set is not empty, then see if its in the list
// of states to do. If not, then add it.
//
if (!newSet->isEmpty())
{
//
// Search the 'states to do' list to see if this new
// state set is already in there.
//
unsigned int stateIndex = 0;
for (; stateIndex < curState; stateIndex++)
{
if (*statesToDo[stateIndex] == *newSet)
break;
}
// If we did not find it, then add it
if (stateIndex == curState)
{
//
// Put this new state into the states to do and init
// a new entry at the same index in the transition
// table.
//
statesToDo[curState] = newSet;
fTransTable[curState] = makeDefStateList();
// We now have a new state to do so bump the count
curState++;
//
// Null out the new set to indicate we adopted it. This
// will cause the creation of a new set on the next time
// around the loop.
//
newSet = 0;
}
//
// Now set this state in the transition table's entry for this
// element (using its index), with the DFA state we will move
// to from the current state when we see this input element.
//
transEntry[elemIndex] = stateIndex;
// Expand the arrays if we're full
if (curState == curArraySize)
{
//
// Yikes, we overflowed the initial array size, so we've
// got to expand all of these arrays. So adjust up the
// size by 50% and allocate new arrays.
//
const unsigned int newSize = (unsigned int)(curArraySize * 1.5);
const CMStateSet** newToDo = new const CMStateSet*[newSize];
bool* newFinalFlags = new bool[newSize];
unsigned int** newTransTable = new unsigned int*[newSize];
// Copy over all of the existing content
for (unsigned int expIndex = 0; expIndex < curArraySize; expIndex++)
{
newToDo[expIndex] = statesToDo[expIndex];
newFinalFlags[expIndex] = fFinalStateFlags[expIndex];
newTransTable[expIndex] = fTransTable[expIndex];
}
// Clean up the old stuff
delete [] statesToDo;
delete [] fFinalStateFlags;
delete [] fTransTable;
// Store the new array size and pointers
curArraySize = newSize;
statesToDo = newToDo;
fFinalStateFlags = newFinalFlags;
fTransTable = newTransTable;
}
}
}
}
// Store the current state count in the trans table size
fTransTableSize = curState;
// If the last temp set was not stored, then clean it up
if (newSet)
delete newSet;
//
// Now we can clean up all of the temporary data that was needed during
// DFA build.
//
delete fHeadNode;
fHeadNode = 0;
for (index = 0; index < fLeafCount; index++)
delete fFollowList[index];
for (index = 0; index < curState; index++)
delete (CMStateSet*)statesToDo[index];
delete [] fLeafList;
delete [] fFollowList;
delete [] statesToDo;
}
CMNode* DFAContentModel::buildSyntaxTree(const ContentSpecNode* const curNode)
{
// Initialize a return node pointer
CMNode* retNode = 0;
// Get the spec type of the passed node
const ContentSpecNode::NodeTypes curType = curNode->getType();
if (curType == ContentSpecNode::Leaf)
{
//
// Create a new leaf node, and pass it the current leaf count, which
// is its DFA state position. Bump the leaf count after storing it.
// This makes the positions zero based since we store first and then
// increment.
//
retNode = new CMLeaf(curNode->getElemId(), fLeafCount++);
}
else
{
//
// Its not a leaf, so we have to recurse its left and maybe right
// nodes. Save both values before we recurse and trash the node.
//
const ContentSpecNode* leftNode = curNode->getFirst();
const ContentSpecNode* rightNode = curNode->getSecond();
if ((curType == ContentSpecNode::Choice)
|| (curType == ContentSpecNode::Sequence))
{
//
// Recurse on both children, and return a binary op node with the
// two created sub nodes as its children. The node type is the
// same type as the source.
//
CMNode* newLeft = buildSyntaxTree(leftNode);
CMNode* newRight = buildSyntaxTree(rightNode);
retNode = new CMBinaryOp(curType, newLeft, newRight);
}
else if (curType == ContentSpecNode::ZeroOrMore)
{
// This one is fine as is, just change to our form
retNode = new CMUnaryOp(curType, buildSyntaxTree(leftNode));
}
else if (curType == ContentSpecNode::ZeroOrOne)
{
// Convert to (x|epsilon)
CMNode* newLeft = buildSyntaxTree(leftNode);
retNode = new CMBinaryOp
(
ContentSpecNode::Choice
, newLeft
, new CMLeaf(gEpsilonFakeId)
);
}
else if (curType == ContentSpecNode::OneOrMore)
{
// Convert to (x,x*)
CMNode* newLeft = buildSyntaxTree(leftNode);
CMNode* newLeft2 = buildSyntaxTree(leftNode);
retNode = new CMBinaryOp
(
ContentSpecNode::Sequence
, newLeft
, new CMUnaryOp(ContentSpecNode::ZeroOrMore, newLeft2)
);
}
else
{
ThrowXML(RuntimeException, XMLExcepts::CM_UnknownCMSpecType);
}
}
return retNode;
}
void DFAContentModel::calcFollowList(CMNode* const curNode)
{
// Get the spec type of the passed node
const ContentSpecNode::NodeTypes curType = curNode->getType();
if (curType == ContentSpecNode::Choice)
{
// Just recurse
calcFollowList(((CMBinaryOp*)curNode)->getLeft());
calcFollowList(((CMBinaryOp*)curNode)->getRight());
}
else if (curType == ContentSpecNode::Sequence)
{
// Recurse before we process this node
calcFollowList(((CMBinaryOp*)curNode)->getLeft());
calcFollowList(((CMBinaryOp*)curNode)->getRight());
//
// Now handle our level. We use our left child's last pos set and our
// right child's first pos set, so get them now for convenience.
//
const CMStateSet& last = ((CMBinaryOp*)curNode)->getLeft()->getLastPos();
const CMStateSet& first = ((CMBinaryOp*)curNode)->getRight()->getFirstPos();
//
// Now, for every position which is in our left child's last set
// add all of the states in our right child's first set to the
// follow set for that position.
//
for (unsigned int index = 0; index < fLeafCount; index++)
{
if (last.getBit(index))
*fFollowList[index] |= first;
}
}
else if (curType == ContentSpecNode::ZeroOrMore)
{
// Recurse first
calcFollowList(((CMUnaryOp*)curNode)->getChild());
//
// Now handle our level. We use our own first and last position
// sets, so get them up front.
//
const CMStateSet& first = curNode->getFirstPos();
const CMStateSet& last = curNode->getLastPos();
//
// For every position which is in our last position set, add all
// of our first position states to the follow set for that
// position.
//
for (unsigned int index = 0; index < fLeafCount; index++)
{
if (last.getBit(index))
*fFollowList[index] |= first;
}
}
else if ((curType == ContentSpecNode::OneOrMore)
|| (curType == ContentSpecNode::ZeroOrOne))
{
ThrowXML1(RuntimeException, XMLExcepts::CM_NotValidForSpecType, "CalcFollowList");
}
}
bool DFAContentModel::isAmbiguous() const
{
unsigned int index;
//
// Run through the current leaves and remember the min and max element
// ids. These will be used to create a bit set that will map to element
// ids (adjusted by the min value.)
//
// Do fLeafCount - 1 because we don't want to pick up the 'EOC' node,
// which has a very large dummy value in it.
//
unsigned int minId = 0xFFFFFFFF;
unsigned int maxId = 0;
for (index = 0; index < fLeafCount - 1; index++)
{
const unsigned int curId = fLeafList[index]->getId();
if (curId < minId)
minId = curId;
if (curId > maxId)
maxId = curId;
}
//
// Ok, now we can create a range value that represents the spread
// between the min/max element value. The range can never be larger
// than the number of elements in the content model, so it would
// never be outrageously large unless the content model was just
// totally pathological.
//
// With this number we can create a state set that has a bit per
// possible entry in the leaf array.
//
const unsigned int idRange = (maxId - minId) + 1;
CMStateSet idSet(idRange);
// Check each follow list
for (index = 0; index < fLeafCount - 1; index++)
{
// Get the current follow list set
const CMStateSet* curSet = fFollowList[index];
//
// For each possible leaf, we now go through and get the element
// id, adjust it to zero base it, then check it in the idSet. If
// that bit is already on, its ambiguous. Else set that bit and
// keep going.
//
for (unsigned int inner = 0; inner < fLeafCount - 1; inner++)
{
// If this bit is not on in the follow set, skip to next
if (!curSet->getBit(inner))
continue;
// Get the adjusted id value for the element in the follow list
const unsigned int adjustedId = fLeafList[inner]->getId() - minId;
if (idSet.getBit(adjustedId))
return true;
idSet.setBit(adjustedId);
}
// Zero out the bitset for the next round
idSet.zeroBits();
}
return false;
}
//
// gInvalidTrans is used to represent bad transitions in the transition table
// entry for each state. So each entry is initialized to that value. This
// method creates a new entry and initializes it.
//
unsigned int* DFAContentModel::makeDefStateList() const
{
unsigned int* retArray = new unsigned int[fElemMapSize];
for (unsigned int index = 0; index < fElemMapSize; index++)
retArray[index] = gInvalidTrans;
return retArray;
}
int DFAContentModel::postTreeBuildInit( CMNode* const nodeCur
, const unsigned int curIndex)
{
// Set the maximum states on this node
nodeCur->setMaxStates(fLeafCount);
// Get the spec type of the passed node
const ContentSpecNode::NodeTypes curType = nodeCur->getType();
// Get a copy of the index we can modify
unsigned int newIndex = curIndex;
// Recurse as required
if ((curType == ContentSpecNode::Choice)
|| (curType == ContentSpecNode::Sequence))
{
newIndex = postTreeBuildInit(((CMBinaryOp*)nodeCur)->getLeft(), newIndex);
newIndex = postTreeBuildInit(((CMBinaryOp*)nodeCur)->getRight(), newIndex);
}
else if (curType == ContentSpecNode::ZeroOrMore)
{
newIndex = postTreeBuildInit(((CMUnaryOp*)nodeCur)->getChild(), newIndex);
}
else if (curType == ContentSpecNode::Leaf)
{
//
// Put this node in the leaf list at the current index if its
// a non-epsilon leaf.
//
if (((CMLeaf*)nodeCur)->getId() != gEpsilonFakeId)
fLeafList[newIndex++] = (CMLeaf*)nodeCur;
}
else
{
ThrowXML(RuntimeException, XMLExcepts::CM_UnknownCMSpecType);
}
return newIndex;
}
1.1 xml-xerces/c/src/validators/common/DFAContentModel.hpp
Index: DFAContentModel.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: DFAContentModel.hpp,v $
* Revision 1.1 2001/02/16 14:17:29 tng
* Schema: Move the common Content Model files that are shared by DTD
* and schema from 'DTD' folder to 'common' folder. By Pei Yong Zhang.
*
* Revision 1.4 2000/03/02 19:55:38 roddey
* This checkin includes many changes done while waiting for the
* 1.1.0 code to be finished. I can't list them all here, but a list is
* available elsewhere.
*
* Revision 1.3 2000/02/24 20:16:48 abagchi
* Swat for removing Log from API docs
*
* Revision 1.2 2000/02/09 21:42:37 abagchi
* Copyright swat
*
* Revision 1.1.1.1 1999/11/09 01:03:19 twl
* Initial checkin
*
* Revision 1.2 1999/11/08 20:45:38 rahul
* Swat for adding in Product name and CVS comment log variable.
*
*/
#if !defined(DFACONTENTMODEL_HPP)
#define DFACONTENTMODEL_HPP
#include <util/XercesDefs.hpp>
#include <framework/XMLContentModel.hpp>
class ContentSpecNode;
class CMLeaf;
class CMNode;
class CMStateSet;
class DTDElementDecl;
//
// 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 DTDElementDecl& elemDecl);
virtual ~DFAContentModel();
// -----------------------------------------------------------------------
// Implementation of the virtual content model interface
// -----------------------------------------------------------------------
virtual bool getIsAmbiguous() const;
virtual int validateContent
(
const unsigned int* childIds
, const unsigned int childCount
) const;
private :
// -----------------------------------------------------------------------
// Unimplemented constructors and operators
// -----------------------------------------------------------------------
DFAContentModel();
DFAContentModel(const DFAContentModel&);
void operator=(const DFAContentModel&);
// -----------------------------------------------------------------------
// Private helper methods
// -----------------------------------------------------------------------
void buildDFA();
CMNode* buildSyntaxTree(const ContentSpecNode* const curNode);
void calcFollowList(CMNode* const curNode);
bool isAmbiguous() const;
unsigned int* makeDefStateList() const;
int postTreeBuildInit
(
CMNode* const nodeCur
, const unsigned int curIndex
);
// -----------------------------------------------------------------------
// Private data members
//
// fElemDecl
// The element decl object of the element that this is the content
// model for. Its just stored here to avoid passing it around all
// over the place while building up the DFA.
//
// 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.
//
// 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.
//
// fIsAmbiguous
// This flag is set during construction if the content model is
// ambiguous. This will be used by the scanner to report an error
// and is available for later perusal if required.
//
// 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.
//
// fSpecNode
// The content spec node for the element that this object represents
// the content of. This info is needed a good bit so we get it once
// and keep it. We don't own it, we just reference it.
//
// 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.
// -----------------------------------------------------------------------
const DTDElementDecl& fElemDecl;
unsigned int* fElemMap;
unsigned int fElemMapSize;
bool fEmptyOk;
unsigned int fEOCPos;
bool* fFinalStateFlags;
CMStateSet** fFollowList;
CMNode* fHeadNode;
bool fIsAmbiguous;
unsigned int fLeafCount;
CMLeaf** fLeafList;
const ContentSpecNode* fSpecNode;
unsigned int** fTransTable;
unsigned int fTransTableSize;
};
inline bool DFAContentModel::getIsAmbiguous() const
{
return fIsAmbiguous;
}
#endif
1.1 xml-xerces/c/src/validators/common/MixedContentModel.cpp
Index: MixedContentModel.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: MixedContentModel.cpp,v $
* Revision 1.1 2001/02/16 14:17:29 tng
* Schema: Move the common Content Model files that are shared by DTD
* and schema from 'DTD' folder to 'common' folder. By Pei Yong Zhang.
*
* Revision 1.5 2000/05/15 22:31:32 andyh
* Replace #include<memory.h> with <string.h> everywhere.
*
* Revision 1.4 2000/03/18 00:00:05 roddey
* Initial updates for two way transcoding support
*
* Revision 1.3 2000/03/02 19:55:39 roddey
* This checkin includes many changes done while waiting for the
* 1.1.0 code to be finished. I can't list them all here, but a list is
* available elsewhere.
*
* Revision 1.2 2000/02/09 21:42:39 abagchi
* Copyright swatswat
*
* Revision 1.1.1.1 1999/11/09 01:03:43 twl
* Initial checkin
*
* Revision 1.3 1999/11/08 20:45:43 rahul
* Swat for adding in Product name and CVS comment log variable.
*
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <string.h>
#include <util/RuntimeException.hpp>
#include <framework/XMLElementDecl.hpp>
#include <framework/XMLValidator.hpp>
#include <validators/DTD/ContentSpecNode.hpp>
#include <validators/DTD/DTDElementDecl.hpp>
#include <validators/DTD/MixedContentModel.hpp>
#include <validators/DTD/CMStateSet.hpp>
// ---------------------------------------------------------------------------
// MixedContentModel: Constructors and Destructor
// ---------------------------------------------------------------------------
MixedContentModel::MixedContentModel(const DTDElementDecl& parentElem)
{
//
// 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<unsigned int> childIds(64);
//
// 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.
//
const ContentSpecNode* curNode = parentElem.getContentSpec();
if (!curNode)
ThrowXML(RuntimeException, XMLExcepts::CM_NoParentCSN);
// And now call the private recursive method that iterates the tree
buildChildList(*curNode, childIds);
//
// And now we know how many elements we need in our member list. So
// fill them in.
//
fCount = childIds.size();
fChildIds = new unsigned int[fCount];
memcpy(fChildIds, childIds.rawData(), fCount * sizeof(unsigned int));
}
MixedContentModel::~MixedContentModel()
{
delete [] fChildIds;
}
// ---------------------------------------------------------------------------
// MixedContentModel: Getter methods
// ---------------------------------------------------------------------------
bool MixedContentModel::hasDups() const
{
// Can't have dups if only one child
if (fCount == 1)
return false;
for (unsigned int index = 0; index < fCount; index++)
{
const unsigned int curVal = fChildIds[index];
for (unsigned int iIndex = 0; iIndex < fCount; iIndex++)
{
if (iIndex == index)
continue;
if (curVal == fChildIds[iIndex])
return true;
}
}
return false;
}
// ---------------------------------------------------------------------------
// MixedContentModel: Implementation of the ContentModel virtual interface
// ---------------------------------------------------------------------------
bool MixedContentModel::getIsAmbiguous() const
{
if (fCount < 2)
return false;
unsigned int index;
//
// Run through the children and remember the min and max element ids.
// These will be used to create a bit set that will map to element ids
// (adjusted by the min value.)
//
// Note that we skip the 0th element because its the PCDATA one.
//
unsigned int minId = 0xFFFFFFFF;
unsigned int maxId = 0;
for (index = 1; index < fCount; index++)
{
const unsigned int curId = fChildIds[index];
if (curId < minId)
minId = curId;
if (curId > maxId)
maxId = curId;
}
//
// Ok, now we can create a range value that represents the spread
// between the min/max element value.
//
// With this number we can create a state set that has a bit per
// possible entry in the leaf array.
//
const unsigned int idRange = (maxId - minId) + 1;
CMStateSet idSet(idRange);
for (index = 1; index < fCount; index++)
{
const unsigned int adjustedId = fChildIds[index] - minId;
if (idSet.getBit(adjustedId))
return true;
idSet.setBit(adjustedId);
}
return false;
}
int
MixedContentModel::validateContent( const unsigned int* childIds
, const unsigned int childCount) const
{
// Use an outer index to search the passed list of children
for (unsigned int outIndex = 0; outIndex < childCount; outIndex++)
{
// Get the current child out of the source index
const unsigned int curChild = childIds[outIndex];
// If its PCDATA, then we just accept that
if (curChild == XMLElementDecl::fgPCDataElemId)
continue;
// Otherwise try to find it in our list using an inner index
unsigned int inIndex = 0;
for (; inIndex < fCount; inIndex++)
{
if (curChild == fChildIds[inIndex])
break;
}
//
// We did not find this one, so the validation failed. We return
// the outer index, which is the index of the child that failed.
//
if (inIndex == fCount)
return outIndex;
}
// Return success
return XMLValidator::Success;
}
// ---------------------------------------------------------------------------
// MixedContentModel: Private helper methods
// ---------------------------------------------------------------------------
void
MixedContentModel::buildChildList( const ContentSpecNode& curNode
, ValueVectorOf<unsigned int>& toFill)
{
// 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)
{
toFill.addElement(curNode.getElemId());
return;
}
// Get both the child node pointers
const ContentSpecNode* leftNode = curNode.getFirst();
const ContentSpecNode* rightNode = curNode.getSecond();
// And recurse according to the type of node
if ((curType == ContentSpecNode::Choice)
|| (curType == ContentSpecNode::Sequence))
{
// Recurse on the left and right nodes
buildChildList(*leftNode, toFill);
// The last node of a choice or sequence has a null right
if (rightNode)
buildChildList(*rightNode, toFill);
}
else if ((curType == ContentSpecNode::OneOrMore)
|| (curType == ContentSpecNode::ZeroOrOne)
|| (curType == ContentSpecNode::ZeroOrMore))
{
// Just do the left node on this one
buildChildList(*leftNode, toFill);
}
}
1.1 xml-xerces/c/src/validators/common/MixedContentModel.hpp
Index: MixedContentModel.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: MixedContentModel.hpp,v $
* Revision 1.1 2001/02/16 14:17:29 tng
* Schema: Move the common Content Model files that are shared by DTD
* and schema from 'DTD' folder to 'common' folder. By Pei Yong Zhang.
*
* Revision 1.3 2000/02/24 20:16:49 abagchi
* Swat for removing Log from API docs
*
* Revision 1.2 2000/02/09 21:42:39 abagchi
* Copyright swat
*
* Revision 1.1.1.1 1999/11/09 01:03:45 twl
* Initial checkin
*
* Revision 1.3 1999/11/08 20:45:43 rahul
* Swat for adding in Product name and CVS comment log variable.
*
*/
#if !defined(MIXEDCONTENTMODEL_HPP)
#define MIXEDCONTENTMODEL_HPP
#include <util/ValueVectorOf.hpp>
#include <framework/XMLContentModel.hpp>
class ContentSpecNode;
class DTDElementDecl;
//
// 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 DTDElementDecl& parentElem
);
~MixedContentModel();
// -----------------------------------------------------------------------
// Getter methods
// -----------------------------------------------------------------------
bool hasDups() const;
// -----------------------------------------------------------------------
// Implementation of the ContentModel virtual interface
// -----------------------------------------------------------------------
virtual bool getIsAmbiguous() const;
virtual int validateContent
(
const unsigned int* childIds
, const unsigned int childCount
) const;
private :
// -----------------------------------------------------------------------
// Private helper methods
// -----------------------------------------------------------------------
void buildChildList
(
const ContentSpecNode& curNode
, ValueVectorOf<unsigned int>& toFill
);
// -----------------------------------------------------------------------
// Unimplemented constructors and operators
// -----------------------------------------------------------------------
MixedContentModel();
MixedContentModel(const MixedContentModel&);
void operator=(const MixedContentModel&);
// -----------------------------------------------------------------------
// Private data members
//
// fCount
// The count of possible children in the fChildIds member.
//
// fChildIds
// The list of possible children that we have to accept. This array
// is allocated as large as needed in the constructor.
// -----------------------------------------------------------------------
unsigned int fCount;
unsigned int* fChildIds;
};
#endif
1.1 xml-xerces/c/src/validators/common/SimpleContentModel.cpp
Index: SimpleContentModel.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: SimpleContentModel.cpp,v $
* Revision 1.1 2001/02/16 14:17:29 tng
* Schema: Move the common Content Model files that are shared by DTD
* and schema from 'DTD' folder to 'common' folder. By Pei Yong Zhang.
*
* Revision 1.4 2000/03/03 22:33:00 roddey
* Fixed a bug in SimpleContentModel that allowed an <a/> to be taken
* as valid for a content model of (a,b).
*
* Revision 1.3 2000/03/02 19:55:40 roddey
* This checkin includes many changes done while waiting for the
* 1.1.0 code to be finished. I can't list them all here, but a list is
* available elsewhere.
*
* Revision 1.2 2000/02/09 21:42:39 abagchi
* Copyright swatswat
*
* Revision 1.1.1.1 1999/11/09 01:03:46 twl
* Initial checkin
*
* Revision 1.2 1999/11/08 20:45:44 rahul
* Swat for adding in Product name and CVS comment log variable.
*
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <util/RuntimeException.hpp>
#include <validators/DTD/SimpleContentModel.hpp>
// ---------------------------------------------------------------------------
// SimpleContentModel: Implementation of the ContentModel virtual interface
// ---------------------------------------------------------------------------
//
// For this content model, the only way it can be ambiguous is if it is a
// choice and both sides are the same.
//
bool SimpleContentModel::getIsAmbiguous() const
{
if (fOp != ContentSpecNode::Choice)
return false;
return fFirstChild == fSecondChild;
}
//
// 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.
//
int
SimpleContentModel::validateContent(const unsigned int* childIds
, const unsigned int childCount) const
{
//
// According to the type of operation, we do the correct type of
// content check.
//
unsigned int index;
switch(fOp)
{
case ContentSpecNode::Leaf :
//
// There can only be one child and it has to be of the
// element type we stored.
//
if (!childCount)
return 0;
if (childIds[0] != fFirstChild)
return 0;
if (childCount > 1)
return 1;
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) && (childIds[0] != fFirstChild))
return 0;
if (childCount > 1)
return 1;
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 (childIds[index] != fFirstChild)
return index;
}
}
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)
return 0;
for (index = 0; index < childCount; index++)
{
if (childIds[index] != fFirstChild)
return index;
}
break;
case ContentSpecNode::Choice :
//
// There can only be one child, and it must be one of the
// two types we stored.
//
if (!childCount)
return 0;
if ((childIds[0] != fFirstChild) && (childIds[0] != fSecondChild))
return 0;
if (childCount > 1)
return 1;
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)
return 0;
// If we have at least one child, its got to match our first
if ((childCount >= 1) && (childIds[0] != fFirstChild))
return 0;
// If we hvae at least two children, its got to match our second
if ((childCount >= 2) && (childIds[1] != fSecondChild))
return 1;
// If we only had one (and it was valid), then too few children
if (childCount == 1)
return 1;
// And finally check for too many children
if (childCount > 2)
return 2;
break;
default :
ThrowXML(RuntimeException, XMLExcepts::CM_UnknownCMSpecType);
break;
}
return -1;
}
1.1 xml-xerces/c/src/validators/common/SimpleContentModel.hpp
Index: SimpleContentModel.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: SimpleContentModel.hpp,v $
* Revision 1.1 2001/02/16 14:17:29 tng
* Schema: Move the common Content Model files that are shared by DTD
* and schema from 'DTD' folder to 'common' folder. By Pei Yong Zhang.
*
* Revision 1.3 2000/02/24 20:16:49 abagchi
* Swat for removing Log from API docs
*
* Revision 1.2 2000/02/09 21:42:39 abagchi
* Copyright swat
*
* Revision 1.1.1.1 1999/11/09 01:03:48 twl
* Initial checkin
*
* Revision 1.2 1999/11/08 20:45:44 rahul
* Swat for adding in Product name and CVS comment log variable.
*
*/
#if !defined(SIMPLECONTENTMODEL_HPP)
#define SIMPLECONTENTMODEL_HPP
#include <framework/XMLContentModel.hpp>
#include <validators/DTD/ContentSpecNode.hpp>
//
// 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 ids.
//
class SimpleContentModel : public XMLContentModel
{
public :
// -----------------------------------------------------------------------
// Constructors and Destructor
// -----------------------------------------------------------------------
SimpleContentModel
(
const unsigned int firstChildId
, const unsigned int secondChildId
, const ContentSpecNode::NodeTypes cmOp
);
~SimpleContentModel();
// -----------------------------------------------------------------------
// Implementation of the ContentModel virtual interface
// -----------------------------------------------------------------------
virtual bool getIsAmbiguous() const;
virtual int validateContent
(
const unsigned int* childIds
, const unsigned int childCount
) const;
private :
// -----------------------------------------------------------------------
// Unimplemented constructors and operators
// -----------------------------------------------------------------------
SimpleContentModel();
SimpleContentModel(const SimpleContentModel&);
void operator=(const SimpleContentModel&);
// -----------------------------------------------------------------------
// Private data members
//
// fFirstChild
// fSecondChild
// The element idsof 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.)
// -----------------------------------------------------------------------
unsigned int fFirstChild;
unsigned int fSecondChild;
ContentSpecNode::NodeTypes fOp;
};
// ---------------------------------------------------------------------------
// SimpleContentModel: Constructors and Destructor
// ---------------------------------------------------------------------------
inline
SimpleContentModel::SimpleContentModel( const unsigned int firstChildId
, const unsigned int secondChildId
, const ContentSpecNode::NodeTypes cmOp) :
fOp(cmOp)
, fFirstChild(firstChildId)
, fSecondChild(secondChildId)
{
}
inline SimpleContentModel::~SimpleContentModel()
{
}
#endif