Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
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/. */
6 #ifndef txXPathTreeWalker_h__
7 #define txXPathTreeWalker_h__
9 #include "txCore.h"
10 #include "txXPathNode.h"
11 #include "nsIContentInlines.h"
12 #include "nsINodeInfo.h"
13 #include "nsTArray.h"
15 class nsIAtom;
16 class nsIDOMDocument;
18 class txUint32Array : public nsTArray<uint32_t>
19 {
20 public:
21 bool AppendValue(uint32_t aValue)
22 {
23 return AppendElement(aValue) != nullptr;
24 }
25 bool RemoveValueAt(uint32_t aIndex)
26 {
27 if (aIndex < Length()) {
28 RemoveElementAt(aIndex);
29 }
30 return true;
31 }
32 uint32_t ValueAt(uint32_t aIndex) const
33 {
34 return (aIndex < Length()) ? ElementAt(aIndex) : 0;
35 }
36 };
38 class txXPathTreeWalker
39 {
40 public:
41 txXPathTreeWalker(const txXPathTreeWalker& aOther);
42 explicit txXPathTreeWalker(const txXPathNode& aNode);
44 bool getAttr(nsIAtom* aLocalName, int32_t aNSID, nsAString& aValue) const;
45 int32_t getNamespaceID() const;
46 uint16_t getNodeType() const;
47 void appendNodeValue(nsAString& aResult) const;
48 void getNodeName(nsAString& aName) const;
50 void moveTo(const txXPathTreeWalker& aWalker);
52 void moveToRoot();
53 bool moveToParent();
54 bool moveToElementById(const nsAString& aID);
55 bool moveToFirstAttribute();
56 bool moveToNextAttribute();
57 bool moveToNamedAttribute(nsIAtom* aLocalName, int32_t aNSID);
58 bool moveToFirstChild();
59 bool moveToLastChild();
60 bool moveToNextSibling();
61 bool moveToPreviousSibling();
63 bool isOnNode(const txXPathNode& aNode) const;
65 const txXPathNode& getCurrentPosition() const;
67 private:
68 txXPathNode mPosition;
70 bool moveToValidAttribute(uint32_t aStartIndex);
71 bool moveToSibling(int32_t aDir);
73 uint32_t mCurrentIndex;
74 txUint32Array mDescendants;
75 };
77 class txXPathNodeUtils
78 {
79 public:
80 static bool getAttr(const txXPathNode& aNode, nsIAtom* aLocalName,
81 int32_t aNSID, nsAString& aValue);
82 static already_AddRefed<nsIAtom> getLocalName(const txXPathNode& aNode);
83 static nsIAtom* getPrefix(const txXPathNode& aNode);
84 static void getLocalName(const txXPathNode& aNode, nsAString& aLocalName);
85 static void getNodeName(const txXPathNode& aNode,
86 nsAString& aName);
87 static int32_t getNamespaceID(const txXPathNode& aNode);
88 static void getNamespaceURI(const txXPathNode& aNode, nsAString& aURI);
89 static uint16_t getNodeType(const txXPathNode& aNode);
90 static void appendNodeValue(const txXPathNode& aNode, nsAString& aResult);
91 static bool isWhitespace(const txXPathNode& aNode);
92 static txXPathNode* getOwnerDocument(const txXPathNode& aNode);
93 static int32_t getUniqueIdentifier(const txXPathNode& aNode);
94 static nsresult getXSLTId(const txXPathNode& aNode,
95 const txXPathNode& aBase, nsAString& aResult);
96 static void release(txXPathNode* aNode);
97 static void getBaseURI(const txXPathNode& aNode, nsAString& aURI);
98 static int comparePosition(const txXPathNode& aNode,
99 const txXPathNode& aOtherNode);
100 static bool localNameEquals(const txXPathNode& aNode,
101 nsIAtom* aLocalName);
102 static bool isRoot(const txXPathNode& aNode);
103 static bool isElement(const txXPathNode& aNode);
104 static bool isAttribute(const txXPathNode& aNode);
105 static bool isProcessingInstruction(const txXPathNode& aNode);
106 static bool isComment(const txXPathNode& aNode);
107 static bool isText(const txXPathNode& aNode);
108 static inline bool isHTMLElementInHTMLDocument(const txXPathNode& aNode)
109 {
110 if (!aNode.isContent()) {
111 return false;
112 }
113 nsIContent* content = aNode.Content();
114 return content->IsHTML() && content->IsInHTMLDocument();
115 }
116 };
118 class txXPathNativeNode
119 {
120 public:
121 static txXPathNode* createXPathNode(nsIDOMNode* aNode,
122 bool aKeepRootAlive = false);
123 static txXPathNode* createXPathNode(nsIContent* aContent,
124 bool aKeepRootAlive = false);
125 static txXPathNode* createXPathNode(nsIDOMDocument* aDocument);
126 static nsresult getNode(const txXPathNode& aNode, nsIDOMNode** aResult);
127 static nsIContent* getContent(const txXPathNode& aNode);
128 static nsIDocument* getDocument(const txXPathNode& aNode);
129 static void addRef(const txXPathNode& aNode)
130 {
131 NS_ADDREF(aNode.mNode);
132 }
133 static void release(const txXPathNode& aNode)
134 {
135 nsINode *node = aNode.mNode;
136 NS_RELEASE(node);
137 }
138 };
140 inline const txXPathNode&
141 txXPathTreeWalker::getCurrentPosition() const
142 {
143 return mPosition;
144 }
146 inline bool
147 txXPathTreeWalker::getAttr(nsIAtom* aLocalName, int32_t aNSID,
148 nsAString& aValue) const
149 {
150 return txXPathNodeUtils::getAttr(mPosition, aLocalName, aNSID, aValue);
151 }
153 inline int32_t
154 txXPathTreeWalker::getNamespaceID() const
155 {
156 return txXPathNodeUtils::getNamespaceID(mPosition);
157 }
159 inline void
160 txXPathTreeWalker::appendNodeValue(nsAString& aResult) const
161 {
162 txXPathNodeUtils::appendNodeValue(mPosition, aResult);
163 }
165 inline void
166 txXPathTreeWalker::getNodeName(nsAString& aName) const
167 {
168 txXPathNodeUtils::getNodeName(mPosition, aName);
169 }
171 inline void
172 txXPathTreeWalker::moveTo(const txXPathTreeWalker& aWalker)
173 {
174 nsINode *root = nullptr;
175 if (mPosition.mRefCountRoot) {
176 root = mPosition.Root();
177 }
178 mPosition.mIndex = aWalker.mPosition.mIndex;
179 mPosition.mRefCountRoot = aWalker.mPosition.mRefCountRoot;
180 mPosition.mNode = aWalker.mPosition.mNode;
181 nsINode *newRoot = nullptr;
182 if (mPosition.mRefCountRoot) {
183 newRoot = mPosition.Root();
184 }
185 if (root != newRoot) {
186 NS_IF_ADDREF(newRoot);
187 NS_IF_RELEASE(root);
188 }
190 mCurrentIndex = aWalker.mCurrentIndex;
191 mDescendants.Clear();
192 }
194 inline bool
195 txXPathTreeWalker::isOnNode(const txXPathNode& aNode) const
196 {
197 return (mPosition == aNode);
198 }
200 /* static */
201 inline int32_t
202 txXPathNodeUtils::getUniqueIdentifier(const txXPathNode& aNode)
203 {
204 NS_PRECONDITION(!aNode.isAttribute(),
205 "Not implemented for attributes.");
206 return NS_PTR_TO_INT32(aNode.mNode);
207 }
209 /* static */
210 inline void
211 txXPathNodeUtils::release(txXPathNode* aNode)
212 {
213 NS_RELEASE(aNode->mNode);
214 }
216 /* static */
217 inline bool
218 txXPathNodeUtils::localNameEquals(const txXPathNode& aNode,
219 nsIAtom* aLocalName)
220 {
221 if (aNode.isContent() &&
222 aNode.Content()->IsElement()) {
223 return aNode.Content()->NodeInfo()->Equals(aLocalName);
224 }
226 nsCOMPtr<nsIAtom> localName = txXPathNodeUtils::getLocalName(aNode);
228 return localName == aLocalName;
229 }
231 /* static */
232 inline bool
233 txXPathNodeUtils::isRoot(const txXPathNode& aNode)
234 {
235 return !aNode.isAttribute() && !aNode.mNode->GetParentNode();
236 }
238 /* static */
239 inline bool
240 txXPathNodeUtils::isElement(const txXPathNode& aNode)
241 {
242 return aNode.isContent() &&
243 aNode.Content()->IsElement();
244 }
247 /* static */
248 inline bool
249 txXPathNodeUtils::isAttribute(const txXPathNode& aNode)
250 {
251 return aNode.isAttribute();
252 }
254 /* static */
255 inline bool
256 txXPathNodeUtils::isProcessingInstruction(const txXPathNode& aNode)
257 {
258 return aNode.isContent() &&
259 aNode.Content()->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION);
260 }
262 /* static */
263 inline bool
264 txXPathNodeUtils::isComment(const txXPathNode& aNode)
265 {
266 return aNode.isContent() &&
267 aNode.Content()->IsNodeOfType(nsINode::eCOMMENT);
268 }
270 /* static */
271 inline bool
272 txXPathNodeUtils::isText(const txXPathNode& aNode)
273 {
274 return aNode.isContent() &&
275 aNode.Content()->IsNodeOfType(nsINode::eTEXT);
276 }
278 #endif /* txXPathTreeWalker_h__ */