dbertoni    00/12/20 20:00:41

  Added:       c/src/XSLT CountersTable.cpp CountersTable.hpp
  Log:
  Moved code from ElemNumber.hpp and ElemNumber.cpp to new files.
  
  Revision  Changes    Path
  1.1                  xml-xalan/c/src/XSLT/CountersTable.cpp
  
  Index: CountersTable.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 "Xalan" 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 [EMAIL PROTECTED]
   *
   * 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/>.
   */
  #include "CountersTable.hpp"
  
  
  
  #include <algorithm>
  
  
  
  #include "ElemNumber.hpp"
  #include "StylesheetExecutionContext.hpp"
  
  
  
  inline void
  CountersTable::appendBtoFList(
                        NodeVectorType&         flist,
                        NodeVectorType&         blist)
  {
  #if !defined(XALAN_NO_NAMESPACES)
        using std::back_inserter;
        using std::copy;
  #endif
  
        flist.reserve(flist.size() + blist.size());
  
        copy(
                blist.rbegin(),
                blist.rend(),
                back_inserter(flist));
  }
  
  
  
  int
  CountersTable::countNode(
                        StylesheetExecutionContext&             support,
                        const ElemNumber*                               
numberElem,
                        XalanNode*                                              
node)
  {
        int             count = 0;
  
        CounterVectorType&      counters = m_counterMap[numberElem];
  
        const CounterVectorType::size_type      nCounters = counters.size();
  
        XalanNode*      target = numberElem->getTargetNode(support, node);
  
        if(0 != target)
        {
                for(CounterVectorType::size_type i = 0; i < nCounters; i++)
                {    
                        const Counter&  counter = counters[i];
  
                        count = counter.getPreviouslyCounted(support, target);
  
                        if(count > 0)
                                return count;
                }
  
                // In the loop below, we collect the nodes in backwards doc 
order, so 
                // we don't have to do inserts, but then we store the nodes in 
forwards 
                // document order, so we don't have to insert nodes into that 
list, 
                // so that's what the appendBtoFList stuff is all about.  In 
cases 
                // of forward counting by one, this will mean a single node 
copy from 
                // the backwards list (m_newFound) to the forwards list
                // (counter.m_countNodes).
                count = 0;
                for(; 0 != target; target = 
numberElem->getPreviousNode(support, target))
                {   
                        // First time in, we should not have to check for 
previous counts, 
                        // since the original target node was already checked 
in the 
                        // block above.
                        if(0 != count)  
                        {
                                for(CounterVectorType::size_type i = 0; i < 
nCounters; ++i)
                                {
                                        Counter&        counter = counters[i];
  
                                        const unsigned int      cacheLen = 
counter.m_countNodes.size();
  
                                        if(cacheLen > 0 && 
counter.m_countNodes[cacheLen - 1] == target)
                                        {
                                                count += cacheLen + 
counter.m_countNodesStartCount;
  
                                                if(cacheLen > 0)
                                                {
                                                        
appendBtoFList(counter.m_countNodes, m_newFound);
                                                }
  
                                                m_newFound.clear();
  
                                                return count;
                                        }
                                }
                        }
  
                        m_newFound.push_back(target);
  
                        ++count;
                }
  
                // If we got to this point, then we didn't find a counter, so 
make 
                // one and add it to the list.
                counters.push_back(Counter(numberElem));
  
                Counter&        counter = counters.back();
  
                appendBtoFList(counter.m_countNodes, m_newFound);
  
                m_newFound.clear();
        }
  
        return count;
  }
  
  
  
  int
  Counter::getPreviouslyCounted(
                StylesheetExecutionContext&             executionContext,
                const XalanNode*                                node) const
  {
        const int       n = m_countNodes.size();
  
        int                     result = 0;
  
        for(int i = n - 1; i >= 0; --i)
        {
                const XalanNode* const  countedNode = m_countNodes[i];
  
                if(node == countedNode)
                {
                        // Since the list is in backwards order, the count is 
                        // how many are in the rest of the list.
                        result = i + 1 + m_countNodesStartCount;
                        break;
                }
  
                // Try to see if the given node falls after the counted node...
                // if it does, don't keep searching backwards.
                if(executionContext.isNodeAfter(*countedNode, *node))
                        break;
        }
  
        return result;
  }
  
  
  
  1.1                  xml-xalan/c/src/XSLT/CountersTable.hpp
  
  Index: CountersTable.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 "Xalan" 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 [EMAIL PROTECTED]
   *
   * 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/>.
   */
  #if !defined(XALAN_COUNTERSTABLE_HEADER_GUARD_1357924680)
  #define XALAN_ELEMNUMBER_HEADER_GUARD_1357924680 
  
  /**
   * $Id: CountersTable.hpp,v 1.1 2000/12/21 04:00:41 dbertoni Exp $
   * 
   * $State: Exp $
   * 
   */
  
  // Base include file.  Must be first.
  #include <XSLT/XSLTDefinitions.hpp>
  
  
  
  #include <map>
  #include <vector>
  
  
  
  #include "XPath/MutableNodeRefList.hpp"
  
  
  
  class ElemNumber;
  class StylesheetExecutionContext;
  
  
  
  /**
   * <meta name="usage" content="internal"/>
   * A class that does incremental counting for support of xsl:number.
   * This class stores a cache of counted nodes (m_countNodes). 
   * It tries to cache the counted nodes in document order... 
   * the node count is based on its position in the cache list 
   */
  struct Counter
  {
  #if defined(XALAN_NO_NAMESPACES)
        typedef vector<XalanNode*>                      NodeVectorType;
  #else
        typedef std::vector<XalanNode*>         NodeVectorType;
  #endif
        /**
         * The start count from where m_countNodes counts 
         * from.  In other words, the count of a given node 
         * in the m_countNodes vector is node position + 
         * m_countNodesStartCount.
         */
        int                                     m_countNodesStartCount;
  
        /**
         * A vector of all nodes counted so far.
         */
        NodeVectorType          m_countNodes;
  
        /**
         * The node from where the counting starts.  This is needed to 
         * find a counter if the node being counted is not immediatly
         * found in the m_countNodes vector.
         */
        const XalanNode*        m_fromNode;
  
        /**
         * The owning xsl:number element.
         */
        const ElemNumber*       m_numberElem;
  
        /**
         * Construct a counter object.
         */
        Counter(
                        const ElemNumber*       numberElem,
                        NodeVectorType&         countNodes) :
                m_countNodesStartCount(0),
                m_countNodes(countNodes),
                m_fromNode(0),
                m_numberElem(numberElem)
        {
        }
  
        /**
         * Construct a counter object.
         */
        Counter(const ElemNumber*       numberElem = 0) :
                m_countNodesStartCount(0),
                m_countNodes(),
                m_fromNode(0),
                m_numberElem(numberElem)
        {
        }
  
        /**
         * Try to find a node that was previously counted. If found, return a
         * positive integer that corresponds to the count.
         * @param node The node to be counted.
         * @returns The count of the node, or -1 if not found.
         */
        int
        getPreviouslyCounted(
                        StylesheetExecutionContext&             support,
                        const XalanNode*                                node) 
const;
  
        /**
         * Get the last node in the list.
         */
        XalanNode*
        getLast() const
        {
                return m_countNodes.size() == 0 ? 0 : m_countNodes.back();
        }
  };
  
  
  
  /**
   * <meta name="usage" content="internal"/>
   * This is a table of counters, keyed by ElemNumber objects, each 
   * of which has a list of Counter objects.  This really isn't a true 
   * table, it is more like a list of lists (there must be a technical 
   * term for that...).
   */
  class CountersTable
  {
  public:
  
  #if defined(XALAN_NO_NAMESPACES)
        typedef vector<Counter>                                 
CounterVectorType;
        typedef map<const ElemNumber*,
                                CounterVectorType,
                                less<const ElemNumber*> >       
ElemToCounterVectorMapType;
  #else
        typedef std::vector<Counter>                    CounterVectorType;
        typedef std::map<const ElemNumber*,
                                         CounterVectorType>             
ElemToCounterVectorMapType;
  #endif
  
        typedef Counter::NodeVectorType                 NodeVectorType;
  
        /**
         * Construct a CountersTable.
         */
        CountersTable() : 
                m_newFound(),
                m_counterMap()
        {
        };
  
  
        /**
         * Count forward until the given node is found, or until 
         * we have looked to the given amount.
         *
         * @executionContext The current execution context;
         * @numberElem The executing ElemNumber
         * @node The node to count.
         * @return The node count, or 0 if not found.
         */
        int
        countNode(
                        StylesheetExecutionContext&             
executionContext,
                        const ElemNumber*                               
numberElem,
                        XalanNode*                                              
node);
  
        /**
         * Clear all cached data from the table.
         */
        void
        reset()
        {
                m_newFound.clear();
  
                m_counterMap.clear();
        }
  
  private:
  
        /**
         * Add a list of counted nodes that were built in backwards document 
         * order, or a list of counted nodes that are in forwards document 
         * order.
         */
        void
        appendBtoFList(
                        NodeVectorType&         flist,
                        NodeVectorType&         blist);
  
        /**
         * A map which holds counters for ElemNumber instances.
         */
        ElemToCounterVectorMapType      m_counterMap;
  
  
        /**
         * A vector to use as a temporary buffer.
         */
        NodeVectorType                          m_newFound;
  };
  
  
  #endif        // !defined(XALAN_COUNTERSTABLE_HEADER_GUARD_1357924680)
  
  
  

Reply via email to