diff options
Diffstat (limited to 'svl/source/numbers/zforfind.cxx')
-rw-r--r-- | svl/source/numbers/zforfind.cxx | 48 |
1 files changed, 23 insertions, 25 deletions
diff --git a/svl/source/numbers/zforfind.cxx b/svl/source/numbers/zforfind.cxx index e56a5cef8502..32b471a5df23 100644 --- a/svl/source/numbers/zforfind.cxx +++ b/svl/source/numbers/zforfind.cxx @@ -18,6 +18,7 @@ */ #include <cstdlib> +#include <dtoa.h> #include <float.h> #include <comphelper/string.hxx> #include <sal/log.hxx> @@ -36,6 +37,8 @@ #include "zforscan.hxx" #include <svl/zformat.hxx> +#include <memory> + #include "zforfind.hxx" #ifndef DBG_UTIL @@ -151,35 +154,30 @@ static void TransformInput( SvNumberFormatter const * pFormatter, OUString& rStr */ double ImpSvNumberInputScan::StringToDouble( const OUString& rStr, bool bForceFraction ) { - double fNum = 0.0; - double fFrac = 0.0; - int nExp = 0; - sal_Int32 nPos = 0; - sal_Int32 nLen = rStr.getLength(); - bool bPreSep = !bForceFraction; - - while (nPos < nLen) + std::unique_ptr<char[]> bufInHeap; + constexpr int bufOnStackSize = 256; + char bufOnStack[bufOnStackSize]; + char* buf = bufOnStack; + const sal_Int32 bufsize = rStr.getLength() + (bForceFraction ? 2 : 1); + if (bufsize > bufOnStackSize) { - if (rStr[nPos] == '.') - { - bPreSep = false; - } - else if (bPreSep) - { - fNum = fNum * 10.0 + static_cast<double>(rStr[nPos] - '0'); - } - else - { - fFrac = fFrac * 10.0 + static_cast<double>(rStr[nPos] - '0'); - --nExp; - } - nPos++; + bufInHeap = std::make_unique<char[]>(bufsize); + buf = bufInHeap.get(); } - if ( fFrac ) + char* p = buf; + if (bForceFraction) + *p++ = '.'; + for (sal_Int32 nPos = 0; nPos < rStr.getLength(); ++nPos) { - return fNum + ::rtl::math::pow10Exp( fFrac, nExp ); + sal_Unicode c = rStr[nPos]; + if (c == '.' || (c >= '0' && c <= '9')) + *p++ = static_cast<char>(c); + else + break; } - return fNum; + *p = '\0'; + + return strtod_nolocale(buf, nullptr); } namespace { |