diff options
Diffstat (limited to 'dom/xslt/xslt/txKey.h')
-rw-r--r-- | dom/xslt/xslt/txKey.h | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/dom/xslt/xslt/txKey.h b/dom/xslt/xslt/txKey.h new file mode 100644 index 000000000..90a15f2f0 --- /dev/null +++ b/dom/xslt/xslt/txKey.h @@ -0,0 +1,212 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef txKey_h__ +#define txKey_h__ + +#include "nsTHashtable.h" +#include "txNodeSet.h" +#include "txList.h" +#include "txXSLTPatterns.h" +#include "txXMLUtils.h" + +class txPattern; +class Expr; +class txExecutionState; + +class txKeyValueHashKey +{ +public: + txKeyValueHashKey(const txExpandedName& aKeyName, + int32_t aRootIdentifier, + const nsAString& aKeyValue) + : mKeyName(aKeyName), + mKeyValue(aKeyValue), + mRootIdentifier(aRootIdentifier) + { + } + + txExpandedName mKeyName; + nsString mKeyValue; + int32_t mRootIdentifier; +}; + +struct txKeyValueHashEntry : public PLDHashEntryHdr +{ +public: + typedef const txKeyValueHashKey& KeyType; + typedef const txKeyValueHashKey* KeyTypePointer; + + explicit txKeyValueHashEntry(KeyTypePointer aKey) + : mKey(*aKey), + mNodeSet(new txNodeSet(nullptr)) { } + + txKeyValueHashEntry(const txKeyValueHashEntry& entry) + : mKey(entry.mKey), + mNodeSet(entry.mNodeSet) { } + + bool KeyEquals(KeyTypePointer aKey) const; + + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } + + static PLDHashNumber HashKey(KeyTypePointer aKey); + + enum { ALLOW_MEMMOVE = true }; + + txKeyValueHashKey mKey; + RefPtr<txNodeSet> mNodeSet; +}; + +typedef nsTHashtable<txKeyValueHashEntry> txKeyValueHash; + +class txIndexedKeyHashKey +{ +public: + txIndexedKeyHashKey(txExpandedName aKeyName, + int32_t aRootIdentifier) + : mKeyName(aKeyName), + mRootIdentifier(aRootIdentifier) + { + } + + txExpandedName mKeyName; + int32_t mRootIdentifier; +}; + +struct txIndexedKeyHashEntry : public PLDHashEntryHdr +{ +public: + typedef const txIndexedKeyHashKey& KeyType; + typedef const txIndexedKeyHashKey* KeyTypePointer; + + explicit txIndexedKeyHashEntry(KeyTypePointer aKey) + : mKey(*aKey), + mIndexed(false) { } + + txIndexedKeyHashEntry(const txIndexedKeyHashEntry& entry) + : mKey(entry.mKey), + mIndexed(entry.mIndexed) { } + + bool KeyEquals(KeyTypePointer aKey) const; + + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } + + static PLDHashNumber HashKey(KeyTypePointer aKey); + + enum { ALLOW_MEMMOVE = true }; + + txIndexedKeyHashKey mKey; + bool mIndexed; +}; + +typedef nsTHashtable<txIndexedKeyHashEntry> txIndexedKeyHash; + +/** + * Class holding all <xsl:key>s of a particular expanded name in the + * stylesheet. + */ +class txXSLKey { + +public: + explicit txXSLKey(const txExpandedName& aName) : mName(aName) + { + } + + /** + * Adds a match/use pair. + * @param aMatch match-pattern + * @param aUse use-expression + * @return false if an error occurred, true otherwise + */ + bool addKey(nsAutoPtr<txPattern>&& aMatch, nsAutoPtr<Expr>&& aUse); + + /** + * Indexes a subtree and adds it to the hash of key values + * @param aRoot Subtree root to index and add + * @param aKeyValueHash Hash to add values to + * @param aEs txExecutionState to use for XPath evaluation + */ + nsresult indexSubtreeRoot(const txXPathNode& aRoot, + txKeyValueHash& aKeyValueHash, + txExecutionState& aEs); + +private: + /** + * Recursively searches a node, its attributes and its subtree for + * nodes matching any of the keys match-patterns. + * @param aNode Node to search + * @param aKey Key to use when adding into the hash + * @param aKeyValueHash Hash to add values to + * @param aEs txExecutionState to use for XPath evaluation + */ + nsresult indexTree(const txXPathNode& aNode, txKeyValueHashKey& aKey, + txKeyValueHash& aKeyValueHash, txExecutionState& aEs); + + /** + * Tests one node if it matches any of the keys match-patterns. If + * the node matches its values are added to the index. + * @param aNode Node to test + * @param aKey Key to use when adding into the hash + * @param aKeyValueHash Hash to add values to + * @param aEs txExecutionState to use for XPath evaluation + */ + nsresult testNode(const txXPathNode& aNode, txKeyValueHashKey& aKey, + txKeyValueHash& aKeyValueHash, txExecutionState& aEs); + + /** + * represents one match/use pair + */ + struct Key { + nsAutoPtr<txPattern> matchPattern; + nsAutoPtr<Expr> useExpr; + }; + + /** + * List of all match/use pairs. The items as |Key|s + */ + nsTArray<Key> mKeys; + + /** + * Name of this key + */ + txExpandedName mName; +}; + + +class txKeyHash +{ +public: + explicit txKeyHash(const txOwningExpandedNameMap<txXSLKey>& aKeys) + : mKeyValues(4) + , mIndexedKeys(1) + , mKeys(aKeys) + { + } + + nsresult init(); + + nsresult getKeyNodes(const txExpandedName& aKeyName, + const txXPathNode& aRoot, + const nsAString& aKeyValue, + bool aIndexIfNotFound, + txExecutionState& aEs, + txNodeSet** aResult); + +private: + // Hash of all indexed key-values + txKeyValueHash mKeyValues; + + // Hash showing which keys+roots has been indexed + txIndexedKeyHash mIndexedKeys; + + // Map of txXSLKeys + const txOwningExpandedNameMap<txXSLKey>& mKeys; + + // Empty nodeset returned if no key is found + RefPtr<txNodeSet> mEmptyNodeSet; +}; + + +#endif //txKey_h__ |