Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef txKey_h__
7 : #define txKey_h__
8 :
9 : #include "nsTHashtable.h"
10 : #include "txNodeSet.h"
11 : #include "txList.h"
12 : #include "txXSLTPatterns.h"
13 : #include "txXMLUtils.h"
14 :
15 : class txPattern;
16 : class Expr;
17 : class txExecutionState;
18 :
19 0 : class txKeyValueHashKey
20 : {
21 : public:
22 0 : txKeyValueHashKey(const txExpandedName& aKeyName,
23 : int32_t aRootIdentifier,
24 : const nsAString& aKeyValue)
25 0 : : mKeyName(aKeyName),
26 : mKeyValue(aKeyValue),
27 0 : mRootIdentifier(aRootIdentifier)
28 : {
29 0 : }
30 :
31 : txExpandedName mKeyName;
32 : nsString mKeyValue;
33 : int32_t mRootIdentifier;
34 : };
35 :
36 0 : struct txKeyValueHashEntry : public PLDHashEntryHdr
37 : {
38 : public:
39 : typedef const txKeyValueHashKey& KeyType;
40 : typedef const txKeyValueHashKey* KeyTypePointer;
41 :
42 0 : explicit txKeyValueHashEntry(KeyTypePointer aKey)
43 0 : : mKey(*aKey),
44 0 : mNodeSet(new txNodeSet(nullptr)) { }
45 :
46 : txKeyValueHashEntry(const txKeyValueHashEntry& entry)
47 : : mKey(entry.mKey),
48 : mNodeSet(entry.mNodeSet) { }
49 :
50 : bool KeyEquals(KeyTypePointer aKey) const;
51 :
52 0 : static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
53 :
54 : static PLDHashNumber HashKey(KeyTypePointer aKey);
55 :
56 : enum { ALLOW_MEMMOVE = true };
57 :
58 : txKeyValueHashKey mKey;
59 : RefPtr<txNodeSet> mNodeSet;
60 : };
61 :
62 : typedef nsTHashtable<txKeyValueHashEntry> txKeyValueHash;
63 :
64 0 : class txIndexedKeyHashKey
65 : {
66 : public:
67 0 : txIndexedKeyHashKey(txExpandedName aKeyName,
68 : int32_t aRootIdentifier)
69 0 : : mKeyName(aKeyName),
70 0 : mRootIdentifier(aRootIdentifier)
71 : {
72 0 : }
73 :
74 : txExpandedName mKeyName;
75 : int32_t mRootIdentifier;
76 : };
77 :
78 0 : struct txIndexedKeyHashEntry : public PLDHashEntryHdr
79 : {
80 : public:
81 : typedef const txIndexedKeyHashKey& KeyType;
82 : typedef const txIndexedKeyHashKey* KeyTypePointer;
83 :
84 0 : explicit txIndexedKeyHashEntry(KeyTypePointer aKey)
85 0 : : mKey(*aKey),
86 0 : mIndexed(false) { }
87 :
88 : txIndexedKeyHashEntry(const txIndexedKeyHashEntry& entry)
89 : : mKey(entry.mKey),
90 : mIndexed(entry.mIndexed) { }
91 :
92 : bool KeyEquals(KeyTypePointer aKey) const;
93 :
94 0 : static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
95 :
96 : static PLDHashNumber HashKey(KeyTypePointer aKey);
97 :
98 : enum { ALLOW_MEMMOVE = true };
99 :
100 : txIndexedKeyHashKey mKey;
101 : bool mIndexed;
102 : };
103 :
104 : typedef nsTHashtable<txIndexedKeyHashEntry> txIndexedKeyHash;
105 :
106 : /**
107 : * Class holding all <xsl:key>s of a particular expanded name in the
108 : * stylesheet.
109 : */
110 0 : class txXSLKey {
111 :
112 : public:
113 0 : explicit txXSLKey(const txExpandedName& aName) : mName(aName)
114 : {
115 0 : }
116 :
117 : /**
118 : * Adds a match/use pair.
119 : * @param aMatch match-pattern
120 : * @param aUse use-expression
121 : * @return false if an error occurred, true otherwise
122 : */
123 : bool addKey(nsAutoPtr<txPattern>&& aMatch, nsAutoPtr<Expr>&& aUse);
124 :
125 : /**
126 : * Indexes a subtree and adds it to the hash of key values
127 : * @param aRoot Subtree root to index and add
128 : * @param aKeyValueHash Hash to add values to
129 : * @param aEs txExecutionState to use for XPath evaluation
130 : */
131 : nsresult indexSubtreeRoot(const txXPathNode& aRoot,
132 : txKeyValueHash& aKeyValueHash,
133 : txExecutionState& aEs);
134 :
135 : private:
136 : /**
137 : * Recursively searches a node, its attributes and its subtree for
138 : * nodes matching any of the keys match-patterns.
139 : * @param aNode Node to search
140 : * @param aKey Key to use when adding into the hash
141 : * @param aKeyValueHash Hash to add values to
142 : * @param aEs txExecutionState to use for XPath evaluation
143 : */
144 : nsresult indexTree(const txXPathNode& aNode, txKeyValueHashKey& aKey,
145 : txKeyValueHash& aKeyValueHash, txExecutionState& aEs);
146 :
147 : /**
148 : * Tests one node if it matches any of the keys match-patterns. If
149 : * the node matches its values are added to the index.
150 : * @param aNode Node to test
151 : * @param aKey Key to use when adding into the hash
152 : * @param aKeyValueHash Hash to add values to
153 : * @param aEs txExecutionState to use for XPath evaluation
154 : */
155 : nsresult testNode(const txXPathNode& aNode, txKeyValueHashKey& aKey,
156 : txKeyValueHash& aKeyValueHash, txExecutionState& aEs);
157 :
158 : /**
159 : * represents one match/use pair
160 : */
161 0 : struct Key {
162 : nsAutoPtr<txPattern> matchPattern;
163 : nsAutoPtr<Expr> useExpr;
164 : };
165 :
166 : /**
167 : * List of all match/use pairs. The items as |Key|s
168 : */
169 : nsTArray<Key> mKeys;
170 :
171 : /**
172 : * Name of this key
173 : */
174 : txExpandedName mName;
175 : };
176 :
177 :
178 0 : class txKeyHash
179 : {
180 : public:
181 0 : explicit txKeyHash(const txOwningExpandedNameMap<txXSLKey>& aKeys)
182 0 : : mKeyValues(4)
183 : , mIndexedKeys(1)
184 0 : , mKeys(aKeys)
185 : {
186 0 : }
187 :
188 : nsresult init();
189 :
190 : nsresult getKeyNodes(const txExpandedName& aKeyName,
191 : const txXPathNode& aRoot,
192 : const nsAString& aKeyValue,
193 : bool aIndexIfNotFound,
194 : txExecutionState& aEs,
195 : txNodeSet** aResult);
196 :
197 : private:
198 : // Hash of all indexed key-values
199 : txKeyValueHash mKeyValues;
200 :
201 : // Hash showing which keys+roots has been indexed
202 : txIndexedKeyHash mIndexedKeys;
203 :
204 : // Map of txXSLKeys
205 : const txOwningExpandedNameMap<txXSLKey>& mKeys;
206 :
207 : // Empty nodeset returned if no key is found
208 : RefPtr<txNodeSet> mEmptyNodeSet;
209 : };
210 :
211 :
212 : #endif //txKey_h__
|