commsfwsupport/commselements/NetMeta/src/MetaData.cpp
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file 
       
    18  @internalTechnology
       
    19 */
       
    20 
       
    21 #include <ecom/ecom.h>
       
    22 #include <elements/metadata.h>
       
    23 #include <elements/metatype.h>
       
    24 #include <elements/metaiterator.h>
       
    25 
       
    26 
       
    27 #ifdef _DEBUG
       
    28 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
       
    29 // (if it could happen through user error then you should give it an explicit, documented, category + code)
       
    30 _LIT(KSpecAssert_ElemNetMetaMtDt, "ElemNetMetaMtDt.");
       
    31 #endif
       
    32 
       
    33 // Maximum size of the MMetaType based object in terms of sizeof(TAny*).
       
    34 // KMMetaTypeMaxSize * sizeof(TAny*) is the size of the memory reserved
       
    35 // on the stack for the in-place instantiation.
       
    36 const TInt KMMetaTypeMaxSize = 10;
       
    37 
       
    38 
       
    39 using namespace Meta;
       
    40 
       
    41 #ifdef SYMBIAN_NETWORKING_CFTRANSPORT
       
    42 EXPORT_C STypeId STypeId::CreateSTypeId(TPtrC8& aDes)
       
    43 	{
       
    44 	// check no padding, so no alignment worries in copying single block
       
    45 	STypeId id;
       
    46 	__ASSERT_COMPILE(sizeof(STypeId) == sizeof(id.iUid) + sizeof(id.iType));
       
    47 
       
    48 	Mem::Copy(&id, aDes.Ptr(), sizeof(STypeId));
       
    49 	
       
    50 	// trim typeid from front of store
       
    51 	aDes.Set(aDes.Ptr() + sizeof(STypeId), aDes.Length() - sizeof(STypeId));
       
    52 	return id;
       
    53 	}
       
    54 #endif
       
    55 
       
    56 EXPORT_C TInt STypeId::Check( TPtrC8& aDes ) const
       
    57 	{
       
    58 	if (aDes.Length() < (TInt)sizeof(STypeId))
       
    59 		{
       
    60 		return KErrArgument;
       
    61 		}
       
    62 	STypeId typeId;
       
    63 	Mem::Copy(&typeId, aDes.Ptr(), sizeof(STypeId));
       
    64 	TInt error = KErrArgument;
       
    65 	if ( *this == typeId )
       
    66 		{//update pointer (type) only if the type matches
       
    67 		aDes.Set(aDes.Ptr()+sizeof(STypeId),aDes.Length()-sizeof(STypeId));
       
    68 		error = KErrNone;
       
    69 		}
       
    70 	return  error;
       
    71 	}
       
    72 
       
    73 EXPORT_C SMetaData::SMetaData()
       
    74 /**
       
    75  * Protected and explicit constructor
       
    76  */
       
    77     {
       
    78     }
       
    79 
       
    80 EXPORT_C SMetaData::~SMetaData()
       
    81 /**
       
    82  * Virtual destructor
       
    83  */
       
    84 	{
       
    85 	}
       
    86 
       
    87 EXPORT_C TInt SMetaData::CheckTypeOf( TPtrC8& aDes ) const
       
    88 	{
       
    89 	if (aDes.Length() < (TInt)sizeof(STypeId))
       
    90 		{
       
    91 		return KErrArgument;
       
    92 		}
       
    93 	STypeId typeId;
       
    94 	Mem::Copy(&typeId, aDes.Ptr(), sizeof(STypeId));
       
    95 	TInt error = KErrArgument;
       
    96 	if ( IsTypeOf(typeId) )
       
    97 		{//update pointer (type) only if the type matches
       
    98 		aDes.Set(aDes.Ptr()+sizeof(STypeId),aDes.Length()-sizeof(STypeId));
       
    99 		error = KErrNone;
       
   100 		}
       
   101 	return  error;
       
   102 	}
       
   103 
       
   104 EXPORT_C STypeId SMetaData::GetTypeId() const
       
   105 	{
       
   106 	const SVDataTableEntry* entry = GetVDataTable();
       
   107 	__ASSERT_DEBUG( entry , User::Panic(KSpecAssert_ElemNetMetaMtDt, 1));
       
   108 	return STypeId::CreateSTypeId( entry->iOffset, reinterpret_cast<TInt32>(entry->iMetaNewL) );
       
   109 	}
       
   110 
       
   111 EXPORT_C TInt SMetaData::IsTypeOf( const STypeId& aTypeId ) const
       
   112 	{
       
   113 	const SVDataTableEntry* entry = GetVDataTable();
       
   114 	__ASSERT_DEBUG( entry , User::Panic(KSpecAssert_ElemNetMetaMtDt, 2));
       
   115 	for(;;)
       
   116 		{
       
   117 		STypeId typeId = { entry->iOffset, reinterpret_cast<TInt32>(entry->iMetaNewL) };
       
   118 		if ( typeId == aTypeId )
       
   119 			{
       
   120 			return 1;
       
   121 			}
       
   122 		//move through the table
       
   123 		while ( (++entry)->iMetaNewL ) {;}
       
   124 		if ( !entry->iOffset )
       
   125 			{
       
   126 			break;
       
   127 			}
       
   128 		typedef SVDataTableEntry* (*TMetaBaseTableNewL)();
       
   129 		entry = reinterpret_cast<TMetaBaseTableNewL>(entry->iOffset)();
       
   130 		}
       
   131 	return 0;
       
   132 	}
       
   133 
       
   134 EXPORT_C void SMetaData::Copy(const SMetaData& aSource)
       
   135 /**
       
   136  * Copies values of a SMetaData object's properties into properties of *this.
       
   137  * Both meta objects are of the same type.
       
   138  */
       
   139     {
       
   140     __ASSERT_DEBUG(GetTypeId()==aSource.GetTypeId(),User::Panic(_L("SMetaData"),KErrArgument));
       
   141 
       
   142     TAny* mem[KMMetaTypeMaxSize];
       
   143     TMetaVTableIterator attribIter(this);
       
   144     SVDataTableEntry const* entry;
       
   145     while ((entry = attribIter++) != NULL)
       
   146         {
       
   147         MMetaType* metaType = entry->iMetaNewL(mem,GetAttribPtr(entry->iOffset));
       
   148         metaType->Copy(aSource.GetAttribPtr(entry->iOffset));
       
   149         }
       
   150     }
       
   151 
       
   152 EXPORT_C TInt SMetaData::Store(TDes8& aDes) const
       
   153 /**
       
   154  * Stores the meta object into a descriptor
       
   155  */
       
   156     {
       
   157 	const STypeId& typeId = GetTypeId();
       
   158 	TInt len = Length();
       
   159 
       
   160 	if ((aDes.MaxLength()-aDes.Length()) < len)
       
   161 		{
       
   162 		return KErrOverflow;
       
   163 		}
       
   164 
       
   165 	aDes.Append((TUint8*)&typeId,sizeof(STypeId)); //store TID
       
   166 	aDes.Append((TUint8*)&len,sizeof(TInt32)); //store length
       
   167 
       
   168     TAny* mem[KMMetaTypeMaxSize];
       
   169     TMetaVTableIterator attribIter(this);
       
   170     SVDataTableEntry const* entry;
       
   171     while ((entry = attribIter++) != NULL)
       
   172         {
       
   173         MMetaType* metaType = entry->iMetaNewL(mem,GetAttribPtr(entry->iOffset));
       
   174 		TInt ret = metaType->Store(aDes);
       
   175 		if (ret != KErrNone)
       
   176 			{
       
   177 			return ret;
       
   178 			}
       
   179         }
       
   180 	return KErrNone;
       
   181     }
       
   182 
       
   183 EXPORT_C TInt SMetaData::Check(TPtrC8& aDes) const
       
   184 	{
       
   185 	return GetTypeId().Check(aDes);
       
   186 	}
       
   187 
       
   188 EXPORT_C TInt SMetaData::Load(TPtrC8& aDes)
       
   189 /**
       
   190  * Loads the meta object from a descriptor
       
   191  */
       
   192     {
       
   193 	if (aDes.Length() < (TInt)sizeof(TInt32))
       
   194 		{
       
   195 		return KErrArgument;
       
   196 		}
       
   197 
       
   198 	TUint32 length;
       
   199 	Mem::Copy(&length, aDes.Ptr(), sizeof(TUint32));
       
   200 	aDes.Set(aDes.Ptr()+sizeof(TUint32),aDes.Length()-sizeof(TUint32)); //update pointer (type)
       
   201 
       
   202 	if (length > aDes.Length() + sizeof(TUint32) + sizeof(STypeId))
       
   203 		{
       
   204 		return KErrArgument;
       
   205 		}
       
   206 
       
   207     TAny* mem[KMMetaTypeMaxSize];
       
   208     TMetaVTableIterator attribIter(this);
       
   209     SVDataTableEntry const* entry;
       
   210     while ((entry = attribIter++) != NULL)
       
   211         {
       
   212 		//xxx This isn't a leaving function! It should be New not NewL
       
   213         MMetaType* metaType = entry->iMetaNewL(mem,GetAttribPtr(entry->iOffset));
       
   214         TInt ret = metaType->Load(aDes);
       
   215 		if (ret != KErrNone)
       
   216 			{
       
   217 			return ret;
       
   218 			}
       
   219         }
       
   220 	return KErrNone;
       
   221     }
       
   222 
       
   223 EXPORT_C TInt SMetaData::Length() const
       
   224 /**
       
   225  * Returns length of the object excluding TID and stored length fields
       
   226  */
       
   227 	{
       
   228 	TInt length = sizeof(STypeId) + sizeof(TInt32);
       
   229     TAny* mem[KMMetaTypeMaxSize];
       
   230     TMetaVTableIterator attribIter(this);
       
   231     SVDataTableEntry const* entry;
       
   232     while ((entry = attribIter++) != NULL)
       
   233         {
       
   234         MMetaType* metaType = entry->iMetaNewL(mem,GetAttribPtr(entry->iOffset));
       
   235         length += metaType->Length();
       
   236         }
       
   237 	return length;
       
   238 	}
       
   239 
       
   240 using Meta::SMetaDataECom;
       
   241 
       
   242 EXPORT_C SMetaDataECom::SMetaDataECom()
       
   243 /**
       
   244  * Protected and explicit constructor
       
   245  */
       
   246 	{
       
   247 	iDestroyUid.iUid = 0;
       
   248 	}
       
   249 
       
   250 EXPORT_C SMetaDataECom::~SMetaDataECom()
       
   251 /**
       
   252  * Destructor
       
   253  */
       
   254 	{
       
   255 	if ( iDestroyUid.iUid )
       
   256       {
       
   257       REComSession::DestroyedImplementation(iDestroyUid);
       
   258       }
       
   259    }
       
   260 
       
   261 EXPORT_C SMetaDataECom* SMetaDataECom::LoadL(TPtrC8& aDes)
       
   262 /**
       
   263  * Static, encapsulates instantiation and loading of a content of a meta object
       
   264  * from data contained in a descriptor.
       
   265  * This function must be provided by all meta objects that will be used as a parameter
       
   266  * to TMetaPtr<> template.
       
   267  */
       
   268 	{
       
   269 	if (aDes.Length() < (3 * (TInt) sizeof(TInt32)))
       
   270 		{
       
   271 		// Fatal error, descriptor is corrupt
       
   272 		User::Leave(KErrArgument);
       
   273 		}
       
   274 
       
   275 	// Extract UID and type
       
   276 #ifdef SYMBIAN_NETWORKING_CFTRANSPORT
       
   277 	STypeId typeId = STypeId::CreateSTypeId(aDes);
       
   278 #else
       
   279 	STypeId typeId;
       
   280 	Mem::Copy(&typeId.iUid, aDes.Ptr(), sizeof(TUid));
       
   281 	aDes.Set(aDes.Ptr()+sizeof(TUint32),aDes.Length()-sizeof(TUint32)); //update pointer (uid)
       
   282 	Mem::Copy(&typeId.iType, aDes.Ptr(), sizeof(TInt32));
       
   283 	aDes.Set(aDes.Ptr()+sizeof(TUint32),aDes.Length()-sizeof(TUint32)); //update pointer (type)
       
   284 #endif
       
   285 
       
   286 	// Attempt to load the object
       
   287 	SMetaDataECom* mtd = NULL;
       
   288 	TRAPD(ret, mtd = NewInstanceL(typeId));
       
   289 
       
   290 	if (ret != KErrNone)
       
   291 		{
       
   292 		if (ret == KErrNotFound)
       
   293 			{
       
   294 			// Attempt to move the pointer on
       
   295 			TUint32 len;
       
   296 			Mem::Copy(&len, aDes.Ptr(), sizeof(TUint32));
       
   297 			if (len <= (TUint32) aDes.Length())
       
   298 				{
       
   299 				aDes.Set(aDes.Ptr()+len,aDes.Length()-len); //update pointer (type)
       
   300 				}
       
   301 			else
       
   302 				{
       
   303 				aDes.Set(aDes.Right(0));
       
   304 				}
       
   305 			}
       
   306 		User::Leave(ret);
       
   307 		}
       
   308 
       
   309 	CleanupDeletePushL(mtd);
       
   310 
       
   311 	// Ask the object to de-marshall its data
       
   312 	ret = mtd->Load(aDes);
       
   313 	if (ret != KErrNone)
       
   314 		{
       
   315 		User::Leave(ret);
       
   316 		}
       
   317 	CleanupStack::Pop(mtd);
       
   318     return mtd;
       
   319 	}
       
   320 
       
   321 EXPORT_C SMetaDataECom* SMetaDataECom::NewInstanceL(const STypeId& aTypeId)
       
   322 /**
       
   323  * Static, instantiates a meta object based on its Type ID.
       
   324  */
       
   325     {
       
   326 	TUid destroyUid;
       
   327 	SMetaDataECom* obj = reinterpret_cast<SMetaDataECom*>(REComSession::CreateImplementationL(aTypeId.iUid, destroyUid, (TAny*)aTypeId.iType));
       
   328 	obj->iDestroyUid = destroyUid;
       
   329 	return obj;
       
   330 	}
       
   331 
       
   332