summaryrefslogtreecommitdiff
path: root/basic
diff options
context:
space:
mode:
authorNoel Power <noel.power@novell.com>2010-12-14 20:38:17 +0000
committerNoel Power <noel.power@novell.com>2010-12-14 20:38:17 +0000
commitf8a7ca0e835ba262b5b277827384281fa46ba4b3 (patch)
tree7f8650041e04d0c67d8e8593e4ffe195ac16d8c6 /basic
parent6c831fb7afde5a6e7156bd6863b1391e5f0c7bb6 (diff)
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 )
Diffstat (limited to 'basic')
-rw-r--r--basic/source/sbx/sbxcurr.cxx80
1 files changed, 38 insertions, 42 deletions
diff --git a/basic/source/sbx/sbxcurr.cxx b/basic/source/sbx/sbxcurr.cxx
index 632c2f221035..7775dde239f3 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;
}