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