Update contrib.
1 // Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\euser\us_des.cpp
20 // Terrible hack. Surely we should use VA_START instead of the below?
21 #if defined(__EABI__) || (defined(__X86__) && defined(__GCC32__))
22 #define EABI_STYLE_VA_LISTS
25 const TInt KNoPrecision=-1;
26 const TInt KDefaultPrecision=6;
27 const TInt KMaxRealWidth=0x20;
29 // TFormatedText8 and TFormatedText16
53 // TPanicker8 and TPanicker16
58 static inline void Panic_BadFormatDescriptor() {Panic(ETDes8BadFormatDescriptor);}
59 static inline void Panic_BadFormatParams() {Panic(ETDes8BadFormatParams);}
65 static inline void Panic_BadFormatDescriptor() {Panic(ETDes16BadFormatDescriptor);}
66 static inline void Panic_BadFormatParams() {Panic(ETDes16BadFormatParams);}
71 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
74 inline TFormatDirective() :iSizesOfParametersInBytes(0), iFormatDirectiveIndex(EImplicitFormatDirectiveIndex) {}
75 void AppendParameter(TInt aSizeOfParameterInBytes,TInt aParameterAlignment);
76 inline void FormatDirectiveHasExplicitIndex(TInt aFormatDirectiveIndex) {iFormatDirectiveIndex=aFormatDirectiveIndex;}
78 friend class TParameterManager;
80 enum {EImplicitFormatDirectiveIndex=-1};
83 EShiftToNumberOfParameters=28,
84 ENumberOfBitsPerParameter=5,
85 EMaskForSingleParameter=(1<<ENumberOfBitsPerParameter)-1,
86 EMaskForAlignmentShift=3,
87 EMaskForParameterSize=EMaskForSingleParameter&~EMaskForAlignmentShift,
88 EMaximumNumberOfParameters=EShiftToNumberOfParameters/ENumberOfBitsPerParameter
90 private: // these functions are used by the TParameterManager class
91 inline TInt NumberOfParameters() const {return iSizesOfParametersInBytes>>EShiftToNumberOfParameters;}
92 TInt SizeOfParameter(TInt aIndex) const;
93 TUint8* CalculateDataPointer(const TUint8* aDataPtr,TInt aIndex) const;
95 TUint iSizesOfParametersInBytes; // a compactly stored array
96 TInt iFormatDirectiveIndex;
99 void TFormatDirective::AppendParameter(TInt aSizeOfParameterInBytes, TInt aParameterAlignment)
101 const TInt numberOfParameters=NumberOfParameters();
102 __ASSERT_DEBUG(numberOfParameters<EMaximumNumberOfParameters, Panic(ENumberOfParametersExceedsMaximum));
103 __ASSERT_DEBUG((aSizeOfParameterInBytes&EMaskForParameterSize)==aSizeOfParameterInBytes, Panic(ESizeOfParameterTooBig));
104 iSizesOfParametersInBytes+=(1<<EShiftToNumberOfParameters); // increment the count
106 switch(aParameterAlignment)
109 // aSizeOfParameterInBytes |= 0;
112 aSizeOfParameterInBytes |= 1;
115 __ASSERT_DEBUG(0, Panic(EUnexpectedError3));
118 iSizesOfParametersInBytes|=(aSizeOfParameterInBytes<<(numberOfParameters*ENumberOfBitsPerParameter)); // store aSizeOfParameterInBytes
121 TInt TFormatDirective::SizeOfParameter(TInt aIndex) const
123 __ASSERT_DEBUG(aIndex<NumberOfParameters(), Panic(EParameterIndexOutOfRange1));
124 return (iSizesOfParametersInBytes>>(aIndex*ENumberOfBitsPerParameter))&EMaskForParameterSize;
127 TUint8* TFormatDirective::CalculateDataPointer(const TUint8* aDataPtr,TInt aIndex) const
129 TInt numParams = NumberOfParameters();
130 __ASSERT_DEBUG(aIndex<=numParams, Panic(EParameterIndexOutOfRange1));
131 TInt paramInfo = iSizesOfParametersInBytes;
134 TInt alignMask = (4<<(paramInfo&EMaskForAlignmentShift))-1;
135 aDataPtr = (TUint8*)(((TInt)aDataPtr+alignMask)&~alignMask);
138 aDataPtr += paramInfo&EMaskForParameterSize;
139 paramInfo >>= ENumberOfBitsPerParameter;
141 return const_cast<TUint8*>(aDataPtr);
146 class TParameterManager
150 void AddFormatDirective(const TFormatDirective& aFormatDirective);
151 TInt PrepareToExtractNextParameter(VA_LIST aList); // returns either KErrNone or KErrNotReady
152 void PrepareToExtractParameters(VA_LIST aList);
153 TInt ExtractParameter(TAny* aTarget, TInt aSizeOfParameterInBytes, TInt aFormatDirectiveIndex, TInt aParameterIndexWithinFormatDirective, const TFormatDirective* aNextFormatDirective);
157 EMaximumNumberOfFormatDirectives=40,
158 ENumberOfBytesInBitArray=(EMaximumNumberOfFormatDirectives+7)/8
161 inline TBool FormatDirectiveIsSet(TInt aIndex) const {return iFormatDirectivesSet[aIndex/8]&(1<<(aIndex%8));}
162 inline void MarkFormatDirectiveAsSet(TInt aIndex) {iFormatDirectivesSet[aIndex/8]|=(1<<(aIndex%8)); __ASSERT_DEBUG(FormatDirectiveIsSet(aIndex), Panic(EFormatDirectiveAlreadySet1));}
164 TInt iNumberOfFormatDirectives;
165 TFixedArray<TUint8, ENumberOfBytesInBitArray> iFormatDirectivesSet;
166 TFixedArray<TFormatDirective, EMaximumNumberOfFormatDirectives> iFormatDirectives;
167 TFixedArray<const TUint8*, EMaximumNumberOfFormatDirectives> iFormatDirectiveDataPointers;
170 TParameterManager::TParameterManager()
171 :iNumberOfFormatDirectives(0)
174 for (i=0; i<ENumberOfBytesInBitArray; ++i)
176 iFormatDirectivesSet[i]=0;
178 for (i=0; i<EMaximumNumberOfFormatDirectives; ++i)
180 iFormatDirectiveDataPointers[i]=NULL;
184 void TParameterManager::AddFormatDirective(const TFormatDirective& aFormatDirective)
186 __ASSERT_ALWAYS(iNumberOfFormatDirectives<EMaximumNumberOfFormatDirectives, Panic(ENumberOfFormatDirectivesExceedsMaximum));
187 const TInt index=(aFormatDirective.iFormatDirectiveIndex>=0)? aFormatDirective.iFormatDirectiveIndex: iNumberOfFormatDirectives;
188 __ASSERT_ALWAYS(!FormatDirectiveIsSet(index), Panic(EFormatDirectiveAlreadySet2));
189 MarkFormatDirectiveAsSet(index);
190 iFormatDirectives[index]=aFormatDirective;
191 ++iNumberOfFormatDirectives;
194 TInt TParameterManager::PrepareToExtractNextParameter(VA_LIST aList)
196 if (iNumberOfFormatDirectives==0)
198 #ifdef EABI_STYLE_VA_LISTS
199 // NB under the EABI we are passing va_list (a struct) by value.
200 // We could extract the pointer using aList.__ap under RVCT, but I don't believe the EABI
201 // extends to the name of the field. So I think the 'nasty' cast is likely to be more
203 const TUint8 ** aL = (const TUint8**)&aList;
204 iFormatDirectiveDataPointers[iNumberOfFormatDirectives] = aL[0];
206 // The horrible cast is there because you can't assume aList is of 'array' type
207 iFormatDirectiveDataPointers[iNumberOfFormatDirectives] = (const TUint8*)(*(TInt*)aList);
212 const TInt previousFormatDirective=iNumberOfFormatDirectives-1;
213 const TUint8* dataPointer=iFormatDirectiveDataPointers[previousFormatDirective];
214 if ((dataPointer==NULL) || !FormatDirectiveIsSet(previousFormatDirective))
218 const TFormatDirective& formatDirective=iFormatDirectives[previousFormatDirective];
219 dataPointer = formatDirective.CalculateDataPointer(dataPointer,formatDirective.NumberOfParameters());
220 iFormatDirectiveDataPointers[iNumberOfFormatDirectives]=dataPointer;
225 void TParameterManager::PrepareToExtractParameters(VA_LIST aList)
227 #ifdef EABI_STYLE_VA_LISTS
228 // NB under the EABI we are passing va_list (a struct) by value.
229 // We could extract the pointer using aList.__ap under RVCT, but I don't believe the EABI
230 // extends to the name of the field. So I think the 'nasty' cast is likely to be more
232 const TUint8 ** aL = (const TUint8**)&aList;
233 const TUint8* dataPointer = aL[0];
235 // The horrible cast is there because you can't assume aList is of 'array' type
236 const TUint8* dataPointer = (const TUint8*)(*(TInt*)aList);
238 if (iNumberOfFormatDirectives>0)
240 for (TInt i=0; ; ++i)
242 __ASSERT_ALWAYS(FormatDirectiveIsSet(i), Panic(EFormatDirectiveNotYetSet));
243 __ASSERT_DEBUG((iFormatDirectiveDataPointers[i]==NULL) || (iFormatDirectiveDataPointers[i]==dataPointer), Panic(EBadFormatDirectiveDataPointer));
244 iFormatDirectiveDataPointers[i]=dataPointer;
245 if (i+1>=iNumberOfFormatDirectives)
249 const TFormatDirective& formatDirective=iFormatDirectives[i];
250 dataPointer = formatDirective.CalculateDataPointer(dataPointer,formatDirective.NumberOfParameters());
255 TInt TParameterManager::ExtractParameter(TAny* aTarget, TInt aSizeOfParameterInBytes, TInt aFormatDirectiveIndex, TInt aParameterIndexWithinFormatDirective, const TFormatDirective* aNextFormatDirective)
257 __ASSERT_DEBUG(aFormatDirectiveIndex<EMaximumNumberOfFormatDirectives, Panic(EFormatDirectiveIndexOutOfRange));
258 const TFormatDirective* formatDirective=NULL;
259 if (aFormatDirectiveIndex<iNumberOfFormatDirectives)
261 if (!FormatDirectiveIsSet(aFormatDirectiveIndex))
265 formatDirective=&iFormatDirectives[aFormatDirectiveIndex];
269 __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
270 if (aFormatDirectiveIndex>iNumberOfFormatDirectives)
274 formatDirective=aNextFormatDirective;
276 __ASSERT_DEBUG(aSizeOfParameterInBytes==formatDirective->SizeOfParameter(aParameterIndexWithinFormatDirective), Panic(EInconsistentSizeOfParameter));
277 const TUint8* dataPointer=iFormatDirectiveDataPointers[aFormatDirectiveIndex];
278 if (dataPointer==NULL)
280 __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
283 __ASSERT_DEBUG(aParameterIndexWithinFormatDirective<formatDirective->NumberOfParameters(), Panic(EParameterIndexOutOfRange2));
284 dataPointer = formatDirective->CalculateDataPointer(dataPointer,aParameterIndexWithinFormatDirective);
285 Mem::Copy(aTarget, dataPointer, aSizeOfParameterInBytes);
291 class TParameterHandler
296 EParameterNotExtracted,
300 inline TParameterHandler(TInt aImplicitFormatDirectiveIndex, TParameterManager& aParameterManager, TFormatDirective& aFormatDirective) :iFormatDirectiveIndex(aImplicitFormatDirectiveIndex), iParameterIndex(0), iFormatDirective(&aFormatDirective), iParameterManager(aParameterManager) {} // for the first pass
301 inline TParameterHandler(TInt aImplicitFormatDirectiveIndex, TParameterManager& aParameterManager) :iFormatDirectiveIndex(aImplicitFormatDirectiveIndex), iParameterIndex(0), iFormatDirective(NULL), iParameterManager(aParameterManager) {} // for the second pass
302 TAction HandleParameter(TAny* aTarget, TInt aSizeOfParameterInBytes, TInt aParameterAlignment=4);
303 void FormatDirectiveHasExplicitIndex(TInt aFormatDirectiveIndex);
305 TInt iFormatDirectiveIndex;
306 TInt iParameterIndex;
307 TFormatDirective* iFormatDirective;
308 TParameterManager& iParameterManager;
311 TParameterHandler::TAction TParameterHandler::HandleParameter(TAny* aTarget, TInt aSizeOfParameterInBytes, TInt aParameterAlignment)
312 // Increments iParameterIndex each time it is called.
313 // 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.
315 __ASSERT_DEBUG(aTarget!=NULL, Panic(ENullTargetPointer));
316 __ASSERT_DEBUG(aSizeOfParameterInBytes>=0, Panic(ENegativeSizeOfParameter));
317 const TUint machineWordAlignmentConstant=sizeof(TUint)-1;
318 aSizeOfParameterInBytes+=machineWordAlignmentConstant;
319 aSizeOfParameterInBytes&=~machineWordAlignmentConstant;
321 if (iFormatDirective!=NULL)
323 iFormatDirective->AppendParameter(aSizeOfParameterInBytes,aParameterAlignment);
325 const TInt error=iParameterManager.ExtractParameter(aTarget, aSizeOfParameterInBytes, iFormatDirectiveIndex, iParameterIndex, iFormatDirective);
327 if (iFormatDirective==NULL) // if we're on the second pass...
329 __ASSERT_DEBUG(error==KErrNone, Panic(EErrorOnSecondPassOfFormatDescriptor));
333 __ASSERT_DEBUG(error==KErrNone || error==KErrNotReady, Panic(EUnexpectedError1));
337 return (error==KErrNone)? EParameterExtracted: EParameterNotExtracted;
340 void TParameterHandler::FormatDirectiveHasExplicitIndex(TInt aFormatDirectiveIndex)
342 if (iFormatDirective!=NULL)
344 iFormatDirective->FormatDirectiveHasExplicitIndex(aFormatDirectiveIndex);
346 iFormatDirectiveIndex=aFormatDirectiveIndex;
349 template <class XDesC, class XFormatedText, class XLex, class XPanicker, TInt XItemSize>
350 void HandleFormatDirective(TParameterHandler& aParameterHandler, XFormatedText& aFormatedText, XLex& aFmt)
352 // Handle a single format directive, i.e. sequence starting with a '%', (although the initial '%' will have been consumed by this point).
356 // Determine alignment of various types on the stack. The FOFF approach
357 // does not work for GCC 3.4.4 on X86 so we use hardcoded constants instead.
358 #if defined(__GCC32__) && defined(__X86__)
359 const TInt KAlignTReal = 4;
360 const TInt KAlignTRealX = 4;
361 const TInt KAlignTInt64 = 4;
363 #ifndef __VC32__ // MSVC generates an internal compiler error with the following code
364 struct TReal_align {char c; TReal a;};
365 const TInt KAlignTReal = _FOFF(TReal_align,a);
367 struct TRealX_align {char c; TRealX a;};
368 const TInt KAlignTRealX = _FOFF(TRealX_align,a);
370 struct TInt64_align {char c; TInt64 a;};
371 const TInt KAlignTInt64 = _FOFF(TInt64_align,a);
373 //SL: Now also hardcoding KAlignTReal
374 const TInt KAlignTReal = 4;
375 const TInt KAlignTRealX = 4; // Hard code value for MSVC
376 const TInt KAlignTInt64 = 4; // Hard code value for MSVC
380 aFormatedText.iJustify=ERight; // Default is justify right
381 aFormatedText.iFill=KNoChar; // Default fill character is space
382 // After a % may come +,-,= or space
384 XPanicker::Panic_BadFormatDescriptor();
389 TInt formatDirectiveIndex;
390 if (aFmt.Val(formatDirectiveIndex)!=0)
391 XPanicker::Panic_BadFormatDescriptor();
392 aParameterHandler.FormatDirectiveHasExplicitIndex(formatDirectiveIndex-1);
394 XPanicker::Panic_BadFormatDescriptor();
401 aFormatedText.iFill=' ';
404 aFormatedText.iJustify=ELeft;
407 aFormatedText.iJustify=ECenter;
412 XPanicker::Panic_BadFormatDescriptor();
413 if (!aFmt.Peek().IsDigit())
415 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
416 if (aFormatedText.iFill=='*') // If* take it from the arguments
417 aParameterHandler.HandleParameter(&aFormatedText.iFill, sizeof(TUint));
424 aFormatedText.iWidth=KDefaultJustifyWidth; // Default width is whatever the conversion takes
425 if (aFmt.Peek().IsDigit())
427 // If it starts with 0 and the fill character has not been
428 // specified then the fill character will be a 0
429 // For compatibility with standard C libraries
430 if (aFmt.Peek()=='0' && aFormatedText.iFill==KNoChar)
432 aFormatedText.iFill='0';
435 if (aFmt.Peek()!='*')
436 if (aFmt.Val(aFormatedText.iWidth)) // Convert field width value
437 XPanicker::Panic_BadFormatDescriptor();
439 if (aFmt.Peek()=='*' && aFormatedText.iWidth==KDefaultJustifyWidth) // If a * then get width from arguments
441 aParameterHandler.HandleParameter(&aFormatedText.iWidth, sizeof(TInt));
444 // Get precision setting if given
445 TInt precision=KNoPrecision;
446 if (aFmt.Peek()=='.')
449 if (aFmt.Peek()=='*')
451 aParameterHandler.HandleParameter(&precision, sizeof(TInt));
454 else if (aFmt.Val(precision))
455 XPanicker::Panic_BadFormatDescriptor();
457 if (aFormatedText.iFill==KNoChar) // If still default fill character make it space
458 aFormatedText.iFill=' ';
460 XPanicker::Panic_BadFormatDescriptor();
463 TCharUC f=aFmt.Peek();
464 if (f=='L') // If l set selector for longs
469 selector=aFmt.Get(); // Get the selector in upper case
470 aFormatedText.iText=aFormatedText.iBuffer.Ptr();
471 aFormatedText.iTextLength=1;
472 TRadix radix=EDecimal;
476 TInt realFormatType=KRealFormatFixed;
479 case 'S': // String conversion
482 if (aParameterHandler.HandleParameter(&pB, sizeof(const TAny*))==TParameterHandler::EParameterExtracted)
484 __ASSERT_DEBUG(pB!=0,XPanicker::Panic_BadFormatParams());
485 aFormatedText.iTextLength=pB->Length();
486 if (precision!=KNoPrecision && precision<aFormatedText.iTextLength)
487 aFormatedText.iTextLength=precision;
488 aFormatedText.iText=pB->Ptr();
493 if (aParameterHandler.HandleParameter(&aFormatedText.iText, sizeof(const TAny*))==TParameterHandler::EParameterExtracted)
495 __ASSERT_DEBUG(aFormatedText.iText!=0,XPanicker::Panic_BadFormatParams());
496 if (precision!=KNoPrecision)
497 aFormatedText.iTextLength=precision;
499 aFormatedText.iTextLength=User::StringLength(aFormatedText.iText);
510 case 'B': // Binary conversion
513 // Fall-through to lConv
520 if (aParameterHandler.HandleParameter(&uVal64, sizeof(TInt64), KAlignTInt64)==TParameterHandler::EParameterExtracted)
523 aFormatedText.iBuffer.NumUC(uVal64,radix);
525 aFormatedText.iBuffer.Num(uVal64,radix);
530 if (aParameterHandler.HandleParameter(&uVal, sizeof(TUint))==TParameterHandler::EParameterExtracted)
533 aFormatedText.iBuffer.NumUC(uVal,radix);
535 aFormatedText.iBuffer.Num(uVal,radix);
538 aFormatedText.iTextLength=aFormatedText.iBuffer.Length();
540 case 'D': // Decimal conversion
547 if (aParameterHandler.HandleParameter(&iVal64, sizeof(TInt64),KAlignTInt64)==TParameterHandler::EParameterExtracted)
549 aFormatedText.iBuffer.Num(iVal64);
555 if (aParameterHandler.HandleParameter(&iVal, sizeof(TInt))==TParameterHandler::EParameterExtracted)
557 aFormatedText.iBuffer.Num(iVal);
560 aFormatedText.iTextLength=aFormatedText.iBuffer.Length();
562 case 'P': // Padded conversion
564 aFormatedText.iTextLength=0;
567 case 'c': // Ascii character conversion
568 if (aParameterHandler.HandleParameter(&uVal, sizeof(TUint))==TParameterHandler::EParameterExtracted)
570 aFormatedText.iBuffer.Append(uVal);
573 case 'W': // SLONG binary lsb first conversion
574 case 'M': // SLONG binary msb first conversion
575 if (aParameterHandler.HandleParameter(&uVal, sizeof(TUint))!=TParameterHandler::EParameterExtracted)
579 aFormatedText.iTextLength=4/XItemSize;
581 case 'w': // SWORD binary lsb first conversion
582 case 'm': // SWORD binary msb first conversion
583 if (aParameterHandler.HandleParameter(&uVal, sizeof(TUint))!=TParameterHandler::EParameterExtracted)
587 aFormatedText.iTextLength=2/XItemSize;
593 if (selector=='m' || selector=='M')
595 pC=((TUint8*)(aFormatedText.iText+aFormatedText.iTextLength))-1;
600 pC=(TUint8*)aFormatedText.iText;
603 for (TInt k=aFormatedText.iTextLength*sizeof(*aFormatedText.iText);k>0;--k)
611 case 'F': // TRealX conversion
612 if (aParameterHandler.HandleParameter(&rValX, sizeof(TRealX), KAlignTRealX)!=TParameterHandler::EParameterExtracted)
618 case 'f': // TReal conversion
619 if (aParameterHandler.HandleParameter(&rVal, sizeof(TReal), KAlignTReal)!=TParameterHandler::EParameterExtracted)
625 if (aParameterHandler.HandleParameter(&rValX, sizeof(TRealX), KAlignTRealX)!=TParameterHandler::EParameterExtracted)
630 realFormatType=KRealFormatExponent|KAllowThreeDigitExp; // AnnW - changed from EExponent
633 if (aParameterHandler.HandleParameter(&rVal, sizeof(TReal), KAlignTReal)!=TParameterHandler::EParameterExtracted)
637 realFormatType=KRealFormatExponent|KAllowThreeDigitExp; // AnnW - changed from EExponent
641 if (precision==KNoPrecision)
642 precision=KDefaultPrecision;
643 TRealFormat realFormat(KMaxRealWidth, precision);
644 realFormat.iType=realFormatType;
645 aFormatedText.iTextLength=aFormatedText.iBuffer.Num(rVal, realFormat);
646 if (aFormatedText.iTextLength<0)
648 if (aFormatedText.iTextLength==KErrGeneral)
649 XPanicker::Panic_BadFormatDescriptor();
651 aFormatedText.iTextLength=aFormatedText.iBuffer.Length();
653 if (aFormatedText.iWidth!=KDefaultJustifyWidth && aFormatedText.iTextLength>aFormatedText.iWidth)
654 aFormatedText.iWidth=aFormatedText.iTextLength;
658 if (aParameterHandler.HandleParameter(&rValX, sizeof(TRealX), KAlignTRealX)!=TParameterHandler::EParameterExtracted)
665 if (aParameterHandler.HandleParameter(&rVal, sizeof(TReal), KAlignTReal)!=TParameterHandler::EParameterExtracted)
672 if (precision==KNoPrecision)
673 precision=KDefaultPrecision;
675 // aFormatedText.iBuffer must be >= KMaxRealWidth
676 TRealFormat realFormat(KMaxRealWidth, precision); // Changed from 'width' to KMaxRealWidth
677 realFormat.iType=KRealFormatGeneral|KAllowThreeDigitExp; // AnnW - changed from EGeneral
678 aFormatedText.iTextLength=aFormatedText.iBuffer.Num(rVal, realFormat);
679 if (aFormatedText.iTextLength<0)
681 // Doesn't fit in given width
682 realFormat.iWidth=KDefaultRealWidth;
683 aFormatedText.iTextLength=aFormatedText.iBuffer.Num(rVal, realFormat);
685 if (aFormatedText.iTextLength<0)
687 if (aFormatedText.iTextLength==KErrGeneral)
688 XPanicker::Panic_BadFormatDescriptor();
690 aFormatedText.iTextLength=aFormatedText.iBuffer.Length();
692 if (aFormatedText.iWidth!=KDefaultJustifyWidth && aFormatedText.iTextLength>aFormatedText.iWidth)
693 aFormatedText.iWidth=aFormatedText.iTextLength;
696 default: // Not recognized - output % something
697 XPanicker::Panic_BadFormatDescriptor();
699 // Justify result of conversion
700 if (aFormatedText.iWidth==KDefaultJustifyWidth)
701 aFormatedText.iWidth=aFormatedText.iTextLength;
702 if (aFormatedText.iTextLength>aFormatedText.iWidth)
703 aFormatedText.iTextLength=aFormatedText.iWidth;
706 template <class XDes, class XDesOverflow, class XDesC, class XFormatedText, class XLex, class XPanicker, TInt XItemSize>
707 void DoAppendFormatList(XDes& aThis,const XDesC& aFormat,VA_LIST aList,XDesOverflow* aOverflowHandler)
709 // Convert the argument list, using the format descriptor.
713 const TInt overflowLength=aOverflowHandler? aThis.MaxLength(): KMaxTInt;
714 const TInt originalLength=aThis.Length();
715 TBool needSecondPass=EFalse;
716 TParameterManager parameterManager;
717 XLex format(aFormat);
718 TInt implicitFormatDirectiveIndex=0;
725 const TChar character=format.Get();
730 if (aThis.Length()>=overflowLength)
732 aOverflowHandler->Overflow(aThis);
735 aThis.Append(character);
738 else if (format.Peek()=='%')
742 if (aThis.Length()>=overflowLength)
744 aOverflowHandler->Overflow(aThis);
747 aThis.Append(character);
753 TFormatDirective formatDirective;
754 TParameterHandler parameterHandler(implicitFormatDirectiveIndex, parameterManager, formatDirective);
755 XFormatedText formatedText;
756 const TInt error=parameterManager.PrepareToExtractNextParameter(aList);
759 __ASSERT_DEBUG(error==KErrNotReady, Panic(EUnexpectedError2));
760 needSecondPass=ETrue;
762 HandleFormatDirective<XDesC, XFormatedText, XLex, XPanicker, XItemSize>(parameterHandler, formatedText, format);
763 parameterManager.AddFormatDirective(formatDirective);
766 if ((aThis.Length()+formatedText.iWidth)>overflowLength)
768 aOverflowHandler->Overflow(aThis);
771 aThis.AppendJustify(formatedText.iText, formatedText.iTextLength, formatedText.iWidth, formatedText.iJustify, formatedText.iFill);
773 ++implicitFormatDirectiveIndex;
778 aThis.SetLength(originalLength);
779 parameterManager.PrepareToExtractParameters(aList);
781 implicitFormatDirectiveIndex=0;
788 const TChar character=format.Get();
791 if (aThis.Length()>=overflowLength)
793 aOverflowHandler->Overflow(aThis);
796 aThis.Append(character);
798 else if (format.Peek()=='%')
800 if (aThis.Length()>=overflowLength)
802 aOverflowHandler->Overflow(aThis);
805 aThis.Append(character);
810 TParameterHandler parameterHandler(implicitFormatDirectiveIndex, parameterManager);
811 XFormatedText formatedText;
812 HandleFormatDirective<XDesC, XFormatedText, XLex, XPanicker, XItemSize>(parameterHandler, formatedText, format);
813 if ((aThis.Length()+formatedText.iWidth)>overflowLength)
815 aOverflowHandler->Overflow(aThis);
818 aThis.AppendJustify(formatedText.iText, formatedText.iTextLength, formatedText.iWidth, formatedText.iJustify, formatedText.iFill);
819 ++implicitFormatDirectiveIndex;
829 Formats and appends text onto the end of this descriptor's data.
831 The length of this descriptor is incremented to reflect the new content.
833 The behaviour of this function is the same as
834 AppendFormat(TRefByValue<const TDesC8> aFmt,TDes8Overflow *aOverflowHandler,...).
835 In practice, it is better and easier to use AppendFormat(), passing a variable number of
836 arguments as required by the format string.
838 @param aFormat The descriptor containing the format string.
839 @param aList A pointer to an argument list.
840 @param aOverflowHandler If supplied, a pointer to the overflow handler.
842 @see TDes8::AppendFormat
845 EXPORT_C void TDes8::AppendFormatList(const TDesC8 &aFormat,VA_LIST aList,TDes8Overflow *aOverflowHandler)
848 DoAppendFormatList<TDes8, TDes8Overflow, TDesC8, TFormatedText8, TLex8, TPanicker8, sizeof(TUint8)>(*this,aFormat,aList,aOverflowHandler);
854 Formats and appends text onto the end of this descriptor's data.
856 The length of this descriptor is incremented to reflect the new content.
858 The behaviour of this function is the same as
859 AppendFormat(TRefByValue<const TDesC16> aFmt,TDes16Overflow *aOverflowHandler,...).
860 In practice, it is better and easier to use AppendFormat(), passing a variable number of
861 arguments as required by the format string.
863 @param aFormat The descriptor containing the format string.
864 @param aList A pointer to an argument list.
865 @param aOverflowHandler If supplied, a pointer to the overflow handler.
867 @see TDes16::AppendFormat
870 EXPORT_C void TDes16::AppendFormatList(const TDesC16 &aFormat,VA_LIST aList,TDes16Overflow *aOverflowHandler)
873 DoAppendFormatList<TDes16, TDes16Overflow, TDesC16, TFormatedText16, TLex16, TPanicker16, sizeof(TUint16)>(*this,aFormat,aList,aOverflowHandler);