srsf/vcommandhandler/src/tagcommandconverter.cpp
branchRCL_3
changeset 23 e36f3802f733
parent 0 bf1d17376201
equal deleted inserted replaced
22:cad71a31b7fc 23:e36f3802f733
       
     1 /*
       
     2 * Copyright (c) 2006 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:  Converts VCommands into tags and vise veraa
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <e32def.h>
       
    21 #include <s32mem.h>  // memory streams
       
    22 #include <vcommandapi.h>
       
    23 #include "rubydebug.h"
       
    24 #include "desarrayconverter.h"
       
    25 #include "tagcommandconverter.h"
       
    26 #include "vcommandinternalapi.h"
       
    27 
       
    28 // For CleanupResetAndDestroy
       
    29 #include <mmfcontrollerpluginresolver.h>  
       
    30 
       
    31 /** The index of the first element of the tag RRD text array, that is used to 
       
    32  * store the streamed VCommand
       
    33  */
       
    34 const TInt KStreamStartIndex = 1;
       
    35 
       
    36 /** 
       
    37  * Streamimg the VCommand might take arbitrary amount of space.
       
    38  * Every time the streaming buffer needs to be increased it grows up
       
    39  * this amount of bytes
       
    40  */
       
    41 const TInt KCommandBufferSizeExpansion = 500;
       
    42 
       
    43 /** 
       
    44 * Granularity for the returned tag array
       
    45 */ 
       
    46 const TInt KDefaultTagsPerCommand = 2;
       
    47 
       
    48 /**
       
    49 * Converts given tag to the VCommand
       
    50 * @leave KErrTotalLossOfPrecision if the aTag's intArray is empty
       
    51 */
       
    52 CStoredVCommand* CTagCommandConverter::TagToCommandLC( const MNssTag& aTag )
       
    53 	{
       
    54     MNssTag& varTag ( const_cast<MNssTag&>(aTag) );
       
    55     CArrayFixFlat<TInt>& intArray = *( varTag.RRD()->IntArray() );
       
    56     __ASSERT_ALWAYS( intArray.Count() > 0, User::Leave( KErrTotalLossOfPrecision  ) );
       
    57     
       
    58     CArrayFixFlat<NssRRDText>& tagArray = *(varTag.RRD()->TextArray());
       
    59     TDesC8* storage = CDesArrayConverter::ArrayToDesC8LC( tagArray, KStreamStartIndex, 
       
    60                             tagArray.Count() - KStreamStartIndex );
       
    61     TInt commandId = intArray[KCommandIdRrdIntIndex];
       
    62         
       
    63     RDesReadStream readStream( *storage );
       
    64     CleanupClosePushL( readStream );
       
    65     CStoredVCommand* command = CStoredVCommand::NewL( readStream, commandId );
       
    66     
       
    67     CleanupStack::PopAndDestroy( &readStream );    
       
    68     CleanupStack::PopAndDestroy( storage );
       
    69     CleanupStack::PushL( command );
       
    70     return command;
       
    71 	}
       
    72     
       
    73 /**
       
    74 * Constructs a new VAS tag from a command and a context. 
       
    75 * Does not save to VAS, just creates. Created tag stores the streamed
       
    76 * VCommand in its RRDText array. The tag's rrd int array is empty
       
    77 */
       
    78 MNssTag* CTagCommandConverter::CommandToTagLC( const CVCommand& aCommand, 
       
    79 						const MNssContext& aContext, MNssTagMgr& aTagMgr )
       
    80     {
       
    81     MNssTag* tag = aTagMgr.CreateTagL( const_cast<MNssContext*>( &aContext ) );
       
    82     CleanupDeletePushL( tag );
       
    83 
       
    84     // the first (and only) element of the rrdint array is the application uid
       
    85     // the first element of the rrdtext array is the command line arguments 
       
    86     // converted to 16 bit representation (on 16-bit systems)
       
    87     /** @todo consider removing this "simple" shortcut of saving the arguments 
       
    88      *        into the first RRD text element. This information is 
       
    89      *        anyway streamed into the other rrdtext slots
       
    90      */
       
    91     CArrayFixFlat<TInt> *theId = new (ELeave) CArrayFixFlat<TInt>( 1 );
       
    92     CleanupStack::PushL( theId );
       
    93     
       
    94     
       
    95     CBufFlat* storage = CBufFlat::NewL( KCommandBufferSizeExpansion );
       
    96     CleanupStack::PushL( storage );
       
    97     
       
    98     RBufWriteStream writeStream( *storage);
       
    99     CleanupClosePushL( writeStream );
       
   100     writeStream << aCommand;    
       
   101     CleanupStack::PopAndDestroy( &writeStream );
       
   102    
       
   103     CArrayFixFlat<NssRRDText>* streamChunks = 
       
   104                         CDesArrayConverter::DesC8ToArrayLC( storage->Ptr( 0 ) );
       
   105     // 1 for the command line args. They are saved separately
       
   106     CArrayFixFlat<NssRRDText>* theText = 
       
   107     	new (ELeave) CArrayFixFlat<NssRRDText>( streamChunks->Count() + 1 );
       
   108     CleanupStack::PushL(theText);
       
   109     
       
   110     NssRRDText bufArguments;
       
   111     // converts to 16-bits in unicode builds
       
   112     bufArguments.Copy( aCommand.Runnable().Arguments() );
       
   113     theText->AppendL( bufArguments );
       
   114         
       
   115     for( TInt i(0); i < streamChunks->Count(); i++ )
       
   116         {
       
   117         // the last piece
       
   118         theText->AppendL( streamChunks->At( i ) );
       
   119         }
       
   120     RUBY_DEBUG0( "CTagCommandConverter::CommandToTagLC Saved command to the rrd text array" );
       
   121     tag->RRD()->SetIntArrayL( theId );
       
   122     tag->RRD()->SetTextArrayL( theText );
       
   123     
       
   124     CleanupStack::PopAndDestroy( theText );
       
   125     CleanupStack::PopAndDestroy( streamChunks );
       
   126     CleanupStack::PopAndDestroy( storage );
       
   127     CleanupStack::PopAndDestroy( theId );
       
   128     
       
   129     return tag;
       
   130     }    
       
   131 
       
   132 /**
       
   133 * Converts given tags to the VCommand. This tags must have been generated
       
   134 * from a single VCommand (via CommandToTagsLC2 ) 
       
   135 * @leave KErrOverflow if given array has more, than two elements
       
   136 * @leave KErrUnderflow if given array is empty
       
   137 * @leave KErrArgument if given tags correspond to the different VCommands
       
   138 */
       
   139 CStoredVCommand* CTagCommandConverter::TagsToCommandLC( const CArrayPtr<MNssTag>& aTags )
       
   140     {
       
   141     __ASSERT_ALWAYS( aTags.Count() <= KMaxTagsPerCommand, User::Leave( KErrOverflow ) );
       
   142     __ASSERT_ALWAYS( aTags.Count() > 0, User::Leave( KErrUnderflow ) );
       
   143     CStoredVCommand* firstCommand = TagToCommandLC( *aTags[0] );
       
   144     // Comparing tags is complex. Comparing VCommands is simple
       
   145     if( aTags.Count() == KMaxTagsPerCommand )
       
   146         {
       
   147         CStoredVCommand* secondCommand = TagToCommandLC( *aTags[1] );
       
   148         if( !( *firstCommand == *secondCommand ) )
       
   149             {
       
   150             RUBY_ERROR0( "CTagCommandConverter::TagsToCommandLC firstCommand is NOT equal to second command. Leaving with KErrArgument");
       
   151             User::Leave( KErrArgument );
       
   152             }
       
   153         CleanupStack::PopAndDestroy( secondCommand );
       
   154         }
       
   155     return firstCommand;    
       
   156     }
       
   157 
       
   158 /**
       
   159 * Constructs new VAS tags from a command and a context. 
       
   160 * Does not save to VAS, just creates. At the end of this function two
       
   161 * items are pushed to the cleanup stack. The first PopAndDestroy will
       
   162 * ResetAndDestroy the generated tags, the second one will delete the
       
   163 * CArrayPtr itself
       
   164 *
       
   165 * @return array of one or two VAS tags. Two tags are created if a given 
       
   166 *         command has a UserText set. The created tags bear the identical
       
   167 *         data
       
   168 */
       
   169 CArrayPtr<MNssTag>* CTagCommandConverter::CommandToTagsLC2( const CVCommand& aCommand, 
       
   170 				const MNssContext& aContext, MNssTagMgr& aTagMgr )
       
   171     {
       
   172     CArrayPtr<MNssTag>* array = new (ELeave) CArrayPtrFlat<MNssTag>( KDefaultTagsPerCommand );
       
   173     CleanupStack::PushL( array );
       
   174     CleanupResetAndDestroyPushL( *array );
       
   175     
       
   176     MNssTag* firstTag = CommandToTagLC( aCommand, aContext, aTagMgr );
       
   177     array->AppendL( firstTag );
       
   178     CleanupStack::Pop( firstTag );
       
   179     if( aCommand.AlternativeSpokenText() != KNullDesC )
       
   180         {
       
   181         // Second tag is needed
       
   182         MNssTag* secondTag = CommandToTagLC( aCommand, aContext, aTagMgr );
       
   183         array->AppendL( secondTag );
       
   184         CleanupStack::Pop( secondTag );
       
   185         }
       
   186     return array;    
       
   187     }
       
   188 
       
   189 //End of file