PECengine/CoreUtilsLib2/SrvSrc/PEngMessagePacker.cpp
changeset 0 094583676ce7
equal deleted inserted replaced
-1:000000000000 0:094583676ce7
       
     1 /*
       
     2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Collection of tools used to pack and unpack
       
    15 *                data transferred over IPC.
       
    16 *
       
    17 */
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <E32Std.h>
       
    21 #include "PEngMessagePacker.h"
       
    22 
       
    23 
       
    24 _LIT( KPEngMsgPckPanic, "PEngMsgPckr" );
       
    25 enum TPEngMsgPckPanicReason
       
    26     {
       
    27     EResetIntArrayBufLength,
       
    28     EIntArrayCountBufLength,
       
    29     EIntFromArrayIndexNegative,
       
    30     EIntFromArrayIndexTooLarge
       
    31     };
       
    32 
       
    33 
       
    34 // ====================== MEMBER FUNCTIONS ======================================
       
    35 
       
    36 // =============================================================================
       
    37 // ===================== DESCRIPTOR ARRAY PACKING ==============================
       
    38 // =============================================================================
       
    39 
       
    40 
       
    41 // -----------------------------------------------------------------------------
       
    42 // PEngMessagePacker::DesArrayPackageSize()
       
    43 // -----------------------------------------------------------------------------
       
    44 //
       
    45 EXPORT_C TInt PEngMessagePacker::DesArrayPackageSize( const MDesCArray& aDesArray )
       
    46     {
       
    47     TInt count ( aDesArray.MdcaCount() );
       
    48     TInt len( count + 1 ); // once more count on the begining of buf
       
    49     for ( TInt x( 0 ) ; x < count ; x++ )
       
    50         {
       
    51         len += aDesArray.MdcaPoint( x ).Length();
       
    52         }
       
    53 
       
    54     return len;
       
    55     }
       
    56 
       
    57 
       
    58 // -----------------------------------------------------------------------------
       
    59 // PEngMessagePacker::DesArrayPackageSize()
       
    60 // -----------------------------------------------------------------------------
       
    61 //
       
    62 EXPORT_C TInt PEngMessagePacker::DesArrayPackageSize( const TDesC& aDesAsArray )
       
    63     {
       
    64     return aDesAsArray.Length() + 2; // length and cout
       
    65     }
       
    66 
       
    67 
       
    68 // -----------------------------------------------------------------------------
       
    69 // PEngMessagePacker::PackDesArrayL()
       
    70 // -----------------------------------------------------------------------------
       
    71 //
       
    72 EXPORT_C HBufC16* PEngMessagePacker::PackDesArrayL( const MDesCArray& aDesArray )
       
    73     {
       
    74     HBufC16* desBuffer = HBufC16::NewL( DesArrayPackageSize( aDesArray ) );
       
    75     TPtr des = desBuffer->Des();
       
    76     TInt count ( aDesArray.MdcaCount() );
       
    77     des.Append( ( TUint16* ) &count, 1 );
       
    78     for ( TInt x( 0 ) ; x < count ; x++ )
       
    79         {
       
    80         TPtrC element( aDesArray.MdcaPoint( x ) );
       
    81         TInt length( element.Length() );
       
    82         des.Append( reinterpret_cast<TUint16*> ( &length ), 1 );
       
    83         des.Append( element );
       
    84         }
       
    85 
       
    86     return desBuffer;
       
    87     }
       
    88 
       
    89 
       
    90 // -----------------------------------------------------------------------------
       
    91 // PEngMessagePacker::PackDesArray()
       
    92 // -----------------------------------------------------------------------------
       
    93 //
       
    94 EXPORT_C TInt PEngMessagePacker::PackDesArray( TDes& aBuffer,
       
    95                                                const MDesCArray& aDesArray )
       
    96     {
       
    97     aBuffer.Zero();
       
    98     if ( aBuffer.MaxLength() < DesArrayPackageSize( aDesArray ) )
       
    99         {
       
   100         return KErrArgument;
       
   101         }
       
   102 
       
   103     TInt count ( aDesArray.MdcaCount() );
       
   104     aBuffer.Append( reinterpret_cast<TUint16*> ( &count ), 1 );
       
   105     for ( TInt x( 0 ) ; x < count ; x++ )
       
   106         {
       
   107         TPtrC element( aDesArray.MdcaPoint( x ) );
       
   108         TInt length( element.Length() );
       
   109         aBuffer.Append( reinterpret_cast<TUint16*> ( &length ), 1 );
       
   110         aBuffer.Append( element );
       
   111         }
       
   112 
       
   113 
       
   114     return KErrNone;
       
   115     }
       
   116 
       
   117 
       
   118 // -----------------------------------------------------------------------------
       
   119 // PEngMessagePacker::PackOneDesAsArrayL()
       
   120 // -----------------------------------------------------------------------------
       
   121 //
       
   122 EXPORT_C HBufC16* PEngMessagePacker::PackOneDesAsArrayL( const TDesC& aDes )
       
   123     {
       
   124     HBufC16* desBuffer = HBufC16::NewL( aDes.Length() + 2 ); // count and size
       
   125     TPtr des = desBuffer->Des();
       
   126     TInt count( 1 ); //Only one descriptor is packed
       
   127     des.Append( reinterpret_cast<TUint16*> ( &count ), 1 );
       
   128     TInt length( aDes.Length() );
       
   129     des.Append( reinterpret_cast<TUint16*> ( &length ), 1 );
       
   130     des.Append( aDes );
       
   131     return desBuffer;
       
   132     }
       
   133 
       
   134 
       
   135 // -----------------------------------------------------------------------------
       
   136 // PEngMessagePacker::PackOneDesAsArray()
       
   137 // -----------------------------------------------------------------------------
       
   138 //
       
   139 EXPORT_C TInt PEngMessagePacker::PackOneDesAsArray( TDes& aBuffer,
       
   140                                                     const TDesC& aDes )
       
   141     {
       
   142     aBuffer.Zero();
       
   143     if ( aBuffer.MaxLength() < ( aDes.Length() + 2 ) ) // count and size
       
   144         {
       
   145         return KErrArgument;
       
   146         }
       
   147 
       
   148     TInt count( 1 );
       
   149     aBuffer.Append( reinterpret_cast<TUint16*> ( &count ), 1 );
       
   150     TInt length( aDes.Length() );
       
   151     aBuffer.Append( reinterpret_cast<TUint16*> ( &length ), 1 );
       
   152     aBuffer.Append( aDes );
       
   153     return KErrNone;
       
   154     }
       
   155 
       
   156 
       
   157 // -----------------------------------------------------------------------------
       
   158 // PEngMessagePacker::AppendToDesArray()
       
   159 // -----------------------------------------------------------------------------
       
   160 //
       
   161 EXPORT_C TInt PEngMessagePacker::AppendToDesArray( TDes& aBuffer,
       
   162                                                    const TDesC& aDes )
       
   163     {
       
   164     // is anything in the array?
       
   165     TInt count( 0 ); // if array will be empty
       
   166     if ( aBuffer.Length() == 0 )
       
   167         {
       
   168         // first element appent count first
       
   169         aBuffer.Append( reinterpret_cast<TUint16*> ( &count ), 1 );
       
   170         }
       
   171 
       
   172     // check space
       
   173     if ( ( aBuffer.Length() + aDes.Length() + 1 ) > aBuffer.MaxLength() )
       
   174         {
       
   175         return KErrBadDescriptor;
       
   176         }
       
   177 
       
   178     TInt length( aDes.Length() );
       
   179     aBuffer.Append( reinterpret_cast<TUint16*> ( &length ), 1 );
       
   180     aBuffer.Append( aDes );
       
   181 
       
   182     //  update count
       
   183     count = ( TInt ) ( aBuffer[ 0 ] ); // count is first
       
   184     count++;
       
   185     aBuffer[ 0 ] = static_cast<TUint16> ( count );
       
   186     return KErrNone;
       
   187     }
       
   188 
       
   189 
       
   190 
       
   191 
       
   192 // =============================================================================
       
   193 // =================== DESCRIPTOR ARRAY EXTRACTING =============================
       
   194 // =============================================================================
       
   195 
       
   196 
       
   197 // -----------------------------------------------------------------------------
       
   198 // PEngMessagePacker::DesArrayCount()
       
   199 // -----------------------------------------------------------------------------
       
   200 //
       
   201 EXPORT_C TInt PEngMessagePacker::DesArrayCount( const TDesC& aBuffer )
       
   202     {
       
   203     if ( aBuffer.Length() == 0 )
       
   204         {
       
   205         return 0; // des is empty
       
   206         }
       
   207 
       
   208     return ( TInt ) ( aBuffer[ 0 ] );
       
   209     }
       
   210 
       
   211 
       
   212 // -----------------------------------------------------------------------------
       
   213 // PEngMessagePacker::UnpackDesArrayL()
       
   214 // -----------------------------------------------------------------------------
       
   215 //
       
   216 EXPORT_C TInt PEngMessagePacker::UnpackDesArrayL( const TDesC& aBuffer,
       
   217                                                   CDesCArray& aArray )
       
   218     {
       
   219     return UnpackDesTempArrayL( aBuffer, aArray );
       
   220     }
       
   221 
       
   222 // -----------------------------------------------------------------------------
       
   223 // PEngMessagePacker::UnpackDesArrayL()
       
   224 // -----------------------------------------------------------------------------
       
   225 //
       
   226 EXPORT_C TInt PEngMessagePacker::UnpackDesArrayL( const TDesC& aBuffer,
       
   227                                                   CPtrCArray& aArray )
       
   228     {
       
   229     return UnpackDesTempArrayL( aBuffer, aArray );
       
   230     }
       
   231 
       
   232 // -----------------------------------------------------------------------------
       
   233 // PEngMessagePacker::UnpackDesArrayLC()
       
   234 // -----------------------------------------------------------------------------
       
   235 //
       
   236 EXPORT_C CDesCArray* PEngMessagePacker::UnpackDesArrayLC( const TDesC& aBuffer )
       
   237     {
       
   238     TInt count ( DesArrayCount( aBuffer ) );
       
   239     CDesC16ArrayFlat* desArray = new( ELeave ) CDesC16ArrayFlat( ++count );
       
   240     CleanupStack::PushL( desArray );
       
   241     UnpackDesArrayL( aBuffer, *desArray );
       
   242     return desArray;
       
   243     }
       
   244 
       
   245 
       
   246 // -----------------------------------------------------------------------------
       
   247 // PEngMessagePacker::UnpackFirstDesFromArrayL()
       
   248 // -----------------------------------------------------------------------------
       
   249 //
       
   250 EXPORT_C HBufC* PEngMessagePacker::UnpackFirstDesFromArrayL( const TDesC& aBuffer )
       
   251     {
       
   252     // Ignore count, read length of des
       
   253     TInt desL ( ( TInt ) ( aBuffer[1] ) ); // first was count
       
   254 
       
   255     // First two are info about count and length
       
   256     // Returns buffer ownership to caller
       
   257     return aBuffer.Mid( 2, desL ).AllocL();
       
   258     }
       
   259 
       
   260 
       
   261 
       
   262 // =============================================================================
       
   263 // ===================== INTEGER ARRAY HANDLING ================================
       
   264 // =============================================================================
       
   265 
       
   266 
       
   267 // -----------------------------------------------------------------------------
       
   268 // AppendInt32ToDesc()
       
   269 // -----------------------------------------------------------------------------
       
   270 //
       
   271 void AppendInt32ToDesc( TDes& aBuffer, TInt32 aValue )
       
   272     {
       
   273     aBuffer.Append( ( TUint16* ) &aValue, 2 );  //TInt32 ==> 2 x 16bytes
       
   274     }
       
   275 
       
   276 
       
   277 // -----------------------------------------------------------------------------
       
   278 // PEngMessagePacker::TIntArrayPackageSize()
       
   279 // -----------------------------------------------------------------------------
       
   280 //
       
   281 EXPORT_C TInt PEngMessagePacker::TIntArrayPackageSize( TInt aElementCount )
       
   282     {
       
   283     TInt size = 2; //array count is stored to 32 bit ==> 2 x 16bytes
       
   284     size += aElementCount * 2;  //each array element takes 2 x 16bytes
       
   285     return size;
       
   286     }
       
   287 
       
   288 
       
   289 // -----------------------------------------------------------------------------
       
   290 // PEngMessagePacker::PackTIntArrayL()
       
   291 // -----------------------------------------------------------------------------
       
   292 //
       
   293 EXPORT_C HBufC16* PEngMessagePacker::PackTIntArrayL( const RArray<TInt>& aTIntArray )
       
   294     {
       
   295     TInt packSize = PEngMessagePacker::TIntArrayPackageSize( aTIntArray.Count() );
       
   296     HBufC* packBuf = HBufC::NewL( packSize );
       
   297     TPtr pack = packBuf->Des();
       
   298 
       
   299     //Add first the count
       
   300     TInt32 count( aTIntArray.Count() );
       
   301     AppendInt32ToDesc( pack, count );
       
   302 
       
   303 
       
   304     //Then entries
       
   305     for ( TInt ix( 0 ) ; ix < count ; ix++ )
       
   306         {
       
   307         TInt32 intValue = aTIntArray[ ix ];
       
   308         AppendInt32ToDesc( pack, intValue );
       
   309         }
       
   310 
       
   311 
       
   312     return packBuf;
       
   313     }
       
   314 
       
   315 
       
   316 // -----------------------------------------------------------------------------
       
   317 // PEngMessagePacker::ResetTIntArray()
       
   318 // -----------------------------------------------------------------------------
       
   319 //
       
   320 EXPORT_C void PEngMessagePacker::ResetTIntArray( TDes& aBuffer )
       
   321     {
       
   322     __ASSERT_ALWAYS( aBuffer.MaxLength() >= 2,
       
   323                      User::Panic( KPEngMsgPckPanic, EResetIntArrayBufLength ) );
       
   324 
       
   325     aBuffer.Zero();
       
   326 
       
   327     //Reset first the count
       
   328     AppendInt32ToDesc( aBuffer, 0 ); //No entries ==> count is 0
       
   329 
       
   330     //Then entries
       
   331     const TInt placeCount = ( aBuffer.MaxLength() - 2 ) / 2;
       
   332     for ( TInt ix = 0; ix < placeCount; ix++ )
       
   333         {
       
   334         AppendInt32ToDesc( aBuffer, KErrNotFound ); //Entries are reset to -1
       
   335         }
       
   336     }
       
   337 
       
   338 
       
   339 
       
   340 // -----------------------------------------------------------------------------
       
   341 // PEngMessagePacker::TIntArrayCount()
       
   342 // -----------------------------------------------------------------------------
       
   343 //
       
   344 EXPORT_C TInt PEngMessagePacker::TIntArrayCount( const TDesC& aBuffer )
       
   345     {
       
   346     //Array count is stored in the start of buffer, 2 x 16bytes
       
   347     __ASSERT_ALWAYS( aBuffer.Length() >= 2,
       
   348                      User::Panic( KPEngMsgPckPanic, EIntArrayCountBufLength ) );
       
   349 
       
   350 
       
   351     TInt32 count = *( TInt32* ) aBuffer.Ptr();
       
   352     return count;
       
   353     }
       
   354 
       
   355 // -----------------------------------------------------------------------------
       
   356 // PEngMessagePacker::TIntFromArray()
       
   357 // -----------------------------------------------------------------------------
       
   358 //
       
   359 EXPORT_C TInt PEngMessagePacker::TIntFromArray( const TDesC& aBuffer,
       
   360                                                 TInt aIndex )
       
   361     {
       
   362     //Assert index range
       
   363     __ASSERT_ALWAYS( aIndex >= 0,
       
   364                      User::Panic( KPEngMsgPckPanic, EIntFromArrayIndexNegative ) );
       
   365 
       
   366     __ASSERT_ALWAYS( aIndex < PEngMessagePacker::TIntArrayCount( aBuffer ),
       
   367                      User::Panic( KPEngMsgPckPanic, EIntFromArrayIndexTooLarge ) );
       
   368 
       
   369 
       
   370     TInt entryOffset = 2;   //array count is in the start, 2 x 16bytes
       
   371     entryOffset += aIndex * 2;  //each entry takes 2 x 16bytes
       
   372 
       
   373 
       
   374     TInt entryValue = *( TInt32* ) aBuffer.Mid( entryOffset ).Ptr();
       
   375     return entryValue;
       
   376     }
       
   377 
       
   378 
       
   379 // -----------------------------------------------------------------------------
       
   380 // PEngMessagePacker::UnpackDesTempArrayL()
       
   381 // -----------------------------------------------------------------------------
       
   382 //
       
   383 template<class T>
       
   384 TInt PEngMessagePacker::UnpackDesTempArrayL( const TDesC& aBuffer,
       
   385                                              T& aArray )
       
   386     {
       
   387     TInt count ( DesArrayCount( aBuffer ) );
       
   388     TInt desOffset( 1 ); // start with first element
       
   389     for ( TInt x( 0 ) ; x < count ; x++ )
       
   390         {
       
   391         // get length of the des
       
   392         TInt desL ( static_cast<TUint16> ( ( aBuffer[ desOffset ] ) ) );
       
   393         // get offset to the beginning of the packed descriptor
       
   394         desOffset++;
       
   395         aArray.AppendL( aBuffer.Mid( desOffset, desL ) );
       
   396         // move to length info of another packed des
       
   397         desOffset += desL;
       
   398         }
       
   399 
       
   400     return count;
       
   401     }
       
   402 
       
   403 //  End of File
       
   404