--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/euser/us_des.cpp Thu Dec 17 09:24:54 2009 +0200
@@ -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);
+ }
+