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