tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsAttrName.h (5218B)


      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/. */
      6 
      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.
     11 */
     12 
     13 #ifndef nsAttrName_h___
     14 #define nsAttrName_h___
     15 
     16 #include "mozilla/dom/NodeInfo.h"
     17 #include "nsAtom.h"
     18 #include "nsDOMString.h"
     19 
     20 #define NS_ATTRNAME_NODEINFO_BIT 1
     21 class nsAttrName {
     22 public:
     23  nsAttrName(const nsAttrName& aOther) : mBits(aOther.mBits) {
     24    AddRefInternalName();
     25  }
     26 
     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);
     31  }
     32 
     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);
     41    }
     42  }
     43 
     44  ~nsAttrName() { ReleaseInternalName(); }
     45 
     46  void SetTo(mozilla::dom::NodeInfo* aNodeInfo) {
     47    NS_ASSERTION(aNodeInfo, "null nodeinfo-name in nsAttrName");
     48 
     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);
     56    }
     57  }
     58 
     59  void SetTo(nsAtom* aAtom) {
     60    NS_ASSERTION(aAtom, "null atom-name in nsAttrName");
     61 
     62    ReleaseInternalName();
     63    mBits = reinterpret_cast<uintptr_t>(aAtom);
     64    NS_ADDREF(aAtom);
     65  }
     66 
     67  bool IsAtom() const { return !(mBits & NS_ATTRNAME_NODEINFO_BIT); }
     68 
     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);
     73  }
     74 
     75  nsAtom* Atom() const {
     76    NS_ASSERTION(IsAtom(), "getting atom-value of nodeinfo-name");
     77    return reinterpret_cast<nsAtom*>(mBits);
     78  }
     79 
     80  bool Equals(const nsAttrName& aOther) const { return mBits == aOther.mBits; }
     81 
     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;
     89  }
     90 
     91  // And the same but without forcing callers to atomize
     92  bool Equals(const nsAString& aLocalName) const {
     93    return IsAtom() && Atom()->Equals(aLocalName);
     94  }
     95 
     96  bool Equals(const nsAtom* aLocalName, int32_t aNamespaceID) const {
     97    if (aNamespaceID == kNameSpaceID_None) {
     98      return Equals(aLocalName);
     99    }
    100    return !IsAtom() && NodeInfo()->Equals(aLocalName, aNamespaceID);
    101  }
    102 
    103  bool Equals(mozilla::dom::NodeInfo* aNodeInfo) const {
    104    return Equals(aNodeInfo->NameAtom(), aNodeInfo->NamespaceID());
    105  }
    106 
    107  int32_t NamespaceID() const {
    108    return IsAtom() ? kNameSpaceID_None : NodeInfo()->NamespaceID();
    109  }
    110 
    111  int32_t NamespaceEquals(int32_t aNamespaceID) const {
    112    return aNamespaceID == kNameSpaceID_None
    113               ? IsAtom()
    114               : (!IsAtom() && NodeInfo()->NamespaceEquals(aNamespaceID));
    115  }
    116 
    117  nsAtom* LocalName() const {
    118    return IsAtom() ? Atom() : NodeInfo()->NameAtom();
    119  }
    120 
    121  nsAtom* GetPrefix() const {
    122    return IsAtom() ? nullptr : NodeInfo()->GetPrefixAtom();
    123  }
    124 
    125  bool QualifiedNameEquals(const nsAString& aName) const {
    126    return IsAtom() ? Atom()->Equals(aName)
    127                    : NodeInfo()->QualifiedNameEquals(aName);
    128  }
    129 
    130  void GetQualifiedName(nsAString& aStr) const {
    131    if (IsAtom()) {
    132      Atom()->ToString(aStr);
    133    } else {
    134      aStr = NodeInfo()->QualifiedName();
    135    }
    136  }
    137 
    138 #ifdef MOZILLA_INTERNAL_API
    139  void GetPrefix(nsAString& aStr) const {
    140    if (IsAtom()) {
    141      SetDOMStringToNull(aStr);
    142    } else {
    143      NodeInfo()->GetPrefix(aStr);
    144    }
    145  }
    146 #endif
    147 
    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;
    153  }
    154 
    155  bool IsSmaller(const nsAtom* aOther) const {
    156    return mBits < reinterpret_cast<uintptr_t>(aOther);
    157  }
    158 
    159 private:
    160  void AddRefInternalName() {
    161    if (IsAtom()) {
    162      NS_ADDREF(Atom());
    163    } else {
    164      NS_ADDREF(NodeInfo());
    165    }
    166  }
    167 
    168  void ReleaseInternalName() {
    169    if (IsAtom()) {
    170      Atom()->Release();
    171    } else {
    172      NodeInfo()->Release();
    173    }
    174  }
    175 
    176  uintptr_t mBits;
    177 };
    178 
    179 #endif