| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #if !defined(XALAN_NODESORTER_HEADER_GUARD) |
| #define XALAN_NODESORTER_HEADER_GUARD |
| |
| // Base include file. Must be first. |
| #include "XSLTDefinitions.hpp" |
| |
| |
| |
| #include <functional> |
| |
| |
| |
| #include <xalanc/Include/XalanVector.hpp> |
| |
| |
| |
| #include <xalanc/XPath/XObject.hpp> |
| |
| |
| |
| #include <xalanc/XSLT/NodeSortKey.hpp> |
| |
| |
| |
| namespace XALAN_CPP_NAMESPACE { |
| |
| |
| |
| class MutableNodeRefList; |
| class StylesheetExecutionContext; |
| class XalanNode; |
| class XPath; |
| |
| |
| typedef XalanVector<double> NumberVectorTypeDecl; |
| XALAN_USES_MEMORY_MANAGER(NumberVectorTypeDecl) |
| |
| typedef XalanVector<XalanDOMString> StringVectorTypeDecl; |
| XALAN_USES_MEMORY_MANAGER(StringVectorTypeDecl) |
| |
| |
| /** |
| * This class can sort vectors of nodes according to a select pattern. |
| */ |
| class XALAN_XSLT_EXPORT NodeSorter |
| { |
| public: |
| |
| struct XALAN_XSLT_EXPORT VectorEntry |
| { |
| public: |
| |
| VectorEntry( |
| XalanNode* theNode = 0, |
| XalanSize_t thePosition = 0) : |
| m_node(theNode), |
| m_position(thePosition) |
| { |
| } |
| |
| XalanNode* m_node; |
| XalanSize_t m_position; |
| }; |
| |
| typedef XalanVector<VectorEntry> NodeVectorType; |
| typedef XalanVector<NodeSortKey> NodeSortKeyVectorType; |
| |
| explicit |
| NodeSorter(MemoryManager& theManager); |
| |
| ~NodeSorter(); |
| |
| NodeSortKeyVectorType& |
| getSortKeys() |
| { |
| return m_keys; |
| } |
| |
| /** |
| * Given a list of nodes, sort each node according to the criteria in the |
| * keys. The list is assumed to be in document order. |
| * |
| * @param executionContext current execution context |
| * @param v list of Nodes |
| */ |
| void |
| sort( |
| StylesheetExecutionContext& executionContext, |
| MutableNodeRefList& theList); |
| |
| /** |
| * Return the results of a compare of two nodes. |
| */ |
| struct XALAN_XSLT_EXPORT NodeSortKeyCompare |
| { |
| public: |
| |
| /** |
| * Construct a NodeSortKeyCompare object, to perform the sort |
| * |
| * @param executionContext current execution context |
| * @param theNodes vector or nodes to be sorted |
| * @param theNodeSortKeys vector of keys upon which to sort |
| */ |
| NodeSortKeyCompare( |
| StylesheetExecutionContext& executionContext, |
| NodeSorter& theSorter, |
| const NodeVectorType& theNodes, |
| const NodeSortKeyVectorType& theNodeSortKeys) : |
| m_executionContext(executionContext), |
| m_sorter(theSorter), |
| m_nodes(theNodes), |
| m_nodeSortKeys(theNodeSortKeys) |
| { |
| } |
| |
| /** |
| * Compare two nodes, returning a value to indicate the |
| * result |
| * |
| * @param theLHS the first node to compare |
| * @param theRHS the second node to compare |
| * @param theKeyIndex the index of the key to use |
| * @result < 0 if theLHS is less than theRHS, 0 if they are equal, and > 0 if theLHS is greater than theRHS |
| */ |
| int |
| compare( |
| const NodeVectorType::value_type& theLHS, |
| const NodeVectorType::value_type& theRHS, |
| XalanSize_t theKeyIndex = 0) const; |
| |
| /** |
| * Compare two nodes as a less predicate. |
| * |
| * @param theLHS the first node to compare |
| * @param theRHS the second node to compare |
| * @param theKeyIndex the index of the key to use |
| * @return true if theLHS is less than theRHS |
| */ |
| bool |
| operator()( |
| const NodeVectorType::value_type& theLHS, |
| const NodeVectorType::value_type& theRHS, |
| XalanSize_t theKeyIndex = 0) const |
| { |
| return compare(theLHS, theRHS, theKeyIndex) < 0 ? true : false; |
| } |
| |
| protected: |
| |
| double |
| getNumberResult( |
| const NodeSortKey& theKey, |
| XalanSize_t theKeyIndex, |
| const NodeVectorType::value_type& theEntry) const; |
| |
| const XalanDOMString& |
| getStringResult( |
| const NodeSortKey& theKey, |
| XalanSize_t theKeyIndex, |
| const NodeVectorType::value_type& theEntry) const; |
| |
| private: |
| |
| StylesheetExecutionContext& m_executionContext; |
| NodeSorter& m_sorter; |
| const NodeVectorType& m_nodes; |
| const NodeSortKeyVectorType& m_nodeSortKeys; |
| }; |
| |
| friend struct NodeSortKeyCompare; |
| |
| typedef NumberVectorTypeDecl NumberVectorType; |
| typedef XalanVector<XObjectPtr> XObjectVectorType; |
| typedef StringVectorTypeDecl StringVectorType; |
| |
| typedef XalanVector<NumberVectorType> NumberCacheType; |
| typedef XalanVector<XObjectVectorType> XObjectCacheType; |
| typedef XalanVector<StringVectorType> StringCacheType; |
| |
| typedef NumberCacheType NumberResultsCacheType; |
| |
| #if defined(XALAN_NODESORTER_CACHE_XOBJECTS) |
| typedef XObjectCacheType StringResultsCacheType; |
| #else |
| typedef StringCacheType StringResultsCacheType; |
| #endif |
| |
| private: |
| |
| /** |
| * Given a vector of nodes, sort each node according to the criteria in the |
| * keys. |
| * |
| * @param executionContext current execution context |
| */ |
| void |
| sort(StylesheetExecutionContext& executionContext); |
| |
| // Data members... |
| NumberResultsCacheType m_numberResultsCache; |
| |
| StringResultsCacheType m_stringResultsCache; |
| |
| NodeSortKeyVectorType m_keys; |
| |
| NodeVectorType m_scratchVector; |
| }; |
| |
| |
| |
| } |
| |
| |
| |
| #endif // XALAN_NODESORTER_HEADER_GUARD |