|
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "clientmessagecmn.h" |
|
17 |
|
18 using namespace BSUL; |
|
19 |
|
20 /** |
|
21 Base 64 decoding table |
|
22 */ |
|
23 const TInt8 AsciiToBase64[80]= |
|
24 { |
|
25 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, |
|
26 57, 58, 59, 60, 61, -1, -1, -1, 64, -1, |
|
27 -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, |
|
28 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, |
|
29 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, |
|
30 -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, |
|
31 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, |
|
32 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 |
|
33 }; |
|
34 |
|
35 /** |
|
36 Base 64 encoding table |
|
37 */ |
|
38 const TInt8 Base64ToAscii[65]= |
|
39 { |
|
40 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, |
|
41 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, |
|
42 85, 86, 87, 88, 89, 90, 97, 98, 99,100, |
|
43 101,102,103,104,105,106,107,108,109,110, |
|
44 111,112,113,114,115,116,117,118,119,120, |
|
45 121,122, 48, 49, 50, 51, 52, 53, 54, 55, |
|
46 56, 57, 43, 47, 61 |
|
47 }; |
|
48 |
|
49 const TInt8 KImcvLookUpStartOffset = 43; |
|
50 const TUint8 KImcvConvEquals = '='; |
|
51 /** |
|
52 The maximum number of US ASCII characters per line that are before the CRLF line |
|
53 terminator when sending emails. RFC 2822 recommends that each line SHOULD not exceed |
|
54 80 characters including the CRLF terminator, and MUST not exceed 1000. |
|
55 */ |
|
56 const TInt KMaxB64EncodedCharsPerLine = 60; // Could be increased to 75 characters for every encoded line if KDecodeLineLength = 675. 60 was chosen to maintain existing behaviour. |
|
57 |
|
58 /** |
|
59 Parameter factory function lookup table. This is used to instantiate a |
|
60 CMessageParameterBase derived object based on a TParamType enum value |
|
61 */ |
|
62 const TMessageParameterFactoryFn KParameterFactoryFunctions[] = {NULL, |
|
63 CIntParameter::NewL, |
|
64 CDes8ReadParameter::NewL, |
|
65 CDes8Parameter::NewL, |
|
66 CPckgParameter::NewL, |
|
67 CDes16ReadParameter::NewL, |
|
68 CDes16Parameter::NewL, |
|
69 CPtrParameter::NewL}; |
|
70 |
|
71 /** |
|
72 Panic string for client message framework panic |
|
73 */ |
|
74 #ifdef _DEBUG |
|
75 _LIT(KPanicCategory,"BSUL::ClientMsg"); |
|
76 #endif |
|
77 |
|
78 const TInt KMaxServerNameLength = 32; |
|
79 |
|
80 /** |
|
81 This static function is used to panic the server in case of |
|
82 incorrect use of CMessageParameterBase APIs or a badly formed |
|
83 message schema |
|
84 @param aPanic The Panic value |
|
85 */ |
|
86 void PanicServer(TInt aPanic) |
|
87 { |
|
88 _LIT(KUnknownServer, "Unknown"); |
|
89 TBuf<KMaxServerNameLength> serverName(KUnknownServer); |
|
90 |
|
91 //Get the TLS data for this thread |
|
92 TClientMessageServerData* serverData = static_cast<TClientMessageServerData*>(Dll::Tls()); |
|
93 |
|
94 if(serverData != NULL) |
|
95 { |
|
96 TPtrC8 name(serverData->iServerName); |
|
97 serverName.Copy(name); |
|
98 } |
|
99 |
|
100 User::Panic(serverName, aPanic); |
|
101 } |
|
102 |
|
103 /** |
|
104 Static initialisation function for ClientMessage Framework |
|
105 @param aServerData The initialisation data for the server using the library |
|
106 @leave Any system wide error code |
|
107 */ |
|
108 EXPORT_C void CClientMessage::InitialiseFrameworkL(const TClientMessageServerData& aServerData) |
|
109 { |
|
110 __ASSERT_DEBUG(User::StringLength(aServerData.iServerName) <= KMaxServerNameLength, User::Invariant()); |
|
111 Dll::SetTls((TAny*)&aServerData); |
|
112 } |
|
113 |
|
114 /** |
|
115 Static factory function for CClientMessage class |
|
116 @param aMessage The message that this object encapsulates |
|
117 @return Pointer to a fully constructed CClientMessage object. |
|
118 @leave KErrNotInitialised if the framework has not been initialised by a |
|
119 call to InitialiseFrameworkL. |
|
120 */ |
|
121 EXPORT_C CClientMessage* CClientMessage::NewL(const RMessage2& aMessage) |
|
122 { |
|
123 const TClientMessageServerData* serverData = static_cast<const TClientMessageServerData*>(Dll::Tls()); |
|
124 if(serverData == NULL) |
|
125 { |
|
126 User::Leave(KErrNotInitialised); |
|
127 } |
|
128 |
|
129 CClientMessage* self = new(ELeave) CClientMessage(aMessage,*serverData); |
|
130 CleanupStack::PushL(self); |
|
131 self->ConstructL(); |
|
132 CleanupStack::Pop(self); |
|
133 |
|
134 return self; |
|
135 } |
|
136 |
|
137 |
|
138 /** |
|
139 Second phase constructor of CClientMessage Object |
|
140 Finds the schema for this message and checks the caller against the security |
|
141 policy defined for this message. Traverses the array of message parameters |
|
142 and instantiates a CMessageParameterBase object for each parameter and adds these |
|
143 to its internal array. |
|
144 @leave KErrInvalidFunction If the message function is not found in the message table |
|
145 @leave KErrBadHandle if the message handle is Null |
|
146 @leave KErrPermissionDenied if the security policy for this message is not satisfied |
|
147 */ |
|
148 void CClientMessage::ConstructL() |
|
149 { |
|
150 if(!iMessage.IsNull()) |
|
151 { |
|
152 |
|
153 //Find the message schema for this message. |
|
154 const TClientMessageSchema* messageSchema = FindMessageSchema(); |
|
155 |
|
156 if(!messageSchema) |
|
157 { |
|
158 LogBadMessageL(KErrInvalidFunction); |
|
159 User::Leave(KErrInvalidFunction); |
|
160 } |
|
161 |
|
162 //Check message against security policy |
|
163 CheckSecurityPolicyL(messageSchema->iPolicy); |
|
164 |
|
165 //iterate through message parameters and instantiate all parameter objects |
|
166 for(int index = 0;index < messageSchema->iParamCount;index++) |
|
167 { |
|
168 CMessageParameterBase* parameter = |
|
169 CMessageParameterBase::CreateL(messageSchema->iParams[index], index, iMessage); |
|
170 |
|
171 //Some parameter types are defined to be ignored. These |
|
172 //should not be added to the list of parameters |
|
173 if(parameter != NULL) |
|
174 { |
|
175 //AppendL can leave so use cleanupstack to ensure that memory is not |
|
176 //leaked if AppendL leaves. |
|
177 CleanupStack::PushL(parameter); |
|
178 iParameters.AppendL(parameter); |
|
179 CleanupStack::Pop(parameter); |
|
180 } |
|
181 } |
|
182 } |
|
183 else |
|
184 { |
|
185 LogBadMessageL(KErrBadHandle); |
|
186 User::Leave(KErrBadHandle); |
|
187 } |
|
188 } |
|
189 |
|
190 /** |
|
191 Constructor for CClientMessage Object |
|
192 @param aMessage The RMessage2 to be represented by this object |
|
193 @param aServerData The Initialisation data for the server creating this object |
|
194 */ |
|
195 EXPORT_C CClientMessage::CClientMessage(const RMessage2& aMessage, |
|
196 const TClientMessageServerData& aServerData) |
|
197 : iParameters(KMaxParameters), iMessage(aMessage), |
|
198 iServerData(aServerData),iFlags(aServerData.iFlags & 0xFFFF0000) |
|
199 |
|
200 { |
|
201 |
|
202 } |
|
203 |
|
204 /** |
|
205 Destructor for CClientMessageObject |
|
206 */ |
|
207 EXPORT_C CClientMessage::~CClientMessage() |
|
208 { |
|
209 for(int i = 0; i < iParameters.Count();i++) |
|
210 { |
|
211 delete iParameters[i]; |
|
212 } |
|
213 iParameters.Reset(); |
|
214 } |
|
215 |
|
216 EXPORT_C const RMessage2& CClientMessage::Message() |
|
217 { |
|
218 return iMessage; |
|
219 } |
|
220 |
|
221 /** |
|
222 Panics the client through the message object |
|
223 set an internal flag to indicate that the RMessage reference handle is now NULL |
|
224 due to the client thread being tidied up. |
|
225 @param aServer The Panic category |
|
226 @param aPanic The Panic value |
|
227 */ |
|
228 EXPORT_C void CClientMessage::PanicClient(const TDesC& aServer, TInt aPanic) |
|
229 { |
|
230 iMessage.Panic(aServer, aPanic); |
|
231 iFlags.Set(EFlagPanicClient); |
|
232 } |
|
233 |
|
234 /** |
|
235 Checks a message against the security policy defined for the server |
|
236 @param aPolicy The security policy to check this message against |
|
237 @leave KErrPermissionDenied if the message does not fulfil the security policy |
|
238 */ |
|
239 void CClientMessage::CheckSecurityPolicyL(const TSecurityPolicy& aPolicy) |
|
240 { |
|
241 if(!(aPolicy.CheckPolicy(iMessage, |
|
242 "Client failed security policy check for this server"))) |
|
243 { |
|
244 User::Leave(KErrPermissionDenied); |
|
245 } |
|
246 return; |
|
247 } |
|
248 |
|
249 /** |
|
250 Finds a message schema in the message table for this server. |
|
251 Does a binary search on the function number to pull the correct |
|
252 message from the table. Note that this assumes that the table |
|
253 is sorted. |
|
254 @return A pointer to a TClientMessageSchema object in the message table, or Null if |
|
255 the message does not correpsond to a message in the message table |
|
256 */ |
|
257 const TClientMessageSchema* CClientMessage::FindMessageSchema() |
|
258 { |
|
259 //This should always be less than KNumClientMessages |
|
260 TInt function = iMessage.Function(); |
|
261 TInt beg = 0; |
|
262 TInt end = iServerData.iMessageCount - 1; |
|
263 TInt mid = 0; |
|
264 TInt midFn = 0; |
|
265 |
|
266 while(beg <= end) |
|
267 { |
|
268 mid = (end + beg)/2; |
|
269 |
|
270 midFn = iServerData.iMessageSchema[mid].iFunction; |
|
271 if(midFn > function) |
|
272 { |
|
273 end = mid - 1; |
|
274 } |
|
275 else if(midFn < function) |
|
276 { |
|
277 beg = mid + 1; |
|
278 } |
|
279 else |
|
280 { |
|
281 return &iServerData.iMessageSchema[mid]; |
|
282 } |
|
283 } |
|
284 return NULL; |
|
285 } |
|
286 |
|
287 |
|
288 |
|
289 |
|
290 /** |
|
291 Validates the message parameters against the constraints provided |
|
292 in the message table |
|
293 @leave KErrBadMessage if the message fails validation against the criteria supplied in the |
|
294 message table |
|
295 @leave Any system-wide error code |
|
296 */ |
|
297 EXPORT_C void CClientMessage::ValidateL() |
|
298 { |
|
299 |
|
300 for(int i = 0; i < iParameters.Count();i++) |
|
301 { |
|
302 iParameters[i]->ValidateL(); |
|
303 iFlags.Set(i); |
|
304 } |
|
305 } |
|
306 |
|
307 /** |
|
308 Validates a single message argument against the constraints provided |
|
309 in the message table |
|
310 @param aParam The index value identifying the argument to validate |
|
311 @leave KErrBadMessage if the message fails validation against the criteria supplied in the |
|
312 message table for the requested argument |
|
313 @leave KErrArgument if aParam is negative or is greater than the number of parameters for |
|
314 this message |
|
315 @leave Any system-wide error code |
|
316 */ |
|
317 EXPORT_C void CClientMessage::ValidateL(TInt aParam) |
|
318 { |
|
319 |
|
320 if(( aParam >= 0) && (aParam < iParameters.Count())) |
|
321 { |
|
322 iParameters[aParam]->ValidateL(); |
|
323 iFlags.Set(aParam); |
|
324 } |
|
325 else |
|
326 { |
|
327 User::Leave(KErrArgument); |
|
328 } |
|
329 } |
|
330 |
|
331 /** |
|
332 Checks if a given parameter has been validated |
|
333 @param aParam The index value identifying the paramater to check |
|
334 @leave KErrArgument if aParam is not a valid parameter value |
|
335 @leave KErrNotValidated if the parameter has not been validated |
|
336 */ |
|
337 void CClientMessage::CheckValidatedL(TInt aParam) |
|
338 { |
|
339 if((aParam < EFlagParam0Validated) || (aParam > EFlagParam3Validated)) |
|
340 { |
|
341 User::Leave(KErrArgument); |
|
342 } |
|
343 |
|
344 if(!iFlags.IsSet(aParam)) |
|
345 { |
|
346 User::Leave(KErrNotValidated); |
|
347 } |
|
348 } |
|
349 |
|
350 |
|
351 /** |
|
352 Checks if a bad messages should be logged |
|
353 @return True if bad messages should be logged |
|
354 */ |
|
355 TBool CClientMessage::LogBadMessages() |
|
356 { |
|
357 return iFlags.IsSet(EFlagLogBadMessages); |
|
358 } |
|
359 |
|
360 /** |
|
361 Checks if a bad messages should be logged |
|
362 @param aError The error code to log |
|
363 */ |
|
364 void CClientMessage::LogBadMessageL(TInt aError) |
|
365 { |
|
366 //Check if logging of bad messages is enabled |
|
367 if(LogBadMessages()) |
|
368 { |
|
369 |
|
370 TUid sid = TUid(iMessage.SecureId()); |
|
371 TUidName clientSid = sid.Name(); |
|
372 |
|
373 TInt function = Function(); |
|
374 |
|
375 TBuf<KMaxServerNameLength> serverName; |
|
376 TPtrC8 name(iServerData.iServerName); |
|
377 serverName.Copy(name); |
|
378 |
|
379 switch(aError) |
|
380 { |
|
381 #ifdef _DEBUG |
|
382 |
|
383 |
|
384 case KErrInvalidFunction: |
|
385 RDebug::Print(_L("%S - CClientMessage Error: %d, Function %d. Unknown function request from client %S.\n"), |
|
386 &serverName,aError,function, &clientSid); |
|
387 break; |
|
388 |
|
389 case KErrBadParameter: |
|
390 RDebug::Print(_L("%S - CClientMessage Error: %d, Function %d. Bad argument in IPC request from client %S.\n"), |
|
391 &serverName,aError,function, &clientSid); |
|
392 break; |
|
393 |
|
394 case KErrBadMessageSchema: |
|
395 RDebug::Print(_L("%S - CClientMessage Error: %d, Function %d. Message schema incotrectly defined for this function %S.\n"), |
|
396 &serverName,aError,function, &clientSid); |
|
397 break; |
|
398 |
|
399 case KErrBadDescriptor: |
|
400 case KErrOverflow: |
|
401 RDebug::Print(_L("%S - CClientMessage Error: %d, Function %d. Bad descriptor argument in IPC request from client %S.\n"), |
|
402 &serverName,aError,function, &clientSid); |
|
403 break; |
|
404 |
|
405 case KErrNotValidated: |
|
406 RDebug::Print(_L("%S - CClientMessage Error: %d, Function %d. Message parameter not validated before use %S.\n"), |
|
407 &serverName,aError,function, &clientSid); |
|
408 break; |
|
409 |
|
410 default: |
|
411 RDebug::Print(_L("%S - CClientMessage Error: %d, Function %d. Bad message received from client %S.\n"), |
|
412 &serverName,aError,function, &clientSid); |
|
413 break; |
|
414 #else |
|
415 default: |
|
416 break; |
|
417 #endif |
|
418 } |
|
419 } |
|
420 |
|
421 |
|
422 } |
|
423 |
|
424 /** |
|
425 Completes the message request or Panics the client if a |
|
426 message error has occured. |
|
427 @param aError The error value to complete the message with |
|
428 */ |
|
429 EXPORT_C void CClientMessage::CompleteRequestL(TInt aError) |
|
430 { |
|
431 //If server panics client |
|
432 //then iMessage will be NULL |
|
433 if(!iFlags.IsSet(EFlagPanicClient)) |
|
434 { |
|
435 if(aError != KErrNone) |
|
436 { |
|
437 LogBadMessageL(aError); |
|
438 } |
|
439 |
|
440 switch(aError) |
|
441 { |
|
442 case KErrInvalidFunction: |
|
443 case KErrBadDescriptor: |
|
444 case KErrOverflow: |
|
445 { |
|
446 //Check if Panic is disabled |
|
447 if( iFlags.IsClear(EFlagDoNotPanicClientOnBadMessageErrors) ) |
|
448 { |
|
449 TBuf<KMaxServerNameLength> serverName; |
|
450 TPtrC8 name(iServerData.iServerName); |
|
451 serverName.Copy(name); |
|
452 PanicClient(serverName, aError); |
|
453 break; |
|
454 } |
|
455 } |
|
456 default: |
|
457 { |
|
458 iMessage.Complete(aError); |
|
459 break; |
|
460 } |
|
461 }//switch |
|
462 |
|
463 }//if |
|
464 } |
|
465 |
|
466 /** |
|
467 Gets the function number of this message |
|
468 @return The function number of this message |
|
469 */ |
|
470 EXPORT_C TInt CClientMessage::Function() |
|
471 { |
|
472 return iMessage.Function(); |
|
473 } |
|
474 |
|
475 /** |
|
476 Gets the requested message argument as an integer value |
|
477 @param aParam The parameter number to retrieve |
|
478 @return The Int value for the requested parameter |
|
479 @leave KErrNotValidated if the message parameter has not been validated |
|
480 KErrWrongParameterType in UREL is the parameter requested is not an integer type |
|
481 Any other system wide error code |
|
482 @panic ECMPanicWrongParameterType If this function is called for a parameter |
|
483 type that is not CIntParameter. |
|
484 */ |
|
485 EXPORT_C TInt CClientMessage::GetIntL(TInt aParam) |
|
486 { |
|
487 CheckValidatedL(aParam); |
|
488 |
|
489 return iParameters[aParam]->GetIntL(); |
|
490 } |
|
491 |
|
492 /** |
|
493 Gets the requested message argument as an TAny* |
|
494 @param aParam The parameter number to retrieve |
|
495 @return The TAny* for the requested parameter |
|
496 @leave KErrNotValidated if the message parameter has not been validated |
|
497 KErrWrongParameterType in UREL is the parameter requested is not an Ptr type |
|
498 Any other system wide error code |
|
499 @panic ECMPanicWrongParameterType If this function is called for a parameter |
|
500 type that is not CPtrParameter. |
|
501 */ |
|
502 EXPORT_C const TAny* CClientMessage::GetPtrL(TInt aParam) |
|
503 { |
|
504 CheckValidatedL(aParam); |
|
505 |
|
506 return iParameters[aParam]->GetPtrL(); |
|
507 } |
|
508 |
|
509 /** |
|
510 Gets a reference to the local copy of the descriptor read from the message |
|
511 @param aParam The parameter number of the descriptor to retrieve |
|
512 @leave KErrNotValidated if the message parameter has not been validated |
|
513 KErrWrongParameterType in UREL is the parameter requested is not a readable |
|
514 TDes8 type |
|
515 Any other system wide error code |
|
516 @panic ECMPanicWrongParameterType If this function is called for a parameter |
|
517 type that is not CDes8ReadParameter. |
|
518 */ |
|
519 EXPORT_C const TDesC8& CClientMessage::GetDes8L(TInt aParam) |
|
520 { |
|
521 CheckValidatedL(aParam); |
|
522 |
|
523 return iParameters[aParam]->GetDes8L(); |
|
524 } |
|
525 |
|
526 /** |
|
527 Gets a reference to the local copy of the descriptor read from the message |
|
528 @param aParam The parameter number of the descriptor to retrieve |
|
529 @leave KErrNotValidated if the message parameter has not been validated |
|
530 KErrWrongParameterType in UREL is the parameter requested is not a readable |
|
531 TDes16 type |
|
532 Any other system wide error code |
|
533 @panic ECMPanicWrongParameterType If this function is called for a parameter |
|
534 type that is not CDes16ReadParameter. |
|
535 */ |
|
536 EXPORT_C const TDesC& CClientMessage::GetDes16L(TInt aParam) |
|
537 { |
|
538 CheckValidatedL(aParam); |
|
539 |
|
540 return iParameters[aParam]->GetDes16L(); |
|
541 } |
|
542 |
|
543 |
|
544 |
|
545 /** |
|
546 Gets a descriptor value read from the message |
|
547 @param aParam The parameter number of the descriptor to retrieve |
|
548 @param aDes On exit contains the descriptor value requested |
|
549 @param aOffset The desired offset from which to read the descriptor |
|
550 @leave KErrNotValidated if the message parameter has not been validated |
|
551 KErrWrongParameterType in UREL is the parameter requested is not a readable |
|
552 TDes8 type |
|
553 Any other system wide error code |
|
554 @panic ECMPanicWrongParameterType If this function is called for a parameter |
|
555 type that is not CDes8Parameter or CDes8ReadParameter. |
|
556 */ |
|
557 EXPORT_C void CClientMessage::ReadL(TInt aParam, TDes8& aDes, TInt aOffset) |
|
558 { |
|
559 CheckValidatedL(aParam); |
|
560 |
|
561 iParameters[aParam]->ReadL(aDes, aOffset); |
|
562 } |
|
563 |
|
564 /** |
|
565 Gets a descriptor value read from the message |
|
566 @param aParam The parameter number of the descriptor to retrieve |
|
567 @param aDes On exit contains the descriptor value requested |
|
568 @param aOffset The desired offset from which to read the descriptor |
|
569 @leave KErrNotValidated if the message parameter has not been validated |
|
570 KErrWrongParameterType in UREL is the parameter requested is not a readable |
|
571 TDes16 type |
|
572 Any other system wide error code |
|
573 @panic ECMPanicWrongParameterType If this function is called for a parameter |
|
574 type that is not CDes16Parameter or CDes16ReadParameter. |
|
575 */ |
|
576 EXPORT_C void CClientMessage::ReadL(TInt aParam, TDes16& aDes, TInt aOffset) |
|
577 { |
|
578 CheckValidatedL(aParam); |
|
579 |
|
580 iParameters[aParam]->ReadL(aDes, aOffset); |
|
581 } |
|
582 |
|
583 /** |
|
584 Writes to a descriptor field in the message |
|
585 @param aParam The parameter number of the descriptor to write |
|
586 @param aDes The descriptor to write to the message |
|
587 @param aOffset The desired offset at which to write the descriptor |
|
588 @leave KErrNotValidated if the message parameter has not been validated |
|
589 KErrWrongParameterType in UREL is the parameter requested is not a writable |
|
590 TDes8 type |
|
591 Any other system wide error code |
|
592 @panic ECMPanicWrongParameterType If this function is called for a parameter |
|
593 type that is not CDes8Parameter |
|
594 */ |
|
595 EXPORT_C void CClientMessage::WriteL(TInt aParam, const TDesC8& aDes, TInt aOffset) |
|
596 { |
|
597 CheckValidatedL(aParam); |
|
598 |
|
599 iParameters[aParam]->WriteL(aDes, aOffset); |
|
600 } |
|
601 |
|
602 /** |
|
603 Writes to a descriptor field in the message |
|
604 @param aParam The parameter number of the descriptor to write |
|
605 @param aDes The descriptor to write to the message |
|
606 @param aOffset The desired offset at which to write the descriptor |
|
607 @leave KErrNotValidated if the message parameter has not been validated |
|
608 KErrWrongParameterType in UREL is the parameter requested is not a writable |
|
609 TDes16 type |
|
610 Any other system wide error code |
|
611 @panic ECMPanicWrongParameterType If this function is called for a parameter |
|
612 type that is notCDes16Parameter |
|
613 */ |
|
614 EXPORT_C void CClientMessage::WriteL(TInt aParam, const TDesC16& aDes, TInt aOffset) |
|
615 { |
|
616 CheckValidatedL(aParam); |
|
617 |
|
618 iParameters[aParam]->WriteL(aDes, aOffset); |
|
619 } |
|
620 |
|
621 /** |
|
622 Gets the length of the requested descriptor message argument |
|
623 @param aParam The parameter number to retrieve |
|
624 @return The Length of the descriptor in the client process |
|
625 @leave KErrNotValidated if the message parameter has not been validated |
|
626 KErrWrongParameterType in UREL is the parameter requested is not a descriptor type |
|
627 Any other system wide error code |
|
628 @panic ECMPanicWrongParameterType If this function is called for a parameter |
|
629 type that is not a descriptor type. |
|
630 */ |
|
631 EXPORT_C TInt CClientMessage::GetDesLengthL(TInt aParam) |
|
632 { |
|
633 CheckValidatedL(aParam); |
|
634 |
|
635 return iParameters[aParam]->GetDesLengthL(); |
|
636 } |
|
637 |
|
638 /** |
|
639 Gets the max length of the requested descriptor message argument |
|
640 @param aParam The parameter number to retrieve |
|
641 @return The Max length of the descriptor in the client process |
|
642 @leave KErrNotValidated if the message parameter has not been validated |
|
643 KErrWrongParameterType in UREL is the parameter requested is not a descriptor type |
|
644 Any other system wide error code |
|
645 @panic ECMPanicWrongParameterType If this function is called for a parameter type |
|
646 that is not a descriptor type. |
|
647 */ |
|
648 EXPORT_C TInt CClientMessage::GetDesMaxLengthL(TInt aParam) |
|
649 { |
|
650 CheckValidatedL(aParam); |
|
651 |
|
652 return iParameters[aParam]->GetDesMaxLengthL(); |
|
653 } |
|
654 |
|
655 /******************************************************************************** |
|
656 * CMessageParameterBase and Derived Class Definitions |
|
657 *******************************************************************************/ |
|
658 |
|
659 |
|
660 /** |
|
661 Factory function for instantiating derived Parameter classes. |
|
662 Uses factory lookup table to instantiate approptiate parameter |
|
663 object based on parameter details passed in |
|
664 @param aParam Parameter details object used to instantiate an appropriate |
|
665 implementation of CMessageParameterBase. |
|
666 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
667 @param aMessage The RMessage2 object containing the parameter represented by |
|
668 this object |
|
669 @return A fully constructed CMessageParameterBase derived object deterimined by |
|
670 aParam. |
|
671 @leave KErrBadMessageSchema in UREL if if the schema for this parameter is |
|
672 incorrectly defined |
|
673 @leave Any system-wide error code. |
|
674 @panic ECMPanicBadMessageSchema in UDEB if the schema for this parameter is |
|
675 incorrectly defined |
|
676 */ |
|
677 CMessageParameterBase* CMessageParameterBase::CreateL(const TParameterDetails& aParam, |
|
678 TInt aParamIndex, const RMessage2& aMessage) |
|
679 { |
|
680 |
|
681 //The parameter type is the bottom 16 bits of the param type |
|
682 TInt paramType = (aParam.iType & KParamTypeMask); |
|
683 |
|
684 __ASSERT_DEBUG((paramType > 0), PanicServer(ECMPanicBadMessageSchema)); |
|
685 |
|
686 CMessageParameterBase* newParam = NULL; |
|
687 |
|
688 switch(paramType) |
|
689 { |
|
690 case EParamInt: |
|
691 case EParamDes8Read: |
|
692 case EParamDes8: |
|
693 case EParamDes16Read: |
|
694 case EParamDes16: |
|
695 case EParamPtr: |
|
696 case EParamPckg: |
|
697 { |
|
698 //Create the new parameter object |
|
699 newParam = (KParameterFactoryFunctions[paramType])(aParam, aParamIndex, |
|
700 aMessage, GetValidationFunctionL(aParam)); |
|
701 break; |
|
702 } |
|
703 |
|
704 default: |
|
705 { |
|
706 #ifdef _DEBUG |
|
707 PanicServer(ECMPanicBadMessageSchema); |
|
708 #else |
|
709 User::Leave(KErrBadMessageSchema); |
|
710 #endif |
|
711 } |
|
712 } |
|
713 |
|
714 return newParam; |
|
715 } |
|
716 |
|
717 /** |
|
718 Constructor for CMessageParameterBase object |
|
719 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
720 @param aMessage The RMessage2 object containing the parameter represented by |
|
721 this object |
|
722 */ |
|
723 CMessageParameterBase::CMessageParameterBase(const TParameterDetails& aParam, |
|
724 TInt aParamIndex,const RMessage2& aMessage, TCustomValidationFn aValidationFn) |
|
725 : iIndex(aParamIndex), iMessage(aMessage), iParamDetails(aParam), iValidationFn(aValidationFn) |
|
726 { |
|
727 |
|
728 } |
|
729 |
|
730 /** |
|
731 Gets the validation function for this parameter from the |
|
732 TClientMessageServerData structure |
|
733 @param aParam Parameter object used to find the validation function |
|
734 @return The validation function for this parameter type |
|
735 @leave KErrBadMessageSchema in UREL if if the schema for this parameter is |
|
736 incorrectly defined |
|
737 @leave Any other system wide error code |
|
738 @panic ECMPanicBadMessageSchema in UDEB if the schema for this parameter is |
|
739 incorrectly defined |
|
740 */ |
|
741 TCustomValidationFn CMessageParameterBase::GetValidationFunctionL(const TParameterDetails& aParam) |
|
742 { |
|
743 //Get the TLS data for this thread - this will never be null at this point |
|
744 //as it is checked in CClientMessage::NewL |
|
745 TClientMessageServerData* serverData = static_cast<TClientMessageServerData*>(Dll::Tls()); |
|
746 |
|
747 //The index of the validation function for this parameter is held in |
|
748 //the upper 16 bits of aParam.iType. Mask this out and shift down to |
|
749 //get the index. |
|
750 TInt fnIndex = (aParam.iType & KValidationFnIndexMask) >> KShift16Bit; |
|
751 |
|
752 |
|
753 if(fnIndex >= serverData->iValidationFnCount) |
|
754 { |
|
755 #ifdef _DEBUG |
|
756 PanicServer(ECMPanicBadMessageSchema); |
|
757 #else |
|
758 User::Leave(KErrBadMessageSchema); |
|
759 #endif |
|
760 } |
|
761 |
|
762 //Return the validation function |
|
763 return serverData->iCustomValidationFns[fnIndex]; |
|
764 } |
|
765 |
|
766 /** |
|
767 Default implementation of GetIntL for CMessageParameterBase object. |
|
768 This is only called if this API is not defined for the given parameter type. |
|
769 @return KErrNone - A Dummy return value |
|
770 @leave KErrWrongParameterType in UREL if this function is not defined for the |
|
771 given parameter type |
|
772 @panic ECMPanicWrongParameterType in UDEB if this function is not defined for the |
|
773 given parameter type |
|
774 */ |
|
775 TInt CMessageParameterBase::GetIntL() |
|
776 { |
|
777 #ifdef _DEBUG |
|
778 User::Panic(KPanicCategory,ECMPanicWrongParameterType); |
|
779 #else |
|
780 User::Leave(KErrWrongParameterType); |
|
781 #endif |
|
782 return KErrNone; |
|
783 } |
|
784 |
|
785 /** |
|
786 Default implementation of GetPtrL for CMessageParameterBase object. |
|
787 This is only called if this API is not defined for the given parameter type. |
|
788 @return NULL - A Dummy return value |
|
789 @leave KErrWrongParameterType in UREL if this function is not defined for the |
|
790 given parameter type |
|
791 @panic ECMPanicWrongParameterType in UDEB if this function is not defined for the |
|
792 given parameter type |
|
793 */ |
|
794 const TAny* CMessageParameterBase::GetPtrL() |
|
795 { |
|
796 #ifdef _DEBUG |
|
797 User::Panic(KPanicCategory,ECMPanicWrongParameterType); |
|
798 #else |
|
799 User::Leave(KErrWrongParameterType); |
|
800 #endif |
|
801 return NULL; |
|
802 } |
|
803 |
|
804 /** |
|
805 Default implementation of WriteL for CMessageParameterBase object. |
|
806 This is only called if this API is not defined for the given parameter type. |
|
807 @leave KErrWrongParameterType in UREL if this function is not defined for the |
|
808 given parameter type |
|
809 @panic ECMPanicWrongParameterType in UDEB if this function is not defined for the |
|
810 given parameter type |
|
811 */ |
|
812 void CMessageParameterBase::WriteL(const TDesC8& /*aDes*/, TInt /*aOffset*/) |
|
813 { |
|
814 #ifdef _DEBUG |
|
815 User::Panic(KPanicCategory,ECMPanicWrongParameterType); |
|
816 #else |
|
817 User::Leave(KErrWrongParameterType); |
|
818 #endif |
|
819 } |
|
820 |
|
821 /** |
|
822 Default implementation of WriteL for CMessageParameterBase object. |
|
823 This is only called if this API is not defined for the given parameter type. |
|
824 @leave KErrWrongParameterType in UREL if this function is not defined for the |
|
825 given parameter type |
|
826 @panic ECMPanicWrongParameterType in UDEB if this function is not defined for the |
|
827 given parameter type |
|
828 */ |
|
829 void CMessageParameterBase::WriteL(const TDesC& /*aDes*/, TInt /*aOffset*/) |
|
830 { |
|
831 #ifdef _DEBUG |
|
832 User::Panic(KPanicCategory,ECMPanicWrongParameterType); |
|
833 #else |
|
834 User::Leave(KErrWrongParameterType); |
|
835 #endif |
|
836 } |
|
837 |
|
838 /** |
|
839 Default implementation of ReadL for CMessageParameterBase object. |
|
840 This is only called if this API is not defined for the given parameter type. |
|
841 @leave KErrWrongParameterType in UREL if this function is not defined for the |
|
842 given parameter type |
|
843 @panic ECMPanicWrongParameterType in UDEB if this function is not defined for the |
|
844 given parameter type |
|
845 */ |
|
846 void CMessageParameterBase::ReadL(TDes8& /*aDes*/,TInt /*aOffset*/) |
|
847 { |
|
848 #ifdef _DEBUG |
|
849 User::Panic(KPanicCategory,ECMPanicWrongParameterType); |
|
850 #else |
|
851 User::Leave(KErrWrongParameterType); |
|
852 #endif |
|
853 } |
|
854 |
|
855 /** |
|
856 Default implementation of ReadL for CMessageParameterBase object. |
|
857 This is only called if this API is not defined for the given parameter type. |
|
858 @leave KErrWrongParameterType in UREL if this function is not defined for the |
|
859 given parameter type |
|
860 @panic ECMPanicWrongParameterType in UDEB if this function is not defined for the |
|
861 given parameter type |
|
862 */ |
|
863 void CMessageParameterBase::ReadL(TDes& /*aDes*/, TInt /*aOffset*/) |
|
864 { |
|
865 #ifdef _DEBUG |
|
866 User::Panic(KPanicCategory,ECMPanicWrongParameterType); |
|
867 #else |
|
868 User::Leave(KErrWrongParameterType); |
|
869 #endif |
|
870 } |
|
871 |
|
872 /** |
|
873 Default implementation of GetDesLengthL for CMessageParameterBase object. |
|
874 This is only called if this API is not defined for the given parameter type. |
|
875 @return KErrNone - A Dummy return |
|
876 @leave KErrWrongParameterType in UREL if this function is not defined for the |
|
877 given parameter type |
|
878 @panic ECMPanicWrongParameterType in UDEB if this function is not defined for the |
|
879 given parameter type |
|
880 */ |
|
881 TInt CMessageParameterBase::GetDesLengthL() |
|
882 { |
|
883 #ifdef _DEBUG |
|
884 User::Panic(KPanicCategory,ECMPanicWrongParameterType); |
|
885 #else |
|
886 User::Leave(KErrWrongParameterType); |
|
887 #endif |
|
888 return KErrNone; |
|
889 } |
|
890 |
|
891 /** |
|
892 Default implementation of GetDesMaxLengthL for CMessageParameterBase object. |
|
893 This is only called if this API is not defined for the given parameter type. |
|
894 @return KErrNone - A Dummy return |
|
895 @leave KErrWrongParameterType in UREL if this function is not defined for the |
|
896 given parameter type |
|
897 @panic ECMPanicWrongParameterType in UDEB if this function is not defined for the |
|
898 given parameter type |
|
899 */ |
|
900 TInt CMessageParameterBase::GetDesMaxLengthL() |
|
901 { |
|
902 #ifdef _DEBUG |
|
903 User::Panic(KPanicCategory,ECMPanicWrongParameterType); |
|
904 #else |
|
905 User::Leave(KErrWrongParameterType); |
|
906 #endif |
|
907 return KErrNone; |
|
908 } |
|
909 |
|
910 /** |
|
911 Default implementation of GetDes8L for CMessageParameterBase object. |
|
912 This is only called if this API is not defined for the given parameter type. |
|
913 @return KErrNone - A Dummy return |
|
914 @leave KErrWrongParameterType in UREL if this function is not defined for the |
|
915 given parameter type |
|
916 @panic ECMPanicWrongParameterType in UDEB if this function is not defined for the |
|
917 given parameter type |
|
918 */ |
|
919 |
|
920 const TDesC8& CMessageParameterBase::GetDes8L() |
|
921 { |
|
922 #ifdef _DEBUG |
|
923 User::Panic(KPanicCategory,ECMPanicWrongParameterType); |
|
924 #else |
|
925 User::Leave(KErrWrongParameterType); |
|
926 #endif |
|
927 _LIT8(KDummy,""); |
|
928 return KDummy; |
|
929 } |
|
930 |
|
931 /** |
|
932 Default implementation of GetDes16L for CMessageParameterBase object. |
|
933 This is only called if this API is not defined for the given parameter type. |
|
934 @return KErrNone - A Dummy return |
|
935 @leave KErrWrongParameterType in UREL if this function is not defined for the |
|
936 given parameter type |
|
937 @panic ECMPanicWrongParameterType in UDEB if this function is not defined for the |
|
938 given parameter type |
|
939 */ |
|
940 const TDesC& CMessageParameterBase::GetDes16L() |
|
941 { |
|
942 #ifdef _DEBUG |
|
943 User::Panic(KPanicCategory,ECMPanicWrongParameterType); |
|
944 #else |
|
945 User::Leave(KErrWrongParameterType); |
|
946 #endif |
|
947 |
|
948 _LIT(KDummy,""); |
|
949 return KDummy; |
|
950 } |
|
951 |
|
952 /** |
|
953 Returns the value of iMin defined in the schema for this parameter |
|
954 @return The Min constraint for this parameter |
|
955 */ |
|
956 TInt CMessageParameterBase::Min() |
|
957 { |
|
958 return iParamDetails.iMin; |
|
959 } |
|
960 |
|
961 /** |
|
962 Returns the value of iMax defined in the schema for this parameter |
|
963 @return The max constraint for this parameter |
|
964 */ |
|
965 TInt CMessageParameterBase::Max() |
|
966 { |
|
967 return iParamDetails.iMax; |
|
968 } |
|
969 |
|
970 |
|
971 /** |
|
972 Factory function for instantiating CIntParameter objects |
|
973 @param aParam Parameter details object used to construct object. |
|
974 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
975 @param aMessage The RMessage2 object containing the parameter represented by |
|
976 @return A fully constructed CIntParameter object. |
|
977 @leave Any system-wide error code. |
|
978 */ |
|
979 CMessageParameterBase* CIntParameter::NewL(const TParameterDetails& aParam, |
|
980 TInt aParamIndex, const RMessage2& aMessage, TCustomValidationFn aValidationFn) |
|
981 { |
|
982 CIntParameter* self = new(ELeave) CIntParameter(aParam, aParamIndex, aMessage, aValidationFn); |
|
983 return self; |
|
984 } |
|
985 |
|
986 /** |
|
987 Constructor for CIntParameter class. |
|
988 @param aParam Parameter details to be encapsulated by object |
|
989 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
990 @param aMessage The RMessage2 object containing the parameter to be represented |
|
991 @panic ECMPanicBadMessageSchema in UDEB if the schema for this parameter is |
|
992 incorrectly defined |
|
993 */ |
|
994 CIntParameter::CIntParameter(const TParameterDetails& aParam, TInt aParamIndex, |
|
995 const RMessage2& aMessage, TCustomValidationFn aValidationFn) |
|
996 : CMessageParameterBase(aParam, aParamIndex, aMessage, aValidationFn) |
|
997 |
|
998 { |
|
999 __ASSERT_DEBUG((iParamDetails.iMax >= iParamDetails.iMin), |
|
1000 PanicServer(ECMPanicBadMessageSchema)); |
|
1001 } |
|
1002 |
|
1003 /** |
|
1004 Destructor for CIntParameter class. |
|
1005 */ |
|
1006 CIntParameter::~CIntParameter() |
|
1007 { |
|
1008 |
|
1009 } |
|
1010 |
|
1011 /** |
|
1012 Validates given message parameter agains constraints |
|
1013 represented by this object. Stores the Int value from the message |
|
1014 to allow for simple retrieval when required. |
|
1015 @leave KErrBadParameter if the message parameter does not conform |
|
1016 to the constraints represented by this object |
|
1017 @leave Any system-wide error code |
|
1018 */ |
|
1019 void CIntParameter::ValidateL() |
|
1020 { |
|
1021 |
|
1022 switch(iIndex) |
|
1023 { |
|
1024 |
|
1025 case 0: |
|
1026 iValue = iMessage.Int0(); |
|
1027 break; |
|
1028 |
|
1029 case 1: |
|
1030 iValue = iMessage.Int1(); |
|
1031 break; |
|
1032 |
|
1033 case 2: |
|
1034 iValue = iMessage.Int2(); |
|
1035 break; |
|
1036 |
|
1037 case 3: |
|
1038 iValue = iMessage.Int3(); |
|
1039 break; |
|
1040 |
|
1041 default: |
|
1042 User::Leave(KErrArgument); |
|
1043 break; |
|
1044 } |
|
1045 |
|
1046 if(iValidationFn != NULL) |
|
1047 { |
|
1048 iValidationFn(this); |
|
1049 } |
|
1050 |
|
1051 else |
|
1052 { |
|
1053 if((iValue < iParamDetails.iMin)||(iValue > iParamDetails.iMax)) |
|
1054 { |
|
1055 User::Leave(KErrBadParameter); |
|
1056 } |
|
1057 } |
|
1058 } |
|
1059 |
|
1060 /** |
|
1061 Retrieves the TInt value read from the clients message during validation |
|
1062 @return The TInt value read from the client message |
|
1063 */ |
|
1064 TInt CIntParameter::GetIntL() |
|
1065 { |
|
1066 return iValue; |
|
1067 } |
|
1068 |
|
1069 /** |
|
1070 Factory function for instantiating CDes8ReadParameter objects |
|
1071 @param aParam Parameter details object used to construct object. |
|
1072 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
1073 @param aMessage The RMessage2 object containing the parameter to be represented |
|
1074 @return A fully constructed CDes8ReadParameter object. |
|
1075 @leave Any system-wide error code. |
|
1076 */ |
|
1077 CMessageParameterBase* CDes8ReadParameter::NewL(const TParameterDetails& aParam, |
|
1078 TInt aParamIndex, const RMessage2& aMessage, TCustomValidationFn aValidationFn) |
|
1079 { |
|
1080 CDes8ReadParameter* self = |
|
1081 new(ELeave) CDes8ReadParameter(aParam, aParamIndex, aMessage, aValidationFn); |
|
1082 |
|
1083 return self; |
|
1084 } |
|
1085 |
|
1086 /** |
|
1087 Constructor for CDes8ReadParameter class. |
|
1088 @param aParam Parameter details to be encapsulated by object |
|
1089 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
1090 @param aMessage The RMessage2 object containing the parameter to be represented |
|
1091 @panic ECMPanicBadMessageSchema in UDEB if the schema for this parameter is |
|
1092 incorrectly defined |
|
1093 */ |
|
1094 CDes8ReadParameter::CDes8ReadParameter(const TParameterDetails& aParam, TInt aParamIndex, |
|
1095 const RMessage2& aMessage, TCustomValidationFn aValidationFn) |
|
1096 : CMessageParameterBase(aParam, aParamIndex, aMessage, aValidationFn) |
|
1097 { |
|
1098 __ASSERT_DEBUG((iParamDetails.iMin >= 0), |
|
1099 PanicServer(ECMPanicBadMessageSchema)); |
|
1100 |
|
1101 __ASSERT_DEBUG((iParamDetails.iMax > 0), |
|
1102 PanicServer(ECMPanicBadMessageSchema)); |
|
1103 |
|
1104 __ASSERT_DEBUG((iParamDetails.iMax >= iParamDetails.iMin), |
|
1105 PanicServer(ECMPanicBadMessageSchema)); |
|
1106 } |
|
1107 |
|
1108 /** |
|
1109 Destructor for CDes8ReadParameter class. |
|
1110 */ |
|
1111 CDes8ReadParameter::~CDes8ReadParameter() |
|
1112 { |
|
1113 delete iValue; |
|
1114 } |
|
1115 |
|
1116 /** |
|
1117 Validates given message argument against constraints |
|
1118 represented by this object. Reads in the descriptor from the |
|
1119 clients message to enable simple retrival when required. |
|
1120 @leave KErrBadDescriptor if the message parameter does not conform |
|
1121 to the constraints represented by this object |
|
1122 @leave Any system-wide error code |
|
1123 */ |
|
1124 void CDes8ReadParameter::ValidateL() |
|
1125 { |
|
1126 TInt length = iMessage.GetDesLengthL(iIndex); |
|
1127 |
|
1128 //if there is a supplied custom validation function, call that now |
|
1129 if(iValidationFn != NULL) |
|
1130 { |
|
1131 iValidationFn(this); |
|
1132 } |
|
1133 |
|
1134 else |
|
1135 { |
|
1136 if((length < iParamDetails.iMin) || (length > iParamDetails.iMax)) |
|
1137 { |
|
1138 User::Leave(KErrBadDescriptor); |
|
1139 } |
|
1140 } |
|
1141 |
|
1142 iValue = HBufC8::NewL(length); |
|
1143 TPtr8 ptr = iValue->Des(); |
|
1144 ReadL(ptr,0); |
|
1145 } |
|
1146 |
|
1147 /** |
|
1148 Gets the descriptor read from the clients message during validation |
|
1149 @return const reference to the local descriptor copy |
|
1150 */ |
|
1151 const TDesC8& CDes8ReadParameter::GetDes8L() |
|
1152 { |
|
1153 return *iValue; |
|
1154 } |
|
1155 |
|
1156 /** |
|
1157 Gets the length of the descriptor in the client message |
|
1158 @return The length of the descriptor |
|
1159 @leave KErrBadDescriptor if the message argument is not a descriptor type |
|
1160 Any other system wide error code |
|
1161 */ |
|
1162 TInt CDes8ReadParameter::GetDesLengthL() |
|
1163 { |
|
1164 return iMessage.GetDesLengthL(iIndex); |
|
1165 } |
|
1166 |
|
1167 /** |
|
1168 Retrieves the descriptor value read from the clients |
|
1169 message during validation |
|
1170 @param aDes The target descriptor. |
|
1171 @param aOffset The offset from the start of the clients descriptor |
|
1172 @leave KErrArgument if iIndex has a value outside the valid range, or if aOffset is negative. |
|
1173 @panic ECMPanicBadDescriptor in UDEB if the supplied descriptor is too small. |
|
1174 if the schema for this parameter is incorrectly defined |
|
1175 */ |
|
1176 void CDes8ReadParameter::ReadL(TDes8& aDes, TInt aOffset) |
|
1177 { |
|
1178 __ASSERT_DEBUG((aDes.MaxLength() >= (iMessage.GetDesLengthL(iIndex) - aOffset)), |
|
1179 PanicServer(ECMPanicBadDescriptor)); |
|
1180 |
|
1181 iMessage.ReadL(iIndex,aDes,aOffset); |
|
1182 } |
|
1183 |
|
1184 /** |
|
1185 Factory function for instantiating CDes8WriteParameter objects |
|
1186 @param aParam Parameter details object used to construct object. |
|
1187 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
1188 @param aMessage The RMessage2 object containing the parameter to be represented |
|
1189 @return A fully constructed CDes8WriteParameter object. |
|
1190 @leave Any system-wide error code. |
|
1191 */ |
|
1192 CMessageParameterBase* CDes8Parameter::NewL(const TParameterDetails& aParam, |
|
1193 TInt aParamIndex, const RMessage2& aMessage, TCustomValidationFn aValidationFn) |
|
1194 { |
|
1195 CDes8Parameter* self = |
|
1196 new(ELeave) CDes8Parameter(aParam, aParamIndex, aMessage, aValidationFn); |
|
1197 |
|
1198 return self; |
|
1199 } |
|
1200 |
|
1201 /** |
|
1202 Constructor for CDes8WriteParameter class. |
|
1203 @param aParam Parameter details to be encapsulated by object |
|
1204 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
1205 @param aMessage The RMessage2 object containing the parameter to be represented |
|
1206 @panic ECMPanicBadMessageSchema in UDEB if the schema for this parameter is |
|
1207 incorrectly defined |
|
1208 */ |
|
1209 CDes8Parameter::CDes8Parameter(const TParameterDetails& aParam, TInt aParamIndex, |
|
1210 const RMessage2& aMessage, TCustomValidationFn aValidationFn) |
|
1211 : CMessageParameterBase(aParam, aParamIndex, aMessage, aValidationFn) |
|
1212 |
|
1213 { |
|
1214 __ASSERT_DEBUG((iParamDetails.iMin >= 0), |
|
1215 PanicServer(ECMPanicBadMessageSchema)); |
|
1216 |
|
1217 __ASSERT_DEBUG((iParamDetails.iMax >= 0), |
|
1218 PanicServer(ECMPanicBadMessageSchema)); |
|
1219 } |
|
1220 |
|
1221 /** |
|
1222 Destructor for CDes8WriteParameter class. |
|
1223 */ |
|
1224 CDes8Parameter::~CDes8Parameter() |
|
1225 { |
|
1226 } |
|
1227 |
|
1228 /** |
|
1229 Validates given message argument against constraints |
|
1230 represented by this object. |
|
1231 @leave KErrBadDescriptor if the message parameter does not conform |
|
1232 to the constraints represented by this object |
|
1233 @leave Any system-wide error code |
|
1234 */ |
|
1235 void CDes8Parameter::ValidateL() |
|
1236 { |
|
1237 |
|
1238 //if there is a supplied custom validation function, call that now |
|
1239 if(iValidationFn != NULL) |
|
1240 { |
|
1241 iValidationFn(this); |
|
1242 } |
|
1243 |
|
1244 else |
|
1245 { |
|
1246 TInt length = iMessage.GetDesLengthL(iIndex); |
|
1247 TInt maxLength = iMessage.GetDesMaxLengthL(iIndex); |
|
1248 |
|
1249 if((maxLength < iParamDetails.iMin)||(length > iParamDetails.iMax)) |
|
1250 { |
|
1251 User::Leave(KErrBadDescriptor); |
|
1252 } |
|
1253 } |
|
1254 } |
|
1255 |
|
1256 /** |
|
1257 Gets the length of the descriptor in the client message |
|
1258 @return The length of the descriptor |
|
1259 @leave KErrBadDescriptor if the message argument is not a descriptor type |
|
1260 Any other system wide error code |
|
1261 */ |
|
1262 TInt CDes8Parameter::GetDesLengthL() |
|
1263 { |
|
1264 return iMessage.GetDesLengthL(iIndex); |
|
1265 } |
|
1266 |
|
1267 /** |
|
1268 Gets the max length of the descriptor in the client message |
|
1269 @return The max length of the descriptor |
|
1270 @leave KErrBadDescriptor if the message argument is not a descriptor type |
|
1271 Any other system wide error code |
|
1272 */ |
|
1273 TInt CDes8Parameter::GetDesMaxLengthL() |
|
1274 { |
|
1275 return iMessage.GetDesMaxLengthL(iIndex); |
|
1276 } |
|
1277 |
|
1278 |
|
1279 /** |
|
1280 Reads a descriptor from the requested message argument |
|
1281 @param aDes The target descriptor. |
|
1282 @param aOffset The offset from the start of the clients descriptor |
|
1283 @leave Any system wide error code. |
|
1284 @panic ECMPanicBadDescriptor in UDEB if the supplied descriptor is too small. |
|
1285 */ |
|
1286 void CDes8Parameter::ReadL(TDes8& aDes, TInt aOffset) |
|
1287 { |
|
1288 __ASSERT_DEBUG((aDes.MaxLength() >= (iMessage.GetDesLengthL(iIndex) - aOffset)), |
|
1289 PanicServer(ECMPanicBadDescriptor)); |
|
1290 |
|
1291 iMessage.ReadL(iIndex,aDes,aOffset); |
|
1292 } |
|
1293 |
|
1294 /** |
|
1295 Validates and writes a descriptor to the requested |
|
1296 message argument |
|
1297 @param aDes The source descriptor containing the data to be written. |
|
1298 @param aOffset The offset from the start of the clients descriptor |
|
1299 @leave Any system wide error code. |
|
1300 */ |
|
1301 void CDes8Parameter::WriteL(const TDesC8& aDes, TInt aOffset) |
|
1302 { |
|
1303 iMessage.WriteL(iIndex,aDes,aOffset); |
|
1304 } |
|
1305 |
|
1306 /** |
|
1307 Factory function for instantiating CIntParameter objects |
|
1308 @param aParam Parameter details object used to construct object. |
|
1309 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
1310 @param aMessage The RMessage2 object containing the parameter to be represented |
|
1311 @return A fully constructed CIntParameter object. |
|
1312 @leave Any system-wide error code. |
|
1313 */ |
|
1314 CMessageParameterBase* CDes16ReadParameter::NewL(const TParameterDetails& aParam, |
|
1315 TInt aParamIndex, const RMessage2& aMessage, TCustomValidationFn aValidationFn) |
|
1316 { |
|
1317 CDes16ReadParameter* self = |
|
1318 new(ELeave) CDes16ReadParameter(aParam, aParamIndex, aMessage, aValidationFn); |
|
1319 |
|
1320 return self; |
|
1321 } |
|
1322 |
|
1323 /** |
|
1324 Constructor for CDes8ReadParameter class. |
|
1325 @param aParam Parameter details to be encapsulated by object |
|
1326 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
1327 @param aMessage The RMessage2 object containing the parameter to be represented |
|
1328 @panic ECMPanicBadMessageSchema in UDEB if the schema for this parameter is |
|
1329 incorrectly defined |
|
1330 */ |
|
1331 CDes16ReadParameter::CDes16ReadParameter(const TParameterDetails& aParam, TInt aParamIndex, |
|
1332 const RMessage2& aMessage, TCustomValidationFn aValidationFn) |
|
1333 : CMessageParameterBase(aParam, aParamIndex, aMessage, aValidationFn) |
|
1334 { |
|
1335 __ASSERT_DEBUG((iParamDetails.iMin >= 0), |
|
1336 PanicServer(ECMPanicBadMessageSchema)); |
|
1337 |
|
1338 __ASSERT_DEBUG((iParamDetails.iMax > 0), |
|
1339 PanicServer(ECMPanicBadMessageSchema)); |
|
1340 |
|
1341 __ASSERT_DEBUG((iParamDetails.iMax >= iParamDetails.iMin), |
|
1342 PanicServer(ECMPanicBadMessageSchema)); |
|
1343 } |
|
1344 |
|
1345 /** |
|
1346 Destructor for CDes16ReadParameter class. |
|
1347 */ |
|
1348 CDes16ReadParameter::~CDes16ReadParameter() |
|
1349 { |
|
1350 delete iValue; |
|
1351 } |
|
1352 |
|
1353 /** |
|
1354 Validates given message argument against constraints |
|
1355 represented by this object. Reads in the descriptor from the |
|
1356 clients message to enable simple retrival when required. |
|
1357 @leave KErrBadDescriptor if the message parameter does not conform |
|
1358 to the constraints represented by this object |
|
1359 @leave Any system-wide error code |
|
1360 */ |
|
1361 void CDes16ReadParameter::ValidateL() |
|
1362 { |
|
1363 TInt length = iMessage.GetDesLengthL(iIndex); |
|
1364 |
|
1365 //if there is a supplied custom validation function, call that now |
|
1366 if(iValidationFn != NULL) |
|
1367 { |
|
1368 iValidationFn(this); |
|
1369 } |
|
1370 |
|
1371 else |
|
1372 { |
|
1373 if((length < iParamDetails.iMin) || (length > iParamDetails.iMax)) |
|
1374 { |
|
1375 User::Leave(KErrBadDescriptor); |
|
1376 } |
|
1377 } |
|
1378 |
|
1379 iValue = HBufC::NewL(length); |
|
1380 TPtr ptr = iValue->Des(); |
|
1381 ReadL(ptr,0); |
|
1382 } |
|
1383 |
|
1384 /** |
|
1385 Gets the descriptor read from the clients message during validation |
|
1386 @return const reference to the local descriptor copy |
|
1387 */ |
|
1388 const TDesC& CDes16ReadParameter::GetDes16L() |
|
1389 { |
|
1390 return *iValue; |
|
1391 } |
|
1392 |
|
1393 /** |
|
1394 Gets the length of the descriptor in the client message |
|
1395 @return The length of the descriptor |
|
1396 @leave KErrBadDescriptor if the message argument is not a descriptor type |
|
1397 Any other system wide error code |
|
1398 */ |
|
1399 TInt CDes16ReadParameter::GetDesLengthL() |
|
1400 { |
|
1401 return iMessage.GetDesLengthL(iIndex); |
|
1402 } |
|
1403 |
|
1404 /** |
|
1405 Retrieves the descriptor value read from the clients |
|
1406 message during validation |
|
1407 @param aDes The target descriptor. |
|
1408 @param aOffset The offset from the start of the clients descriptor |
|
1409 @leave KErrArgument if the suplied descriptor is too small or an invalid |
|
1410 offset is supplied |
|
1411 @panic ECMPanicBadDescriptor in UDEB if the supplied descriptor is too small. |
|
1412 */ |
|
1413 void CDes16ReadParameter::ReadL(TDes& aDes, TInt aOffset) |
|
1414 { |
|
1415 __ASSERT_DEBUG((aDes.MaxLength() >= (iMessage.GetDesLengthL(iIndex) - aOffset)), |
|
1416 PanicServer(ECMPanicBadDescriptor)); |
|
1417 |
|
1418 iMessage.ReadL(iIndex,aDes,aOffset); |
|
1419 } |
|
1420 |
|
1421 /** |
|
1422 Factory function for instantiating CDes16WriteParameter objects |
|
1423 @param aParam Parameter details object used to construct object. |
|
1424 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
1425 @param aMessage The RMessage2 object containing the parameter to be represented |
|
1426 @return A fully constructed CDes16WriteParameter object. |
|
1427 @leave Any system-wide error code. |
|
1428 */ |
|
1429 CMessageParameterBase* CDes16Parameter::NewL(const TParameterDetails& aParam, |
|
1430 TInt aParamIndex, const RMessage2& aMessage, TCustomValidationFn aValidationFn) |
|
1431 { |
|
1432 CDes16Parameter* self = |
|
1433 new(ELeave) CDes16Parameter(aParam, aParamIndex, aMessage, aValidationFn); |
|
1434 |
|
1435 return self; |
|
1436 } |
|
1437 |
|
1438 /** |
|
1439 Constructor for CDes16WriteParameter class. |
|
1440 @param aParam Parameter details to be encapsulated by object |
|
1441 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
1442 @param aMessage The RMessage2 object containing the parameter to be represented |
|
1443 @panic ECMPanicBadMessageSchema in UDEB if the schema for this parameter is |
|
1444 incorrectly defined |
|
1445 */ |
|
1446 CDes16Parameter::CDes16Parameter(const TParameterDetails& aParam, TInt aParamIndex, |
|
1447 const RMessage2& aMessage, TCustomValidationFn aValidationFn) |
|
1448 : CMessageParameterBase(aParam, aParamIndex, aMessage, aValidationFn) |
|
1449 { |
|
1450 __ASSERT_DEBUG((iParamDetails.iMin >= 0), |
|
1451 PanicServer(ECMPanicBadMessageSchema)); |
|
1452 __ASSERT_DEBUG((iParamDetails.iMax >= 0), |
|
1453 PanicServer(ECMPanicBadMessageSchema)); |
|
1454 } |
|
1455 |
|
1456 /** |
|
1457 Destructor for CDes16WriteParameter class. |
|
1458 */ |
|
1459 CDes16Parameter::~CDes16Parameter() |
|
1460 { |
|
1461 |
|
1462 } |
|
1463 |
|
1464 /** |
|
1465 Validates given message argument against constraints |
|
1466 represented by this object. |
|
1467 @leave KErrBadDescriptor if the message parameter does not conform |
|
1468 to the constraints represented by this object |
|
1469 @leave Any system-wide error code |
|
1470 */ |
|
1471 void CDes16Parameter::ValidateL() |
|
1472 { |
|
1473 |
|
1474 //if there is a supplied custom validation function, call that now |
|
1475 if(iValidationFn != NULL) |
|
1476 { |
|
1477 iValidationFn(this); |
|
1478 } |
|
1479 else |
|
1480 { |
|
1481 TInt length = iMessage.GetDesLengthL(iIndex); |
|
1482 TInt maxLength = iMessage.GetDesMaxLengthL(iIndex); |
|
1483 |
|
1484 if((maxLength < iParamDetails.iMin)||(length > iParamDetails.iMax)) |
|
1485 { |
|
1486 User::Leave(KErrBadDescriptor); |
|
1487 } |
|
1488 } |
|
1489 } |
|
1490 |
|
1491 /** |
|
1492 Gets the length of the descriptor in the client message |
|
1493 @return The length of the descriptor |
|
1494 @leave KErrBadDescriptor if the message argument is not a descriptor type |
|
1495 Any other system wide error code |
|
1496 */ |
|
1497 TInt CDes16Parameter::GetDesLengthL() |
|
1498 { |
|
1499 return iMessage.GetDesLengthL(iIndex); |
|
1500 } |
|
1501 |
|
1502 /** |
|
1503 Gets the max length of the descriptor in the client message |
|
1504 @return The max length of the descriptor |
|
1505 @leave KErrBadDescriptor if the message argument is not a descriptor type |
|
1506 Any other system wide error code |
|
1507 */ |
|
1508 TInt CDes16Parameter::GetDesMaxLengthL() |
|
1509 { |
|
1510 return iMessage.GetDesMaxLengthL(iIndex); |
|
1511 } |
|
1512 |
|
1513 /** |
|
1514 Reads a descriptor from the requested message argument |
|
1515 @param aDes The target descriptor. |
|
1516 @param aOffset The offset from the start of the clients descriptor |
|
1517 @leave Any system wide error code. |
|
1518 @panic ECMPanicBadDescriptor in UDEB if the supplied descriptor is too small. |
|
1519 */ |
|
1520 void CDes16Parameter::ReadL(TDes& aDes, TInt aOffset) |
|
1521 { |
|
1522 __ASSERT_DEBUG((aDes.MaxLength() >= (iMessage.GetDesLengthL(iIndex) - aOffset)), |
|
1523 PanicServer(ECMPanicBadDescriptor)); |
|
1524 |
|
1525 iMessage.ReadL(iIndex,aDes,aOffset); |
|
1526 } |
|
1527 |
|
1528 /** |
|
1529 Writes a descriptor to the requested message argument |
|
1530 @param aDes The source descriptor containing the data to be written. |
|
1531 @param aOffset The offset from the start of the clients descriptor |
|
1532 @leave Any system wide error code. |
|
1533 */ |
|
1534 void CDes16Parameter::WriteL(const TDesC& aDes, TInt aOffset) |
|
1535 { |
|
1536 iMessage.WriteL(iIndex,aDes,aOffset); |
|
1537 } |
|
1538 |
|
1539 /** |
|
1540 Factory function for instantiating CPckgParameter objects |
|
1541 @param aParam Parameter details object used to construct object. |
|
1542 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
1543 @param aMessage The RMessage2 object containing the parameter to be represented |
|
1544 @return A fully constructed CPckgParameter object. |
|
1545 @leave Any system-wide error code. |
|
1546 */ |
|
1547 CMessageParameterBase* CPckgParameter::NewL(const TParameterDetails& aParam, |
|
1548 TInt aParamIndex, const RMessage2& aMessage, TCustomValidationFn aValidationFn ) |
|
1549 { |
|
1550 CPckgParameter* self = |
|
1551 new(ELeave) CPckgParameter(aParam, aParamIndex, aMessage, aValidationFn); |
|
1552 |
|
1553 return self; |
|
1554 } |
|
1555 |
|
1556 /** |
|
1557 Constructor for CPckgParameter class. |
|
1558 @param aParam Parameter details to be encapsulated by object |
|
1559 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
1560 @param aMessage The RMessage2 object containing the parameter to be represented |
|
1561 */ |
|
1562 CPckgParameter::CPckgParameter(const TParameterDetails& aParam, TInt aParamIndex, |
|
1563 const RMessage2& aMessage, TCustomValidationFn aValidationFn) |
|
1564 : CDes8Parameter(aParam, aParamIndex, aMessage, aValidationFn) |
|
1565 |
|
1566 { |
|
1567 |
|
1568 } |
|
1569 |
|
1570 /** |
|
1571 Destructor for CPckgParameter class. |
|
1572 */ |
|
1573 CPckgParameter::~CPckgParameter() |
|
1574 { |
|
1575 } |
|
1576 |
|
1577 /** |
|
1578 Validates given message argument against constraints |
|
1579 represented by this object. |
|
1580 @leave KErrBadDescriptor if the message parameter does not conform |
|
1581 to the constraints represented by this object |
|
1582 @leave Any system-wide error code |
|
1583 */ |
|
1584 void CPckgParameter::ValidateL() |
|
1585 { |
|
1586 |
|
1587 //if there is a supplied custom validation function, call that now |
|
1588 if(iValidationFn != NULL) |
|
1589 { |
|
1590 iValidationFn(this); |
|
1591 } |
|
1592 |
|
1593 else |
|
1594 { |
|
1595 TInt length = iMessage.GetDesLengthL(iIndex); |
|
1596 |
|
1597 if((length < iParamDetails.iMin)||(length > iParamDetails.iMax)) |
|
1598 { |
|
1599 User::Leave(KErrBadDescriptor); |
|
1600 } |
|
1601 } |
|
1602 } |
|
1603 |
|
1604 /** |
|
1605 Factory function for instantiating CPtrParameter objects |
|
1606 @param aParam Parameter details object used to construct object. |
|
1607 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
1608 @param aMessage The RMessage2 object containing the parameter to be represented |
|
1609 @return A fully constructed CPtrParameter object. |
|
1610 @leave Any system-wide error code. |
|
1611 */ |
|
1612 CMessageParameterBase* CPtrParameter::NewL(const TParameterDetails& aParam, |
|
1613 TInt aParamIndex, const RMessage2& aMessage, TCustomValidationFn aValidationFn) |
|
1614 { |
|
1615 CPtrParameter* self = new(ELeave) CPtrParameter(aParam, aParamIndex, aMessage, aValidationFn); |
|
1616 return self; |
|
1617 } |
|
1618 |
|
1619 /** |
|
1620 Constructor for CPtrParameter class. |
|
1621 @param aParamIndex The Index of this parameter within the RMessage2 arguments |
|
1622 @param aMessage The RMessage2 object containing the parameter to be represented |
|
1623 */ |
|
1624 CPtrParameter::CPtrParameter(const TParameterDetails& aParam, TInt aParamIndex, |
|
1625 const RMessage2& aMessage, TCustomValidationFn aValidationFn) |
|
1626 : CMessageParameterBase(aParam, aParamIndex, aMessage, aValidationFn) |
|
1627 { |
|
1628 |
|
1629 } |
|
1630 |
|
1631 /** |
|
1632 Validates given message argument against constraints |
|
1633 represented by this object. Stores the TAny* from the |
|
1634 clients message to enable simple retrival when required. |
|
1635 @leave KErrArgument if the argument index is invalid |
|
1636 @leave Any system-wide error code |
|
1637 */ |
|
1638 void CPtrParameter::ValidateL() |
|
1639 { |
|
1640 |
|
1641 switch(iIndex) |
|
1642 { |
|
1643 |
|
1644 case 0: |
|
1645 iValue = iMessage.Ptr0(); |
|
1646 break; |
|
1647 |
|
1648 case 1: |
|
1649 iValue = iMessage.Ptr1(); |
|
1650 break; |
|
1651 |
|
1652 case 2: |
|
1653 iValue = iMessage.Ptr2(); |
|
1654 break; |
|
1655 |
|
1656 case 3: |
|
1657 iValue = iMessage.Ptr3(); |
|
1658 break; |
|
1659 |
|
1660 default: |
|
1661 User::Leave(KErrArgument); |
|
1662 break; |
|
1663 } |
|
1664 |
|
1665 //if there is a supplied custom validation function, call that now |
|
1666 if(iValidationFn != NULL) |
|
1667 { |
|
1668 iValidationFn(this); |
|
1669 } |
|
1670 } |
|
1671 |
|
1672 /** |
|
1673 Retrieves the TAny pointer read from the clients message during validation |
|
1674 @return The TAny pointer read from the client message |
|
1675 */ |
|
1676 const TAny* CPtrParameter::GetPtrL() |
|
1677 { |
|
1678 return iValue; |
|
1679 } |
|
1680 |
|
1681 /** |
|
1682 Decode the string |
|
1683 @param aSrcString Source string |
|
1684 @param rDestString Destination string |
|
1685 @return 1 if aSrcString is not long enough to decode fully, resulting in the storage of |
|
1686 the last character and requiring another aSrcString (poss 0 length) to be passed to it to |
|
1687 clear this character. |
|
1688 @return 0 if the line was decoded OK or the end of the encoded file is reached ie "=" |
|
1689 */ |
|
1690 |
|
1691 EXPORT_C TInt Base64Codec::Decode(const TDesC8& aSrcString, TDes8& rDestString) |
|
1692 { |
|
1693 TInt shiftStored = 0; |
|
1694 TInt maskShiftStored = ESix; |
|
1695 |
|
1696 TInt decodedInt=0; |
|
1697 TInt8 offsetChar=0; |
|
1698 TUint8 decodedChar=0; |
|
1699 |
|
1700 // Clears the destination string |
|
1701 rDestString.Zero(); |
|
1702 |
|
1703 // Initialise variables |
|
1704 const TUint8* srcStringPtr=aSrcString.Ptr(); |
|
1705 const TUint8* srcStringEnd=aSrcString.Length()+srcStringPtr; |
|
1706 TUint8* destStringPtr=(TUint8*)rDestString.Ptr(); |
|
1707 TUint8* destStringPtrBase=destStringPtr; |
|
1708 |
|
1709 TInt maskShift=maskShiftStored; |
|
1710 TInt shiftStorage=shiftStored; |
|
1711 |
|
1712 // Main character process loop |
|
1713 while(srcStringPtr<srcStringEnd) |
|
1714 { |
|
1715 offsetChar=(TInt8)(*srcStringPtr-KImcvLookUpStartOffset); |
|
1716 srcStringPtr++; |
|
1717 |
|
1718 // Check for valid B64 character |
|
1719 if((offsetChar>=0)&&(offsetChar<80)) |
|
1720 { |
|
1721 // Read in next character and B64 decode |
|
1722 decodedInt=AsciiToBase64[offsetChar]; |
|
1723 |
|
1724 // Exits when a PAD char is reached |
|
1725 if(decodedInt==EPadChar) |
|
1726 { |
|
1727 rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase)); |
|
1728 return EFalse; |
|
1729 } |
|
1730 |
|
1731 // Ensures the first 2 chars of 4 are received before processing |
|
1732 if(maskShift==ESix) |
|
1733 maskShift=EFour; |
|
1734 else |
|
1735 { |
|
1736 shiftStorage=shiftStorage<<ESix; |
|
1737 shiftStorage=shiftStorage|decodedInt; |
|
1738 decodedChar=(TUint8)((shiftStorage>>maskShift)&EEightBitMask); |
|
1739 |
|
1740 if((maskShift-=ETwo)<EZero) |
|
1741 maskShift=ESix; |
|
1742 |
|
1743 *destStringPtr++=decodedChar; |
|
1744 } |
|
1745 shiftStorage=decodedInt; |
|
1746 } |
|
1747 } |
|
1748 shiftStored=shiftStorage; |
|
1749 maskShiftStored=maskShift; |
|
1750 |
|
1751 rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase)); |
|
1752 |
|
1753 return maskShift<ESix; |
|
1754 } |
|
1755 |
|
1756 /** |
|
1757 Encode the string |
|
1758 @param aSrcString Source string |
|
1759 @param rDestString Destination string |
|
1760 @return 1 if aSrcString is not long enough to encode fully |
|
1761 @return 0 if the line was encoded OK |
|
1762 */ |
|
1763 EXPORT_C TInt Base64Codec::Encode(const TDesC8& aSrcString, TDes8& rDestString) |
|
1764 { |
|
1765 // Clears the destination string |
|
1766 rDestString.Zero(); |
|
1767 |
|
1768 // Initialise variables |
|
1769 const TUint8* srcStringPtr=aSrcString.Ptr(); |
|
1770 const TUint8* srcStringEnd=aSrcString.Length()+srcStringPtr; |
|
1771 TUint8* destStringPtr=(TUint8*)rDestString.Ptr(); |
|
1772 TUint8* destStringPtrBase=destStringPtr; |
|
1773 |
|
1774 TInt character=0; |
|
1775 TUint8 encodedChar=0; |
|
1776 TInt charStorage=0; |
|
1777 TInt maskShift=EZero; |
|
1778 TInt destStringCharNum = 0; |
|
1779 |
|
1780 while(srcStringPtr<=srcStringEnd) |
|
1781 { |
|
1782 // maskShift is used as a char read counter |
|
1783 if(maskShift==ESix) |
|
1784 { |
|
1785 // If the 3rd char read is also the last char then the while loop |
|
1786 // is broken on the next check. |
|
1787 if(srcStringPtr==srcStringEnd) |
|
1788 srcStringPtr++; |
|
1789 maskShift=EZero; |
|
1790 character=0; |
|
1791 } |
|
1792 else |
|
1793 { |
|
1794 if(srcStringPtr==srcStringEnd) |
|
1795 character=0; |
|
1796 else |
|
1797 character=*srcStringPtr; |
|
1798 |
|
1799 srcStringPtr++; |
|
1800 // Shifts charStorage ready for the next char |
|
1801 charStorage=charStorage<<8; |
|
1802 maskShift+=ETwo; |
|
1803 } |
|
1804 charStorage=charStorage|character; |
|
1805 // Shifts the mask to the correct bit location |
|
1806 // Masks (AND's) the valid bits from charStorage |
|
1807 // Shifts the valid bits into the low order 8bits |
|
1808 // Converts to BASE64 char, Casts the result to an unsigned char (which it should be ?....I hope) |
|
1809 encodedChar=(TUint8)Base64ToAscii[((charStorage>>maskShift)&ESixBitMask)]; |
|
1810 |
|
1811 *destStringPtr++=encodedChar; |
|
1812 destStringCharNum++; |
|
1813 |
|
1814 // Add a CRLF every KMaxB64EncodedCharsPerLine characters so as not to exceed the line length |
|
1815 // limitation specified in RFC 2822. |
|
1816 if (destStringCharNum == KMaxB64EncodedCharsPerLine) |
|
1817 { |
|
1818 destStringCharNum = 0; |
|
1819 *destStringPtr++ = '\r'; |
|
1820 *destStringPtr++ = '\n'; |
|
1821 } |
|
1822 } |
|
1823 |
|
1824 // Check for not enough chars and pad if required |
|
1825 if (maskShift==EFour) |
|
1826 { |
|
1827 *destStringPtr++=KImcvConvEquals; |
|
1828 *destStringPtr++=KImcvConvEquals; |
|
1829 } |
|
1830 else |
|
1831 if(maskShift==ESix) |
|
1832 *destStringPtr++=KImcvConvEquals; |
|
1833 |
|
1834 rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase)); |
|
1835 return ((TInt)(srcStringPtr-srcStringEnd)); |
|
1836 } |