crypto/weakcryptospi/inc/spi/romlit.h
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:40:57 +0100
branchRCL_3
changeset 62 a71299154b21
parent 8 35751d3474b7
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201035 Kit: 201035

/*
* 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