/* -*- 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; 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; nsRefPtr mNodeSet; }; typedef nsTHashtable 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; 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 txIndexedKeyHash; /** * Class holding all s of a particular expanded name in the * stylesheet. */ class txXSLKey { public: 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&& aMatch, nsAutoPtr&& 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 matchPattern; nsAutoPtr useExpr; }; /** * List of all match/use pairs. The items as |Key|s */ nsTArray mKeys; /** * Name of this key */ txExpandedName mName; }; class txKeyHash { public: txKeyHash(const txOwningExpandedNameMap& aKeys) : mKeyValues(8) , 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& mKeys; // Empty nodeset returned if no key is found nsRefPtr mEmptyNodeSet; }; #endif //txKey_h__