memspy/Engine/Source/Sink/MemSpyEngineOutputList.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 16:45:49 +0300
branchRCL_3
changeset 20 ca8a1b6995f6
parent 0 a03f92240627
child 21 52e343bb8f80
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
* 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/memspyengineoutputlist.h>

// System includes
#include <e32debug.h>

// User includes
#include <memspy/engine/memspyengineutils.h>
#include <memspy/engine/memspyengineoutputsink.h>
#include "MemSpyEngineOutputListItem.h"

// Constants
_LIT( KMemSpyOutputListPseudoBlankItem, " " );


CMemSpyEngineOutputList::CMemSpyEngineOutputList( CMemSpyEngineOutputSink* aSink )
:   iSink( aSink ), iFormatBufferPtr( NULL, 0 )
    {
    }


CMemSpyEngineOutputList::~CMemSpyEngineOutputList()
    {
    delete iFormatBuffer;
    iItems.ResetAndDestroy();
    iItems.Close();
    }


void CMemSpyEngineOutputList::ConstructL()
    {
    iFormatBuffer = HBufC::NewL( 1024 );
    iFormatBufferPtr.Set( iFormatBuffer->Des() );
    }


CMemSpyEngineOutputList* CMemSpyEngineOutputList::NewL()
    {
    CMemSpyEngineOutputList* self = new(ELeave) CMemSpyEngineOutputList();
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    return self;
    }


CMemSpyEngineOutputList* CMemSpyEngineOutputList::NewLC( CMemSpyEngineOutputSink& aSink )
    {
    CMemSpyEngineOutputList* self = new(ELeave) CMemSpyEngineOutputList( &aSink );
    CleanupStack::PushL( self );

    // No need to call ConstructL - it uses the sink's format buffer
    return self;
    }


TInt CMemSpyEngineOutputList::MdcaCount() const
    {
    return iItems.Count();
    }


TPtrC CMemSpyEngineOutputList::MdcaPoint( TInt aPos ) const
    {
    CMemSpyEngineOutputListItem* item = iItems[ aPos ];
    return TPtrC( item->Combined() );
    }


void CMemSpyEngineOutputList::PrintL()
    {
    ASSERT( iSink != NULL );
    PrintL( *iSink );
    }


void CMemSpyEngineOutputList::PrintL( CMemSpyEngineOutputSink& aSink )
    {
    const TInt count = iItems.Count();
    if  ( count > 0 )
        {
        // First pass to get max lengths
        TInt maxLengthCaption = 0;
        TInt maxLengthValue = 0;

        for( TInt j=0; j<count; j++ )
            {
            const CMemSpyEngineOutputListItem* item = iItems[ j ];
			if (item->Value().Length())
				{
	            maxLengthCaption = Max( maxLengthCaption, item->Caption().Length() );
	            maxLengthValue = Max( maxLengthValue, item->Value().Length() );
				}
			else
				{
				// If something doesn't have a value (ie it's a section header, represented as just a caption) then the caption
				// shouldn't be factored into the maxcaptionlength. But consider it in maxlengthValue to make sure we actually
				// make the overall buffers big enough
				maxLengthValue = Max( maxLengthValue, item->Caption().Length() );
				}
            }

        // Second pass - real this time - to print the values
        HBufC* line = HBufC::NewLC( ( maxLengthCaption + maxLengthValue ) + 20 );
        TPtr pLine( line->Des() );
        //
        for( TInt i=0; i<count; i++ )
            {
            const CMemSpyEngineOutputListItem* item = iItems[ i ];

            // Remove initial tabs in caption
            HBufC* caption = MemSpyEngineUtils::CleanupTextLC( item->Caption() );
        
            // Create value item & replace any further tabs
            HBufC* value = MemSpyEngineUtils::CleanupTextLC( item->Value() );

            // Now format the final line, with padding.
			if (value->Length()) 
				{
	            pLine.Justify( *caption, maxLengthCaption + 3, ELeft, TChar(' ') );
				}
			else
				{
				// items without value (ie just captions, ie section headers) aren't constrained by the maxLengthCaption restriction
				pLine.Copy(*caption);
				}
            pLine.Append( *value );
            CleanupStack::PopAndDestroy( 2, caption );

            // Sink output
            aSink.OutputLineL( pLine );
            }
        //
        CleanupStack::PopAndDestroy( line );
        }
    }


CMemSpyEngineOutputListItem& CMemSpyEngineOutputList::Item( TInt aPos )
    {
    CMemSpyEngineOutputListItem* ret = iItems[ aPos ];
    return *ret;
    }


const CMemSpyEngineOutputListItem& CMemSpyEngineOutputList::Item( TInt aPos ) const
    {
    const CMemSpyEngineOutputListItem* ret = iItems[ aPos ];
    return *ret;
    }


