--- /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<KMaxServerNameLength> serverName(KUnknownServer);
+
+ //Get the TLS data for this thread
+ TClientMessageServerData* serverData = static_cast<TClientMessageServerData*>(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<const TClientMessageServerData*>(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<KMaxServerNameLength> 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<KMaxServerNameLength> 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<TClientMessageServerData*>(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<srcStringEnd)
+ {
+ offsetChar=(TInt8)(*srcStringPtr-KImcvLookUpStartOffset);
+ srcStringPtr++;
+
+ // Check for valid B64 character
+ if((offsetChar>=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<<ESix;
+ shiftStorage=shiftStorage|decodedInt;
+ decodedChar=(TUint8)((shiftStorage>>maskShift)&EEightBitMask);
+
+ if((maskShift-=ETwo)<EZero)
+ maskShift=ESix;
+
+ *destStringPtr++=decodedChar;
+ }
+ shiftStorage=decodedInt;
+ }
+ }
+ shiftStored=shiftStorage;
+ maskShiftStored=maskShift;
+
+ rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase));
+
+ return maskShift<ESix;
+ }
+
+/**
+Encode the string
+@param aSrcString Source string
+@param rDestString Destination string
+@return 1 if aSrcString is not long enough to encode fully
+@return 0 if the line was encoded OK
+*/
+EXPORT_C TInt Base64Codec::Encode(const TDesC8& aSrcString, TDes8& rDestString)
+ {
+ // 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 character=0;
+ TUint8 encodedChar=0;
+ TInt charStorage=0;
+ TInt maskShift=EZero;
+ TInt destStringCharNum = 0;
+
+ while(srcStringPtr<=srcStringEnd)
+ {
+ // maskShift is used as a char read counter
+ if(maskShift==ESix)
+ {
+ // If the 3rd char read is also the last char then the while loop
+ // is broken on the next check.
+ if(srcStringPtr==srcStringEnd)
+ srcStringPtr++;
+ maskShift=EZero;
+ character=0;
+ }
+ else
+ {
+ if(srcStringPtr==srcStringEnd)
+ character=0;
+ else
+ character=*srcStringPtr;
+
+ srcStringPtr++;
+ // Shifts charStorage ready for the next char
+ charStorage=charStorage<<8;
+ maskShift+=ETwo;
+ }
+ charStorage=charStorage|character;
+ // Shifts the mask to the correct bit location
+ // Masks (AND's) the valid bits from charStorage
+ // Shifts the valid bits into the low order 8bits
+ // Converts to BASE64 char, Casts the result to an unsigned char (which it should be ?....I hope)
+ encodedChar=(TUint8)Base64ToAscii[((charStorage>>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));
+ }