Back to index

lightning-sunbird  0.9+nobinonly
nsInterfaceHashtable.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 C++ hashtable templates.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Benjamin Smedberg.
00019  * Portions created by the Initial Developer are Copyright (C) 2002
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef nsInterfaceHashtable_h__
00039 #define nsInterfaceHashtable_h__
00040 
00041 #include "nsBaseHashtable.h"
00042 #include "nsHashKeys.h"
00043 #include "nsCOMPtr.h"
00044 
00053 template<class KeyClass,class Interface>
00054 class nsInterfaceHashtable :
00055   public nsBaseHashtable< KeyClass, nsCOMPtr<Interface> , Interface* >
00056 {
00057 public:
00058   typedef typename KeyClass::KeyType KeyType;
00059   typedef Interface* UserDataType;
00060 
00066   PRBool Get(KeyType aKey, UserDataType* pData) const;
00067 
00074   Interface* GetWeak(KeyType aKey, PRBool* aFound = nsnull) const;
00075 };
00076 
00083 template<class KeyClass,class Interface>
00084 class nsInterfaceHashtableMT :
00085   public nsBaseHashtableMT< KeyClass, nsCOMPtr<Interface> , Interface* >
00086 {
00087 public:
00088   typedef typename KeyClass::KeyType KeyType;
00089   typedef Interface* UserDataType;
00090 
00096   PRBool Get(KeyType aKey, UserDataType* pData) const;
00097 
00098   // GetWeak does not make sense on a multi-threaded hashtable, where another
00099   // thread may remove the entry (and hence release it) as soon as GetWeak
00100   // returns
00101 };
00102 
00103 
00104 //
00105 // nsInterfaceHashtable definitions
00106 //
00107 
00108 template<class KeyClass,class Interface>
00109 PRBool
00110 nsInterfaceHashtable<KeyClass,Interface>::Get
00111   (KeyType aKey, UserDataType* pInterface) const
00112 {
00113   typename nsBaseHashtable<KeyClass, nsCOMPtr<Interface>, Interface*>::EntryType* ent =
00114     GetEntry(aKey);
00115 
00116   if (ent)
00117   {
00118     if (pInterface)
00119     {
00120       *pInterface = ent->mData;
00121 
00122       NS_IF_ADDREF(*pInterface);
00123     }
00124 
00125     return PR_TRUE;
00126   }
00127 
00128   // if the key doesn't exist, set *pInterface to null
00129   // so that it is a valid XPCOM getter
00130   if (pInterface)
00131     *pInterface = nsnull;
00132 
00133   return PR_FALSE;
00134 }
00135 
00136 template<class KeyClass,class Interface>
00137 Interface*
00138 nsInterfaceHashtable<KeyClass,Interface>::GetWeak
00139   (KeyType aKey, PRBool* aFound) const
00140 {
00141   typename nsBaseHashtable<KeyClass, nsCOMPtr<Interface>, Interface*>::EntryType* ent =
00142     GetEntry(aKey);
00143 
00144   if (ent)
00145   {
00146     if (aFound)
00147       *aFound = PR_TRUE;
00148 
00149     return ent->mData;
00150   }
00151 
00152   // Key does not exist, return nsnull and set aFound to PR_FALSE
00153   if (aFound)
00154     *aFound = PR_FALSE;
00155   return nsnull;
00156 }
00157 
00158 //
00159 // nsInterfaceHashtableMT definitions
00160 //
00161 
00162 template<class KeyClass,class Interface>
00163 PRBool
00164 nsInterfaceHashtableMT<KeyClass,Interface>::Get
00165   (KeyType aKey, UserDataType* pInterface) const
00166 {
00167   PR_Lock(this->mLock);
00168 
00169   typename nsBaseHashtableMT<KeyClass, nsCOMPtr<Interface>, Interface*>::EntryType* ent =
00170     GetEntry(aKey);
00171 
00172   if (ent)
00173   {
00174     if (pInterface)
00175     {
00176       *pInterface = ent->mData;
00177 
00178       NS_IF_ADDREF(*pInterface);
00179     }
00180 
00181     PR_Unlock(this->mLock);
00182 
00183     return PR_TRUE;
00184   }
00185 
00186   // if the key doesn't exist, set *pInterface to null
00187   // so that it is a valid XPCOM getter
00188   if (pInterface)
00189     *pInterface = nsnull;
00190 
00191   PR_Unlock(this->mLock);
00192 
00193   return PR_FALSE;
00194 }
00195 
00196 #endif // nsInterfaceHashtable_h__