/* HeapSearch Copyright (C) 2007 Oasis Feng http://www.oasisfeng.com/ This code snippet is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 2.0 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/en/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA. */ ////////////////////////////////////////////////////////////////////////// // HeapSearch.hpp // class THeapSearch : private THeapWalk { public : THeapSearch(RHeap& aHeap); TInt Search(CBase & aRefObject); inline CBase * FirstResult() { return iObjectFound; } // Override this function to deal with each object found. virtual void DealL(CBase * /*aObject*/) {} private: void Info(TCellType aType,TAny *aBase,TInt aLength); RHeap & iHeap; // The heap to search object in. CBase * iObjectFound; // Object found (NULL if not found) CBase * iRefObject; // Reference object TInt iCellLengthExpected; // Expected length of cell TInt iCellHeaderLength; // Length of cell header in current build TInt iTypeId; // Address of virtual function table }; inline TInt _typeid(CBase & aObject) { return (* reinterpret_cast(& aObject)); } ////////////////////////////////////////////////////////////////////////// // HeapSearch.cpp // class RHeapExt : public RHeap { public: inline SCell* GetAddress(TAny* aCell) { return RHeap::GetAddress(aCell); } private: RHeapExt(); }; THeapSearch::THeapSearch(RHeap& aHeap) : THeapWalk(aHeap), iHeap(aHeap), iObjectFound(NULL), iRefObject(NULL), iCellLengthExpected(0), iCellHeaderLength(KErrNotFound), iTypeId(0) { } TInt THeapSearch::Search(CBase & aRefObject) { iObjectFound = NULL; iRefObject = & aRefObject; if (KErrNotFound == iCellHeaderLength) { RHeap::SCell * cell = static_cast(iHeap).GetAddress(&aRefObject); if (NULL == cell) // Reference object is not in the same heap. cell = static_cast(User::Heap()).GetAddress(&aRefObject); if (NULL == cell) // Not in the user heap either. return KErrArgument; iCellHeaderLength = (TUint8 *) (& aRefObject) - (TUint8 *) cell; } iTypeId = _typeid(aRefObject); iCellLengthExpected = ((RHeap::SCell *) ((TUint8 *) &aRefObject - iCellHeaderLength))->len; return Walk(); } void THeapSearch::Info(TCellType aType,TAny *aBase,TInt aLength) { CBase * object; if (NULL == aBase || NULL == iRefObject) return; switch(aType) { case EGoodAllocatedCell: if (aLength == iCellLengthExpected) { object = reinterpret_cast((TUint8 *)aBase + iCellHeaderLength); if (object != iRefObject && _typeid(*object) == iTypeId) { if (NULL == iObjectFound) // Only store the object found first. { iObjectFound = object; } SetValue(Value() + 1); DealL(object); } } break; default: break; } }