void CMemSpyEngineOutputList::AddItemL( const TDesC& aCaption )
    {
    AddItemL( aCaption, KNullDesC );
    }


void CMemSpyEngineOutputList::AddItemL( const TDesC& aCaption, const TDesC& aValue )
    {
    CMemSpyEngineOutputListItem* item = CMemSpyEngineOutputListItem::NewLC( aCaption, aValue );
    iItems.AppendL( item );
    CleanupStack::Pop( item );
    }


void CMemSpyEngineOutputList::AddItemL( const TDesC& aCaption, TInt aValue )
    {
    CMemSpyEngineOutputListItem* item = CMemSpyEngineOutputListItem::NewDecimalLC( aCaption, aValue );
    iItems.AppendL( item );
    CleanupStack::Pop( item );
    }


void CMemSpyEngineOutputList::AddItemL( const TDesC& aCaption, TUint aValue )
    {
    CMemSpyEngineOutputListItem* item = CMemSpyEngineOutputListItem::NewDecimalLC( aCaption, aValue );
    iItems.AppendL( item );
    CleanupStack::Pop( item );
    }


void CMemSpyEngineOutputList::AddItemL( const TDesC& aCaption, const TInt64& aValue )
    {
    CMemSpyEngineOutputListItem* item = CMemSpyEngineOutputListItem::NewLongLC( aCaption, aValue );
    iItems.AppendL( item );
    CleanupStack::Pop( item );
    }


void CMemSpyEngineOutputList::AddItemL( const TDesC& aCaption, TAny* aValue )
    {
    AddItemHexL( aCaption, (TUint) aValue );
    }


void CMemSpyEngineOutputList::AddItemL( const TDesC& aCaption, TUint* aValue )
    {
    AddItemHexL( aCaption, (TUint) aValue );
    }


void CMemSpyEngineOutputList::AddItemL( const TDesC& aCaption, TUint8* aValue )
    {
    AddItemHexL( aCaption, (TUint) aValue );
    }


void CMemSpyEngineOutputList::AddItemFormatL( TRefByValue<const TDesC> aFormat, ... )
    {
	VA_LIST list;
	VA_START(list,aFormat);

    TPtr formatBuffer( FormatBuffer() );
	formatBuffer.Zero();
    formatBuffer.FormatList( aFormat, list );
    //
    AddItemL( formatBuffer, KNullDesC );
    }


void CMemSpyEngineOutputList::AddItemFormatL( const TDesC& aCaption, TRefByValue<const TDesC> aValueFormat, ... )
    {
	VA_LIST list;
	VA_START(list,aValueFormat);

    TPtr formatBuffer( FormatBuffer() );
	formatBuffer.Zero();
    formatBuffer.FormatList( aValueFormat, list );
    //
    AddItemL( aCaption, formatBuffer );
    }


void CMemSpyEngineOutputList::AddItemFormatUCL( TRefByValue<const TDesC> aFormat, ... )
    {
	VA_LIST list;
	VA_START(list,aFormat);

    TPtr formatBuffer( FormatBuffer() );
	formatBuffer.Zero();
    formatBuffer.FormatList( aFormat, list );
    //
    AddItemUCL( formatBuffer, KNullDesC );
    }


void CMemSpyEngineOutputList::AddItemUCL( const TDesC& aCaption, const TDesC& aValue )
    {
    CMemSpyEngineOutputListItem* item = CMemSpyEngineOutputListItem::NewLC( aCaption, aValue );
    iItems.AppendL( item );
    CleanupStack::Pop( item );
    //
    item->iCaption->Des().UpperCase();
    item->UpdateCombinedL();
    }


void CMemSpyEngineOutputList::AddItemFormatUCL( const TDesC& aCaption, TRefByValue<const TDesC> aValueFormat, ... )
    {
	VA_LIST list;
	VA_START(list,aValueFormat);

    TPtr formatBuffer( FormatBuffer() );
	formatBuffer.Zero();
    formatBuffer.FormatList( aValueFormat, list );
    //
    AddItemUCL( aCaption, formatBuffer );
    }


void CMemSpyEngineOutputList::AddItemHexL( const TDesC& aCaption, TUint aValue )
    {
    CMemSpyEngineOutputListItem* item = CMemSpyEngineOutputListItem::NewHexLC( aCaption, aValue );
    iItems.AppendL( item );
    CleanupStack::Pop( item );
    }


void CMemSpyEngineOutputList::AddItemYesNoL( const TDesC& aCaption, TBool aYes )
    {
    CMemSpyEngineOutputListItem* item = CMemSpyEngineOutputListItem::NewYesNoLC( aCaption, aYes );
    iItems.AppendL( item );
    CleanupStack::Pop( item );
    }


