diff -r 000000000000 -r e4d67989cc36 lowlevellibsandfws/apputils/bsul/src/clientmessage.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lowlevellibsandfws/apputils/bsul/src/clientmessage.cpp Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,1836 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include "clientmessagecmn.h" + +using namespace BSUL; + +/** +Base 64 decoding table +*/ +const TInt8 AsciiToBase64[80]= + { + 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, -1, -1, -1, 64, -1, + -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, + -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 + }; + +/** +Base 64 encoding table +*/ +const TInt8 Base64ToAscii[65]= + { + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 97, 98, 99,100, + 101,102,103,104,105,106,107,108,109,110, + 111,112,113,114,115,116,117,118,119,120, + 121,122, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 43, 47, 61 + }; + +const TInt8 KImcvLookUpStartOffset = 43; +const TUint8 KImcvConvEquals = '='; +/** +The maximum number of US ASCII characters per line that are before the CRLF line +terminator when sending emails. RFC 2822 recommends that each line SHOULD not exceed +80 characters including the CRLF terminator, and MUST not exceed 1000. +*/ +const TInt KMaxB64EncodedCharsPerLine = 60; // Could be increased to 75 characters for every encoded line if KDecodeLineLength = 675. 60 was chosen to maintain existing behaviour. + +/** +Parameter factory function lookup table. This is used to instantiate a +CMessageParameterBase derived object based on a TParamType enum value +*/ +const TMessageParameterFactoryFn KParameterFactoryFunctions[] = {NULL, + CIntParameter::NewL, + CDes8ReadParameter::NewL, + CDes8Parameter::NewL, + CPckgParameter::NewL, + CDes16ReadParameter::NewL, + CDes16Parameter::NewL, + CPtrParameter::NewL}; + +/** +Panic string for client message framework panic +*/ +#ifdef _DEBUG +_LIT(KPanicCategory,"BSUL::ClientMsg"); +#endif + +const TInt KMaxServerNameLength = 32; + +/** +This static function is used to panic the server in case of +incorrect use of CMessageParameterBase APIs or a badly formed +message schema +@param aPanic The Panic value +*/ +void PanicServer(TInt aPanic) + { + _LIT(KUnknownServer, "Unknown"); + TBuf serverName(KUnknownServer); + + //Get the TLS data for this thread + TClientMessageServerData* serverData = static_cast(Dll::Tls()); + + if(serverData != NULL) + { + TPtrC8 name(serverData->iServerName); + serverName.Copy(name); + } + + User::Panic(serverName, aPanic); + } + +/** +Static initialisation function for ClientMessage Framework +@param aServerData The initialisation data for the server using the library +@leave Any system wide error code +*/ +EXPORT_C void CClientMessage::InitialiseFrameworkL(const TClientMessageServerData& aServerData) + { + __ASSERT_DEBUG(User::StringLength(aServerData.iServerName) <= KMaxServerNameLength, User::Invariant()); + Dll::SetTls((TAny*)&aServerData); + } + +/** +Static factory function for CClientMessage class +@param aMessage The message that this object encapsulates +@return Pointer to a fully constructed CClientMessage object. +@leave KErrNotInitialised if the framework has not been initialised by a + call to InitialiseFrameworkL. +*/ +EXPORT_C CClientMessage* CClientMessage::NewL(const RMessage2& aMessage) + { + const TClientMessageServerData* serverData = static_cast(Dll::Tls()); + if(serverData == NULL) + { + User::Leave(KErrNotInitialised); + } + + CClientMessage* self = new(ELeave) CClientMessage(aMessage,*serverData); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + + return self; + } + + +/** +Second phase constructor of CClientMessage Object +Finds the schema for this message and checks the caller against the security +policy defined for this message. Traverses the array of message parameters +and instantiates a CMessageParameterBase object for each parameter and adds these +to its internal array. +@leave KErrInvalidFunction If the message function is not found in the message table +@leave KErrBadHandle if the message handle is Null +@leave KErrPermissionDenied if the security policy for this message is not satisfied +*/ +void CClientMessage::ConstructL() + { + if(!iMessage.IsNull()) + { + + //Find the message schema for this message. + const TClientMessageSchema* messageSchema = FindMessageSchema(); + + if(!messageSchema) + { + LogBadMessageL(KErrInvalidFunction); + User::Leave(KErrInvalidFunction); + } + + //Check message against security policy + CheckSecurityPolicyL(messageSchema->iPolicy); + + //iterate through message parameters and instantiate all parameter objects + for(int index = 0;index < messageSchema->iParamCount;index++) + { + CMessageParameterBase* parameter = + CMessageParameterBase::CreateL(messageSchema->iParams[index], index, iMessage); + + //Some parameter types are defined to be ignored. These + //should not be added to the list of parameters + if(parameter != NULL) + { + //AppendL can leave so use cleanupstack to ensure that memory is not + //leaked if AppendL leaves. + CleanupStack::PushL(parameter); + iParameters.AppendL(parameter); + CleanupStack::Pop(parameter); + } + } + } + else + { + LogBadMessageL(KErrBadHandle); + User::Leave(KErrBadHandle); + } + } + +/** +Constructor for CClientMessage Object +@param aMessage The RMessage2 to be represented by this object +@param aServerData The Initialisation data for the server creating this object +*/ +EXPORT_C CClientMessage::CClientMessage(const RMessage2& aMessage, + const TClientMessageServerData& aServerData) + : iParameters(KMaxParameters), iMessage(aMessage), + iServerData(aServerData),iFlags(aServerData.iFlags & 0xFFFF0000) + + { + + } + +/** +Destructor for CClientMessageObject +*/ +EXPORT_C CClientMessage::~CClientMessage() + { + for(int i = 0; i < iParameters.Count();i++) + { + delete iParameters[i]; + } + iParameters.Reset(); + } + +EXPORT_C const RMessage2& CClientMessage::Message() + { + return iMessage; + } + +/** +Panics the client through the message object +set an internal flag to indicate that the RMessage reference handle is now NULL +due to the client thread being tidied up. +@param aServer The Panic category +@param aPanic The Panic value +*/ +EXPORT_C void CClientMessage::PanicClient(const TDesC& aServer, TInt aPanic) + { + iMessage.Panic(aServer, aPanic); + iFlags.Set(EFlagPanicClient); + } + +/** +Checks a message against the security policy defined for the server +@param aPolicy The security policy to check this message against +@leave KErrPermissionDenied if the message does not fulfil the security policy +*/ +void CClientMessage::CheckSecurityPolicyL(const TSecurityPolicy& aPolicy) + { + if(!(aPolicy.CheckPolicy(iMessage, + "Client failed security policy check for this server"))) + { + User::Leave(KErrPermissionDenied); + } + return; + } + +/** +Finds a message schema in the message table for this server. +Does a binary search on the function number to pull the correct +message from the table. Note that this assumes that the table +is sorted. +@return A pointer to a TClientMessageSchema object in the message table, or Null if + the message does not correpsond to a message in the message table +*/ +const TClientMessageSchema* CClientMessage::FindMessageSchema() + { + //This should always be less than KNumClientMessages + TInt function = iMessage.Function(); + TInt beg = 0; + TInt end = iServerData.iMessageCount - 1; + TInt mid = 0; + TInt midFn = 0; + + while(beg <= end) + { + mid = (end + beg)/2; + + midFn = iServerData.iMessageSchema[mid].iFunction; + if(midFn > function) + { + end = mid - 1; + } + else if(midFn < function) + { + beg = mid + 1; + } + else + { + return &iServerData.iMessageSchema[mid]; + } + } + return NULL; + } + + + + +/** +Validates the message parameters against the constraints provided +in the message table +@leave KErrBadMessage if the message fails validation against the criteria supplied in the + message table +@leave Any system-wide error code +*/ +EXPORT_C void CClientMessage::ValidateL() + { + + for(int i = 0; i < iParameters.Count();i++) + { + iParameters[i]->ValidateL(); + iFlags.Set(i); + } + } + +/** +Validates a single message argument against the constraints provided +in the message table +@param aParam The index value identifying the argument to validate +@leave KErrBadMessage if the message fails validation against the criteria supplied in the + message table for the requested argument +@leave KErrArgument if aParam is negative or is greater than the number of parameters for + this message +@leave Any system-wide error code +*/ +EXPORT_C void CClientMessage::ValidateL(TInt aParam) + { + + if(( aParam >= 0) && (aParam < iParameters.Count())) + { + iParameters[aParam]->ValidateL(); + iFlags.Set(aParam); + } + else + { + User::Leave(KErrArgument); + } + } + +/** +Checks if a given parameter has been validated +@param aParam The index value identifying the paramater to check +@leave KErrArgument if aParam is not a valid parameter value +@leave KErrNotValidated if the parameter has not been validated +*/ +void CClientMessage::CheckValidatedL(TInt aParam) + { + if((aParam < EFlagParam0Validated) || (aParam > EFlagParam3Validated)) + { + User::Leave(KErrArgument); + } + + if(!iFlags.IsSet(aParam)) + { + User::Leave(KErrNotValidated); + } + } + + +/** +Checks if a bad messages should be logged +@return True if bad messages should be logged +*/ +TBool CClientMessage::LogBadMessages() + { + return iFlags.IsSet(EFlagLogBadMessages); + } + +/** +Checks if a bad messages should be logged +@param aError The error code to log +*/ +void CClientMessage::LogBadMessageL(TInt aError) + { + //Check if logging of bad messages is enabled + if(LogBadMessages()) + { + + TUid sid = TUid(iMessage.SecureId()); + TUidName clientSid = sid.Name(); + + TInt function = Function(); + + TBuf serverName; + TPtrC8 name(iServerData.iServerName); + serverName.Copy(name); + + switch(aError) + { + #ifdef _DEBUG + + + case KErrInvalidFunction: + RDebug::Print(_L("%S - CClientMessage Error: %d, Function %d. Unknown function request from client %S.\n"), + &serverName,aError,function, &clientSid); + break; + + case KErrBadParameter: + RDebug::Print(_L("%S - CClientMessage Error: %d, Function %d. Bad argument in IPC request from client %S.\n"), + &serverName,aError,function, &clientSid); + break; + + case KErrBadMessageSchema: + RDebug::Print(_L("%S - CClientMessage Error: %d, Function %d. Message schema incotrectly defined for this function %S.\n"), + &serverName,aError,function, &clientSid); + break; + + case KErrBadDescriptor: + case KErrOverflow: + RDebug::Print(_L("%S - CClientMessage Error: %d, Function %d. Bad descriptor argument in IPC request from client %S.\n"), + &serverName,aError,function, &clientSid); + break; + + case KErrNotValidated: + RDebug::Print(_L("%S - CClientMessage Error: %d, Function %d. Message parameter not validated before use %S.\n"), + &serverName,aError,function, &clientSid); + break; + + default: + RDebug::Print(_L("%S - CClientMessage Error: %d, Function %d. Bad message received from client %S.\n"), + &serverName,aError,function, &clientSid); + break; + #else + default: + break; + #endif + } + } + + + } + +/** +Completes the message request or Panics the client if a +message error has occured. +@param aError The error value to complete the message with +*/ +EXPORT_C void CClientMessage::CompleteRequestL(TInt aError) + { + //If server panics client + //then iMessage will be NULL + if(!iFlags.IsSet(EFlagPanicClient)) + { + if(aError != KErrNone) + { + LogBadMessageL(aError); + } + + switch(aError) + { + case KErrInvalidFunction: + case KErrBadDescriptor: + case KErrOverflow: + { + //Check if Panic is disabled + if( iFlags.IsClear(EFlagDoNotPanicClientOnBadMessageErrors) ) + { + TBuf serverName; + TPtrC8 name(iServerData.iServerName); + serverName.Copy(name); + PanicClient(serverName, aError); + break; + } + } + default: + { + iMessage.Complete(aError); + break; + } + }//switch + + }//if + } + +/** +Gets the function number of this message +@return The function number of this message +*/ +EXPORT_C TInt CClientMessage::Function() + { + return iMessage.Function(); + } + +/** +Gets the requested message argument as an integer value +@param aParam The parameter number to retrieve +@return The Int value for the requested parameter +@leave KErrNotValidated if the message parameter has not been validated + KErrWrongParameterType in UREL is the parameter requested is not an integer type + Any other system wide error code +@panic ECMPanicWrongParameterType If this function is called for a parameter +type that is not CIntParameter. +*/ +EXPORT_C TInt CClientMessage::GetIntL(TInt aParam) + { + CheckValidatedL(aParam); + + return iParameters[aParam]->GetIntL(); + } + +/** +Gets the requested message argument as an TAny* +@param aParam The parameter number to retrieve +@return The TAny* for the requested parameter +@leave KErrNotValidated if the message parameter has not been validated + KErrWrongParameterType in UREL is the parameter requested is not an Ptr type + Any other system wide error code +@panic ECMPanicWrongParameterType If this function is called for a parameter +type that is not CPtrParameter. +*/ +EXPORT_C const TAny* CClientMessage::GetPtrL(TInt aParam) + { + CheckValidatedL(aParam); + + return iParameters[aParam]->GetPtrL(); + } + +/** +Gets a reference to the local copy of the descriptor read from the message +@param aParam The parameter number of the descriptor to retrieve +@leave KErrNotValidated if the message parameter has not been validated + KErrWrongParameterType in UREL is the parameter requested is not a readable + TDes8 type + Any other system wide error code +@panic ECMPanicWrongParameterType If this function is called for a parameter +type that is not CDes8ReadParameter. +*/ +EXPORT_C const TDesC8& CClientMessage::GetDes8L(TInt aParam) + { + CheckValidatedL(aParam); + + return iParameters[aParam]->GetDes8L(); + } + +/** +Gets a reference to the local copy of the descriptor read from the message +@param aParam The parameter number of the descriptor to retrieve +@leave KErrNotValidated if the message parameter has not been validated + KErrWrongParameterType in UREL is the parameter requested is not a readable + TDes16 type + Any other system wide error code +@panic ECMPanicWrongParameterType If this function is called for a parameter +type that is not CDes16ReadParameter. +*/ +EXPORT_C const TDesC& CClientMessage::GetDes16L(TInt aParam) + { + CheckValidatedL(aParam); + + return iParameters[aParam]->GetDes16L(); + } + + + +/** +Gets a descriptor value read from the message +@param aParam The parameter number of the descriptor to retrieve +@param aDes On exit contains the descriptor value requested +@param aOffset The desired offset from which to read the descriptor +@leave KErrNotValidated if the message parameter has not been validated + KErrWrongParameterType in UREL is the parameter requested is not a readable + TDes8 type + Any other system wide error code +@panic ECMPanicWrongParameterType If this function is called for a parameter +type that is not CDes8Parameter or CDes8ReadParameter. +*/ +EXPORT_C void CClientMessage::ReadL(TInt aParam, TDes8& aDes, TInt aOffset) + { + CheckValidatedL(aParam); + + iParameters[aParam]->ReadL(aDes, aOffset); + } + +/** +Gets a descriptor value read from the message +@param aParam The parameter number of the descriptor to retrieve +@param aDes On exit contains the descriptor value requested +@param aOffset The desired offset from which to read the descriptor +@leave KErrNotValidated if the message parameter has not been validated + KErrWrongParameterType in UREL is the parameter requested is not a readable + TDes16 type + Any other system wide error code +@panic ECMPanicWrongParameterType If this function is called for a parameter +type that is not CDes16Parameter or CDes16ReadParameter. +*/ +EXPORT_C void CClientMessage::ReadL(TInt aParam, TDes16& aDes, TInt aOffset) + { + CheckValidatedL(aParam); + + iParameters[aParam]->ReadL(aDes, aOffset); + } + +/** +Writes to a descriptor field in the message +@param aParam The parameter number of the descriptor to write +@param aDes The descriptor to write to the message +@param aOffset The desired offset at which to write the descriptor +@leave KErrNotValidated if the message parameter has not been validated + KErrWrongParameterType in UREL is the parameter requested is not a writable + TDes8 type + Any other system wide error code +@panic ECMPanicWrongParameterType If this function is called for a parameter +type that is not CDes8Parameter +*/ +EXPORT_C void CClientMessage::WriteL(TInt aParam, const TDesC8& aDes, TInt aOffset) + { + CheckValidatedL(aParam); + + iParameters[aParam]->WriteL(aDes, aOffset); + } + +/** +Writes to a descriptor field in the message +@param aParam The parameter number of the descriptor to write +@param aDes The descriptor to write to the message +@param aOffset The desired offset at which to write the descriptor +@leave KErrNotValidated if the message parameter has not been validated + KErrWrongParameterType in UREL is the parameter requested is not a writable + TDes16 type + Any other system wide error code +@panic ECMPanicWrongParameterType If this function is called for a parameter +type that is notCDes16Parameter +*/ +EXPORT_C void CClientMessage::WriteL(TInt aParam, const TDesC16& aDes, TInt aOffset) + { + CheckValidatedL(aParam); + + iParameters[aParam]->WriteL(aDes, aOffset); + } + +/** +Gets the length of the requested descriptor message argument +@param aParam The parameter number to retrieve +@return The Length of the descriptor in the client process +@leave KErrNotValidated if the message parameter has not been validated + KErrWrongParameterType in UREL is the parameter requested is not a descriptor type + Any other system wide error code +@panic ECMPanicWrongParameterType If this function is called for a parameter +type that is not a descriptor type. +*/ +EXPORT_C TInt CClientMessage::GetDesLengthL(TInt aParam) + { + CheckValidatedL(aParam); + + return iParameters[aParam]->GetDesLengthL(); + } + +/** +Gets the max length of the requested descriptor message argument +@param aParam The parameter number to retrieve +@return The Max length of the descriptor in the client process +@leave KErrNotValidated if the message parameter has not been validated + KErrWrongParameterType in UREL is the parameter requested is not a descriptor type + Any other system wide error code +@panic ECMPanicWrongParameterType If this function is called for a parameter type +that is not a descriptor type. +*/ +EXPORT_C TInt CClientMessage::GetDesMaxLengthL(TInt aParam) + { + CheckValidatedL(aParam); + + return iParameters[aParam]->GetDesMaxLengthL(); + } + +/******************************************************************************** + * CMessageParameterBase and Derived Class Definitions + *******************************************************************************/ + + +/** +Factory function for instantiating derived Parameter classes. +Uses factory lookup table to instantiate approptiate parameter +object based on parameter details passed in +@param aParam Parameter details object used to instantiate an appropriate + implementation of CMessageParameterBase. +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter represented by + this object +@return A fully constructed CMessageParameterBase derived object deterimined by + aParam. +@leave KErrBadMessageSchema in UREL if if the schema for this parameter is + incorrectly defined +@leave Any system-wide error code. +@panic ECMPanicBadMessageSchema in UDEB if the schema for this parameter is + incorrectly defined +*/ +CMessageParameterBase* CMessageParameterBase::CreateL(const TParameterDetails& aParam, + TInt aParamIndex, const RMessage2& aMessage) + { + + //The parameter type is the bottom 16 bits of the param type + TInt paramType = (aParam.iType & KParamTypeMask); + + __ASSERT_DEBUG((paramType > 0), PanicServer(ECMPanicBadMessageSchema)); + + CMessageParameterBase* newParam = NULL; + + switch(paramType) + { + case EParamInt: + case EParamDes8Read: + case EParamDes8: + case EParamDes16Read: + case EParamDes16: + case EParamPtr: + case EParamPckg: + { + //Create the new parameter object + newParam = (KParameterFactoryFunctions[paramType])(aParam, aParamIndex, + aMessage, GetValidationFunctionL(aParam)); + break; + } + + default: + { +#ifdef _DEBUG + PanicServer(ECMPanicBadMessageSchema); +#else + User::Leave(KErrBadMessageSchema); +#endif + } + } + + return newParam; + } + +/** +Constructor for CMessageParameterBase object +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter represented by + this object +*/ +CMessageParameterBase::CMessageParameterBase(const TParameterDetails& aParam, + TInt aParamIndex,const RMessage2& aMessage, TCustomValidationFn aValidationFn) + : iIndex(aParamIndex), iMessage(aMessage), iParamDetails(aParam), iValidationFn(aValidationFn) + { + + } + +/** +Gets the validation function for this parameter from the +TClientMessageServerData structure +@param aParam Parameter object used to find the validation function +@return The validation function for this parameter type +@leave KErrBadMessageSchema in UREL if if the schema for this parameter is + incorrectly defined +@leave Any other system wide error code +@panic ECMPanicBadMessageSchema in UDEB if the schema for this parameter is + incorrectly defined +*/ +TCustomValidationFn CMessageParameterBase::GetValidationFunctionL(const TParameterDetails& aParam) + { + //Get the TLS data for this thread - this will never be null at this point + //as it is checked in CClientMessage::NewL + TClientMessageServerData* serverData = static_cast(Dll::Tls()); + + //The index of the validation function for this parameter is held in + //the upper 16 bits of aParam.iType. Mask this out and shift down to + //get the index. + TInt fnIndex = (aParam.iType & KValidationFnIndexMask) >> KShift16Bit; + + + if(fnIndex >= serverData->iValidationFnCount) + { +#ifdef _DEBUG + PanicServer(ECMPanicBadMessageSchema); +#else + User::Leave(KErrBadMessageSchema); +#endif + } + + //Return the validation function + return serverData->iCustomValidationFns[fnIndex]; + } + +/** +Default implementation of GetIntL for CMessageParameterBase object. +This is only called if this API is not defined for the given parameter type. +@return KErrNone - A Dummy return value +@leave KErrWrongParameterType in UREL if this function is not defined for the + given parameter type +@panic ECMPanicWrongParameterType in UDEB if this function is not defined for the + given parameter type +*/ +TInt CMessageParameterBase::GetIntL() + { +#ifdef _DEBUG + User::Panic(KPanicCategory,ECMPanicWrongParameterType); +#else + User::Leave(KErrWrongParameterType); +#endif + return KErrNone; + } + +/** +Default implementation of GetPtrL for CMessageParameterBase object. +This is only called if this API is not defined for the given parameter type. +@return NULL - A Dummy return value +@leave KErrWrongParameterType in UREL if this function is not defined for the + given parameter type +@panic ECMPanicWrongParameterType in UDEB if this function is not defined for the + given parameter type +*/ +const TAny* CMessageParameterBase::GetPtrL() + { +#ifdef _DEBUG + User::Panic(KPanicCategory,ECMPanicWrongParameterType); +#else + User::Leave(KErrWrongParameterType); +#endif + return NULL; + } + +/** +Default implementation of WriteL for CMessageParameterBase object. +This is only called if this API is not defined for the given parameter type. +@leave KErrWrongParameterType in UREL if this function is not defined for the + given parameter type +@panic ECMPanicWrongParameterType in UDEB if this function is not defined for the + given parameter type +*/ +void CMessageParameterBase::WriteL(const TDesC8& /*aDes*/, TInt /*aOffset*/) + { +#ifdef _DEBUG + User::Panic(KPanicCategory,ECMPanicWrongParameterType); +#else + User::Leave(KErrWrongParameterType); +#endif + } + +/** +Default implementation of WriteL for CMessageParameterBase object. +This is only called if this API is not defined for the given parameter type. +@leave KErrWrongParameterType in UREL if this function is not defined for the + given parameter type +@panic ECMPanicWrongParameterType in UDEB if this function is not defined for the + given parameter type +*/ +void CMessageParameterBase::WriteL(const TDesC& /*aDes*/, TInt /*aOffset*/) + { +#ifdef _DEBUG + User::Panic(KPanicCategory,ECMPanicWrongParameterType); +#else + User::Leave(KErrWrongParameterType); +#endif + } + +/** +Default implementation of ReadL for CMessageParameterBase object. +This is only called if this API is not defined for the given parameter type. +@leave KErrWrongParameterType in UREL if this function is not defined for the + given parameter type +@panic ECMPanicWrongParameterType in UDEB if this function is not defined for the + given parameter type +*/ +void CMessageParameterBase::ReadL(TDes8& /*aDes*/,TInt /*aOffset*/) + { +#ifdef _DEBUG + User::Panic(KPanicCategory,ECMPanicWrongParameterType); +#else + User::Leave(KErrWrongParameterType); +#endif + } + +/** +Default implementation of ReadL for CMessageParameterBase object. +This is only called if this API is not defined for the given parameter type. +@leave KErrWrongParameterType in UREL if this function is not defined for the + given parameter type +@panic ECMPanicWrongParameterType in UDEB if this function is not defined for the + given parameter type +*/ +void CMessageParameterBase::ReadL(TDes& /*aDes*/, TInt /*aOffset*/) + { +#ifdef _DEBUG + User::Panic(KPanicCategory,ECMPanicWrongParameterType); +#else + User::Leave(KErrWrongParameterType); +#endif + } + +/** +Default implementation of GetDesLengthL for CMessageParameterBase object. +This is only called if this API is not defined for the given parameter type. +@return KErrNone - A Dummy return +@leave KErrWrongParameterType in UREL if this function is not defined for the + given parameter type +@panic ECMPanicWrongParameterType in UDEB if this function is not defined for the + given parameter type +*/ +TInt CMessageParameterBase::GetDesLengthL() + { +#ifdef _DEBUG + User::Panic(KPanicCategory,ECMPanicWrongParameterType); +#else + User::Leave(KErrWrongParameterType); +#endif + return KErrNone; + } + +/** +Default implementation of GetDesMaxLengthL for CMessageParameterBase object. +This is only called if this API is not defined for the given parameter type. +@return KErrNone - A Dummy return +@leave KErrWrongParameterType in UREL if this function is not defined for the + given parameter type +@panic ECMPanicWrongParameterType in UDEB if this function is not defined for the + given parameter type +*/ +TInt CMessageParameterBase::GetDesMaxLengthL() + { +#ifdef _DEBUG + User::Panic(KPanicCategory,ECMPanicWrongParameterType); +#else + User::Leave(KErrWrongParameterType); +#endif + return KErrNone; + } + +/** +Default implementation of GetDes8L for CMessageParameterBase object. +This is only called if this API is not defined for the given parameter type. +@return KErrNone - A Dummy return +@leave KErrWrongParameterType in UREL if this function is not defined for the + given parameter type +@panic ECMPanicWrongParameterType in UDEB if this function is not defined for the + given parameter type +*/ + +const TDesC8& CMessageParameterBase::GetDes8L() + { +#ifdef _DEBUG + User::Panic(KPanicCategory,ECMPanicWrongParameterType); +#else + User::Leave(KErrWrongParameterType); +#endif + _LIT8(KDummy,""); + return KDummy; + } + +/** +Default implementation of GetDes16L for CMessageParameterBase object. +This is only called if this API is not defined for the given parameter type. +@return KErrNone - A Dummy return +@leave KErrWrongParameterType in UREL if this function is not defined for the + given parameter type +@panic ECMPanicWrongParameterType in UDEB if this function is not defined for the + given parameter type +*/ +const TDesC& CMessageParameterBase::GetDes16L() + { +#ifdef _DEBUG + User::Panic(KPanicCategory,ECMPanicWrongParameterType); +#else + User::Leave(KErrWrongParameterType); +#endif + + _LIT(KDummy,""); + return KDummy; + } + +/** +Returns the value of iMin defined in the schema for this parameter +@return The Min constraint for this parameter +*/ +TInt CMessageParameterBase::Min() + { + return iParamDetails.iMin; + } + +/** +Returns the value of iMax defined in the schema for this parameter +@return The max constraint for this parameter +*/ +TInt CMessageParameterBase::Max() + { + return iParamDetails.iMax; + } + + +/** +Factory function for instantiating CIntParameter objects +@param aParam Parameter details object used to construct object. +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter represented by +@return A fully constructed CIntParameter object. +@leave Any system-wide error code. +*/ +CMessageParameterBase* CIntParameter::NewL(const TParameterDetails& aParam, + TInt aParamIndex, const RMessage2& aMessage, TCustomValidationFn aValidationFn) + { + CIntParameter* self = new(ELeave) CIntParameter(aParam, aParamIndex, aMessage, aValidationFn); + return self; + } + +/** +Constructor for CIntParameter class. +@param aParam Parameter details to be encapsulated by object +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter to be represented +@panic ECMPanicBadMessageSchema in UDEB if the schema for this parameter is + incorrectly defined +*/ +CIntParameter::CIntParameter(const TParameterDetails& aParam, TInt aParamIndex, + const RMessage2& aMessage, TCustomValidationFn aValidationFn) + : CMessageParameterBase(aParam, aParamIndex, aMessage, aValidationFn) + + { + __ASSERT_DEBUG((iParamDetails.iMax >= iParamDetails.iMin), + PanicServer(ECMPanicBadMessageSchema)); + } + +/** +Destructor for CIntParameter class. +*/ +CIntParameter::~CIntParameter() + { + + } + +/** +Validates given message parameter agains constraints +represented by this object. Stores the Int value from the message + to allow for simple retrieval when required. +@leave KErrBadParameter if the message parameter does not conform + to the constraints represented by this object +@leave Any system-wide error code +*/ +void CIntParameter::ValidateL() + { + + switch(iIndex) + { + + case 0: + iValue = iMessage.Int0(); + break; + + case 1: + iValue = iMessage.Int1(); + break; + + case 2: + iValue = iMessage.Int2(); + break; + + case 3: + iValue = iMessage.Int3(); + break; + + default: + User::Leave(KErrArgument); + break; + } + + if(iValidationFn != NULL) + { + iValidationFn(this); + } + + else + { + if((iValue < iParamDetails.iMin)||(iValue > iParamDetails.iMax)) + { + User::Leave(KErrBadParameter); + } + } + } + +/** +Retrieves the TInt value read from the clients message during validation +@return The TInt value read from the client message +*/ +TInt CIntParameter::GetIntL() + { + return iValue; + } + +/** +Factory function for instantiating CDes8ReadParameter objects +@param aParam Parameter details object used to construct object. +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter to be represented +@return A fully constructed CDes8ReadParameter object. +@leave Any system-wide error code. +*/ +CMessageParameterBase* CDes8ReadParameter::NewL(const TParameterDetails& aParam, + TInt aParamIndex, const RMessage2& aMessage, TCustomValidationFn aValidationFn) + { + CDes8ReadParameter* self = + new(ELeave) CDes8ReadParameter(aParam, aParamIndex, aMessage, aValidationFn); + + return self; + } + +/** +Constructor for CDes8ReadParameter class. +@param aParam Parameter details to be encapsulated by object +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter to be represented +@panic ECMPanicBadMessageSchema in UDEB if the schema for this parameter is + incorrectly defined +*/ +CDes8ReadParameter::CDes8ReadParameter(const TParameterDetails& aParam, TInt aParamIndex, + const RMessage2& aMessage, TCustomValidationFn aValidationFn) + : CMessageParameterBase(aParam, aParamIndex, aMessage, aValidationFn) + { + __ASSERT_DEBUG((iParamDetails.iMin >= 0), + PanicServer(ECMPanicBadMessageSchema)); + + __ASSERT_DEBUG((iParamDetails.iMax > 0), + PanicServer(ECMPanicBadMessageSchema)); + + __ASSERT_DEBUG((iParamDetails.iMax >= iParamDetails.iMin), + PanicServer(ECMPanicBadMessageSchema)); + } + +/** +Destructor for CDes8ReadParameter class. +*/ +CDes8ReadParameter::~CDes8ReadParameter() + { + delete iValue; + } + +/** +Validates given message argument against constraints +represented by this object. Reads in the descriptor from the +clients message to enable simple retrival when required. +@leave KErrBadDescriptor if the message parameter does not conform + to the constraints represented by this object +@leave Any system-wide error code +*/ +void CDes8ReadParameter::ValidateL() + { + TInt length = iMessage.GetDesLengthL(iIndex); + + //if there is a supplied custom validation function, call that now + if(iValidationFn != NULL) + { + iValidationFn(this); + } + + else + { + if((length < iParamDetails.iMin) || (length > iParamDetails.iMax)) + { + User::Leave(KErrBadDescriptor); + } + } + + iValue = HBufC8::NewL(length); + TPtr8 ptr = iValue->Des(); + ReadL(ptr,0); + } + +/** +Gets the descriptor read from the clients message during validation +@return const reference to the local descriptor copy +*/ +const TDesC8& CDes8ReadParameter::GetDes8L() + { + return *iValue; + } + +/** +Gets the length of the descriptor in the client message +@return The length of the descriptor +@leave KErrBadDescriptor if the message argument is not a descriptor type + Any other system wide error code +*/ +TInt CDes8ReadParameter::GetDesLengthL() + { + return iMessage.GetDesLengthL(iIndex); + } + +/** +Retrieves the descriptor value read from the clients +message during validation +@param aDes The target descriptor. +@param aOffset The offset from the start of the clients descriptor +@leave KErrArgument if iIndex has a value outside the valid range, or if aOffset is negative. +@panic ECMPanicBadDescriptor in UDEB if the supplied descriptor is too small. +if the schema for this parameter is incorrectly defined +*/ +void CDes8ReadParameter::ReadL(TDes8& aDes, TInt aOffset) + { + __ASSERT_DEBUG((aDes.MaxLength() >= (iMessage.GetDesLengthL(iIndex) - aOffset)), + PanicServer(ECMPanicBadDescriptor)); + + iMessage.ReadL(iIndex,aDes,aOffset); + } + +/** +Factory function for instantiating CDes8WriteParameter objects +@param aParam Parameter details object used to construct object. +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter to be represented +@return A fully constructed CDes8WriteParameter object. +@leave Any system-wide error code. +*/ +CMessageParameterBase* CDes8Parameter::NewL(const TParameterDetails& aParam, + TInt aParamIndex, const RMessage2& aMessage, TCustomValidationFn aValidationFn) + { + CDes8Parameter* self = + new(ELeave) CDes8Parameter(aParam, aParamIndex, aMessage, aValidationFn); + + return self; + } + +/** +Constructor for CDes8WriteParameter class. +@param aParam Parameter details to be encapsulated by object +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter to be represented +@panic ECMPanicBadMessageSchema in UDEB if the schema for this parameter is + incorrectly defined +*/ +CDes8Parameter::CDes8Parameter(const TParameterDetails& aParam, TInt aParamIndex, + const RMessage2& aMessage, TCustomValidationFn aValidationFn) + : CMessageParameterBase(aParam, aParamIndex, aMessage, aValidationFn) + + { + __ASSERT_DEBUG((iParamDetails.iMin >= 0), + PanicServer(ECMPanicBadMessageSchema)); + + __ASSERT_DEBUG((iParamDetails.iMax >= 0), + PanicServer(ECMPanicBadMessageSchema)); + } + +/** +Destructor for CDes8WriteParameter class. +*/ +CDes8Parameter::~CDes8Parameter() + { + } + +/** +Validates given message argument against constraints +represented by this object. +@leave KErrBadDescriptor if the message parameter does not conform + to the constraints represented by this object +@leave Any system-wide error code +*/ +void CDes8Parameter::ValidateL() + { + + //if there is a supplied custom validation function, call that now + if(iValidationFn != NULL) + { + iValidationFn(this); + } + + else + { + TInt length = iMessage.GetDesLengthL(iIndex); + TInt maxLength = iMessage.GetDesMaxLengthL(iIndex); + + if((maxLength < iParamDetails.iMin)||(length > iParamDetails.iMax)) + { + User::Leave(KErrBadDescriptor); + } + } + } + +/** +Gets the length of the descriptor in the client message +@return The length of the descriptor +@leave KErrBadDescriptor if the message argument is not a descriptor type + Any other system wide error code +*/ +TInt CDes8Parameter::GetDesLengthL() + { + return iMessage.GetDesLengthL(iIndex); + } + +/** +Gets the max length of the descriptor in the client message +@return The max length of the descriptor +@leave KErrBadDescriptor if the message argument is not a descriptor type + Any other system wide error code +*/ +TInt CDes8Parameter::GetDesMaxLengthL() + { + return iMessage.GetDesMaxLengthL(iIndex); + } + + +/** +Reads a descriptor from the requested message argument +@param aDes The target descriptor. +@param aOffset The offset from the start of the clients descriptor +@leave Any system wide error code. +@panic ECMPanicBadDescriptor in UDEB if the supplied descriptor is too small. +*/ +void CDes8Parameter::ReadL(TDes8& aDes, TInt aOffset) + { + __ASSERT_DEBUG((aDes.MaxLength() >= (iMessage.GetDesLengthL(iIndex) - aOffset)), + PanicServer(ECMPanicBadDescriptor)); + + iMessage.ReadL(iIndex,aDes,aOffset); + } + +/** +Validates and writes a descriptor to the requested +message argument +@param aDes The source descriptor containing the data to be written. +@param aOffset The offset from the start of the clients descriptor +@leave Any system wide error code. +*/ +void CDes8Parameter::WriteL(const TDesC8& aDes, TInt aOffset) + { + iMessage.WriteL(iIndex,aDes,aOffset); + } + +/** +Factory function for instantiating CIntParameter objects +@param aParam Parameter details object used to construct object. +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter to be represented +@return A fully constructed CIntParameter object. +@leave Any system-wide error code. +*/ +CMessageParameterBase* CDes16ReadParameter::NewL(const TParameterDetails& aParam, + TInt aParamIndex, const RMessage2& aMessage, TCustomValidationFn aValidationFn) + { + CDes16ReadParameter* self = + new(ELeave) CDes16ReadParameter(aParam, aParamIndex, aMessage, aValidationFn); + + return self; + } + +/** +Constructor for CDes8ReadParameter class. +@param aParam Parameter details to be encapsulated by object +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter to be represented +@panic ECMPanicBadMessageSchema in UDEB if the schema for this parameter is + incorrectly defined +*/ +CDes16ReadParameter::CDes16ReadParameter(const TParameterDetails& aParam, TInt aParamIndex, + const RMessage2& aMessage, TCustomValidationFn aValidationFn) + : CMessageParameterBase(aParam, aParamIndex, aMessage, aValidationFn) + { + __ASSERT_DEBUG((iParamDetails.iMin >= 0), + PanicServer(ECMPanicBadMessageSchema)); + + __ASSERT_DEBUG((iParamDetails.iMax > 0), + PanicServer(ECMPanicBadMessageSchema)); + + __ASSERT_DEBUG((iParamDetails.iMax >= iParamDetails.iMin), + PanicServer(ECMPanicBadMessageSchema)); + } + +/** +Destructor for CDes16ReadParameter class. +*/ +CDes16ReadParameter::~CDes16ReadParameter() + { + delete iValue; + } + +/** +Validates given message argument against constraints +represented by this object. Reads in the descriptor from the +clients message to enable simple retrival when required. +@leave KErrBadDescriptor if the message parameter does not conform + to the constraints represented by this object +@leave Any system-wide error code +*/ +void CDes16ReadParameter::ValidateL() + { + TInt length = iMessage.GetDesLengthL(iIndex); + + //if there is a supplied custom validation function, call that now + if(iValidationFn != NULL) + { + iValidationFn(this); + } + + else + { + if((length < iParamDetails.iMin) || (length > iParamDetails.iMax)) + { + User::Leave(KErrBadDescriptor); + } + } + + iValue = HBufC::NewL(length); + TPtr ptr = iValue->Des(); + ReadL(ptr,0); + } + +/** +Gets the descriptor read from the clients message during validation +@return const reference to the local descriptor copy +*/ +const TDesC& CDes16ReadParameter::GetDes16L() + { + return *iValue; + } + +/** +Gets the length of the descriptor in the client message +@return The length of the descriptor +@leave KErrBadDescriptor if the message argument is not a descriptor type + Any other system wide error code +*/ +TInt CDes16ReadParameter::GetDesLengthL() + { + return iMessage.GetDesLengthL(iIndex); + } + +/** +Retrieves the descriptor value read from the clients +message during validation +@param aDes The target descriptor. +@param aOffset The offset from the start of the clients descriptor +@leave KErrArgument if the suplied descriptor is too small or an invalid + offset is supplied +@panic ECMPanicBadDescriptor in UDEB if the supplied descriptor is too small. +*/ +void CDes16ReadParameter::ReadL(TDes& aDes, TInt aOffset) + { + __ASSERT_DEBUG((aDes.MaxLength() >= (iMessage.GetDesLengthL(iIndex) - aOffset)), + PanicServer(ECMPanicBadDescriptor)); + + iMessage.ReadL(iIndex,aDes,aOffset); + } + +/** +Factory function for instantiating CDes16WriteParameter objects +@param aParam Parameter details object used to construct object. +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter to be represented +@return A fully constructed CDes16WriteParameter object. +@leave Any system-wide error code. +*/ +CMessageParameterBase* CDes16Parameter::NewL(const TParameterDetails& aParam, + TInt aParamIndex, const RMessage2& aMessage, TCustomValidationFn aValidationFn) + { + CDes16Parameter* self = + new(ELeave) CDes16Parameter(aParam, aParamIndex, aMessage, aValidationFn); + + return self; + } + +/** +Constructor for CDes16WriteParameter class. +@param aParam Parameter details to be encapsulated by object +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter to be represented +@panic ECMPanicBadMessageSchema in UDEB if the schema for this parameter is + incorrectly defined +*/ +CDes16Parameter::CDes16Parameter(const TParameterDetails& aParam, TInt aParamIndex, + const RMessage2& aMessage, TCustomValidationFn aValidationFn) + : CMessageParameterBase(aParam, aParamIndex, aMessage, aValidationFn) + { + __ASSERT_DEBUG((iParamDetails.iMin >= 0), + PanicServer(ECMPanicBadMessageSchema)); + __ASSERT_DEBUG((iParamDetails.iMax >= 0), + PanicServer(ECMPanicBadMessageSchema)); + } + +/** +Destructor for CDes16WriteParameter class. +*/ +CDes16Parameter::~CDes16Parameter() + { + + } + +/** +Validates given message argument against constraints +represented by this object. +@leave KErrBadDescriptor if the message parameter does not conform + to the constraints represented by this object +@leave Any system-wide error code +*/ +void CDes16Parameter::ValidateL() + { + + //if there is a supplied custom validation function, call that now + if(iValidationFn != NULL) + { + iValidationFn(this); + } + else + { + TInt length = iMessage.GetDesLengthL(iIndex); + TInt maxLength = iMessage.GetDesMaxLengthL(iIndex); + + if((maxLength < iParamDetails.iMin)||(length > iParamDetails.iMax)) + { + User::Leave(KErrBadDescriptor); + } + } + } + +/** +Gets the length of the descriptor in the client message +@return The length of the descriptor +@leave KErrBadDescriptor if the message argument is not a descriptor type + Any other system wide error code +*/ +TInt CDes16Parameter::GetDesLengthL() + { + return iMessage.GetDesLengthL(iIndex); + } + +/** +Gets the max length of the descriptor in the client message +@return The max length of the descriptor +@leave KErrBadDescriptor if the message argument is not a descriptor type + Any other system wide error code +*/ +TInt CDes16Parameter::GetDesMaxLengthL() + { + return iMessage.GetDesMaxLengthL(iIndex); + } + +/** +Reads a descriptor from the requested message argument +@param aDes The target descriptor. +@param aOffset The offset from the start of the clients descriptor +@leave Any system wide error code. +@panic ECMPanicBadDescriptor in UDEB if the supplied descriptor is too small. +*/ +void CDes16Parameter::ReadL(TDes& aDes, TInt aOffset) + { + __ASSERT_DEBUG((aDes.MaxLength() >= (iMessage.GetDesLengthL(iIndex) - aOffset)), + PanicServer(ECMPanicBadDescriptor)); + + iMessage.ReadL(iIndex,aDes,aOffset); + } + +/** +Writes a descriptor to the requested message argument +@param aDes The source descriptor containing the data to be written. +@param aOffset The offset from the start of the clients descriptor +@leave Any system wide error code. +*/ +void CDes16Parameter::WriteL(const TDesC& aDes, TInt aOffset) + { + iMessage.WriteL(iIndex,aDes,aOffset); + } + +/** +Factory function for instantiating CPckgParameter objects +@param aParam Parameter details object used to construct object. +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter to be represented +@return A fully constructed CPckgParameter object. +@leave Any system-wide error code. +*/ +CMessageParameterBase* CPckgParameter::NewL(const TParameterDetails& aParam, + TInt aParamIndex, const RMessage2& aMessage, TCustomValidationFn aValidationFn ) + { + CPckgParameter* self = + new(ELeave) CPckgParameter(aParam, aParamIndex, aMessage, aValidationFn); + + return self; + } + +/** +Constructor for CPckgParameter class. +@param aParam Parameter details to be encapsulated by object +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter to be represented +*/ +CPckgParameter::CPckgParameter(const TParameterDetails& aParam, TInt aParamIndex, + const RMessage2& aMessage, TCustomValidationFn aValidationFn) + : CDes8Parameter(aParam, aParamIndex, aMessage, aValidationFn) + + { + + } + +/** +Destructor for CPckgParameter class. +*/ +CPckgParameter::~CPckgParameter() + { + } + +/** +Validates given message argument against constraints +represented by this object. +@leave KErrBadDescriptor if the message parameter does not conform + to the constraints represented by this object +@leave Any system-wide error code +*/ +void CPckgParameter::ValidateL() + { + + //if there is a supplied custom validation function, call that now + if(iValidationFn != NULL) + { + iValidationFn(this); + } + + else + { + TInt length = iMessage.GetDesLengthL(iIndex); + + if((length < iParamDetails.iMin)||(length > iParamDetails.iMax)) + { + User::Leave(KErrBadDescriptor); + } + } + } + +/** +Factory function for instantiating CPtrParameter objects +@param aParam Parameter details object used to construct object. +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter to be represented +@return A fully constructed CPtrParameter object. +@leave Any system-wide error code. +*/ +CMessageParameterBase* CPtrParameter::NewL(const TParameterDetails& aParam, + TInt aParamIndex, const RMessage2& aMessage, TCustomValidationFn aValidationFn) + { + CPtrParameter* self = new(ELeave) CPtrParameter(aParam, aParamIndex, aMessage, aValidationFn); + return self; + } + +/** +Constructor for CPtrParameter class. +@param aParamIndex The Index of this parameter within the RMessage2 arguments +@param aMessage The RMessage2 object containing the parameter to be represented +*/ +CPtrParameter::CPtrParameter(const TParameterDetails& aParam, TInt aParamIndex, + const RMessage2& aMessage, TCustomValidationFn aValidationFn) + : CMessageParameterBase(aParam, aParamIndex, aMessage, aValidationFn) + { + + } + +/** +Validates given message argument against constraints +represented by this object. Stores the TAny* from the +clients message to enable simple retrival when required. +@leave KErrArgument if the argument index is invalid +@leave Any system-wide error code +*/ +void CPtrParameter::ValidateL() + { + + switch(iIndex) + { + + case 0: + iValue = iMessage.Ptr0(); + break; + + case 1: + iValue = iMessage.Ptr1(); + break; + + case 2: + iValue = iMessage.Ptr2(); + break; + + case 3: + iValue = iMessage.Ptr3(); + break; + + default: + User::Leave(KErrArgument); + break; + } + + //if there is a supplied custom validation function, call that now + if(iValidationFn != NULL) + { + iValidationFn(this); + } + } + +/** +Retrieves the TAny pointer read from the clients message during validation +@return The TAny pointer read from the client message +*/ +const TAny* CPtrParameter::GetPtrL() + { + return iValue; + } + +/** +Decode the string +@param aSrcString Source string +@param rDestString Destination string +@return 1 if aSrcString is not long enough to decode fully, resulting in the storage of + the last character and requiring another aSrcString (poss 0 length) to be passed to it to + clear this character. +@return 0 if the line was decoded OK or the end of the encoded file is reached ie "=" +*/ + +EXPORT_C TInt Base64Codec::Decode(const TDesC8& aSrcString, TDes8& rDestString) + { + TInt shiftStored = 0; + TInt maskShiftStored = ESix; + + TInt decodedInt=0; + TInt8 offsetChar=0; + TUint8 decodedChar=0; + + // Clears the destination string + rDestString.Zero(); + + // Initialise variables + const TUint8* srcStringPtr=aSrcString.Ptr(); + const TUint8* srcStringEnd=aSrcString.Length()+srcStringPtr; + TUint8* destStringPtr=(TUint8*)rDestString.Ptr(); + TUint8* destStringPtrBase=destStringPtr; + + TInt maskShift=maskShiftStored; + TInt shiftStorage=shiftStored; + + // Main character process loop + while(srcStringPtr=0)&&(offsetChar<80)) + { + // Read in next character and B64 decode + decodedInt=AsciiToBase64[offsetChar]; + + // Exits when a PAD char is reached + if(decodedInt==EPadChar) + { + rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase)); + return EFalse; + } + + // Ensures the first 2 chars of 4 are received before processing + if(maskShift==ESix) + maskShift=EFour; + else + { + shiftStorage=shiftStorage<>maskShift)&EEightBitMask); + + if((maskShift-=ETwo)>maskShift)&ESixBitMask)]; + + *destStringPtr++=encodedChar; + destStringCharNum++; + + // Add a CRLF every KMaxB64EncodedCharsPerLine characters so as not to exceed the line length + // limitation specified in RFC 2822. + if (destStringCharNum == KMaxB64EncodedCharsPerLine) + { + destStringCharNum = 0; + *destStringPtr++ = '\r'; + *destStringPtr++ = '\n'; + } + } + + // Check for not enough chars and pad if required + if (maskShift==EFour) + { + *destStringPtr++=KImcvConvEquals; + *destStringPtr++=KImcvConvEquals; + } + else + if(maskShift==ESix) + *destStringPtr++=KImcvConvEquals; + + rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase)); + return ((TInt)(srcStringPtr-srcStringEnd)); + }