[Libreoffice-commits] .: Branch 'feature/currency-64bit' - 2 commits - basic/source
Noel Power
noelp at kemper.freedesktop.org
Tue Dec 14 13:50:33 PST 2010
basic/source/classes/sbunoobj.cxx | 4 -
basic/source/sbx/sbxcurr.cxx | 87 +++++++++++++++++++-------------------
basic/source/sbx/sbxvalue.cxx | 38 +++++++---------
3 files changed, 62 insertions(+), 67 deletions(-)
New commits:
commit 493bea7486f5239b2c35a51369f23f7ef815226d
Author: Noel Power <noel.power at novell.com>
Date: Tue Dec 14 20:38:17 2010 +0000
Changes to ImpStringToCurrency
Make ImpStringToCurrency be less of a home grown parser, use existing OUString -> number functionality ( and ws treatment ) Also raise an error now if illegal chars are found in the middle of the string ( including spaces )
diff --git a/basic/source/sbx/sbxcurr.cxx b/basic/source/sbx/sbxcurr.cxx
index 1de0ec4..9278ada 100644
--- a/basic/source/sbx/sbxcurr.cxx
+++ b/basic/source/sbx/sbxcurr.cxx
@@ -118,24 +118,18 @@ static rtl::OUString ImpCurrencyToString( const sal_Int64 &rVal )
static sal_Int64 ImpStringToCurrency( const rtl::OUString &rStr )
{
-// TODO consider various possible errors: overflow, end-of-string check for leftovers from malformed string
- sal_Int32 nFractDigit = 4;
- sal_Int64 nResult = 0;
- sal_Bool bNeg = sal_False;
- const sal_Unicode* p = rStr.getStr();
+ sal_Int32 nFractDigit = 4;
SvtSysLocale aSysLocale;
+ sal_Unicode cDeciPnt = sal_Unicode('.');
+ sal_Unicode c1000Sep = sal_Unicode(',');
+
#if MAYBEFUTURE
const LocaleDataWrapper& rData = aSysLocale.GetLocaleData();
sal_Unicode cLocaleDeciPnt = rData.getNumDecimalSep().GetBuffer()[0];
sal_Unicode cLocale1000Sep = rData.getNumThousandSep().GetBuffer()[0];
-#endif
- sal_Unicode cSpaceSep = sal_Unicode(' ');
- sal_Unicode cDeciPnt = sal_Unicode('.');
- sal_Unicode c1000Sep = sal_Unicode(',');
-#if MAYBEFUTURE
// score each set of separators (Locale and Basic) on total number of matches
// if one set has more matches use that set
// if tied use the set with the only or rightmost decimal separator match
@@ -171,51 +165,53 @@ static sal_Int64 ImpStringToCurrency( const rtl::OUString &rStr )
}
#endif
- // p == original param value: re-starting at top of string
- while( *p == cSpaceSep ) p++; // skip leading spaces
- if( *p == sal_Unicode('-') )
- {
- p++;
- bNeg = sal_True;
- }
- else if ( *p == sal_Unicode('+') )
- p++;
+ // lets use the existing string number conversions
+ // there is a performance impact here ( multiple string copies )
+ // but better I think than a home brewed string parser, if we need a parser
+ // we should share some existing ( possibly from calc is there a currency
+ // conversion there ? #TODO check )
+
+ rtl::OUString sTmp( rStr.trim() );
+ const sal_Unicode* p = sTmp.getStr();
- while( *p == cSpaceSep ) p++; // skip space between sign and number
+ // normalise string number by removeing thousands & decimal point seperators
+ rtl::OUStringBuffer sNormalisedNumString( sTmp.getLength() + nFractDigit );
- // always accept space as thousand separator (is never decimal pt; maybe stray)
- // exits on non-numeric (incl. null terminator)
- while( ( *p >= '0' && *p <= '9' ) || *p == c1000Sep || *p == cSpaceSep )
+ if ( *p == '-' || *p == '+' )
+ sNormalisedNumString.append( *p );
+
+ while ( ( *p >= '0' && *p <= '9' ) )
{
- if ( *p >= '0' && *p <= '9' )
- nResult = 10*nResult + (sal_Int64)*p - (sal_Int64)'0';
- p++;
- // could be overflow here ... new result < last result (results always > 0)
+ sNormalisedNumString.append( *p++ );
+ // #TODO in vba mode set runtime error when a space ( or other )
+ // illegal character is found
+ if( *p == c1000Sep )
+ p++;
}
- if( *p == cDeciPnt ) {
+ if( *p == cDeciPnt )
+ {
p++;
- while( (nFractDigit && *p >= '0' && *p <= '9') || *p == cSpaceSep )
+ while( nFractDigit && *p >= '0' && *p <= '9' )
{
- nResult = 10*nResult + (sal_Int64)*p - (sal_Int64)'0';
+ sNormalisedNumString.append( *p++ );
nFractDigit--;
- p++;
- // could be overflow here ...
}
- while( *p == cSpaceSep ) p++; // skip mid-number/trailing spaces
- if( *p >= '5' && *p <= '9' ) nResult ++; // round 5-9 up = round to nearest
}
- while( *p == cSpaceSep ) p++; // skip mid-number/trailing spaces
- // error cases of junky string skip thru to end up here
- // warning cases of extra num ignored end up here too
+ // can we raise error here ? ( previous behaviour was more forgiving )
+ // so... not sure that could bread existing code, lets see if anyone
+ // complains.
- // make sure all of CURRENCY_FACTOR is applied
- while( nFractDigit ) {
- nResult *= 10;
+ if ( p != sTmp.getStr() + sTmp.getLength() )
+ SbxBase::SetError( SbxERR_CONVERSION );
+ while( nFractDigit )
+ {
+ sNormalisedNumString.append( '0' );
nFractDigit--;
}
- if( bNeg ) return -nResult;
- return nResult;
+
+ sal_Int64 result = sNormalisedNumString.makeStringAndClear().toInt64();
+ return result;
}
commit 30c79efc5903edc5bc8994f518c206a608ef3a14
Author: Noel Power <noel.power at novell.com>
Date: Tue Dec 14 18:23:05 2010 +0000
redo stream operators & misc changes to prepare to integrate into master
diff --git a/basic/source/classes/sbunoobj.cxx b/basic/source/classes/sbunoobj.cxx
index bab1cd6..c979455 100644
--- a/basic/source/classes/sbunoobj.cxx
+++ b/basic/source/classes/sbunoobj.cxx
@@ -1149,10 +1149,6 @@ Any sbxToUnoValueImpl( SbxVariable* pVar, bool bBlockConversionToSmallestType =
aType = ::getCppuType( (sal_Int16*)0 );
else if( d >= -SbxMAXLNG && d <= SbxMAXLNG )
aType = ::getCppuType( (sal_Int32*)0 );
-#if MAYBEFUTURE
- else
- aType = ::getCppuType( (sal_Int64*)0 );
-#endif
}
break;
}
diff --git a/basic/source/sbx/sbxcurr.cxx b/basic/source/sbx/sbxcurr.cxx
index f40e0b0..1de0ec4 100644
--- a/basic/source/sbx/sbxcurr.cxx
+++ b/basic/source/sbx/sbxcurr.cxx
@@ -43,8 +43,9 @@ static rtl::OUString ImpCurrencyToString( const sal_Int64 &rVal )
sal_Int64 absVal = isNeg ? -rVal : rVal;
SvtSysLocale aSysLocale;
- sal_Unicode cDecimalSep = '.', cThousandSep = ',';
+ sal_Unicode cDecimalSep = '.';
#if MAYBEFUTURE
+ sal_Unicode cThousandSep = ',';
const LocaleDataWrapper& rData = aSysLocale.GetLocaleData();
cDecimalSep = rData.getNumDecimalSep().GetBuffer()[0];
cThousandSep = rData.getNumThousandSep().GetBuffer()[0];
@@ -64,11 +65,13 @@ static rtl::OUString ImpCurrencyToString( const sal_Int64 &rVal )
if ( !bLessThanOne )
{
nCapacity = initialLen + 1;
+#if MAYBEFUTURE
if ( initialLen > 5 )
{
sal_Int32 nThouSeperators = ( initialLen - 5 ) / 3;
nCapacity += nThouSeperators;
}
+#endif
}
if ( isNeg )
@@ -85,8 +88,10 @@ static rtl::OUString ImpCurrencyToString( const sal_Int64 &rVal )
{
if ( nDigitCount == 4 )
aBuf.setCharAt( nInsertIndex--, cDecimalSep );
+#if MAYBEFUTURE
if ( nDigitCount > 4 && ! ( ( nDigitCount - 4 ) % 3) )
aBuf.setCharAt( nInsertIndex--, cThousandSep );
+#endif
if ( nDigitCount < initialLen )
aBuf.setCharAt( nInsertIndex--, aAbsStr[ charCpyIndex-- ] );
else
diff --git a/basic/source/sbx/sbxvalue.cxx b/basic/source/sbx/sbxvalue.cxx
index ff30acd..690df56 100644
--- a/basic/source/sbx/sbxvalue.cxx
+++ b/basic/source/sbx/sbxvalue.cxx
@@ -1502,6 +1502,8 @@ BOOL SbxValue::Compare( SbxOperator eOp, const SbxValue& rOp ) const
BOOL SbxValue::LoadData( SvStream& r, USHORT )
{
+ // #TODO see if these types are really dumped to any stream
+ // more than likely this is functionality used in the binfilter alone
SbxValue::Clear();
UINT16 nType;
r >> nType;
@@ -1543,21 +1545,20 @@ BOOL SbxValue::LoadData( SvStream& r, USHORT )
break;
}
case SbxSALUINT64:
- {
-// TODO fix write for whole 64 bits was Hi then Lo
- sal_uInt32 tmpHi, tmpLo;
- r >> tmpHi >> tmpLo;
- aData.uInt64 = ((sal_Int64)tmpHi << 32) || (sal_Int64)tmpLo;
- break;
- }
case SbxSALINT64:
+ // Rather ugly use of the union here because we only
+ // have a SvStream& SvStream::operator>>(sal_uInt64&) available to us
+ // There is no SvStream::operator>>(sal_Int64&) due to conflict with
+ // SvStream::operator>>(long&) ( at least on 64 bit linux )
+ r >> aData.uInt64;
+ break;
case SbxCURRENCY:
{
-// TODO fix write for whole 64 bits was Hi then Lo
- sal_Int32 tmpHi;
- sal_uInt32 tmpLo;
+ sal_uInt32 tmpHi = 0;
+ sal_uInt32 tmpLo = 0;
r >> tmpHi >> tmpLo;
- aData.nInt64 = ((sal_Int64)tmpHi << 32) || (sal_Int64)tmpLo;
+ aData.nInt64 = ((sal_Int64)tmpHi << 32);
+ aData.nInt64 |= (sal_Int64)tmpLo;
break;
}
case SbxSTRING:
@@ -1667,18 +1668,15 @@ BOOL SbxValue::StoreData( SvStream& r ) const
r.WriteByteString( GetCoreString(), RTL_TEXTENCODING_ASCII_US );
break;
case SbxSALUINT64:
- {
-// TODO check output from this
- sal_uInt32 tmpHi = (aData.uInt64 >> 32);
- r << tmpHi << (sal_uInt32)(aData.uInt64);
- break;
- }
case SbxSALINT64:
+ // see comment in SbxValue::StoreData
+ r << aData.uInt64;
+ break;
case SbxCURRENCY:
{
-// TODO check output from this
- sal_Int32 tmpHi = (aData.nInt64 >> 32);
- r << tmpHi << (sal_Int32)(aData.nInt64);
+ sal_Int32 tmpHi = ( (aData.nInt64 >> 32) & 0xFFFFFFFF );
+ sal_Int32 tmpLo = ( sal_Int32 )aData.nInt64;
+ r << tmpHi << tmpLo;
break;
}
case SbxSTRING:
More information about the Libreoffice-commits
mailing list