Implemented RObjectIx-based memoryaccess APIs.
Upshot is that objinfo now works again on platforms that define FSHELL_NO_DOBJECTIX_SUPPORT.
// 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