--- a/bintools/rcomp/src/NUMVAL.CPP Wed Jun 16 16:51:40 2010 +0300
+++ b/bintools/rcomp/src/NUMVAL.CPP Wed Jun 23 16:56:47 2010 +0800
@@ -1,473 +1,473 @@
-/*
-* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-
-
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-
-#if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
-#include <sstream>
-#include <iostream>
-using std::cerr;
-using std::endl;
-#else //!__MSVCDOTNET__
-#ifndef __LINUX__
-#include <strstrea.h>
-#endif //!__LINUX__
-#endif //__MSVCDOTNET__
-
-#include "ASTRING.H"
-#include "NUMVAL.H"
-#include "STRUCTST.H"
-#include "Parser.h"
-#include "rcomp.hpp"
-#include "MEM.H"
-#include "ERRORHAN.H"
-#include "RCBINSTR.H"
-
-#if defined(__VC32__)
-#pragma warning( disable : 4702 ) // unreachable code
-#endif
-
-NumericValue::NumericValue( const String & Source, DataType NumericValueType):
- iNumericValueType( NumericValueType),
- iData( NULL),
- iULongValue( 0),
- iSignedValue( 0),
- iDoubleValue( 0.0)
- {
- AllocateSpace();
- ConvertToNumber( Source);
- }
-
-NumericValue::NumericValue( DataType NumericValueType):
- iNumericValueType( NumericValueType),
- iData( NULL),
- iULongValue( 0),
- iSignedValue( 0),
- iDoubleValue( 0.0)
- {
- AllocateSpace();
- }
-
-NumericValue::NumericValue( unsigned long ValueToSet, DataType NumericValueType):
- iNumericValueType( NumericValueType),
- iData( NULL),
- iULongValue( 0),
- iSignedValue( 0),
- iDoubleValue( 0.0)
- {
- AllocateSpace();
- StoreValue( ValueToSet);
- }
-
-NumericValue::~NumericValue()
- {
- delete [] iData;
- }
-
-NumericValue::NumericValue( const NumericValue & Source):
- iNumericValueType( Source.iNumericValueType),
- iData( NULL),
- iULongValue( 0),
- iSignedValue( 0),
- iDoubleValue( 0.0)
- {
- AllocateSpace();
- memcpy( iData, Source.iData, iSize);
- }
-
-void NumericValue::AllocateSpace()
- {
- switch(iNumericValueType)
- {
- case L_BYTE:
- iData = new unsigned char [1];
- iSize = 1;
- break;
- case L_WORD:
- iData = new unsigned char [2];
- iSize = 2;
- break;
- case L_LONG:
- iData = new unsigned char [4];
- iSize = 4;
- break;
- default:
- if ( iNumericValueType != L_DOUBLE)
- assert(0); // Cannot use NumericValue for specified data type.
- }
-
- if ( iNumericValueType != L_DOUBLE && iData == NULL)
- {
- ErrorHandler::OutputErrorLine( "Failed to allocate space for number.");
- exit(1);
- }
- }
-
-const unsigned char * NumericValue::Data() const
- {
- return iData;
- }
-
-unsigned long NumericValue::Size() const
- {
- return iSize;
- }
-
-DataType NumericValue::NumericValueType() const
- {
- return iNumericValueType;
- }
-
-void NumericValue::ConvertToNumber( const String & Source)
- {
- if ( iNumericValueType == L_DOUBLE)
- ConvertToDouble( Source);
- else
- ConvertToNatural( Source);
- }
-
-void NumericValue::ConvertToDouble( const String & Source)
- {
- assert( iNumericValueType == L_DOUBLE);
- assert( Source.Length() > 0);
-
- double d = atof( Source.GetAssertedNonEmptyBuffer());
- if ( d == 0.0 && !( Source == "0.0" || Source == "0") )
- { MOFF; cerr << "atof may have failed for " << Source << endl; MON;}
-
- iDoubleValue = d;
- }
-
-#if defined(__VC32__)
-#pragma warning( disable : 4706 ) // assignment within conditional expression
-#endif
-
-void NumericValue::ConvertToNatural( const String & Source)
- {
- unsigned long LongValue = 0;
-
- assert( sizeof( unsigned long) >= 4); // Assume that LongValue can hold at least 2^32 - 1.
-
- const char * pSourceChar = Source.iRep;
- int bLeadingHyphen = 0;
- int bHexNumber = 0;
-
- if ( pSourceChar[0] == '0' && pSourceChar[1] == 'x')
- {
- bHexNumber = 1;
- pSourceChar++;
- pSourceChar++;
- }
-
- if ( pSourceChar[0] == '-')
- {
- bLeadingHyphen = 1;
- pSourceChar++;
- }
-
- while ( * pSourceChar != '\0')
- {
- unsigned char DigitValue;
-
- if ( bHexNumber)
- {
- assert( isxdigit( * pSourceChar) );
- if ( isdigit( * pSourceChar) )
- DigitValue = (unsigned char)(* pSourceChar - '0');
- else
- DigitValue = (unsigned char)(toupper( * pSourceChar) - 'A' + 10);
- if (LongValue >= 0x10000000)
- {
- String st("Number \"");
- st += Source;
- st += "\" is too big ";
- ErrorHandler::OutputErrorLine(st); //prevents overflow if number is bigger than 2^32 - 1.
- }
- LongValue = LongValue * 16 + DigitValue;
- }
- else
- {
- if ( ! isdigit( * pSourceChar) )
- {
- String s( "Cannot convert \"");
- s += Source;
- s += "\" to a number.";
- ErrorHandler::OutputErrorLine( s);
- exit(1);
- // unreachable code
- }
- DigitValue = (unsigned char)(* pSourceChar - '0');
- if ((LongValue > 429496729) || ((LongValue == 429496729) && (DigitValue > 5)))
- {
- String st("Number \"");
- st += Source;
- st += "\" is too big ";
- ErrorHandler::OutputErrorLine(st); //prevents overflow if number is bigger than 2^32 - 1.
- }
- LongValue = LongValue * 10 + DigitValue;
- }
- pSourceChar++;
- assert( ( pSourceChar - Source.iRep) < 10000); // Safety check!
- }
-
- int inrange=0;
-
- // Check value is within the allowed range for the type taking into account
- // a leading hyphen (minus sign) if there was one.
- switch( iNumericValueType)
- {
- case L_BYTE: // L_BYTE is 8 bits long.
- if ( bLeadingHyphen)
- {
- if ( ! ( inrange = (LongValue <= 128) ) ) // 2 ^ 7
- ErrorHandler::OutputErrorLine( "Number too low for BYTE");
- }
- else
- if ( ! ( inrange = (LongValue <= 0xFF) ) )
- ErrorHandler::OutputErrorLine( "Number too big for BYTE");
- break;
- case L_WORD: // L_WORD is 16-bits long.
- if ( bLeadingHyphen)
- {
- if ( ! ( inrange = (LongValue <= 32768) ) ) // 2^15
- ErrorHandler::OutputErrorLine( "Number too low for WORD");
- }
- else
- if ( ! ( inrange = (LongValue <= 0xFFFF) ) )
- ErrorHandler::OutputErrorLine( "Number too big for WORD");
- break;
- case L_LONG: // L_LONG is 32-bits long
- if ( bLeadingHyphen)
- {
- if ( ! ( inrange = (LongValue <= 0x80000000) ) ) // 2^31
- ErrorHandler::OutputErrorLine( "Number too low for LONG");
- }
- else
- if ( ! ( inrange = (LongValue <= 0xFFFFFFFF ) ) ) // This test is a bit pointless as long cannot be greater than 0xffffffff
- ErrorHandler::OutputErrorLine( "Number too big for LONG");
- break;
- default:
- assert(0); // Other data types cannot be converted to natural numbers.
- }
-
- if(!inrange)
- exit(1);
-
- StoreValue( LongValue);
-
- // If there was a hyphen then make the stored number negative (using two's complement).
- if ( bLeadingHyphen)
- {
- LongValue = (LongValue ^ 0xFFFFFFFFu)+1;
-
- // Output file will be treated as little-endian.
- switch ( iNumericValueType)
- {
- case L_LONG:
- iData[3] = (unsigned char)((LongValue & 0xFF000000) >> 24);
- iData[2] = (unsigned char)((LongValue & 0xFF0000) >> 16);
- case L_WORD:
- iData[1] = (unsigned char)((LongValue & 0xFF00) >> 8);
- case L_BYTE:
- iData[0] = (unsigned char)(LongValue & 0xFF);
- }
- }
- }
-
-#if defined(__VC32__)
-#pragma warning( default : 4706 ) // assignment within conditional expression
-#endif
-
-void NumericValue::StoreValue( unsigned long LongValue)
- {
- iULongValue = LongValue;
-
- if ( LongValue <= 0x80000000)
- iSignedValue = (unsigned long) LongValue;
-
- int inrange = 1;
-
- switch( iNumericValueType)
- {
- case L_BYTE:
- inrange = ( LongValue <= 0xFF);
- break;
- case L_WORD:
- inrange = ( LongValue <= 0xFFFF);
- break;
- case L_LONG:
- inrange = ( LongValue <= 0xFFFFFFFF);
- }
-
- if ( ! inrange)
- {
- ErrorHandler::OutputErrorLine( "Numeric value out of range for specified type");
- exit(1);
- }
-
- // Output file will be treated as little-endian.
- switch ( iNumericValueType)
- {
- case L_LONG:
- iData[3] = (unsigned char)((LongValue & 0xFF000000) >> 24);
- iData[2] = (unsigned char)((LongValue & 0xFF0000) >> 16);
- case L_WORD:
- iData[1] = (unsigned char)((LongValue & 0xFF00) >> 8);
- case L_BYTE:
- iData[0] = (unsigned char)(LongValue & 0xFF);
- }
- }
-
-template<bool> class __CompileTimeAssert {public: __CompileTimeAssert(...) {}};
-template<> class __CompileTimeAssert<false> {};
-struct COMPILE_TIME_ERROR {};
-#define COMPILE_TIME_ASSERT(aCondition) { __CompileTimeAssert<(aCondition)> __temp = __CompileTimeAssert<(aCondition)>(COMPILE_TIME_ERROR()); }
-
-RCBinaryStream & operator<< ( RCBinaryStream & os, NumericValue o)
- {
- switch( o.iNumericValueType)
- {
- case L_BYTE:
- os.Write( o.iData, 1);
- break;
- case L_WORD:
- os.Write( o.iData, 2);
- break;
- case L_LONG:
- os.Write( o.iData, 4);
- break;
- case L_DOUBLE:
- COMPILE_TIME_ASSERT(sizeof(double) == 8);
- os.Write(reinterpret_cast<unsigned char*>(&o.iDoubleValue), 8);
- break;
- default:
- assert(0);
- }
-
- return os;
- }
-
-void NumericValue::StreamOut(ResourceDataStream& aStream) const
- {
- switch (iNumericValueType)
- {
- case L_BYTE:
- aStream.StreamIn(iData, 1);
- break;
- case L_WORD:
- aStream.StreamIn(iData, 2);
- break;
- case L_LONG:
- aStream.StreamIn(iData, 4);
- break;
- case L_DOUBLE:
- COMPILE_TIME_ASSERT(sizeof(double) == 8);
- aStream.StreamIn(reinterpret_cast<const unsigned char*>(&iDoubleValue), 8);
- break;
- default:
- assert(0);
- }
- }
-
-NumericValue & NumericValue::operator= ( unsigned long ValueToSet)
- {
- StoreValue( ValueToSet);
-
- return * this;
- }
-
-unsigned long NumericValue::GetULong() const
- {
- return iULongValue;
- }
-
-long NumericValue::GetLong() const
- {
- assert( iULongValue <= 2147483647); // Check that we are not holding a number that is really positive only.
- return iSignedValue;
- }
-
-bool NumericValue::CheckSigned(unsigned long aValue, DataType aNumericValueType)
- {
- switch (aNumericValueType)
- {
- case L_BYTE:
- if (aValue > 0x7f) return false;
- break;
- case L_WORD:
- if (aValue > 0x7fff) return false;
- break;
- case L_LONG:
- if (aValue > 0x7fffffff) return false;
- break;
- default:
- assert(0);
- }
- return true;
- }
-
-String NumericValue::ltoa( long Source)
- {
- char v[10]; // long can have no more than 10 digits in this implementation.
- char * pv = v;
- long x;
-
- if ( Source < 0)
- x = - Source;
- else
- x = Source;
-
- if ( x == 0)
- * pv++ = '0';
- else
- {
- while( x > 0)
- {
- assert( pv <= (v+9) );
-
- * pv = char(x%10 + '0');
- pv++;
- x /= 10;
- }
- }
-
- // Now reverse digits so they are in the correct order. Put in terminating null and hyphen
- // if necessary.
-
- char r[12];
- char * pr = r;
-
- if ( Source < 0)
- {
- r[0] = '-';
- pr++;
- }
-
- while( pv != v)
- {
- assert( pr < (r+11) );
- * pr++ = * --pv;
- }
-
- * pr = '\0';
-
- return r;
- }
+/*
+* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
+#include <sstream>
+#include <iostream>
+using std::cerr;
+using std::endl;
+#else //!__MSVCDOTNET__
+#ifndef __LINUX__
+#include <strstrea.h>
+#endif //!__LINUX__
+#endif //__MSVCDOTNET__
+
+#include "ASTRING.H"
+#include "NUMVAL.H"
+#include "STRUCTST.H"
+#include "Parser.h"
+#include "rcomp.hpp"
+#include "MEM.H"
+#include "ERRORHAN.H"
+#include "RCBINSTR.H"
+
+#if defined(__VC32__)
+#pragma warning( disable : 4702 ) // unreachable code
+#endif
+
+NumericValue::NumericValue( const String & Source, DataType NumericValueType):
+ iNumericValueType( NumericValueType),
+ iData( NULL),
+ iULongValue( 0),
+ iSignedValue( 0),
+ iDoubleValue( 0.0)
+ {
+ AllocateSpace();
+ ConvertToNumber( Source);
+ }
+
+NumericValue::NumericValue( DataType NumericValueType):
+ iNumericValueType( NumericValueType),
+ iData( NULL),
+ iULongValue( 0),
+ iSignedValue( 0),
+ iDoubleValue( 0.0)
+ {
+ AllocateSpace();
+ }
+
+NumericValue::NumericValue( unsigned long ValueToSet, DataType NumericValueType):
+ iNumericValueType( NumericValueType),
+ iData( NULL),
+ iULongValue( 0),
+ iSignedValue( 0),
+ iDoubleValue( 0.0)
+ {
+ AllocateSpace();
+ StoreValue( ValueToSet);
+ }
+
+NumericValue::~NumericValue()
+ {
+ delete [] iData;
+ }
+
+NumericValue::NumericValue( const NumericValue & Source):
+ iNumericValueType( Source.iNumericValueType),
+ iData( NULL),
+ iULongValue( 0),
+ iSignedValue( 0),
+ iDoubleValue( 0.0)
+ {
+ AllocateSpace();
+ memcpy( iData, Source.iData, iSize);
+ }
+
+void NumericValue::AllocateSpace()
+ {
+ switch(iNumericValueType)
+ {
+ case L_BYTE:
+ iData = new unsigned char [1];
+ iSize = 1;
+ break;
+ case L_WORD:
+ iData = new unsigned char [2];
+ iSize = 2;
+ break;
+ case L_LONG:
+ iData = new unsigned char [4];
+ iSize = 4;
+ break;
+ default:
+ if ( iNumericValueType != L_DOUBLE)
+ assert(0); // Cannot use NumericValue for specified data type.
+ }
+
+ if ( iNumericValueType != L_DOUBLE && iData == NULL)
+ {
+ ErrorHandler::OutputErrorLine( "Error: Failed to allocate space for number.");
+ exit(1);
+ }
+ }
+
+const unsigned char * NumericValue::Data() const
+ {
+ return iData;
+ }
+
+unsigned long NumericValue::Size() const
+ {
+ return iSize;
+ }
+
+DataType NumericValue::NumericValueType() const
+ {
+ return iNumericValueType;
+ }
+
+void NumericValue::ConvertToNumber( const String & Source)
+ {
+ if ( iNumericValueType == L_DOUBLE)
+ ConvertToDouble( Source);
+ else
+ ConvertToNatural( Source);
+ }
+
+void NumericValue::ConvertToDouble( const String & Source)
+ {
+ assert( iNumericValueType == L_DOUBLE);
+ assert( Source.Length() > 0);
+
+ double d = atof( Source.GetAssertedNonEmptyBuffer());
+ if ( d == 0.0 && !( Source == "0.0" || Source == "0") )
+ { MOFF; cerr << "atof may have failed for " << Source << endl; MON;}
+
+ iDoubleValue = d;
+ }
+
+#if defined(__VC32__)
+#pragma warning( disable : 4706 ) // assignment within conditional expression
+#endif
+
+void NumericValue::ConvertToNatural( const String & Source)
+ {
+ unsigned long LongValue = 0;
+
+ assert( sizeof( unsigned long) >= 4); // Assume that LongValue can hold at least 2^32 - 1.
+
+ const char * pSourceChar = Source.iRep;
+ int bLeadingHyphen = 0;
+ int bHexNumber = 0;
+
+ if ( pSourceChar[0] == '0' && pSourceChar[1] == 'x')
+ {
+ bHexNumber = 1;
+ pSourceChar++;
+ pSourceChar++;
+ }
+
+ if ( pSourceChar[0] == '-')
+ {
+ bLeadingHyphen = 1;
+ pSourceChar++;
+ }
+
+ while ( * pSourceChar != '\0')
+ {
+ unsigned char DigitValue;
+
+ if ( bHexNumber)
+ {
+ assert( isxdigit( * pSourceChar) );
+ if ( isdigit( * pSourceChar) )
+ DigitValue = (unsigned char)(* pSourceChar - '0');
+ else
+ DigitValue = (unsigned char)(toupper( * pSourceChar) - 'A' + 10);
+ if (LongValue >= 0x10000000)
+ {
+ String st("Number \"");
+ st += Source;
+ st += "\" is too big ";
+ ErrorHandler::OutputErrorLine(st); //prevents overflow if number is bigger than 2^32 - 1.
+ }
+ LongValue = LongValue * 16 + DigitValue;
+ }
+ else
+ {
+ if ( ! isdigit( * pSourceChar) )
+ {
+ String s( "Error: Cannot convert \"");
+ s += Source;
+ s += "\" to a number.";
+ ErrorHandler::OutputErrorLine( s);
+ exit(1);
+ // unreachable code
+ }
+ DigitValue = (unsigned char)(* pSourceChar - '0');
+ if ((LongValue > 429496729) || ((LongValue == 429496729) && (DigitValue > 5)))
+ {
+ String st("Number \"");
+ st += Source;
+ st += "\" is too big ";
+ ErrorHandler::OutputErrorLine(st); //prevents overflow if number is bigger than 2^32 - 1.
+ }
+ LongValue = LongValue * 10 + DigitValue;
+ }
+ pSourceChar++;
+ assert( ( pSourceChar - Source.iRep) < 10000); // Safety check!
+ }
+
+ int inrange=0;
+
+ // Check value is within the allowed range for the type taking into account
+ // a leading hyphen (minus sign) if there was one.
+ switch( iNumericValueType)
+ {
+ case L_BYTE: // L_BYTE is 8 bits long.
+ if ( bLeadingHyphen)
+ {
+ if ( ! ( inrange = (LongValue <= 128) ) ) // 2 ^ 7
+ ErrorHandler::OutputErrorLine( "Error: Number too low for BYTE");
+ }
+ else
+ if ( ! ( inrange = (LongValue <= 0xFF) ) )
+ ErrorHandler::OutputErrorLine( "Error: Number too big for BYTE");
+ break;
+ case L_WORD: // L_WORD is 16-bits long.
+ if ( bLeadingHyphen)
+ {
+ if ( ! ( inrange = (LongValue <= 32768) ) ) // 2^15
+ ErrorHandler::OutputErrorLine( "Error: Number too low for WORD");
+ }
+ else
+ if ( ! ( inrange = (LongValue <= 0xFFFF) ) )
+ ErrorHandler::OutputErrorLine( "Error: Number too big for WORD");
+ break;
+ case L_LONG: // L_LONG is 32-bits long
+ if ( bLeadingHyphen)
+ {
+ if ( ! ( inrange = (LongValue <= 0x80000000) ) ) // 2^31
+ ErrorHandler::OutputErrorLine( "Error: Number too low for LONG");
+ }
+ else
+ if ( ! ( inrange = (LongValue <= 0xFFFFFFFF ) ) ) // This test is a bit pointless as long cannot be greater than 0xffffffff
+ ErrorHandler::OutputErrorLine( "Error: Number too big for LONG");
+ break;
+ default:
+ assert(0); // Other data types cannot be converted to natural numbers.
+ }
+
+ if(!inrange)
+ exit(1);
+
+ StoreValue( LongValue);
+
+ // If there was a hyphen then make the stored number negative (using two's complement).
+ if ( bLeadingHyphen)
+ {
+ LongValue = (LongValue ^ 0xFFFFFFFFu)+1;
+
+ // Output file will be treated as little-endian.
+ switch ( iNumericValueType)
+ {
+ case L_LONG:
+ iData[3] = (unsigned char)((LongValue & 0xFF000000) >> 24);
+ iData[2] = (unsigned char)((LongValue & 0xFF0000) >> 16);
+ case L_WORD:
+ iData[1] = (unsigned char)((LongValue & 0xFF00) >> 8);
+ case L_BYTE:
+ iData[0] = (unsigned char)(LongValue & 0xFF);
+ }
+ }
+ }
+
+#if defined(__VC32__)
+#pragma warning( default : 4706 ) // assignment within conditional expression
+#endif
+
+void NumericValue::StoreValue( unsigned long LongValue)
+ {
+ iULongValue = LongValue;
+
+ if ( LongValue <= 0x80000000)
+ iSignedValue = (unsigned long) LongValue;
+
+ int inrange = 1;
+
+ switch( iNumericValueType)
+ {
+ case L_BYTE:
+ inrange = ( LongValue <= 0xFF);
+ break;
+ case L_WORD:
+ inrange = ( LongValue <= 0xFFFF);
+ break;
+ case L_LONG:
+ inrange = ( LongValue <= 0xFFFFFFFF);
+ }
+
+ if ( ! inrange)
+ {
+ ErrorHandler::OutputErrorLine( "Error: Numeric value out of range for specified type");
+ exit(1);
+ }
+
+ // Output file will be treated as little-endian.
+ switch ( iNumericValueType)
+ {
+ case L_LONG:
+ iData[3] = (unsigned char)((LongValue & 0xFF000000) >> 24);
+ iData[2] = (unsigned char)((LongValue & 0xFF0000) >> 16);
+ case L_WORD:
+ iData[1] = (unsigned char)((LongValue & 0xFF00) >> 8);
+ case L_BYTE:
+ iData[0] = (unsigned char)(LongValue & 0xFF);
+ }
+ }
+
+template<bool> class __CompileTimeAssert {public: __CompileTimeAssert(...) {}};
+template<> class __CompileTimeAssert<false> {};
+struct COMPILE_TIME_ERROR {};
+#define COMPILE_TIME_ASSERT(aCondition) { __CompileTimeAssert<(aCondition)> __temp = __CompileTimeAssert<(aCondition)>(COMPILE_TIME_ERROR()); }
+
+RCBinaryStream & operator<< ( RCBinaryStream & os, NumericValue o)
+ {
+ switch( o.iNumericValueType)
+ {
+ case L_BYTE:
+ os.Write( o.iData, 1);
+ break;
+ case L_WORD:
+ os.Write( o.iData, 2);
+ break;
+ case L_LONG:
+ os.Write( o.iData, 4);
+ break;
+ case L_DOUBLE:
+ COMPILE_TIME_ASSERT(sizeof(double) == 8);
+ os.Write(reinterpret_cast<unsigned char*>(&o.iDoubleValue), 8);
+ break;
+ default:
+ assert(0);
+ }
+
+ return os;
+ }
+
+void NumericValue::StreamOut(ResourceDataStream& aStream) const
+ {
+ switch (iNumericValueType)
+ {
+ case L_BYTE:
+ aStream.StreamIn(iData, 1);
+ break;
+ case L_WORD:
+ aStream.StreamIn(iData, 2);
+ break;
+ case L_LONG:
+ aStream.StreamIn(iData, 4);
+ break;
+ case L_DOUBLE:
+ COMPILE_TIME_ASSERT(sizeof(double) == 8);
+ aStream.StreamIn(reinterpret_cast<const unsigned char*>(&iDoubleValue), 8);
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+NumericValue & NumericValue::operator= ( unsigned long ValueToSet)
+ {
+ StoreValue( ValueToSet);
+
+ return * this;
+ }
+
+unsigned long NumericValue::GetULong() const
+ {
+ return iULongValue;
+ }
+
+long NumericValue::GetLong() const
+ {
+ assert( iULongValue <= 2147483647); // Check that we are not holding a number that is really positive only.
+ return iSignedValue;
+ }
+
+bool NumericValue::CheckSigned(unsigned long aValue, DataType aNumericValueType)
+ {
+ switch (aNumericValueType)
+ {
+ case L_BYTE:
+ if (aValue > 0x7f) return false;
+ break;
+ case L_WORD:
+ if (aValue > 0x7fff) return false;
+ break;
+ case L_LONG:
+ if (aValue > 0x7fffffff) return false;
+ break;
+ default:
+ assert(0);
+ }
+ return true;
+ }
+
+String NumericValue::ltoa( long Source)
+ {
+ char v[10]; // long can have no more than 10 digits in this implementation.
+ char * pv = v;
+ long x;
+
+ if ( Source < 0)
+ x = - Source;
+ else
+ x = Source;
+
+ if ( x == 0)
+ * pv++ = '0';
+ else
+ {
+ while( x > 0)
+ {
+ assert( pv <= (v+9) );
+
+ * pv = char(x%10 + '0');
+ pv++;
+ x /= 10;
+ }
+ }
+
+ // Now reverse digits so they are in the correct order. Put in terminating null and hyphen
+ // if necessary.
+
+ char r[12];
+ char * pr = r;
+
+ if ( Source < 0)
+ {
+ r[0] = '-';
+ pr++;
+ }
+
+ while( pv != v)
+ {
+ assert( pr < (r+11) );
+ * pr++ = * --pv;
+ }
+
+ * pr = '\0';
+
+ return r;
+ }