LCOV - code coverage report
Current view: top level - dom/base - nsAttrAndChildArray.h (source / functions) Hit Total Coverage
Test: output.info Lines: 33 37 89.2 %
Date: 2017-07-14 16:53:18 Functions: 12 13 92.3 %
Legend: Lines: hit not hit

          Line data    Source code
       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             :  * Storage of the children and attributes of a DOM node; storage for
       9             :  * the two is unified to minimize footprint.
      10             :  */
      11             : 
      12             : #ifndef nsAttrAndChildArray_h___
      13             : #define nsAttrAndChildArray_h___
      14             : 
      15             : #include "mozilla/Attributes.h"
      16             : #include "mozilla/MemoryReporting.h"
      17             : #include "mozilla/dom/BorrowedAttrInfo.h"
      18             : 
      19             : #include "nscore.h"
      20             : #include "nsAttrName.h"
      21             : #include "nsAttrValue.h"
      22             : #include "nsCaseTreatment.h"
      23             : 
      24             : class nsINode;
      25             : class nsIContent;
      26             : class nsMappedAttributes;
      27             : class nsHTMLStyleSheet;
      28             : class nsRuleWalker;
      29             : class nsMappedAttributeElement;
      30             : 
      31             : #define ATTRCHILD_ARRAY_GROWSIZE 8
      32             : #define ATTRCHILD_ARRAY_LINEAR_THRESHOLD 32
      33             : 
      34             : #define ATTRCHILD_ARRAY_ATTR_SLOTS_BITS 10
      35             : 
      36             : #define ATTRCHILD_ARRAY_MAX_ATTR_COUNT \
      37             :     ((1 << ATTRCHILD_ARRAY_ATTR_SLOTS_BITS) - 1)
      38             : 
      39             : #define ATTRCHILD_ARRAY_MAX_CHILD_COUNT \
      40             :     (~uint32_t(0) >> ATTRCHILD_ARRAY_ATTR_SLOTS_BITS)
      41             : 
      42             : #define ATTRCHILD_ARRAY_ATTR_SLOTS_COUNT_MASK \
      43             :     ((1 << ATTRCHILD_ARRAY_ATTR_SLOTS_BITS) - 1)
      44             : 
      45             : 
      46             : #define ATTRSIZE (sizeof(InternalAttr) / sizeof(void*))
      47             : 
      48             : class nsAttrAndChildArray
      49             : {
      50             :   typedef mozilla::dom::BorrowedAttrInfo BorrowedAttrInfo;
      51             : public:
      52             :   nsAttrAndChildArray();
      53             :   ~nsAttrAndChildArray();
      54             : 
      55       29809 :   uint32_t ChildCount() const
      56             :   {
      57       29809 :     return mImpl ? (mImpl->mAttrAndChildCount >> ATTRCHILD_ARRAY_ATTR_SLOTS_BITS) : 0;
      58             :   }
      59        2667 :   nsIContent* ChildAt(uint32_t aPos) const
      60             :   {
      61        2667 :     NS_ASSERTION(aPos < ChildCount(), "out-of-bounds access in nsAttrAndChildArray");
      62        2667 :     return reinterpret_cast<nsIContent*>(mImpl->mBuffer[AttrSlotsSize() + aPos]);
      63             :   }
      64             :   nsIContent* GetSafeChildAt(uint32_t aPos) const;
      65             :   nsIContent * const * GetChildArray(uint32_t* aChildCount) const;
      66             :   nsresult AppendChild(nsIContent* aChild)
      67             :   {
      68             :     return InsertChildAt(aChild, ChildCount());
      69             :   }
      70             :   nsresult InsertChildAt(nsIContent* aChild, uint32_t aPos);
      71             :   void RemoveChildAt(uint32_t aPos);
      72             :   // Like RemoveChildAt but hands the reference to the child being
      73             :   // removed back to the caller instead of just releasing it.
      74             :   already_AddRefed<nsIContent> TakeChildAt(uint32_t aPos);
      75             :   int32_t IndexOfChild(const nsINode* aPossibleChild) const;
      76             : 
      77       56070 :   bool HasAttrs() const
      78             :   {
      79       56070 :     return MappedAttrCount() || (AttrSlotCount() && AttrSlotIsTaken(0));
      80             :   }
      81             : 
      82             :   uint32_t AttrCount() const;
      83             :   const nsAttrValue* GetAttr(nsIAtom* aLocalName,
      84             :                              int32_t aNamespaceID = kNameSpaceID_None) const;
      85             :   // As above but using a string attr name and always using
      86             :   // kNameSpaceID_None.  This is always case-sensitive.
      87             :   const nsAttrValue* GetAttr(const nsAString& aName) const;
      88             :   // Get an nsAttrValue by qualified name.  Can optionally do
      89             :   // ASCII-case-insensitive name matching.
      90             :   const nsAttrValue* GetAttr(const nsAString& aName,
      91             :                              nsCaseTreatment aCaseSensitive) const;
      92             :   const nsAttrValue* AttrAt(uint32_t aPos) const;
      93             :   // SetAndSwapAttr swaps the current attribute value with aValue.
      94             :   // If the attribute was unset, an empty value will be swapped into aValue
      95             :   // and aHadValue will be set to false. Otherwise, aHadValue will be set to
      96             :   // true.
      97             :   nsresult SetAndSwapAttr(nsIAtom* aLocalName, nsAttrValue& aValue,
      98             :                           bool* aHadValue);
      99             :   nsresult SetAndSwapAttr(mozilla::dom::NodeInfo* aName, nsAttrValue& aValue,
     100             :                           bool* aHadValue);
     101             : 
     102             :   // Remove the attr at position aPos.  The value of the attr is placed in
     103             :   // aValue; any value that was already in aValue is destroyed.
     104             :   nsresult RemoveAttrAt(uint32_t aPos, nsAttrValue& aValue);
     105             : 
     106             :   // Returns attribute name at given position, *not* out-of-bounds safe
     107             :   const nsAttrName* AttrNameAt(uint32_t aPos) const;
     108             : 
     109             :   // Returns the attribute info at a given position, *not* out-of-bounds safe
     110             :   BorrowedAttrInfo AttrInfoAt(uint32_t aPos) const;
     111             : 
     112             :   // Returns attribute name at given position or null if aPos is out-of-bounds
     113             :   const nsAttrName* GetSafeAttrNameAt(uint32_t aPos) const;
     114             : 
     115             :   const nsAttrName* GetExistingAttrNameFromQName(const nsAString& aName) const;
     116             :   int32_t IndexOfAttr(nsIAtom* aLocalName, int32_t aNamespaceID = kNameSpaceID_None) const;
     117             : 
     118             :   // SetAndSwapMappedAttr swaps the current attribute value with aValue.
     119             :   // If the attribute was unset, an empty value will be swapped into aValue
     120             :   // and aHadValue will be set to false. Otherwise, aHadValue will be set to
     121             :   // true.
     122             :   nsresult SetAndSwapMappedAttr(nsIAtom* aLocalName, nsAttrValue& aValue,
     123             :                                 nsMappedAttributeElement* aContent,
     124             :                                 nsHTMLStyleSheet* aSheet,
     125             :                                 bool* aHadValue);
     126           0 :   nsresult SetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet) {
     127           0 :     if (!mImpl || !mImpl->mMappedAttrs) {
     128           0 :       return NS_OK;
     129             :     }
     130           0 :     return DoSetMappedAttrStyleSheet(aSheet);
     131             :   }
     132             :   void WalkMappedAttributeStyleRules(nsRuleWalker* aRuleWalker);
     133             : 
     134             :   void Compact();
     135             : 
     136        1917 :   bool CanFitMoreAttrs() const
     137             :   {
     138        1917 :     return AttrSlotCount() < ATTRCHILD_ARRAY_MAX_ATTR_COUNT ||
     139        1917 :            !AttrSlotIsTaken(ATTRCHILD_ARRAY_MAX_ATTR_COUNT - 1);
     140             :   }
     141             : 
     142             :   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     143         374 :   bool HasMappedAttrs() const
     144             :   {
     145         374 :     return MappedAttrCount();
     146             :   }
     147             :   const nsMappedAttributes* GetMapped() const;
     148             : 
     149             :   // Force this to have mapped attributes, even if those attributes are empty.
     150             :   nsresult ForceMapped(nsMappedAttributeElement* aContent, nsIDocument* aDocument);
     151             : 
     152             :   // Clear the servo declaration block on the mapped attributes, if any
     153             :   // Will assert off main thread
     154             :   void ClearMappedServoStyle();
     155             : 
     156             :   // Increases capacity (if necessary) to have enough space to accomodate the
     157             :   // unmapped attributes and children of |aOther|. If |aAllocateChildren| is not
     158             :   // true, only enough space for unmapped attributes will be reserved.
     159             :   // It is REQUIRED that this function be called ONLY when the array is empty.
     160             :   nsresult EnsureCapacityToClone(const nsAttrAndChildArray& aOther,
     161             :                                  bool aAllocateChildren);
     162             : 
     163             : private:
     164             :   nsAttrAndChildArray(const nsAttrAndChildArray& aOther) = delete;
     165             :   nsAttrAndChildArray& operator=(const nsAttrAndChildArray& aOther) = delete;
     166             : 
     167             :   void Clear();
     168             : 
     169             :   uint32_t NonMappedAttrCount() const;
     170             :   uint32_t MappedAttrCount() const;
     171             : 
     172             :   // Returns a non-null zero-refcount object.
     173             :   nsMappedAttributes*
     174             :   GetModifiableMapped(nsMappedAttributeElement* aContent,
     175             :                       nsHTMLStyleSheet* aSheet,
     176             :                       bool aWillAddAttr,
     177             :                       int32_t aAttrCount = 1);
     178             :   nsresult MakeMappedUnique(nsMappedAttributes* aAttributes);
     179             : 
     180        7203 :   uint32_t AttrSlotsSize() const
     181             :   {
     182        7203 :     return AttrSlotCount() * ATTRSIZE;
     183             :   }
     184             : 
     185      833543 :   uint32_t AttrSlotCount() const
     186             :   {
     187      833543 :     return mImpl ? mImpl->mAttrAndChildCount & ATTRCHILD_ARRAY_ATTR_SLOTS_COUNT_MASK : 0;
     188             :   }
     189             : 
     190      547351 :   bool AttrSlotIsTaken(uint32_t aSlot) const
     191             :   {
     192      547351 :     NS_PRECONDITION(aSlot < AttrSlotCount(), "out-of-bounds");
     193      547351 :     return mImpl->mBuffer[aSlot * ATTRSIZE];
     194             :   }
     195             : 
     196        3526 :   void SetChildCount(uint32_t aCount)
     197             :   {
     198        7052 :     mImpl->mAttrAndChildCount =
     199        7052 :         (mImpl->mAttrAndChildCount & ATTRCHILD_ARRAY_ATTR_SLOTS_COUNT_MASK) |
     200        3526 :         (aCount << ATTRCHILD_ARRAY_ATTR_SLOTS_BITS);
     201        3526 :   }
     202             : 
     203        6489 :   void SetAttrSlotCount(uint32_t aCount)
     204             :   {
     205       12978 :     mImpl->mAttrAndChildCount =
     206        6489 :         (mImpl->mAttrAndChildCount & ~ATTRCHILD_ARRAY_ATTR_SLOTS_COUNT_MASK) |
     207             :         aCount;
     208        6489 :   }
     209             : 
     210        3037 :   void SetAttrSlotAndChildCount(uint32_t aSlotCount, uint32_t aChildCount)
     211             :   {
     212        6074 :     mImpl->mAttrAndChildCount = aSlotCount |
     213        3037 :       (aChildCount << ATTRCHILD_ARRAY_ATTR_SLOTS_BITS);
     214        3037 :   }
     215             : 
     216             :   bool GrowBy(uint32_t aGrowSize);
     217             :   bool AddAttrSlot();
     218             : 
     219             :   /**
     220             :    * Set *aPos to aChild and update sibling pointers as needed.  aIndex is the
     221             :    * index at which aChild is actually being inserted.  aChildCount is the
     222             :    * number of kids we had before the insertion.
     223             :    */
     224             :   inline void SetChildAtPos(void** aPos, nsIContent* aChild, uint32_t aIndex,
     225             :                             uint32_t aChildCount);
     226             : 
     227             :   /**
     228             :    * Guts of SetMappedAttrStyleSheet for the rare case when we have mapped attrs
     229             :    */
     230             :   nsresult DoSetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet);
     231             : 
     232         248 :   struct InternalAttr
     233             :   {
     234             :     nsAttrName mName;
     235             :     nsAttrValue mValue;
     236             :   };
     237             : 
     238             :   struct Impl {
     239             :     uint32_t mAttrAndChildCount;
     240             :     uint32_t mBufferSize;
     241             :     nsMappedAttributes* mMappedAttrs;
     242             :     void* mBuffer[1];
     243             :   };
     244             : 
     245             :   Impl* mImpl;
     246             : };
     247             : 
     248             : #endif

Generated by: LCOV version 1.13