summaryrefslogtreecommitdiffstats
path: root/dom/xslt/xslt/txKey.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/xslt/xslt/txKey.h')
-rw-r--r--dom/xslt/xslt/txKey.h186
1 files changed, 186 insertions, 0 deletions
diff --git a/dom/xslt/xslt/txKey.h b/dom/xslt/xslt/txKey.h
new file mode 100644
index 0000000000..e3bf56ebaa
--- /dev/null
+++ b/dom/xslt/xslt/txKey.h
@@ -0,0 +1,186 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 "txExpandedNameMap.h"
+#include "txList.h"
+#include "txNodeSet.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:
+ using KeyType = const txKeyValueHashKey&;
+ using KeyTypePointer = const txKeyValueHashKey*;
+
+ 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;
+};
+
+using txKeyValueHash = nsTHashtable<txKeyValueHashEntry>;
+
+class txIndexedKeyHashKey {
+ public:
+ txIndexedKeyHashKey(txExpandedName aKeyName, int32_t aRootIdentifier)
+ : mKeyName(aKeyName), mRootIdentifier(aRootIdentifier) {}
+
+ txExpandedName mKeyName;
+ int32_t mRootIdentifier;
+};
+
+struct txIndexedKeyHashEntry : public PLDHashEntryHdr {
+ public:
+ using KeyType = const txIndexedKeyHashKey&;
+ using KeyTypePointer = const txIndexedKeyHashKey*;
+
+ 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;
+};
+
+using txIndexedKeyHash = nsTHashtable<txIndexedKeyHashEntry>;
+
+/**
+ * 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(mozilla::UniquePtr<txPattern>&& aMatch,
+ mozilla::UniquePtr<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 {
+ mozilla::UniquePtr<txPattern> matchPattern;
+ mozilla::UniquePtr<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__