crypto/weakcryptospi/inc/spi/romlit.h
changeset 8 35751d3474b7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crypto/weakcryptospi/inc/spi/romlit.h	Thu Sep 10 14:01:51 2009 +0300
@@ -0,0 +1,101 @@
+/*
+* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+/**
+ @file
+ @publishedPartner
+ @released
+*/
+
+#ifndef __ROMLIT_H__
+#define __ROMLIT_H__
+#include <e32def.h>
+#include <u32std.h>
+/**
+   Special ROM friendly _LIT16 replacement.
+
+   The existing _LIT16 macro/template successfully creates descriptors
+   which will be put into ROM, but it is IMPOSSIBLE to initialize
+   another "romable" variable with the address of one....
+
+   What happens is that the compiler thinks it needs to call the
+   TLitC16 operator& function call (even though it is a cast which
+   will be optimized out of existence) to take the address of the
+   object created by _LIT16.
+
+   The result is that the DESTINATION variable gets moved from ROM to
+   an initialized data area so that the return value of the TLitC16
+   operator& function can be written to it at run time.
+
+   The net result is that your code will not be legal in a target DLL
+   (unless you enable thread initialized data, which is not
+   recommended).
+
+   A solution is to use this macro/class which creates TRomLitC16
+   objects which have an identical layout to TPtrC16 objects and can
+   generally be used just like all the other descriptor types.
+
+   You use the _ROMLIT16 macro to create a TRomLitC16 object, then
+   take its address and store that in a TRomLitC16 ptr. Attempting to
+   store its address into other ptr types will compile but encounter
+   the same problem as trying to use _LIT16.
+   
+   In most cases you can just dereference a TRomLitC16 ptr and pass it
+   to any functions which can handle a _LIT16 (due to the out cast
+   operators). If it doesn't automatically work, apply the function
+   operator to the TRomLitC16 which will return a TDescC16 reference
+   (for example ((*ptrToTRomLitC16)()') which is 100% compatible.
+*/
+
+#ifndef __TText_defined
+#define __TText_defined
+#ifdef __GCC32__
+typedef wchar_t __TText;
+#else
+typedef TUint16 __TText;
+#endif
+#endif
+
+// All L"" strings are correctly aligned to an even boundary so can be
+// placed directly into the ptr field of a TPtr object.
+//
+// Note that the RVCT assembler listings are confusing because a
+// standalone ALIGN directive's argument is the requested alignment,
+// but the ALIGN argument to an AREA directive specifies a power of 2
+// for alignment. So the following RVCT generated code ensures
+// wchar_t strings are 2 byte aligned:-
+//
+// "AREA ||.constwstring||, DATA, READONLY, MERGE=2, STRINGS, ALIGN=1"
+#define _ROMLIT16(name,s) \
+	const static TRomLitC16 name={((EPtrC<<KShiftDesType16) | (sizeof(L##s)/2-1)), L##s}
+
+struct TRomLitC16
+	{
+	operator const TDesC16 *() const
+		{ return reinterpret_cast<const TDesC16*>(this); }
+	operator const TDesC16 &() const
+		{ return *(TDesC16 *)this; }
+	const TDesC16& operator()() const
+		{ return *(TDesC16 *)this; }
+	operator const __TRefDesC16() const
+		{ return *(TDesC16 *)this; }
+	TUint iTypeLength;
+	const __TText *iPtr;
+	};
+
+#endif