First public contribution.
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 struct TReal_align {char c; TReal a;};
364 const TInt KAlignTReal = _FOFF(TReal_align,a);
365 #ifndef __VC32__ // MSVC generates an internal compiler error with the following code
366 struct TRealX_align {char c; TRealX a;};
367 const TInt KAlignTRealX = _FOFF(TRealX_align,a);
369 struct TInt64_align {char c; TInt64 a;};
370 const TInt KAlignTInt64 = _FOFF(TInt64_align,a);
372 const TInt KAlignTRealX = 4; // Hard code value for MSVC
373 const TInt KAlignTInt64 = 4; // Hard code value for MSVC
377 aFormatedText.iJustify=ERight; // Default is justify right
378 aFormatedText.iFill=KNoChar; // Default fill character is space
379 // After a % may come +,-,= or space
381 XPanicker::Panic_BadFormatDescriptor();
386 TInt formatDirectiveIndex;
387 if (aFmt.Val(formatDirectiveIndex)!=0)
388 XPanicker::Panic_BadFormatDescriptor();
389 aParameterHandler.FormatDirectiveHasExplicitIndex(formatDirectiveIndex-1);
391 XPanicker::Panic_BadFormatDescriptor();
398 aFormatedText.iFill=' ';
401 aFormatedText.iJustify=ELeft;
404 aFormatedText.iJustify=ECenter;
409 XPanicker::Panic_BadFormatDescriptor();
410 if (!aFmt.Peek().IsDigit())
412 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
413 if (aFormatedText.iFill=='*') // If* take it from the arguments
414 aParameterHandler.HandleParameter(&aFormatedText.iFill, sizeof(TUint));
421 aFormatedText.iWidth=KDefaultJustifyWidth; // Default width is whatever the conversion takes
422 if (aFmt.Peek().IsDigit())
424 // If it starts with 0 and the fill character has not been
425 // specified then the fill character will be a 0
426 // For compatibility with standard C libraries
427 if (aFmt.Peek()=='0' && aFormatedText.iFill==KNoChar)
429 aFormatedText.iFill='0';
432 if (aFmt.Peek()!='*')
433 if (aFmt.Val(aFormatedText.iWidth)) // Convert field width value
434 XPanicker::Panic_BadFormatDescriptor();
436 if (aFmt.Peek()=='*' && aFormatedText.iWidth==KDefaultJustifyWidth) // If a * then get width from arguments
438 aParameterHandler.HandleParameter(&aFormatedText.iWidth, sizeof(TInt));
441 // Get precision setting if given
442 TInt precision=KNoPrecision;
443 if (aFmt.Peek()=='.')
446 if (aFmt.Peek()=='*')
448 aParameterHandler.HandleParameter(&precision, sizeof(TInt));
451 else if (aFmt.Val(precision))
452 XPanicker::Panic_BadFormatDescriptor();
454 if (aFormatedText.iFill==KNoChar) // If still default fill character make it space
455 aFormatedText.iFill=' ';
457 XPanicker::Panic_BadFormatDescriptor();
460 TCharUC f=aFmt.Peek();
461 if (f=='L') // If l set selector for longs
466 selector=aFmt.Get(); // Get the selector in upper case
467 aFormatedText.iText=aFormatedText.iBuffer.Ptr();
468 aFormatedText.iTextLength=1;
469 TRadix radix=EDecimal;
473 TInt realFormatType=KRealFormatFixed;
476 case 'S': // String conversion
479 if (aParameterHandler.HandleParameter(&pB, sizeof(const TAny*))==TParameterHandler::EParameterExtracted)
481 __ASSERT_DEBUG(pB!=0,XPanicker::Panic_BadFormatParams());
482 aFormatedText.iTextLength=pB->Length();
483 if (precision!=KNoPrecision && precision<aFormatedText.iTextLength)
484 aFormatedText.iTextLength=precision;
485 aFormatedText.iText=pB->Ptr();
490 if (aParameterHandler.HandleParameter(&aFormatedText.iText, sizeof(const TAny*))==TParameterHandler::EParameterExtracted)
492 __ASSERT_DEBUG(aFormatedText.iText!=0,XPanicker::Panic_BadFormatParams());
493 if (precision!=KNoPrecision)
494 aFormatedText.iTextLength=precision;
496 aFormatedText.iTextLength=User::StringLength(aFormatedText.iText);
507 case 'B': // Binary conversion
510 // Fall-through to lConv
517 if (aParameterHandler.HandleParameter(&uVal64, sizeof(TInt64), KAlignTInt64)==TParameterHandler::EParameterExtracted)
520 aFormatedText.iBuffer.NumUC(uVal64,radix);
522 aFormatedText.iBuffer.Num(uVal64,radix);
527 if (aParameterHandler.HandleParameter(&uVal, sizeof(TUint))==TParameterHandler::EParameterExtracted)
530 aFormatedText.iBuffer.NumUC(uVal,radix);
532 aFormatedText.iBuffer.Num(uVal,radix);
535 aFormatedText.iTextLength=aFormatedText.iBuffer.Length();
537 case 'D': // Decimal conversion
544 if (aParameterHandler.HandleParameter(&iVal64, sizeof(TInt64),KAlignTInt64)==TParameterHandler::EParameterExtracted)
546 aFormatedText.iBuffer.Num(iVal64);
552 if (aParameterHandler.HandleParameter(&iVal, sizeof(TInt))==TParameterHandler::EParameterExtracted)
554 aFormatedText.iBuffer.Num(iVal);
557 aFormatedText.iTextLength=aFormatedText.iBuffer.Length();
559 case 'P': // Padded conversion
561 aFormatedText.iTextLength=0;
564 case 'c': // Ascii character conversion
565 if (aParameterHandler.HandleParameter(&uVal, sizeof(TUint))==TParameterHandler::EParameterExtracted)
567 aFormatedText.iBuffer.Append(uVal);
570 case 'W': // SLONG binary lsb first conversion
571 case 'M': // SLONG binary msb first conversion
572 if (aParameterHandler.HandleParameter(&uVal, sizeof(TUint))!=TParameterHandler::EParameterExtracted)
576 aFormatedText.iTextLength=4/XItemSize;
578 case 'w': // SWORD binary lsb first conversion
579 case 'm': // SWORD binary msb first conversion
580 if (aParameterHandler.HandleParameter(&uVal, sizeof(TUint))!=TParameterHandler::EParameterExtracted)
584 aFormatedText.iTextLength=2/XItemSize;
590 if (selector=='m' || selector=='M')
592 pC=((TUint8*)(aFormatedText.iText+aFormatedText.iTextLength))-1;
597 pC=(TUint8*)aFormatedText.iText;
600 for (TInt k=aFormatedText.iTextLength*sizeof(*aFormatedText.iText);k>0;--k)
608 case 'F': // TRealX conversion
609 if (aParameterHandler.HandleParameter(&rValX, sizeof(TRealX), KAlignTRealX)!=TParameterHandler::EParameterExtracted)
615 case 'f': // TReal conversion
616 if (aParameterHandler.HandleParameter(&rVal, sizeof(TReal), KAlignTReal)!=TParameterHandler::EParameterExtracted)
622 if (aParameterHandler.HandleParameter(&rValX, sizeof(TRealX), KAlignTRealX)!=TParameterHandler::EParameterExtracted)
627 realFormatType=KRealFormatExponent|KAllowThreeDigitExp; // AnnW - changed from EExponent
630 if (aParameterHandler.HandleParameter(&rVal, sizeof(TReal), KAlignTReal)!=TParameterHandler::EParameterExtracted)
634 realFormatType=KRealFormatExponent|KAllowThreeDigitExp; // AnnW - changed from EExponent
638 if (precision==KNoPrecision)
639 precision=KDefaultPrecision;
640 TRealFormat realFormat(KMaxRealWidth, precision);
641 realFormat.iType=realFormatType;
642 aFormatedText.iTextLength=aFormatedText.iBuffer.Num(rVal, realFormat);
643 if (aFormatedText.iTextLength<0)
645 if (aFormatedText.iTextLength==KErrGeneral)
646 XPanicker::Panic_BadFormatDescriptor();
648 aFormatedText.iTextLength=aFormatedText.iBuffer.Length();
650 if (aFormatedText.iWidth!=KDefaultJustifyWidth && aFormatedText.iTextLength>aFormatedText.iWidth)
651 aFormatedText.iWidth=aFormatedText.iTextLength;
655 if (aParameterHandler.HandleParameter(&rValX, sizeof(TRealX), KAlignTRealX)!=TParameterHandler::EParameterExtracted)
662 if (aParameterHandler.HandleParameter(&rVal, sizeof(TReal), KAlignTReal)!=TParameterHandler::EParameterExtracted)
669 if (precision==KNoPrecision)
670 precision=KDefaultPrecision;
672 // aFormatedText.iBuffer must be >= KMaxRealWidth
673 TRealFormat realFormat(KMaxRealWidth, precision); // Changed from 'width' to KMaxRealWidth
674 realFormat.iType=KRealFormatGeneral|KAllowThreeDigitExp; // AnnW - changed from EGeneral
675 aFormatedText.iTextLength=aFormatedText.iBuffer.Num(rVal, realFormat);
676 if (aFormatedText.iTextLength<0)
678 // Doesn't fit in given width
679 realFormat.iWidth=KDefaultRealWidth;
680 aFormatedText.iTextLength=aFormatedText.iBuffer.Num(rVal, realFormat);
682 if (aFormatedText.iTextLength<0)
684 if (aFormatedText.iTextLength==KErrGeneral)
685 XPanicker::Panic_BadFormatDescriptor();
687 aFormatedText.iTextLength=aFormatedText.iBuffer.Length();
689 if (aFormatedText.iWidth!=KDefaultJustifyWidth && aFormatedText.iTextLength>aFormatedText.iWidth)
690 aFormatedText.iWidth=aFormatedText.iTextLength;
693 default: // Not recognized - output % something
694 XPanicker::Panic_BadFormatDescriptor();
696 // Justify result of conversion
697 if (aFormatedText.iWidth==KDefaultJustifyWidth)
698 aFormatedText.iWidth=aFormatedText.iTextLength;
699 if (aFormatedText.iTextLength>aFormatedText.iWidth)
700 aFormatedText.iTextLength=aFormatedText.iWidth;
703 template <class XDes, class XDesOverflow, class XDesC, class XFormatedText, class XLex, class XPanicker, TInt XItemSize>
704 void DoAppendFormatList(XDes& aThis,const XDesC& aFormat,VA_LIST aList,XDesOverflow* aOverflowHandler)
706 // Convert the argument list, using the format descriptor.
710 const TInt overflowLength=aOverflowHandler? aThis.MaxLength(): KMaxTInt;
711 const TInt originalLength=aThis.Length();
712 TBool needSecondPass=EFalse;
713 TParameterManager parameterManager;
714 XLex format(aFormat);
715 TInt implicitFormatDirectiveIndex=0;
722 const TChar character=format.Get();
727 if (aThis.Length()>=overflowLength)
729 aOverflowHandler->Overflow(aThis);
732 aThis.Append(character);
735 else if (format.Peek()=='%')
739 if (aThis.Length()>=overflowLength)
741 aOverflowHandler->Overflow(aThis);
744 aThis.Append(character);
750 TFormatDirective formatDirective;
751 TParameterHandler parameterHandler(implicitFormatDirectiveIndex, parameterManager, formatDirective);
752 XFormatedText formatedText;
753 const TInt error=parameterManager.PrepareToExtractNextParameter(aList);
756 __ASSERT_DEBUG(error==KErrNotReady, Panic(EUnexpectedError2));
757 needSecondPass=ETrue;
759 HandleFormatDirective<XDesC, XFormatedText, XLex, XPanicker, XItemSize>(parameterHandler, formatedText, format);
760 parameterManager.AddFormatDirective(formatDirective);
763 if ((aThis.Length()+formatedText.iWidth)>overflowLength)
765 aOverflowHandler->Overflow(aThis);
768 aThis.AppendJustify(formatedText.iText, formatedText.iTextLength, formatedText.iWidth, formatedText.iJustify, formatedText.iFill);
770 ++implicitFormatDirectiveIndex;
775 aThis.SetLength(originalLength);
776 parameterManager.PrepareToExtractParameters(aList);
778 implicitFormatDirectiveIndex=0;
785 const TChar character=format.Get();
788 if (aThis.Length()>=overflowLength)
790 aOverflowHandler->Overflow(aThis);
793 aThis.Append(character);
795 else if (format.Peek()=='%')
797 if (aThis.Length()>=overflowLength)
799 aOverflowHandler->Overflow(aThis);
802 aThis.Append(character);
807 TParameterHandler parameterHandler(implicitFormatDirectiveIndex, parameterManager);
808 XFormatedText formatedText;
809 HandleFormatDirective<XDesC, XFormatedText, XLex, XPanicker, XItemSize>(parameterHandler, formatedText, format);
810 if ((aThis.Length()+formatedText.iWidth)>overflowLength)
812 aOverflowHandler->Overflow(aThis);
815 aThis.AppendJustify(formatedText.iText, formatedText.iTextLength, formatedText.iWidth, formatedText.iJustify, formatedText.iFill);
816 ++implicitFormatDirectiveIndex;
826 Formats and appends text onto the end of this descriptor's data.
828 The length of this descriptor is incremented to reflect the new content.
830 The behaviour of this function is the same as
831 AppendFormat(TRefByValue<const TDesC8> aFmt,TDes8Overflow *aOverflowHandler,...).
832 In practice, it is better and easier to use AppendFormat(), passing a variable number of
833 arguments as required by the format string.
835 @param aFormat The descriptor containing the format string.
836 @param aList A pointer to an argument list.
837 @param aOverflowHandler If supplied, a pointer to the overflow handler.
839 @see TDes8::AppendFormat
842 EXPORT_C void TDes8::AppendFormatList(const TDesC8 &aFormat,VA_LIST aList,TDes8Overflow *aOverflowHandler)
845 DoAppendFormatList<TDes8, TDes8Overflow, TDesC8, TFormatedText8, TLex8, TPanicker8, sizeof(TUint8)>(*this,aFormat,aList,aOverflowHandler);
851 Formats and appends text onto the end of this descriptor's data.
853 The length of this descriptor is incremented to reflect the new content.
855 The behaviour of this function is the same as
856 AppendFormat(TRefByValue<const TDesC16> aFmt,TDes16Overflow *aOverflowHandler,...).
857 In practice, it is better and easier to use AppendFormat(), passing a variable number of
858 arguments as required by the format string.
860 @param aFormat The descriptor containing the format string.
861 @param aList A pointer to an argument list.
862 @param aOverflowHandler If supplied, a pointer to the overflow handler.
864 @see TDes16::AppendFormat
867 EXPORT_C void TDes16::AppendFormatList(const TDesC16 &aFormat,VA_LIST aList,TDes16Overflow *aOverflowHandler)
870 DoAppendFormatList<TDes16, TDes16Overflow, TDesC16, TFormatedText16, TLex16, TPanicker16, sizeof(TUint16)>(*this,aFormat,aList,aOverflowHandler);