Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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 /*
7 * Class that represents the name (nodeinfo or atom) of an attribute;
8 * using nodeinfos all the time is too slow, so we use atoms when we
9 * can.
10 */
12 #ifndef nsAttrName_h___
13 #define nsAttrName_h___
15 #include "nsINodeInfo.h"
16 #include "nsIAtom.h"
17 #include "nsDOMString.h"
19 #define NS_ATTRNAME_NODEINFO_BIT 1
20 class nsAttrName
21 {
22 public:
23 nsAttrName(const nsAttrName& aOther)
24 : mBits(aOther.mBits)
25 {
26 AddRefInternalName();
27 }
29 explicit nsAttrName(nsIAtom* aAtom)
30 : mBits(reinterpret_cast<uintptr_t>(aAtom))
31 {
32 NS_ASSERTION(aAtom, "null atom-name in nsAttrName");
33 NS_ADDREF(aAtom);
34 }
36 explicit nsAttrName(nsINodeInfo* aNodeInfo)
37 {
38 NS_ASSERTION(aNodeInfo, "null nodeinfo-name in nsAttrName");
39 if (aNodeInfo->NamespaceEquals(kNameSpaceID_None)) {
40 mBits = reinterpret_cast<uintptr_t>(aNodeInfo->NameAtom());
41 NS_ADDREF(aNodeInfo->NameAtom());
42 }
43 else {
44 mBits = reinterpret_cast<uintptr_t>(aNodeInfo) |
45 NS_ATTRNAME_NODEINFO_BIT;
46 NS_ADDREF(aNodeInfo);
47 }
48 }
50 ~nsAttrName()
51 {
52 ReleaseInternalName();
53 }
55 void SetTo(nsINodeInfo* aNodeInfo)
56 {
57 NS_ASSERTION(aNodeInfo, "null nodeinfo-name in nsAttrName");
59 ReleaseInternalName();
60 if (aNodeInfo->NamespaceEquals(kNameSpaceID_None)) {
61 mBits = reinterpret_cast<uintptr_t>(aNodeInfo->NameAtom());
62 NS_ADDREF(aNodeInfo->NameAtom());
63 }
64 else {
65 mBits = reinterpret_cast<uintptr_t>(aNodeInfo) |
66 NS_ATTRNAME_NODEINFO_BIT;
67 NS_ADDREF(aNodeInfo);
68 }
69 }
71 void SetTo(nsIAtom* aAtom)
72 {
73 NS_ASSERTION(aAtom, "null atom-name in nsAttrName");
75 ReleaseInternalName();
76 mBits = reinterpret_cast<uintptr_t>(aAtom);
77 NS_ADDREF(aAtom);
78 }
80 bool IsAtom() const
81 {
82 return !(mBits & NS_ATTRNAME_NODEINFO_BIT);
83 }
85 nsINodeInfo* NodeInfo() const
86 {
87 NS_ASSERTION(!IsAtom(), "getting nodeinfo-value of atom-name");
88 return reinterpret_cast<nsINodeInfo*>(mBits & ~NS_ATTRNAME_NODEINFO_BIT);
89 }
91 nsIAtom* Atom() const
92 {
93 NS_ASSERTION(IsAtom(), "getting atom-value of nodeinfo-name");
94 return reinterpret_cast<nsIAtom*>(mBits);
95 }
97 bool Equals(const nsAttrName& aOther) const
98 {
99 return mBits == aOther.mBits;
100 }
102 // Faster comparison in the case we know the namespace is null
103 bool Equals(nsIAtom* aAtom) const
104 {
105 return reinterpret_cast<uintptr_t>(aAtom) == mBits;
106 }
108 // And the same but without forcing callers to atomize
109 bool Equals(const nsAString& aLocalName) const
110 {
111 return IsAtom() && Atom()->Equals(aLocalName);
112 }
114 bool Equals(nsIAtom* aLocalName, int32_t aNamespaceID) const
115 {
116 if (aNamespaceID == kNameSpaceID_None) {
117 return Equals(aLocalName);
118 }
119 return !IsAtom() && NodeInfo()->Equals(aLocalName, aNamespaceID);
120 }
122 bool Equals(nsINodeInfo* aNodeInfo) const
123 {
124 return Equals(aNodeInfo->NameAtom(), aNodeInfo->NamespaceID());
125 }
127 int32_t NamespaceID() const
128 {
129 return IsAtom() ? kNameSpaceID_None : NodeInfo()->NamespaceID();
130 }
132 int32_t NamespaceEquals(int32_t aNamespaceID) const
133 {
134 return aNamespaceID == kNameSpaceID_None ?
135 IsAtom() :
136 (!IsAtom() && NodeInfo()->NamespaceEquals(aNamespaceID));
137 }
139 nsIAtom* LocalName() const
140 {
141 return IsAtom() ? Atom() : NodeInfo()->NameAtom();
142 }
144 nsIAtom* GetPrefix() const
145 {
146 return IsAtom() ? nullptr : NodeInfo()->GetPrefixAtom();
147 }
149 bool QualifiedNameEquals(const nsAString& aName) const
150 {
151 return IsAtom() ? Atom()->Equals(aName) :
152 NodeInfo()->QualifiedNameEquals(aName);
153 }
155 void GetQualifiedName(nsAString& aStr) const
156 {
157 if (IsAtom()) {
158 Atom()->ToString(aStr);
159 }
160 else {
161 aStr = NodeInfo()->QualifiedName();
162 }
163 }
165 #ifdef MOZILLA_INTERNAL_API
166 void GetPrefix(nsAString& aStr) const
167 {
168 if (IsAtom()) {
169 SetDOMStringToNull(aStr);
170 }
171 else {
172 NodeInfo()->GetPrefix(aStr);
173 }
174 }
175 #endif
177 uint32_t HashValue() const
178 {
179 // mBits and uint32_t might have different size. This should silence
180 // any warnings or compile-errors. This is what the implementation of
181 // NS_PTR_TO_INT32 does to take care of the same problem.
182 return mBits - 0;
183 }
185 bool IsSmaller(nsIAtom* aOther) const
186 {
187 return mBits < reinterpret_cast<uintptr_t>(aOther);
188 }
190 private:
192 void AddRefInternalName()
193 {
194 // Since both nsINodeInfo and nsIAtom inherit nsISupports as its first
195 // interface we can safely assume that it's first in the vtable
196 nsISupports* name = reinterpret_cast<nsISupports *>
197 (mBits & ~NS_ATTRNAME_NODEINFO_BIT);
199 NS_ADDREF(name);
200 }
202 void ReleaseInternalName()
203 {
204 // Since both nsINodeInfo and nsIAtom inherit nsISupports as its first
205 // interface we can safely assume that it's first in the vtable
206 nsISupports* name = reinterpret_cast<nsISupports *>
207 (mBits & ~NS_ATTRNAME_NODEINFO_BIT);
209 NS_RELEASE(name);
210 }
212 uintptr_t mBits;
213 };
215 #endif