|
1 // dobject_compat.h |
|
2 // |
|
3 // Copyright (c) 2007 - 2010 Accenture. All rights reserved. |
|
4 // This component and the accompanying materials are made available |
|
5 // under the terms of the "Eclipse Public License v1.0" |
|
6 // which accompanies this distribution, and is available |
|
7 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 // |
|
9 // Initial Contributors: |
|
10 // Accenture - Initial contribution |
|
11 // |
|
12 |
|
13 #ifndef DOBJECT_COMPAT_H |
|
14 #define DOBJECT_COMPAT_H |
|
15 |
|
16 #include <kernel.h> |
|
17 |
|
18 __ASSERT_COMPILE(sizeof(DObject) == 6*4 || sizeof(DObject) == 8*4); // We can't cope if the size changes again! |
|
19 #define DOBJECT_PADDING TUint64 _padding |
|
20 const TBool KCompiledUsingOldDefinition = sizeof(DObject) == 6*4; |
|
21 #define ADD_PADDING(type, variablePtr) (*reinterpret_cast<type*>((TUint8*)variablePtr + sizeof(TUint64))) |
|
22 #define SUBTRACT_PADDING(type, variablePtr) (*reinterpret_cast<type*>((TUint8*)variablePtr - sizeof(TUint64))) |
|
23 |
|
24 |
|
25 template <class T> |
|
26 class TemplatedPadder |
|
27 { |
|
28 public: |
|
29 inline static T& AddPadding(T* aPtr) |
|
30 { |
|
31 return ADD_PADDING(T, aPtr); |
|
32 } |
|
33 inline static T& SubtractPadding(T* aPtr) |
|
34 { |
|
35 return SUBTRACT_PADDING(T, aPtr); |
|
36 } |
|
37 }; |
|
38 |
|
39 template <class T> |
|
40 inline T& AddPadding(T* aPtr) |
|
41 { |
|
42 return TemplatedPadder<T>::AddPadding(aPtr); |
|
43 } |
|
44 |
|
45 template <class T> |
|
46 inline T& SubtractPadding(T* aPtr) |
|
47 { |
|
48 return TemplatedPadder<T>::SubtractPadding(aPtr); |
|
49 } |
|
50 |
|
51 TBool CalculateDObjectSize(); // returns false if unable to determine |
|
52 extern TBool gRunningWithOldDefinition; |
|
53 |
|
54 /* The SAFE_MEMBER macro exists because DObject grew by 64 bits between 9.1 and 9.2, therefore to write a |
|
55 * DObject-derived class (such as a DLogicalChannel in an LDD) that can be compiled on one but also works on the |
|
56 * other requires that you be very careful accessing member data of your DObject-derived objects, because the |
|
57 * offsets are different on the two OS releases. This macro abstracts the differences away by calculating when |
|
58 * an 8 byte correction needs to be applied to where the compiler thinks the variable is versus where the runtime |
|
59 * knows it is. By necessity, it has a weird definition, that relies on the above helper macros and also on |
|
60 * CalculateDObjectSize being called at some point before the first time any code using SAFE_MACRO is run. |
|
61 * It is recommended that for an LDD, you call it from within your DECLARE_EXTENSION_LDD before doing anything |
|
62 * else. |
|
63 * |
|
64 * SAFE_MEMBER can only be used to access member data of DObject-derived classes, and should be used in ALL |
|
65 * places where the instance variables are used or set, this includes instance variables of the superclass and |
|
66 * instance variables in DObject-derived objects you define yourself. Accesses to instance variables of DObject |
|
67 * itself must NOT use this macro, since the DObject variable offsets do not change. In order to make sure your |
|
68 * class is large enough and that the macro can be used consistantly, you must include a DOBJECT_PADDING at |
|
69 * the *end* of all of your DObject subclass definition. You won't get any warning if you forget to do this, |
|
70 * It will just crash. Likewise if you use SAFE_MEMBER to access the member data of the DObject itself. |
|
71 * |
|
72 * In other words: |
|
73 * DO use SAFE_MEMBER to access the member data of DMyClassThatIsDerivedFromDObject |
|
74 * DO use SAFE_MEMBER to access the member data of DLogicalChannel/DLogicalDevice/DThread etc |
|
75 * DON'T use it to access the member data of DObject itself |
|
76 * ALWAYS include a DOBJECT_PADDING at the end of your DMyDObjectDerivedClass - ie after any other member data |
|
77 * |
|
78 */ |
|
79 |
|
80 #define SAFE_MEMBER(variable) ( \ |
|
81 (KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? variable : ( \ |
|
82 (KCompiledUsingOldDefinition && !gRunningWithOldDefinition) ? AddPadding(&variable) : ( \ |
|
83 (!KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? SubtractPadding(&variable) : ( \ |
|
84 /* running and compiling with new-definition DObject */ variable )))) |
|
85 |
|
86 /* Old definition that doesn't require templating to work, (so is callable from non-C++). A consequence is you |
|
87 * have to explicitly give the type of the variable. |
|
88 */ |
|
89 //#define SAFE_MEMBER(type, variable) ( \ |
|
90 // (KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? variable : ( \ |
|
91 // (KCompiledUsingOldDefinition && !gRunningWithOldDefinition) ? ADD_PADDING(type, &variable) : ( \ |
|
92 // (!KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? SUBTRACT_PADDING(type, &variable) : ( \ |
|
93 // /* running and compiling with new-definition DObject */ variable )))) |
|
94 |
|
95 |
|
96 /* These macros are equivalent to _FOFF and _LOFF and should be used whenever |
|
97 * f refers to a member variable that you would need to use SAFE_MEMBER on |
|
98 */ |
|
99 #define _SAFE_FOFF(c,f) (((TInt)& SAFE_MEMBER((((c *)0x1000)->f) ) )-0x1000) |
|
100 #define _SAFE_LSOFF(p,T,f) ((T*)(((TUint8*)(p))-_SAFE_FOFF(T,f))) |
|
101 |
|
102 #endif |