libraries/clogger/debugRouter/dobject_compat.h
author Tom Sutcliffe <thomas.sutcliffe@accenture.com>
Sat, 31 Jul 2010 19:07:57 +0100
changeset 23 092bcc217d9d
parent 0 7f656887cf89
permissions -rw-r--r--
Tidied iocli exports, build macro tweaks. Removed 4 overloads of CCommandBase::RunCommand[L] that are no longer used at all, and changed one more to not be exported as it's only used internally to iocli.dll. fixed builds on platforms that don't support btrace or any form of tracing.

// dobject_compat.h
// 
// Copyright (c) 2007 - 2010 Accenture. All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the "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:
// Accenture - Initial contribution
//

#ifndef DOBJECT_COMPAT_H
#define DOBJECT_COMPAT_H

#include <kernel.h>

__ASSERT_COMPILE(sizeof(DObject) == 6*4 || sizeof(DObject) == 8*4); // We can't cope if the size changes again!
#define DOBJECT_PADDING TUint64 _padding
const TBool KCompiledUsingOldDefinition = sizeof(DObject) == 6*4;
#define ADD_PADDING(type, variablePtr) (*reinterpret_cast<type*>((TUint8*)variablePtr + sizeof(TUint64)))
#define SUBTRACT_PADDING(type, variablePtr) (*reinterpret_cast<type*>((TUint8*)variablePtr - sizeof(TUint64)))


template <class T>
class TemplatedPadder
	{
public:
	inline static T& AddPadding(T* aPtr)
		{
		return ADD_PADDING(T, aPtr);
		}
	inline static T& SubtractPadding(T* aPtr)
		{
		return SUBTRACT_PADDING(T, aPtr);
		}
	};

template <class T>
inline T& AddPadding(T* aPtr)
	{
	return TemplatedPadder<T>::AddPadding(aPtr);
	}

template <class T>
inline T& SubtractPadding(T* aPtr)
	{
	return TemplatedPadder<T>::SubtractPadding(aPtr);
	}

TBool CalculateDObjectSize(); // returns false if unable to determine 
extern TBool gRunningWithOldDefinition;

/* The SAFE_MEMBER macro exists because DObject grew by 64 bits between 9.1 and 9.2, therefore to write a 
 * DObject-derived class (such as a DLogicalChannel in an LDD) that can be compiled on one but also works on the
 * other requires that you be very careful accessing member data of your DObject-derived objects, because the 
 * offsets are different on the two OS releases. This macro abstracts the differences away by calculating when
 * an 8 byte correction needs to be applied to where the compiler thinks the variable is versus where the runtime
 * knows it is. By necessity, it has a weird definition, that relies on the above helper macros and also on
 * CalculateDObjectSize being called at some point before the first time any code using SAFE_MACRO is run.
 * It is recommended that for an LDD, you call it from within your DECLARE_EXTENSION_LDD before doing anything
 * else.
 * 
 * SAFE_MEMBER can only be used to access member data of DObject-derived classes, and should be used in ALL 
 * places where the instance variables are used or set, this includes instance variables of the superclass and
 * instance variables in DObject-derived objects you define yourself. Accesses to instance variables of DObject
 * itself must NOT use this macro, since the DObject variable offsets do not change. In order to make sure your
 * class is large enough and that the macro can be used consistantly, you must include a DOBJECT_PADDING at 
 * the *end* of all of your DObject subclass definition. You won't get any warning if you forget to do this,
 * It will just crash. Likewise if you use SAFE_MEMBER to access the member data of the DObject itself.
 * 
 * In other words:
 * DO use SAFE_MEMBER to access the member data of DMyClassThatIsDerivedFromDObject
 * DO use SAFE_MEMBER to access the member data of DLogicalChannel/DLogicalDevice/DThread etc
 * DON'T use it to access the member data of DObject itself
 * ALWAYS include a DOBJECT_PADDING at the end of your DMyDObjectDerivedClass - ie after any other member data
 * 
 */

#define SAFE_MEMBER(variable) ( \
	(KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? variable : ( \
	(KCompiledUsingOldDefinition && !gRunningWithOldDefinition) ? AddPadding(&variable) : ( \
	(!KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? SubtractPadding(&variable) : ( \
	/* running and compiling with new-definition DObject */ variable ))))

/* Old definition that doesn't require templating to work, (so is callable from non-C++). A consequence is you
 * have to explicitly give the type of the variable.
 */
//#define SAFE_MEMBER(type, variable) ( \
//	(KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? variable : ( \
//	(KCompiledUsingOldDefinition && !gRunningWithOldDefinition) ? ADD_PADDING(type, &variable) : ( \
//	(!KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? SUBTRACT_PADDING(type, &variable) : ( \
//	/* running and compiling with new-definition DObject */ variable ))))


/* These macros are equivalent to _FOFF and _LOFF and should be used whenever
 * f refers to a member variable that you would need to use SAFE_MEMBER on
 */
#define _SAFE_FOFF(c,f)			(((TInt)&  SAFE_MEMBER((((c *)0x1000)->f) )  )-0x1000)
#define _SAFE_LSOFF(p,T,f) ((T*)(((TUint8*)(p))-_SAFE_FOFF(T,f)))

#endif