diff -r 0ff24a8f6ca2 -r 98307c651589 memspy/Engine/Source/Helpers/MemSpyEngineHelperFbServ.cpp --- a/memspy/Engine/Source/Helpers/MemSpyEngineHelperFbServ.cpp Fri Aug 27 11:37:29 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1335 +0,0 @@ -/* -* 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 - -// System includes -#include -#include -#include - -// Driver includes -#include - -// User includes -#include -#include -#include -#include -#include -#include - -// Literal constants -_LIT( KMemSpyEngineFBServComma, ", " ); -_LIT( KMemSpyEngineFBServExportFileName, "Image_%08x_%02d_bpp_(%d x %d).bmp"); -_LIT( KMemSpyEngineFBSLargeChunkName, "FbsLargeChunk" ); -_LIT( KMemSpyEngineFBSSharedChunkName, "FbsSharedChunk" ); - - -CMemSpyEngineHelperFbServ::CMemSpyEngineHelperFbServ( CMemSpyEngine& aEngine ) -: iEngine( aEngine ) - { - } - - -CMemSpyEngineHelperFbServ::~CMemSpyEngineHelperFbServ() - { - iEngine.Driver().WalkHeapClose(); - } - - -void CMemSpyEngineHelperFbServ::ConstructL() - { - } - - -CMemSpyEngineHelperFbServ* CMemSpyEngineHelperFbServ::NewL( CMemSpyEngine& aEngine ) - { - CMemSpyEngineHelperFbServ* self = new(ELeave) CMemSpyEngineHelperFbServ( aEngine ); - CleanupStack::PushL( self ); - self->ConstructL(); - CleanupStack::Pop( self ); - return self; - } - - -TBool CMemSpyEngineHelperFbServ::IsLargeBitmapChunk( const TMemSpyDriverChunkInfo& aChunkInfo ) - { - TBool ret = EFalse; - // - if ( aChunkInfo.iType == EMemSpyDriverChunkTypeGlobal ) - { - ret = ( aChunkInfo.iName.FindF( KMemSpyEngineFBSLargeChunkName ) >= 0 ); - } - // - return ret; - } - - -TBool CMemSpyEngineHelperFbServ::IsSharedBitmapChunk( const TMemSpyDriverChunkInfo& aChunkInfo ) - { - TBool ret = EFalse; - // - if ( aChunkInfo.iType == EMemSpyDriverChunkTypeGlobal ) - { - ret = ( aChunkInfo.iName.FindF( KMemSpyEngineFBSSharedChunkName ) >= 0 ); - } - // - return ret; - } - - -EXPORT_C void CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL( RArray& aHandles ) - { - TInt fontConCount = 0; - TInt bitmapConCount =0; - //RArray dirtyHandles; - //CleanupClosePushL( dirtyHandles ); - GetArrayOfBitmapHandlesL( aHandles, bitmapConCount, fontConCount ); - //CleanupStack::PopAndDestroy( &dirtyHandles ); - } - - -void CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL( RArray& aHandles, TInt& aBitmapConCount, TInt& aFontConCount ) - { - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - START") ); - CMemSpyThread& fbServThread = IdentifyFbServThreadL(); - - // Suspend the process - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - got FBServ thread, suspending it...")); - iEngine.ProcessSuspendLC( fbServThread.Process().Id() ); - - // Get the heap cell data for the correct object (CFbTop) - TAny* cellAddress = NULL; - HBufC8* cellData = LocateCFbTopHeapCellDataLC( fbServThread, cellAddress ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - got CFbTop cell data: %d bytes", cellData->Length())); - - // Work out the offset to the bitmap address handles array - const TUint offsetBitmapCon = OffsetToCObjectConBitmapCon(); - const TUint offsetFontCon = OffsetToCObjectConFontCon(); - const TUint offsetHandleArray = OffsetToBitmapHandleArray(); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - offsetBitmapCon: %d", offsetBitmapCon )); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - offsetFontCon: %d", offsetFontCon )); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - offsetHandleArray: %d", offsetHandleArray )); - - // Create stream for reading heap data (makes life a bit easier). - RDesReadStream stream( *cellData ); - CleanupClosePushL( stream ); - - // We need to skip over the preamble to the start of the actual data. - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - skipping %d bytes [to start of bitmap con]...", offsetBitmapCon )); - (void) stream.ReadL( offsetBitmapCon ); // skip this much - - // Read CFbTop::iBitmapCon cell address - TAny* cellAddresBitmapCon = reinterpret_cast( stream.ReadUint32L() ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - cellAddresBitmapCon: 0x%08x", cellAddresBitmapCon )); - TInt bitmapConAllocated = 0; - RArray bitmapConAddresses; - CleanupClosePushL( bitmapConAddresses ); - ReadCObjectConInfoL( cellAddresBitmapCon, bitmapConAddresses, aBitmapConCount, bitmapConAllocated ); - CleanupStack::PopAndDestroy( &bitmapConAddresses ); - - // Read CFbTop::iFontCon cell address - TAny* cellAddresFontCon = reinterpret_cast( stream.ReadUint32L() ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - cellAddresFontCon: 0x%08x", cellAddresFontCon )); - TInt fontConAllocated = 0; - RArray fontConAddresses; - CleanupClosePushL( fontConAddresses ); - ReadCObjectConInfoL( cellAddresFontCon, fontConAddresses, aFontConCount, fontConAllocated ); - CleanupStack::PopAndDestroy( &fontConAddresses ); - - // Skip forwards to the bitmap handle array info - const TUint skipRemaining = ( offsetHandleArray - offsetFontCon ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - skipRemaining: %d", skipRemaining )); - (void) stream.ReadL( skipRemaining ); // skip this much - - // The layout of RPointerArrayBase is as follows: - // - // TInt iCount; - // TAny** iEntries; - // TInt iAllocated; - // TInt iGranularity; - // TInt iSpare1; - // TInt iSpare2; - - // Now read the next 4 bytes. This is the number of allocated array entries. - const TInt arrayEntryCount = stream.ReadInt32L(); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - arrayEntryCount: %d", arrayEntryCount )); - - // The next four bytes are the address of the cell we are interested in. - cellAddress = reinterpret_cast( stream.ReadUint32L() ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - cellAddress: 0x%08x", cellAddress )); - - // The next four bytes are the allocated count - const TInt arrayAlloctedCount = stream.ReadInt32L(); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - arrayAlloctedCount: %d", arrayAlloctedCount )); - - // Validate - if ( arrayEntryCount > arrayAlloctedCount || arrayEntryCount < 0 || arrayAlloctedCount < 0 ) - { - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - invalid array details => Leave with KErrCorrupt")); - User::Leave( KErrCorrupt ); - } - - // Clean up - don't need this data anymore. Real data is in another cell - CleanupStack::PopAndDestroy( 2, cellData ); // stream & cellData - - // Now obtain the heap cell data for the actual array itself. - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - trying to find bitmap array data...")); - cellData = LocateBitmapArrayHeapCellDataLC( cellAddress, arrayAlloctedCount ); - - // Parse the cell data in order to obtain the bitmap handles. - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - trying to extract bitmap handles...")); - ParseCellDataAndExtractHandlesL( *cellData, aHandles, arrayEntryCount ); - - // Tidy up - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - resuming process...")); - CleanupStack::PopAndDestroy( cellData ); - - // Close heap walker & resume process - iEngine.Driver().WalkHeapClose(); - CleanupStack::PopAndDestroy(); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetArrayOfBitmapHandlesL() - END")); - } - - -void CMemSpyEngineHelperFbServ::GetBitmapInfoL( TInt aHandle, TMemSpyEngineFBServBitmapInfo& aInfo ) - { - CFbsBitmap* bitmap = GetBitmapInfoLC( aHandle, aInfo ); - CleanupStack::PopAndDestroy( bitmap ); - } - - -CFbsBitmap* CMemSpyEngineHelperFbServ::GetBitmapInfoLC( TInt aHandle, TMemSpyEngineFBServBitmapInfo& aInfo ) - { - CFbsBitmap* bitmap = new(ELeave) CFbsBitmap(); - CleanupStack::PushL( bitmap ); - const TInt error = bitmap->Duplicate( aHandle ); - User::LeaveIfError( error ); - - // Basic info from bitmap itself - aInfo.iHandle = aHandle; - aInfo.iDisplayMode = bitmap->DisplayMode(); - - // Extended info comes from header - const SEpocBitmapHeader header( bitmap->Header() ); - - aInfo.iSizeInPixels = header.iSizeInPixels; - aInfo.iCompressionType = header.iCompression; - aInfo.iColor = header.iColor; - aInfo.iBitsPerPixel = header.iBitsPerPixel; - aInfo.iSizeInBytes = header.iBitmapSize; - - // Flags - aInfo.iFlags = TMemSpyEngineFBServBitmapInfo::EFlagsNone; - if ( bitmap->IsRomBitmap() ) - { - aInfo.iFlags |= TMemSpyEngineFBServBitmapInfo::EFlagsIsRomBitmap; - } - if ( bitmap->IsLargeBitmap() ) - { - aInfo.iFlags |= TMemSpyEngineFBServBitmapInfo::EFlagsIsLarge; - } - if ( bitmap->IsCompressedInRAM() ) - { - aInfo.iFlags |= TMemSpyEngineFBServBitmapInfo::EFlagsIsCompressedInRam; - } - else - { - // Can only do this if not compressed - if ( bitmap->IsMonochrome() ) - { - aInfo.iFlags |= TMemSpyEngineFBServBitmapInfo::EFlagsIsMonochrome; - } - } - - return bitmap; - } - - -CMemSpyThread& CMemSpyEngineHelperFbServ::IdentifyFbServThreadL() - { - _LIT(KFbServThreadName, "FbServ::!Fontbitmapserver"); - // - CMemSpyThread* thread = NULL; - CMemSpyProcess* process = NULL; - - // Get the fbserv thread object - CMemSpyEngineObjectContainer& container = iEngine.Container(); - User::LeaveIfError( container.ProcessAndThreadByFullName( KFbServThreadName, process, thread ) ); - // - return *thread; - } - - -HBufC8* CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC( CMemSpyThread& aFbServThread, TAny*& aCellAddress ) - { - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - START")); - - // We'll start looking for the CFbTop object at cell index 0, then we'll - // continue to a maximum of cell index 10. These are not actual allocation - // numbers, they are just cell indicies within FBServ's heap. - // Realistically, the cell should be the 7th. - const TInt KFbServWillingToStartAtCellIndex = 0; - const TInt KFbServWillingToSearchUntilCellIndex = 10; - - // We know the size of the cell is pretty big, since it contains a large - // hash-map object (4096 elements by default, 4 bytes big => 16k). We'll - // not try to retrieve more than 18k of data. - const TInt KFbServExpectedMinimumCellSize = 14*1024; - const TInt KFbServExpectedMaximumCellSize = 18*1024; - - // This is what we'll return, if we find it... - aCellAddress = NULL; - HBufC8* heapCellData = NULL; - - // Get the heap info - we need this for verification purposes - TMemSpyHeapInfo info; - TInt err = iEngine.Driver().GetHeapInfoUser( info, aFbServThread.Id() ); - if ( err == KErrNone && info.Type() == TMemSpyHeapInfo::ETypeUnknown ) - { - err = KErrNotSupported; - } - User::LeaveIfError( err ); - - // Now walk the heap! - err = iEngine.Driver().WalkHeapInit( aFbServThread.Id() ); - if ( err == KErrNone ) - { - TMemSpyDriverCellType cellType; - TAny* cellAddress; - TInt cellLength; - TInt cellNestingLevel; - TInt cellAllocationNumber; - TInt cellHeaderSize; - TAny* cellPayloadAddress; - // - for( TInt cellIndex = KFbServWillingToStartAtCellIndex; err == KErrNone && cellIndex < KFbServWillingToSearchUntilCellIndex; cellIndex++ ) - { - err = iEngine.Driver().WalkHeapNextCell( aFbServThread.Id(), cellType, cellAddress, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - cellIndex[%d] err: %d, cellLength: %d, cellAllocationNumber: %d, cellType: %d", cellIndex, err, cellLength, cellAllocationNumber, cellType)); - - if ( err == KErrNone && (cellType & EMemSpyDriverAllocatedCellMask)) - { - // We know we are looking for a relatively large *allocated* cell. - if ( cellLength >= KFbServExpectedMinimumCellSize && cellLength <= KFbServExpectedMaximumCellSize ) - { - const TInt payloadLength = cellLength; - - // This is *probably* the right cell. Let's get the data and check. - HBufC8* data = HBufC8::NewLC( payloadLength ); - TPtr8 pData( data->Des() ); - // - err = iEngine.Driver().WalkHeapReadCellData( cellAddress, pData, payloadLength ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - data fetch returned error: %d", err)); - - if ( err == KErrNone ) - { - //_LIT(KHeapDumpDataFormat, "%S"); - //iEngine.Sink().OutputBinaryDataL( KHeapDumpDataFormat, pData.Ptr(), (const TUint8*) cellAddress, pData.Length() ); - - // Check the data - const TUint heapMaxSize = info.AsRHeap().MetaData().iMaxHeapSize; - const TUint heapBaseAddress = (TUint) info.AsRHeap().MetaData().ChunkBaseAddress(); - const TBool correctHeapCellLocated = VerifyCorrectHeapCellL( *data, cellAddress, cellPayloadAddress, heapBaseAddress, heapMaxSize ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - verified: %d", correctHeapCellLocated)); - - if ( correctHeapCellLocated ) - { - aCellAddress = cellAddress; - heapCellData = data; - CleanupStack::Pop( data ); - break; - } - else - { - // Not the right cell. Keep going... - CleanupStack::PopAndDestroy( data ); - } - } - } - } - } - - // NB: don't do this here - - // iEngine.Driver().WalkHeapClose(); - // It gets done after all reading is complete - } - - if ( heapCellData == NULL ) - { - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - END - didn't find the right cell => KErrNotFound")); - User::Leave( KErrNotFound ); - } - // - CleanupStack::PushL( heapCellData ); - - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - END - everything okay, cell is: 0x%08x", aCellAddress)); - return heapCellData; - } - - -void CMemSpyEngineHelperFbServ::ReadCObjectConInfoL( TAny* aCellAddress, RArray& aContainerObjects, TInt& aCount, TInt& aAllocated ) - { - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - START - trying cell: 0x%08x", aCellAddress )); - - // What we will return - HBufC8* cellData = NULL; - - // Try to get info about real cell - TMemSpyDriverCellType cellType; - TInt cellLength; - TInt cellNestingLevel; - TInt cellAllocationNumber; - TInt cellHeaderSize; - TAny* cellPayloadAddress; - - // NOTE: this call may change the value of 'cellAddress' - TInt err = iEngine.Driver().WalkHeapGetCellInfo( aCellAddress, cellType, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - err: %d, cellAddress: 0x%08x, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, aCellAddress, cellLength, cellAllocationNumber, cellType)); - - if (err == KErrNone && (cellType & EMemSpyDriverAllocatedCellMask)) - { - // Check that the cell size meets our expectations - it should be a CObjectCon cell. - const TInt expectedCellSize = sizeof(CObjectCon*) + cellHeaderSize; - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - expectedCellSize: %d, actual: %d, address: 0x%08x", expectedCellSize, cellLength, aCellAddress)); - - if ( expectedCellSize <= cellLength ) - { - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - cell lengths are good, trying to get cell data...")); - - // Try to get real cell data - cellData = HBufC8::NewLC( cellLength ); - TPtr8 pData( cellData->Des() ); - // - err = iEngine.Driver().WalkHeapReadCellData( aCellAddress, pData, cellLength ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - reading cell data returned error: %d", err)); - } - else - { - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - not enough data -> KErrCorrupt")); - err = KErrCorrupt; - } - } - else - { - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - END - didn't find cell data => KErrNotFound")); - User::Leave( KErrNotFound ); - } - - CObjectCon* con = CObjectCon::NewL(); - const TUint32 KExpectedObjectConVTable = *((TUint32*) con); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - KExpectedObjectConVTable: 0x%08x", KExpectedObjectConVTable )); - delete con; - - // We should have the valid CObjectCon data now. - RDesReadStream stream( *cellData ); - CleanupClosePushL( stream ); - - // Read vtable - const TUint32 vTable = stream.ReadUint32L(); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - actual vTable: 0x%08x", vTable )); - if ( vTable != KExpectedObjectConVTable ) - { - User::Leave( KErrNotFound ); - } - - const TInt uniqueId = stream.ReadInt32L(); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - uniqueId: %d", uniqueId )); - - aCount = stream.ReadInt32L(); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - aCount: %d", aCount )); - - aAllocated = stream.ReadInt32L(); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - aAllocated: %d", aAllocated )); - - // This is actually CObject's iObject, i.e. CObject** iObjects. - TAny* pObjects = reinterpret_cast< TAny*>( stream.ReadUint32L() ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - pObjects: 0x%08x", pObjects )); - - CleanupStack::PopAndDestroy( 2, cellData ); // cellData & stream - - // Now fetch the cell containing the CObject pointers... - err = iEngine.Driver().WalkHeapGetCellInfo( pObjects, cellType, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - array of CObject* cell fetch err: %d, cellAddress: 0x%08x, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, aCellAddress, cellLength, cellAllocationNumber, cellType)); - User::LeaveIfError( err ); - - const TInt expectedSize = ( aAllocated * sizeof(CObject*) ) + cellHeaderSize; - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - expectedSize: %d, actual size: %d", expectedSize, cellLength )); - if ( cellLength < expectedSize ) - { - User::Leave( KErrUnderflow ); - } - - // Get the data - cellData = HBufC8::NewLC( cellLength ); - TPtr8 pData( cellData->Des() ); - err = iEngine.Driver().WalkHeapReadCellData( pObjects, pData, cellLength ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - reading cell data returned error: %d", err)); - User::LeaveIfError( err ); - - // Open stream - stream.Open( *cellData ); - CleanupClosePushL( stream ); - - // Extract array of pointers - for( TInt i=0; i( stream.ReadUint32L() ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - object[%04d]: 0x%08x", i, objectAddress )); - aContainerObjects.AppendL( objectAddress ); - } - CleanupStack::PopAndDestroy( 2, cellData ); // cellData & stream - - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - END" )); - } - - -HBufC8* CMemSpyEngineHelperFbServ::LocateBitmapArrayHeapCellDataLC( TAny*& aArrayCellAddress, TInt aArrayAllocCount ) - { - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateBitmapArrayHeapCellDataLC() - START - trying cell: 0x%08x, aArrayAllocCount: %d", aArrayCellAddress, aArrayAllocCount)); - - // What we will return - HBufC8* cellData = NULL; - - // Try to get info about real cell - TMemSpyDriverCellType cellType; - TInt cellLength; - TInt cellNestingLevel; - TInt cellAllocationNumber; - TInt cellHeaderSize; - TAny* cellPayloadAddress; - - // NOTE: this call may change the value of 'cellAddress' - TInt err = iEngine.Driver().WalkHeapGetCellInfo( aArrayCellAddress, cellType, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - err: %d, cellAddress: 0x%08x, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, aArrayCellAddress, cellLength, cellAllocationNumber, cellType)); - - if (err == KErrNone && (cellType & EMemSpyDriverAllocatedCellMask)) - { - // Check that the cell size meets our expectations. - // The cell should be a very specific length - const TInt expectedCellSize = (sizeof(CBase*) * aArrayAllocCount) + cellHeaderSize; - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateBitmapArrayHeapCellDataLC() - expectedCellSize: %d, actual: %d, address: 0x%08x", expectedCellSize, cellLength, aArrayCellAddress)); - - if ( expectedCellSize <= cellLength ) - { - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateBitmapArrayHeapCellDataLC() - cell lengths are good, trying to get cell data...")); - - // Try to get real cell data - cellData = HBufC8::NewLC( cellLength ); - TPtr8 pData( cellData->Des() ); - // - err = iEngine.Driver().WalkHeapReadCellData( aArrayCellAddress, pData, cellLength ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateBitmapArrayHeapCellDataLC() - reading cell data returned error: %d", err)); - } - else - { - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateBitmapArrayHeapCellDataLC() - not enough data -> KErrCorrupt")); - err = KErrCorrupt; - } - } - // - if ( cellData == NULL ) - { - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateBitmapArrayHeapCellDataLC() - END - didn't find cell data => KErrNotFound")); - err = KErrNotFound; - } - User::LeaveIfError( err ); - // - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateBitmapArrayHeapCellDataLC() - END - ok! - got %d bytes", cellData->Length() ) ); - return cellData; - } - - -void CMemSpyEngineHelperFbServ::ParseCellDataAndExtractHandlesL( const TDesC8& aData, RArray& aHandles, TInt aArrayEntryCount ) - { - aHandles.Reset(); - - // Create read stream - RDesReadStream stream( aData ); - CleanupClosePushL( stream ); - - for( TInt i=0; i We must skip it - __ASSERT_ALWAYS( sizeof(RFs) == 4, User::Invariant() ); - address = reader.ReadUint32L(); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::VerifyCorrectHeapCellL() - skipping RFs: 0x%08x", address)); - - // Next object is an address (CFontStore* iFontStore). We can validate this against - // the method arguments. - address = reader.ReadUint32L(); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::VerifyCorrectHeapCellL() - iFontStore: 0x%08x", address)); - - if ( address > aHeapStartingAddress && address < KFbServHeapCeilingAddress ) - { - // Next comes another pointer (CObjectCon* iBitmapCon) - address = reader.ReadUint32L(); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::VerifyCorrectHeapCellL() - iBitmapCon: 0x%08x", address)); - - if ( address > aHeapStartingAddress && address < KFbServHeapCeilingAddress ) - { - // Next another pointer (CObjectCon* iFontCon) - address = reader.ReadUint32L(); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::VerifyCorrectHeapCellL() - iFontCon: 0x%08x", address)); - - if ( address > aHeapStartingAddress && address < KFbServHeapCeilingAddress ) - { - // And finally, yet another pointer (RHeap* iHeap) - address = reader.ReadUint32L(); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::VerifyCorrectHeapCellL() - iHeap: 0x%08x", address)); - - if ( address > aHeapStartingAddress && address < KFbServHeapCeilingAddress ) - { - // That'll do. - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::VerifyCorrectHeapCellL() - data seems okay!")); - correctCell = ETrue; - } - } - } - } - - CleanupStack::PopAndDestroy( &reader ); - // - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::VerifyCorrectHeapCellL() - END - correctCell: %d", correctCell)); - return correctCell; - } - - -TUint CMemSpyEngineHelperFbServ::OffsetToCObjectConBitmapCon() - { - TUint ret = 0; - - // VTable - ret += 4; - - // RFs - ret += sizeof(RFs); - - // CFontStore* iFontStore; - ret += sizeof(CBase*); // best effort - - return ret; - } - - -TUint CMemSpyEngineHelperFbServ::OffsetToCObjectConFontCon() - { - TUint ret = OffsetToCObjectConBitmapCon(); - - // CObjectCon* iBitmapCon; - ret += sizeof(CObjectCon*); - - return ret; - } - - -TUint CMemSpyEngineHelperFbServ::OffsetToBitmapHandleArray() - { - TUint ret = OffsetToCObjectConFontCon(); - - // CObjectConIx* iConIx; - ret += sizeof(CObjectConIx*); - - // RHeap* iHeap; - ret += sizeof(RHeap*); - - // RChunk iChunk - ret += sizeof(RChunk); - - // RChunk iLargeBitmapChunk - ret += sizeof(RChunk); - - // RMutex iLargeBitmapAccess - ret += sizeof(RMutex); - - // CChunkPile* iPile; - ret += sizeof(CBase*); // best effort - - // RPointerArray iFontNameAlias; - ret += sizeof(RPointerArray); - - return ret; - } - - -CMemSpyEngineHelperFbServ::CBitmapObject* CMemSpyEngineHelperFbServ::GetBitmapObjectLC( TAny* aCellAddress ) - { - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - START - aCellAddress: 0x%08x", aCellAddress )); - - // What we will return - CBitmapObject* object = new(ELeave) CBitmapObject(); - CleanupStack::PushL( object ); - - // The data we will read - HBufC8* cellData = NULL; - - // Try to get info about real cell - TMemSpyDriverCellType cellType; - TInt cellLength; - TInt cellNestingLevel; - TInt cellAllocationNumber; - TInt cellHeaderSize; - TAny* cellPayloadAddress; - - // NOTE: this call may change the value of 'cellAddress' - TInt err = iEngine.Driver().WalkHeapGetCellInfo( aCellAddress, cellType, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - err: %d, cellAddress: 0x%08x, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, aCellAddress, cellLength, cellAllocationNumber, cellType)); - - if (err == KErrNone && (cellType & EMemSpyDriverAllocatedCellMask)) - { - // Check that the cell size meets our expectations - it should be a CBitmapObject, but without the additional "this" pointer - // which we have tacked onto the object. - const TInt expectedCellSize = sizeof( CBitmapObject ) + cellHeaderSize - sizeof( CBitmapObject* ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - expectedCellSize: %d, actual: %d, address: 0x%08x", expectedCellSize, cellLength, aCellAddress)); - - if ( expectedCellSize <= cellLength ) - { - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - cell lengths are good, trying to get cell data...")); - - // Try to get real cell data - cellData = HBufC8::NewLC( cellLength ); - TPtr8 pData( cellData->Des() ); - // - err = iEngine.Driver().WalkHeapReadCellData( aCellAddress, pData, cellLength ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - reading cell data returned error: %d", err)); - } - else - { - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - not enough data -> KErrCorrupt")); - err = KErrCorrupt; - } - } - else - { - User::Leave( KErrNotFound ); - } - - RDesReadStream stream( *cellData ); - CleanupClosePushL( stream ); - - // Read vtable - const TUint32 vTable = stream.ReadUint32L(); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - actual vTable: 0x%08x", vTable )); - TBool isROMAddress = EFalse; - err = User::IsRomAddress( isROMAddress, (TAny*) vTable ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - vtable (0x%08x) is in ROM: %d (error: %d)", vTable, isROMAddress, err)); - User::LeaveIfError( err ); - - // Skip CObject members - (void) stream.ReadL( sizeof( CObject ) ); // skip this much - object->iThisPointer = reinterpret_cast< CBitmapObject* >( cellPayloadAddress );; - object->iTop = reinterpret_cast< CBase* >( stream.ReadUint32L() ); - object->iAddressPointer = reinterpret_cast< CBitwiseBitmap* >( stream.ReadUint32L() ); - object->iHandle = stream.ReadInt32L(); - object->iCleanBitmap = reinterpret_cast< CBitmapObject* >( stream.ReadUint32L() ); - - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - object->iThisPointer: 0x%08x", object->iThisPointer )); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - object->iTop: 0x%08x", object->iTop )); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - object->iAddressPointer: 0x%08x", object->iAddressPointer )); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - object->iHandle: 0x%08x", object->iHandle )); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - object->iCleanBitmap: 0x%08x", object->iCleanBitmap )); - - // Clean up - don't need this data anymore. Real data is in another cell - CleanupStack::PopAndDestroy( 2, cellData ); // stream & cellData - - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - END - aCellAddress: 0x%08x", aCellAddress )); - return object; - } - - - - - - - - - - - - - - - - - - - - - - - - - - - -CMemSpyEngineFbServBitmapArray::CMemSpyEngineFbServBitmapArray( const RArray& aBitmapHandles ) -: CActive( CActive::EPriorityIdle ), iBitmapHandles( aBitmapHandles ), iGranularity( 0 ) - { - CActiveScheduler::Add( this ); - } - - -CMemSpyEngineFbServBitmapArray::CMemSpyEngineFbServBitmapArray( TInt aPriority, const RArray& aBitmapHandles, MMemSpyEngineFbSerbBitmapArrayObserver& aObserver, TInt aGranularity ) -: CActive( aPriority ), iBitmapHandles( aBitmapHandles ), iObserver( &aObserver ), iGranularity( aGranularity ) - { - CActiveScheduler::Add( this ); - CompleteSelf(); - } - - -EXPORT_C CMemSpyEngineFbServBitmapArray::~CMemSpyEngineFbServBitmapArray() - { - Cancel(); - // - iBitmaps.ResetAndDestroy(); - iBitmaps.Close(); - } - - -void CMemSpyEngineFbServBitmapArray::ConstructL() - { - if ( !IsActive() ) - { - // Sync construction... - const TInt count = iBitmapHandles.Count(); - for(TInt i=0; i& aBitmapHandles ) - { - CMemSpyEngineFbServBitmapArray* self = new(ELeave) CMemSpyEngineFbServBitmapArray( aBitmapHandles ); - CleanupStack::PushL( self ); - self->ConstructL(); - CleanupStack::Pop( self ); - return self; - } - - -EXPORT_C CMemSpyEngineFbServBitmapArray* CMemSpyEngineFbServBitmapArray::NewL( TInt aPriority, const RArray& aBitmapHandles, MMemSpyEngineFbSerbBitmapArrayObserver& aObserver, TInt aGranularity ) - { - CMemSpyEngineFbServBitmapArray* self = new(ELeave) CMemSpyEngineFbServBitmapArray( aPriority, aBitmapHandles, aObserver, aGranularity ); - CleanupStack::PushL( self ); - self->ConstructL(); - CleanupStack::Pop( self ); - return self; - } - - -EXPORT_C TInt CMemSpyEngineFbServBitmapArray::Count() const - { - return iBitmaps.Count(); - } - - -EXPORT_C CMemSpyEngineFbServBitmap& CMemSpyEngineFbServBitmapArray::At( TInt aIndex ) - { - return *iBitmaps[ aIndex ]; - } - - -EXPORT_C const CMemSpyEngineFbServBitmap& CMemSpyEngineFbServBitmapArray::At( TInt aIndex ) const - { - return *iBitmaps[ aIndex ]; - } - - -EXPORT_C CMemSpyEngineFbServBitmap& CMemSpyEngineFbServBitmapArray::BitmapByHandleL( TInt aHandle ) - { - const TInt index = BitmapIndexByHandle( aHandle ); - User::LeaveIfError( index ); - CMemSpyEngineFbServBitmap& ret = At( index ); - return ret; - } - - -EXPORT_C TInt CMemSpyEngineFbServBitmapArray::BitmapIndexByHandle( TInt aHandle ) const - { - TInt ret = KErrNotFound; - // - const TInt count = Count(); - for( TInt i=0; iHandleFbServBitmapArrayEventL( event ); - } - } - - -void CMemSpyEngineFbServBitmapArray::DoCancel() - { - // Nothing to do - } - - -TInt CMemSpyEngineFbServBitmapArray::RunError( TInt /*aError*/ ) - { - return KErrNone; - } - - -void CMemSpyEngineFbServBitmapArray::CompleteSelf() - { - TRequestStatus* status = &iStatus; - User::RequestComplete( status, KErrNone ); - SetActive(); - } - - -void CMemSpyEngineFbServBitmapArray::CreateBitmapL( TInt aHandle ) - { - CMemSpyEngineFbServBitmap* bitmap = CMemSpyEngineFbServBitmap::NewLC( aHandle ); - iBitmaps.AppendL( bitmap ); - CleanupStack::Pop( bitmap ); - } - - -void CMemSpyEngineFbServBitmapArray::SortBySizeL() - { - TLinearOrder< CMemSpyEngineFbServBitmap > comparer( CompareBySize ); - iBitmaps.Sort( comparer ); - } - - -TInt CMemSpyEngineFbServBitmapArray::CompareBySize( const CMemSpyEngineFbServBitmap& aLeft, const CMemSpyEngineFbServBitmap& aRight ) - { - TInt ret = 1; - // - if ( aLeft.BitmapSizeInBytes() > aRight.BitmapSizeInBytes() ) - { - ret = -1; - } - else if ( aLeft.BitmapSizeInBytes() == aRight.BitmapSizeInBytes() ) - { - ret = 0; - } - // - return ret; - } - - - - - - - - - - - - - - - - - - - - - - -CMemSpyEngineFbServBitmap::CMemSpyEngineFbServBitmap() -: CDesCArrayFlat( 5 ) - { - } - - -EXPORT_C CMemSpyEngineFbServBitmap::~CMemSpyEngineFbServBitmap() - { - delete iBitmap; - delete iCaption; - } - - -void CMemSpyEngineFbServBitmap::ConstructL( TInt aHandle ) - { - iBitmap = new(ELeave) CFbsBitmap(); - const TInt error = iBitmap->Duplicate( aHandle ); - User::LeaveIfError( error ); - const SEpocBitmapHeader header( iBitmap->Header() ); - - // Prepare caption - _LIT( KCaptionFormat, "\t%2d bpp, %S\t\t%4d x %4d pixels" ); - iCaption = HBufC::NewL( 128 ); - TPtr pCaption( iCaption->Des() ); - - // Create size string - const TMemSpySizeText size( MemSpyEngineUtils::FormatSizeText( header.iBitmapSize ) ); - pCaption.AppendFormat( KCaptionFormat, header.iBitsPerPixel, &size, header.iSizeInPixels.iWidth, header.iSizeInPixels.iHeight ); - - // Prepare items - PrepareItemsL(); - } - - -EXPORT_C CMemSpyEngineFbServBitmap* CMemSpyEngineFbServBitmap::NewLC( TInt aHandle ) - { - CMemSpyEngineFbServBitmap* self = new(ELeave) CMemSpyEngineFbServBitmap(); - CleanupStack::PushL( self ); - self->ConstructL( aHandle ); - return self; - } - - -TInt CMemSpyEngineFbServBitmap::BitmapSizeInBytes() const - { - const SEpocBitmapHeader header( iBitmap->Header() ); - return header.iBitmapSize; - } - - -EXPORT_C const TDesC& CMemSpyEngineFbServBitmap::Caption() const - { - return *iCaption; - } - - -EXPORT_C CFbsBitmap& CMemSpyEngineFbServBitmap::Bitmap() - { - return *iBitmap; - } - - -EXPORT_C const CFbsBitmap& CMemSpyEngineFbServBitmap::Bitmap() const - { - return *iBitmap; - } - - -EXPORT_C TInt CMemSpyEngineFbServBitmap::Handle() const - { - return iBitmap->Handle(); - } - - -EXPORT_C void CMemSpyEngineFbServBitmap::OutputDataL( CMemSpyEngine& aEngine ) const - { - const SEpocBitmapHeader header( iBitmap->Header() ); - // - _LIT(KMemSpyFBServHex, "0x%08x"); - _LIT(KMemSpyFBServDecimal, "%d"); - // - HBufC* columns = HBufC::NewLC( 1024 ); - TPtr pColumns( columns->Des() ); - // - pColumns.AppendFormat( KMemSpyFBServHex, Handle() ); - pColumns.Append( KMemSpyEngineFBServComma ); - // - pColumns.AppendFormat( KMemSpyFBServDecimal, header.iBitmapSize ); - pColumns.Append( KMemSpyEngineFBServComma ); - // - pColumns.AppendFormat( KMemSpyFBServDecimal, header.iSizeInPixels.iWidth ); - pColumns.Append( KMemSpyEngineFBServComma ); - // - pColumns.AppendFormat( KMemSpyFBServDecimal, header.iSizeInPixels.iHeight ); - pColumns.Append( KMemSpyEngineFBServComma ); - // - pColumns.AppendFormat( KMemSpyFBServDecimal, header.iBitsPerPixel ); - pColumns.Append( KMemSpyEngineFBServComma ); - // - pColumns.AppendFormat( KMemSpyFBServDecimal, header.iColor ); - pColumns.Append( KMemSpyEngineFBServComma ); - // - TBuf<24> fileCompressionType; - GetFileCompressionTypeAsString( header.iCompression, fileCompressionType ); - pColumns.Append( fileCompressionType ); - pColumns.Append( KMemSpyEngineFBServComma ); - // - GetExportableFileNameL( pColumns ); - // - aEngine.Sink().OutputLineL( pColumns ); - CleanupStack::PopAndDestroy( columns ); - } - - -EXPORT_C void CMemSpyEngineFbServBitmap::OutputDataColumnsL( CMemSpyEngine& aEngine ) - { - HBufC* columns = HBufC::NewLC( 1024 ); - TPtr pColumns( columns->Des() ); - // - _LIT(KCol1, "Handle"); - pColumns.Append( KCol1 ); - pColumns.Append( KMemSpyEngineFBServComma ); - // - _LIT(KCol2, "Uncompressed Size (Bytes)"); - pColumns.Append( KCol2 ); - pColumns.Append( KMemSpyEngineFBServComma ); - // - _LIT(KCol3, "Width"); - pColumns.Append( KCol3 ); - pColumns.Append( KMemSpyEngineFBServComma ); - // - _LIT(KCol4, "Height"); - pColumns.Append( KCol4 ); - pColumns.Append( KMemSpyEngineFBServComma ); - // - _LIT(KCol5, "BPP"); - pColumns.Append( KCol5 ); - pColumns.Append( KMemSpyEngineFBServComma ); - // - _LIT(KCol6, "Color"); - pColumns.Append( KCol6 ); - pColumns.Append( KMemSpyEngineFBServComma ); - // - _LIT(KCol7, "Compression"); - pColumns.Append( KCol7 ); - pColumns.Append( KMemSpyEngineFBServComma ); - // - _LIT(KCol8, "File Name"); - pColumns.Append( KCol8 ); - // - aEngine.Sink().OutputLineL( pColumns ); - CleanupStack::PopAndDestroy( columns ); - } - - -EXPORT_C void CMemSpyEngineFbServBitmap::GetExportableFileNameL( TDes& aAppendName ) const - { - const SEpocBitmapHeader header( iBitmap->Header() ); - - // Create a filename - aAppendName.AppendFormat( KMemSpyEngineFBServExportFileName, Handle(), header.iBitsPerPixel, header.iSizeInPixels.iWidth, header.iSizeInPixels.iHeight ); - } - - -void CMemSpyEngineFbServBitmap::GetExportableFileNameL( const TMemSpyEngineFBServBitmapInfo& aInfo, TDes& aAppendName ) - { - aAppendName.AppendFormat( KMemSpyEngineFBServExportFileName, aInfo.iHandle, aInfo.iBitsPerPixel, aInfo.iSizeInPixels.iWidth, aInfo.iSizeInPixels.iHeight ); - } - - -void CMemSpyEngineFbServBitmap::PrepareItemsL() - { - const SEpocBitmapHeader header( iBitmap->Header() ); - TBuf<256> item; - - // View bitmap (ugly, but needed by UI) - _LIT(KCaptionMinus2, "\tView Bitmap\t\t"); - AppendL( KCaptionMinus2 ); - - // Dimensions - _LIT(KCaptionMinus1, "\tDimensions\t\t%5d x %5d"); - item.Format( KCaptionMinus1, header.iSizeInPixels.iWidth, header.iSizeInPixels.iHeight ); - AppendL( item ); - - // Handle - _LIT(KCaption0, "\tHandle\t\t0x%08x"); - item.Format( KCaption0, iBitmap->Handle() ); - AppendL( item ); - - // In Rom? - _LIT(KCaption1, "\tIn ROM?\t\t%S"); - _LIT(KIsRomBitmap, "Yes"); - _LIT(KNotRomBitmap, "No"); - if ( iBitmap->IsRomBitmap() ) - { - item.Format( KCaption1, &KIsRomBitmap ); - } - else - { - item.Format( KCaption1, &KNotRomBitmap ); - } - AppendL( item ); - - // Bits per pixel - _LIT(KCaption2, "\tBits Per Pixel\t\t%2d"); - item.Format( KCaption2, header.iBitsPerPixel ); - AppendL( item ); - - // Size of uncompressed bitmap data - _LIT(KCaption3, "\tUncompressed data size\t\t%S"); - const TMemSpySizeText sizeStringUncompressed( MemSpyEngineUtils::FormatSizeText( header.iBitmapSize ) ); - item.Format( KCaption3, &sizeStringUncompressed ); - AppendL( item ); - - // Palette entry count - _LIT(KCaption4, "\tNumber of palette entries\t\t%d"); - item.Format( KCaption4, header.iPaletteEntries ); - AppendL( item ); - - // Colour - _LIT(KCaption5, "\tColour\t\t%d"); - item.Format( KCaption5, header.iColor); - AppendL( item ); - - // Palette entry count - _LIT(KCaption6, "\tFile compression type\t\t%S"); - TBuf<24> fileCompressionType; - GetFileCompressionTypeAsString( header.iCompression, fileCompressionType ); - item.Format( KCaption6, &fileCompressionType ); - AppendL( item ); - } - - -void CMemSpyEngineFbServBitmap::GetFileCompressionTypeAsString( TBitmapfileCompression aType, TDes& aString ) - { - _LIT(KUnknown, "Unknown"); - _LIT(KNoCompression, "None"); - _LIT(KRLE, "RLE"); - _LIT(KTwelveBitRLE, "12-bit RLE"); - _LIT(KSixteenBitRLE, "16-bit RLE"); - _LIT(KTwentyFourBitRLE, "24-bit RLE"); - _LIT(KThirtyTwoBitRLE, "32-bit RLE"); - // - switch( aType ) - { - case ENoBitmapCompression: - aString = KNoCompression; - break; - case EByteRLECompression: - aString = KRLE; - break; - case ETwelveBitRLECompression: - aString = KTwelveBitRLE; - break; - case ESixteenBitRLECompression: - aString = KSixteenBitRLE; - break; - case ETwentyFourBitRLECompression: - aString = KTwentyFourBitRLE; - break; - case EThirtyTwoUBitRLECompression: - aString = KThirtyTwoBitRLE; - break; - default: - case ERLECompressionLast: - aString = KUnknown; - break; - } - } - - - - - - - -