content/base/src/nsAttrAndChildArray.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/base/src/nsAttrAndChildArray.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 + * Storage of the children and attributes of a DOM node; storage for
    1.11 + * the two is unified to minimize footprint.
    1.12 + */
    1.13 +
    1.14 +#ifndef nsAttrAndChildArray_h___
    1.15 +#define nsAttrAndChildArray_h___
    1.16 +
    1.17 +#include "mozilla/Attributes.h"
    1.18 +#include "mozilla/MemoryReporting.h"
    1.19 +
    1.20 +#include "nscore.h"
    1.21 +#include "nsAttrName.h"
    1.22 +#include "nsAttrValue.h"
    1.23 +#include "nsCaseTreatment.h"
    1.24 +
    1.25 +class nsINode;
    1.26 +class nsIContent;
    1.27 +class nsMappedAttributes;
    1.28 +class nsHTMLStyleSheet;
    1.29 +class nsRuleWalker;
    1.30 +class nsMappedAttributeElement;
    1.31 +
    1.32 +#define ATTRCHILD_ARRAY_GROWSIZE 8
    1.33 +#define ATTRCHILD_ARRAY_LINEAR_THRESHOLD 32
    1.34 +
    1.35 +#define ATTRCHILD_ARRAY_ATTR_SLOTS_BITS 10
    1.36 +
    1.37 +#define ATTRCHILD_ARRAY_MAX_ATTR_COUNT \
    1.38 +    ((1 << ATTRCHILD_ARRAY_ATTR_SLOTS_BITS) - 1)
    1.39 +
    1.40 +#define ATTRCHILD_ARRAY_MAX_CHILD_COUNT \
    1.41 +    (~uint32_t(0) >> ATTRCHILD_ARRAY_ATTR_SLOTS_BITS)
    1.42 +
    1.43 +#define ATTRCHILD_ARRAY_ATTR_SLOTS_COUNT_MASK \
    1.44 +    ((1 << ATTRCHILD_ARRAY_ATTR_SLOTS_BITS) - 1)
    1.45 +
    1.46 +
    1.47 +#define ATTRSIZE (sizeof(InternalAttr) / sizeof(void*))
    1.48 +
    1.49 +class nsAttrAndChildArray
    1.50 +{
    1.51 +public:
    1.52 +  nsAttrAndChildArray();
    1.53 +  ~nsAttrAndChildArray();
    1.54 +
    1.55 +  uint32_t ChildCount() const
    1.56 +  {
    1.57 +    return mImpl ? (mImpl->mAttrAndChildCount >> ATTRCHILD_ARRAY_ATTR_SLOTS_BITS) : 0;
    1.58 +  }
    1.59 +  nsIContent* ChildAt(uint32_t aPos) const
    1.60 +  {
    1.61 +    NS_ASSERTION(aPos < ChildCount(), "out-of-bounds access in nsAttrAndChildArray");
    1.62 +    return reinterpret_cast<nsIContent*>(mImpl->mBuffer[AttrSlotsSize() + aPos]);
    1.63 +  }
    1.64 +  nsIContent* GetSafeChildAt(uint32_t aPos) const;
    1.65 +  nsIContent * const * GetChildArray(uint32_t* aChildCount) const;
    1.66 +  nsresult AppendChild(nsIContent* aChild)
    1.67 +  {
    1.68 +    return InsertChildAt(aChild, ChildCount());
    1.69 +  }
    1.70 +  nsresult InsertChildAt(nsIContent* aChild, uint32_t aPos);
    1.71 +  void RemoveChildAt(uint32_t aPos);
    1.72 +  // Like RemoveChildAt but hands the reference to the child being
    1.73 +  // removed back to the caller instead of just releasing it.
    1.74 +  already_AddRefed<nsIContent> TakeChildAt(uint32_t aPos);
    1.75 +  int32_t IndexOfChild(const nsINode* aPossibleChild) const;
    1.76 +
    1.77 +  bool HasAttrs() const
    1.78 +  {
    1.79 +    return MappedAttrCount() || (AttrSlotCount() && AttrSlotIsTaken(0));
    1.80 +  }
    1.81 +
    1.82 +  uint32_t AttrCount() const;
    1.83 +  const nsAttrValue* GetAttr(nsIAtom* aLocalName,
    1.84 +                             int32_t aNamespaceID = kNameSpaceID_None) const;
    1.85 +  // As above but using a string attr name and always using
    1.86 +  // kNameSpaceID_None.  This is always case-sensitive.
    1.87 +  const nsAttrValue* GetAttr(const nsAString& aName) const;
    1.88 +  // Get an nsAttrValue by qualified name.  Can optionally do
    1.89 +  // ASCII-case-insensitive name matching.
    1.90 +  const nsAttrValue* GetAttr(const nsAString& aName,
    1.91 +                             nsCaseTreatment aCaseSensitive) const;
    1.92 +  const nsAttrValue* AttrAt(uint32_t aPos) const;
    1.93 +  nsresult SetAndTakeAttr(nsIAtom* aLocalName, nsAttrValue& aValue);
    1.94 +  nsresult SetAndTakeAttr(nsINodeInfo* aName, nsAttrValue& aValue);
    1.95 +
    1.96 +  // Remove the attr at position aPos.  The value of the attr is placed in
    1.97 +  // aValue; any value that was already in aValue is destroyed.
    1.98 +  nsresult RemoveAttrAt(uint32_t aPos, nsAttrValue& aValue);
    1.99 +
   1.100 +  // Returns attribute name at given position, *not* out-of-bounds safe
   1.101 +  const nsAttrName* AttrNameAt(uint32_t aPos) const;
   1.102 +
   1.103 +  // Returns attribute name at given position or null if aPos is out-of-bounds
   1.104 +  const nsAttrName* GetSafeAttrNameAt(uint32_t aPos) const;
   1.105 +
   1.106 +  const nsAttrName* GetExistingAttrNameFromQName(const nsAString& aName) const;
   1.107 +  int32_t IndexOfAttr(nsIAtom* aLocalName, int32_t aNamespaceID = kNameSpaceID_None) const;
   1.108 +
   1.109 +  nsresult SetAndTakeMappedAttr(nsIAtom* aLocalName, nsAttrValue& aValue,
   1.110 +                                nsMappedAttributeElement* aContent,
   1.111 +                                nsHTMLStyleSheet* aSheet);
   1.112 +  nsresult SetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet) {
   1.113 +    if (!mImpl || !mImpl->mMappedAttrs) {
   1.114 +      return NS_OK;
   1.115 +    }
   1.116 +    return DoSetMappedAttrStyleSheet(aSheet);
   1.117 +  }
   1.118 +  void WalkMappedAttributeStyleRules(nsRuleWalker* aRuleWalker);
   1.119 +
   1.120 +  void Compact();
   1.121 +
   1.122 +  bool CanFitMoreAttrs() const
   1.123 +  {
   1.124 +    return AttrSlotCount() < ATTRCHILD_ARRAY_MAX_ATTR_COUNT ||
   1.125 +           !AttrSlotIsTaken(ATTRCHILD_ARRAY_MAX_ATTR_COUNT - 1);
   1.126 +  }
   1.127 +
   1.128 +  size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   1.129 +  bool HasMappedAttrs() const
   1.130 +  {
   1.131 +    return MappedAttrCount();
   1.132 +  }
   1.133 +
   1.134 +private:
   1.135 +  nsAttrAndChildArray(const nsAttrAndChildArray& aOther) MOZ_DELETE;
   1.136 +  nsAttrAndChildArray& operator=(const nsAttrAndChildArray& aOther) MOZ_DELETE;
   1.137 +
   1.138 +  void Clear();
   1.139 +
   1.140 +  uint32_t NonMappedAttrCount() const;
   1.141 +  uint32_t MappedAttrCount() const;
   1.142 +
   1.143 +  // Returns a non-null zero-refcount object.
   1.144 +  nsMappedAttributes*
   1.145 +  GetModifiableMapped(nsMappedAttributeElement* aContent,
   1.146 +                      nsHTMLStyleSheet* aSheet,
   1.147 +                      bool aWillAddAttr);
   1.148 +  nsresult MakeMappedUnique(nsMappedAttributes* aAttributes);
   1.149 +
   1.150 +  uint32_t AttrSlotsSize() const
   1.151 +  {
   1.152 +    return AttrSlotCount() * ATTRSIZE;
   1.153 +  }
   1.154 +
   1.155 +  uint32_t AttrSlotCount() const
   1.156 +  {
   1.157 +    return mImpl ? mImpl->mAttrAndChildCount & ATTRCHILD_ARRAY_ATTR_SLOTS_COUNT_MASK : 0;
   1.158 +  }
   1.159 +
   1.160 +  bool AttrSlotIsTaken(uint32_t aSlot) const
   1.161 +  {
   1.162 +    NS_PRECONDITION(aSlot < AttrSlotCount(), "out-of-bounds");
   1.163 +    return mImpl->mBuffer[aSlot * ATTRSIZE];
   1.164 +  }
   1.165 +
   1.166 +  void SetChildCount(uint32_t aCount)
   1.167 +  {
   1.168 +    mImpl->mAttrAndChildCount = 
   1.169 +        (mImpl->mAttrAndChildCount & ATTRCHILD_ARRAY_ATTR_SLOTS_COUNT_MASK) |
   1.170 +        (aCount << ATTRCHILD_ARRAY_ATTR_SLOTS_BITS);
   1.171 +  }
   1.172 +
   1.173 +  void SetAttrSlotCount(uint32_t aCount)
   1.174 +  {
   1.175 +    mImpl->mAttrAndChildCount =
   1.176 +        (mImpl->mAttrAndChildCount & ~ATTRCHILD_ARRAY_ATTR_SLOTS_COUNT_MASK) |
   1.177 +        aCount;
   1.178 +  }
   1.179 +
   1.180 +  void SetAttrSlotAndChildCount(uint32_t aSlotCount, uint32_t aChildCount)
   1.181 +  {
   1.182 +    mImpl->mAttrAndChildCount = aSlotCount |
   1.183 +      (aChildCount << ATTRCHILD_ARRAY_ATTR_SLOTS_BITS);
   1.184 +  }
   1.185 +
   1.186 +  bool GrowBy(uint32_t aGrowSize);
   1.187 +  bool AddAttrSlot();
   1.188 +
   1.189 +  /**
   1.190 +   * Set *aPos to aChild and update sibling pointers as needed.  aIndex is the
   1.191 +   * index at which aChild is actually being inserted.  aChildCount is the
   1.192 +   * number of kids we had before the insertion.
   1.193 +   */
   1.194 +  inline void SetChildAtPos(void** aPos, nsIContent* aChild, uint32_t aIndex,
   1.195 +                            uint32_t aChildCount);
   1.196 +
   1.197 +  /**
   1.198 +   * Guts of SetMappedAttrStyleSheet for the rare case when we have mapped attrs
   1.199 +   */
   1.200 +  nsresult DoSetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet);
   1.201 +
   1.202 +  struct InternalAttr
   1.203 +  {
   1.204 +    nsAttrName mName;
   1.205 +    nsAttrValue mValue;
   1.206 +  };
   1.207 +
   1.208 +  struct Impl {
   1.209 +    uint32_t mAttrAndChildCount;
   1.210 +    uint32_t mBufferSize;
   1.211 +    nsMappedAttributes* mMappedAttrs;
   1.212 +    void* mBuffer[1];
   1.213 +  };
   1.214 +
   1.215 +  Impl* mImpl;
   1.216 +};
   1.217 +
   1.218 +#endif

mercurial