kernel/eka/euser/maths/um_dtor.cpp
changeset 9 96e5fb8b040d
equal deleted inserted replaced
-1:000000000000 9:96e5fb8b040d
       
     1 // Copyright (c) 1995-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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32\euser\maths\um_dtor.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "um_std.h"
       
    19 
       
    20 const TInt KMaxScanDigits = 19;	// maximum number of decimal digits guaranteed not to overflow TUint64
       
    21 
       
    22 void TLex8::Scndig(TInt& aSig, TInt& aExp, TUint64& aDl)
       
    23 //
       
    24 // Scans a decimal digit field and accumulates the value to a TUint64 at aDl
       
    25 // Used before decimal point - do not drop trailing zeros.
       
    26 //
       
    27 	{
       
    28 	FOREVER
       
    29 		{
       
    30 		if (iNext>=iEnd)
       
    31 			break;
       
    32 		TChar c=Peek();
       
    33 		if (!c.IsDigit())
       
    34 			break;
       
    35 		else
       
    36 			c=Get();
       
    37 		if (aSig<KMaxScanDigits)
       
    38 			{
       
    39 			aDl *= 10;				// Multiply accumulator by 10
       
    40 			aDl+=((TUint)c)-'0';	// Add current digit
       
    41 			aSig++;
       
    42 			}
       
    43 		else
       
    44 			aExp++;
       
    45 		}														  
       
    46 	}
       
    47 
       
    48 void TLex8::ScndigAfterPoint(TInt& aSig, TUint64& aDl)
       
    49 //
       
    50 // Scans a decimal digit field and accumulates the value to a TUint64 at aDl
       
    51 // Used after decimal point - drops trailing zeros.
       
    52 //
       
    53 // Could be improved with change to header file!!
       
    54 	{
       
    55 	TInt trailing=0;	// no of trailing zeros
       
    56 	TInt leading=0;		// no of leading zeros
       
    57 	TInt n;
       
    58 	TChar c;
       
    59 	
       
    60 	FOREVER
       
    61 		{
       
    62 		if (iNext>=iEnd)
       
    63 			break;
       
    64 		c=Peek();
       
    65 		if (!c.IsDigit())
       
    66 			break;
       
    67 		else
       
    68 			{
       
    69 			c=Get();
       
    70 			if (c=='0')
       
    71 				{
       
    72 				if (aDl!=0)		// possible trailing zeros
       
    73 					trailing++;	
       
    74 				else			// if aDl==0 multiplying by 10 and adding 0 has no effect  
       
    75 					{
       
    76 					leading++;
       
    77 					aSig++;		// leading zeros have significance
       
    78 					}
       
    79 				}	
       
    80 			else if ((aSig<KMaxScanDigits+leading && !trailing) || (trailing && aSig+trailing+1<KMaxScanDigits))
       
    81 				{
       
    82 				// first multiply, taking account of preceeding zeros
       
    83 				for (n=trailing; n>=0; n--)
       
    84 					{
       
    85 					aDl *= 10;			// Multiply accumulator by 10
       
    86 					}
       
    87 				// now add current digit
       
    88 				aDl+=((TUint)c)-'0';
       
    89 				// now update significant digits used
       
    90 				aSig+=trailing+1;
       
    91 				trailing=0;
       
    92 				}
       
    93 			}
       
    94 		}
       
    95 	}	
       
    96 
       
    97 void TLex16::Scndig(TInt& aSig, TInt& aExp, TUint64& aDl)
       
    98 //
       
    99 // Scans a decimal digit field and accumulates the value to a TUint64 at aDl
       
   100 //
       
   101 	{
       
   102 
       
   103 	FOREVER
       
   104 		{
       
   105 		TChar c=Peek();
       
   106 		if (!c.IsDigit())
       
   107 			break;
       
   108 		else
       
   109 			c=Get();
       
   110 		if (aSig<KMaxScanDigits)
       
   111 			{
       
   112 			aDl *= 10;				// Multiply accumulator by 10
       
   113 			aDl+=((TUint)c)-'0';	// Add current digit
       
   114 			aSig++;
       
   115 			}
       
   116 		else
       
   117 			aExp++;
       
   118 		}														  
       
   119 	}
       
   120 
       
   121 EXPORT_C TInt TLex8::Val(TReal32& aVal)
       
   122 //
       
   123 // Convert a 32 bit real.
       
   124 //
       
   125 	{
       
   126 	TRealX x;
       
   127 	TInt r=Val(x);
       
   128 	if (r==KErrNone)
       
   129 		r=x.GetTReal(aVal);
       
   130 	return r;
       
   131 	}
       
   132 
       
   133 EXPORT_C TInt TLex8::Val(TReal32& aVal, TChar aPoint)
       
   134 //
       
   135 // Convert a 32 bit real.
       
   136 //
       
   137 	{
       
   138 	TRealX x;
       
   139 	TInt r=Val(x,aPoint);
       
   140 	if (r==KErrNone)
       
   141 		r=x.GetTReal(aVal);
       
   142 	return r;
       
   143 	}
       
   144 
       
   145 EXPORT_C TInt TLex8::Val(TReal64& aVal)
       
   146 //
       
   147 // Convert a 64 bit real.
       
   148 //
       
   149 	{
       
   150 	TRealX x;
       
   151 	TInt r=Val(x);
       
   152 	if (r==KErrNone)
       
   153 		r=x.GetTReal(aVal);
       
   154 	return r;
       
   155 	}
       
   156 
       
   157 EXPORT_C TInt TLex8::Val(TReal64& aVal, TChar aPoint)
       
   158 //
       
   159 // Convert a 64 bit real.
       
   160 //
       
   161 	{
       
   162 	TRealX x;
       
   163 	TInt r=Val(x,aPoint);
       
   164 	if (r==KErrNone)
       
   165 		r=x.GetTReal(aVal);
       
   166 	return r;
       
   167 	}
       
   168 
       
   169 TInt TLex8::Val(TRealX& aVal)
       
   170 //
       
   171 // Convert an extended real. Use the locale decimal point.
       
   172 //
       
   173 	{
       
   174 	TLocale locale;
       
   175 	return(Val(aVal,locale.DecimalSeparator()));
       
   176 	}
       
   177 
       
   178 TInt TLex8::Val(TRealX& aVal, TChar aPoint)
       
   179 //
       
   180 // Convert an extended real.
       
   181 //
       
   182 	{
       
   183 
       
   184 	TLexMark8 start(iNext);
       
   185 	if (iNext>=iEnd)
       
   186 		return(KErrGeneral);
       
   187 	TUint64 n(0);
       
   188 	TBool minus=EFalse;
       
   189 	if (Peek()=='-')
       
   190 		{
       
   191 		Inc();
       
   192 		minus=ETrue;
       
   193 		}
       
   194 	else if (Peek()=='+')
       
   195 		Inc();
       
   196 	TInt digflg=Peek().IsDigit();
       
   197 	while (Peek()=='0')		// Skip leading zeros
       
   198 		Inc();
       
   199 	TInt nsig=0;
       
   200 	TInt nskip=0;
       
   201 	Scndig(nsig,nskip,n);
       
   202 	TInt nint=nsig;
       
   203 	TInt nfract=0;
       
   204 	if (Peek()==aPoint)
       
   205 		{
       
   206 		Inc();
       
   207 		if (!digflg)
       
   208 			digflg=Peek().IsDigit();
       
   209 		ScndigAfterPoint(nsig,n);	// skip trailing zeros
       
   210 		nfract=nsig-nint;
       
   211 		}
       
   212 	if (!digflg)
       
   213 		{
       
   214 		UnGetToMark(start);
       
   215 		return(KErrGeneral);	// Not a number
       
   216 		}
       
   217 	TInt nexp=0;
       
   218 	TInt r;
       
   219 	if (Peek()=='E' || Peek()=='e')
       
   220 		{
       
   221 		TLexMark8 rollback(iNext);
       
   222 		Inc();
       
   223 		r=Val(nexp);
       
   224 		if (r!=KErrNone)
       
   225 			{
       
   226 			if (r==KErrOverflow)
       
   227 				{
       
   228 				aVal.SetInfinite(minus);
       
   229 				return r;
       
   230 				}
       
   231 			else
       
   232 				{
       
   233 				//it wasn't a number after the 'e', so rollback to the 'e'
       
   234 				UnGetToMark(rollback);
       
   235 				}
       
   236 			}
       
   237 		}
       
   238 
       
   239 	if (n == 0)
       
   240 		{
       
   241 		aVal.SetZero();
       
   242 		return KErrNone;
       
   243 		}
       
   244 
       
   245 	// Clear msb and if it was set then add 2^63 to aVal as a TRealX
       
   246 	// as TRealX can only be set from a TInt64.
       
   247 	TUint32 nh = I64HIGH(n);
       
   248 	n <<= 1;	// Clear the msb of n (64 bit number so this is most efficient method).
       
   249 	n >>= 1;
       
   250 	aVal = TInt64(n);
       
   251 	if (nh & 0x80000000u)
       
   252 		{
       
   253 		TRealX nhx(1);
       
   254 		nhx.iExp = (TUint16)(nhx.iExp + 63);
       
   255 		aVal += nhx;
       
   256 		}
       
   257 	if (minus)
       
   258 		aVal = -aVal;
       
   259 	nexp += nskip - nfract;
       
   260 	r=Math::MultPow10X(aVal,nexp);
       
   261 	return r;
       
   262 	}
       
   263 
       
   264 EXPORT_C TInt TLex16::Val(TReal32& aVal)
       
   265 //
       
   266 // Convert a 32 bit real.
       
   267 //
       
   268 	{
       
   269 	TRealX x;
       
   270 	TInt r=Val(x);
       
   271 	if (r==KErrNone)
       
   272 		r=x.GetTReal(aVal);
       
   273 	return r;
       
   274 	}
       
   275 
       
   276 EXPORT_C TInt TLex16::Val(TReal32& aVal, TChar aPoint)
       
   277 //
       
   278 // Convert a 32 bit real.
       
   279 //
       
   280 	{
       
   281 	TRealX x;
       
   282 	TInt r=Val(x,aPoint);
       
   283 	if (r==KErrNone)
       
   284 		r=x.GetTReal(aVal);
       
   285 	return r;
       
   286 	}
       
   287 
       
   288 EXPORT_C TInt TLex16::Val(TReal64& aVal)
       
   289 //
       
   290 // Convert a 64 bit real.
       
   291 //
       
   292 	{
       
   293 	TRealX x;
       
   294 	TInt r=Val(x);
       
   295 	if (r==KErrNone)
       
   296 		r=x.GetTReal(aVal);
       
   297 	return r;
       
   298 	}
       
   299 
       
   300 EXPORT_C TInt TLex16::Val(TReal64& aVal, TChar aPoint)
       
   301 //
       
   302 // Convert a 64 bit real.
       
   303 //
       
   304 	{
       
   305 	TRealX x;
       
   306 	TInt r=Val(x,aPoint);
       
   307 	if (r==KErrNone)
       
   308 		r=x.GetTReal(aVal);
       
   309 	return r;
       
   310 	}
       
   311 
       
   312 TInt TLex16::Val(TRealX& aVal)
       
   313 //
       
   314 // Convert an extended real. Use the locale decimal point.
       
   315 //
       
   316 	{
       
   317 	TLocale locale;
       
   318 	return(Val(aVal,locale.DecimalSeparator()));
       
   319 	}
       
   320 
       
   321 TInt TLex16::Val(TRealX& aVal, TChar aPoint)
       
   322 //
       
   323 // Convert a 64 bit real
       
   324 //
       
   325 	{
       
   326 	
       
   327 	HBufC8 *temp=HBufC8::New(iEnd-iNext);
       
   328 	if (temp==NULL)
       
   329 		return(KErrNoMemory);
       
   330 	TPtr8 tdes(temp->Des());
       
   331 
       
   332 	for (const TText* p = (TText*)iNext; p < (TText*)iEnd; p++)
       
   333 		{
       
   334 		TChar c = *p;
       
   335 		if (c == aPoint)
       
   336 			c = '.';
       
   337 		else if (c == '.')
       
   338 			c = ' ';
       
   339 		else if (c > 255)
       
   340 			c = ' ';
       
   341 		tdes.Append((TUint8)c);
       
   342 		}
       
   343 	aPoint = '.';
       
   344 
       
   345 	TLex8 lex(tdes);
       
   346 	lex.Mark();
       
   347 	TInt r=lex.Val(aVal,aPoint);
       
   348 	User::Free(temp);
       
   349 	if (r==KErrNone)
       
   350 		Inc(lex.TokenLength());
       
   351 	return r;
       
   352 	}