// Copyright (c) 2007-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:
//
/**
@file
*/
#include "nm_signatures.h"
#include "nm_messages_base.h"
#include "nm_messages_errorrecovery.h"
#include "nm_node.h"
#include <elements/interfacetable.h>
#include <elements/metatype.h>
#ifdef _DEBUG
// Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
// (if it could happen through user error then you should give it an explicit, documented, category + code)
_LIT(KSpecAssert_ElemNodeMessMesC, "ElemNodeMessMesC");
#endif
using namespace Messages;
using namespace Elements;
using namespace Meta;
//We can safely reuse this UID for signature's TIDs (but they mean different things)
static const TInt KNodeMessagesImplementationUid = TEBase::ERealmId;
// --- TSignatureBase ---
EXPORT_C TSignatureBase::TSignatureBase()
{
}
EXPORT_C TSignatureBase::TSignatureBase(const TNodeSignal::TMessageId& aMessageId)
: TNodeSignal(aMessageId)
{
}
EXPORT_C void TSignatureBase::DispatchL(const TRuntimeCtxId& aSender, const TRuntimeCtxId& aRecipient)
{
const TNodeId& nodeId = address_cast<TNodeId>(aRecipient); //This message type operates on nodes
__ASSERT_DEBUG(nodeId.Ptr(), User::Panic(KSpecAssert_ElemNodeMessMesC, 1));
nodeId.Node().ReceivedL(aSender, nodeId, *this);
}
EXPORT_C void TSignatureBase::Error(const TRuntimeCtxId& aSender, const TRuntimeCtxId& aRecipient, TInt aError)
{
NM_LOG((KNodeMessagesSubTag, _L8("TSignatureBase %08x:\tError(%d)"), this, aError));
if (!aSender.IsNull())
{
NM_LOG((KNodeMessagesSubTag, _L8("Sending TError")));
RClientInterface::OpenPostMessageClose(aRecipient, aSender, TEBase::TError(MessageId(), aError).CRef());
}
}
enum EMessageTypeId //message signatures only (NOT messages) messages are declared under class TMessage
{
ESignalBase =0,
ENodeSignal =1,
ESignatureBase =2,
ESignatureNumber =3,
ESignatureUid =4,
ESignatureErrContext =5,
ESignatureErrResponse =6,
//empty =7,
ESignatureNodeId =8,
ESignatureNodeIdNumber =9,
ESignatureNodeIdNumberNumber =10,
ESignatureMessageIdNumber =11,
ESignatureAnyNumber =12,
ESignatureMetaDataPtr =13, //the data itslef is not copied it stays owned by whoever allocated it
//unless agreed otherwise upon the actuall message
ESignatureNumberNumberNumber =14,
ESignatureRMessage2 =15,
ESignatureNumberRMessage2 =16,
ESignatureAny =17,
ESignatureNumberNumber =18,
ESignatureNodeIdAny =19,
ESignatureNodeIdNodeId =20,
ESignatureNodeIdNodeIdNumber =21,
ESignatureNumberNumberNumberNumber =22,
ESignatureUidNumber =23,
ESignatureNumberUidNumber =24,
ESignatureNodeIdClientType =25,
ESignatureClientTypeUidClientType =26,
ESignatureClientType =27,
ESignatureClientTypeUid =28,
ESignatureMessageId =29,
ESignatureNodeIdNumberNumberNumber =30,
ESignatureTypeId =31,
ESignatureTypeIdAnyNumber =32
};
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSignalBase, KNodeMessagesImplementationUid, ESignalBase )
END_ATTRIBUTE_TABLE()
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TNodeSignal, KNodeMessagesImplementationUid, ENodeSignal )
REGISTER_ATTRIBUTE( TNodeSignal, iMessageId, TMeta<TNodeSignal::TMessageId> )
END_ATTRIBUTE_TABLE_BASE( TSignalBase, ESignalBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSignatureBase, KNodeMessagesImplementationUid, ESignatureBase )
END_ATTRIBUTE_TABLE_BASE( TNodeSignal, ENodeSignal )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigErrContext, KNodeMessagesImplementationUid, ESignatureErrContext )
REGISTER_ATTRIBUTE( TSigErrContext, iErrContext, TMeta<TErrContext> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigErrResponse, KNodeMessagesImplementationUid, ESignatureErrResponse )
REGISTER_ATTRIBUTE( TSigErrResponse, iErrResponse, TMeta<TErrResponse> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigNumber, KNodeMessagesImplementationUid, ESignatureNumber )
REGISTER_ATTRIBUTE( TSigNumber, iValue, TMetaNumber )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigUid, KNodeMessagesImplementationUid, ESignatureUid )
REGISTER_ATTRIBUTE( TSigUid, iUid, TMeta<TUid> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigNodeId, KNodeMessagesImplementationUid, ESignatureNodeId )
REGISTER_ATTRIBUTE( TSigNodeId, iNodeId, TMeta<TNodeId> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigNodeIdNumber, KNodeMessagesImplementationUid, ESignatureNodeIdNumber )
REGISTER_ATTRIBUTE( TSigNodeIdNumber, iNodeId, TMeta<TNodeId> )
REGISTER_ATTRIBUTE( TSigNodeIdNumber, iValue, TMetaNumber )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigNodeIdClientType, KNodeMessagesImplementationUid, ESignatureNodeIdClientType )
REGISTER_ATTRIBUTE( TSigNodeIdClientType, iNodeId, TMeta<TNodeId> )
REGISTER_ATTRIBUTE( TSigNodeIdClientType, iClientType, TMeta<TClientType> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigNodeIdNumberNumber, KNodeMessagesImplementationUid, ESignatureNodeIdNumberNumber )
REGISTER_ATTRIBUTE( TSigNodeIdNumberNumber, iNodeId, TMeta<TNodeId> )
REGISTER_ATTRIBUTE( TSigNodeIdNumberNumber, iValue1, TMetaNumber )
REGISTER_ATTRIBUTE( TSigNodeIdNumberNumber, iValue2, TMetaNumber )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigMessageIdNumber, KNodeMessagesImplementationUid, ESignatureMessageIdNumber )
REGISTER_ATTRIBUTE( TSigMessageIdNumber, iMsgId, TMeta<TNodeSignal::TMessageId> )
REGISTER_ATTRIBUTE( TSigMessageIdNumber, iValue, TMetaNumber )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigNumberNumberNumber, KNodeMessagesImplementationUid, ESignatureNumberNumberNumber )
REGISTER_ATTRIBUTE( TSigNumberNumberNumber, iValue1, TMetaNumber )
REGISTER_ATTRIBUTE( TSigNumberNumberNumber, iValue2, TMetaNumber )
REGISTER_ATTRIBUTE( TSigNumberNumberNumber, iValue3, TMetaNumber )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigNumberNumberNumberNumber, KNodeMessagesImplementationUid, ESignatureNumberNumberNumberNumber )
REGISTER_ATTRIBUTE( TSigNumberNumberNumberNumber, iValue1, TMetaNumber )
REGISTER_ATTRIBUTE( TSigNumberNumberNumberNumber, iValue2, TMetaNumber )
REGISTER_ATTRIBUTE( TSigNumberNumberNumberNumber, iValue3, TMetaNumber )
REGISTER_ATTRIBUTE( TSigNumberNumberNumberNumber, iValue4, TMetaNumber )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigNodeIdNodeIdNumber, KNodeMessagesImplementationUid, ESignatureNodeIdNodeIdNumber )
REGISTER_ATTRIBUTE( TSigNodeIdNodeIdNumber, iNodeId1, TMeta<TNodeId> )
REGISTER_ATTRIBUTE( TSigNodeIdNodeIdNumber, iNodeId2, TMeta<TNodeId> )
REGISTER_ATTRIBUTE( TSigNodeIdNodeIdNumber, iValue, TMetaNumber )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigMetaDataPtr, KNodeMessagesImplementationUid, ESignatureMetaDataPtr )
REGISTER_ATTRIBUTE( TSigMetaDataPtr, iPtr, TMeta<Meta::SMetaData*> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigRMessage2, KNodeMessagesImplementationUid, ESignatureRMessage2 )
REGISTER_ATTRIBUTE( TSigRMessage2, iMessage, TMeta<RMessage2> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigNumberRMessage2, KNodeMessagesImplementationUid, ESignatureNumberRMessage2 )
REGISTER_ATTRIBUTE( TSigNumberRMessage2, iValue, TMetaNumber )
REGISTER_ATTRIBUTE( TSigNumberRMessage2, iMessage, TMeta<RMessage2> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigAny, KNodeMessagesImplementationUid, ESignatureAny )
REGISTER_ATTRIBUTE( TSigAny, iPtr, TMeta<TAny*> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigAnyNumber, KNodeMessagesImplementationUid, ESignatureAnyNumber )
REGISTER_ATTRIBUTE( TSigAnyNumber, iPtr, TMeta<TAny*> )
REGISTER_ATTRIBUTE( TSigAnyNumber, iValue, TMetaNumber )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigUidNumber, KNodeMessagesImplementationUid, ESignatureUidNumber )
REGISTER_ATTRIBUTE( TSigUidNumber, iUid, TMeta<TUid> )
REGISTER_ATTRIBUTE( TSigUidNumber, iValue, TMetaNumber )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigNumberNumber, KNodeMessagesImplementationUid, ESignatureNumberNumber )
REGISTER_ATTRIBUTE( TSigNumberNumber, iValue1, TMetaNumber )
REGISTER_ATTRIBUTE( TSigNumberNumber, iValue2, TMetaNumber )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigNodeIdAny, KNodeMessagesImplementationUid, ESignatureNodeIdAny )
REGISTER_ATTRIBUTE( TSigNodeIdAny, iNodeId, TMeta<TNodeId> )
REGISTER_ATTRIBUTE( TSigNodeIdAny, iPtr, TMeta<TAny*> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigNodeIdNodeId, KNodeMessagesImplementationUid, ESignatureNodeIdNodeId )
REGISTER_ATTRIBUTE( TSigNodeIdNodeId, iNodeId1, TMeta<TNodeId> )
REGISTER_ATTRIBUTE( TSigNodeIdNodeId, iNodeId2, TMeta<TNodeId> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigNumberUidNumber, KNodeMessagesImplementationUid, ESignatureNumberUidNumber )
REGISTER_ATTRIBUTE( TSigNumberUidNumber, iValue1, TMetaNumber )
REGISTER_ATTRIBUTE( TSigNumberUidNumber, iUid, TMeta<TUid> )
REGISTER_ATTRIBUTE( TSigNumberUidNumber, iValue2, TMetaNumber )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigClientTypeUidClientType, KNodeMessagesImplementationUid, ESignatureClientTypeUidClientType )
REGISTER_ATTRIBUTE( TSigClientTypeUidClientType, iClientType1, TMeta<TClientType> )
REGISTER_ATTRIBUTE( TSigClientTypeUidClientType, iUid, TMeta<TUid> )
REGISTER_ATTRIBUTE( TSigClientTypeUidClientType, iClientType2, TMeta<TClientType> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigClientType, KNodeMessagesImplementationUid, ESignatureClientType )
REGISTER_ATTRIBUTE( TSigClientType, iClientType, TMeta<TClientType> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigClientTypeUid, KNodeMessagesImplementationUid, ESignatureClientTypeUid )
REGISTER_ATTRIBUTE( TSigClientTypeUid, iClientType, TMeta<TClientType> )
REGISTER_ATTRIBUTE( TSigClientTypeUid, iUid, TMeta<TUid> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigMessageId, KNodeMessagesImplementationUid, ESignatureMessageId )
REGISTER_ATTRIBUTE( TSigMessageIdNumber, iMsgId, TMeta<TNodeSignal::TMessageId> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigNodeIdNumberNumberNumber, KNodeMessagesImplementationUid, ESignatureNodeIdNumberNumberNumber )
REGISTER_ATTRIBUTE( TSigNodeIdNumberNumberNumber, iNodeId, TMeta<TNodeId> )
REGISTER_ATTRIBUTE( TSigNodeIdNumberNumberNumber, iValue1, TMetaNumber )
REGISTER_ATTRIBUTE( TSigNodeIdNumberNumberNumber, iValue2, TMetaNumber )
REGISTER_ATTRIBUTE( TSigNodeIdNumberNumberNumber, iValue3, TMetaNumber )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigTypeId, KNodeMessagesImplementationUid, ESignatureTypeId )
REGISTER_ATTRIBUTE( TSigTypeId, iTypeId, TMeta<STypeId> )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
EXPORT_START_ATTRIBUTE_TABLE_AND_FN( TSigTypeIdAnyNumber, KNodeMessagesImplementationUid, ESignatureTypeIdAnyNumber )
REGISTER_ATTRIBUTE( TSigTypeIdAnyNumber, iTypeId, TMeta<Meta::STypeId> )
REGISTER_ATTRIBUTE( TSigTypeIdAnyNumber, iPtr, TMeta<TAny*> )
REGISTER_ATTRIBUTE( TSigTypeIdAnyNumber, iValue, TMetaNumber )
END_ATTRIBUTE_TABLE_BASE( TSignatureBase, ESignatureBase )
DEFINE_MVIP_CTR(TSignatureBase);
DEFINE_MVIP_CTR(TSigErrContext);
DEFINE_MVIP_CTR(TSigErrResponse);
DEFINE_MVIP_CTR(TSigNumber);
DEFINE_MVIP_CTR(TSigUid);
DEFINE_MVIP_CTR(TSigNodeId);
DEFINE_MVIP_CTR(TSigNodeIdNumber);
DEFINE_MVIP_CTR(TSigNodeIdNumberNumber);
DEFINE_MVIP_CTR(TSigMessageIdNumber);
DEFINE_MVIP_CTR(TSigNumberNumberNumber);
DEFINE_MVIP_CTR(TSigNumberNumberNumberNumber);
DEFINE_MVIP_CTR(TSigNodeIdNodeIdNumber);
DEFINE_MVIP_CTR(TSigMetaDataPtr)
DEFINE_MVIP_CTR(TSigRMessage2)
DEFINE_MVIP_CTR(TSigNumberRMessage2)
DEFINE_MVIP_CTR(TSigAny)
DEFINE_MVIP_CTR(TSigAnyNumber)
DEFINE_MVIP_CTR(TSigUidNumber)
DEFINE_MVIP_CTR(TSigNumberNumber)
DEFINE_MVIP_CTR(TSigNodeIdAny)
DEFINE_MVIP_CTR(TSigNodeIdNodeId)
DEFINE_MVIP_CTR(TSigNumberUidNumber)
DEFINE_MVIP_CTR(TSigNodeIdClientType)
DEFINE_MVIP_CTR(TSigClientTypeUidClientType)
DEFINE_MVIP_CTR(TSigClientType)
DEFINE_MVIP_CTR(TSigClientTypeUid)
DEFINE_MVIP_CTR(TSigMessageId);
DEFINE_MVIP_CTR(TSigNodeIdNumberNumberNumber);
DEFINE_MVIP_CTR(TSigTypeId);
DEFINE_MVIP_CTR(TSigTypeIdAnyNumber);
const TImplementationProxy SignatureImplementationTable[] =
{
//NOTE: Entries must be sorted for the binary search to work efficiently!
MVIP_CTR_ENTRY(ESignatureBase,TSignatureBase), //2
MVIP_CTR_ENTRY(ESignatureNumber,TSigNumber), //3
MVIP_CTR_ENTRY(ESignatureUid,TSigUid), //4
MVIP_CTR_ENTRY(ESignatureErrContext,TSigErrContext), //5
MVIP_CTR_ENTRY(ESignatureErrResponse,TSigErrResponse), //6
//empty slot
MVIP_CTR_ENTRY(ESignatureNodeId,TSigNodeId), //8
MVIP_CTR_ENTRY(ESignatureNodeIdNumber,TSigNodeIdNumber), //9
MVIP_CTR_ENTRY(ESignatureNodeIdNumberNumber,TSigNodeIdNumberNumber), //10
MVIP_CTR_ENTRY(ESignatureMessageIdNumber,TSigMessageIdNumber), //11
MVIP_CTR_ENTRY(ESignatureAnyNumber,TSigAnyNumber), //12
MVIP_CTR_ENTRY(ESignatureMetaDataPtr,TSigMetaDataPtr), //13
MVIP_CTR_ENTRY(ESignatureNumberNumberNumber,TSigNumberNumberNumber), //14
MVIP_CTR_ENTRY(ESignatureRMessage2,TSigRMessage2), //15
MVIP_CTR_ENTRY(ESignatureNumberRMessage2,TSigNumberRMessage2), //16
MVIP_CTR_ENTRY(ESignatureAny,TSigAny), //17
MVIP_CTR_ENTRY(ESignatureNumberNumber,TSigNumberNumber), //18
MVIP_CTR_ENTRY(ESignatureNodeIdAny,TSigNodeIdAny), //19
MVIP_CTR_ENTRY(ESignatureNodeIdNodeId,TSigNodeIdNodeId), //20
MVIP_CTR_ENTRY(ESignatureNodeIdNodeIdNumber,TSigNodeIdNodeIdNumber), //21
MVIP_CTR_ENTRY(ESignatureNumberNumberNumberNumber,TSigNumberNumberNumberNumber),//22
MVIP_CTR_ENTRY(ESignatureUidNumber,TSigUidNumber), //23
MVIP_CTR_ENTRY(ESignatureNumberUidNumber,TSigNumberUidNumber), //24
MVIP_CTR_ENTRY(ESignatureNodeIdClientType,TSigNodeIdClientType), //25
MVIP_CTR_ENTRY(ESignatureClientTypeUidClientType,TSigClientTypeUidClientType), //26
MVIP_CTR_ENTRY(ESignatureClientType,TSigClientType), //27
MVIP_CTR_ENTRY(ESignatureClientTypeUid,TSigClientTypeUid), //28
MVIP_CTR_ENTRY(ESignatureMessageId,TSigMessageId), //29
MVIP_CTR_ENTRY(ESignatureNodeIdNumberNumberNumber,TSigNodeIdNumberNumberNumber),//30
MVIP_CTR_ENTRY(ESignatureTypeId,TSigTypeId), //31
MVIP_CTR_ENTRY(ESignatureTypeIdAnyNumber,TSigTypeIdAnyNumber) //32
};
/*ststic*/ void TEBase::RegisterL(CGlobals& aGlobals)
{
aGlobals.RegisterInterfaceL(TUid::Uid(KNodeMessagesImplementationUid), sizeof(SignatureImplementationTable) / sizeof(SignatureImplementationTable[0]), SignatureImplementationTable);
}
/*ststic*/ void TEBase::DeRegister(CGlobals& aGlobals)
{
aGlobals.DeregisterInterface(TUid::Uid(KNodeMessagesImplementationUid));
}
EXPORT_C Meta::SMetaData* TVCFromGlobalsMessagePayloadCreationPolicy::New(TPtrC8& aSrc, TPtr8& aDst)
{
Meta::SMetaData* payload = NULL;
Meta::CMetaDataVirtualCtorInPlace* vctr = TlsGlobals::Get().VirtualCtor();
if (vctr)
{
__ASSERT_DEBUG(aSrc.Length() >= sizeof(STypeId), User::Panic(KSpecAssert_ElemNodeMessMesC, 2)); //At least the type id must be present
TUid uid = *reinterpret_cast<const TUid*>(aSrc.Ptr());
if (vctr->IsInterfaceRegistered(uid))
{
payload = vctr->New(aSrc, aDst);
}
}
return payload;
}
EXPORT_C TSignatureWithPolymorphicPayloadMetaTypeBase::TSignatureWithPolymorphicPayloadMetaTypeBase(TUint8* aData, SMetaData** aPayload, TInt aHostSize)
: iData(aData),
iPayload(aPayload),
iHostSize(aHostSize)
{
}
EXPORT_C TInt TSignatureWithPolymorphicPayloadMetaTypeBase::InternalLoad(TPtrC8& aBuffer, TDes8& aTempBuffer)
{
*iPayload = NULL; //will be set from the buffer, needs to be initialised for length
if (aBuffer.Length() < iHostSize)
{
return KErrArgument;
}
Mem::Copy(iData, aBuffer.Ptr(), iHostSize); //including the ptr (length)
aBuffer.Set(aBuffer.Ptr() + iHostSize, aBuffer.Length() - iHostSize); //update pointer
TInt payloadLength = *(reinterpret_cast<TInt32*>(iPayload)); //payload length only
if (payloadLength)
{
if (payloadLength < 0 || aBuffer.Length() < payloadLength || payloadLength > aTempBuffer.MaxLength())
{
return KErrArgument;
}
aTempBuffer.Copy(aBuffer.Ptr(), payloadLength); //aBuffer already moved to the end
}
return KErrNone; //regardless of *iData being initialised (NULL if not)
}
EXPORT_C TInt TSignatureWithPolymorphicPayloadMetaTypeBase::Store(TDes8& aBuffer) const
{
TInt len = Length();
if (aBuffer.MaxLength() - aBuffer.Length() < len) //including payload if present
{
return KErrOverflow;
}
TInt offsetToPayload = (TUint8*)iPayload - iData;
TPtr8 payloadPtr(const_cast<TUint8*>(aBuffer.Ptr()) + aBuffer.Length() + offsetToPayload, sizeof(SMetaData*));
aBuffer.Append(iData, iHostSize); //Store all including the ptr
len = 0; //Reset the len - now it means payload length only
if (*iPayload)
{
len = (*iPayload)->Length(); //payload length only
TInt error = (*iPayload)->Store(aBuffer);
if (error!=KErrNone)
{
return error;
}
}
//Store the length where the pointer is stored
payloadPtr.Append(reinterpret_cast<TUint8*>(&len), sizeof(SMetaData*));
return KErrNone;
}
EXPORT_C void TSignatureWithPolymorphicPayloadMetaTypeBase::Copy(const TAny* aData)
{
TInt offset = (TUint8*)iPayload - iData;
const TUint8* srcdata = reinterpret_cast<const TUint8*>(aData) + sizeof(SMetaData*) - offset;
Mem::Copy(iData, srcdata, iHostSize);
SMetaData* const* srcpayload = reinterpret_cast<SMetaData* const*>(aData);
if (*iPayload && *srcpayload)
{
(*iPayload)->Copy(**srcpayload);
}
}
EXPORT_C TInt TSignatureWithPolymorphicPayloadMetaTypeBase::Length() const
{
TInt len = iHostSize; //including the ptr
if (*iPayload)
{
len += (*iPayload)->Length(); //the payload
}
return len;
}