Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/dom/NodeInfo.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
/*
8
 * Class that represents a prefix/namespace/localName triple; a single
9
 * nodeinfo is shared by all elements in a document that have that
10
 * prefix, namespace, and localName.
11
 *
12
 * nsNodeInfoManagers are internal objects that manage a list of
13
 * NodeInfos, every document object should hold a strong reference to
14
 * a nsNodeInfoManager and every NodeInfo also holds a strong reference
15
 * to their owning manager. When a NodeInfo is no longer used it will
16
 * automatically remove itself from its owner manager, and when all
17
 * NodeInfos have been removed from a nsNodeInfoManager and all external
18
 * references are released the nsNodeInfoManager deletes itself.
19
 */
20
21
#ifndef mozilla_dom_NodeInfo_h___
22
#define mozilla_dom_NodeInfo_h___
23
24
#include "nsCycleCollectionParticipant.h"
25
#include "mozilla/dom/NameSpaceConstants.h"
26
#include "nsString.h"
27
#include "mozilla/Attributes.h"
28
#include "mozilla/Maybe.h"
29
#include "nsAtom.h"
30
#include "nsHashKeys.h"
31
32
class nsIDocument;
33
class nsNodeInfoManager;
34
35
namespace mozilla {
36
namespace dom {
37
38
class NodeInfo final
39
{
40
public:
41
  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(NodeInfo)
42
  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_NATIVE_CLASS_WITH_CUSTOM_DELETE(NodeInfo)
43
44
  /*
45
   * Get the name from this node as a string, this does not include the prefix.
46
   *
47
   * For the HTML element "<body>" this will return "body" and for the XML
48
   * element "<html:body>" this will return "body".
49
   */
50
  void GetName(nsAString& aName) const;
51
52
  /*
53
   * Get the name from this node as an atom, this does not include the prefix.
54
   * This function never returns a null atom.
55
   *
56
   * For the HTML element "<body>" this will return the "body" atom and for
57
   * the XML element "<html:body>" this will return the "body" atom.
58
   */
59
  nsAtom* NameAtom() const
60
0
  {
61
0
    return mInner.mName;
62
0
  }
63
64
  /*
65
   * Get the qualified name from this node as a string, the qualified name
66
   * includes the prefix, if one exists.
67
   *
68
   * For the HTML element "<body>" this will return "body" and for the XML
69
   * element "<html:body>" this will return "html:body".
70
   */
71
0
  const nsString& QualifiedName() const {
72
0
    return mQualifiedName;
73
0
  }
74
75
  /*
76
   * Returns the node's nodeName as defined in DOM Core
77
   */
78
0
  const nsString& NodeName() const {
79
0
    return mNodeName;
80
0
  }
81
82
  /*
83
   * Returns the node's localName as defined in DOM Core
84
   */
85
0
  const nsString& LocalName() const {
86
0
    return mLocalName;
87
0
  }
88
89
  /*
90
   * Get the prefix from this node as a string.
91
   *
92
   * For the HTML element "<body>" this will return a null string and for
93
   * the XML element "<html:body>" this will return the string "html".
94
   */
95
  void GetPrefix(nsAString& aPrefix) const;
96
97
  /*
98
   * Get the prefix from this node as an atom.
99
   *
100
   * For the HTML element "<body>" this will return a null atom and for
101
   * the XML element "<html:body>" this will return the "html" atom.
102
   */
103
  nsAtom* GetPrefixAtom() const
104
0
  {
105
0
    return mInner.mPrefix;
106
0
  }
107
108
  /*
109
   * Get the namespace URI for a node, if the node has a namespace URI.
110
   */
111
  void GetNamespaceURI(nsAString& aNameSpaceURI) const;
112
113
  /*
114
   * Get the namespace ID for a node if the node has a namespace, if not this
115
   * returns kNameSpaceID_None.
116
   */
117
  int32_t NamespaceID() const
118
0
  {
119
0
    return mInner.mNamespaceID;
120
0
  }
121
122
  /*
123
   * Get the nodetype for the node. Returns the values specified in Node
124
   * for Node.nodeType
125
   */
126
  uint16_t NodeType() const
127
0
  {
128
0
    return mInner.mNodeType;
129
0
  }
130
131
  /*
132
   * Get the extra name, used by PIs and DocTypes, for the node.
133
   */
134
  nsAtom* GetExtraName() const
135
0
  {
136
0
    return mInner.mExtraName;
137
0
  }
138
139
  /**
140
   * Get the owning node info manager. Only to be used inside Gecko, you can't
141
   * really do anything with the pointer outside Gecko anyway.
142
   */
143
  nsNodeInfoManager* NodeInfoManager() const
144
0
  {
145
0
    return mOwnerManager;
146
0
  }
147
148
  /*
149
   * Utility functions that can be used to check if a nodeinfo holds a specific
150
   * name, name and prefix, name and prefix and namespace ID, or just
151
   * namespace ID.
152
   */
153
  inline bool Equals(NodeInfo* aNodeInfo) const;
154
155
  bool NameAndNamespaceEquals(NodeInfo* aNodeInfo) const;
156
157
  bool Equals(nsAtom* aNameAtom) const
158
0
  {
159
0
    return mInner.mName == aNameAtom;
160
0
  }
161
162
  bool Equals(nsAtom* aNameAtom, nsAtom* aPrefixAtom) const
163
0
  {
164
0
    return (mInner.mName == aNameAtom) && (mInner.mPrefix == aPrefixAtom);
165
0
  }
166
167
  bool Equals(nsAtom* aNameAtom, int32_t aNamespaceID) const
168
0
  {
169
0
    return ((mInner.mName == aNameAtom) &&
170
0
            (mInner.mNamespaceID == aNamespaceID));
171
0
  }
172
173
  bool Equals(nsAtom* aNameAtom, nsAtom* aPrefixAtom, int32_t aNamespaceID) const
174
0
  {
175
0
    return ((mInner.mName == aNameAtom) &&
176
0
            (mInner.mPrefix == aPrefixAtom) &&
177
0
            (mInner.mNamespaceID == aNamespaceID));
178
0
  }
179
180
  bool NamespaceEquals(int32_t aNamespaceID) const
181
0
  {
182
0
    return mInner.mNamespaceID == aNamespaceID;
183
0
  }
184
185
  inline bool Equals(const nsAString& aName) const;
186
187
  inline bool Equals(const nsAString& aName, const nsAString& aPrefix) const;
188
189
  inline bool Equals(const nsAString& aName, int32_t aNamespaceID) const;
190
191
  inline bool Equals(const nsAString& aName, const nsAString& aPrefix, int32_t aNamespaceID) const;
192
193
  bool NamespaceEquals(const nsAString& aNamespaceURI) const;
194
195
  inline bool QualifiedNameEquals(nsAtom* aNameAtom) const;
196
197
  bool QualifiedNameEquals(const nsAString& aQualifiedName) const
198
0
  {
199
0
    return mQualifiedName == aQualifiedName;
200
0
  }
201
202
  /*
203
   * Retrieve a pointer to the document that owns this node info.
204
   */
205
  nsIDocument* GetDocument() const
206
0
  {
207
0
    return mDocument;
208
0
  }
209
210
private:
211
  NodeInfo() = delete;
212
  NodeInfo(const NodeInfo& aOther) = delete;
213
214
  // NodeInfo is only constructed by nsNodeInfoManager which is a friend class.
215
  // aName and aOwnerManager may not be null.
216
  NodeInfo(nsAtom* aName, nsAtom* aPrefix, int32_t aNamespaceID,
217
           uint16_t aNodeType, nsAtom* aExtraName,
218
           nsNodeInfoManager* aOwnerManager);
219
220
  ~NodeInfo();
221
222
public:
223
  bool CanSkip();
224
225
  /**
226
   * This method gets called by the cycle collector when it's time to delete
227
   * this object.
228
   */
229
  void DeleteCycleCollectable();
230
231
protected:
232
  /*
233
   * NodeInfoInner is used for two things:
234
   *
235
   *   1. as a member in nsNodeInfo for holding the name, prefix and
236
   *      namespace ID
237
   *   2. as the hash key in the hash table in nsNodeInfoManager
238
   *
239
   * NodeInfoInner does not do any kind of reference counting,
240
   * that's up to the user of this class. Since NodeInfoInner is
241
   * typically used as a member of NodeInfo, the hash table doesn't
242
   * need to delete the keys. When the value (NodeInfo) is deleted
243
   * the key is automatically deleted.
244
   */
245
246
  class NodeInfoInner
247
  {
248
  public:
249
    NodeInfoInner()
250
      : mName(nullptr), mPrefix(nullptr), mNamespaceID(kNameSpaceID_Unknown),
251
        mNodeType(0), mNameString(nullptr), mExtraName(nullptr),
252
        mHash()
253
0
    {
254
0
    }
255
    NodeInfoInner(nsAtom *aName, nsAtom *aPrefix, int32_t aNamespaceID,
256
                    uint16_t aNodeType, nsAtom* aExtraName)
257
      : mName(aName), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
258
        mNodeType(aNodeType), mNameString(nullptr), mExtraName(aExtraName),
259
        mHash()
260
0
    {
261
0
    }
262
    NodeInfoInner(const nsAString& aTmpName, nsAtom *aPrefix,
263
                    int32_t aNamespaceID, uint16_t aNodeType)
264
      : mName(nullptr), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
265
        mNodeType(aNodeType), mNameString(&aTmpName), mExtraName(nullptr),
266
        mHash()
267
0
    {
268
0
    }
269
270
    bool operator==(const NodeInfoInner& aOther) const
271
0
    {
272
0
      if (mPrefix != aOther.mPrefix ||
273
0
          mNamespaceID != aOther.mNamespaceID ||
274
0
          mNodeType != aOther.mNodeType ||
275
0
          mExtraName != aOther.mExtraName) {
276
0
        return false;
277
0
      }
278
0
279
0
      if (mName) {
280
0
        if (aOther.mName) {
281
0
          return mName == aOther.mName;
282
0
        }
283
0
        return mName->Equals(*(aOther.mNameString));
284
0
      }
285
0
286
0
      if (aOther.mName) {
287
0
        return aOther.mName->Equals(*(mNameString));
288
0
      }
289
0
290
0
      return mNameString->Equals(*(aOther.mNameString));
291
0
    }
292
293
    uint32_t Hash() const
294
0
    {
295
0
      if (!mHash) {
296
0
        mHash.emplace(
297
0
            mName ? mName->hash() : mozilla::HashString(*mNameString));
298
0
      }
299
0
      return mHash.value();
300
0
    }
301
302
    nsAtom* const MOZ_OWNING_REF mName;
303
    nsAtom* MOZ_OWNING_REF mPrefix;
304
    int32_t             mNamespaceID;
305
    uint16_t            mNodeType; // As defined by Node.nodeType
306
    const nsAString* const mNameString;
307
    nsAtom* MOZ_OWNING_REF mExtraName; // Only used by PIs and DocTypes
308
    mutable mozilla::Maybe<const uint32_t> mHash;
309
  };
310
311
  // nsNodeInfoManager needs to pass mInner to the hash table.
312
  friend class ::nsNodeInfoManager;
313
314
  // This is a non-owning reference, but it's safe since it's set to nullptr
315
  // by nsNodeInfoManager::DropDocumentReference when the document is destroyed.
316
  nsIDocument* MOZ_NON_OWNING_REF mDocument; // Cache of mOwnerManager->mDocument
317
318
  NodeInfoInner mInner;
319
320
  RefPtr<nsNodeInfoManager> mOwnerManager;
321
322
  /*
323
   * Members for various functions of mName+mPrefix that we can be
324
   * asked to compute.
325
   */
326
327
  // Qualified name
328
  nsString mQualifiedName;
329
330
  // nodeName for the node.
331
  nsString mNodeName;
332
333
  // localName for the node. This is either equal to mInner.mName, or a
334
  // void string, depending on mInner.mNodeType.
335
  nsString mLocalName;
336
};
337
338
} // namespace dom
339
} // namespace mozilla
340
341
#endif /* mozilla_dom_NodeInfo_h___ */