Kaydet (Commit) 7616e1c1 authored tarafından Eike Rathke's avatar Eike Rathke

LocaleDataWrapper::stringToDouble() w/ decimalSeparatorAlternative, tdf#81671

To be used instead of rtl::math::stringToDouble() if locale
dependent separators are involved.

Change-Id: I54359c981901dc57b3d9312b0bfd2f2a14fccb33
üst dc520c77
......@@ -24,6 +24,7 @@
#include <com/sun/star/i18n/LocaleItem.hpp>
#include <com/sun/star/i18n/reservedWords.hpp>
#include <rtl/ustring.hxx>
#include <rtl/math.h>
#include <i18nlangtag/languagetag.hxx>
#include <unotools/readwritemutexguard.hxx>
#include <unotools/unotoolsdllapi.h>
......@@ -240,6 +241,64 @@ public:
const OUString& getLongDateYearSep() const
{ return getOneLocaleItem( css::i18n::LocaleItem::LONG_DATE_YEAR_SEPARATOR ); }
/** A wrapper around rtl::math::stringToDouble() using the locale dependent
decimal separator, group separator, and if needed decimal separator
alternative.
The decimal separator is tried first, if the conversion does not match
the entire string then the decimal separator alternative is tried if it
occurs in the string and was the reason to stop.
Leading blanks are skipped, trailing blanks are not skipped. The number
is parsed up to the first non-floating point number character, same as
rtl::math::stringToDouble() does. The caller is responsible for proper
error checking and end comparison.
@param rString
The string to parse as floating point number.
@param bUseGroupSep
Whether group separator is used/accepted during parsing.
@param pStatus
Pointer to receive the conversion status as in
rtl::math::stringToDouble().
@param pParseEnd
Pointer to receive the parse end (exclusive) as in
rtl::math::stringToDouble().
@return The floating point number as parsed.
*/
double stringToDouble( const OUString& rString, bool bUseGroupSep,
rtl_math_ConversionStatus* pStatus, sal_Int32* pParseEnd ) const;
/** A wrapper around rtl_math_uStringToDouble() using the locale dependent
decimal separator, group separator, and if needed decimal separator
alternative.
The decimal separator is tried first, if the conversion does not match
the entire string then the decimal separator alternative is tried if it
occurs in the string and was the reason to stop.
Leading blanks are skipped, trailing blanks are not skipped. The number
is parsed up to the first non-floating point number character, same as
rtl_math_uStringToDouble() does. The caller is responsible for proper
error checking and end comparison.
@param pBegin
The string position to start parsing a floating point number.
@param pEnd
The string position to stop parsing, exclusive.
@param bUseGroupSep
Whether group separator is used/accepted during parsing.
@param pStatus
Pointer to receive the conversion status as in
rtl_math_uStringToDouble().
@param pParseEnd
Pointer to receive the parse end (exclusive) as in
rtl_math_uStringToDouble().
@return The floating point number as parsed.
*/
double stringToDouble( const sal_Unicode* pBegin, const sal_Unicode* pEnd, bool bUseGroupSep,
rtl_math_ConversionStatus* pStatus, const sal_Unicode** ppParseEnd ) const;
// currency
const OUString& getCurrSymbol() const;
const OUString& getCurrBankSymbol() const;
......
......@@ -41,6 +41,7 @@
#include <rtl/ustrbuf.hxx>
#include <osl/diagnose.h>
#include <sal/macros.h>
#include <rtl/math.hxx>
static const sal_uInt16 nCurrFormatInvalid = 0xffff;
static const sal_uInt16 nCurrFormatDefault = 0;
......@@ -1747,6 +1748,46 @@ OUString LocaleDataWrapper::getCurr( sal_Int64 nNumber, sal_uInt16 nDecimals,
return aNumber;
}
// --- number parsing -------------------------------------------------
double LocaleDataWrapper::stringToDouble( const OUString& rString, bool bUseGroupSep,
rtl_math_ConversionStatus* pStatus, sal_Int32* pParseEnd ) const
{
const sal_Unicode cGroupSep = (bUseGroupSep ? getNumThousandSep()[0] : 0);
rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
sal_Int32 nParseEnd = 0;
double fValue = rtl::math::stringToDouble( rString, getNumDecimalSep()[0], cGroupSep, &eStatus, &nParseEnd);
bool bTryAlt = (nParseEnd < rString.getLength() && !getNumDecimalSepAlt().isEmpty() &&
rString[nParseEnd] == getNumDecimalSepAlt().toChar());
// Try re-parsing with alternative if that was the reason to stop.
if (bTryAlt)
fValue = rtl::math::stringToDouble( rString, getNumDecimalSepAlt().toChar(), cGroupSep, &eStatus, &nParseEnd);
if (pStatus)
*pStatus = eStatus;
if (pParseEnd)
*pParseEnd = nParseEnd;
return fValue;
}
double LocaleDataWrapper::stringToDouble( const sal_Unicode* pBegin, const sal_Unicode* pEnd, bool bUseGroupSep,
rtl_math_ConversionStatus* pStatus, const sal_Unicode** ppParseEnd ) const
{
const sal_Unicode cGroupSep = (bUseGroupSep ? getNumThousandSep()[0] : 0);
rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
const sal_Unicode* pParseEnd = nullptr;
double fValue = rtl_math_uStringToDouble( pBegin, pEnd, getNumDecimalSep()[0], cGroupSep, &eStatus, &pParseEnd);
bool bTryAlt = (pParseEnd < pEnd && !getNumDecimalSepAlt().isEmpty() &&
*pParseEnd == getNumDecimalSepAlt().toChar());
// Try re-parsing with alternative if that was the reason to stop.
if (bTryAlt)
fValue = rtl_math_uStringToDouble( pBegin, pEnd, getNumDecimalSepAlt().toChar(), cGroupSep, &eStatus, &pParseEnd);
if (pStatus)
*pStatus = eStatus;
if (ppParseEnd)
*ppParseEnd = pParseEnd;
return fValue;
}
// --- mixed ----------------------------------------------------------
LanguageTag LocaleDataWrapper::getLoadedLanguageTag() const
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment