Back to index

lightning-sunbird  0.9+nobinonly
nsAttrAndChildArray.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * IBM Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2003
00020  * IBM Corporation. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   IBM Corporation
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #ifndef nsAttrAndChildArray_h___
00040 #define nsAttrAndChildArray_h___
00041 
00042 #include "nscore.h"
00043 #include "nsAttrName.h"
00044 #include "nsAttrValue.h"
00045 
00046 class nsIContent;
00047 class nsMappedAttributes;
00048 class nsHTMLStyleSheet;
00049 class nsRuleWalker;
00050 class nsGenericHTMLElement;
00051 
00052 #define ATTRCHILD_ARRAY_GROWSIZE 8
00053 #define ATTRCHILD_ARRAY_LINEAR_THRESHOLD 32
00054 
00055 #define ATTRCHILD_ARRAY_ATTR_SLOTS_BITS 10
00056 
00057 #define ATTRCHILD_ARRAY_MAX_ATTR_COUNT \
00058     ((1 << ATTRCHILD_ARRAY_ATTR_SLOTS_BITS) - 1)
00059 
00060 #define ATTRCHILD_ARRAY_MAX_CHILD_COUNT \
00061     (~PtrBits(0) >> ATTRCHILD_ARRAY_ATTR_SLOTS_BITS)
00062 
00063 #define ATTRCHILD_ARRAY_ATTR_SLOTS_COUNT_MASK \
00064     ((1 << ATTRCHILD_ARRAY_ATTR_SLOTS_BITS) - 1)
00065 
00066 
00067 #define ATTRSIZE (sizeof(InternalAttr) / sizeof(void*))
00068 
00069 class nsAttrAndChildArray
00070 {
00071 public:
00072   nsAttrAndChildArray();
00073   ~nsAttrAndChildArray();
00074 
00075   PRUint32 ChildCount() const
00076   {
00077     return mImpl ? (mImpl->mAttrAndChildCount >> ATTRCHILD_ARRAY_ATTR_SLOTS_BITS) : 0;
00078   }
00079   nsIContent* ChildAt(PRUint32 aPos) const
00080   {
00081     NS_ASSERTION(aPos < ChildCount(), "out-of-bounds access in nsAttrAndChildArray");
00082     return NS_REINTERPRET_CAST(nsIContent*, mImpl->mBuffer[AttrSlotsSize() + aPos]);
00083   }
00084   nsIContent* GetSafeChildAt(PRUint32 aPos) const;
00085   nsresult AppendChild(nsIContent* aChild)
00086   {
00087     return InsertChildAt(aChild, ChildCount());
00088   }
00089   nsresult InsertChildAt(nsIContent* aChild, PRUint32 aPos);
00090   void RemoveChildAt(PRUint32 aPos);
00091   PRInt32 IndexOfChild(nsIContent* aPossibleChild) const;
00092 
00093   PRUint32 AttrCount() const;
00094   const nsAttrValue* GetAttr(nsIAtom* aLocalName, PRInt32 aNamespaceID = kNameSpaceID_None) const;
00095   const nsAttrValue* AttrAt(PRUint32 aPos) const;
00096   nsresult SetAttr(nsIAtom* aLocalName, const nsAString& aValue);
00097   nsresult SetAndTakeAttr(nsIAtom* aLocalName, nsAttrValue& aValue);
00098   nsresult SetAndTakeAttr(nsINodeInfo* aName, nsAttrValue& aValue);
00099 
00100   // Remove the attr at position aPos.  The value of the attr is placed in
00101   // aValue; any value that was already in aValue is destroyed.
00102   nsresult RemoveAttrAt(PRUint32 aPos, nsAttrValue& aValue);
00103   const nsAttrName* GetSafeAttrNameAt(PRUint32 aPos) const;
00104   // aName is UTF-8 encoded
00105   const nsAttrName* GetExistingAttrNameFromQName(const nsACString& aName) const;
00106   PRInt32 IndexOfAttr(nsIAtom* aLocalName, PRInt32 aNamespaceID = kNameSpaceID_None) const;
00107 
00108   nsresult SetAndTakeMappedAttr(nsIAtom* aLocalName, nsAttrValue& aValue,
00109                                 nsGenericHTMLElement* aContent,
00110                                 nsHTMLStyleSheet* aSheet);
00111   nsresult SetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet);
00112   void WalkMappedAttributeStyleRules(nsRuleWalker* aRuleWalker);
00113 
00114   void Compact();
00115 
00116 private:
00117   nsAttrAndChildArray(const nsAttrAndChildArray& aOther); // Not to be implemented
00118   nsAttrAndChildArray& operator=(const nsAttrAndChildArray& aOther); // Not to be implemented
00119 
00120   void Clear();
00121 
00122   PRUint32 NonMappedAttrCount() const;
00123   PRUint32 MappedAttrCount() const;
00124 
00125   nsresult GetModifiableMapped(nsGenericHTMLElement* aContent,
00126                                nsHTMLStyleSheet* aSheet,
00127                                PRBool aWillAddAttr,
00128                                nsMappedAttributes** aModifiable);
00129   nsresult MakeMappedUnique(nsMappedAttributes* aAttributes);
00130 
00131   PRUint32 AttrSlotsSize() const
00132   {
00133     return AttrSlotCount() * ATTRSIZE;
00134   }
00135 
00136   PRUint32 AttrSlotCount() const
00137   {
00138     return mImpl ? mImpl->mAttrAndChildCount & ATTRCHILD_ARRAY_ATTR_SLOTS_COUNT_MASK : 0;
00139   }
00140 
00141   void SetChildCount(PRUint32 aCount)
00142   {
00143     mImpl->mAttrAndChildCount = 
00144         (mImpl->mAttrAndChildCount & ATTRCHILD_ARRAY_ATTR_SLOTS_COUNT_MASK) |
00145         (aCount << ATTRCHILD_ARRAY_ATTR_SLOTS_BITS);
00146   }
00147 
00148   void SetAttrSlotCount(PRUint32 aCount)
00149   {
00150     mImpl->mAttrAndChildCount =
00151         (mImpl->mAttrAndChildCount & ~ATTRCHILD_ARRAY_ATTR_SLOTS_COUNT_MASK) |
00152         aCount;
00153   }
00154 
00155   void SetAttrSlotAndChildCount(PRUint32 aSlotCount, PRUint32 aChildCount)
00156   {
00157     mImpl->mAttrAndChildCount = aSlotCount |
00158       (aChildCount << ATTRCHILD_ARRAY_ATTR_SLOTS_BITS);
00159   }
00160 
00161   PRBool GrowBy(PRUint32 aGrowSize);
00162   PRBool AddAttrSlot();
00163 
00164   struct InternalAttr
00165   {
00166     nsAttrName mName;
00167     nsAttrValue mValue;
00168   };
00169 
00170   struct Impl {
00171     PRUint32 mAttrAndChildCount;
00172     PRUint32 mBufferSize;
00173     nsMappedAttributes* mMappedAttrs;
00174     void* mBuffer[1];
00175   };
00176 
00177   Impl* mImpl;
00178 };
00179 
00180 #endif