kernel/eka/euser/us_des.cpp
changeset 0 a41df078684a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/euser/us_des.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,872 @@
+// Copyright (c) 1994-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:
+// e32\euser\us_des.cpp
+// 
+//
+
+#include "us_std.h"
+
+// Terrible hack. Surely we should use VA_START instead of the below?
+#if defined(__EABI__) || (defined(__X86__) && defined(__GCC32__))
+#define EABI_STYLE_VA_LISTS
+#endif
+
+const TInt KNoPrecision=-1;
+const TInt KDefaultPrecision=6;
+const TInt KMaxRealWidth=0x20;
+
+// TFormatedText8 and TFormatedText16
+
+class TFormatedText8
+	{
+public:
+	TBuf8<0x40> iBuffer;
+	const TUint8* iText;
+	TInt iTextLength;
+	TInt iWidth;
+	TAlign iJustify;
+	TChar iFill;
+	};
+
+class TFormatedText16
+	{
+public:
+	TBuf16<0x40> iBuffer;
+	const TUint16* iText;
+	TInt iTextLength;
+	TInt iWidth;
+	TAlign iJustify;
+	TChar iFill;
+	};
+
+// TPanicker8 and TPanicker16
+
+class TPanicker8
+	{
+public:
+	static inline void Panic_BadFormatDescriptor() {Panic(ETDes8BadFormatDescriptor);}
+	static inline void Panic_BadFormatParams() {Panic(ETDes8BadFormatParams);}
+	};
+
+class TPanicker16
+	{
+public:
+	static inline void Panic_BadFormatDescriptor() {Panic(ETDes16BadFormatDescriptor);}
+	static inline void Panic_BadFormatParams() {Panic(ETDes16BadFormatParams);}
+	};
+
+// TFormatDirective
+
+class TFormatDirective // basically a sort of array of parameters where the size of each parameter is stored (no more than 4 parameters are possible per format-directive) - it also knows whether the format directive it represents has an explicit index, and if so, what that index is
+	{
+public:
+	inline TFormatDirective() :iSizesOfParametersInBytes(0), iFormatDirectiveIndex(EImplicitFormatDirectiveIndex) {}
+	void AppendParameter(TInt aSizeOfParameterInBytes,TInt aParameterAlignment);
+	inline void FormatDirectiveHasExplicitIndex(TInt aFormatDirectiveIndex) {iFormatDirectiveIndex=aFormatDirectiveIndex;}
+private:
+	friend class TParameterManager;
+private:
+	enum {EImplicitFormatDirectiveIndex=-1};
+	enum
+		{
+		EShiftToNumberOfParameters=28,
+		ENumberOfBitsPerParameter=5,
+		EMaskForSingleParameter=(1<<ENumberOfBitsPerParameter)-1,
+		EMaskForAlignmentShift=3,
+		EMaskForParameterSize=EMaskForSingleParameter&~EMaskForAlignmentShift,
+		EMaximumNumberOfParameters=EShiftToNumberOfParameters/ENumberOfBitsPerParameter
+		};
+private: // these functions are used by the TParameterManager class
+	inline TInt NumberOfParameters() const {return iSizesOfParametersInBytes>>EShiftToNumberOfParameters;}
+	TInt SizeOfParameter(TInt aIndex) const;
+	TUint8* CalculateDataPointer(const TUint8* aDataPtr,TInt aIndex) const;
+private:
+	TUint iSizesOfParametersInBytes; // a compactly stored array
+	TInt iFormatDirectiveIndex;
+	};
+
+void TFormatDirective::AppendParameter(TInt aSizeOfParameterInBytes, TInt aParameterAlignment)
+	{
+	const TInt numberOfParameters=NumberOfParameters();
+	__ASSERT_DEBUG(numberOfParameters<EMaximumNumberOfParameters, Panic(ENumberOfParametersExceedsMaximum));
+	__ASSERT_DEBUG((aSizeOfParameterInBytes&EMaskForParameterSize)==aSizeOfParameterInBytes, Panic(ESizeOfParameterTooBig));
+	iSizesOfParametersInBytes+=(1<<EShiftToNumberOfParameters); // increment the count
+
+	switch(aParameterAlignment)
+		{
+	case 4:
+		// aSizeOfParameterInBytes |= 0;
+		break;
+	case 8:
+		aSizeOfParameterInBytes |= 1;
+		break;
+	default:
+		__ASSERT_DEBUG(0, Panic(EUnexpectedError3));
+		}
+
+	iSizesOfParametersInBytes|=(aSizeOfParameterInBytes<<(numberOfParameters*ENumberOfBitsPerParameter)); // store aSizeOfParameterInBytes
+	}
+
+TInt TFormatDirective::SizeOfParameter(TInt aIndex) const
+	{
+	__ASSERT_DEBUG(aIndex<NumberOfParameters(), Panic(EParameterIndexOutOfRange1));
+	return (iSizesOfParametersInBytes>>(aIndex*ENumberOfBitsPerParameter))&EMaskForParameterSize;
+	}
+
+TUint8* TFormatDirective::CalculateDataPointer(const TUint8* aDataPtr,TInt aIndex) const
+	{
+	TInt numParams = NumberOfParameters();
+	__ASSERT_DEBUG(aIndex<=numParams, Panic(EParameterIndexOutOfRange1));
+	TInt paramInfo = iSizesOfParametersInBytes;
+	while(numParams--)
+		{
+		TInt alignMask = (4<<(paramInfo&EMaskForAlignmentShift))-1;
+		aDataPtr = (TUint8*)(((TInt)aDataPtr+alignMask)&~alignMask);
+		if(!aIndex--)
+			break;
+		aDataPtr += paramInfo&EMaskForParameterSize;
+		paramInfo >>= ENumberOfBitsPerParameter;
+		}
+	return const_cast<TUint8*>(aDataPtr);
+	}
+
+// TParameterManager
+
+class TParameterManager
+	{
+public:
+	TParameterManager();
+	void AddFormatDirective(const TFormatDirective& aFormatDirective);
+	TInt PrepareToExtractNextParameter(VA_LIST aList); // returns either KErrNone or KErrNotReady
+	void PrepareToExtractParameters(VA_LIST aList);
+	TInt ExtractParameter(TAny* aTarget, TInt aSizeOfParameterInBytes, TInt aFormatDirectiveIndex, TInt aParameterIndexWithinFormatDirective, const TFormatDirective* aNextFormatDirective);
+private:
+	enum
+		{
+		EMaximumNumberOfFormatDirectives=40,
+		ENumberOfBytesInBitArray=(EMaximumNumberOfFormatDirectives+7)/8
+		};
+private:
+	inline TBool FormatDirectiveIsSet(TInt aIndex) const {return iFormatDirectivesSet[aIndex/8]&(1<<(aIndex%8));}
+	inline void MarkFormatDirectiveAsSet(TInt aIndex) {iFormatDirectivesSet[aIndex/8]|=(1<<(aIndex%8)); __ASSERT_DEBUG(FormatDirectiveIsSet(aIndex), Panic(EFormatDirectiveAlreadySet1));}
+private:
+	TInt iNumberOfFormatDirectives;
+	TFixedArray<TUint8, ENumberOfBytesInBitArray> iFormatDirectivesSet;
+	TFixedArray<TFormatDirective, EMaximumNumberOfFormatDirectives> iFormatDirectives;
+	TFixedArray<const TUint8*, EMaximumNumberOfFormatDirectives> iFormatDirectiveDataPointers;
+	};
+
+TParameterManager::TParameterManager()
+	:iNumberOfFormatDirectives(0)
+	{
+	TInt i;
+	for (i=0; i<ENumberOfBytesInBitArray; ++i)
+		{
+		iFormatDirectivesSet[i]=0;
+		}
+	for (i=0; i<EMaximumNumberOfFormatDirectives; ++i)
+		{
+		iFormatDirectiveDataPointers[i]=NULL;
+		}
+	}
+
+void TParameterManager::AddFormatDirective(const TFormatDirective& aFormatDirective)
+	{
+	__ASSERT_ALWAYS(iNumberOfFormatDirectives<EMaximumNumberOfFormatDirectives, Panic(ENumberOfFormatDirectivesExceedsMaximum));
+	const TInt index=(aFormatDirective.iFormatDirectiveIndex>=0)? aFormatDirective.iFormatDirectiveIndex: iNumberOfFormatDirectives;
+	__ASSERT_ALWAYS(!FormatDirectiveIsSet(index), Panic(EFormatDirectiveAlreadySet2));
+	MarkFormatDirectiveAsSet(index);
+	iFormatDirectives[index]=aFormatDirective;
+	++iNumberOfFormatDirectives;
+	}
+
+TInt TParameterManager::PrepareToExtractNextParameter(VA_LIST aList)
+	{
+	if (iNumberOfFormatDirectives==0)
+		{
+#ifdef EABI_STYLE_VA_LISTS
+		// NB under the EABI we are passing va_list (a struct) by value. 
+		// We could extract the pointer using aList.__ap under RVCT, but I don't believe the EABI 
+		// extends to the name of the field. So I think the 'nasty' cast is likely to be more
+		// portable.
+		const TUint8 ** aL = (const TUint8**)&aList;
+		iFormatDirectiveDataPointers[iNumberOfFormatDirectives] = aL[0];
+#else
+		// The horrible cast is there because you can't assume aList is of 'array' type   
+		iFormatDirectiveDataPointers[iNumberOfFormatDirectives] = (const TUint8*)(*(TInt*)aList);
+#endif
+		}
+	else
+		{
+		const TInt previousFormatDirective=iNumberOfFormatDirectives-1;
+		const TUint8* dataPointer=iFormatDirectiveDataPointers[previousFormatDirective];
+		if ((dataPointer==NULL) || !FormatDirectiveIsSet(previousFormatDirective))
+			{
+			return KErrNotReady;
+			}
+		const TFormatDirective& formatDirective=iFormatDirectives[previousFormatDirective];
+		dataPointer = formatDirective.CalculateDataPointer(dataPointer,formatDirective.NumberOfParameters());
+		iFormatDirectiveDataPointers[iNumberOfFormatDirectives]=dataPointer;
+		}
+	return KErrNone;
+	}
+
+void TParameterManager::PrepareToExtractParameters(VA_LIST aList)
+	{
+#ifdef EABI_STYLE_VA_LISTS
+	// NB under the EABI we are passing va_list (a struct) by value. 
+	// We could extract the pointer using aList.__ap under RVCT, but I don't believe the EABI 
+	// extends to the name of the field. So I think the 'nasty' cast is likely to be more
+	// portable.
+	const TUint8 ** aL = (const TUint8**)&aList;
+	const TUint8* dataPointer = aL[0];
+#else
+	// The horrible cast is there because you can't assume aList is of 'array' type   
+	const TUint8* dataPointer = (const TUint8*)(*(TInt*)aList);
+#endif
+	if (iNumberOfFormatDirectives>0)
+		{
+		for (TInt i=0; ; ++i)
+			{
+			__ASSERT_ALWAYS(FormatDirectiveIsSet(i), Panic(EFormatDirectiveNotYetSet));
+			__ASSERT_DEBUG((iFormatDirectiveDataPointers[i]==NULL) || (iFormatDirectiveDataPointers[i]==dataPointer), Panic(EBadFormatDirectiveDataPointer));
+			iFormatDirectiveDataPointers[i]=dataPointer;
+			if (i+1>=iNumberOfFormatDirectives)
+				{
+				break;
+				}
+			const TFormatDirective& formatDirective=iFormatDirectives[i];
+			dataPointer = formatDirective.CalculateDataPointer(dataPointer,formatDirective.NumberOfParameters());
+			}
+		}
+	}
+
+TInt TParameterManager::ExtractParameter(TAny* aTarget, TInt aSizeOfParameterInBytes, TInt aFormatDirectiveIndex, TInt aParameterIndexWithinFormatDirective, const TFormatDirective* aNextFormatDirective)
+	{
+	__ASSERT_DEBUG(aFormatDirectiveIndex<EMaximumNumberOfFormatDirectives, Panic(EFormatDirectiveIndexOutOfRange));
+	const TFormatDirective* formatDirective=NULL;
+	if (aFormatDirectiveIndex<iNumberOfFormatDirectives)
+		{
+		if (!FormatDirectiveIsSet(aFormatDirectiveIndex))
+			{
+			return KErrNotReady;
+			}
+		formatDirective=&iFormatDirectives[aFormatDirectiveIndex];
+		}
+	else
+		{
+		__ASSERT_DEBUG(aNextFormatDirective!=NULL, Panic(ENotOnFirstPassOfFormatDescriptor1)); // the above condition (aFormatDirectiveIndex>=iNumberOfFormatDirectives) can only be the case on a first pass of the format descriptor, so assert that we're on the first pass
+		if (aFormatDirectiveIndex>iNumberOfFormatDirectives)
+			{
+			return KErrNotReady;
+			}
+		formatDirective=aNextFormatDirective;
+		}
+	__ASSERT_DEBUG(aSizeOfParameterInBytes==formatDirective->SizeOfParameter(aParameterIndexWithinFormatDirective), Panic(EInconsistentSizeOfParameter));
+	const TUint8* dataPointer=iFormatDirectiveDataPointers[aFormatDirectiveIndex];
+	if (dataPointer==NULL)
+		{
+		__ASSERT_DEBUG(aNextFormatDirective!=NULL, Panic(ENotOnFirstPassOfFormatDescriptor2)); // the above condition (dataPointer==NULL) can only be the case on a first pass of the format descriptor, so assert that we're on the first pass
+		return KErrNotReady;
+		}
+	__ASSERT_DEBUG(aParameterIndexWithinFormatDirective<formatDirective->NumberOfParameters(), Panic(EParameterIndexOutOfRange2));
+	dataPointer = formatDirective->CalculateDataPointer(dataPointer,aParameterIndexWithinFormatDirective);
+	Mem::Copy(aTarget, dataPointer, aSizeOfParameterInBytes);
+	return KErrNone;
+	}
+
+// TParameterHandler
+
+class TParameterHandler
+	{
+public:
+	enum TAction
+		{
+		EParameterNotExtracted,
+		EParameterExtracted
+		};
+public:
+	inline TParameterHandler(TInt aImplicitFormatDirectiveIndex, TParameterManager& aParameterManager, TFormatDirective& aFormatDirective) :iFormatDirectiveIndex(aImplicitFormatDirectiveIndex), iParameterIndex(0), iFormatDirective(&aFormatDirective), iParameterManager(aParameterManager) {} // for the first pass
+	inline TParameterHandler(TInt aImplicitFormatDirectiveIndex, TParameterManager& aParameterManager) :iFormatDirectiveIndex(aImplicitFormatDirectiveIndex), iParameterIndex(0), iFormatDirective(NULL), iParameterManager(aParameterManager) {} // for the second pass
+	TAction HandleParameter(TAny* aTarget, TInt aSizeOfParameterInBytes, TInt aParameterAlignment=4);
+	void FormatDirectiveHasExplicitIndex(TInt aFormatDirectiveIndex);
+private:
+	TInt iFormatDirectiveIndex;
+	TInt iParameterIndex;
+	TFormatDirective* iFormatDirective;
+	TParameterManager& iParameterManager;
+	};
+
+TParameterHandler::TAction TParameterHandler::HandleParameter(TAny* aTarget, TInt aSizeOfParameterInBytes, TInt aParameterAlignment)
+// Increments iParameterIndex each time it is called.
+// This is conceptually a sort of virtual function (i.e. it's behaviour depends on the way the object was constructed), although it is not implemented like that.
+	{
+	__ASSERT_DEBUG(aTarget!=NULL, Panic(ENullTargetPointer));
+	__ASSERT_DEBUG(aSizeOfParameterInBytes>=0, Panic(ENegativeSizeOfParameter));
+	const TUint machineWordAlignmentConstant=sizeof(TUint)-1;
+	aSizeOfParameterInBytes+=machineWordAlignmentConstant;
+	aSizeOfParameterInBytes&=~machineWordAlignmentConstant;
+
+	if (iFormatDirective!=NULL)
+		{
+		iFormatDirective->AppendParameter(aSizeOfParameterInBytes,aParameterAlignment);
+		}
+	const TInt error=iParameterManager.ExtractParameter(aTarget, aSizeOfParameterInBytes, iFormatDirectiveIndex, iParameterIndex, iFormatDirective);
+#if defined(_DEBUG)
+	if (iFormatDirective==NULL) // if we're on the second pass...
+		{
+		__ASSERT_DEBUG(error==KErrNone, Panic(EErrorOnSecondPassOfFormatDescriptor));
+		}
+	else
+		{
+		__ASSERT_DEBUG(error==KErrNone || error==KErrNotReady, Panic(EUnexpectedError1));
+		}
+#endif
+	++iParameterIndex;
+	return (error==KErrNone)? EParameterExtracted: EParameterNotExtracted;
+	}
+
+void TParameterHandler::FormatDirectiveHasExplicitIndex(TInt aFormatDirectiveIndex)
+	{
+	if (iFormatDirective!=NULL)
+		{
+		iFormatDirective->FormatDirectiveHasExplicitIndex(aFormatDirectiveIndex);
+		}
+	iFormatDirectiveIndex=aFormatDirectiveIndex;
+	}
+
+template <class XDesC, class XFormatedText, class XLex, class XPanicker, TInt XItemSize>
+void HandleFormatDirective(TParameterHandler& aParameterHandler, XFormatedText& aFormatedText, XLex& aFmt)
+//
+// Handle a single format directive, i.e. sequence starting with a '%', (although the initial '%' will have been consumed by this point).
+//
+	{
+
+// Determine alignment of various types on the stack. The FOFF approach 
+// does not work for GCC 3.4.4 on X86 so we use hardcoded constants instead.
+#if defined(__GCC32__) && defined(__X86__) 
+	const TInt KAlignTReal = 4;
+	const TInt KAlignTRealX = 4;
+	const TInt KAlignTInt64 = 4;
+#else
+	struct TReal_align {char c; TReal a;};
+	const TInt KAlignTReal = _FOFF(TReal_align,a);
+ #ifndef __VC32__ // MSVC generates an internal compiler error with the following code
+	struct TRealX_align {char c; TRealX a;};
+	const TInt KAlignTRealX = _FOFF(TRealX_align,a);
+
+	struct TInt64_align {char c; TInt64 a;};
+	const TInt KAlignTInt64 = _FOFF(TInt64_align,a);
+ #else
+	const TInt KAlignTRealX = 4;	// Hard code value for MSVC
+	const TInt KAlignTInt64 = 4;	// Hard code value for MSVC
+ #endif
+#endif
+
+	aFormatedText.iJustify=ERight; // Default is justify right
+	aFormatedText.iFill=KNoChar; // Default fill character is space
+	// After a % may come +,-,= or space
+	if (aFmt.Eos())
+		XPanicker::Panic_BadFormatDescriptor();
+	TChar c=aFmt.Get();
+
+	if (c=='$')
+		{
+		TInt formatDirectiveIndex;
+		if (aFmt.Val(formatDirectiveIndex)!=0)
+			XPanicker::Panic_BadFormatDescriptor();
+		aParameterHandler.FormatDirectiveHasExplicitIndex(formatDirectiveIndex-1);
+		if (aFmt.Get()!='$')
+			XPanicker::Panic_BadFormatDescriptor();
+		c=aFmt.Get();
+		}
+
+	switch (c)
+		{
+	case ' ':
+		aFormatedText.iFill=' ';
+		break;
+	case '-':
+		aFormatedText.iJustify=ELeft;
+		goto getFill;
+	case '=':
+		aFormatedText.iJustify=ECenter;
+		goto getFill;
+	case '+':
+getFill:
+		if (aFmt.Eos())
+			XPanicker::Panic_BadFormatDescriptor();
+		if (!aFmt.Peek().IsDigit())
+			{
+			aFormatedText.iFill=aFmt.Get(); // assigning aFormatedText.iFill to something other than KNoChar is necessary as the aParameterHandler.HandleParameter call a couple of lines below will not necessarily set its first parameter (i.e. aFormatedText.iFill) - aFormatedText.iFill is tested against KNoChar ten or so lines below
+			if (aFormatedText.iFill=='*') // If*  take it from the arguments
+				aParameterHandler.HandleParameter(&aFormatedText.iFill, sizeof(TUint));
+			}
+		break;
+	default:
+		aFmt.UnGet();
+		}
+
+	aFormatedText.iWidth=KDefaultJustifyWidth; // Default width is whatever the conversion takes
+	if (aFmt.Peek().IsDigit())
+		{
+		// If it starts with 0 and the fill character has not been
+		// specified then the fill character will be a 0
+		// For compatibility with standard C libraries
+		if (aFmt.Peek()=='0' && aFormatedText.iFill==KNoChar)
+			{
+			aFormatedText.iFill='0';
+			aFmt.Inc();
+			}
+		if (aFmt.Peek()!='*')
+			if (aFmt.Val(aFormatedText.iWidth)) // Convert field width value
+				XPanicker::Panic_BadFormatDescriptor();
+		}
+	if (aFmt.Peek()=='*' && aFormatedText.iWidth==KDefaultJustifyWidth) // If a * then get width from arguments
+		{
+		aParameterHandler.HandleParameter(&aFormatedText.iWidth, sizeof(TInt));
+		aFmt.Inc();
+		}
+	// Get precision setting if given
+	TInt precision=KNoPrecision;
+	if (aFmt.Peek()=='.')
+		{
+		aFmt.Inc();
+		if (aFmt.Peek()=='*')
+			{
+			aParameterHandler.HandleParameter(&precision, sizeof(TInt));
+			aFmt.Inc();
+			}
+		else if (aFmt.Val(precision))
+			XPanicker::Panic_BadFormatDescriptor();
+		}
+	if (aFormatedText.iFill==KNoChar) // If still default fill character make it space
+		aFormatedText.iFill=' ';
+	if (aFmt.Eos())
+		XPanicker::Panic_BadFormatDescriptor();
+	TChar selector;
+	TBool lng=EFalse;
+	TCharUC f=aFmt.Peek();
+	if (f=='L') // If l set selector for longs
+		{
+		aFmt.Inc();
+		lng=ETrue;
+		}
+	selector=aFmt.Get(); // Get the selector in upper case
+	aFormatedText.iText=aFormatedText.iBuffer.Ptr();
+	aFormatedText.iTextLength=1;
+	TRadix radix=EDecimal;
+	TUint uVal=0;
+	TReal rVal=0;
+	TRealX rValX=0;
+	TInt realFormatType=KRealFormatFixed;
+	switch (selector)
+		{
+	case 'S': // String conversion
+		{
+		const XDesC* pB;
+		if (aParameterHandler.HandleParameter(&pB, sizeof(const TAny*))==TParameterHandler::EParameterExtracted)
+			{
+			__ASSERT_DEBUG(pB!=0,XPanicker::Panic_BadFormatParams());
+			aFormatedText.iTextLength=pB->Length();
+			if (precision!=KNoPrecision && precision<aFormatedText.iTextLength)
+				aFormatedText.iTextLength=precision;
+			aFormatedText.iText=pB->Ptr();
+			}
+		}
+		break;
+	case 's':
+		if (aParameterHandler.HandleParameter(&aFormatedText.iText, sizeof(const TAny*))==TParameterHandler::EParameterExtracted)
+			{
+			__ASSERT_DEBUG(aFormatedText.iText!=0,XPanicker::Panic_BadFormatParams());
+			if (precision!=KNoPrecision)
+				aFormatedText.iTextLength=precision;
+			else
+				aFormatedText.iTextLength=User::StringLength(aFormatedText.iText);
+			}
+		break;
+	case 'O':
+	case 'o':
+		radix=EOctal;
+		goto lConv;
+	case 'X':
+	case 'x':
+		radix=EHex;
+		goto lConv;
+	case 'B': // Binary conversion
+	case 'b':
+		radix=EBinary;
+		// Fall-through to lConv
+	case 'U':
+	case 'u':
+lConv:
+		if (lng)
+			{
+			TInt64 uVal64 = 0;
+			if (aParameterHandler.HandleParameter(&uVal64, sizeof(TInt64), KAlignTInt64)==TParameterHandler::EParameterExtracted)
+				{
+				if (selector=='X')
+					aFormatedText.iBuffer.NumUC(uVal64,radix);
+				else
+					aFormatedText.iBuffer.Num(uVal64,radix);
+				}
+			}
+		else
+			{
+			if (aParameterHandler.HandleParameter(&uVal, sizeof(TUint))==TParameterHandler::EParameterExtracted)
+				{
+				if (selector=='X')
+					aFormatedText.iBuffer.NumUC(uVal,radix);
+				else
+					aFormatedText.iBuffer.Num(uVal,radix);
+				}
+			}
+		aFormatedText.iTextLength=aFormatedText.iBuffer.Length();
+		break;
+	case 'D': // Decimal conversion
+	case 'd':
+	case 'I':
+	case 'i':
+		if (lng)
+			{
+			TInt64 iVal64=0;
+			if (aParameterHandler.HandleParameter(&iVal64, sizeof(TInt64),KAlignTInt64)==TParameterHandler::EParameterExtracted)
+				{
+				aFormatedText.iBuffer.Num(iVal64);
+				}
+			}
+		else
+			{
+			TInt iVal=0;
+			if (aParameterHandler.HandleParameter(&iVal, sizeof(TInt))==TParameterHandler::EParameterExtracted)
+				{
+				aFormatedText.iBuffer.Num(iVal);
+				}
+			}
+		aFormatedText.iTextLength=aFormatedText.iBuffer.Length();
+		break;
+	case 'P': // Padded conversion
+	case 'p':
+		aFormatedText.iTextLength=0;
+		break;
+	case 'C':
+	case 'c': // Ascii character conversion
+		if (aParameterHandler.HandleParameter(&uVal, sizeof(TUint))==TParameterHandler::EParameterExtracted)
+			{
+			aFormatedText.iBuffer.Append(uVal);
+			}
+		break;
+	case 'W': // SLONG binary lsb first conversion
+	case 'M': // SLONG binary msb first conversion
+		if (aParameterHandler.HandleParameter(&uVal, sizeof(TUint))!=TParameterHandler::EParameterExtracted)
+			{
+			break;
+			}
+		aFormatedText.iTextLength=4/XItemSize;
+		goto doBinary;
+	case 'w': // SWORD binary lsb first conversion
+	case 'm': // SWORD binary msb first conversion
+		if (aParameterHandler.HandleParameter(&uVal, sizeof(TUint))!=TParameterHandler::EParameterExtracted)
+			{
+			break;
+			}
+		aFormatedText.iTextLength=2/XItemSize;
+		//goto doBinary;
+doBinary:
+		{
+		TUint8* pC;
+		TInt increment;
+		if (selector=='m' || selector=='M')
+			{
+			pC=((TUint8*)(aFormatedText.iText+aFormatedText.iTextLength))-1;
+			increment=(-1);
+			}
+		else
+			{
+			pC=(TUint8*)aFormatedText.iText;
+			increment=1;
+			}
+		for (TInt k=aFormatedText.iTextLength*sizeof(*aFormatedText.iText);k>0;--k)
+			{
+			*pC=(TUint8)uVal;
+			pC+=increment;
+			uVal>>=8;
+			}
+		}
+		break;
+	case 'F': // TRealX conversion
+		if (aParameterHandler.HandleParameter(&rValX, sizeof(TRealX), KAlignTRealX)!=TParameterHandler::EParameterExtracted)
+			{
+			break;
+			}
+		rVal=rValX;
+		goto doReal;
+	case 'f': // TReal conversion
+		if (aParameterHandler.HandleParameter(&rVal, sizeof(TReal), KAlignTReal)!=TParameterHandler::EParameterExtracted)
+			{
+			break;
+			}
+		goto doReal;
+	case 'E':
+		if (aParameterHandler.HandleParameter(&rValX, sizeof(TRealX), KAlignTRealX)!=TParameterHandler::EParameterExtracted)
+			{
+			break;
+			}
+		rVal=rValX;
+		realFormatType=KRealFormatExponent|KAllowThreeDigitExp; 	// AnnW - changed from EExponent
+		goto doReal;
+	case 'e':
+		if (aParameterHandler.HandleParameter(&rVal, sizeof(TReal), KAlignTReal)!=TParameterHandler::EParameterExtracted)
+			{
+			break;
+			}
+		realFormatType=KRealFormatExponent|KAllowThreeDigitExp; 	// AnnW - changed from EExponent
+		//goto doReal;
+doReal:
+		{
+		if (precision==KNoPrecision)
+			precision=KDefaultPrecision;
+		TRealFormat realFormat(KMaxRealWidth, precision);
+		realFormat.iType=realFormatType;
+		aFormatedText.iTextLength=aFormatedText.iBuffer.Num(rVal, realFormat);
+		if (aFormatedText.iTextLength<0)
+			{
+			if (aFormatedText.iTextLength==KErrGeneral)
+				XPanicker::Panic_BadFormatDescriptor();
+			else
+				aFormatedText.iTextLength=aFormatedText.iBuffer.Length();
+			}
+		if (aFormatedText.iWidth!=KDefaultJustifyWidth && aFormatedText.iTextLength>aFormatedText.iWidth)
+			aFormatedText.iWidth=aFormatedText.iTextLength;
+		}
+		break;
+	case 'G':
+		if (aParameterHandler.HandleParameter(&rValX, sizeof(TRealX), KAlignTRealX)!=TParameterHandler::EParameterExtracted)
+			{
+			break;
+			}
+		rVal=rValX;
+		goto doGReal;
+	case 'g':
+		if (aParameterHandler.HandleParameter(&rVal, sizeof(TReal), KAlignTReal)!=TParameterHandler::EParameterExtracted)
+			{
+			break;
+			}
+		//goto doGReal;
+doGReal:
+		{
+		if (precision==KNoPrecision)
+			precision=KDefaultPrecision;
+
+		// aFormatedText.iBuffer must be >= KMaxRealWidth
+		TRealFormat realFormat(KMaxRealWidth, precision);	// Changed from 'width' to KMaxRealWidth
+		realFormat.iType=KRealFormatGeneral|KAllowThreeDigitExp;	// AnnW - changed from EGeneral
+		aFormatedText.iTextLength=aFormatedText.iBuffer.Num(rVal, realFormat);
+		if (aFormatedText.iTextLength<0)
+			{
+			// Doesn't fit in given width
+			realFormat.iWidth=KDefaultRealWidth;
+			aFormatedText.iTextLength=aFormatedText.iBuffer.Num(rVal, realFormat);
+			}
+		if (aFormatedText.iTextLength<0)
+			{
+			if (aFormatedText.iTextLength==KErrGeneral)
+				XPanicker::Panic_BadFormatDescriptor();
+			else
+				aFormatedText.iTextLength=aFormatedText.iBuffer.Length();
+			}
+		if (aFormatedText.iWidth!=KDefaultJustifyWidth && aFormatedText.iTextLength>aFormatedText.iWidth)
+			aFormatedText.iWidth=aFormatedText.iTextLength;
+		}
+		break;
+	default: // Not recognized - output % something
+		XPanicker::Panic_BadFormatDescriptor();
+		}
+	// Justify result of conversion
+	if (aFormatedText.iWidth==KDefaultJustifyWidth)
+		aFormatedText.iWidth=aFormatedText.iTextLength;
+	if (aFormatedText.iTextLength>aFormatedText.iWidth)
+		aFormatedText.iTextLength=aFormatedText.iWidth;
+	}
+
+template <class XDes, class XDesOverflow, class XDesC, class XFormatedText, class XLex, class XPanicker, TInt XItemSize>
+void DoAppendFormatList(XDes& aThis,const XDesC& aFormat,VA_LIST aList,XDesOverflow* aOverflowHandler)
+//
+// Convert the argument list, using the format descriptor.
+//
+	{
+
+	const TInt overflowLength=aOverflowHandler? aThis.MaxLength(): KMaxTInt;
+	const TInt originalLength=aThis.Length();
+	TBool needSecondPass=EFalse;
+	TParameterManager parameterManager;
+	XLex format(aFormat);
+	TInt implicitFormatDirectiveIndex=0;
+	FOREVER
+		{
+		if (format.Eos())
+			{
+			break;
+			}
+		const TChar character=format.Get();
+		if (character!='%')
+			{
+			if (!needSecondPass)
+				{
+				if (aThis.Length()>=overflowLength)
+					{
+					aOverflowHandler->Overflow(aThis);
+					return;
+					}
+				aThis.Append(character);
+				}
+			}
+		else if (format.Peek()=='%')
+			{
+			if (!needSecondPass)
+				{
+				if (aThis.Length()>=overflowLength)
+					{
+					aOverflowHandler->Overflow(aThis);
+					return;
+					}
+				aThis.Append(character);
+				}
+			format.Inc();
+			}
+		else
+			{
+			TFormatDirective formatDirective;
+			TParameterHandler parameterHandler(implicitFormatDirectiveIndex, parameterManager, formatDirective);
+			XFormatedText formatedText;
+			const TInt error=parameterManager.PrepareToExtractNextParameter(aList);
+			if (error!=KErrNone)
+				{
+				__ASSERT_DEBUG(error==KErrNotReady, Panic(EUnexpectedError2));
+				needSecondPass=ETrue;
+				}
+			HandleFormatDirective<XDesC, XFormatedText, XLex, XPanicker, XItemSize>(parameterHandler, formatedText, format);
+			parameterManager.AddFormatDirective(formatDirective);
+			if (!needSecondPass)
+				{
+				if ((aThis.Length()+formatedText.iWidth)>overflowLength)
+					{
+					aOverflowHandler->Overflow(aThis);
+					return;
+					}
+				aThis.AppendJustify(formatedText.iText, formatedText.iTextLength, formatedText.iWidth, formatedText.iJustify, formatedText.iFill);
+				}
+			++implicitFormatDirectiveIndex;
+			}
+		}
+	if (needSecondPass)
+		{
+		aThis.SetLength(originalLength);
+		parameterManager.PrepareToExtractParameters(aList);
+		format=aFormat;
+		implicitFormatDirectiveIndex=0;
+		FOREVER
+			{
+			if (format.Eos())
+				{
+				break;
+				}
+			const TChar character=format.Get();
+			if (character!='%')
+				{
+				if (aThis.Length()>=overflowLength)
+					{
+					aOverflowHandler->Overflow(aThis);
+					return;
+					}
+				aThis.Append(character);
+				}
+			else if (format.Peek()=='%')
+				{
+				if (aThis.Length()>=overflowLength)
+					{
+					aOverflowHandler->Overflow(aThis);
+					return;
+					}
+				aThis.Append(character);
+				format.Inc();
+				}
+			else
+				{
+				TParameterHandler parameterHandler(implicitFormatDirectiveIndex, parameterManager);
+				XFormatedText formatedText;
+				HandleFormatDirective<XDesC, XFormatedText, XLex, XPanicker, XItemSize>(parameterHandler, formatedText, format);
+				if ((aThis.Length()+formatedText.iWidth)>overflowLength)
+					{
+					aOverflowHandler->Overflow(aThis);
+					return;
+					}
+				aThis.AppendJustify(formatedText.iText, formatedText.iTextLength, formatedText.iWidth, formatedText.iJustify, formatedText.iFill);
+				++implicitFormatDirectiveIndex;
+				}
+			}
+		}
+	}
+
+
+
+
+/**
+Formats and appends text onto the end of this descriptor's data.
+	
+The length of this descriptor is incremented to reflect the new content.
+	
+The behaviour of this function is the same as
+AppendFormat(TRefByValue<const TDesC8> aFmt,TDes8Overflow *aOverflowHandler,...).
+In practice, it is better and easier to use AppendFormat(), passing a variable number of 
+arguments as required by the format string.
+	
+@param aFormat          The descriptor containing the format string.
+@param aList            A pointer to an argument list.
+@param aOverflowHandler If supplied, a pointer to the overflow handler.
+
+@see TDes8::AppendFormat
+@see VA_LIST 
+*/
+EXPORT_C void TDes8::AppendFormatList(const TDesC8 &aFormat,VA_LIST aList,TDes8Overflow *aOverflowHandler)
+	{
+
+	DoAppendFormatList<TDes8, TDes8Overflow, TDesC8, TFormatedText8, TLex8, TPanicker8, sizeof(TUint8)>(*this,aFormat,aList,aOverflowHandler);
+	}
+
+
+
+/**
+Formats and appends text onto the end of this descriptor's data.
+	
+The length of this descriptor is incremented to reflect the new content.
+	
+The behaviour of this function is the same as
+AppendFormat(TRefByValue<const TDesC16> aFmt,TDes16Overflow *aOverflowHandler,...).
+In practice, it is better and easier to use AppendFormat(), passing a variable number of 
+arguments as required by the format string.
+	
+@param aFormat          The descriptor containing the format string.
+@param aList            A pointer to an argument list.
+@param aOverflowHandler If supplied, a pointer to the overflow handler.
+
+@see TDes16::AppendFormat
+@see VA_LIST 
+*/
+EXPORT_C void TDes16::AppendFormatList(const TDesC16 &aFormat,VA_LIST aList,TDes16Overflow *aOverflowHandler)
+	{
+
+	DoAppendFormatList<TDes16, TDes16Overflow, TDesC16, TFormatedText16, TLex16, TPanicker16, sizeof(TUint16)>(*this,aFormat,aList,aOverflowHandler);
+	}
+