blob: cad3f28377d09a3654ca5b2eaa82f67011744444 [file] [log] [blame]
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !defined(XALAN_COUNTERSTABLE_HEADER_GUARD_1357924680)
#define XALAN_COUNTERSTABLE_HEADER_GUARD_1357924680
/**
* $Id$
*
* $State$
*
*/
// Base include file. Must be first.
#include <xalanc/XSLT/XSLTDefinitions.hpp>
//#include <xalanc/Include/XalanVector.hpp>
#include <vector>
#include "xalanc/XPath/MutableNodeRefList.hpp"
XALAN_CPP_NAMESPACE_BEGIN
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
{
typedef unsigned long CountType;
typedef XALAN_STD_QUALIFIER vector<XalanNode*> NodeVectorType;
/**
* 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.
*/
CountType 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 0 if not found.
*/
CountType
getPreviouslyCounted(
StylesheetExecutionContext& support,
const XalanNode* node) const;
/**
* Get the last node in the list.
*/
XalanNode*
getLast() const
{
return m_countNodes.empty() == true ? 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:
typedef Counter::CountType CountType;
typedef XALAN_STD_QUALIFIER vector<Counter> CounterVectorType;
typedef XALAN_STD_QUALIFIER vector<CounterVectorType> ElemCounterVectorVectorType;
typedef Counter::NodeVectorType NodeVectorType;
/**
* Construct a CountersTable.
*/
CountersTable(unsigned long theSize = 0) :
m_countersVector(),
m_newFound()
{
resize(theSize);
};
~CountersTable()
{
}
/**
* Resize the table. The must be done prior
* to using the table, if the size was not past
* in the constructor.
*
* @theSize The new size
*/
void
resize(unsigned long theSize)
{
m_countersVector.resize(theSize);
}
/**
* 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.
*/
CountType
countNode(
StylesheetExecutionContext& executionContext,
const ElemNumber& numberElem,
XalanNode* node);
/**
* Clear all cached data from the table.
*/
void
reset()
{
m_newFound.clear();
m_countersVector.clear();
}
private:
/**
* A vector which holds counters for ElemNumber instances.
*/
ElemCounterVectorVectorType m_countersVector;
/**
* A vector to use as a temporary buffer.
*/
NodeVectorType m_newFound;
};
XALAN_CPP_NAMESPACE_END
#endif // !defined(XALAN_COUNTERSTABLE_HEADER_GUARD_1357924680)