1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is TransforMiiX XSLT processor code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Jonas Sicking.
19 : * Portions created by the Initial Developer are Copyright (C) 2003
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Jonas Sicking <jonas@sicking.cc>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #ifndef txKey_h__
40 : #define txKey_h__
41 :
42 : #include "nsTHashtable.h"
43 : #include "txNodeSet.h"
44 : #include "txList.h"
45 : #include "txXSLTPatterns.h"
46 : #include "txXMLUtils.h"
47 :
48 : class txPattern;
49 : class Expr;
50 : class txExecutionState;
51 :
52 : class txKeyValueHashKey
53 0 : {
54 : public:
55 0 : txKeyValueHashKey(const txExpandedName& aKeyName,
56 : PRInt32 aRootIdentifier,
57 : const nsAString& aKeyValue)
58 : : mKeyName(aKeyName),
59 : mKeyValue(aKeyValue),
60 0 : mRootIdentifier(aRootIdentifier)
61 : {
62 0 : }
63 :
64 : txExpandedName mKeyName;
65 : nsString mKeyValue;
66 : PRInt32 mRootIdentifier;
67 : };
68 :
69 : struct txKeyValueHashEntry : public PLDHashEntryHdr
70 0 : {
71 : public:
72 : typedef const txKeyValueHashKey& KeyType;
73 : typedef const txKeyValueHashKey* KeyTypePointer;
74 :
75 0 : txKeyValueHashEntry(KeyTypePointer aKey)
76 : : mKey(*aKey),
77 0 : mNodeSet(new txNodeSet(nsnull)) { }
78 :
79 : txKeyValueHashEntry(const txKeyValueHashEntry& entry)
80 : : mKey(entry.mKey),
81 : mNodeSet(entry.mNodeSet) { }
82 :
83 : bool KeyEquals(KeyTypePointer aKey) const;
84 :
85 0 : static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
86 :
87 : static PLDHashNumber HashKey(KeyTypePointer aKey);
88 :
89 : enum { ALLOW_MEMMOVE = true };
90 :
91 : txKeyValueHashKey mKey;
92 : nsRefPtr<txNodeSet> mNodeSet;
93 : };
94 :
95 : typedef nsTHashtable<txKeyValueHashEntry> txKeyValueHash;
96 :
97 : class txIndexedKeyHashKey
98 0 : {
99 : public:
100 0 : txIndexedKeyHashKey(txExpandedName aKeyName,
101 : PRInt32 aRootIdentifier)
102 : : mKeyName(aKeyName),
103 0 : mRootIdentifier(aRootIdentifier)
104 : {
105 0 : }
106 :
107 : txExpandedName mKeyName;
108 : PRInt32 mRootIdentifier;
109 : };
110 :
111 : struct txIndexedKeyHashEntry : public PLDHashEntryHdr
112 0 : {
113 : public:
114 : typedef const txIndexedKeyHashKey& KeyType;
115 : typedef const txIndexedKeyHashKey* KeyTypePointer;
116 :
117 0 : txIndexedKeyHashEntry(KeyTypePointer aKey)
118 : : mKey(*aKey),
119 0 : mIndexed(false) { }
120 :
121 : txIndexedKeyHashEntry(const txIndexedKeyHashEntry& entry)
122 : : mKey(entry.mKey),
123 : mIndexed(entry.mIndexed) { }
124 :
125 : bool KeyEquals(KeyTypePointer aKey) const;
126 :
127 0 : static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
128 :
129 : static PLDHashNumber HashKey(KeyTypePointer aKey);
130 :
131 : enum { ALLOW_MEMMOVE = true };
132 :
133 : txIndexedKeyHashKey mKey;
134 : bool mIndexed;
135 : };
136 :
137 : typedef nsTHashtable<txIndexedKeyHashEntry> txIndexedKeyHash;
138 :
139 : /**
140 : * Class holding all <xsl:key>s of a particular expanded name in the
141 : * stylesheet.
142 : */
143 0 : class txXSLKey {
144 :
145 : public:
146 0 : txXSLKey(const txExpandedName& aName) : mName(aName)
147 : {
148 0 : }
149 :
150 : /**
151 : * Adds a match/use pair.
152 : * @param aMatch match-pattern
153 : * @param aUse use-expression
154 : * @return false if an error occurred, true otherwise
155 : */
156 : bool addKey(nsAutoPtr<txPattern> aMatch, nsAutoPtr<Expr> aUse);
157 :
158 : /**
159 : * Indexes a subtree and adds it to the hash of key values
160 : * @param aRoot Subtree root to index and add
161 : * @param aKeyValueHash Hash to add values to
162 : * @param aEs txExecutionState to use for XPath evaluation
163 : */
164 : nsresult indexSubtreeRoot(const txXPathNode& aRoot,
165 : txKeyValueHash& aKeyValueHash,
166 : txExecutionState& aEs);
167 :
168 : private:
169 : /**
170 : * Recursively searches a node, its attributes and its subtree for
171 : * nodes matching any of the keys match-patterns.
172 : * @param aNode Node to search
173 : * @param aKey Key to use when adding into the hash
174 : * @param aKeyValueHash Hash to add values to
175 : * @param aEs txExecutionState to use for XPath evaluation
176 : */
177 : nsresult indexTree(const txXPathNode& aNode, txKeyValueHashKey& aKey,
178 : txKeyValueHash& aKeyValueHash, txExecutionState& aEs);
179 :
180 : /**
181 : * Tests one node if it matches any of the keys match-patterns. If
182 : * the node matches its values are added to the index.
183 : * @param aNode Node to test
184 : * @param aKey Key to use when adding into the hash
185 : * @param aKeyValueHash Hash to add values to
186 : * @param aEs txExecutionState to use for XPath evaluation
187 : */
188 : nsresult testNode(const txXPathNode& aNode, txKeyValueHashKey& aKey,
189 : txKeyValueHash& aKeyValueHash, txExecutionState& aEs);
190 :
191 : /**
192 : * represents one match/use pair
193 : */
194 0 : struct Key {
195 : nsAutoPtr<txPattern> matchPattern;
196 : nsAutoPtr<Expr> useExpr;
197 : };
198 :
199 : /**
200 : * List of all match/use pairs. The items as |Key|s
201 : */
202 : nsTArray<Key> mKeys;
203 :
204 : /**
205 : * Name of this key
206 : */
207 : txExpandedName mName;
208 : };
209 :
210 :
211 : class txKeyHash
212 0 : {
213 : public:
214 0 : txKeyHash(const txOwningExpandedNameMap<txXSLKey>& aKeys)
215 0 : : mKeys(aKeys)
216 : {
217 0 : }
218 :
219 : nsresult init();
220 :
221 : nsresult getKeyNodes(const txExpandedName& aKeyName,
222 : const txXPathNode& aRoot,
223 : const nsAString& aKeyValue,
224 : bool aIndexIfNotFound,
225 : txExecutionState& aEs,
226 : txNodeSet** aResult);
227 :
228 : private:
229 : // Hash of all indexed key-values
230 : txKeyValueHash mKeyValues;
231 :
232 : // Hash showing which keys+roots has been indexed
233 : txIndexedKeyHash mIndexedKeys;
234 :
235 : // Map of txXSLKeys
236 : const txOwningExpandedNameMap<txXSLKey>& mKeys;
237 :
238 : // Empty nodeset returned if no key is found
239 : nsRefPtr<txNodeSet> mEmptyNodeSet;
240 : };
241 :
242 :
243 : #endif //txKey_h__
|