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