|
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 |