os/kernelhwsrv/kernel/eka/euser/maths/um_dtor.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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 	}