Back to index

lightning-sunbird  0.9+nobinonly
nsTemplateMatchSet.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Chris Waterson <waterson@netscape.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or 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 nsTemplateMatchSet_h__
00040 #define nsTemplateMatchSet_h__
00041 
00042 #include "nsRuleNetwork.h"
00043 #include "nsFixedSizeAllocator.h"
00044 #include "nsTemplateMatch.h"
00045 #include "pldhash.h"
00046 
00047 class nsTemplateMatchSet {
00048 public:
00049     class ConstIterator;
00050     friend class ConstIterator; // so it can see Element
00051 
00052 protected:
00053     class Element {
00054     public:
00055         Element(nsTemplateMatch* aMatch)
00056             : mMatch(aMatch), mNext(nsnull) {}
00057 
00058         nsTemplateMatch* mMatch;
00059         Element*         mNext;
00060     };
00061 
00062     nsFixedSizeAllocator& mPool;
00063     Element* mHead;
00064 
00065 public:
00066     nsTemplateMatchSet(nsFixedSizeAllocator& aPool)
00067         : mPool(aPool), mHead(nsnull) { MOZ_COUNT_CTOR(nsTemplateMatchSet); }
00068 
00069     ~nsTemplateMatchSet();
00070 
00071     class ConstIterator {
00072     protected:
00073         friend class nsTemplateMatchSet;
00074 
00075         Element* mCurrent;
00076         
00077         ConstIterator(Element* aElement)
00078             : mCurrent(aElement) {}
00079 
00080     public:
00081         ConstIterator() : mCurrent(nsnull) {}
00082 
00083         ConstIterator(const ConstIterator& aIterator)
00084             : mCurrent(aIterator.mCurrent) {}
00085 
00086         ConstIterator&
00087         operator=(const ConstIterator& aIterator) {
00088             mCurrent = aIterator.mCurrent;
00089             return *this; }
00090 
00091         ConstIterator&
00092         operator++() {
00093             mCurrent = mCurrent->mNext;
00094             return *this; };
00095 
00096         ConstIterator
00097         operator++(int) {
00098             ConstIterator tmp(*this);
00099             mCurrent = mCurrent->mNext;
00100             return tmp; }
00101 
00102         nsTemplateMatch& operator*() const {
00103             return *(mCurrent->mMatch); }
00104 
00105         nsTemplateMatch* operator->() const {
00106             return mCurrent->mMatch; }
00107 
00108         PRBool
00109         operator==(const ConstIterator& aIterator) const {
00110             return mCurrent == aIterator.mCurrent; }
00111 
00112         PRBool
00113         operator!=(const ConstIterator& aIterator) const {
00114             return !aIterator.operator==(*this); }
00115     };
00116 
00117     ConstIterator First() const { return ConstIterator(mHead); }
00118 
00119     ConstIterator Last() const { return ConstIterator(nsnull); }
00120 
00121     void
00122     Add(nsTemplateMatch* aMatch) {
00123         Element* element = new Element(aMatch);
00124         if (element) {
00125             aMatch->AddRef();
00126             element->mMatch = aMatch;
00127             element->mNext = mHead;
00128             mHead = element;
00129         } }
00130 };
00131 
00135 class nsTemplateMatchRefSet
00136 {
00137 public:
00138     class ConstIterator;
00139     friend class ConstIterator;
00140 
00141     nsTemplateMatchRefSet() {
00142         MOZ_COUNT_CTOR(nsTemplateMatchRefSet);
00143         Init(); }
00144 
00145     nsTemplateMatchRefSet(const nsTemplateMatchRefSet& aMatchSet) {
00146         MOZ_COUNT_CTOR(nsTemplateMatchRefSet);
00147         Init();
00148         CopyFrom(aMatchSet); }
00149 
00150     nsTemplateMatchRefSet&
00151     operator=(const nsTemplateMatchRefSet& aMatchSet) {
00152         Finish();
00153         Init();
00154         CopyFrom(aMatchSet);
00155         return *this; }
00156 
00157     ~nsTemplateMatchRefSet() {
00158         Finish();
00159         MOZ_COUNT_DTOR(nsTemplateMatchRefSet); }
00160 
00161 protected:
00166     void Init();
00167 
00172     void Finish();
00173 
00177     void CopyFrom(const nsTemplateMatchRefSet& aMatchSet);
00178 
00182     PRBool AddToTable(nsTemplateMatch* aMatch);
00183 
00190 public:
00191     struct Entry {
00192         friend class ConstIterator;
00193 
00194         PLDHashEntryHdr  mHdr;
00195         nsTemplateMatch* mMatch;
00196     };
00197 protected:
00198 
00199     enum { kMaxInlineMatches = (sizeof(PLDHashTable) / sizeof(void*)) - 1 };
00200 
00201     struct InlineMatches;
00202     friend struct InlineMatches;
00203     union _stor_elements;
00204     friend union _stor_elements;
00205 
00209     struct InlineMatches {
00210         PRUint32         mCount;
00211         nsTemplateMatch* mEntries[kMaxInlineMatches];
00212     };
00213 
00232     union _stor_elements {
00233         PLDHashTable  mTable;
00234         InlineMatches mInlineMatches;
00235     } mStorageElements;
00236 
00237     static PLDHashTableOps gOps;
00238 
00239     static PLDHashNumber PR_CALLBACK
00240     HashEntry(PLDHashTable* aTable, const void* aKey);
00241 
00242     static PRBool PR_CALLBACK
00243     MatchEntry(PLDHashTable* aTable, const PLDHashEntryHdr* aHdr, const void* aKey);
00244 
00245 public:
00250     class ConstIterator {
00251     protected:
00252         friend class nsTemplateMatchRefSet;
00253 
00254         void Next();
00255         void Prev();
00256 
00257         ConstIterator(const nsTemplateMatchRefSet* aSet, Entry* aTableEntry)
00258             : mSet(aSet), mTableEntry(aTableEntry) {}
00259 
00260         ConstIterator(const nsTemplateMatchRefSet* aSet, nsTemplateMatch** aInlineEntry)
00261             : mSet(aSet), mInlineEntry(aInlineEntry) {}
00262 
00263         const nsTemplateMatchRefSet* mSet;
00264         union {
00265             Entry*            mTableEntry;
00266             nsTemplateMatch** mInlineEntry;
00267         };
00268 
00269         nsTemplateMatch* get() const {
00270             return mSet->mStorageElements.mInlineMatches.mCount > PRUint32(kMaxInlineMatches)
00271                 ? mTableEntry->mMatch
00272                 : *mInlineEntry; }
00273 
00274     public:
00275         ConstIterator() : mSet(nsnull), mTableEntry(nsnull) {}
00276 
00277         ConstIterator(const ConstIterator& aConstIterator)
00278             : mSet(aConstIterator.mSet),
00279               mTableEntry(aConstIterator.mTableEntry) {}
00280 
00281         ConstIterator& operator=(const ConstIterator& aConstIterator) {
00282             mSet = aConstIterator.mSet;
00283             mTableEntry = aConstIterator.mTableEntry;
00284             return *this; }
00285 
00286         ConstIterator& operator++() {
00287             Next();
00288             return *this; }
00289 
00290         ConstIterator operator++(int) {
00291             ConstIterator result(*this);
00292             Next();
00293             return result; }
00294 
00295         ConstIterator& operator--() {
00296             Prev();
00297             return *this; }
00298 
00299         ConstIterator operator--(int) {
00300             ConstIterator result(*this);
00301             Prev();
00302             return result; }
00303 
00304         /*const*/ nsTemplateMatch& operator*() const {
00305             return *get(); }
00306 
00307         /*const*/ nsTemplateMatch* operator->() const {
00308             return get(); }
00309 
00310         PRBool operator==(const ConstIterator& aConstIterator) const;
00311 
00312         PRBool operator!=(const ConstIterator& aConstIterator) const {
00313             return ! aConstIterator.operator==(*this); }
00314     };
00315 
00320     ConstIterator First() const;
00321 
00326     ConstIterator Last() const;
00327 
00331     PRBool Empty() const;
00332 
00336     PRBool Contains(const nsTemplateMatch* aMatch) const;
00337 
00346     PRBool Add(const nsTemplateMatch* aMatch);
00347 
00353     PRBool Remove(const nsTemplateMatch* aMatch);
00354 };
00355 
00356 #endif // nsTemplateMatchSet_h__