Bug 1812499 [wpt PR 38184] - Simplify handling of name-to-subdir mapping in canvas...
[gecko.git] / dom / base / nsAttrName.h
blob5af01b028b61f19de12ae25510a4000cc1b66d6a
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/. */
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.
13 #ifndef nsAttrName_h___
14 #define nsAttrName_h___
16 #include "mozilla/dom/NodeInfo.h"
17 #include "nsAtom.h"
18 #include "nsDOMString.h"
20 #define NS_ATTRNAME_NODEINFO_BIT 1
21 class nsAttrName {
22 public:
23 nsAttrName(const nsAttrName& aOther) : mBits(aOther.mBits) {
24 AddRefInternalName();
27 explicit nsAttrName(nsAtom* aAtom)
28 : mBits(reinterpret_cast<uintptr_t>(aAtom)) {
29 NS_ASSERTION(aAtom, "null atom-name in nsAttrName");
30 NS_ADDREF(aAtom);
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());
38 } else {
39 mBits = reinterpret_cast<uintptr_t>(aNodeInfo) | NS_ATTRNAME_NODEINFO_BIT;
40 NS_ADDREF(aNodeInfo);
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());
53 } else {
54 mBits = reinterpret_cast<uintptr_t>(aNodeInfo) | NS_ATTRNAME_NODEINFO_BIT;
55 NS_ADDREF(aNodeInfo);
59 void SetTo(nsAtom* aAtom) {
60 NS_ASSERTION(aAtom, "null atom-name in nsAttrName");
62 ReleaseInternalName();
63 mBits = reinterpret_cast<uintptr_t>(aAtom);
64 NS_ADDREF(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
113 ? IsAtom()
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 {
131 if (IsAtom()) {
132 Atom()->ToString(aStr);
133 } else {
134 aStr = NodeInfo()->QualifiedName();
138 #ifdef MOZILLA_INTERNAL_API
139 void GetPrefix(nsAString& aStr) const {
140 if (IsAtom()) {
141 SetDOMStringToNull(aStr);
142 } else {
143 NodeInfo()->GetPrefix(aStr);
146 #endif
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.
152 return mBits - 0;
155 bool IsSmaller(const nsAtom* aOther) const {
156 return mBits < reinterpret_cast<uintptr_t>(aOther);
159 private:
160 void AddRefInternalName() {
161 if (IsAtom()) {
162 NS_ADDREF(Atom());
163 } else {
164 NS_ADDREF(NodeInfo());
168 void ReleaseInternalName() {
169 if (IsAtom()) {
170 Atom()->Release();
171 } else {
172 NodeInfo()->Release();
176 uintptr_t mBits;
179 #endif