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/. */
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
13 #ifndef nsAttrName_h___
14 #define nsAttrName_h___
16 #include "mozilla/dom/NodeInfo.h"
18 #include "nsDOMString.h"
20 #define NS_ATTRNAME_NODEINFO_BIT 1
23 nsAttrName(const nsAttrName
& aOther
) : mBits(aOther
.mBits
) {
27 explicit nsAttrName(nsAtom
* aAtom
)
28 : mBits(reinterpret_cast<uintptr_t>(aAtom
)) {
29 NS_ASSERTION(aAtom
, "null atom-name in nsAttrName");
33 explicit nsAttrName(mozilla::dom::NodeInfo
* aNodeInfo
) {
34 NS_ASSERTION(aNodeInfo
, "null nodeinfo-name in nsAttrName");
35 if (aNodeInfo
->NamespaceEquals(kNameSpaceID_None
)) {
36 mBits
= reinterpret_cast<uintptr_t>(aNodeInfo
->NameAtom());
37 NS_ADDREF(aNodeInfo
->NameAtom());
39 mBits
= reinterpret_cast<uintptr_t>(aNodeInfo
) | NS_ATTRNAME_NODEINFO_BIT
;
44 ~nsAttrName() { ReleaseInternalName(); }
46 void SetTo(mozilla::dom::NodeInfo
* aNodeInfo
) {
47 NS_ASSERTION(aNodeInfo
, "null nodeinfo-name in nsAttrName");
49 ReleaseInternalName();
50 if (aNodeInfo
->NamespaceEquals(kNameSpaceID_None
)) {
51 mBits
= reinterpret_cast<uintptr_t>(aNodeInfo
->NameAtom());
52 NS_ADDREF(aNodeInfo
->NameAtom());
54 mBits
= reinterpret_cast<uintptr_t>(aNodeInfo
) | NS_ATTRNAME_NODEINFO_BIT
;
59 void SetTo(nsAtom
* aAtom
) {
60 NS_ASSERTION(aAtom
, "null atom-name in nsAttrName");
62 ReleaseInternalName();
63 mBits
= reinterpret_cast<uintptr_t>(aAtom
);
67 bool IsAtom() const { return !(mBits
& NS_ATTRNAME_NODEINFO_BIT
); }
69 mozilla::dom::NodeInfo
* NodeInfo() const {
70 NS_ASSERTION(!IsAtom(), "getting nodeinfo-value of atom-name");
71 return reinterpret_cast<mozilla::dom::NodeInfo
*>(mBits
&
72 ~NS_ATTRNAME_NODEINFO_BIT
);
75 nsAtom
* Atom() const {
76 NS_ASSERTION(IsAtom(), "getting atom-value of nodeinfo-name");
77 return reinterpret_cast<nsAtom
*>(mBits
);
80 bool Equals(const nsAttrName
& aOther
) const { return mBits
== aOther
.mBits
; }
82 // Faster comparison in the case we know the namespace is null
83 // Note that some callers such as AttrArray::IndexOfAttr() will
84 // call this function on nsAttrName structs with 0 mBits, so no attempt
85 // must be made to do anything with mBits besides comparing it with the
86 // incoming aAtom argument.
87 bool Equals(const nsAtom
* aAtom
) const {
88 return reinterpret_cast<uintptr_t>(aAtom
) == mBits
;
91 // And the same but without forcing callers to atomize
92 bool Equals(const nsAString
& aLocalName
) const {
93 return IsAtom() && Atom()->Equals(aLocalName
);
96 bool Equals(const nsAtom
* aLocalName
, int32_t aNamespaceID
) const {
97 if (aNamespaceID
== kNameSpaceID_None
) {
98 return Equals(aLocalName
);
100 return !IsAtom() && NodeInfo()->Equals(aLocalName
, aNamespaceID
);
103 bool Equals(mozilla::dom::NodeInfo
* aNodeInfo
) const {
104 return Equals(aNodeInfo
->NameAtom(), aNodeInfo
->NamespaceID());
107 int32_t NamespaceID() const {
108 return IsAtom() ? kNameSpaceID_None
: NodeInfo()->NamespaceID();
111 int32_t NamespaceEquals(int32_t aNamespaceID
) const {
112 return aNamespaceID
== kNameSpaceID_None
114 : (!IsAtom() && NodeInfo()->NamespaceEquals(aNamespaceID
));
117 nsAtom
* LocalName() const {
118 return IsAtom() ? Atom() : NodeInfo()->NameAtom();
121 nsAtom
* GetPrefix() const {
122 return IsAtom() ? nullptr : NodeInfo()->GetPrefixAtom();
125 bool QualifiedNameEquals(const nsAString
& aName
) const {
126 return IsAtom() ? Atom()->Equals(aName
)
127 : NodeInfo()->QualifiedNameEquals(aName
);
130 void GetQualifiedName(nsAString
& aStr
) const {
132 Atom()->ToString(aStr
);
134 aStr
= NodeInfo()->QualifiedName();
138 #ifdef MOZILLA_INTERNAL_API
139 void GetPrefix(nsAString
& aStr
) const {
141 SetDOMStringToNull(aStr
);
143 NodeInfo()->GetPrefix(aStr
);
148 uint32_t HashValue() const {
149 // mBits and uint32_t might have different size. This should silence
150 // any warnings or compile-errors. This is what the implementation of
151 // NS_PTR_TO_INT32 does to take care of the same problem.
155 bool IsSmaller(const nsAtom
* aOther
) const {
156 return mBits
< reinterpret_cast<uintptr_t>(aOther
);
160 void AddRefInternalName() {
164 NS_ADDREF(NodeInfo());
168 void ReleaseInternalName() {
172 NodeInfo()->Release();