loplugin:useuniqueptr in LocaleDataWrapper

just use OUStringBuffer here, and consequently avoid re-implementing
such string-buffer handling code

Change-Id: I61e39dada6f46478b9d289f0310bb6846eb9868b
Reviewed-on: https://gerrit.libreoffice.org/62646
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
Noel Grandin
2018-10-29 12:11:23 +02:00
parent 9bd60e28d8
commit d9013f6a39
2 changed files with 168 additions and 253 deletions

View File

@@ -119,7 +119,7 @@ class UNOTOOLS_DLLPUBLIC LocaleDataWrapper
void getDefaultCalendarImpl(); void getDefaultCalendarImpl();
void getSecondaryCalendarImpl(); void getSecondaryCalendarImpl();
sal_Unicode* ImplAddFormatNum( sal_Unicode* pBuf, void ImplAddFormatNum( rtl::OUStringBuffer& rBuf,
sal_Int64 nNumber, sal_uInt16 nDecimals, sal_Int64 nNumber, sal_uInt16 nDecimals,
bool bUseThousandSep, bool bTrailingZeros ) const; bool bUseThousandSep, bool bTrailingZeros ) const;

View File

@@ -1119,7 +1119,7 @@ const css::uno::Sequence< sal_Int32 > LocaleDataWrapper::getDigitGrouping() cons
// The ImplAdd... methods are taken from class International and modified to // The ImplAdd... methods are taken from class International and modified to
// suit the needs. // suit the needs.
static sal_Unicode* ImplAddUNum( sal_Unicode* pBuf, sal_uInt64 nNumber ) static void ImplAddUNum( OUStringBuffer& rBuf, sal_uInt64 nNumber )
{ {
// fill temp buffer with digits // fill temp buffer with digits
sal_Unicode aTempBuf[64]; sal_Unicode aTempBuf[64];
@@ -1136,15 +1136,12 @@ static sal_Unicode* ImplAddUNum( sal_Unicode* pBuf, sal_uInt64 nNumber )
do do
{ {
pTempBuf--; pTempBuf--;
*pBuf = *pTempBuf; rBuf.append(*pTempBuf);
pBuf++;
} }
while ( pTempBuf != aTempBuf ); while ( pTempBuf != aTempBuf );
return pBuf;
} }
static sal_Unicode* ImplAddUNum( sal_Unicode* pBuf, sal_uInt64 nNumber, int nMinLen ) static void ImplAddUNum( OUStringBuffer& rBuf, sal_uInt64 nNumber, int nMinLen )
{ {
// fill temp buffer with digits // fill temp buffer with digits
sal_Unicode aTempBuf[64]; sal_Unicode aTempBuf[64];
@@ -1161,8 +1158,7 @@ static sal_Unicode* ImplAddUNum( sal_Unicode* pBuf, sal_uInt64 nNumber, int nMin
// fill with zeros up to the minimal length // fill with zeros up to the minimal length
while ( nMinLen > 0 ) while ( nMinLen > 0 )
{ {
*pBuf = '0'; rBuf.append('0');
pBuf++;
nMinLen--; nMinLen--;
} }
@@ -1170,25 +1166,22 @@ static sal_Unicode* ImplAddUNum( sal_Unicode* pBuf, sal_uInt64 nNumber, int nMin
do do
{ {
pTempBuf--; pTempBuf--;
*pBuf = *pTempBuf; rBuf.append(*pTempBuf);
pBuf++;
} }
while ( pTempBuf != aTempBuf ); while ( pTempBuf != aTempBuf );
return pBuf;
} }
static sal_Unicode* ImplAddNum( sal_Unicode* pBuf, sal_Int64 nNumber, int nMinLen ) static void ImplAddNum( OUStringBuffer& rBuf, sal_Int64 nNumber, int nMinLen )
{ {
if (nNumber < 0) if (nNumber < 0)
{ {
*pBuf++ = '-'; rBuf.append('-');
nNumber = -nNumber; nNumber = -nNumber;
} }
return ImplAddUNum( pBuf, nNumber, nMinLen); return ImplAddUNum( rBuf, nNumber, nMinLen);
} }
static sal_Unicode* ImplAdd2UNum( sal_Unicode* pBuf, sal_uInt16 nNumber, bool bLeading ) static void ImplAdd2UNum( OUStringBuffer& rBuf, sal_uInt16 nNumber, bool bLeading )
{ {
DBG_ASSERT( nNumber < 100, "ImplAdd2UNum() - Number >= 100" ); DBG_ASSERT( nNumber < 100, "ImplAdd2UNum() - Number >= 100" );
@@ -1196,25 +1189,20 @@ static sal_Unicode* ImplAdd2UNum( sal_Unicode* pBuf, sal_uInt16 nNumber, bool bL
{ {
if ( bLeading ) if ( bLeading )
{ {
*pBuf = '0'; rBuf.append('0');
pBuf++;
} }
*pBuf = nNumber + '0'; rBuf.append(static_cast<char>(nNumber + '0'));
} }
else else
{ {
sal_uInt16 nTemp = nNumber % 10; sal_uInt16 nTemp = nNumber % 10;
nNumber /= 10; nNumber /= 10;
*pBuf = nNumber + '0'; rBuf.append(static_cast<char>(nNumber + '0'));
pBuf++; rBuf.append(static_cast<char>(nTemp + '0'));
*pBuf = nTemp + '0';
} }
pBuf++;
return pBuf;
} }
static sal_Unicode* ImplAdd9UNum( sal_Unicode* pBuf, sal_uInt32 nNumber ) static void ImplAdd9UNum( OUStringBuffer& rBuf, sal_uInt32 nNumber )
{ {
DBG_ASSERT( nNumber < 1000000000, "ImplAdd9UNum() - Number >= 1000000000" ); DBG_ASSERT( nNumber < 1000000000, "ImplAdd9UNum() - Number >= 1000000000" );
@@ -1223,99 +1211,55 @@ static sal_Unicode* ImplAdd9UNum( sal_Unicode* pBuf, sal_uInt32 nNumber )
ostr.width(9); ostr.width(9);
ostr << nNumber; ostr << nNumber;
std::string aStr = ostr.str(); std::string aStr = ostr.str();
for(const char *pAB= aStr.c_str(); *pAB != '\0'; ++pAB, ++pBuf) rBuf.appendAscii(aStr.c_str(), aStr.size());
{
*pBuf = *pAB;
}
return pBuf;
} }
static sal_Unicode* ImplAddString( sal_Unicode* pBuf, const OUString& rStr ) void LocaleDataWrapper::ImplAddFormatNum( OUStringBuffer& rBuf,
{
if ( rStr.getLength() == 1 )
*pBuf++ = rStr[0];
else if (rStr.isEmpty())
;
else
{
memcpy( pBuf, rStr.getStr(), rStr.getLength() * sizeof(sal_Unicode) );
pBuf += rStr.getLength();
}
return pBuf;
}
static sal_Unicode* ImplAddString( sal_Unicode* pBuf, sal_Unicode c )
{
*pBuf = c;
pBuf++;
return pBuf;
}
static sal_Unicode* ImplAddString( sal_Unicode* pBuf, const sal_Unicode* pCopyBuf, sal_Int32 nLen )
{
memcpy( pBuf, pCopyBuf, nLen * sizeof(sal_Unicode) );
return pBuf + nLen;
}
sal_Unicode* LocaleDataWrapper::ImplAddFormatNum( sal_Unicode* pBuf,
sal_Int64 nNumber, sal_uInt16 nDecimals, bool bUseThousandSep, sal_Int64 nNumber, sal_uInt16 nDecimals, bool bUseThousandSep,
bool bTrailingZeros ) const bool bTrailingZeros ) const
{ {
sal_Unicode aNumBuf[64]; OUStringBuffer aNumBuf(64);
sal_Unicode* pNumBuf;
sal_uInt16 nNumLen; sal_uInt16 nNumLen;
sal_uInt16 i = 0;
// negative number // negative number
if ( nNumber < 0 ) if ( nNumber < 0 )
{ {
nNumber *= -1; nNumber *= -1;
*pBuf = '-'; rBuf.append('-');
pBuf++;
} }
// convert number // convert number
pNumBuf = ImplAddUNum( aNumBuf, static_cast<sal_uInt64>(nNumber) ); ImplAddUNum( aNumBuf, static_cast<sal_uInt64>(nNumber) );
nNumLen = static_cast<sal_uInt16>(static_cast<sal_uLong>(pNumBuf-aNumBuf)); nNumLen = static_cast<sal_uInt16>(aNumBuf.getLength());
pNumBuf = aNumBuf;
if ( nNumLen <= nDecimals ) if ( nNumLen <= nDecimals )
{ {
// strip .0 in decimals? // strip .0 in decimals?
if ( !nNumber && !bTrailingZeros ) if ( !nNumber && !bTrailingZeros )
{ {
*pBuf = '0'; rBuf.append('0');
pBuf++;
} }
else else
{ {
// LeadingZero, insert 0 // LeadingZero, insert 0
if ( isNumLeadingZero() ) if ( isNumLeadingZero() )
{ {
*pBuf = '0'; rBuf.append('0');
pBuf++;
} }
// append decimal separator // append decimal separator
pBuf = ImplAddString( pBuf, getNumDecimalSep() ); rBuf.append( getNumDecimalSep() );
// fill with zeros // fill with zeros
sal_uInt16 i = 0;
while ( i < (nDecimals-nNumLen) ) while ( i < (nDecimals-nNumLen) )
{ {
*pBuf = '0'; rBuf.append('0');
pBuf++;
i++; i++;
} }
// append decimals // append decimals
while ( nNumLen ) rBuf.append(aNumBuf);
{
*pBuf = *pNumBuf;
pBuf++;
pNumBuf++;
nNumLen--;
}
} }
} }
else else
@@ -1328,41 +1272,36 @@ sal_Unicode* LocaleDataWrapper::ImplAddFormatNum( sal_Unicode* pBuf,
if (bUseThousandSep) if (bUseThousandSep)
aGroupPos = utl::DigitGroupingIterator::createForwardSequence( aGroupPos = utl::DigitGroupingIterator::createForwardSequence(
nNumLen2, getDigitGrouping()); nNumLen2, getDigitGrouping());
sal_uInt16 i = 0;
for (; i < nNumLen2; ++i ) for (; i < nNumLen2; ++i )
{ {
*pBuf = *pNumBuf; rBuf.append(aNumBuf[i]);
pBuf++;
pNumBuf++;
// add thousand separator? // add thousand separator?
if ( bUseThousandSep && aGroupPos[i] ) if ( bUseThousandSep && aGroupPos[i] )
pBuf = ImplAddString( pBuf, rThoSep ); rBuf.append( rThoSep );
} }
// append decimals // append decimals
if ( nDecimals ) if ( nDecimals )
{ {
pBuf = ImplAddString( pBuf, getNumDecimalSep() ); rBuf.append( getNumDecimalSep() );
bool bNullEnd = true; bool bNullEnd = true;
while ( i < nNumLen ) while ( i < nNumLen )
{ {
if ( *pNumBuf != '0' ) if ( aNumBuf[i] != '0' )
bNullEnd = false; bNullEnd = false;
*pBuf = *pNumBuf; rBuf.append(aNumBuf[i]);
pBuf++;
pNumBuf++;
i++; i++;
} }
// strip .0 in decimals? // strip .0 in decimals?
if ( bNullEnd && !bTrailingZeros ) if ( bNullEnd && !bTrailingZeros )
pBuf -= nDecimals+1; rBuf.setLength( rBuf.getLength() - (nDecimals + 1) );
} }
} }
return pBuf;
} }
// --- simple date and time formatting -------------------------------- // --- simple date and time formatting --------------------------------
@@ -1371,8 +1310,7 @@ OUString LocaleDataWrapper::getDate( const Date& rDate ) const
{ {
::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical ); ::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical );
//!TODO: leading zeros et al //!TODO: leading zeros et al
sal_Unicode aBuf[128]; OUStringBuffer aBuf(128);
sal_Unicode* pBuf = aBuf;
sal_uInt16 nDay = rDate.GetDay(); sal_uInt16 nDay = rDate.GetDay();
sal_uInt16 nMonth = rDate.GetMonth(); sal_uInt16 nMonth = rDate.GetMonth();
sal_Int16 nYear = rDate.GetYear(); sal_Int16 nYear = rDate.GetYear();
@@ -1389,128 +1327,125 @@ OUString LocaleDataWrapper::getDate( const Date& rDate ) const
switch ( getDateOrder() ) switch ( getDateOrder() )
{ {
case DateOrder::DMY : case DateOrder::DMY :
pBuf = ImplAdd2UNum( pBuf, nDay, true /* IsDateDayLeadingZero() */ ); ImplAdd2UNum( aBuf, nDay, true /* IsDateDayLeadingZero() */ );
pBuf = ImplAddString( pBuf, getDateSep() ); aBuf.append( getDateSep() );
pBuf = ImplAdd2UNum( pBuf, nMonth, true /* IsDateMonthLeadingZero() */ ); ImplAdd2UNum( aBuf, nMonth, true /* IsDateMonthLeadingZero() */ );
pBuf = ImplAddString( pBuf, getDateSep() ); aBuf.append( getDateSep() );
pBuf = ImplAddNum( pBuf, nYear, nYearLen ); ImplAddNum( aBuf, nYear, nYearLen );
break; break;
case DateOrder::MDY : case DateOrder::MDY :
pBuf = ImplAdd2UNum( pBuf, nMonth, true /* IsDateMonthLeadingZero() */ ); ImplAdd2UNum( aBuf, nMonth, true /* IsDateMonthLeadingZero() */ );
pBuf = ImplAddString( pBuf, getDateSep() ); aBuf.append( getDateSep() );
pBuf = ImplAdd2UNum( pBuf, nDay, true /* IsDateDayLeadingZero() */ ); ImplAdd2UNum( aBuf, nDay, true /* IsDateDayLeadingZero() */ );
pBuf = ImplAddString( pBuf, getDateSep() ); aBuf.append( getDateSep() );
pBuf = ImplAddNum( pBuf, nYear, nYearLen ); ImplAddNum( aBuf, nYear, nYearLen );
break; break;
default: default:
pBuf = ImplAddNum( pBuf, nYear, nYearLen ); ImplAddNum( aBuf, nYear, nYearLen );
pBuf = ImplAddString( pBuf, getDateSep() ); aBuf.append( getDateSep() );
pBuf = ImplAdd2UNum( pBuf, nMonth, true /* IsDateMonthLeadingZero() */ ); ImplAdd2UNum( aBuf, nMonth, true /* IsDateMonthLeadingZero() */ );
pBuf = ImplAddString( pBuf, getDateSep() ); aBuf.append( getDateSep() );
pBuf = ImplAdd2UNum( pBuf, nDay, true /* IsDateDayLeadingZero() */ ); ImplAdd2UNum( aBuf, nDay, true /* IsDateDayLeadingZero() */ );
} }
return OUString(aBuf, pBuf-aBuf); return aBuf.makeStringAndClear();
} }
OUString LocaleDataWrapper::getTime( const tools::Time& rTime, bool bSec, bool b100Sec ) const OUString LocaleDataWrapper::getTime( const tools::Time& rTime, bool bSec, bool b100Sec ) const
{ {
::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical ); ::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical );
//!TODO: leading zeros et al //!TODO: leading zeros et al
sal_Unicode aBuf[128]; OUStringBuffer aBuf(128);
sal_Unicode* pBuf = aBuf;
sal_uInt16 nHour = rTime.GetHour(); sal_uInt16 nHour = rTime.GetHour();
nHour %= 24; nHour %= 24;
pBuf = ImplAdd2UNum( pBuf, nHour, true /* IsTimeLeadingZero() */ ); ImplAdd2UNum( aBuf, nHour, true /* IsTimeLeadingZero() */ );
pBuf = ImplAddString( pBuf, getTimeSep() ); aBuf.append( getTimeSep() );
pBuf = ImplAdd2UNum( pBuf, rTime.GetMin(), true ); ImplAdd2UNum( aBuf, rTime.GetMin(), true );
if ( bSec ) if ( bSec )
{ {
pBuf = ImplAddString( pBuf, getTimeSep() ); aBuf.append( getTimeSep() );
pBuf = ImplAdd2UNum( pBuf, rTime.GetSec(), true ); ImplAdd2UNum( aBuf, rTime.GetSec(), true );
if ( b100Sec ) if ( b100Sec )
{ {
pBuf = ImplAddString( pBuf, getTime100SecSep() ); aBuf.append( getTime100SecSep() );
pBuf = ImplAdd9UNum( pBuf, rTime.GetNanoSec() ); ImplAdd9UNum( aBuf, rTime.GetNanoSec() );
} }
} }
return OUString(aBuf, pBuf - aBuf); return aBuf.makeStringAndClear();
} }
OUString LocaleDataWrapper::getLongDate( const Date& rDate, CalendarWrapper& rCal, OUString LocaleDataWrapper::getLongDate( const Date& rDate, CalendarWrapper& rCal,
bool bTwoDigitYear ) const bool bTwoDigitYear ) const
{ {
::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical ); ::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical );
sal_Unicode aBuf[20]; OUStringBuffer aBuf(20);
sal_Unicode* pBuf; OUStringBuffer aStr(120); // complete guess
OUString aStr;
sal_Int16 nVal; sal_Int16 nVal;
rCal.setGregorianDateTime( rDate ); rCal.setGregorianDateTime( rDate );
// day of week // day of week
nVal = rCal.getValue( CalendarFieldIndex::DAY_OF_WEEK ); nVal = rCal.getValue( CalendarFieldIndex::DAY_OF_WEEK );
aStr += rCal.getDisplayName( CalendarDisplayIndex::DAY, nVal, 1 ); aStr.append(rCal.getDisplayName( CalendarDisplayIndex::DAY, nVal, 1 ));
aStr += getLongDateDayOfWeekSep(); aStr.append(getLongDateDayOfWeekSep());
// day of month // day of month
nVal = rCal.getValue( CalendarFieldIndex::DAY_OF_MONTH ); nVal = rCal.getValue( CalendarFieldIndex::DAY_OF_MONTH );
pBuf = ImplAdd2UNum( aBuf, nVal, false/*bDayOfMonthWithLeadingZero*/ ); ImplAdd2UNum( aBuf, nVal, false/*bDayOfMonthWithLeadingZero*/ );
OUString aDay(aBuf, pBuf-aBuf); OUString aDay = aBuf.makeStringAndClear();
// month of year // month of year
nVal = rCal.getValue( CalendarFieldIndex::MONTH ); nVal = rCal.getValue( CalendarFieldIndex::MONTH );
OUString aMonth( rCal.getDisplayName( CalendarDisplayIndex::MONTH, nVal, 1 ) ); OUString aMonth( rCal.getDisplayName( CalendarDisplayIndex::MONTH, nVal, 1 ) );
// year // year
nVal = rCal.getValue( CalendarFieldIndex::YEAR ); nVal = rCal.getValue( CalendarFieldIndex::YEAR );
if ( bTwoDigitYear ) if ( bTwoDigitYear )
pBuf = ImplAddUNum( aBuf, nVal % 100, 2 ); ImplAddUNum( aBuf, nVal % 100, 2 );
else else
pBuf = ImplAddUNum( aBuf, nVal ); ImplAddUNum( aBuf, nVal );
OUString aYear(aBuf, pBuf-aBuf); OUString aYear = aBuf.makeStringAndClear();
// concatenate // concatenate
switch ( getLongDateOrder() ) switch ( getLongDateOrder() )
{ {
case DateOrder::DMY : case DateOrder::DMY :
aStr += aDay + getLongDateDaySep() + aMonth + getLongDateMonthSep() + aYear; aStr.append(aDay).append(getLongDateDaySep()).append(aMonth).append(getLongDateMonthSep()).append(aYear);
break; break;
case DateOrder::MDY : case DateOrder::MDY :
aStr += aMonth + getLongDateMonthSep() + aDay + getLongDateDaySep() + aYear; aStr.append(aMonth).append(getLongDateMonthSep()).append(aDay).append(getLongDateDaySep()).append(aYear);
break; break;
default: // YMD default: // YMD
aStr += aYear + getLongDateYearSep() + aMonth + getLongDateMonthSep() + aDay; aStr.append(aYear).append(getLongDateYearSep()).append(aMonth).append(getLongDateMonthSep()).append(aDay);
} }
return aStr; return aStr.makeStringAndClear();
} }
OUString LocaleDataWrapper::getDuration( const tools::Time& rTime, bool bSec, bool b100Sec ) const OUString LocaleDataWrapper::getDuration( const tools::Time& rTime, bool bSec, bool b100Sec ) const
{ {
::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical ); ::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical );
sal_Unicode aBuf[128]; OUStringBuffer aBuf(128);
sal_Unicode* pBuf = aBuf;
if ( rTime < tools::Time( 0 ) ) if ( rTime < tools::Time( 0 ) )
pBuf = ImplAddString( pBuf, ' ' ); aBuf.append(' ' );
if ( (true) /* IsTimeLeadingZero() */ ) if ( (true) /* IsTimeLeadingZero() */ )
pBuf = ImplAddUNum( pBuf, rTime.GetHour(), 2 ); ImplAddUNum( aBuf, rTime.GetHour(), 2 );
else else
pBuf = ImplAddUNum( pBuf, rTime.GetHour() ); ImplAddUNum( aBuf, rTime.GetHour() );
pBuf = ImplAddString( pBuf, getTimeSep() ); aBuf.append( getTimeSep() );
pBuf = ImplAdd2UNum( pBuf, rTime.GetMin(), true ); ImplAdd2UNum( aBuf, rTime.GetMin(), true );
if ( bSec ) if ( bSec )
{ {
pBuf = ImplAddString( pBuf, getTimeSep() ); aBuf.append( getTimeSep() );
pBuf = ImplAdd2UNum( pBuf, rTime.GetSec(), true ); ImplAdd2UNum( aBuf, rTime.GetSec(), true );
if ( b100Sec ) if ( b100Sec )
{ {
pBuf = ImplAddString( pBuf, getTime100SecSep() ); aBuf.append( getTime100SecSep() );
pBuf = ImplAdd9UNum( pBuf, rTime.GetNanoSec() ); ImplAdd9UNum( aBuf, rTime.GetNanoSec() );
} }
} }
return OUString(aBuf, pBuf-aBuf); return aBuf.makeStringAndClear();
} }
// --- simple number formatting --------------------------------------- // --- simple number formatting ---------------------------------------
@@ -1530,38 +1465,26 @@ OUString LocaleDataWrapper::getNum( sal_Int64 nNumber, sal_uInt16 nDecimals,
bool bUseThousandSep, bool bTrailingZeros ) const bool bUseThousandSep, bool bTrailingZeros ) const
{ {
::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical ); ::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical );
sal_Unicode aBuf[128]; // big enough for 64-bit long and crazy grouping
// check if digits and separators will fit into fixed buffer or allocate // check if digits and separators will fit into fixed buffer or allocate
size_t nGuess = ImplGetNumberStringLengthGuess( *this, nDecimals ); size_t nGuess = ImplGetNumberStringLengthGuess( *this, nDecimals );
sal_Unicode* const pBuffer = (nGuess < 118 ? aBuf : OUStringBuffer aBuf(int(nGuess + 16));
new sal_Unicode[nGuess + 16]);
sal_Unicode* pBuf = ImplAddFormatNum( pBuffer, nNumber, nDecimals, ImplAddFormatNum( aBuf, nNumber, nDecimals,
bUseThousandSep, bTrailingZeros ); bUseThousandSep, bTrailingZeros );
OUString aStr(pBuffer, pBuf-pBuffer);
if ( pBuffer != aBuf ) return aBuf.makeStringAndClear();
delete [] pBuffer;
return aStr;
} }
OUString LocaleDataWrapper::getCurr( sal_Int64 nNumber, sal_uInt16 nDecimals, OUString LocaleDataWrapper::getCurr( sal_Int64 nNumber, sal_uInt16 nDecimals,
const OUString& rCurrencySymbol, bool bUseThousandSep ) const const OUString& rCurrencySymbol, bool bUseThousandSep ) const
{ {
::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical ); ::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical );
sal_Unicode aBuf[192];
sal_Unicode aNumBuf[128]; // big enough for 64-bit long and crazy grouping
sal_Unicode cZeroChar = getCurrZeroChar(); sal_Unicode cZeroChar = getCurrZeroChar();
// check if digits and separators will fit into fixed buffer or allocate // check if digits and separators will fit into fixed buffer or allocate
size_t nGuess = ImplGetNumberStringLengthGuess( *this, nDecimals ); size_t nGuess = ImplGetNumberStringLengthGuess( *this, nDecimals );
sal_Unicode* const pNumBuffer = (nGuess < 118 ? aNumBuf : OUStringBuffer aNumBuf(int(nGuess + 16));
new sal_Unicode[nGuess + 16]); OUStringBuffer aBuf(int(rCurrencySymbol.getLength() + nGuess + 20 ));
sal_Unicode* const pBuffer =
((size_t(rCurrencySymbol.getLength()) + nGuess + 20) < SAL_N_ELEMENTS(aBuf) ? aBuf :
new sal_Unicode[ rCurrencySymbol.getLength() + nGuess + 20 ]);
sal_Unicode* pBuf = pBuffer;
bool bNeg; bool bNeg;
if ( nNumber < 0 ) if ( nNumber < 0 )
@@ -1573,40 +1496,39 @@ OUString LocaleDataWrapper::getCurr( sal_Int64 nNumber, sal_uInt16 nDecimals,
bNeg = false; bNeg = false;
// convert number // convert number
sal_Unicode* pEndNumBuf = ImplAddFormatNum( pNumBuffer, nNumber, nDecimals, ImplAddFormatNum( aNumBuf, nNumber, nDecimals,
bUseThousandSep, true ); bUseThousandSep, true );
sal_Int32 nNumLen = static_cast<sal_Int32>(static_cast<sal_uLong>(pEndNumBuf-pNumBuffer)); const sal_Int32 nNumLen = aNumBuf.getLength();
// replace zeros with zero character // replace zeros with zero character
if ( (cZeroChar != '0') && nDecimals /* && IsNumTrailingZeros() */ ) if ( (cZeroChar != '0') && nDecimals /* && IsNumTrailingZeros() */ )
{ {
sal_Unicode* pTempBuf;
sal_uInt16 i; sal_uInt16 i;
bool bZero = true; bool bZero = true;
pTempBuf = pNumBuffer+nNumLen-nDecimals; sal_uInt16 nNumBufIndex = nNumLen-nDecimals;
i = 0; i = 0;
do do
{ {
if ( *pTempBuf != '0' ) if ( aNumBuf[nNumBufIndex] != '0' )
{ {
bZero = false; bZero = false;
break; break;
} }
pTempBuf++; nNumBufIndex++;
i++; i++;
} }
while ( i < nDecimals ); while ( i < nDecimals );
if ( bZero ) if ( bZero )
{ {
pTempBuf = pNumBuffer+nNumLen-nDecimals; nNumBufIndex = nNumLen-nDecimals;
i = 0; i = 0;
do do
{ {
*pTempBuf = cZeroChar; aNumBuf[nNumBufIndex] = cZeroChar;
pTempBuf++; nNumBufIndex++;
i++; i++;
} }
while ( i < nDecimals ); while ( i < nDecimals );
@@ -1618,22 +1540,22 @@ OUString LocaleDataWrapper::getCurr( sal_Int64 nNumber, sal_uInt16 nDecimals,
switch( getCurrPositiveFormat() ) switch( getCurrPositiveFormat() )
{ {
case 0: case 0:
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
break; break;
case 1: case 1:
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
break; break;
case 2: case 2:
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
pBuf = ImplAddString( pBuf, ' ' ); aBuf.append( ' ' );
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
break; break;
case 3: case 3:
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
pBuf = ImplAddString( pBuf, ' ' ); aBuf.append( ' ' );
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
break; break;
} }
} }
@@ -1642,108 +1564,101 @@ OUString LocaleDataWrapper::getCurr( sal_Int64 nNumber, sal_uInt16 nDecimals,
switch( getCurrNegativeFormat() ) switch( getCurrNegativeFormat() )
{ {
case 0: case 0:
pBuf = ImplAddString( pBuf, '(' ); aBuf.append( '(' );
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
pBuf = ImplAddString( pBuf, ')' ); aBuf.append( ')' );
break; break;
case 1: case 1:
pBuf = ImplAddString( pBuf, '-' ); aBuf.append( '-' );
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
break; break;
case 2: case 2:
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
pBuf = ImplAddString( pBuf, '-' ); aBuf.append( '-' );
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
break; break;
case 3: case 3:
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
pBuf = ImplAddString( pBuf, '-' ); aBuf.append( '-' );
break; break;
case 4: case 4:
pBuf = ImplAddString( pBuf, '(' ); aBuf.append( '(' );
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
pBuf = ImplAddString( pBuf, ')' ); aBuf.append( ')' );
break; break;
case 5: case 5:
pBuf = ImplAddString( pBuf, '-' ); aBuf.append( '-' );
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
break; break;
case 6: case 6:
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
pBuf = ImplAddString( pBuf, '-' ); aBuf.append( '-' );
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
break; break;
case 7: case 7:
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
pBuf = ImplAddString( pBuf, '-' ); aBuf.append( '-' );
break; break;
case 8: case 8:
pBuf = ImplAddString( pBuf, '-' ); aBuf.append( '-' );
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
pBuf = ImplAddString( pBuf, ' ' ); aBuf.append( ' ' );
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
break; break;
case 9: case 9:
pBuf = ImplAddString( pBuf, '-' ); aBuf.append( '-' );
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
pBuf = ImplAddString( pBuf, ' ' ); aBuf.append( ' ' );
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
break; break;
case 10: case 10:
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
pBuf = ImplAddString( pBuf, ' ' ); aBuf.append( ' ' );
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
pBuf = ImplAddString( pBuf, '-' ); aBuf.append( '-' );
break; break;
case 11: case 11:
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
pBuf = ImplAddString( pBuf, ' ' ); aBuf.append( ' ' );
pBuf = ImplAddString( pBuf, '-' ); aBuf.append( '-' );
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
break; break;
case 12: case 12:
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
pBuf = ImplAddString( pBuf, ' ' ); aBuf.append( ' ' );
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
pBuf = ImplAddString( pBuf, '-' ); aBuf.append( '-' );
break; break;
case 13: case 13:
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
pBuf = ImplAddString( pBuf, '-' ); aBuf.append( '-' );
pBuf = ImplAddString( pBuf, ' ' ); aBuf.append( ' ' );
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
break; break;
case 14: case 14:
pBuf = ImplAddString( pBuf, '(' ); aBuf.append( '(' );
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
pBuf = ImplAddString( pBuf, ' ' ); aBuf.append( ' ' );
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
pBuf = ImplAddString( pBuf, ')' ); aBuf.append( ')' );
break; break;
case 15: case 15:
pBuf = ImplAddString( pBuf, '(' ); aBuf.append( '(' );
pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); aBuf.append( aNumBuf );
pBuf = ImplAddString( pBuf, ' ' ); aBuf.append( ' ' );
pBuf = ImplAddString( pBuf, rCurrencySymbol ); aBuf.append( rCurrencySymbol );
pBuf = ImplAddString( pBuf, ')' ); aBuf.append( ')' );
break; break;
} }
} }
OUString aNumber(pBuffer, pBuf-pBuffer); return aBuf.makeStringAndClear();
if ( pBuffer != aBuf )
delete [] pBuffer;
if ( pNumBuffer != aNumBuf )
delete [] pNumBuffer;
return aNumber;
} }
// --- number parsing ------------------------------------------------- // --- number parsing -------------------------------------------------