libraries/ltkutils/inc/stringhash.h
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // stringhash.h
       
     2 // 
       
     3 // Copyright (c) 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 #ifndef FSHELL_STRINGHASH_H
       
    13 #define FSHELL_STRINGHASH_H
       
    14 
       
    15 #include <e32hashtab.h>
       
    16 
       
    17 namespace LtkUtils
       
    18 	{
       
    19 	template <typename T> class TStringHashIter;
       
    20 	template <typename T> struct SHashVal { HBufC* iKey; T iValue; };
       
    21 	
       
    22 	template <typename T>
       
    23 	class RStringHash
       
    24 		{
       
    25 	public: // RHashMap-style
       
    26 		inline RStringHash();
       
    27 		inline T* Find(const TDesC& aKey);
       
    28 		inline T FindPtr(const TDesC& aKey); // Only use if T is a pointer
       
    29 		inline T& FindL(const TDesC& aKey);
       
    30 		inline T const* Find(const TDesC& aKey) const;
       
    31 		inline T const FindPtr(const TDesC& aKey) const; // Only use if T is a pointer
       
    32 		inline T const& FindL(const TDesC& aKey) const;
       
    33 		inline TInt Insert(const TDesC& aKey, const T& aValue);
       
    34 		inline void InsertL(const TDesC& aKey, const T& aValue);
       
    35 		inline TInt Remove(const TDesC& aKey);
       
    36 
       
    37 		inline TInt Count() const;
       
    38 		inline TInt Reserve(TInt aCount);
       
    39 		inline void ReserveL(TInt aCount);
       
    40 		inline void Close();
       
    41 
       
    42 	protected:
       
    43 		inline SHashVal<T>* DoFind(const TDesC& aKey);
       
    44 		inline SHashVal<T> const* DoFind(const TDesC& aKey) const;
       
    45 		friend class TStringHashIter<T>;
       
    46 
       
    47 		RHashMap<TDesC*, SHashVal<T> > iHash;
       
    48 		TAny* iSpare;
       
    49 		TAny* iSpare2;
       
    50 		};
       
    51 
       
    52 	template <typename T>
       
    53 	class TStringHashIter
       
    54 		{
       
    55 	public:
       
    56 		inline TStringHashIter(const RStringHash<T>& aHash);
       
    57 		inline const TDesC* CurrentKey() const;
       
    58 		inline const TDesC* NextKey();
       
    59 		inline T* CurrentValue();
       
    60 		inline const T* NextValue();
       
    61 		inline void RemoveCurrent();
       
    62 
       
    63 	private:
       
    64 		THashMapIter<TDesC*, SHashVal<T> > iIter;
       
    65 		};
       
    66 
       
    67 	inline TUint32 HashFn(TDesC* const& aKey);
       
    68 	inline TBool IdFn(TDesC* const& aFirst, TDesC* const& aSecond);
       
    69 	}
       
    70 
       
    71 
       
    72 // Nothing to see here, move along move along
       
    73 
       
    74 template <typename T>
       
    75 LtkUtils::RStringHash<T>::RStringHash()
       
    76 	: iHash(THashFunction32<TDesC*>(&HashFn), TIdentityRelation<TDesC*>(&IdFn)), iSpare(NULL), iSpare2(NULL)
       
    77 	{
       
    78 	}
       
    79 
       
    80 inline TUint32 LtkUtils::HashFn(TDesC* const& aKey)
       
    81 	{
       
    82 	return DefaultHash::Des16(*aKey);
       
    83 	}
       
    84 
       
    85 inline TBool LtkUtils::IdFn(TDesC* const& aFirst, TDesC* const& aSecond)
       
    86 	{
       
    87 	return DefaultIdentity::Des16(*aFirst, *aSecond);
       
    88 	}
       
    89 
       
    90 template <typename T>
       
    91 inline T* LtkUtils::RStringHash<T>::Find(const TDesC& aKey)
       
    92 	{
       
    93 	SHashVal<T>* res = DoFind(aKey);
       
    94 	if (res) return &res->iValue;
       
    95 	else return NULL;
       
    96 	}
       
    97 
       
    98 
       
    99 template <typename T>
       
   100 inline T LtkUtils::RStringHash<T>::FindPtr(const TDesC& aKey)
       
   101 	{
       
   102 	T* res = Find(aKey);
       
   103 	if (res) return *res;
       
   104 	else return NULL;
       
   105 	}
       
   106 
       
   107 
       
   108 template <typename T>
       
   109 inline T const* LtkUtils::RStringHash<T>::Find(const TDesC& aKey) const
       
   110 	{
       
   111 	SHashVal<T> const* res = DoFind(aKey);
       
   112 	if (res) return &res->iValue;
       
   113 	else return NULL;
       
   114 	}
       
   115 
       
   116 template <typename T>
       
   117 inline T const LtkUtils::RStringHash<T>::FindPtr(const TDesC& aKey) const
       
   118 	{
       
   119 	T const* res = Find(aKey);
       
   120 	if (res) return *res;
       
   121 	else return NULL;
       
   122 	}
       
   123 
       
   124 template <typename T>
       
   125 inline T& LtkUtils::RStringHash<T>::FindL(const TDesC& aKey)
       
   126 	{
       
   127 	T* res = Find(aKey);
       
   128 	if (!res) User::Leave(KErrNotFound);
       
   129 	return *res;
       
   130 	}
       
   131 
       
   132 template <typename T>
       
   133 inline T const& LtkUtils::RStringHash<T>::FindL(const TDesC& aKey) const
       
   134 	{
       
   135 	T const* res = Find(aKey);
       
   136 	if (!res) User::Leave(KErrNotFound);
       
   137 	return *res;
       
   138 	}
       
   139 
       
   140 template <typename T>
       
   141 TInt LtkUtils::RStringHash<T>::Insert(const TDesC& aKey, const T& aValue)
       
   142 	{
       
   143 	SHashVal<T>* valPtr = DoFind(aKey);
       
   144 	if (valPtr)
       
   145 		{
       
   146 		// Just update the value, no need to realloc anything
       
   147 		memcpy(&valPtr->iValue, &aValue, sizeof(T));
       
   148 		return KErrNone;
       
   149 		}
       
   150 
       
   151 	HBufC* buf = aKey.Alloc();
       
   152 	if (!buf) return KErrNoMemory;
       
   153 	// Avoid declaring an SHashVal<T> as that requires T to have a default constructor
       
   154 	TUint8 valBuf[sizeof(SHashVal<T>)];
       
   155 	SHashVal<T>& val = *reinterpret_cast<SHashVal<T>*>(valBuf);
       
   156 	val.iKey = buf;
       
   157 	memcpy(&val.iValue, &aValue, sizeof(T));
       
   158 	TInt err = iHash.Insert(buf, val);
       
   159 	if (err)
       
   160 		{
       
   161 		delete buf;
       
   162 		}
       
   163 	return err;
       
   164 	}
       
   165 
       
   166 template <typename T>
       
   167 inline TInt LtkUtils::RStringHash<T>::Remove(const TDesC& aKey)
       
   168 	{
       
   169 	SHashVal<T>* valPtr = DoFind(aKey);
       
   170 	if (valPtr)
       
   171 		{
       
   172 		HBufC* key = valPtr->iKey;
       
   173 		iHash.Remove(key);
       
   174 		delete key;
       
   175 		return KErrNone;
       
   176 		}
       
   177 	else
       
   178 		{
       
   179 		return KErrNotFound;
       
   180 		}
       
   181 	}
       
   182 
       
   183 template <typename T>
       
   184 inline void LtkUtils::RStringHash<T>::Close()
       
   185 	{
       
   186 	THashMapIter<TDesC*, SHashVal<T> > iter(iHash);
       
   187 	while (iter.NextValue() != NULL)
       
   188 		{
       
   189 		SHashVal<T>* current = const_cast<SHashVal<T>*>(iter.CurrentValue()); // const_cast not needed except on 9.1
       
   190 		HBufC* key = current->iKey;
       
   191 		iter.RemoveCurrent();
       
   192 		delete key;
       
   193 		}
       
   194 	iHash.Close();
       
   195 	}
       
   196 
       
   197 template <typename T>
       
   198 inline void LtkUtils::RStringHash<T>::InsertL(const TDesC& aKey, const T& aValue)
       
   199 	{
       
   200 	User::LeaveIfError(Insert(aKey, aValue));
       
   201 	}
       
   202 
       
   203 template <typename T>
       
   204 inline TInt LtkUtils::RStringHash<T>::Count() const
       
   205 	{
       
   206 	return iHash.Count();
       
   207 	}
       
   208 
       
   209 template <typename T>
       
   210 inline TInt LtkUtils::RStringHash<T>::Reserve(TInt aCount)
       
   211 	{
       
   212 	return iHash.Reserve(aCount);
       
   213 	}
       
   214 
       
   215 template <typename T>
       
   216 inline void LtkUtils::RStringHash<T>::ReserveL(TInt aCount)
       
   217 	{
       
   218 	User::LeaveIfError(Reserve(aCount));
       
   219 	}
       
   220 
       
   221 template <typename T>
       
   222 inline LtkUtils::SHashVal<T>* LtkUtils::RStringHash<T>::DoFind(const TDesC& aKey)
       
   223 	{
       
   224 	return iHash.Find(const_cast<TDesC*>(&aKey));
       
   225 	}
       
   226 
       
   227 template <typename T>
       
   228 inline LtkUtils::SHashVal<T> const* LtkUtils::RStringHash<T>::DoFind(const TDesC& aKey) const
       
   229 	{
       
   230 	return iHash.Find(const_cast<TDesC*>(&aKey));
       
   231 	}
       
   232 
       
   233 /// Iterator support
       
   234 
       
   235 template <typename T>
       
   236 inline const TDesC* LtkUtils::TStringHashIter<T>::CurrentKey() const
       
   237 	{
       
   238 	return *const_cast<TDesC**>(iIter.CurrentKey());
       
   239 	}
       
   240 
       
   241 template <typename T>
       
   242 inline const TDesC* LtkUtils::TStringHashIter<T>::NextKey()
       
   243 	{
       
   244 	return *const_cast<TDesC**>(iIter.NextKey());
       
   245 	}
       
   246 
       
   247 template <typename T>
       
   248 inline T* LtkUtils::TStringHashIter<T>::CurrentValue()
       
   249 	{
       
   250 	SHashVal<T>* val = const_cast<SHashVal<T>*>(iIter.CurrentValue()); // The const_cast isn't needed, except on 9.1
       
   251 	if (val) return &val->iValue;
       
   252 	return NULL;
       
   253 	}
       
   254 
       
   255 template <typename T>
       
   256 inline const T* LtkUtils::TStringHashIter<T>::NextValue()
       
   257 	{
       
   258 	const SHashVal<T>* val = iIter.NextValue();
       
   259 	if (val) return &val->iValue;
       
   260 	return NULL;
       
   261 	}
       
   262 
       
   263 template <typename T>
       
   264 inline void LtkUtils::TStringHashIter<T>::RemoveCurrent()
       
   265 	{
       
   266 	SHashVal<T>* val = iIter.CurrentValue();
       
   267 	if (val)
       
   268 		{
       
   269 		HBufC* key = val->iKey;
       
   270 		iIter.RemoveCurrent();
       
   271 		delete key;
       
   272 		}
       
   273 	}
       
   274 
       
   275 template <typename T>
       
   276 inline LtkUtils::TStringHashIter<T>::TStringHashIter(const RStringHash<T>& aHash)
       
   277 	: iIter(aHash.iHash)
       
   278 	{}
       
   279 
       
   280 #endif