Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/base/nsAttrName.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 the name (nodeinfo or atom) of an attribute;
9
 * using nodeinfos all the time is too slow, so we use atoms when we
10
 * can.
11
 */
12
13
#ifndef nsAttrName_h___
14
#define nsAttrName_h___
15
16
#include "mozilla/dom/NodeInfo.h"
17
#include "nsAtom.h"
18
#include "nsDOMString.h"
19
20
0
#define NS_ATTRNAME_NODEINFO_BIT 1
21
class nsAttrName
22
{
23
public:
24
  nsAttrName(const nsAttrName& aOther)
25
    : mBits(aOther.mBits)
26
0
  {
27
0
    AddRefInternalName();
28
0
  }
29
30
  explicit nsAttrName(nsAtom* aAtom)
31
    : mBits(reinterpret_cast<uintptr_t>(aAtom))
32
0
  {
33
0
    NS_ASSERTION(aAtom, "null atom-name in nsAttrName");
34
0
    NS_ADDREF(aAtom);
35
0
  }
36
37
  explicit nsAttrName(mozilla::dom::NodeInfo* aNodeInfo)
38
0
  {
39
0
    NS_ASSERTION(aNodeInfo, "null nodeinfo-name in nsAttrName");
40
0
    if (aNodeInfo->NamespaceEquals(kNameSpaceID_None)) {
41
0
      mBits = reinterpret_cast<uintptr_t>(aNodeInfo->NameAtom());
42
0
      NS_ADDREF(aNodeInfo->NameAtom());
43
0
    }
44
0
    else {
45
0
      mBits = reinterpret_cast<uintptr_t>(aNodeInfo) |
46
0
              NS_ATTRNAME_NODEINFO_BIT;
47
0
      NS_ADDREF(aNodeInfo);
48
0
    }
49
0
  }
50
51
  ~nsAttrName()
52
0
  {
53
0
    ReleaseInternalName();
54
0
  }
55
56
  void SetTo(mozilla::dom::NodeInfo* aNodeInfo)
57
0
  {
58
0
    NS_ASSERTION(aNodeInfo, "null nodeinfo-name in nsAttrName");
59
0
60
0
    ReleaseInternalName();
61
0
    if (aNodeInfo->NamespaceEquals(kNameSpaceID_None)) {
62
0
      mBits = reinterpret_cast<uintptr_t>(aNodeInfo->NameAtom());
63
0
      NS_ADDREF(aNodeInfo->NameAtom());
64
0
    }
65
0
    else {
66
0
      mBits = reinterpret_cast<uintptr_t>(aNodeInfo) |
67
0
              NS_ATTRNAME_NODEINFO_BIT;
68
0
      NS_ADDREF(aNodeInfo);
69
0
    }
70
0
  }
71
72
  void SetTo(nsAtom* aAtom)
73
0
  {
74
0
    NS_ASSERTION(aAtom, "null atom-name in nsAttrName");
75
0
76
0
    ReleaseInternalName();
77
0
    mBits = reinterpret_cast<uintptr_t>(aAtom);
78
0
    NS_ADDREF(aAtom);
79
0
  }
80
81
  bool IsAtom() const
82
0
  {
83
0
    return !(mBits & NS_ATTRNAME_NODEINFO_BIT);
84
0
  }
85
86
  mozilla::dom::NodeInfo* NodeInfo() const
87
0
  {
88
0
    NS_ASSERTION(!IsAtom(), "getting nodeinfo-value of atom-name");
89
0
    return reinterpret_cast<mozilla::dom::NodeInfo*>(mBits & ~NS_ATTRNAME_NODEINFO_BIT);
90
0
  }
91
92
  nsAtom* Atom() const
93
0
  {
94
0
    NS_ASSERTION(IsAtom(), "getting atom-value of nodeinfo-name");
95
0
    return reinterpret_cast<nsAtom*>(mBits);
96
0
  }
97
98
  bool Equals(const nsAttrName& aOther) const
99
0
  {
100
0
    return mBits == aOther.mBits;
101
0
  }
102
103
  // Faster comparison in the case we know the namespace is null
104
  // Note that some callers such as AttrArray::IndexOfAttr() will
105
  // call this function on nsAttrName structs with 0 mBits, so no attempt
106
  // must be made to do anything with mBits besides comparing it with the
107
  // incoming aAtom argument.
108
  bool Equals(nsAtom* aAtom) const
109
0
  {
110
0
    return reinterpret_cast<uintptr_t>(aAtom) == mBits;
111
0
  }
112
113
  // And the same but without forcing callers to atomize
114
  bool Equals(const nsAString& aLocalName) const
115
0
  {
116
0
    return IsAtom() && Atom()->Equals(aLocalName);
117
0
  }
118
119
  bool Equals(nsAtom* aLocalName, int32_t aNamespaceID) const
120
0
  {
121
0
    if (aNamespaceID == kNameSpaceID_None) {
122
0
      return Equals(aLocalName);
123
0
    }
124
0
    return !IsAtom() && NodeInfo()->Equals(aLocalName, aNamespaceID);
125
0
  }
126
127
  bool Equals(mozilla::dom::NodeInfo* aNodeInfo) const
128
0
  {
129
0
    return Equals(aNodeInfo->NameAtom(), aNodeInfo->NamespaceID());
130
0
  }
131
132
  int32_t NamespaceID() const
133
0
  {
134
0
    return IsAtom() ? kNameSpaceID_None : NodeInfo()->NamespaceID();
135
0
  }
136
137
  int32_t NamespaceEquals(int32_t aNamespaceID) const
138
0
  {
139
0
    return aNamespaceID == kNameSpaceID_None ?
140
0
           IsAtom() :
141
0
           (!IsAtom() && NodeInfo()->NamespaceEquals(aNamespaceID));
142
0
  }
143
144
  nsAtom* LocalName() const
145
0
  {
146
0
    return IsAtom() ? Atom() : NodeInfo()->NameAtom();
147
0
  }
148
149
  nsAtom* GetPrefix() const
150
0
  {
151
0
    return IsAtom() ? nullptr : NodeInfo()->GetPrefixAtom();
152
0
  }
153
154
  bool QualifiedNameEquals(const nsAString& aName) const
155
0
  {
156
0
    return IsAtom() ? Atom()->Equals(aName) :
157
0
                      NodeInfo()->QualifiedNameEquals(aName);
158
0
  }
159
160
  void GetQualifiedName(nsAString& aStr) const
161
0
  {
162
0
    if (IsAtom()) {
163
0
      Atom()->ToString(aStr);
164
0
    }
165
0
    else {
166
0
      aStr = NodeInfo()->QualifiedName();
167
0
    }
168
0
  }
169
170
#ifdef MOZILLA_INTERNAL_API
171
  void GetPrefix(nsAString& aStr) const
172
0
  {
173
0
    if (IsAtom()) {
174
0
      SetDOMStringToNull(aStr);
175
0
    }
176
0
    else {
177
0
      NodeInfo()->GetPrefix(aStr);
178
0
    }
179
0
  }
180
#endif
181
182
  uint32_t HashValue() const
183
0
  {
184
0
    // mBits and uint32_t might have different size. This should silence
185
0
    // any warnings or compile-errors. This is what the implementation of
186
0
    // NS_PTR_TO_INT32 does to take care of the same problem.
187
0
    return mBits - 0;
188
0
  }
189
190
  bool IsSmaller(nsAtom* aOther) const
191
0
  {
192
0
    return mBits < reinterpret_cast<uintptr_t>(aOther);
193
0
  }
194
195
private:
196
197
  void AddRefInternalName()
198
0
  {
199
0
    if (IsAtom()) {
200
0
      NS_ADDREF(Atom());
201
0
    } else {
202
0
      NS_ADDREF(NodeInfo());
203
0
    }
204
0
  }
205
206
  void ReleaseInternalName()
207
0
  {
208
0
    if (IsAtom()) {
209
0
      Atom()->Release();
210
0
    } else {
211
0
      NodeInfo()->Release();
212
0
    }
213
0
  }
214
215
  uintptr_t mBits;
216
};
217
218
#endif