memspy/Engine/Source/Helpers/MemSpyEngineHelperChunk.cpp
changeset 0 a03f92240627
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/Engine/Source/Helpers/MemSpyEngineHelperChunk.cpp	Tue Feb 02 01:57:15 2010 +0200
@@ -0,0 +1,812 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <memspy/engine/memspyenginehelperchunk.h>
+
+// Driver includes
+#include <memspy/driver/memspydriverclient.h>
+
+// User includes
+#include <memspy/engine/memspyengine.h>
+#include <memspy/engine/memspyengineutils.h>
+#include <memspy/engine/memspyengineoutputsink.h>
+#include <memspy/engine/memspyengineoutputlist.h>
+#include <memspy/engine/memspyengineobjectthread.h>
+#include <memspy/engine/memspyengineobjectprocess.h>
+
+// Constants
+const TInt KMemSpyEngineMaxChunkCount = 768;
+
+// Literal constants
+_LIT( KMemSpyEngineChunkListOutputComma, ", " );
+
+
+
+CMemSpyEngineHelperChunk::CMemSpyEngineHelperChunk( CMemSpyEngine& aEngine )
+:   iEngine( aEngine )
+    {
+    }
+
+    
+CMemSpyEngineHelperChunk::~CMemSpyEngineHelperChunk()
+    {
+    }
+
+
+void CMemSpyEngineHelperChunk::ConstructL()
+    {
+    }
+
+
+CMemSpyEngineHelperChunk* CMemSpyEngineHelperChunk::NewL( CMemSpyEngine& aEngine )
+    {
+    CMemSpyEngineHelperChunk* self = new(ELeave) CMemSpyEngineHelperChunk( aEngine );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+EXPORT_C void CMemSpyEngineHelperChunk::OutputChunkInfoForThreadL( const CMemSpyThread& aThread )
+    {
+    OutputChunkInfoForThreadL( aThread.Id() );
+    }
+
+
+EXPORT_C void CMemSpyEngineHelperChunk::OutputChunkInfoForThreadL( TThreadId aTid )
+    {
+    TBuf<512> lineBuffer;
+    OutputChunkInfoForThreadL( aTid, lineBuffer );
+    }
+
+
+EXPORT_C void CMemSpyEngineHelperChunk::OutputChunkInfoForThreadL( TThreadId aTid, TDes& aLineBuffer )
+    {
+    DoOutputChunkInfoForObjectL( aTid, aLineBuffer, EThread );
+    }
+
+
+EXPORT_C void CMemSpyEngineHelperChunk::OutputChunkInfoForProcessL( const CMemSpyProcess& aProcess )
+    {
+    OutputChunkInfoForProcessL( aProcess.Id() );
+    }
+
+
+EXPORT_C void CMemSpyEngineHelperChunk::OutputChunkInfoForProcessL( TProcessId aPid )
+    {
+    TBuf<512> lineBuffer;
+    OutputChunkInfoForProcessL( aPid, lineBuffer );
+    }
+
+
+EXPORT_C void CMemSpyEngineHelperChunk::OutputChunkInfoForProcessL( TProcessId aPid, TDes& aLineBuffer )
+    {
+    DoOutputChunkInfoForObjectL( aPid, aLineBuffer, EProcess );
+    }
+
+
+EXPORT_C CMemSpyEngineChunkList* CMemSpyEngineHelperChunk::ListL()
+    {
+    RArray<TAny*> handles( 128 );
+    CleanupClosePushL( handles );
+    //
+    GetChunkHandlesL( handles, EAll );
+    CMemSpyEngineChunkList* list = CreateListFromHandlesL( handles );
+    //
+    CleanupStack::PopAndDestroy( &handles );
+    return list;
+    }
+
+
+EXPORT_C CMemSpyEngineChunkList* CMemSpyEngineHelperChunk::ListForThreadL( TThreadId aTid )
+    {
+    RArray<TAny*> handles( 128 );
+    CleanupClosePushL( handles );
+    //
+    GetChunkHandlesL( handles, EThread, aTid );
+    CMemSpyEngineChunkList* list = CreateListFromHandlesL( handles );
+    //
+    CleanupStack::PopAndDestroy( &handles );
+    return list;
+    }
+
+
+EXPORT_C CMemSpyEngineChunkList* CMemSpyEngineHelperChunk::ListForProcessL( TProcessId aPid )
+    {
+    RArray<TAny*> handles( 128 );
+    CleanupClosePushL( handles );
+    //
+    GetChunkHandlesL( handles, EProcess, aPid );
+    CMemSpyEngineChunkList* list = CreateListFromHandlesL( handles );
+    //
+    CleanupStack::PopAndDestroy( &handles );
+    return list;
+    }
+
+
+void CMemSpyEngineHelperChunk::DoOutputChunkInfoForObjectL( TUint aId, TDes& aLineBuffer, TType aType )
+    {
+    TFullName ownerName;
+	//
+    RArray<TAny*> handles( 128 );
+    CleanupClosePushL( handles );
+    //
+    GetChunkHandlesL( handles, aType, aId );
+    CMemSpyEngineChunkList* list = CreateListFromHandlesL( handles );
+    //
+    CleanupStack::PopAndDestroy( &handles );
+    CleanupStack::PushL( list );
+    //
+    const TInt count = list->Count();
+    for (TInt i=0; i<count; i++)
+    	{
+        const CMemSpyEngineChunkEntry& entry = list->At( i );
+        //
+        _LIT(KLine1, "Name");
+        iEngine.Sink().OutputItemAndValueL( KLine1, entry.Name() );
+        //
+        _LIT(KLine2, "Owner");
+        entry.OwnerName( ownerName );
+        iEngine.Sink().OutputItemAndValueL( KLine2, ownerName );
+        //
+        _LIT(KLine3, "Address");
+        _LIT(KLine3Format, "0x%08x - 0x%08x");
+        aLineBuffer.Format(KLine3Format, entry.BaseAddress(), entry.UpperAddress() );
+        iEngine.Sink().OutputItemAndValueL( KLine3, aLineBuffer );
+        //
+        _LIT(KLine4, "Size (max)");
+        _LIT(KLine4Format, "%d (%d)");
+        aLineBuffer.Format(KLine4Format, entry.Size(), entry.MaxSize());
+        iEngine.Sink().OutputItemAndValueL( KLine4, aLineBuffer );
+        //
+        if  ( i < count - 1 )
+            {
+            iEngine.Sink().OutputBlankLineL();
+    		}
+        }
+    //
+    CleanupStack::PopAndDestroy( list );
+    }
+
+
+void CMemSpyEngineHelperChunk::GetChunkHandlesL( RArray<TAny*>& aHandles, TType aType, TUint aId )
+    {
+	TAny* handles[ KMemSpyEngineMaxChunkCount ];
+	TInt count = KMemSpyEngineMaxChunkCount;
+
+    TInt r = 0;
+    //
+    switch( aType )
+        {
+    case EThread:
+        r = iEngine.Driver().GetChunkHandlesForThread( aId, handles, count );
+        break;
+    case EProcess:
+        r = iEngine.Driver().GetChunkHandlesForProcess( aId, handles, count );
+        break;
+    default:
+    case EAll:
+        r = iEngine.Driver().GetChunkHandles( handles, count );
+        break;
+        }
+    //
+    if  ( r == KErrNone )
+    	{
+        count = Min( count, KMemSpyEngineMaxChunkCount );
+        for( TInt index = 0; index < count; index++ )
+            {
+            TAny* handle = handles[ index ];
+
+            if  ( aHandles.Find( handle ) == KErrNotFound )
+                {
+                aHandles.AppendL( handle );
+                }
+            }
+        }
+    }
+
+
+CMemSpyEngineChunkList* CMemSpyEngineHelperChunk::CreateListFromHandlesL( const RArray<TAny*>& aHandles )
+    {
+    CMemSpyEngineChunkList* list = CMemSpyEngineChunkList::NewLC( iEngine );
+    //
+    TMemSpyDriverChunkInfo info;
+    const TInt count = aHandles.Count();
+    //
+    for( TInt i=0; i<count; i++ )
+        {
+        TAny* handle = aHandles[ i ];
+        //
+    	const TInt error = iEngine.Driver().GetChunkInfo( handle, info );
+        if  ( error == KErrNone )
+            {
+            CMemSpyEngineChunkEntry* entry = CMemSpyEngineChunkEntry::NewLC( iEngine, info );
+            list->AddItemL( entry );
+            CleanupStack::Pop( entry );
+            }
+        }
+    //
+    list->SortBySizeL();
+    //
+    CleanupStack::Pop( list );
+    return list;
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+CMemSpyEngineChunkList::CMemSpyEngineChunkList( CMemSpyEngine& aEngine )
+:   iEngine( aEngine )
+    {
+    }
+
+
+EXPORT_C CMemSpyEngineChunkList::~CMemSpyEngineChunkList()
+    {
+    iItems.ResetAndDestroy();
+    iItems.Close();
+    }
+
+
+void CMemSpyEngineChunkList::ConstructL()
+    {
+    }
+
+
+CMemSpyEngineChunkList* CMemSpyEngineChunkList::NewLC( CMemSpyEngine& aEngine )
+    {
+    CMemSpyEngineChunkList* self = new(ELeave) CMemSpyEngineChunkList( aEngine );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+
+EXPORT_C TInt CMemSpyEngineChunkList::Count() const
+    {
+    return iItems.Count();
+    }
+
+
+EXPORT_C CMemSpyEngineChunkEntry& CMemSpyEngineChunkList::At( TInt aIndex )
+    {
+    return *iItems[ aIndex ];
+    }
+
+
+EXPORT_C const CMemSpyEngineChunkEntry& CMemSpyEngineChunkList::At( TInt aIndex ) const
+    {
+    return *iItems[ aIndex ];
+    }
+
+
+EXPORT_C void CMemSpyEngineChunkList::SortByNameL()
+    {
+    TLinearOrder< CMemSpyEngineChunkEntry > comparer( CompareByName );
+    iItems.Sort( comparer );
+    }
+
+
+EXPORT_C void CMemSpyEngineChunkList::SortBySizeL()
+    {
+    TLinearOrder< CMemSpyEngineChunkEntry > comparer( CompareBySize );
+    iItems.Sort( comparer );
+    }
+
+
+EXPORT_C TInt CMemSpyEngineChunkList::ItemIndex( const CMemSpyEngineChunkEntry& aEntry ) const
+    {
+    TInt ret = KErrNotFound;
+    //
+    const TInt count = Count();
+    for( TInt i=0; i<count; i++ )
+        {
+        const CMemSpyEngineChunkEntry* item = iItems[ i ];
+        //
+        if  ( item == &aEntry )
+            {
+            ret = i;
+            break;
+            }
+        }
+    //
+    return ret;
+    }
+
+
+EXPORT_C void CMemSpyEngineChunkList::OutputDataColumnsL( CMemSpyEngine& aEngine )
+    {
+    HBufC* columns = HBufC::NewLC( 1024 );
+    TPtr pColumns( columns->Des() );
+
+    //
+    _LIT(KCol1, "Name");
+    pColumns.Append( KCol1 );
+    pColumns.Append( KMemSpyEngineChunkListOutputComma );
+
+    //
+    _LIT(KCol2, "Owning Process");
+    pColumns.Append( KCol2 );
+    pColumns.Append( KMemSpyEngineChunkListOutputComma );
+
+    //
+    _LIT(KCol3, "Size");
+    pColumns.Append( KCol3 );
+    pColumns.Append( KMemSpyEngineChunkListOutputComma );
+
+    //
+    _LIT(KCol4, "Max. Size");
+    pColumns.Append( KCol4 );
+    pColumns.Append( KMemSpyEngineChunkListOutputComma );
+
+    //
+    _LIT(KCol5, "Address");
+    pColumns.Append( KCol5 );
+
+    //
+    aEngine.Sink().OutputLineL( pColumns );
+    CleanupStack::PopAndDestroy( columns );
+    }
+
+
+EXPORT_C TBool CMemSpyEngineChunkList::EntryExists( TAny* aHandle ) const
+    {
+    TBool ret = EFalse;
+    //
+    const TInt count = Count();
+    for( TInt i=0; i<count && !ret; i++ )
+        {
+        const CMemSpyEngineChunkEntry* item = iItems[ i ];
+        ret = ( item->Handle() == aHandle );
+        }
+    //
+    return ret;
+    }
+
+
+void CMemSpyEngineChunkList::AddItemL( CMemSpyEngineChunkEntry* aItem )
+    {
+    iItems.AppendL( aItem );
+    }
+
+
+void CMemSpyEngineChunkList::Remove( TInt aIndex )
+    {
+    CMemSpyEngineChunkEntry* item = iItems[ aIndex ];
+    delete item;
+    iItems.Remove( aIndex );
+    }
+
+
+void CMemSpyEngineChunkList::RemoveByHandle( TAny* aChunkHandle )
+    {
+    const TInt index = ItemIndexByChunkHandle( aChunkHandle );
+    if  ( index >= 0 )
+        {
+        Remove( index );
+        }
+    }
+
+
+TInt CMemSpyEngineChunkList::ItemIndexByProcessId( TUint aPid ) const
+    {
+    const TInt ret = ItemIndexByProcessId( aPid, 0 );
+    return ret;
+    }
+
+
+TInt CMemSpyEngineChunkList::ItemIndexByProcessId( TUint aPid, TInt aStartIndex ) const
+    {
+    TInt ret = KErrNotFound;
+    //
+    const TInt count = Count();
+    for( TInt i=aStartIndex; i<count; i++ )
+        {
+        const CMemSpyEngineChunkEntry* item = iItems[ i ];
+        //
+        if  ( item->OwnerId() == aPid )
+            {
+            ret = i;
+            break;
+            }
+        }
+    //
+    return ret;
+    }
+
+
+TInt CMemSpyEngineChunkList::ItemIndexByProcessId( TUint aPid, TMemSpyDriverChunkType aType ) const
+    {
+    TInt ret = KErrNotFound;
+    //
+    const TInt count = Count();
+    for( TInt i=0; i<count; i++ )
+        {
+        const CMemSpyEngineChunkEntry* item = iItems[ i ];
+        //
+        if  ( item->OwnerId() == aPid && item->Info().iType == aType )
+            {
+            ret = i;
+            break;
+            }
+        }
+    //
+    return ret;
+    }
+
+
+TInt CMemSpyEngineChunkList::ItemIndexByChunkHandle( TAny* aHandle ) const
+    {
+    TInt ret = KErrNotFound;
+    //
+    const TInt count = Count();
+    for( TInt i=0; i<count; i++ )
+        {
+        const CMemSpyEngineChunkEntry* item = iItems[ i ];
+        //
+        if  ( item->Handle() == aHandle )
+            {
+            ret = i;
+            break;
+            }
+        }
+    //
+    return ret;
+    }
+
+
+EXPORT_C TInt CMemSpyEngineChunkList::MdcaCount() const
+    {
+    return Count();
+    }
+
+
+EXPORT_C TPtrC CMemSpyEngineChunkList::MdcaPoint( TInt aIndex ) const
+    {
+    const CMemSpyEngineChunkEntry& item = At( aIndex );
+    return TPtrC( item.Caption() );
+    }
+
+
+TInt CMemSpyEngineChunkList::CompareByName( const CMemSpyEngineChunkEntry& aLeft, const CMemSpyEngineChunkEntry& aRight )
+    {
+    const TInt ret = aLeft.Name().CompareF( aRight.Name() );
+    return ret;
+    }
+
+
+TInt CMemSpyEngineChunkList::CompareBySize( const CMemSpyEngineChunkEntry& aLeft, const CMemSpyEngineChunkEntry& aRight )
+    {
+    TInt ret = -1;
+    //
+    if  ( aLeft.Size() < aRight.Size() )
+        {
+        ret = 1;
+        }
+    else if ( aLeft.Size() == aRight.Size() )
+        {
+        ret = 0;
+        }
+    //
+    return ret;
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+CMemSpyEngineChunkEntry::CMemSpyEngineChunkEntry( CMemSpyEngine& aEngine )
+:   iEngine( aEngine )
+    {
+    }
+
+
+CMemSpyEngineChunkEntry::~CMemSpyEngineChunkEntry()
+    {
+    delete iCaption;
+    delete iInfo;
+    delete iList;
+    }
+
+
+void CMemSpyEngineChunkEntry::ConstructL( const TMemSpyDriverChunkInfo& aInfo )
+    {
+    // Copy info
+    iInfo = new(ELeave) TMemSpyDriverChunkInfo();
+    *iInfo = aInfo;
+
+    // Make caption
+    TBuf<KMaxFullName+128> item;
+    _LIT(KCaptionFormat, "\t%S\t\t%d");
+    item.Format( KCaptionFormat, &Name(), Size() );
+    iCaption = item.AllocL();
+
+    // Make other items
+    iList = CMemSpyEngineOutputList::NewL();
+
+    _LIT( KEntry0, "Name");
+    iList->AddItemL( KEntry0, Name() );
+
+    _LIT( KEntryType, "Type" );
+    switch( aInfo.iType )
+        {
+    default:
+    case EMemSpyDriverChunkTypeUnknown:
+        iList->AddItemL( KEntryType, _L("Unknown") );
+        break;
+    case EMemSpyDriverChunkTypeHeap:
+        iList->AddItemL( KEntryType, _L("Heap") );
+        break;
+    case EMemSpyDriverChunkTypeHeapKernel:
+        iList->AddItemL( KEntryType, _L("Kernel Heap") );
+        break;
+    case EMemSpyDriverChunkTypeStackAndProcessGlobalData:
+        iList->AddItemL( KEntryType, _L("Stack and Process Global Data") );
+        break;
+    case EMemSpyDriverChunkTypeStackKernel:
+        iList->AddItemL( KEntryType, _L("Kernel Stack") );
+        break;
+    case EMemSpyDriverChunkTypeGlobalData:
+        iList->AddItemL( KEntryType, _L("Global Data") );
+        break;
+    case EMemSpyDriverChunkTypeCode:
+        iList->AddItemL( KEntryType, _L("Code") );
+        break;
+    case EMemSpyDriverChunkTypeCodeGlobal:
+        iList->AddItemL( KEntryType, _L("Global Code") );
+        break;
+    case EMemSpyDriverChunkTypeCodeSelfModifiable:
+        iList->AddItemL( KEntryType, _L("Self Modifiable Code") );
+        break;
+    case EMemSpyDriverChunkTypeLocal:
+        iList->AddItemL( KEntryType, _L("Local") );
+        break;
+    case EMemSpyDriverChunkTypeGlobal:
+        iList->AddItemL( KEntryType, _L("Global") );
+        break;
+    case EMemSpyDriverChunkTypeRamDrive:
+        iList->AddItemL( KEntryType, _L("RAM Drive") );
+        break;
+        }
+
+    _LIT( KEntry1, "Owning Process");
+    OwnerName( item );
+    iList->AddItemL( KEntry1, item );
+
+    _LIT( KEntry2, "Address" );
+    _LIT( KEntry2Format, "0x%08x - 0x%08x" );
+    item.Format( KEntry2Format, BaseAddress(), UpperAddress() );
+    iList->AddItemL( KEntry2, item );
+
+    _LIT( KEntry3, "Size");
+    iList->AddItemL( KEntry3, Size() );
+
+    _LIT( KEntry4, "Max. Size");
+    iList->AddItemL( KEntry4, MaxSize() );
+
+    _LIT( KEntryAttributeFormat, "Attribute %d");
+    TInt attribNum = 0;
+    //
+    if  ( aInfo.iAttributes & ENormal )
+        {
+        item.Format( KEntryAttributeFormat, ++attribNum );
+        iList->AddItemL( item, _L("Normal") );
+        }
+    if  ( aInfo.iAttributes & EDoubleEnded )
+        {
+        item.Format( KEntryAttributeFormat, ++attribNum );
+        iList->AddItemL( item, _L("Double Ended") );
+        }
+    if  ( aInfo.iAttributes & EDisconnected )
+        {
+        item.Format( KEntryAttributeFormat, ++attribNum );
+        iList->AddItemL( item, _L("Disconnected") );
+        }
+    if  ( aInfo.iAttributes & EConstructed )
+        {
+        item.Format( KEntryAttributeFormat, ++attribNum );
+        iList->AddItemL( item, _L("Constructed") );
+        }
+    if  ( aInfo.iAttributes & EMemoryNotOwned )
+        {
+        item.Format( KEntryAttributeFormat, ++attribNum );
+        iList->AddItemL( item, _L("Memory Not Owned") );
+        }
+    }
+
+
+CMemSpyEngineChunkEntry* CMemSpyEngineChunkEntry::NewLC( CMemSpyEngine& aEngine, const TMemSpyDriverChunkInfo& aInfo )
+    {
+    CMemSpyEngineChunkEntry* self = new(ELeave) CMemSpyEngineChunkEntry( aEngine );
+    CleanupStack::PushL( self );
+    self->ConstructL( aInfo );
+    return self;
+    }
+
+
+const TDesC& CMemSpyEngineChunkEntry::Name() const
+    {
+    return iInfo->iName;
+    }
+
+
+TAny* CMemSpyEngineChunkEntry::Handle() const 
+    {
+    return iInfo->iHandle;
+    }
+
+
+TInt CMemSpyEngineChunkEntry::Size() const
+    {
+    return iInfo->iSize;
+    }
+
+
+TInt CMemSpyEngineChunkEntry::MaxSize() const
+    {
+    return iInfo->iMaxSize;
+    }
+
+
+TAny* CMemSpyEngineChunkEntry::BaseAddress() const
+    { 
+    return iInfo->iBaseAddress;
+    }
+
+
+TAny* CMemSpyEngineChunkEntry::UpperAddress() const
+    {
+    return (TAny*) (TUint(BaseAddress()) + TUint(Size()));
+    }
+
+
+TUint CMemSpyEngineChunkEntry::OwnerId() const
+    {
+    return iInfo->iOwnerId;
+    }
+
+
+EXPORT_C void CMemSpyEngineChunkEntry::OwnerName( TDes& aDes ) const
+    {
+    aDes.Zero();
+    AppendOwnerName( aDes );
+    }
+
+
+EXPORT_C void CMemSpyEngineChunkEntry::AppendOwnerName( TDes& aDes ) const
+    {
+    RProcess owner;
+    const TInt error = owner.Open( (TProcessId) OwnerId() );
+    if  ( error == KErrNone )
+        {
+        aDes.Append( owner.FullName() );
+        owner.Close();
+        }
+    }
+
+
+EXPORT_C void CMemSpyEngineChunkEntry::OutputDataL( CMemSpyEngineHelperChunk& aHelper ) const
+    {
+    HBufC* columns = HBufC::NewLC( 1024 );
+    TPtr pColumns( columns->Des() );
+
+    // Name
+    pColumns.Copy( Name() );
+    MemSpyEngineUtils::TextAfterDoubleColon( pColumns );
+    pColumns.Append( KMemSpyEngineChunkListOutputComma );
+
+    // Owning Process
+    AppendOwnerName( pColumns );
+    pColumns.Append( KMemSpyEngineChunkListOutputComma );
+
+    // Size
+    pColumns.AppendNum( Size(), EDecimal ); 
+    pColumns.Append( KMemSpyEngineChunkListOutputComma );
+
+    // Max. Size
+    pColumns.AppendNum( MaxSize(), EDecimal ); 
+    pColumns.Append( KMemSpyEngineChunkListOutputComma );
+
+    // Address
+    _LIT( KAddressFormat, "0x%08x - 0x%08x");
+    pColumns.AppendFormat( KAddressFormat, BaseAddress(), UpperAddress() );
+
+    //
+    aHelper.Engine().Sink().OutputLineL( pColumns );
+    CleanupStack::PopAndDestroy( columns );
+    }
+
+
+EXPORT_C TInt CMemSpyEngineChunkEntry::MdcaCount() const
+    {
+    return iList->MdcaCount();
+    }
+
+
+EXPORT_C TPtrC CMemSpyEngineChunkEntry::MdcaPoint( TInt aIndex ) const
+    {
+    return iList->MdcaPoint( aIndex );
+    }
+
+
+TMemSpyDriverChunkInfo& CMemSpyEngineChunkEntry::Info()
+    {
+    return *iInfo;
+    }
+
+
+const TMemSpyDriverChunkInfo& CMemSpyEngineChunkEntry::Info() const
+    {
+    return *iInfo;
+    }
+
+