void CMemSpyEngineOutputList::AddItemTrueFalseL( const TDesC& aCaption, TBool aTrue )
    {
    CMemSpyEngineOutputListItem* item = CMemSpyEngineOutputListItem::NewTrueFalseLC( aCaption, aTrue );
    iItems.AppendL( item );
    CleanupStack::Pop( item );
    }


void CMemSpyEngineOutputList::AddItemOnOffL( const TDesC& aCaption, TBool aOn )
    {
    CMemSpyEngineOutputListItem* item = CMemSpyEngineOutputListItem::NewOnOffLC( aCaption, aOn );
    iItems.AppendL( item );
    CleanupStack::Pop( item );
    }


void CMemSpyEngineOutputList::AddItemPercentageL( const TDesC& aCaption, TInt aOneHundredPercentValue, TInt aValue )
    {
    const TMemSpyPercentText val( MemSpyEngineUtils::FormatPercentage( TReal( aOneHundredPercentValue ), TReal( aValue ) ) );
    AddItemL( aCaption, val );
    }


void CMemSpyEngineOutputList::AddBlankItemL( TInt aRepetitions )
    {
    const TInt count = Count();
    InsertBlankItemL( count, aRepetitions );
    }


void CMemSpyEngineOutputList::AddUnderlineForPreviousItemL( TChar aUnderlineCharacter, TInt aBlankItemCount )
    {
    const TInt count = iItems.Count();
    if  ( count > 0 )
        {
        InsertUnderlineForItemAtL( count - 1, aUnderlineCharacter, aBlankItemCount );
        }
    }


void CMemSpyEngineOutputList::InsertItemL( TInt aPos, const TDesC& aCaption )
    {
    InsertItemL( aPos, aCaption, KNullDesC );
    }


void CMemSpyEngineOutputList::InsertItemL( TInt aPos, const TDesC& aCaption, const TDesC& aValue )
    {
    CMemSpyEngineOutputListItem* item = CMemSpyEngineOutputListItem::NewLC( aCaption, aValue );
    iItems.InsertL( item, aPos );
    CleanupStack::Pop( item );
    }


void CMemSpyEngineOutputList::InsertItemFormatUCL( TInt aPos, TRefByValue<const TDesC> aValueFormat, ... )
    {
	VA_LIST list;
	VA_START(list,aValueFormat);

    TPtr formatBuffer( FormatBuffer() );
	formatBuffer.Zero();
    formatBuffer.FormatList( aValueFormat, list );
    //
    InsertItemL( aPos, formatBuffer, KNullDesC );
    }


void CMemSpyEngineOutputList::InsertBlankItemL( TInt aPos, TInt aRepetitions )
    {
    while( aRepetitions-- > 0 )
        {
        InsertItemL( aPos, KMemSpyOutputListPseudoBlankItem, KMemSpyOutputListPseudoBlankItem );
        }
    }


void CMemSpyEngineOutputList::InsertUnderlineForItemAtL( TInt aPos, TChar aUnderlineCharacter, TInt aBlankItemCount )
    {
    const CMemSpyEngineOutputListItem& item = Item( aPos );
    
    // Clean text
    HBufC* caption = MemSpyEngineUtils::CleanupTextLC( item.Caption() );
    //RDebug::Print( _L("CMemSpyEngineOutputList::AddUnderlineForPreviousItemL() - [%3d] caption: %S"), caption->Length(), caption );
    HBufC* value = MemSpyEngineUtils::CleanupTextLC( item.Value() );
    //RDebug::Print( _L("CMemSpyEngineOutputList::AddUnderlineForPreviousItemL() - [%3d] value: %S"), value->Length(), value );
    
    // Make underline descriptor
    TBuf<1> underline;
    underline.Append( aUnderlineCharacter );

    // Make underline items
    const TInt lenCaption = caption->Length();
    if ( lenCaption > 0 )
        {
        TPtr pText( caption->Des() );
        pText.Repeat( underline );
        }

    const TInt lenValue = value->Length();
    if ( lenValue > 0 )
        {
        TPtr pText( value->Des() );
        pText.Repeat( underline );
        }

    // Create new item
    InsertItemL( aPos + 1, *caption, *value );

    // Clean up
    CleanupStack::PopAndDestroy( 2, caption );

    // Make blank row if needed
    InsertBlankItemL( aPos + 2, aBlankItemCount );
    }


TPtr& CMemSpyEngineOutputList::FormatBuffer()
    {
    if  ( iSink )
        {
        return iSink->FormatBuffer();
        }
    //
    return iFormatBufferPtr;
    }