Backed out changeset 58dbd2146e24 (bug 944961) for bustage.
[gecko.git] / content / base / src / nsAttrName.h
blob34910738c12d15742a62633da31ae5798eb7df6d
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.
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
22 public:
23 nsAttrName(const nsAttrName& aOther)
24 : mBits(aOther.mBits)
26 AddRefInternalName();
29 explicit nsAttrName(nsIAtom* aAtom)
30 : mBits(reinterpret_cast<uintptr_t>(aAtom))
32 NS_ASSERTION(aAtom, "null atom-name in nsAttrName");
33 NS_ADDREF(aAtom);
36 explicit nsAttrName(nsINodeInfo* aNodeInfo)
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());
43 else {
44 mBits = reinterpret_cast<uintptr_t>(aNodeInfo) |
45 NS_ATTRNAME_NODEINFO_BIT;
46 NS_ADDREF(aNodeInfo);
50 ~nsAttrName()
52 ReleaseInternalName();
55 void SetTo(nsINodeInfo* aNodeInfo)
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());
64 else {
65 mBits = reinterpret_cast<uintptr_t>(aNodeInfo) |
66 NS_ATTRNAME_NODEINFO_BIT;
67 NS_ADDREF(aNodeInfo);
71 void SetTo(nsIAtom* aAtom)
73 NS_ASSERTION(aAtom, "null atom-name in nsAttrName");
75 ReleaseInternalName();
76 mBits = reinterpret_cast<uintptr_t>(aAtom);
77 NS_ADDREF(aAtom);
80 bool IsAtom() const
82 return !(mBits & NS_ATTRNAME_NODEINFO_BIT);
85 nsINodeInfo* NodeInfo() const
87 NS_ASSERTION(!IsAtom(), "getting nodeinfo-value of atom-name");
88 return reinterpret_cast<nsINodeInfo*>(mBits & ~NS_ATTRNAME_NODEINFO_BIT);
91 nsIAtom* Atom() const
93 NS_ASSERTION(IsAtom(), "getting atom-value of nodeinfo-name");
94 return reinterpret_cast<nsIAtom*>(mBits);
97 bool Equals(const nsAttrName& aOther) const
99 return mBits == aOther.mBits;
102 // Faster comparison in the case we know the namespace is null
103 bool Equals(nsIAtom* aAtom) const
105 return reinterpret_cast<uintptr_t>(aAtom) == mBits;
108 // And the same but without forcing callers to atomize
109 bool Equals(const nsAString& aLocalName) const
111 return IsAtom() && Atom()->Equals(aLocalName);
114 bool Equals(nsIAtom* aLocalName, int32_t aNamespaceID) const
116 if (aNamespaceID == kNameSpaceID_None) {
117 return Equals(aLocalName);
119 return !IsAtom() && NodeInfo()->Equals(aLocalName, aNamespaceID);
122 bool Equals(nsINodeInfo* aNodeInfo) const
124 return Equals(aNodeInfo->NameAtom(), aNodeInfo->NamespaceID());
127 int32_t NamespaceID() const
129 return IsAtom() ? kNameSpaceID_None : NodeInfo()->NamespaceID();
132 int32_t NamespaceEquals(int32_t aNamespaceID) const
134 return aNamespaceID == kNameSpaceID_None ?
135 IsAtom() :
136 (!IsAtom() && NodeInfo()->NamespaceEquals(aNamespaceID));
139 nsIAtom* LocalName() const
141 return IsAtom() ? Atom() : NodeInfo()->NameAtom();
144 nsIAtom* GetPrefix() const
146 return IsAtom() ? nullptr : NodeInfo()->GetPrefixAtom();
149 bool QualifiedNameEquals(const nsAString& aName) const
151 return IsAtom() ? Atom()->Equals(aName) :
152 NodeInfo()->QualifiedNameEquals(aName);
155 void GetQualifiedName(nsAString& aStr) const
157 if (IsAtom()) {
158 Atom()->ToString(aStr);
160 else {
161 aStr = NodeInfo()->QualifiedName();
165 #ifdef MOZILLA_INTERNAL_API
166 void GetPrefix(nsAString& aStr) const
168 if (IsAtom()) {
169 SetDOMStringToNull(aStr);
171 else {
172 NodeInfo()->GetPrefix(aStr);
175 #endif
177 uint32_t HashValue() const
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;
185 bool IsSmaller(nsIAtom* aOther) const
187 return mBits < reinterpret_cast<uintptr_t>(aOther);
190 private:
192 void AddRefInternalName()
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);
202 void ReleaseInternalName()
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);
212 uintptr_t mBits;
215 #endif