1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/base/src/nsAttrName.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,215 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* 1.10 + * Class that represents the name (nodeinfo or atom) of an attribute; 1.11 + * using nodeinfos all the time is too slow, so we use atoms when we 1.12 + * can. 1.13 + */ 1.14 + 1.15 +#ifndef nsAttrName_h___ 1.16 +#define nsAttrName_h___ 1.17 + 1.18 +#include "nsINodeInfo.h" 1.19 +#include "nsIAtom.h" 1.20 +#include "nsDOMString.h" 1.21 + 1.22 +#define NS_ATTRNAME_NODEINFO_BIT 1 1.23 +class nsAttrName 1.24 +{ 1.25 +public: 1.26 + nsAttrName(const nsAttrName& aOther) 1.27 + : mBits(aOther.mBits) 1.28 + { 1.29 + AddRefInternalName(); 1.30 + } 1.31 + 1.32 + explicit nsAttrName(nsIAtom* aAtom) 1.33 + : mBits(reinterpret_cast<uintptr_t>(aAtom)) 1.34 + { 1.35 + NS_ASSERTION(aAtom, "null atom-name in nsAttrName"); 1.36 + NS_ADDREF(aAtom); 1.37 + } 1.38 + 1.39 + explicit nsAttrName(nsINodeInfo* aNodeInfo) 1.40 + { 1.41 + NS_ASSERTION(aNodeInfo, "null nodeinfo-name in nsAttrName"); 1.42 + if (aNodeInfo->NamespaceEquals(kNameSpaceID_None)) { 1.43 + mBits = reinterpret_cast<uintptr_t>(aNodeInfo->NameAtom()); 1.44 + NS_ADDREF(aNodeInfo->NameAtom()); 1.45 + } 1.46 + else { 1.47 + mBits = reinterpret_cast<uintptr_t>(aNodeInfo) | 1.48 + NS_ATTRNAME_NODEINFO_BIT; 1.49 + NS_ADDREF(aNodeInfo); 1.50 + } 1.51 + } 1.52 + 1.53 + ~nsAttrName() 1.54 + { 1.55 + ReleaseInternalName(); 1.56 + } 1.57 + 1.58 + void SetTo(nsINodeInfo* aNodeInfo) 1.59 + { 1.60 + NS_ASSERTION(aNodeInfo, "null nodeinfo-name in nsAttrName"); 1.61 + 1.62 + ReleaseInternalName(); 1.63 + if (aNodeInfo->NamespaceEquals(kNameSpaceID_None)) { 1.64 + mBits = reinterpret_cast<uintptr_t>(aNodeInfo->NameAtom()); 1.65 + NS_ADDREF(aNodeInfo->NameAtom()); 1.66 + } 1.67 + else { 1.68 + mBits = reinterpret_cast<uintptr_t>(aNodeInfo) | 1.69 + NS_ATTRNAME_NODEINFO_BIT; 1.70 + NS_ADDREF(aNodeInfo); 1.71 + } 1.72 + } 1.73 + 1.74 + void SetTo(nsIAtom* aAtom) 1.75 + { 1.76 + NS_ASSERTION(aAtom, "null atom-name in nsAttrName"); 1.77 + 1.78 + ReleaseInternalName(); 1.79 + mBits = reinterpret_cast<uintptr_t>(aAtom); 1.80 + NS_ADDREF(aAtom); 1.81 + } 1.82 + 1.83 + bool IsAtom() const 1.84 + { 1.85 + return !(mBits & NS_ATTRNAME_NODEINFO_BIT); 1.86 + } 1.87 + 1.88 + nsINodeInfo* NodeInfo() const 1.89 + { 1.90 + NS_ASSERTION(!IsAtom(), "getting nodeinfo-value of atom-name"); 1.91 + return reinterpret_cast<nsINodeInfo*>(mBits & ~NS_ATTRNAME_NODEINFO_BIT); 1.92 + } 1.93 + 1.94 + nsIAtom* Atom() const 1.95 + { 1.96 + NS_ASSERTION(IsAtom(), "getting atom-value of nodeinfo-name"); 1.97 + return reinterpret_cast<nsIAtom*>(mBits); 1.98 + } 1.99 + 1.100 + bool Equals(const nsAttrName& aOther) const 1.101 + { 1.102 + return mBits == aOther.mBits; 1.103 + } 1.104 + 1.105 + // Faster comparison in the case we know the namespace is null 1.106 + bool Equals(nsIAtom* aAtom) const 1.107 + { 1.108 + return reinterpret_cast<uintptr_t>(aAtom) == mBits; 1.109 + } 1.110 + 1.111 + // And the same but without forcing callers to atomize 1.112 + bool Equals(const nsAString& aLocalName) const 1.113 + { 1.114 + return IsAtom() && Atom()->Equals(aLocalName); 1.115 + } 1.116 + 1.117 + bool Equals(nsIAtom* aLocalName, int32_t aNamespaceID) const 1.118 + { 1.119 + if (aNamespaceID == kNameSpaceID_None) { 1.120 + return Equals(aLocalName); 1.121 + } 1.122 + return !IsAtom() && NodeInfo()->Equals(aLocalName, aNamespaceID); 1.123 + } 1.124 + 1.125 + bool Equals(nsINodeInfo* aNodeInfo) const 1.126 + { 1.127 + return Equals(aNodeInfo->NameAtom(), aNodeInfo->NamespaceID()); 1.128 + } 1.129 + 1.130 + int32_t NamespaceID() const 1.131 + { 1.132 + return IsAtom() ? kNameSpaceID_None : NodeInfo()->NamespaceID(); 1.133 + } 1.134 + 1.135 + int32_t NamespaceEquals(int32_t aNamespaceID) const 1.136 + { 1.137 + return aNamespaceID == kNameSpaceID_None ? 1.138 + IsAtom() : 1.139 + (!IsAtom() && NodeInfo()->NamespaceEquals(aNamespaceID)); 1.140 + } 1.141 + 1.142 + nsIAtom* LocalName() const 1.143 + { 1.144 + return IsAtom() ? Atom() : NodeInfo()->NameAtom(); 1.145 + } 1.146 + 1.147 + nsIAtom* GetPrefix() const 1.148 + { 1.149 + return IsAtom() ? nullptr : NodeInfo()->GetPrefixAtom(); 1.150 + } 1.151 + 1.152 + bool QualifiedNameEquals(const nsAString& aName) const 1.153 + { 1.154 + return IsAtom() ? Atom()->Equals(aName) : 1.155 + NodeInfo()->QualifiedNameEquals(aName); 1.156 + } 1.157 + 1.158 + void GetQualifiedName(nsAString& aStr) const 1.159 + { 1.160 + if (IsAtom()) { 1.161 + Atom()->ToString(aStr); 1.162 + } 1.163 + else { 1.164 + aStr = NodeInfo()->QualifiedName(); 1.165 + } 1.166 + } 1.167 + 1.168 +#ifdef MOZILLA_INTERNAL_API 1.169 + void GetPrefix(nsAString& aStr) const 1.170 + { 1.171 + if (IsAtom()) { 1.172 + SetDOMStringToNull(aStr); 1.173 + } 1.174 + else { 1.175 + NodeInfo()->GetPrefix(aStr); 1.176 + } 1.177 + } 1.178 +#endif 1.179 + 1.180 + uint32_t HashValue() const 1.181 + { 1.182 + // mBits and uint32_t might have different size. This should silence 1.183 + // any warnings or compile-errors. This is what the implementation of 1.184 + // NS_PTR_TO_INT32 does to take care of the same problem. 1.185 + return mBits - 0; 1.186 + } 1.187 + 1.188 + bool IsSmaller(nsIAtom* aOther) const 1.189 + { 1.190 + return mBits < reinterpret_cast<uintptr_t>(aOther); 1.191 + } 1.192 + 1.193 +private: 1.194 + 1.195 + void AddRefInternalName() 1.196 + { 1.197 + // Since both nsINodeInfo and nsIAtom inherit nsISupports as its first 1.198 + // interface we can safely assume that it's first in the vtable 1.199 + nsISupports* name = reinterpret_cast<nsISupports *> 1.200 + (mBits & ~NS_ATTRNAME_NODEINFO_BIT); 1.201 + 1.202 + NS_ADDREF(name); 1.203 + } 1.204 + 1.205 + void ReleaseInternalName() 1.206 + { 1.207 + // Since both nsINodeInfo and nsIAtom inherit nsISupports as its first 1.208 + // interface we can safely assume that it's first in the vtable 1.209 + nsISupports* name = reinterpret_cast<nsISupports *> 1.210 + (mBits & ~NS_ATTRNAME_NODEINFO_BIT); 1.211 + 1.212 + NS_RELEASE(name); 1.213 + } 1.214 + 1.215 + uintptr_t mBits; 1.216 +}; 1.217 + 1.218 +#endif