sl@0: // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32\euser\maths\um_dtor.cpp sl@0: // sl@0: // sl@0: sl@0: #include "um_std.h" sl@0: sl@0: const TInt KMaxScanDigits = 19; // maximum number of decimal digits guaranteed not to overflow TUint64 sl@0: sl@0: void TLex8::Scndig(TInt& aSig, TInt& aExp, TUint64& aDl) sl@0: // sl@0: // Scans a decimal digit field and accumulates the value to a TUint64 at aDl sl@0: // Used before decimal point - do not drop trailing zeros. sl@0: // sl@0: { sl@0: FOREVER sl@0: { sl@0: if (iNext>=iEnd) sl@0: break; sl@0: TChar c=Peek(); sl@0: if (!c.IsDigit()) sl@0: break; sl@0: else sl@0: c=Get(); sl@0: if (aSig=iEnd) sl@0: break; sl@0: c=Peek(); sl@0: if (!c.IsDigit()) sl@0: break; sl@0: else sl@0: { sl@0: c=Get(); sl@0: if (c=='0') sl@0: { sl@0: if (aDl!=0) // possible trailing zeros sl@0: trailing++; sl@0: else // if aDl==0 multiplying by 10 and adding 0 has no effect sl@0: { sl@0: leading++; sl@0: aSig++; // leading zeros have significance sl@0: } sl@0: } sl@0: else if ((aSig=0; n--) sl@0: { sl@0: aDl *= 10; // Multiply accumulator by 10 sl@0: } sl@0: // now add current digit sl@0: aDl+=((TUint)c)-'0'; sl@0: // now update significant digits used sl@0: aSig+=trailing+1; sl@0: trailing=0; sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: void TLex16::Scndig(TInt& aSig, TInt& aExp, TUint64& aDl) sl@0: // sl@0: // Scans a decimal digit field and accumulates the value to a TUint64 at aDl sl@0: // sl@0: { sl@0: sl@0: FOREVER sl@0: { sl@0: TChar c=Peek(); sl@0: if (!c.IsDigit()) sl@0: break; sl@0: else sl@0: c=Get(); sl@0: if (aSig=iEnd) sl@0: return(KErrGeneral); sl@0: TUint64 n(0); sl@0: TBool minus=EFalse; sl@0: if (Peek()=='-') sl@0: { sl@0: Inc(); sl@0: minus=ETrue; sl@0: } sl@0: else if (Peek()=='+') sl@0: Inc(); sl@0: TInt digflg=Peek().IsDigit(); sl@0: while (Peek()=='0') // Skip leading zeros sl@0: Inc(); sl@0: TInt nsig=0; sl@0: TInt nskip=0; sl@0: Scndig(nsig,nskip,n); sl@0: TInt nint=nsig; sl@0: TInt nfract=0; sl@0: if (Peek()==aPoint) sl@0: { sl@0: Inc(); sl@0: if (!digflg) sl@0: digflg=Peek().IsDigit(); sl@0: ScndigAfterPoint(nsig,n); // skip trailing zeros sl@0: nfract=nsig-nint; sl@0: } sl@0: if (!digflg) sl@0: { sl@0: UnGetToMark(start); sl@0: return(KErrGeneral); // Not a number sl@0: } sl@0: TInt nexp=0; sl@0: TInt r; sl@0: if (Peek()=='E' || Peek()=='e') sl@0: { sl@0: TLexMark8 rollback(iNext); sl@0: Inc(); sl@0: r=Val(nexp); sl@0: if (r!=KErrNone) sl@0: { sl@0: if (r==KErrOverflow) sl@0: { sl@0: aVal.SetInfinite(minus); sl@0: return r; sl@0: } sl@0: else sl@0: { sl@0: //it wasn't a number after the 'e', so rollback to the 'e' sl@0: UnGetToMark(rollback); sl@0: } sl@0: } sl@0: } sl@0: sl@0: if (n == 0) sl@0: { sl@0: aVal.SetZero(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: // Clear msb and if it was set then add 2^63 to aVal as a TRealX sl@0: // as TRealX can only be set from a TInt64. sl@0: TUint32 nh = I64HIGH(n); sl@0: n <<= 1; // Clear the msb of n (64 bit number so this is most efficient method). sl@0: n >>= 1; sl@0: aVal = TInt64(n); sl@0: if (nh & 0x80000000u) sl@0: { sl@0: TRealX nhx(1); sl@0: nhx.iExp = (TUint16)(nhx.iExp + 63); sl@0: aVal += nhx; sl@0: } sl@0: if (minus) sl@0: aVal = -aVal; sl@0: nexp += nskip - nfract; sl@0: r=Math::MultPow10X(aVal,nexp); sl@0: return r; sl@0: } sl@0: sl@0: EXPORT_C TInt TLex16::Val(TReal32& aVal) sl@0: // sl@0: // Convert a 32 bit real. sl@0: // sl@0: { sl@0: TRealX x; sl@0: TInt r=Val(x); sl@0: if (r==KErrNone) sl@0: r=x.GetTReal(aVal); sl@0: return r; sl@0: } sl@0: sl@0: EXPORT_C TInt TLex16::Val(TReal32& aVal, TChar aPoint) sl@0: // sl@0: // Convert a 32 bit real. sl@0: // sl@0: { sl@0: TRealX x; sl@0: TInt r=Val(x,aPoint); sl@0: if (r==KErrNone) sl@0: r=x.GetTReal(aVal); sl@0: return r; sl@0: } sl@0: sl@0: EXPORT_C TInt TLex16::Val(TReal64& aVal) sl@0: // sl@0: // Convert a 64 bit real. sl@0: // sl@0: { sl@0: TRealX x; sl@0: TInt r=Val(x); sl@0: if (r==KErrNone) sl@0: r=x.GetTReal(aVal); sl@0: return r; sl@0: } sl@0: sl@0: EXPORT_C TInt TLex16::Val(TReal64& aVal, TChar aPoint) sl@0: // sl@0: // Convert a 64 bit real. sl@0: // sl@0: { sl@0: TRealX x; sl@0: TInt r=Val(x,aPoint); sl@0: if (r==KErrNone) sl@0: r=x.GetTReal(aVal); sl@0: return r; sl@0: } sl@0: sl@0: TInt TLex16::Val(TRealX& aVal) sl@0: // sl@0: // Convert an extended real. Use the locale decimal point. sl@0: // sl@0: { sl@0: TLocale locale; sl@0: return(Val(aVal,locale.DecimalSeparator())); sl@0: } sl@0: sl@0: TInt TLex16::Val(TRealX& aVal, TChar aPoint) sl@0: // sl@0: // Convert a 64 bit real sl@0: // sl@0: { sl@0: sl@0: HBufC8 *temp=HBufC8::New(iEnd-iNext); sl@0: if (temp==NULL) sl@0: return(KErrNoMemory); sl@0: TPtr8 tdes(temp->Des()); sl@0: sl@0: for (const TText* p = (TText*)iNext; p < (TText*)iEnd; p++) sl@0: { sl@0: TChar c = *p; sl@0: if (c == aPoint) sl@0: c = '.'; sl@0: else if (c == '.') sl@0: c = ' '; sl@0: else if (c > 255) sl@0: c = ' '; sl@0: tdes.Append((TUint8)c); sl@0: } sl@0: aPoint = '.'; sl@0: sl@0: TLex8 lex(tdes); sl@0: lex.Mark(); sl@0: TInt r=lex.Val(aVal,aPoint); sl@0: User::Free(temp); sl@0: if (r==KErrNone) sl@0: Inc(lex.TokenLength()); sl@0: return r; sl@0: }