PECengine/CoreUtilsLib2/SrvSrc/PEngMessagePacker.cpp
changeset 0 094583676ce7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PECengine/CoreUtilsLib2/SrvSrc/PEngMessagePacker.cpp	Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,404 @@
+/*
+* Copyright (c) 2005 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:  Collection of tools used to pack and unpack
+*                data transferred over IPC.
+*
+*/
+
+// INCLUDE FILES
+#include <E32Std.h>
+#include "PEngMessagePacker.h"
+
+
+_LIT( KPEngMsgPckPanic, "PEngMsgPckr" );
+enum TPEngMsgPckPanicReason
+    {
+    EResetIntArrayBufLength,
+    EIntArrayCountBufLength,
+    EIntFromArrayIndexNegative,
+    EIntFromArrayIndexTooLarge
+    };
+
+
+// ====================== MEMBER FUNCTIONS ======================================
+
+// =============================================================================
+// ===================== DESCRIPTOR ARRAY PACKING ==============================
+// =============================================================================
+
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::DesArrayPackageSize()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt PEngMessagePacker::DesArrayPackageSize( const MDesCArray& aDesArray )
+    {
+    TInt count ( aDesArray.MdcaCount() );
+    TInt len( count + 1 ); // once more count on the begining of buf
+    for ( TInt x( 0 ) ; x < count ; x++ )
+        {
+        len += aDesArray.MdcaPoint( x ).Length();
+        }
+
+    return len;
+    }
+
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::DesArrayPackageSize()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt PEngMessagePacker::DesArrayPackageSize( const TDesC& aDesAsArray )
+    {
+    return aDesAsArray.Length() + 2; // length and cout
+    }
+
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::PackDesArrayL()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C HBufC16* PEngMessagePacker::PackDesArrayL( const MDesCArray& aDesArray )
+    {
+    HBufC16* desBuffer = HBufC16::NewL( DesArrayPackageSize( aDesArray ) );
+    TPtr des = desBuffer->Des();
+    TInt count ( aDesArray.MdcaCount() );
+    des.Append( ( TUint16* ) &count, 1 );
+    for ( TInt x( 0 ) ; x < count ; x++ )
+        {
+        TPtrC element( aDesArray.MdcaPoint( x ) );
+        TInt length( element.Length() );
+        des.Append( reinterpret_cast<TUint16*> ( &length ), 1 );
+        des.Append( element );
+        }
+
+    return desBuffer;
+    }
+
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::PackDesArray()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt PEngMessagePacker::PackDesArray( TDes& aBuffer,
+                                               const MDesCArray& aDesArray )
+    {
+    aBuffer.Zero();
+    if ( aBuffer.MaxLength() < DesArrayPackageSize( aDesArray ) )
+        {
+        return KErrArgument;
+        }
+
+    TInt count ( aDesArray.MdcaCount() );
+    aBuffer.Append( reinterpret_cast<TUint16*> ( &count ), 1 );
+    for ( TInt x( 0 ) ; x < count ; x++ )
+        {
+        TPtrC element( aDesArray.MdcaPoint( x ) );
+        TInt length( element.Length() );
+        aBuffer.Append( reinterpret_cast<TUint16*> ( &length ), 1 );
+        aBuffer.Append( element );
+        }
+
+
+    return KErrNone;
+    }
+
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::PackOneDesAsArrayL()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C HBufC16* PEngMessagePacker::PackOneDesAsArrayL( const TDesC& aDes )
+    {
+    HBufC16* desBuffer = HBufC16::NewL( aDes.Length() + 2 ); // count and size
+    TPtr des = desBuffer->Des();
+    TInt count( 1 ); //Only one descriptor is packed
+    des.Append( reinterpret_cast<TUint16*> ( &count ), 1 );
+    TInt length( aDes.Length() );
+    des.Append( reinterpret_cast<TUint16*> ( &length ), 1 );
+    des.Append( aDes );
+    return desBuffer;
+    }
+
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::PackOneDesAsArray()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt PEngMessagePacker::PackOneDesAsArray( TDes& aBuffer,
+                                                    const TDesC& aDes )
+    {
+    aBuffer.Zero();
+    if ( aBuffer.MaxLength() < ( aDes.Length() + 2 ) ) // count and size
+        {
+        return KErrArgument;
+        }
+
+    TInt count( 1 );
+    aBuffer.Append( reinterpret_cast<TUint16*> ( &count ), 1 );
+    TInt length( aDes.Length() );
+    aBuffer.Append( reinterpret_cast<TUint16*> ( &length ), 1 );
+    aBuffer.Append( aDes );
+    return KErrNone;
+    }
+
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::AppendToDesArray()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt PEngMessagePacker::AppendToDesArray( TDes& aBuffer,
+                                                   const TDesC& aDes )
+    {
+    // is anything in the array?
+    TInt count( 0 ); // if array will be empty
+    if ( aBuffer.Length() == 0 )
+        {
+        // first element appent count first
+        aBuffer.Append( reinterpret_cast<TUint16*> ( &count ), 1 );
+        }
+
+    // check space
+    if ( ( aBuffer.Length() + aDes.Length() + 1 ) > aBuffer.MaxLength() )
+        {
+        return KErrBadDescriptor;
+        }
+
+    TInt length( aDes.Length() );
+    aBuffer.Append( reinterpret_cast<TUint16*> ( &length ), 1 );
+    aBuffer.Append( aDes );
+
+    //  update count
+    count = ( TInt ) ( aBuffer[ 0 ] ); // count is first
+    count++;
+    aBuffer[ 0 ] = static_cast<TUint16> ( count );
+    return KErrNone;
+    }
+
+
+
+
+// =============================================================================
+// =================== DESCRIPTOR ARRAY EXTRACTING =============================
+// =============================================================================
+
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::DesArrayCount()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt PEngMessagePacker::DesArrayCount( const TDesC& aBuffer )
+    {
+    if ( aBuffer.Length() == 0 )
+        {
+        return 0; // des is empty
+        }
+
+    return ( TInt ) ( aBuffer[ 0 ] );
+    }
+
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::UnpackDesArrayL()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt PEngMessagePacker::UnpackDesArrayL( const TDesC& aBuffer,
+                                                  CDesCArray& aArray )
+    {
+    return UnpackDesTempArrayL( aBuffer, aArray );
+    }
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::UnpackDesArrayL()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt PEngMessagePacker::UnpackDesArrayL( const TDesC& aBuffer,
+                                                  CPtrCArray& aArray )
+    {
+    return UnpackDesTempArrayL( aBuffer, aArray );
+    }
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::UnpackDesArrayLC()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CDesCArray* PEngMessagePacker::UnpackDesArrayLC( const TDesC& aBuffer )
+    {
+    TInt count ( DesArrayCount( aBuffer ) );
+    CDesC16ArrayFlat* desArray = new( ELeave ) CDesC16ArrayFlat( ++count );
+    CleanupStack::PushL( desArray );
+    UnpackDesArrayL( aBuffer, *desArray );
+    return desArray;
+    }
+
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::UnpackFirstDesFromArrayL()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C HBufC* PEngMessagePacker::UnpackFirstDesFromArrayL( const TDesC& aBuffer )
+    {
+    // Ignore count, read length of des
+    TInt desL ( ( TInt ) ( aBuffer[1] ) ); // first was count
+
+    // First two are info about count and length
+    // Returns buffer ownership to caller
+    return aBuffer.Mid( 2, desL ).AllocL();
+    }
+
+
+
+// =============================================================================
+// ===================== INTEGER ARRAY HANDLING ================================
+// =============================================================================
+
+
+// -----------------------------------------------------------------------------
+// AppendInt32ToDesc()
+// -----------------------------------------------------------------------------
+//
+void AppendInt32ToDesc( TDes& aBuffer, TInt32 aValue )
+    {
+    aBuffer.Append( ( TUint16* ) &aValue, 2 );  //TInt32 ==> 2 x 16bytes
+    }
+
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::TIntArrayPackageSize()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt PEngMessagePacker::TIntArrayPackageSize( TInt aElementCount )
+    {
+    TInt size = 2; //array count is stored to 32 bit ==> 2 x 16bytes
+    size += aElementCount * 2;  //each array element takes 2 x 16bytes
+    return size;
+    }
+
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::PackTIntArrayL()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C HBufC16* PEngMessagePacker::PackTIntArrayL( const RArray<TInt>& aTIntArray )
+    {
+    TInt packSize = PEngMessagePacker::TIntArrayPackageSize( aTIntArray.Count() );
+    HBufC* packBuf = HBufC::NewL( packSize );
+    TPtr pack = packBuf->Des();
+
+    //Add first the count
+    TInt32 count( aTIntArray.Count() );
+    AppendInt32ToDesc( pack, count );
+
+
+    //Then entries
+    for ( TInt ix( 0 ) ; ix < count ; ix++ )
+        {
+        TInt32 intValue = aTIntArray[ ix ];
+        AppendInt32ToDesc( pack, intValue );
+        }
+
+
+    return packBuf;
+    }
+
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::ResetTIntArray()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void PEngMessagePacker::ResetTIntArray( TDes& aBuffer )
+    {
+    __ASSERT_ALWAYS( aBuffer.MaxLength() >= 2,
+                     User::Panic( KPEngMsgPckPanic, EResetIntArrayBufLength ) );
+
+    aBuffer.Zero();
+
+    //Reset first the count
+    AppendInt32ToDesc( aBuffer, 0 ); //No entries ==> count is 0
+
+    //Then entries
+    const TInt placeCount = ( aBuffer.MaxLength() - 2 ) / 2;
+    for ( TInt ix = 0; ix < placeCount; ix++ )
+        {
+        AppendInt32ToDesc( aBuffer, KErrNotFound ); //Entries are reset to -1
+        }
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::TIntArrayCount()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt PEngMessagePacker::TIntArrayCount( const TDesC& aBuffer )
+    {
+    //Array count is stored in the start of buffer, 2 x 16bytes
+    __ASSERT_ALWAYS( aBuffer.Length() >= 2,
+                     User::Panic( KPEngMsgPckPanic, EIntArrayCountBufLength ) );
+
+
+    TInt32 count = *( TInt32* ) aBuffer.Ptr();
+    return count;
+    }
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::TIntFromArray()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt PEngMessagePacker::TIntFromArray( const TDesC& aBuffer,
+                                                TInt aIndex )
+    {
+    //Assert index range
+    __ASSERT_ALWAYS( aIndex >= 0,
+                     User::Panic( KPEngMsgPckPanic, EIntFromArrayIndexNegative ) );
+
+    __ASSERT_ALWAYS( aIndex < PEngMessagePacker::TIntArrayCount( aBuffer ),
+                     User::Panic( KPEngMsgPckPanic, EIntFromArrayIndexTooLarge ) );
+
+
+    TInt entryOffset = 2;   //array count is in the start, 2 x 16bytes
+    entryOffset += aIndex * 2;  //each entry takes 2 x 16bytes
+
+
+    TInt entryValue = *( TInt32* ) aBuffer.Mid( entryOffset ).Ptr();
+    return entryValue;
+    }
+
+
+// -----------------------------------------------------------------------------
+// PEngMessagePacker::UnpackDesTempArrayL()
+// -----------------------------------------------------------------------------
+//
+template<class T>
+TInt PEngMessagePacker::UnpackDesTempArrayL( const TDesC& aBuffer,
+                                             T& aArray )
+    {
+    TInt count ( DesArrayCount( aBuffer ) );
+    TInt desOffset( 1 ); // start with first element
+    for ( TInt x( 0 ) ; x < count ; x++ )
+        {
+        // get length of the des
+        TInt desL ( static_cast<TUint16> ( ( aBuffer[ desOffset ] ) ) );
+        // get offset to the beginning of the packed descriptor
+        desOffset++;
+        aArray.AppendL( aBuffer.Mid( desOffset, desL ) );
+        // move to length info of another packed des
+        desOffset += desL;
+        }
+
+    return count;
+    }
+
+//  End of File
+