diff -r 000000000000 -r dfb7c4ff071f commsfwsupport/commselements/NetMeta/src/MetaData.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/commsfwsupport/commselements/NetMeta/src/MetaData.cpp Thu Dec 17 09:22:25 2009 +0200 @@ -0,0 +1,332 @@ +// Copyright (c) 2004-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 + @internalTechnology +*/ + +#include +#include +#include +#include + + +#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_ElemNetMetaMtDt, "ElemNetMetaMtDt."); +#endif + +// Maximum size of the MMetaType based object in terms of sizeof(TAny*). +// KMMetaTypeMaxSize * sizeof(TAny*) is the size of the memory reserved +// on the stack for the in-place instantiation. +const TInt KMMetaTypeMaxSize = 10; + + +using namespace Meta; + +#ifdef SYMBIAN_NETWORKING_CFTRANSPORT +EXPORT_C STypeId STypeId::CreateSTypeId(TPtrC8& aDes) + { + // check no padding, so no alignment worries in copying single block + STypeId id; + __ASSERT_COMPILE(sizeof(STypeId) == sizeof(id.iUid) + sizeof(id.iType)); + + Mem::Copy(&id, aDes.Ptr(), sizeof(STypeId)); + + // trim typeid from front of store + aDes.Set(aDes.Ptr() + sizeof(STypeId), aDes.Length() - sizeof(STypeId)); + return id; + } +#endif + +EXPORT_C TInt STypeId::Check( TPtrC8& aDes ) const + { + if (aDes.Length() < (TInt)sizeof(STypeId)) + { + return KErrArgument; + } + STypeId typeId; + Mem::Copy(&typeId, aDes.Ptr(), sizeof(STypeId)); + TInt error = KErrArgument; + if ( *this == typeId ) + {//update pointer (type) only if the type matches + aDes.Set(aDes.Ptr()+sizeof(STypeId),aDes.Length()-sizeof(STypeId)); + error = KErrNone; + } + return error; + } + +EXPORT_C SMetaData::SMetaData() +/** + * Protected and explicit constructor + */ + { + } + +EXPORT_C SMetaData::~SMetaData() +/** + * Virtual destructor + */ + { + } + +EXPORT_C TInt SMetaData::CheckTypeOf( TPtrC8& aDes ) const + { + if (aDes.Length() < (TInt)sizeof(STypeId)) + { + return KErrArgument; + } + STypeId typeId; + Mem::Copy(&typeId, aDes.Ptr(), sizeof(STypeId)); + TInt error = KErrArgument; + if ( IsTypeOf(typeId) ) + {//update pointer (type) only if the type matches + aDes.Set(aDes.Ptr()+sizeof(STypeId),aDes.Length()-sizeof(STypeId)); + error = KErrNone; + } + return error; + } + +EXPORT_C STypeId SMetaData::GetTypeId() const + { + const SVDataTableEntry* entry = GetVDataTable(); + __ASSERT_DEBUG( entry , User::Panic(KSpecAssert_ElemNetMetaMtDt, 1)); + return STypeId::CreateSTypeId( entry->iOffset, reinterpret_cast(entry->iMetaNewL) ); + } + +EXPORT_C TInt SMetaData::IsTypeOf( const STypeId& aTypeId ) const + { + const SVDataTableEntry* entry = GetVDataTable(); + __ASSERT_DEBUG( entry , User::Panic(KSpecAssert_ElemNetMetaMtDt, 2)); + for(;;) + { + STypeId typeId = { entry->iOffset, reinterpret_cast(entry->iMetaNewL) }; + if ( typeId == aTypeId ) + { + return 1; + } + //move through the table + while ( (++entry)->iMetaNewL ) {;} + if ( !entry->iOffset ) + { + break; + } + typedef SVDataTableEntry* (*TMetaBaseTableNewL)(); + entry = reinterpret_cast(entry->iOffset)(); + } + return 0; + } + +EXPORT_C void SMetaData::Copy(const SMetaData& aSource) +/** + * Copies values of a SMetaData object's properties into properties of *this. + * Both meta objects are of the same type. + */ + { + __ASSERT_DEBUG(GetTypeId()==aSource.GetTypeId(),User::Panic(_L("SMetaData"),KErrArgument)); + + TAny* mem[KMMetaTypeMaxSize]; + TMetaVTableIterator attribIter(this); + SVDataTableEntry const* entry; + while ((entry = attribIter++) != NULL) + { + MMetaType* metaType = entry->iMetaNewL(mem,GetAttribPtr(entry->iOffset)); + metaType->Copy(aSource.GetAttribPtr(entry->iOffset)); + } + } + +EXPORT_C TInt SMetaData::Store(TDes8& aDes) const +/** + * Stores the meta object into a descriptor + */ + { + const STypeId& typeId = GetTypeId(); + TInt len = Length(); + + if ((aDes.MaxLength()-aDes.Length()) < len) + { + return KErrOverflow; + } + + aDes.Append((TUint8*)&typeId,sizeof(STypeId)); //store TID + aDes.Append((TUint8*)&len,sizeof(TInt32)); //store length + + TAny* mem[KMMetaTypeMaxSize]; + TMetaVTableIterator attribIter(this); + SVDataTableEntry const* entry; + while ((entry = attribIter++) != NULL) + { + MMetaType* metaType = entry->iMetaNewL(mem,GetAttribPtr(entry->iOffset)); + TInt ret = metaType->Store(aDes); + if (ret != KErrNone) + { + return ret; + } + } + return KErrNone; + } + +EXPORT_C TInt SMetaData::Check(TPtrC8& aDes) const + { + return GetTypeId().Check(aDes); + } + +EXPORT_C TInt SMetaData::Load(TPtrC8& aDes) +/** + * Loads the meta object from a descriptor + */ + { + if (aDes.Length() < (TInt)sizeof(TInt32)) + { + return KErrArgument; + } + + TUint32 length; + Mem::Copy(&length, aDes.Ptr(), sizeof(TUint32)); + aDes.Set(aDes.Ptr()+sizeof(TUint32),aDes.Length()-sizeof(TUint32)); //update pointer (type) + + if (length > aDes.Length() + sizeof(TUint32) + sizeof(STypeId)) + { + return KErrArgument; + } + + TAny* mem[KMMetaTypeMaxSize]; + TMetaVTableIterator attribIter(this); + SVDataTableEntry const* entry; + while ((entry = attribIter++) != NULL) + { + //xxx This isn't a leaving function! It should be New not NewL + MMetaType* metaType = entry->iMetaNewL(mem,GetAttribPtr(entry->iOffset)); + TInt ret = metaType->Load(aDes); + if (ret != KErrNone) + { + return ret; + } + } + return KErrNone; + } + +EXPORT_C TInt SMetaData::Length() const +/** + * Returns length of the object excluding TID and stored length fields + */ + { + TInt length = sizeof(STypeId) + sizeof(TInt32); + TAny* mem[KMMetaTypeMaxSize]; + TMetaVTableIterator attribIter(this); + SVDataTableEntry const* entry; + while ((entry = attribIter++) != NULL) + { + MMetaType* metaType = entry->iMetaNewL(mem,GetAttribPtr(entry->iOffset)); + length += metaType->Length(); + } + return length; + } + +using Meta::SMetaDataECom; + +EXPORT_C SMetaDataECom::SMetaDataECom() +/** + * Protected and explicit constructor + */ + { + iDestroyUid.iUid = 0; + } + +EXPORT_C SMetaDataECom::~SMetaDataECom() +/** + * Destructor + */ + { + if ( iDestroyUid.iUid ) + { + REComSession::DestroyedImplementation(iDestroyUid); + } + } + +EXPORT_C SMetaDataECom* SMetaDataECom::LoadL(TPtrC8& aDes) +/** + * Static, encapsulates instantiation and loading of a content of a meta object + * from data contained in a descriptor. + * This function must be provided by all meta objects that will be used as a parameter + * to TMetaPtr<> template. + */ + { + if (aDes.Length() < (3 * (TInt) sizeof(TInt32))) + { + // Fatal error, descriptor is corrupt + User::Leave(KErrArgument); + } + + // Extract UID and type +#ifdef SYMBIAN_NETWORKING_CFTRANSPORT + STypeId typeId = STypeId::CreateSTypeId(aDes); +#else + STypeId typeId; + Mem::Copy(&typeId.iUid, aDes.Ptr(), sizeof(TUid)); + aDes.Set(aDes.Ptr()+sizeof(TUint32),aDes.Length()-sizeof(TUint32)); //update pointer (uid) + Mem::Copy(&typeId.iType, aDes.Ptr(), sizeof(TInt32)); + aDes.Set(aDes.Ptr()+sizeof(TUint32),aDes.Length()-sizeof(TUint32)); //update pointer (type) +#endif + + // Attempt to load the object + SMetaDataECom* mtd = NULL; + TRAPD(ret, mtd = NewInstanceL(typeId)); + + if (ret != KErrNone) + { + if (ret == KErrNotFound) + { + // Attempt to move the pointer on + TUint32 len; + Mem::Copy(&len, aDes.Ptr(), sizeof(TUint32)); + if (len <= (TUint32) aDes.Length()) + { + aDes.Set(aDes.Ptr()+len,aDes.Length()-len); //update pointer (type) + } + else + { + aDes.Set(aDes.Right(0)); + } + } + User::Leave(ret); + } + + CleanupDeletePushL(mtd); + + // Ask the object to de-marshall its data + ret = mtd->Load(aDes); + if (ret != KErrNone) + { + User::Leave(ret); + } + CleanupStack::Pop(mtd); + return mtd; + } + +EXPORT_C SMetaDataECom* SMetaDataECom::NewInstanceL(const STypeId& aTypeId) +/** + * Static, instantiates a meta object based on its Type ID. + */ + { + TUid destroyUid; + SMetaDataECom* obj = reinterpret_cast(REComSession::CreateImplementationL(aTypeId.iUid, destroyUid, (TAny*)aTypeId.iType)); + obj->iDestroyUid = destroyUid; + return obj; + } + +