diff -r 000000000000 -r 7f656887cf89 libraries/ltkutils/inc/stringhash.h --- /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 + +namespace LtkUtils + { + template class TStringHashIter; + template struct SHashVal { HBufC* iKey; T iValue; }; + + template + 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* DoFind(const TDesC& aKey); + inline SHashVal const* DoFind(const TDesC& aKey) const; + friend class TStringHashIter; + + RHashMap > iHash; + TAny* iSpare; + TAny* iSpare2; + }; + + template + class TStringHashIter + { + public: + inline TStringHashIter(const RStringHash& aHash); + inline const TDesC* CurrentKey() const; + inline const TDesC* NextKey(); + inline T* CurrentValue(); + inline const T* NextValue(); + inline void RemoveCurrent(); + + private: + THashMapIter > 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 +LtkUtils::RStringHash::RStringHash() + : iHash(THashFunction32(&HashFn), TIdentityRelation(&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 +inline T* LtkUtils::RStringHash::Find(const TDesC& aKey) + { + SHashVal* res = DoFind(aKey); + if (res) return &res->iValue; + else return NULL; + } + + +template +inline T LtkUtils::RStringHash::FindPtr(const TDesC& aKey) + { + T* res = Find(aKey); + if (res) return *res; + else return NULL; + } + + +template +inline T const* LtkUtils::RStringHash::Find(const TDesC& aKey) const + { + SHashVal const* res = DoFind(aKey); + if (res) return &res->iValue; + else return NULL; + } + +template +inline T const LtkUtils::RStringHash::FindPtr(const TDesC& aKey) const + { + T const* res = Find(aKey); + if (res) return *res; + else return NULL; + } + +template +inline T& LtkUtils::RStringHash::FindL(const TDesC& aKey) + { + T* res = Find(aKey); + if (!res) User::Leave(KErrNotFound); + return *res; + } + +template +inline T const& LtkUtils::RStringHash::FindL(const TDesC& aKey) const + { + T const* res = Find(aKey); + if (!res) User::Leave(KErrNotFound); + return *res; + } + +template +TInt LtkUtils::RStringHash::Insert(const TDesC& aKey, const T& aValue) + { + SHashVal* 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 as that requires T to have a default constructor + TUint8 valBuf[sizeof(SHashVal)]; + SHashVal& val = *reinterpret_cast*>(valBuf); + val.iKey = buf; + memcpy(&val.iValue, &aValue, sizeof(T)); + TInt err = iHash.Insert(buf, val); + if (err) + { + delete buf; + } + return err; + } + +template +inline TInt LtkUtils::RStringHash::Remove(const TDesC& aKey) + { + SHashVal* valPtr = DoFind(aKey); + if (valPtr) + { + HBufC* key = valPtr->iKey; + iHash.Remove(key); + delete key; + return KErrNone; + } + else + { + return KErrNotFound; + } + } + +template +inline void LtkUtils::RStringHash::Close() + { + THashMapIter > iter(iHash); + while (iter.NextValue() != NULL) + { + SHashVal* current = const_cast*>(iter.CurrentValue()); // const_cast not needed except on 9.1 + HBufC* key = current->iKey; + iter.RemoveCurrent(); + delete key; + } + iHash.Close(); + } + +template +inline void LtkUtils::RStringHash::InsertL(const TDesC& aKey, const T& aValue) + { + User::LeaveIfError(Insert(aKey, aValue)); + } + +template +inline TInt LtkUtils::RStringHash::Count() const + { + return iHash.Count(); + } + +template +inline TInt LtkUtils::RStringHash::Reserve(TInt aCount) + { + return iHash.Reserve(aCount); + } + +template +inline void LtkUtils::RStringHash::ReserveL(TInt aCount) + { + User::LeaveIfError(Reserve(aCount)); + } + +template +inline LtkUtils::SHashVal* LtkUtils::RStringHash::DoFind(const TDesC& aKey) + { + return iHash.Find(const_cast(&aKey)); + } + +template +inline LtkUtils::SHashVal const* LtkUtils::RStringHash::DoFind(const TDesC& aKey) const + { + return iHash.Find(const_cast(&aKey)); + } + +/// Iterator support + +template +inline const TDesC* LtkUtils::TStringHashIter::CurrentKey() const + { + return *const_cast(iIter.CurrentKey()); + } + +template +inline const TDesC* LtkUtils::TStringHashIter::NextKey() + { + return *const_cast(iIter.NextKey()); + } + +template +inline T* LtkUtils::TStringHashIter::CurrentValue() + { + SHashVal* val = const_cast*>(iIter.CurrentValue()); // The const_cast isn't needed, except on 9.1 + if (val) return &val->iValue; + return NULL; + } + +template +inline const T* LtkUtils::TStringHashIter::NextValue() + { + const SHashVal* val = iIter.NextValue(); + if (val) return &val->iValue; + return NULL; + } + +template +inline void LtkUtils::TStringHashIter::RemoveCurrent() + { + SHashVal* val = iIter.CurrentValue(); + if (val) + { + HBufC* key = val->iKey; + iIter.RemoveCurrent(); + delete key; + } + } + +template +inline LtkUtils::TStringHashIter::TStringHashIter(const RStringHash& aHash) + : iIter(aHash.iHash) + {} + +#endif