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.h212
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__