summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/unotools/localedatawrapper.hxx59
-rw-r--r--unotools/source/i18n/localedatawrapper.cxx41
2 files changed, 100 insertions, 0 deletions
diff --git a/include/unotools/localedatawrapper.hxx b/include/unotools/localedatawrapper.hxx
index a5f1988f1db4..02b416250adc 100644
--- a/include/unotools/localedatawrapper.hxx
+++ b/include/unotools/localedatawrapper.hxx
@@ -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;
diff --git a/unotools/source/i18n/localedatawrapper.cxx b/unotools/source/i18n/localedatawrapper.cxx
index 52269c291fcc..2f125f6b8e14 100644
--- a/unotools/source/i18n/localedatawrapper.cxx
+++ b/unotools/source/i18n/localedatawrapper.cxx
@@ -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