LCOV - code coverage report
Current view: directory - layout/style - nsCSSDataBlock.h (source / functions) Found Hit Coverage
Test: app.info Lines: 39 6 15.4 %
Date: 2012-06-02 Functions: 17 2 11.8 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is nsCSSDataBlock.h.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is L. David Baron.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2003
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *   L. David Baron <dbaron@dbaron.org> (original author)
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      26                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : /*
      39                 :  * compact representation of the property-value pairs within a CSS
      40                 :  * declaration, and the code for expanding and compacting it
      41                 :  */
      42                 : 
      43                 : #ifndef nsCSSDataBlock_h__
      44                 : #define nsCSSDataBlock_h__
      45                 : 
      46                 : #include "nsCSSProps.h"
      47                 : #include "nsCSSPropertySet.h"
      48                 : 
      49                 : struct nsRuleData;
      50                 : class nsCSSExpandedDataBlock;
      51                 : 
      52                 : namespace mozilla {
      53                 : namespace css {
      54                 : class Declaration;
      55                 : }
      56                 : }
      57                 : 
      58                 : /*
      59                 :  * nsCSSCompressedDataBlock holds property-value pairs corresponding
      60                 :  * to CSS declaration blocks.  Each pair is stored in a CDBValueStorage
      61                 :  * object; these objects form an array at the end of the data block.
      62                 :  */
      63                 : struct CDBValueStorage {
      64                 :     nsCSSProperty property;
      65                 :     nsCSSValue value;
      66                 : };
      67                 : 
      68                 : /**
      69                 :  * An |nsCSSCompressedDataBlock| holds a usually-immutable chunk of
      70                 :  * property-value data for a CSS declaration block (which we misname a
      71                 :  * |css::Declaration|).  Mutation is accomplished through
      72                 :  * |nsCSSExpandedDataBlock| or in some cases via direct slot access.
      73                 :  */
      74                 : class nsCSSCompressedDataBlock {
      75                 : private:
      76                 :     friend class nsCSSExpandedDataBlock;
      77                 : 
      78                 :     // Only this class (via |CreateEmptyBlock|) or nsCSSExpandedDataBlock
      79                 :     // (in |Compress|) can create compressed data blocks.
      80               0 :     nsCSSCompressedDataBlock() : mStyleBits(0) {}
      81                 : 
      82                 : public:
      83                 :     ~nsCSSCompressedDataBlock();
      84                 : 
      85                 :     /**
      86                 :      * Do what |nsIStyleRule::MapRuleInfoInto| needs to do for a style
      87                 :      * rule using this block for storage.
      88                 :      */
      89                 :     void MapRuleInfoInto(nsRuleData *aRuleData) const;
      90                 : 
      91                 :     /**
      92                 :      * Return the location at which the *value* for the property is
      93                 :      * stored, or null if the block does not contain a value for the
      94                 :      * property.
      95                 :      *
      96                 :      * Inefficient (by design).
      97                 :      *
      98                 :      * Must not be called for shorthands.
      99                 :      */
     100                 :     const nsCSSValue* ValueFor(nsCSSProperty aProperty) const;
     101                 : 
     102                 :     /**
     103                 :      * Attempt to replace the value for |aProperty| stored in this block
     104                 :      * with the matching value stored in |aFromBlock|.
     105                 :      * This method will fail (returning false) if |aProperty| is not
     106                 :      * already in this block.  It will set |aChanged| to true if it
     107                 :      * actually made a change to the block, but regardless, if it
     108                 :      * returns true, the value in |aFromBlock| was erased.
     109                 :      */
     110                 :     bool TryReplaceValue(nsCSSProperty aProperty,
     111                 :                            nsCSSExpandedDataBlock& aFromBlock,
     112                 :                            bool* aChanged);
     113                 : 
     114                 :     /**
     115                 :      * Clone this block, or return null on out-of-memory.
     116                 :      */
     117                 :     nsCSSCompressedDataBlock* Clone() const;
     118                 : 
     119                 :     /**
     120                 :      * Create a new nsCSSCompressedDataBlock holding no declarations.
     121                 :      */
     122                 :     static nsCSSCompressedDataBlock* CreateEmptyBlock();
     123                 : 
     124                 :     size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
     125                 : 
     126                 : private:
     127               0 :     void* operator new(size_t aBaseSize, size_t aDataSize) {
     128               0 :         NS_ABORT_IF_FALSE(aBaseSize == sizeof(nsCSSCompressedDataBlock),
     129                 :                           "unexpected size for nsCSSCompressedDataBlock");
     130               0 :         return ::operator new(aBaseSize + aDataSize);
     131                 :     }
     132                 : 
     133                 :     /**
     134                 :      * Delete all the data stored in this block, and the block itself.
     135                 :      */
     136                 :     void Destroy();
     137                 : 
     138                 :     PRInt32 mStyleBits; // the structs for which we have data, according to
     139                 :                         // |nsCachedStyleData::GetBitForSID|.
     140                 :     PRUint32 mDataSize;
     141                 :     // CDBValueStorage elements are stored after these fields.  Space for them
     142                 :     // is allocated in |operator new| above.  The static assertions following
     143                 :     // this class make sure that the CDBValueStorage elements are aligned
     144                 :     // appropriately.
     145                 :     
     146               0 :     char* Block() { return (char*)this + sizeof(*this); }
     147               0 :     char* BlockEnd() { return Block() + mDataSize; }
     148               0 :     const char* Block() const { return (char*)this + sizeof(*this); }
     149               0 :     const char* BlockEnd() const { return Block() + mDataSize; }
     150               0 :     void SetBlockEnd(char *blockEnd) { 
     151                 :         /*
     152                 :          * Note:  if we ever change nsCSSDeclaration to store the declarations
     153                 :          * in order and also store repeated declarations of the same property,
     154                 :          * then we need to worry about checking for integer overflow here.
     155                 :          */
     156               0 :         NS_ABORT_IF_FALSE(size_t(blockEnd - Block()) <= size_t(PR_UINT32_MAX),
     157                 :                           "overflow of mDataSize");
     158               0 :         mDataSize = PRUint32(blockEnd - Block());
     159               0 :     }
     160               0 :     ptrdiff_t DataSize() const { return mDataSize; }
     161                 : };
     162                 : 
     163                 : /* Make sure the CDBValueStorage elements are aligned appropriately. */
     164                 : MOZ_STATIC_ASSERT(sizeof(nsCSSCompressedDataBlock) == 8,
     165                 :                   "nsCSSCompressedDataBlock's size has changed");
     166                 : MOZ_STATIC_ASSERT(NS_ALIGNMENT_OF(CDBValueStorage) <= 8,
     167                 :                   "CDBValueStorage needs too much alignment");
     168                 : 
     169                 : class nsCSSExpandedDataBlock {
     170                 :     friend class nsCSSCompressedDataBlock;
     171                 : 
     172                 : public:
     173                 :     nsCSSExpandedDataBlock();
     174                 :     ~nsCSSExpandedDataBlock();
     175                 : 
     176                 : private:
     177                 :     /* Property storage may not be accessed directly; use AddLonghandProperty
     178                 :      * and friends.
     179                 :      */
     180                 :     nsCSSValue mValues[eCSSProperty_COUNT_no_shorthands];
     181                 : 
     182                 : public:
     183                 :     /**
     184                 :      * Transfer all of the state from a pair of compressed data blocks
     185                 :      * to this expanded block.  This expanded block must be clear
     186                 :      * beforehand.
     187                 :      *
     188                 :      * This method DELETES both of the compressed data blocks it is
     189                 :      * passed.  (This is necessary because ownership of sub-objects
     190                 :      * is transferred to the expanded block.)
     191                 :      */
     192                 :     void Expand(nsCSSCompressedDataBlock *aNormalBlock,
     193                 :                 nsCSSCompressedDataBlock *aImportantBlock);
     194                 : 
     195                 :     /**
     196                 :      * Allocate new compressed blocks and transfer all of the state
     197                 :      * from this expanded block to the new blocks, clearing this
     198                 :      * expanded block.  A normal block will always be allocated, but
     199                 :      * an important block will only be allocated if there are
     200                 :      * !important properties in the expanded block; otherwise
     201                 :      * |*aImportantBlock| will be set to null.
     202                 :      */
     203                 :     void Compress(nsCSSCompressedDataBlock **aNormalBlock,
     204                 :                   nsCSSCompressedDataBlock **aImportantBlock);
     205                 : 
     206                 :     /**
     207                 :      * Copy a value into this expanded block.  This does NOT destroy
     208                 :      * the source value object.  |aProperty| cannot be a shorthand.
     209                 :      */
     210                 :     void AddLonghandProperty(nsCSSProperty aProperty, const nsCSSValue& aValue);
     211                 : 
     212                 :     /**
     213                 :      * Clear the state of this expanded block.
     214                 :      */
     215                 :     void Clear();
     216                 : 
     217                 :     /**
     218                 :      * Clear the data for the given property (including the set and
     219                 :      * important bits).  Can be used with shorthand properties.
     220                 :      */
     221                 :     void ClearProperty(nsCSSProperty aPropID);
     222                 : 
     223                 :     /**
     224                 :      * Same as ClearProperty, but faster and cannot be used with shorthands.
     225                 :      */
     226                 :     void ClearLonghandProperty(nsCSSProperty aPropID);
     227                 : 
     228                 :     /**
     229                 :      * Transfer the state for |aPropID| (which may be a shorthand)
     230                 :      * from |aFromBlock| to this block.  The property being transferred
     231                 :      * is !important if |aIsImportant| is true, and should replace an
     232                 :      * existing !important property regardless of its own importance
     233                 :      * if |aOverrideImportant| is true.
     234                 :      *
     235                 :      * Returns true if something changed, false otherwise.  Calls
     236                 :      * |ValueAppended| on |aDeclaration| if the property was not
     237                 :      * previously set, or in any case if |aMustCallValueAppended| is true.
     238                 :      */
     239                 :     bool TransferFromBlock(nsCSSExpandedDataBlock& aFromBlock,
     240                 :                              nsCSSProperty aPropID,
     241                 :                              bool aIsImportant,
     242                 :                              bool aOverrideImportant,
     243                 :                              bool aMustCallValueAppended,
     244                 :                              mozilla::css::Declaration* aDeclaration);
     245                 : 
     246              72 :     void AssertInitialState() {
     247                 : #ifdef DEBUG
     248              72 :         DoAssertInitialState();
     249                 : #endif
     250              72 :     }
     251                 : 
     252                 : private:
     253                 :     /**
     254                 :      * Compute the size that will be occupied by the result of
     255                 :      * |Compress|.
     256                 :      */
     257                 :     struct ComputeSizeResult {
     258                 :         PRUint32 normal, important;
     259                 :     };
     260                 :     ComputeSizeResult ComputeSize();
     261                 : 
     262                 :     void DoExpand(nsCSSCompressedDataBlock *aBlock, bool aImportant);
     263                 : 
     264                 :     /**
     265                 :      * Worker for TransferFromBlock; cannot be used with shorthands.
     266                 :      */
     267                 :     bool DoTransferFromBlock(nsCSSExpandedDataBlock& aFromBlock,
     268                 :                                nsCSSProperty aPropID,
     269                 :                                bool aIsImportant,
     270                 :                                bool aOverrideImportant,
     271                 :                                bool aMustCallValueAppended,
     272                 :                                mozilla::css::Declaration* aDeclaration);
     273                 : 
     274                 : #ifdef DEBUG
     275                 :     void DoAssertInitialState();
     276                 : #endif
     277                 : 
     278                 :     /*
     279                 :      * mPropertiesSet stores a bit for every property that is present,
     280                 :      * to optimize compression of blocks with small numbers of
     281                 :      * properties (the norm) and to allow quickly checking whether a
     282                 :      * property is set in this block.
     283                 :      */
     284                 :     nsCSSPropertySet mPropertiesSet;
     285                 :     /*
     286                 :      * mPropertiesImportant indicates which properties are '!important'.
     287                 :      */
     288                 :     nsCSSPropertySet mPropertiesImportant;
     289                 : 
     290                 :     /*
     291                 :      * Return the storage location within |this| of the value of the
     292                 :      * property |aProperty|.
     293                 :      */
     294           16848 :     nsCSSValue* PropertyAt(nsCSSProperty aProperty) {
     295           16848 :         NS_ABORT_IF_FALSE(0 <= aProperty &&
     296                 :                           aProperty < eCSSProperty_COUNT_no_shorthands,
     297                 :                           "property out of range");
     298           16848 :         return &mValues[aProperty];
     299                 :     }
     300                 : 
     301               0 :     void SetPropertyBit(nsCSSProperty aProperty) {
     302               0 :         mPropertiesSet.AddProperty(aProperty);
     303               0 :     }
     304                 : 
     305               0 :     void ClearPropertyBit(nsCSSProperty aProperty) {
     306               0 :         mPropertiesSet.RemoveProperty(aProperty);
     307               0 :     }
     308                 : 
     309               0 :     bool HasPropertyBit(nsCSSProperty aProperty) {
     310               0 :         return mPropertiesSet.HasProperty(aProperty);
     311                 :     }
     312                 : 
     313               0 :     void SetImportantBit(nsCSSProperty aProperty) {
     314               0 :         mPropertiesImportant.AddProperty(aProperty);
     315               0 :     }
     316                 : 
     317               0 :     void ClearImportantBit(nsCSSProperty aProperty) {
     318               0 :         mPropertiesImportant.RemoveProperty(aProperty);
     319               0 :     }
     320                 : 
     321               0 :     bool HasImportantBit(nsCSSProperty aProperty) {
     322               0 :         return mPropertiesImportant.HasProperty(aProperty);
     323                 :     }
     324                 : 
     325               0 :     void ClearSets() {
     326               0 :         mPropertiesSet.Empty();
     327               0 :         mPropertiesImportant.Empty();
     328               0 :     }
     329                 : };
     330                 : 
     331                 : #endif /* !defined(nsCSSDataBlock_h__) */

Generated by: LCOV version 1.7