commsfwsupport/commselements/virtualconstructors/src/vc.cpp
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2007-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 "vc.h"
       
    22 
       
    23 #include <elements/vc.h>
       
    24 #include <elements/metadata.h> //Should we decouple STypeId from NetMeta (circular dependency)?
       
    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_ElemVirtualCtorv, "ElemVirtualCtorv");
       
    31 #endif
       
    32 
       
    33 using namespace Meta;
       
    34 using namespace VC;
       
    35 
       
    36 
       
    37 #ifdef _DEBUG
       
    38 	_LIT(KNetCtorPanic, "NetCtor");
       
    39 #endif
       
    40 enum TNetCtorPanic
       
    41 	{
       
    42 	EConstructorTableHasRepetitions = 0,
       
    43 	EConstructorTableIsNotSorted = 1
       
    44 	};
       
    45 
       
    46 const TInt KConstructorTableArrayGranularity = 8;
       
    47 
       
    48 EXPORT_C CVirtualCtorBase::CVirtualCtorBase()
       
    49 :	iCtorTableList(KConstructorTableArrayGranularity,_FOFF(TCtorTable,iInterfaceId))
       
    50 	{
       
    51 	}
       
    52 
       
    53 EXPORT_C CVirtualCtorBase::~CVirtualCtorBase()
       
    54 	{
       
    55 	iCtorTableList.Close();
       
    56 	}
       
    57 
       
    58 #if defined(_DEBUG)
       
    59 //This fn is only a debug mode helper function.
       
    60 //It may not:
       
    61 //1) be exported in a header file
       
    62 //2) be exported as IMPORT_C/EXPORT_C
       
    63 //3) modify the object being debugged in any way
       
    64 
       
    65 //We assume that elements of the array may never be NULL
       
    66 TBool __Debug_NoRepetitions(const TImplementationProxy* aFirstEntry, TInt aLength)
       
    67 	{
       
    68 	__ASSERT_DEBUG(aLength>=0, User::Panic(KSpecAssert_ElemVirtualCtorv, 1));
       
    69 
       
    70 	if (aLength<=1)
       
    71 		{
       
    72 		return ETrue;
       
    73 		}
       
    74 
       
    75 	for (TInt i = 0; i < aLength; ++i)
       
    76 		{
       
    77 		for (TInt j = i + 1; j < aLength; ++j)
       
    78 			{
       
    79 			if ((aFirstEntry+i)->iImplementationUid.iUid == (aFirstEntry+j)->iImplementationUid.iUid)
       
    80 				{
       
    81 				return EFalse;
       
    82 				}
       
    83 			}
       
    84 		}
       
    85 
       
    86 	return ETrue;
       
    87 	}
       
    88 
       
    89 //We assume that elements of the array may never be NULL
       
    90 TBool __Debug_IsSorted(const TImplementationProxy* aFirstEntry, TInt aLength)
       
    91 	{
       
    92 	__ASSERT_DEBUG(aLength>=0, User::Panic(KSpecAssert_ElemVirtualCtorv, 2));
       
    93 
       
    94 	if (aLength<=1)
       
    95 		{
       
    96 		return ETrue;
       
    97 		}
       
    98 
       
    99 	const TImplementationProxy* thisEntry = aFirstEntry + 1;
       
   100 
       
   101 	TReal trend = thisEntry->iImplementationUid.iUid - aFirstEntry->iImplementationUid.iUid;
       
   102 
       
   103 	for (TInt i = 1; i < aLength; ++i)
       
   104 		{
       
   105 		TReal next = (thisEntry++)->iImplementationUid.iUid;
       
   106 		TReal prev = (aFirstEntry++)->iImplementationUid.iUid;
       
   107 		if (((next - prev) * trend) < 0)
       
   108 			{
       
   109 			return EFalse;
       
   110 			}
       
   111 		}
       
   112 	return ETrue;
       
   113 	}
       
   114 #endif
       
   115 
       
   116 EXPORT_C void CVirtualCtorBase::RegisterInterfaceL(TUid aInterfaceId, TInt aNumCtors, const TImplementationProxy* aCtorTable)
       
   117 	{
       
   118 	TInt dummyIndex;
       
   119 	const TCtorTable* table = FindCtorTable(aInterfaceId, dummyIndex);
       
   120 	if(table != NULL)
       
   121 		{
       
   122 		table->iRegisteredCount++;
       
   123 		}
       
   124 	else
       
   125 		{
       
   126 		//Repetitions are not allowed. It is a serious programming mistake.
       
   127 		__ASSERT_DEBUG(__Debug_NoRepetitions(aCtorTable,aNumCtors), User::Panic(KNetCtorPanic, EConstructorTableHasRepetitions));
       
   128 
       
   129 		//The disadvantage of a binary search is that the array needs to be sorted
       
   130 		//(in this case at compile time) or there will be a significant speed penalty.
       
   131 
       
   132 		//We assert here (and not log only) to protect binary compatibility of future tables.
       
   133 		__ASSERT_DEBUG(__Debug_IsSorted(aCtorTable,aNumCtors), User::Panic(KNetCtorPanic, EConstructorTableIsNotSorted));
       
   134 
       
   135 		iCtorTableList.InsertInUnsignedKeyOrderL(TCtorTable(aInterfaceId, aNumCtors, aCtorTable));
       
   136 		}
       
   137 	}
       
   138 
       
   139 EXPORT_C void CVirtualCtorBase::DeregisterInterface(TUid aInterfaceId)
       
   140 	{
       
   141 	TInt index;
       
   142 	const TCtorTable* table = FindCtorTable(aInterfaceId, index);
       
   143 	if(table != NULL)
       
   144 		{
       
   145 		if(--(table->iRegisteredCount) == 0)
       
   146 			{
       
   147 			iCtorTableList.Remove(index);
       
   148 			}
       
   149 		}
       
   150 	}
       
   151 
       
   152 EXPORT_C TBool CVirtualCtorBase::IsInterfaceRegistered(TUid aInterfaceId) const
       
   153 	{
       
   154 	TInt idx;
       
   155 	const CVirtualCtorBase::TCtorTable* table = FindCtorTable(aInterfaceId,idx);
       
   156 	return table!=NULL;
       
   157 	}
       
   158 
       
   159 const CVirtualCtorBase::TCtorTable* CVirtualCtorBase::FindCtorTable(TUid aInterfaceId, TInt& aIndex) const
       
   160 	{
       
   161 	return (KErrNone==iCtorTableList.FindInUnsignedKeyOrder(TCtorTable(aInterfaceId,0,0),aIndex))? &iCtorTableList[aIndex] : NULL;
       
   162 	}
       
   163 
       
   164 EXPORT_C TProxyNewLPtr CVirtualCtorBase::FindRawCtor(const Meta::STypeId& aType) const
       
   165 	{
       
   166 	TInt aIndex;
       
   167 	const TCtorTable* ctorTable;
       
   168 	if((ctorTable = FindCtorTable(aType.iUid, aIndex)) != NULL)
       
   169 		{
       
   170 		//In our case the only advantage of binary search over linear search is speed.
       
   171 		//The number of comparisons required for a binary search on N lelments is on average log2(N),
       
   172 		//while for linear search it is obviously N/2.
       
   173 		//For example, for an array of 40 entries, binary search will on average require 6 comparisons
       
   174 		//against 20 for linear. For an array with 1000 entries the proportion is around 1%.
       
   175 
       
   176 		//For very small arrays the speed gain is insigniffcant, but we have decided that
       
   177 		//advantages from searching of even medium sized arrays compensate disadvantages related to
       
   178 		//forced sorting.
       
   179 
       
   180 		//Currently there is no support for binary search of const (compile time) arrays like TFixedArray.
       
   181 		//We use this "workaround" below to be able to use supported binary search on our const arrays.
       
   182 		TImplementationProxy* entries = const_cast<TImplementationProxy*>(ctorTable->iCtorTable);
       
   183 		RArray<TImplementationProxy> array(sizeof(TImplementationProxy),entries,ctorTable->iNumCtors);
       
   184 		TImplementationProxy tester = {aType.iType,NULL};
       
   185 		__ASSERT_COMPILE(_FOFF(TImplementationProxy,iImplementationUid)==0); //We rely on the fact that the key offset is 0
       
   186 		return (KErrNone==array.FindInUnsignedKeyOrder(tester,aIndex))? array[aIndex].iNewLFuncPtr : NULL;
       
   187 		}
       
   188 	return NULL;
       
   189 	}
       
   190 
       
   191 EXPORT_C TAny* CVirtualCtorInPlace::New(const Meta::STypeId& aType, TDes8& aBuff) const
       
   192     {
       
   193 	TInPlaceNewPtr newFn = FindCtor(aType);
       
   194 	if(newFn)
       
   195 		{
       
   196 		return newFn(aBuff);
       
   197 		}
       
   198 	return NULL;
       
   199     }
       
   200 
       
   201