--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libraries/ltkutils/inc/stringhash.h Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,280 @@
+// stringhash.h
+//
+// Copyright (c) 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+#ifndef FSHELL_STRINGHASH_H
+#define FSHELL_STRINGHASH_H
+
+#include <e32hashtab.h>
+
+namespace LtkUtils
+ {
+ template <typename T> class TStringHashIter;
+ template <typename T> struct SHashVal { HBufC* iKey; T iValue; };
+
+ template <typename T>
+ class RStringHash
+ {
+ public: // RHashMap-style
+ inline RStringHash();
+ inline T* Find(const TDesC& aKey);
+ inline T FindPtr(const TDesC& aKey); // Only use if T is a pointer
+ inline T& FindL(const TDesC& aKey);
+ inline T const* Find(const TDesC& aKey) const;
+ inline T const FindPtr(const TDesC& aKey) const; // Only use if T is a pointer
+ inline T const& FindL(const TDesC& aKey) const;
+ inline TInt Insert(const TDesC& aKey, const T& aValue);
+ inline void InsertL(const TDesC& aKey, const T& aValue);
+ inline TInt Remove(const TDesC& aKey);
+
+ inline TInt Count() const;
+ inline TInt Reserve(TInt aCount);
+ inline void ReserveL(TInt aCount);
+ inline void Close();
+
+ protected:
+ inline SHashVal<T>* DoFind(const TDesC& aKey);
+ inline SHashVal<T> const* DoFind(const TDesC& aKey) const;
+ friend class TStringHashIter<T>;
+
+ RHashMap<TDesC*, SHashVal<T> > iHash;
+ TAny* iSpare;
+ TAny* iSpare2;
+ };
+
+ template <typename T>
+ class TStringHashIter
+ {
+ public:
+ inline TStringHashIter(const RStringHash<T>& aHash);
+ inline const TDesC* CurrentKey() const;
+ inline const TDesC* NextKey();
+ inline T* CurrentValue();
+ inline const T* NextValue();
+ inline void RemoveCurrent();
+
+ private:
+ THashMapIter<TDesC*, SHashVal<T> > iIter;
+ };
+
+ inline TUint32 HashFn(TDesC* const& aKey);
+ inline TBool IdFn(TDesC* const& aFirst, TDesC* const& aSecond);
+ }
+
+
+// Nothing to see here, move along move along
+
+template <typename T>
+LtkUtils::RStringHash<T>::RStringHash()
+ : iHash(THashFunction32<TDesC*>(&HashFn), TIdentityRelation<TDesC*>(&IdFn)), iSpare(NULL), iSpare2(NULL)
+ {
+ }
+
+inline TUint32 LtkUtils::HashFn(TDesC* const& aKey)
+ {
+ return DefaultHash::Des16(*aKey);
+ }
+
+inline TBool LtkUtils::IdFn(TDesC* const& aFirst, TDesC* const& aSecond)
+ {
+ return DefaultIdentity::Des16(*aFirst, *aSecond);
+ }
+
+template <typename T>
+inline T* LtkUtils::RStringHash<T>::Find(const TDesC& aKey)
+ {
+ SHashVal<T>* res = DoFind(aKey);
+ if (res) return &res->iValue;
+ else return NULL;
+ }
+
+
+template <typename T>
+inline T LtkUtils::RStringHash<T>::FindPtr(const TDesC& aKey)
+ {
+ T* res = Find(aKey);
+ if (res) return *res;
+ else return NULL;
+ }
+
+
+template <typename T>
+inline T const* LtkUtils::RStringHash<T>::Find(const TDesC& aKey) const
+ {
+ SHashVal<T> const* res = DoFind(aKey);
+ if (res) return &res->iValue;
+ else return NULL;
+ }
+
+template <typename T>
+inline T const LtkUtils::RStringHash<T>::FindPtr(const TDesC& aKey) const
+ {
+ T const* res = Find(aKey);
+ if (res) return *res;
+ else return NULL;
+ }
+
+template <typename T>
+inline T& LtkUtils::RStringHash<T>::FindL(const TDesC& aKey)
+ {
+ T* res = Find(aKey);
+ if (!res) User::Leave(KErrNotFound);
+ return *res;
+ }
+
+template <typename T>
+inline T const& LtkUtils::RStringHash<T>::FindL(const TDesC& aKey) const
+ {
+ T const* res = Find(aKey);
+ if (!res) User::Leave(KErrNotFound);
+ return *res;
+ }
+
+template <typename T>
+TInt LtkUtils::RStringHash<T>::Insert(const TDesC& aKey, const T& aValue)
+ {
+ SHashVal<T>* valPtr = DoFind(aKey);
+ if (valPtr)
+ {
+ // Just update the value, no need to realloc anything
+ memcpy(&valPtr->iValue, &aValue, sizeof(T));
+ return KErrNone;
+ }
+
+ HBufC* buf = aKey.Alloc();
+ if (!buf) return KErrNoMemory;
+ // Avoid declaring an SHashVal<T> as that requires T to have a default constructor
+ TUint8 valBuf[sizeof(SHashVal<T>)];
+ SHashVal<T>& val = *reinterpret_cast<SHashVal<T>*>(valBuf);
+ val.iKey = buf;
+ memcpy(&val.iValue, &aValue, sizeof(T));
+ TInt err = iHash.Insert(buf, val);
+ if (err)
+ {
+ delete buf;
+ }
+ return err;
+ }
+
+template <typename T>
+inline TInt LtkUtils::RStringHash<T>::Remove(const TDesC& aKey)
+ {
+ SHashVal<T>* valPtr = DoFind(aKey);
+ if (valPtr)
+ {
+ HBufC* key = valPtr->iKey;
+ iHash.Remove(key);
+ delete key;
+ return KErrNone;
+ }
+ else
+ {
+ return KErrNotFound;
+ }
+ }
+
+template <typename T>
+inline void LtkUtils::RStringHash<T>::Close()
+ {
+ THashMapIter<TDesC*, SHashVal<T> > iter(iHash);
+ while (iter.NextValue() != NULL)
+ {
+ SHashVal<T>* current = const_cast<SHashVal<T>*>(iter.CurrentValue()); // const_cast not needed except on 9.1
+ HBufC* key = current->iKey;
+ iter.RemoveCurrent();
+ delete key;
+ }
+ iHash.Close();
+ }
+
+template <typename T>
+inline void LtkUtils::RStringHash<T>::InsertL(const TDesC& aKey, const T& aValue)
+ {
+ User::LeaveIfError(Insert(aKey, aValue));
+ }
+
+template <typename T>
+inline TInt LtkUtils::RStringHash<T>::Count() const
+ {
+ return iHash.Count();
+ }
+
+template <typename T>
+inline TInt LtkUtils::RStringHash<T>::Reserve(TInt aCount)
+ {
+ return iHash.Reserve(aCount);
+ }
+
+template <typename T>
+inline void LtkUtils::RStringHash<T>::ReserveL(TInt aCount)
+ {
+ User::LeaveIfError(Reserve(aCount));
+ }
+
+template <typename T>
+inline LtkUtils::SHashVal<T>* LtkUtils::RStringHash<T>::DoFind(const TDesC& aKey)
+ {
+ return iHash.Find(const_cast<TDesC*>(&aKey));
+ }
+
+template <typename T>
+inline LtkUtils::SHashVal<T> const* LtkUtils::RStringHash<T>::DoFind(const TDesC& aKey) const
+ {
+ return iHash.Find(const_cast<TDesC*>(&aKey));
+ }
+
+/// Iterator support
+
+template <typename T>
+inline const TDesC* LtkUtils::TStringHashIter<T>::CurrentKey() const
+ {
+ return *const_cast<TDesC**>(iIter.CurrentKey());
+ }
+
+template <typename T>
+inline const TDesC* LtkUtils::TStringHashIter<T>::NextKey()
+ {
+ return *const_cast<TDesC**>(iIter.NextKey());
+ }
+
+template <typename T>
+inline T* LtkUtils::TStringHashIter<T>::CurrentValue()
+ {
+ SHashVal<T>* val = const_cast<SHashVal<T>*>(iIter.CurrentValue()); // The const_cast isn't needed, except on 9.1
+ if (val) return &val->iValue;
+ return NULL;
+ }
+
+template <typename T>
+inline const T* LtkUtils::TStringHashIter<T>::NextValue()
+ {
+ const SHashVal<T>* val = iIter.NextValue();
+ if (val) return &val->iValue;
+ return NULL;
+ }
+
+template <typename T>
+inline void LtkUtils::TStringHashIter<T>::RemoveCurrent()
+ {
+ SHashVal<T>* val = iIter.CurrentValue();
+ if (val)
+ {
+ HBufC* key = val->iKey;
+ iIter.RemoveCurrent();
+ delete key;
+ }
+ }
+
+template <typename T>
+inline LtkUtils::TStringHashIter<T>::TStringHashIter(const RStringHash<T>& aHash)
+ : iIter(aHash.iHash)
+ {}
+
+#endif