diff -r 000000000000 -r 7f656887cf89 libraries/clogger/debugRouter/dobject_compat.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libraries/clogger/debugRouter/dobject_compat.h Wed Jun 23 15:52:26 2010 +0100 @@ -0,0 +1,102 @@ +// 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 + +__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((TUint8*)variablePtr + sizeof(TUint64))) +#define SUBTRACT_PADDING(type, variablePtr) (*reinterpret_cast((TUint8*)variablePtr - sizeof(TUint64))) + + +template +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 +inline T& AddPadding(T* aPtr) + { + return TemplatedPadder::AddPadding(aPtr); + } + +template +inline T& SubtractPadding(T* aPtr) + { + return TemplatedPadder::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