summaryrefslogtreecommitdiff
path: root/basic/source/sbx/sbxconv.hxx
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2021-11-24 13:43:05 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2021-12-01 14:03:30 +0100
commitc28a13b9e2bd864e8c574d604bcd6da9e93fb476 (patch)
treec00f9e065e8f62e755bfbf242ff67eb6ef202165 /basic/source/sbx/sbxconv.hxx
parent25a368c30acb54e0819d2b2b890a3fd1530d8a76 (diff)
Unify and simplify floating-point-to-integer conversion
* Round the number once, to avoid doing it three times for a successful conversion. * Round to nearest before convertsToAtMost/convertsToAtLeast, to handle cases like Dim n As Integer n = 32767.4 which should succeed. * Add overflow checks to Hyper (U/Int64) types. Change-Id: Ib10837e6df3cc1e3aba7a657e882bd40e344fd3b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126173 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'basic/source/sbx/sbxconv.hxx')
-rw-r--r--basic/source/sbx/sbxconv.hxx37
1 files changed, 35 insertions, 2 deletions
diff --git a/basic/source/sbx/sbxconv.hxx b/basic/source/sbx/sbxconv.hxx
index dede96942297..a3837d9a3dbf 100644
--- a/basic/source/sbx/sbxconv.hxx
+++ b/basic/source/sbx/sbxconv.hxx
@@ -20,10 +20,45 @@
#pragma once
#include "sbxdec.hxx"
+#include <basic/sberrors.hxx>
#include <basic/sbx.hxx>
+#include <basic/sbxcore.hxx>
+#include <basic/sbxdef.hxx>
+
+#include <o3tl/float_int_conversion.hxx>
+#include <rtl/math.hxx>
+#include <sal/types.h>
class SbxArray;
+template <typename I> inline I DoubleTo(double f, I min, I max)
+{
+ f = rtl::math::round(f);
+ if (!o3tl::convertsToAtMost(f, max))
+ {
+ SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW);
+ return max;
+ }
+ if (!o3tl::convertsToAtLeast(f, min))
+ {
+ SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW);
+ return min;
+ }
+ return f;
+}
+
+inline auto ImpDoubleToChar(double f) { return DoubleTo<sal_Unicode>(f, SbxMINCHAR, SbxMAXCHAR); }
+inline auto ImpDoubleToByte(double f) { return DoubleTo<sal_uInt8>(f, 0, SbxMAXBYTE); }
+inline auto ImpDoubleToUShort(double f) { return DoubleTo<sal_uInt16>(f, 0, SbxMAXUINT); }
+inline auto ImpDoubleToInteger(double f) { return DoubleTo<sal_Int16>(f, SbxMININT, SbxMAXINT); }
+inline auto ImpDoubleToULong(double f) { return DoubleTo<sal_uInt32>(f, 0, SbxMAXULNG); }
+inline auto ImpDoubleToLong(double f) { return DoubleTo<sal_Int32>(f, SbxMINLNG, SbxMAXLNG); }
+inline auto ImpDoubleToSalUInt64(double d) { return DoubleTo<sal_uInt64>(d, 0, SAL_MAX_UINT64); }
+inline auto ImpDoubleToSalInt64(double d)
+{
+ return DoubleTo<sal_Int64>(d, SAL_MIN_INT64, SAL_MAX_INT64);
+}
+
// SBXSCAN.CXX
extern void ImpCvtNum( double nNum, short nPrec, OUString& rRes, bool bCoreString=false );
extern ErrCode ImpScan
@@ -45,8 +80,6 @@ void ImpPutInt64( SbxValues*, sal_Int64 );
sal_uInt64 ImpGetUInt64( const SbxValues* );
void ImpPutUInt64( SbxValues*, sal_uInt64 );
-sal_Int64 ImpDoubleToSalInt64 ( double d );
-sal_uInt64 ImpDoubleToSalUInt64( double d );
double ImpSalUInt64ToDouble( sal_uInt64 n );
// SBXLNG.CXX