basic/Library_sb.mk | 7 basic/source/sbx/sbxbool.cxx | 199 ++++----- basic/source/sbx/sbxbyte.cxx | 309 --------------- basic/source/sbx/sbxchar.cxx | 295 -------------- basic/source/sbx/sbxconv.hxx | 163 ++++---- basic/source/sbx/sbxcurr.cxx | 122 ++---- basic/source/sbx/sbxdate.cxx | 278 +++++-------- basic/source/sbx/sbxdbl.cxx | 265 ------------- basic/source/sbx/sbxdec.cxx | 296 ++++++-------- basic/source/sbx/sbxdec.hxx | 32 + basic/source/sbx/sbxint.cxx | 868 ++++++++----------------------------------- basic/source/sbx/sbxlng.cxx | 285 -------------- basic/source/sbx/sbxsng.cxx | 279 ------------- basic/source/sbx/sbxuint.cxx | 281 ------------- basic/source/sbx/sbxulng.cxx | 266 ------------- 15 files changed, 661 insertions(+), 3284 deletions(-)
New commits: commit 2143c0a6949ee80c34ec6a8e2028fea2930dd947 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Tue Jun 3 18:09:30 2025 +0500 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Sat Jun 7 12:30:17 2025 +0200 Simplify getter/setter implementations For numeric types, they are made unified templates. In many cases, gotos were dropped, and the code was streamlined. Hopefully, this would make it at least a bit manageable. Change-Id: I63154d61fa6629d1431157ac382ec758f4f50074 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186234 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> diff --git a/basic/Library_sb.mk b/basic/Library_sb.mk index dae083a34864..aa1de14b01f8 100644 --- a/basic/Library_sb.mk +++ b/basic/Library_sb.mk @@ -113,25 +113,18 @@ $(eval $(call gb_Library_add_exception_objects,sb,\ basic/source/runtime/runtime \ basic/source/sbx/sbxarray \ basic/source/sbx/sbxbool \ - basic/source/sbx/sbxbyte \ - basic/source/sbx/sbxchar \ basic/source/sbx/sbxcoll \ basic/source/sbx/sbxcurr \ basic/source/sbx/sbxbase \ basic/source/sbx/sbxdate \ - basic/source/sbx/sbxdbl \ basic/source/sbx/sbxdec \ basic/source/sbx/sbxexec \ basic/source/sbx/sbxform \ basic/source/sbx/sbxint \ - basic/source/sbx/sbxlng \ basic/source/sbx/sbxobj \ basic/source/sbx/sbxres \ basic/source/sbx/sbxscan \ - basic/source/sbx/sbxsng \ basic/source/sbx/sbxstr \ - basic/source/sbx/sbxuint \ - basic/source/sbx/sbxulng \ basic/source/sbx/sbxvalue \ basic/source/sbx/sbxvar \ )) diff --git a/basic/source/sbx/sbxbool.cxx b/basic/source/sbx/sbxbool.cxx index c6d9c2fbd166..6cdcb9ed464a 100644 --- a/basic/source/sbx/sbxbool.cxx +++ b/basic/source/sbx/sbxbool.cxx @@ -24,116 +24,100 @@ enum SbxBOOL ImpGetBool( const SbxValues* p ) { - enum SbxBOOL nRes; + auto SbxBoolFrom = [](auto val) { return val != 0 ? SbxTRUE : SbxFALSE; }; switch( +p->eType ) { - case SbxNULL: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); - [[fallthrough]]; case SbxEMPTY: - nRes = SbxFALSE; break; + return SbxFALSE; case SbxCHAR: - nRes = p->nChar ? SbxTRUE : SbxFALSE; break; + return SbxBoolFrom(p->nChar); + case SbxBYREF | SbxCHAR: + return SbxBoolFrom(*p->pChar); case SbxBYTE: - nRes = p->nByte ? SbxTRUE : SbxFALSE; break; + return SbxBoolFrom(p->nByte); + case SbxBYREF | SbxBYTE: + return SbxBoolFrom(*p->pByte); case SbxINTEGER: case SbxBOOL: - nRes = p->nInteger ? SbxTRUE : SbxFALSE; break; + return SbxBoolFrom(p->nInteger); + case SbxBYREF | SbxINTEGER: + case SbxBYREF | SbxBOOL: + return SbxBoolFrom(*p->pInteger); case SbxERROR: case SbxUSHORT: - nRes = p->nUShort ? SbxTRUE : SbxFALSE; break; + return SbxBoolFrom(p->nUShort); + case SbxBYREF | SbxERROR: + case SbxBYREF | SbxUSHORT: + return SbxBoolFrom(*p->pUShort); case SbxLONG: - nRes = p->nLong ? SbxTRUE : SbxFALSE; break; + return SbxBoolFrom(p->nLong); + case SbxBYREF | SbxLONG: + return SbxBoolFrom(*p->pLong); case SbxULONG: - nRes = p->nULong ? SbxTRUE : SbxFALSE; break; + return SbxBoolFrom(p->nULong); + case SbxBYREF | SbxULONG: + return SbxBoolFrom(*p->pULong); case SbxSINGLE: - nRes = p->nSingle ? SbxTRUE : SbxFALSE; break; + return SbxBoolFrom(p->nSingle); + case SbxBYREF | SbxSINGLE: + return SbxBoolFrom(*p->pSingle); case SbxDATE: case SbxDOUBLE: - nRes = p->nDouble ? SbxTRUE : SbxFALSE; break; + return SbxBoolFrom(p->nDouble); + case SbxBYREF | SbxDATE: + case SbxBYREF | SbxDOUBLE: + return SbxBoolFrom(*p->pDouble); case SbxDECIMAL: case SbxBYREF | SbxDECIMAL: - { - double dVal = 0.0; if( p->pDecimal ) - p->pDecimal->getDouble( dVal ); - nRes = dVal ? SbxTRUE : SbxFALSE; - } - break; + return SbxBoolFrom(p->pDecimal->getWithOverflow<double>()); + return SbxFALSE; case SbxSALINT64: case SbxCURRENCY: - nRes = p->nInt64 ? SbxTRUE : SbxFALSE; break; + return SbxBoolFrom(p->nInt64); + case SbxBYREF | SbxSALINT64: + case SbxBYREF | SbxCURRENCY: + return SbxBoolFrom(*p->pnInt64); case SbxSALUINT64: - nRes = p->uInt64 ? SbxTRUE : SbxFALSE; break; + return SbxBoolFrom(p->uInt64); + case SbxBYREF | SbxSALUINT64: + return SbxBoolFrom(*p->puInt64); + case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - nRes = SbxFALSE; if ( p->pOUString ) { if( p->pOUString->equalsIgnoreAsciiCase( GetSbxRes( StringId::True ) ) ) - nRes = SbxTRUE; - else if( !p->pOUString->equalsIgnoreAsciiCase( GetSbxRes( StringId::False ) ) ) + return SbxTRUE; + if( p->pOUString->equalsIgnoreAsciiCase( GetSbxRes( StringId::False ) ) ) + return SbxFALSE; + + // it can be convertible to a number + double n; + SbxDataType t; + sal_Int32 nLen = 0; + if( ImpScan( *p->pOUString, n, t, &nLen ) == ERRCODE_NONE ) { - // it can be convertible to a number - bool bError = true; - double n; - SbxDataType t; - sal_Int32 nLen = 0; - if( ImpScan( *p->pOUString, n, t, &nLen ) == ERRCODE_NONE ) + if( nLen == p->pOUString->getLength() ) { - if( nLen == p->pOUString->getLength() ) - { - bError = false; - if( n != 0.0 ) - nRes = SbxTRUE; - } + return SbxBoolFrom(n); } - if( bError ) - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); } + SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); } - break; + return SbxFALSE; + case SbxOBJECT: - { - SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) - nRes = pVal->GetBool() ? SbxTRUE : SbxFALSE; - else - { - SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = SbxFALSE; - } - break; - } + if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj)) + return SbxBoolFrom(pVal->GetBool()); + SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); + return SbxFALSE; - case SbxBYREF | SbxCHAR: - nRes = *p->pChar ? SbxTRUE : SbxFALSE; break; - case SbxBYREF | SbxBYTE: - nRes = *p->pByte ? SbxTRUE : SbxFALSE; break; - case SbxBYREF | SbxINTEGER: - case SbxBYREF | SbxBOOL: - nRes = *p->pInteger ? SbxTRUE : SbxFALSE; break; - case SbxBYREF | SbxLONG: - nRes = *p->pLong ? SbxTRUE : SbxFALSE; break; - case SbxBYREF | SbxULONG: - nRes = *p->pULong ? SbxTRUE : SbxFALSE; break; - case SbxBYREF | SbxERROR: - case SbxBYREF | SbxUSHORT: - nRes = *p->pUShort ? SbxTRUE : SbxFALSE; break; - case SbxBYREF | SbxSINGLE: - nRes = ( *p->pSingle != 0 ) ? SbxTRUE : SbxFALSE; break; - case SbxBYREF | SbxDATE: - case SbxBYREF | SbxDOUBLE: - nRes = ( *p->pDouble != 0 ) ? SbxTRUE : SbxFALSE; break; - case SbxBYREF | SbxCURRENCY: - case SbxBYREF | SbxSALINT64: - nRes = ( *p->pnInt64 ) ? SbxTRUE : SbxFALSE; break; - case SbxBYREF | SbxSALUINT64: - nRes = ( *p->puInt64 ) ? SbxTRUE : SbxFALSE; break; default: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = SbxFALSE; + SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); + return SbxFALSE; } - return nRes; } void ImpPutBool( SbxValues* p, sal_Int16 n ) @@ -144,28 +128,53 @@ void ImpPutBool( SbxValues* p, sal_Int16 n ) { case SbxCHAR: p->nChar = static_cast<sal_Unicode>(n); break; - case SbxUINT: + case SbxBYREF | SbxCHAR: + *p->pChar = static_cast<sal_Unicode>(n); break; + case SbxBYTE: p->nByte = static_cast<sal_uInt8>(n); break; + case SbxBYREF | SbxBYTE: + *p->pByte = static_cast<sal_uInt8>(n); break; case SbxINTEGER: case SbxBOOL: p->nInteger = n; break; + case SbxBYREF | SbxINTEGER: + case SbxBYREF | SbxBOOL: + *p->pInteger = n; break; + case SbxERROR: + case SbxUSHORT: + p->nUShort = static_cast<sal_uInt16>(n); break; + case SbxBYREF | SbxERROR: + case SbxBYREF | SbxUSHORT: + *p->pUShort = static_cast<sal_uInt16>(n); break; case SbxLONG: p->nLong = n; break; + case SbxBYREF | SbxLONG: + *p->pLong = n; break; case SbxULONG: p->nULong = static_cast<sal_uInt32>(n); break; - case SbxERROR: - case SbxUSHORT: - p->nUShort = static_cast<sal_uInt16>(n); break; + case SbxBYREF | SbxULONG: + *p->pULong = static_cast<sal_uInt32>(n); break; case SbxSINGLE: p->nSingle = n; break; + case SbxBYREF | SbxSINGLE: + *p->pSingle = n; break; case SbxDATE: case SbxDOUBLE: p->nDouble = n; break; + case SbxBYREF | SbxDATE: + case SbxBYREF | SbxDOUBLE: + *p->pDouble = n; break; case SbxCURRENCY: case SbxSALINT64: - p->nInt64 = static_cast<sal_Int64>(n); break; + p->nInt64 = n; break; + case SbxBYREF | SbxCURRENCY: + case SbxBYREF | SbxSALINT64: + *p->pnInt64 = n; break; case SbxSALUINT64: p->uInt64 = static_cast<sal_uInt64>(n); break; + case SbxBYREF | SbxSALUINT64: + *p->puInt64 = static_cast<sal_uInt64>(n); break; + case SbxDECIMAL: case SbxBYREF | SbxDECIMAL: ImpCreateDecimal( p )->setInt( n ); @@ -181,38 +190,12 @@ void ImpPutBool( SbxValues* p, sal_Int16 n ) break; case SbxOBJECT: - { - SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) + if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj)) pVal->PutBool( n != 0 ); else SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); break; - } - case SbxBYREF | SbxCHAR: - *p->pChar = static_cast<sal_Unicode>(n); break; - case SbxBYREF | SbxBYTE: - *p->pByte = static_cast<sal_uInt8>(n); break; - case SbxBYREF | SbxINTEGER: - case SbxBYREF | SbxBOOL: - *p->pInteger = n; break; - case SbxBYREF | SbxERROR: - case SbxBYREF | SbxUSHORT: - *p->pUShort = static_cast<sal_uInt16>(n); break; - case SbxBYREF | SbxLONG: - *p->pLong = n; break; - case SbxBYREF | SbxULONG: - *p->pULong = static_cast<sal_uInt32>(n); break; - case SbxBYREF | SbxSINGLE: - *p->pSingle = n; break; - case SbxBYREF | SbxDATE: - case SbxBYREF | SbxDOUBLE: - *p->pDouble = n; break; - case SbxBYREF | SbxCURRENCY: - case SbxBYREF | SbxSALINT64: - *p->pnInt64 = static_cast<sal_Int64>(n); break; - case SbxBYREF | SbxSALUINT64: - *p->puInt64 = static_cast<sal_uInt64>(n); break; + default: SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); } diff --git a/basic/source/sbx/sbxbyte.cxx b/basic/source/sbx/sbxbyte.cxx deleted file mode 100644 index 3e95c5124219..000000000000 --- a/basic/source/sbx/sbxbyte.cxx +++ /dev/null @@ -1,309 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <sal/config.h> - -#include <o3tl/safeint.hxx> -#include <comphelper/errcode.hxx> -//#include <basic/sbx.hxx> -#include <basic/sberrors.hxx> -#include "sbxconv.hxx" - -#include <rtl/math.hxx> - -sal_uInt8 ImpGetByte( const SbxValues* p ) -{ - SbxValues aTmp; - sal_uInt8 nRes; -start: - switch( +p->eType ) - { - case SbxNULL: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); - [[fallthrough]]; - case SbxEMPTY: - nRes = 0; break; - case SbxCHAR: - if( p->nChar > SbxMAXBYTE ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0; - } - else - nRes = static_cast<sal_uInt8>(p->nChar); - break; - case SbxBYTE: - nRes = p->nByte; break; - case SbxINTEGER: - case SbxBOOL: - if( p->nInteger > SbxMAXBYTE ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXBYTE; - } - else if( p->nInteger < 0 ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0; - } - else - nRes = static_cast<sal_uInt8>(p->nInteger); - break; - case SbxERROR: - case SbxUSHORT: - if( p->nUShort > o3tl::make_unsigned(SbxMAXBYTE) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXBYTE; - } - else - nRes = static_cast<sal_uInt8>(p->nUShort); - break; - case SbxLONG: - if( p->nLong > SbxMAXBYTE ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXBYTE; - } - else if( p->nLong < 0 ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0; - } - else - nRes = static_cast<sal_uInt8>(p->nLong); - break; - case SbxULONG: - if( p->nULong > SbxMAXBYTE ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXBYTE; - } - else - nRes = static_cast<sal_uInt8>(p->nULong); - break; - case SbxCURRENCY: - nRes = CurTo<sal_uInt8>(p->nInt64); - break; - case SbxSALINT64: - if (sal_Int64 val = p->nInt64; val > SbxMAXBYTE) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXBYTE; - } - else if (val < 0) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0; - } - else - nRes = static_cast<sal_uInt8>(val); - break; - case SbxSALUINT64: - if( p->uInt64 > SbxMAXBYTE ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXBYTE; - } - else - nRes = static_cast<sal_uInt8>(p->uInt64); - break; - case SbxSINGLE: - if( p->nSingle > SbxMAXBYTE ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXBYTE; - } - else if( p->nSingle < 0 ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0; - } - else - nRes = static_cast<sal_uInt8>(rtl::math::round( p->nSingle )); - break; - case SbxDATE: - case SbxDOUBLE: - case SbxDECIMAL: - case SbxBYREF | SbxDECIMAL: - { - double dVal; - if( p->eType == SbxDECIMAL ) - { - dVal = 0.0; - if( p->pDecimal ) - p->pDecimal->getDouble( dVal ); - } - else - dVal = p->nDouble; - - if( dVal > SbxMAXBYTE ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXBYTE; - } - else if( dVal < 0 ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0; - } - else - nRes = static_cast<sal_uInt8>(rtl::math::round( dVal )); - break; - } - case SbxBYREF | SbxSTRING: - case SbxSTRING: - case SbxLPSTR: - if( !p->pOUString ) - nRes = 0; - else - { - double d; - SbxDataType t; - if( ImpScan( *p->pOUString, d, t, nullptr ) != ERRCODE_NONE ) - nRes = 0; - else if( d > SbxMAXBYTE ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXBYTE; - } - else if( d < 0 ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0; - } - else - nRes = static_cast<sal_uInt8>( d + 0.5 ); - } - break; - case SbxOBJECT: - { - SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) - nRes = pVal->GetByte(); - else - { - SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0; - } - break; - } - - case SbxBYREF | SbxBYTE: - nRes = p->nByte; break; - - // from here on will be tested - case SbxBYREF | SbxCHAR: - aTmp.nChar = *p->pChar; goto ref; - case SbxBYREF | SbxINTEGER: - case SbxBYREF | SbxBOOL: - aTmp.nInteger = *p->pInteger; goto ref; - case SbxBYREF | SbxLONG: - aTmp.nLong = *p->pLong; goto ref; - case SbxBYREF | SbxULONG: - aTmp.nULong = *p->pULong; goto ref; - case SbxBYREF | SbxERROR: - case SbxBYREF | SbxUSHORT: - aTmp.nUShort = *p->pUShort; goto ref; - case SbxBYREF | SbxSINGLE: - aTmp.nSingle = *p->pSingle; goto ref; - case SbxBYREF | SbxDATE: - case SbxBYREF | SbxDOUBLE: - aTmp.nDouble = *p->pDouble; goto ref; - case SbxBYREF | SbxCURRENCY: - case SbxBYREF | SbxSALINT64: - aTmp.nInt64 = *p->pnInt64; goto ref; - case SbxBYREF | SbxSALUINT64: - aTmp.uInt64 = *p->puInt64; goto ref; - ref: - aTmp.eType = SbxDataType( p->eType & 0x0FFF ); - p = &aTmp; goto start; - - default: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0; - } - return nRes; -} - -void ImpPutByte( SbxValues* p, sal_uInt8 n ) -{ - switch( +p->eType ) - { - case SbxBYTE: - p->nByte = n; break; - case SbxINTEGER: - case SbxBOOL: - p->nInteger = n; break; - case SbxERROR: - case SbxUSHORT: - p->nUShort = n; break; - case SbxLONG: - p->nLong = n; break; - case SbxULONG: - p->nULong = n; break; - case SbxSINGLE: - p->nSingle = n; break; - case SbxDATE: - case SbxDOUBLE: - p->nDouble = n; break; - case SbxCURRENCY: - p->nInt64 = CurFrom(n); break; - case SbxSALINT64: - p->nInt64 = n; break; - case SbxSALUINT64: - p->uInt64 = n; break; - case SbxDECIMAL: - case SbxBYREF | SbxDECIMAL: - ImpCreateDecimal( p )->setByte( n ); - break; - - case SbxCHAR: - p->nChar = static_cast<sal_Unicode>(n); break; - - case SbxBYREF | SbxSTRING: - case SbxSTRING: - case SbxLPSTR: - if( !p->pOUString ) - p->pOUString = new OUString; - ImpCvtNum( static_cast<double>(n), 0, *p->pOUString ); - break; - case SbxOBJECT: - { - SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) - pVal->PutByte( n ); - else - SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); - break; - } - case SbxBYREF | SbxCHAR: - *p->pChar = static_cast<sal_Unicode>(n); break; - case SbxBYREF | SbxBYTE: - *p->pByte = n; break; - case SbxBYREF | SbxINTEGER: - case SbxBYREF | SbxBOOL: - *p->pInteger = n; break; - case SbxBYREF | SbxERROR: - case SbxBYREF | SbxUSHORT: - *p->pUShort = n; break; - case SbxBYREF | SbxLONG: - *p->pLong = n; break; - case SbxBYREF | SbxULONG: - *p->pULong = n; break; - case SbxBYREF | SbxSINGLE: - *p->pSingle = n; break; - case SbxBYREF | SbxDATE: - case SbxBYREF | SbxDOUBLE: - *p->pDouble = n; break; - case SbxBYREF | SbxCURRENCY: - p->nInt64 = CurFrom(n); break; - case SbxBYREF | SbxSALINT64: - *p->pnInt64 = n; break; - case SbxBYREF | SbxSALUINT64: - *p->puInt64 = n; break; - - default: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); - } -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/basic/source/sbx/sbxchar.cxx b/basic/source/sbx/sbxchar.cxx deleted file mode 100644 index 6bc44b4e138a..000000000000 --- a/basic/source/sbx/sbxchar.cxx +++ /dev/null @@ -1,295 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <comphelper/errcode.hxx> -#include <basic/sberrors.hxx> -#include "sbxconv.hxx" - -#include <rtl/math.hxx> - -sal_Unicode ImpGetChar( const SbxValues* p ) -{ - SbxValues aTmp; - sal_Unicode nRes = 0; -start: - switch( +p->eType ) - { - case SbxNULL: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); - [[fallthrough]]; - case SbxEMPTY: - nRes = 0; break; - case SbxCHAR: - nRes = p->nChar; break; - case SbxBYTE: - nRes = static_cast<sal_Unicode>(p->nByte); - break; - case SbxINTEGER: - case SbxBOOL: - if( p->nInteger < SbxMINCHAR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMINCHAR; - } - else - nRes = static_cast<sal_Unicode>(p->nInteger); - break; - case SbxERROR: - case SbxUSHORT: - nRes = static_cast<sal_Unicode>(p->nUShort); - break; - case SbxLONG: - if( p->nLong > SbxMAXCHAR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXCHAR; - } - else if( p->nLong < SbxMINCHAR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMINCHAR; - } - else - nRes = static_cast<sal_Unicode>(p->nLong); - break; - case SbxULONG: - if( p->nULong > SbxMAXCHAR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXCHAR; - } - else - nRes = static_cast<sal_Unicode>(p->nULong); - break; - case SbxCURRENCY: - nRes = CurTo<sal_Unicode>(p->nInt64); - break; - case SbxSALINT64: - if (sal_Int64 val = p->nInt64; val > SbxMAXCHAR) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXCHAR; - } - else if (val < SbxMINCHAR) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMINCHAR; - } - else - nRes = static_cast<sal_Unicode>(val); - break; - case SbxSALUINT64: - if( p->uInt64 > SbxMAXCHAR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXCHAR; - } - else - nRes = static_cast<sal_Unicode>(p->uInt64); - break; - case SbxSINGLE: - if( p->nSingle > SbxMAXCHAR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXCHAR; - } - else if( p->nSingle < SbxMINCHAR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMINCHAR; - } - else - nRes = static_cast<sal_Unicode>(rtl::math::round( p->nSingle )); - break; - case SbxDATE: - case SbxDOUBLE: - case SbxDECIMAL: - case SbxBYREF | SbxDECIMAL: - { - double dVal; - if( p->eType == SbxDECIMAL ) - { - dVal = 0.0; - if( p->pDecimal ) - p->pDecimal->getDouble( dVal ); - } - else - dVal = p->nDouble; - - if( dVal > SbxMAXCHAR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXCHAR; - } - else if( dVal < SbxMINCHAR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMINCHAR; - } - else - nRes = static_cast<sal_uInt8>(rtl::math::round( dVal )); - break; - } - case SbxBYREF | SbxSTRING: - case SbxSTRING: - case SbxLPSTR: - if ( p->pOUString ) - { - double d; - SbxDataType t; - if( ImpScan( *p->pOUString, d, t, nullptr ) != ERRCODE_NONE ) - nRes = 0; - else if( d > SbxMAXCHAR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXCHAR; - } - else if( d < SbxMINCHAR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMINCHAR; - } - else - nRes = static_cast<sal_Unicode>(rtl::math::round( d )); - } - break; - case SbxOBJECT: - { - SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) - nRes = pVal->GetChar(); - else - { - SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0; - } - break; - } - - case SbxBYREF | SbxCHAR: - nRes = *p->pChar; break; - // from here on will be tested - case SbxBYREF | SbxBYTE: - aTmp.nByte = *p->pByte; goto ref; - case SbxBYREF | SbxINTEGER: - case SbxBYREF | SbxBOOL: - aTmp.nInteger = *p->pInteger; goto ref; - case SbxBYREF | SbxLONG: - aTmp.nLong = *p->pLong; goto ref; - case SbxBYREF | SbxULONG: - aTmp.nULong = *p->pULong; goto ref; - case SbxBYREF | SbxERROR: - case SbxBYREF | SbxUSHORT: - aTmp.nUShort = *p->pUShort; goto ref; - case SbxBYREF | SbxSINGLE: - aTmp.nSingle = *p->pSingle; goto ref; - case SbxBYREF | SbxDATE: - case SbxBYREF | SbxDOUBLE: - aTmp.nDouble = *p->pDouble; goto ref; - case SbxBYREF | SbxCURRENCY: - case SbxBYREF | SbxSALINT64: - aTmp.nInt64 = *p->pnInt64; goto ref; - case SbxBYREF | SbxSALUINT64: - aTmp.uInt64 = *p->puInt64; goto ref; - ref: - aTmp.eType = SbxDataType( p->eType & 0x0FFF ); - p = &aTmp; goto start; - - default: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0; - } - return nRes; -} - -void ImpPutChar( SbxValues* p, sal_Unicode n ) -{ - SbxValues aTmp; -start: - switch( +p->eType ) - { - case SbxCHAR: - p->nChar = n; break; - case SbxINTEGER: - case SbxBOOL: - p->nInteger = n; break; - case SbxLONG: - p->nLong = n; break; - case SbxSINGLE: - p->nSingle = n; break; - case SbxDATE: - case SbxDOUBLE: - p->nDouble = n; break; - case SbxCURRENCY: - p->nInt64 = CurFrom(n); break; - case SbxSALINT64: - p->nInt64 = n; break; - case SbxSALUINT64: - p->uInt64 = n; break; - case SbxBYREF | SbxDECIMAL: - ImpCreateDecimal( p )->setChar( n ); - break; - - // from here on will be tested - case SbxBYTE: - aTmp.pByte = &p->nByte; goto direct; - case SbxULONG: - aTmp.pULong = &p->nULong; goto direct; - case SbxERROR: - case SbxUSHORT: - aTmp.pUShort = &p->nUShort; goto direct; - direct: - aTmp.eType = SbxDataType( p->eType | SbxBYREF ); - p = &aTmp; goto start; - - case SbxBYREF | SbxSTRING: - case SbxSTRING: - case SbxLPSTR: - if ( !p->pOUString ) - p->pOUString = new OUString( n ); - else - *p->pOUString = OUString( n ); - break; - case SbxOBJECT: - { - SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) - pVal->PutChar( n ); - else - SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); - break; - } - case SbxBYREF | SbxCHAR: - *p->pChar = n; break; - case SbxBYREF | SbxBYTE: - *p->pByte = static_cast<sal_uInt8>(n); break; - case SbxBYREF | SbxINTEGER: - case SbxBYREF | SbxBOOL: - *p->pInteger = n; break; - case SbxBYREF | SbxERROR: - case SbxBYREF | SbxUSHORT: - *p->pUShort = static_cast<sal_uInt16>(n); break; - case SbxBYREF | SbxLONG: - *p->pLong = static_cast<sal_Int32>(n); break; - case SbxBYREF | SbxULONG: - *p->pULong = static_cast<sal_uInt32>(n); break; - case SbxBYREF | SbxSINGLE: - *p->pSingle = static_cast<float>(n); break; - case SbxBYREF | SbxDATE: - case SbxBYREF | SbxDOUBLE: - *p->pDouble = static_cast<double>(n); break; - case SbxBYREF | SbxCURRENCY: - p->nInt64 = CurFrom(n); break; - case SbxBYREF | SbxSALINT64: - *p->pnInt64 = n; break; - case SbxBYREF | SbxSALUINT64: - *p->puInt64 = n; break; - - default: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); - } -} - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/basic/source/sbx/sbxconv.hxx b/basic/source/sbx/sbxconv.hxx index edb0e8cd973c..b04d534f42a2 100644 --- a/basic/source/sbx/sbxconv.hxx +++ b/basic/source/sbx/sbxconv.hxx @@ -32,32 +32,87 @@ class SbxArray; -template <typename I> inline I DoubleTo(double f, I min, I max) +template <std::integral I> I ConvertWithOverflowTo(double f) { f = rtl::math::round(f); - if (!o3tl::convertsToAtMost(f, max)) + if (!o3tl::convertsToAtMost(f, std::numeric_limits<I>::max())) { SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); - return max; + return std::numeric_limits<I>::max(); } - if (!o3tl::convertsToAtLeast(f, min)) + if (!o3tl::convertsToAtLeast(f, std::numeric_limits<I>::min())) { SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); - return min; + return std::numeric_limits<I>::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) +template <std::integral To, std::integral From> To ConvertWithOverflowTo(From n) +{ + using ValidRange = o3tl::ValidRange<To>; + if (ValidRange::isAbove(n)) + { + SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); + return std::numeric_limits<To>::max(); + } + if (ValidRange::isBelow(n)) + { + SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); + return std::numeric_limits<To>::min(); + } + return n; +} + +template <std::floating_point To, std::floating_point From> inline To ConvertWithOverflowTo(From n) +{ + if constexpr (std::numeric_limits<From>::max() > std::numeric_limits<To>::max()) + { + if (n > std::numeric_limits<To>::max()) + { + SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); + return std::numeric_limits<To>::max(); + } + } + if constexpr (std::numeric_limits<From>::lowest() < std::numeric_limits<To>::lowest()) + { + if (n < std::numeric_limits<To>::lowest()) + { + SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); + return std::numeric_limits<To>::lowest(); + } + } + // tests for underflow - storing value too small for precision of single + if constexpr (std::numeric_limits<From>::min() < std::numeric_limits<To>::min()) + { + if (n > 0 && n < std::numeric_limits<To>::min()) + { + SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); + return std::numeric_limits<To>::min(); + } + if (n < 0 && n > -std::numeric_limits<To>::min()) + { + SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); + return -std::numeric_limits<To>::min(); + } + } + return n; +} + +template <std::floating_point To, std::integral From> inline To ConvertWithOverflowTo(From n) { - return DoubleTo<sal_Int64>(d, SAL_MIN_INT64, SAL_MAX_INT64); + // No integral types overflow floats + return static_cast<To>(n); +} + +template <typename T1, typename T2> void assignWithOverflowTo(T1& dest, T2 src) +{ + dest = ConvertWithOverflowTo<T1>(src); +} + +template <typename T> void assignWithOverflowTo(T& dest, SbxDecimal& dec) +{ + dest = dec.getWithOverflow<T>(); } // SBXSCAN.CXX @@ -73,37 +128,33 @@ void ImpGetIntntlSep( sal_Unicode& rcDecimalSep, sal_Unicode& rcThousandSep, sal // SBXINT.CXX +sal_Unicode ImpGetChar( const SbxValues* ); +void ImpPutChar( SbxValues*, sal_Unicode ); +sal_uInt8 ImpGetByte( const SbxValues* ); +void ImpPutByte( SbxValues*, sal_uInt8 ); sal_Int16 ImpGetInteger( const SbxValues* ); void ImpPutInteger( SbxValues*, sal_Int16 ); - +sal_uInt16 ImpGetUShort( const SbxValues* ); +void ImpPutUShort( SbxValues*, sal_uInt16 ); +sal_Int32 ImpGetLong( const SbxValues* ); +void ImpPutLong( SbxValues*, sal_Int32 ); +sal_uInt32 ImpGetULong( const SbxValues* ); +void ImpPutULong( SbxValues*, sal_uInt32 ); sal_Int64 ImpGetInt64( const SbxValues* ); void ImpPutInt64( SbxValues*, sal_Int64 ); sal_uInt64 ImpGetUInt64( const SbxValues* ); void ImpPutUInt64( SbxValues*, sal_uInt64 ); - -double ImpSalUInt64ToDouble( sal_uInt64 n ); - -// SBXLNG.CXX - -sal_Int32 ImpGetLong( const SbxValues* ); -void ImpPutLong( SbxValues*, sal_Int32 ); - -// SBXSNG.CXX - -float ImpGetSingle( const SbxValues* ); -void ImpPutSingle( SbxValues*, float ); - -// SBXDBL.CXX - -double ImpGetDouble( const SbxValues* ); -void ImpPutDouble( SbxValues*, double, bool bCoreString=false ); +double ImpGetDouble( const SbxValues* ); +void ImpPutDouble( SbxValues*, double, bool bCoreString=false ); +float ImpGetSingle( const SbxValues* ); +void ImpPutSingle( SbxValues*, float ); // SBXCURR.CXX sal_Int64 ImpGetCurrency( const SbxValues* ); void ImpPutCurrency( SbxValues*, const sal_Int64 ); -inline sal_Int64 ImpDoubleToCurrency( double d ) +inline sal_Int64 CurFrom(double d) { double result = d > 0 ? (d * CURRENCY_FACTOR + 0.5) : (d * CURRENCY_FACTOR - 0.5); if (result >= double(SAL_MAX_INT64)) // double(SAL_MAX_INT64) is greater than SAL_MAX_INT64 @@ -119,9 +170,7 @@ inline sal_Int64 ImpDoubleToCurrency( double d ) return result; } -template <typename I> - requires std::is_integral_v<I> -inline sal_Int64 CurFrom(I n) +template <std::integral I> sal_Int64 CurFrom(I n) { using ValidRange = o3tl::ValidRange<sal_Int64, SAL_MIN_INT64 / CURRENCY_FACTOR, SAL_MAX_INT64 / CURRENCY_FACTOR>; if (ValidRange::isAbove(n)) @@ -137,24 +186,9 @@ inline sal_Int64 CurFrom(I n) return n * CURRENCY_FACTOR; } -inline double ImpCurrencyToDouble(sal_Int64 r) { return static_cast<double>(r) / CURRENCY_FACTOR; } - -template <typename I> - requires std::is_integral_v<I> -inline I CurTo(sal_Int64 cur_val) +template <std::integral I> I CurTo(sal_Int64 cur_val) { - sal_Int64 i = CurTo<sal_Int64>(cur_val); - if (o3tl::ValidRange<I>::isAbove(i)) - { - SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); - return std::numeric_limits<I>::max(); - } - if (o3tl::ValidRange<I>::isBelow(i)) - { - SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); - return std::numeric_limits<I>::min(); - } - return i; + return ConvertWithOverflowTo<I>(CurTo<sal_Int64>(cur_val)); } template <> inline sal_Int64 CurTo<sal_Int64>(sal_Int64 cur_val) @@ -176,6 +210,10 @@ template <> inline sal_Int64 CurTo<sal_Int64>(sal_Int64 cur_val) return i; } +template <std::floating_point F> F CurTo(sal_Int64 r) +{ + return ConvertWithOverflowTo<F>(static_cast<double>(r) / CURRENCY_FACTOR); +} // SBXDEC.CXX @@ -194,25 +232,6 @@ OUString ImpGetString( const SbxValues* ); OUString ImpGetCoreString( const SbxValues* ); void ImpPutString( SbxValues*, const OUString* ); -// SBXCHAR.CXX - -sal_Unicode ImpGetChar( const SbxValues* ); -void ImpPutChar( SbxValues*, sal_Unicode ); - -// SBXBYTE.CXX -sal_uInt8 ImpGetByte( const SbxValues* ); -void ImpPutByte( SbxValues*, sal_uInt8 ); - -// SBXUINT.CXX - -sal_uInt16 ImpGetUShort( const SbxValues* ); -void ImpPutUShort( SbxValues*, sal_uInt16 ); - -// SBXULNG.CXX - -sal_uInt32 ImpGetULong( const SbxValues* ); -void ImpPutULong( SbxValues*, sal_uInt32 ); - // SBXBOOL.CXX enum SbxBOOL ImpGetBool( const SbxValues* ); diff --git a/basic/source/sbx/sbxcurr.cxx b/basic/source/sbx/sbxcurr.cxx index d5fe4be9f6b7..5b452686de24 100644 --- a/basic/source/sbx/sbxcurr.cxx +++ b/basic/source/sbx/sbxcurr.cxx @@ -104,129 +104,98 @@ static sal_Int64 ImpStringToCurrency(const rtl::OUString& rStr) SbxBase::SetError(ERRCODE_BASIC_CONVERSION); } - return ImpDoubleToCurrency(fResult); + return CurFrom(fResult); } sal_Int64 ImpGetCurrency( const SbxValues* p ) { - SbxValues aTmp; - sal_Int64 nRes; -start: switch( +p->eType ) { case SbxERROR: case SbxNULL: SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); - nRes = 0; break; + return 0; case SbxEMPTY: - nRes = 0; break; + return 0; case SbxCURRENCY: - nRes = p->nInt64; break; + return p->nInt64; case SbxBYTE: - nRes = CurFrom(p->nByte); - break; + return CurFrom(p->nByte); case SbxCHAR: - nRes = CurFrom(p->nChar); - break; + return CurFrom(p->nChar); case SbxBOOL: case SbxINTEGER: - nRes = CurFrom(p->nInteger); - break; + return CurFrom(p->nInteger); case SbxUSHORT: - nRes = CurFrom(p->nUShort); - break; + return CurFrom(p->nUShort); case SbxLONG: - nRes = CurFrom(p->nLong); - break; + return CurFrom(p->nLong); case SbxULONG: - nRes = CurFrom(p->nULong); - break; + return CurFrom(p->nULong); case SbxSALINT64: - nRes = CurFrom(p->nInt64); - break; + return CurFrom(p->nInt64); case SbxSALUINT64: - nRes = CurFrom(p->uInt64); - break; + return CurFrom(p->uInt64); case SbxSINGLE: - nRes = ImpDoubleToCurrency(p->nSingle); - break; + return CurFrom(p->nSingle); case SbxDATE: case SbxDOUBLE: - nRes = ImpDoubleToCurrency( p->nDouble ); - break; + return CurFrom(p->nDouble); case SbxDECIMAL: case SbxBYREF | SbxDECIMAL: - { - double d = 0.0; if( p->pDecimal ) + { + double d = 0.0; p->pDecimal->getDouble( d ); - nRes = ImpDoubleToCurrency( d ); - break; + return CurFrom(d); } - + return 0; case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pOUString ) - nRes=0; - else - nRes = ImpStringToCurrency( *p->pOUString ); - break; + if (p->pOUString) + return ImpStringToCurrency( *p->pOUString ); + return 0; case SbxOBJECT: - { - SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) - nRes = pVal->GetCurrency(); - else - { - SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); - nRes=0; - } - break; - } + if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj)) + return pVal->GetCurrency(); + SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); + return 0; case SbxBYREF | SbxCHAR: - nRes = CurFrom(*p->pChar); - break; + return CurFrom(*p->pChar); case SbxBYREF | SbxBYTE: - nRes = CurFrom(*p->pByte); - break; + return CurFrom(*p->pByte); case SbxBYREF | SbxBOOL: case SbxBYREF | SbxINTEGER: - nRes = CurFrom(*p->pInteger); - break; + return CurFrom(*p->pInteger); case SbxBYREF | SbxERROR: case SbxBYREF | SbxUSHORT: - nRes = CurFrom(*p->pUShort); - break; + return CurFrom(*p->pUShort); - // from here on had to be tested case SbxBYREF | SbxLONG: - aTmp.nLong = *p->pLong; goto ref; + return CurFrom(*p->pLong); case SbxBYREF | SbxULONG: - aTmp.nULong = *p->pULong; goto ref; + return CurFrom(*p->pULong); case SbxBYREF | SbxSINGLE: - aTmp.nSingle = *p->pSingle; goto ref; + return CurFrom(*p->pSingle); case SbxBYREF | SbxDATE: case SbxBYREF | SbxDOUBLE: - aTmp.nDouble = *p->pDouble; goto ref; + return CurFrom(*p->pDouble); case SbxBYREF | SbxCURRENCY: + return *p->pnInt64; case SbxBYREF | SbxSALINT64: - aTmp.nInt64 = *p->pnInt64; goto ref; + return CurFrom(*p->pnInt64); case SbxBYREF | SbxSALUINT64: - aTmp.uInt64 = *p->puInt64; goto ref; - ref: - aTmp.eType = SbxDataType( p->eType & ~SbxBYREF ); - p = &aTmp; goto start; + return CurFrom(*p->puInt64); default: SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); - nRes=0; + return 0; } - return nRes; } void ImpPutCurrency( SbxValues* p, const sal_Int64 r ) @@ -235,7 +204,7 @@ void ImpPutCurrency( SbxValues* p, const sal_Int64 r ) { case SbxDATE: case SbxDOUBLE: - p->nDouble = ImpCurrencyToDouble( r ); break; + p->nDouble = CurTo<double>( r ); break; case SbxSALUINT64: p->uInt64 = CurTo<sal_uInt64>(r); break; case SbxSALINT64: @@ -246,12 +215,9 @@ void ImpPutCurrency( SbxValues* p, const sal_Int64 r ) case SbxDECIMAL: case SbxBYREF | SbxDECIMAL: - { - SbxDecimal* pDec = ImpCreateDecimal( p ); - if( !pDec->setDouble( ImpCurrencyToDouble( r ) ) ) + if (!ImpCreateDecimal(p)->setDouble(CurTo<double>(r))) SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); break; - } case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: @@ -261,14 +227,11 @@ void ImpPutCurrency( SbxValues* p, const sal_Int64 r ) *p->pOUString = ImpCurrencyToString( r ); break; case SbxOBJECT: - { - SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) + if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj)) pVal->PutCurrency( r ); else SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); break; - } case SbxCHAR: p->nChar = CurTo<sal_Unicode>(r); break; case SbxBYREF | SbxCHAR: @@ -304,11 +267,12 @@ void ImpPutCurrency( SbxValues* p, const sal_Int64 r ) case SbxBYREF | SbxSALUINT64: *p->puInt64 = CurTo<sal_uInt64>(r); break; case SbxSINGLE: + p->nSingle = CurTo<float>( r ); break; case SbxBYREF | SbxSINGLE: - p->nSingle = r / float(CURRENCY_FACTOR); break; + *p->pSingle = CurTo<float>( r ); break; case SbxBYREF | SbxDATE: case SbxBYREF | SbxDOUBLE: - *p->pDouble = ImpCurrencyToDouble( r ); break; + *p->pDouble = CurTo<double>( r ); break; default: SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); } diff --git a/basic/source/sbx/sbxdate.cxx b/basic/source/sbx/sbxdate.cxx index 057e16f09d03..c3d3a4d2a4f2 100644 --- a/basic/source/sbx/sbxdate.cxx +++ b/basic/source/sbx/sbxdate.cxx @@ -35,67 +35,46 @@ double ImpGetDate( const SbxValues* p ) { - double nRes; - SbxValue* pVal; - switch( +p->eType ) { - case SbxNULL: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); - [[fallthrough]]; case SbxEMPTY: - nRes = 0; - break; + return 0; case SbxCHAR: - nRes = p->nChar; - break; + return p->nChar; case SbxBYTE: - nRes = p->nByte; - break; + return p->nByte; case SbxINTEGER: case SbxBOOL: - nRes = p->nInteger; - break; + return p->nInteger; case SbxERROR: case SbxUSHORT: - nRes = p->nUShort; - break; + return p->nUShort; case SbxLONG: - nRes = static_cast<double>(p->nLong); - break; + return p->nLong; case SbxULONG: - nRes = static_cast<double>(p->nULong); - break; + return p->nULong; case SbxSINGLE: - nRes = p->nSingle; - break; + return p->nSingle; case SbxDATE: case SbxDOUBLE: - nRes = p->nDouble; - break; + return p->nDouble; case SbxCURRENCY: - nRes = ImpCurrencyToDouble( p->nInt64 ); - break; + return CurTo<double>(p->nInt64); case SbxSALINT64: - nRes = static_cast< double >(p->nInt64); - break; + return static_cast<double>(p->nInt64); case SbxSALUINT64: - nRes = ImpSalUInt64ToDouble( p->uInt64 ); - break; + return static_cast<double>(p->uInt64); case SbxDECIMAL: case SbxBYREF | SbxDECIMAL: - if (!p->pDecimal || !p->pDecimal->getDouble(nRes)) - nRes = 0.0; - break; + if (p->pDecimal) + if (double d; p->pDecimal->getDouble(d)) + return d; + return 0; case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: #if HAVE_FEATURE_SCRIPTING - if( !p->pOUString ) - { - nRes = 0; - } - else + if (p->pOUString) { LanguageType eLangType = Application::GetSettings().GetLanguageTag().getLanguageType(); std::shared_ptr<SvNumberFormatter> pFormatter; @@ -137,135 +116,137 @@ double ImpGetDate( const SbxValues* p ) pFormatter->PutandConvertEntry( aStr, nCheckPos, nType, nIndex, LANGUAGE_ENGLISH_US, eLangType, true); - bool bSuccess = pFormatter->IsNumberFormat( *p->pOUString, nIndex, nRes ); - if ( bSuccess ) + if (double d; pFormatter->IsNumberFormat(*p->pOUString, nIndex, d)) { SvNumFormatType nType_ = pFormatter->GetType( nIndex ); - if(!(nType_ & ( SvNumFormatType::DATETIME | SvNumFormatType::DATE | - SvNumFormatType::TIME | SvNumFormatType::DEFINED ))) + if(nType_ & ( SvNumFormatType::DATETIME | SvNumFormatType::DATE | + SvNumFormatType::TIME | SvNumFormatType::DEFINED )) { - bSuccess = false; + return d; } } - if ( !bSuccess ) - { - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0; - } + SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); } -#else - nRes = 0; #endif - break; + return 0; case SbxOBJECT: - pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) - { - nRes = pVal->GetDate(); - } - else - { - SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0; - } - break; + if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj)) + return pVal->GetDate(); + SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); + return 0; case SbxBYREF | SbxCHAR: - nRes = *p->pChar; - break; + return *p->pChar; case SbxBYREF | SbxBYTE: - nRes = *p->pByte; - break; + return *p->pByte; case SbxBYREF | SbxINTEGER: case SbxBYREF | SbxBOOL: - nRes = *p->pInteger; - break; + return *p->pInteger; case SbxBYREF | SbxLONG: - nRes = *p->pLong; - break; + return *p->pLong; case SbxBYREF | SbxULONG: - nRes = *p->pULong; - break; + return *p->pULong; case SbxBYREF | SbxERROR: case SbxBYREF | SbxUSHORT: - nRes = *p->pUShort; - break; + return *p->pUShort; case SbxBYREF | SbxSINGLE: - nRes = *p->pSingle; - break; + return *p->pSingle; case SbxBYREF | SbxDATE: case SbxBYREF | SbxDOUBLE: - nRes = *p->pDouble; - break; + return *p->pDouble; case SbxBYREF | SbxCURRENCY: - nRes = ImpCurrencyToDouble( *p->pnInt64 ); - break; + return CurTo<double>(*p->pnInt64); case SbxBYREF | SbxSALINT64: - nRes = static_cast< double >(*p->pnInt64); - break; + return static_cast<double>(*p->pnInt64); case SbxBYREF | SbxSALUINT64: - nRes = ImpSalUInt64ToDouble( *p->puInt64 ); - break; + return static_cast<double>(*p->puInt64); default: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0; - break; + SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); + return 0; } - return nRes; } void ImpPutDate( SbxValues* p, double n ) { - SbxValues aTmp; - SbxDecimal* pDec; - SbxValue* pVal; - -start: switch( +p->eType ) { case SbxDATE: case SbxDOUBLE: p->nDouble = n; break; - // from here will be tested + case SbxBYREF | SbxDATE: + case SbxBYREF | SbxDOUBLE: + *p->pDouble = n; + break; case SbxCHAR: - aTmp.pChar = &p->nChar; - goto direct; + assignWithOverflowTo(p->nChar, n); + break; + case SbxBYREF | SbxCHAR: + assignWithOverflowTo(*p->pChar, n); + break; case SbxBYTE: - aTmp.pByte = &p->nByte; - goto direct; + assignWithOverflowTo(p->nByte, n); + break; + case SbxBYREF | SbxBYTE: + assignWithOverflowTo(*p->pByte, n); + break; case SbxINTEGER: case SbxBOOL: - aTmp.pInteger = &p->nInteger; - goto direct; - case SbxLONG: - aTmp.pLong = &p->nLong; - goto direct; - case SbxULONG: - aTmp.pULong = &p->nULong; - goto direct; + assignWithOverflowTo(p->nInteger, n); + break; + case SbxBYREF | SbxINTEGER: + case SbxBYREF | SbxBOOL: + assignWithOverflowTo(*p->pInteger, n); + break; case SbxERROR: case SbxUSHORT: - aTmp.pUShort = &p->nUShort; - goto direct; - case SbxSINGLE: - aTmp.pSingle = &p->nSingle; - goto direct; + assignWithOverflowTo(p->nUShort, n); + break; + case SbxBYREF | SbxERROR: + case SbxBYREF | SbxUSHORT: + assignWithOverflowTo(*p->pUShort, n); + break; + case SbxLONG: + assignWithOverflowTo(p->nLong, n); + break; + case SbxBYREF | SbxLONG: + assignWithOverflowTo(*p->pLong, n); + break; + case SbxULONG: + assignWithOverflowTo(p->nULong, n); + break; + case SbxBYREF | SbxULONG: + assignWithOverflowTo(*p->pULong, n); + break; case SbxCURRENCY: + assignWithOverflowTo(p->nInt64, CurFrom(n)); + break; + case SbxBYREF | SbxCURRENCY: + assignWithOverflowTo(*p->pnInt64, CurFrom(n)); + break; case SbxSALINT64: - aTmp.pnInt64 = &p->nInt64; - goto direct; + assignWithOverflowTo(p->nInt64, n); + break; + case SbxBYREF | SbxSALINT64: + assignWithOverflowTo(*p->pnInt64, n); + break; case SbxSALUINT64: - aTmp.puInt64 = &p->uInt64; - goto direct; + assignWithOverflowTo(p->uInt64, n); + break; + case SbxBYREF | SbxSALUINT64: + assignWithOverflowTo(*p->puInt64, n); + break; + case SbxSINGLE: + assignWithOverflowTo(p->nSingle, n); + break; + case SbxBYREF | SbxSINGLE: + assignWithOverflowTo(*p->pSingle, n); + break; + case SbxDECIMAL: case SbxBYREF | SbxDECIMAL: - pDec = ImpCreateDecimal( p ); - if( !pDec->setDouble( n ) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - } + ImpCreateDecimal(p)->setWithOverflow(n); break; - direct: - aTmp.eType = SbxDataType( p->eType | SbxBYREF ); - p = &aTmp; goto start; case SbxBYREF | SbxSTRING: case SbxSTRING: @@ -336,9 +317,9 @@ start: #endif break; } + case SbxOBJECT: - pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) + if (auto pVal = dynamic_cast<SbxValue*>(p->pObj)) { pVal->PutDate( n ); } @@ -347,58 +328,7 @@ start: SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); } break; - case SbxBYREF | SbxCHAR: - *p->pChar = ImpDoubleToChar(n); - break; - case SbxBYREF | SbxBYTE: - *p->pByte = ImpDoubleToByte(n); - break; - case SbxBYREF | SbxINTEGER: - case SbxBYREF | SbxBOOL: - *p->pInteger = ImpDoubleToInteger(n); - break; - case SbxBYREF | SbxERROR: - case SbxBYREF | SbxUSHORT: - *p->pUShort = ImpDoubleToUShort(n); - break; - case SbxBYREF | SbxLONG: - *p->pLong = ImpDoubleToLong(n); - break; - case SbxBYREF | SbxULONG: - *p->pULong = ImpDoubleToULong(n); - break; - case SbxBYREF | SbxSINGLE: - if( n > SbxMAXSNG ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXSNG; - } - else if( n < SbxMINSNG ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINSNG; - } - *p->pSingle = static_cast<float>(n); - break; - case SbxBYREF | SbxSALINT64: - *p->pnInt64 = ImpDoubleToSalInt64( n ); - break; - case SbxBYREF | SbxSALUINT64: - *p->puInt64 = ImpDoubleToSalUInt64( n ); - break; - case SbxBYREF | SbxDATE: - case SbxBYREF | SbxDOUBLE: - *p->pDouble = n; - break; - case SbxBYREF | SbxCURRENCY: - if( n > SbxMAXCURR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXCURR; - } - else if( n < SbxMINCURR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINCURR; - } - *p->pnInt64 = ImpDoubleToCurrency( n ); - break; + default: SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); break; diff --git a/basic/source/sbx/sbxdbl.cxx b/basic/source/sbx/sbxdbl.cxx deleted file mode 100644 index fa6ca01d6219..000000000000 --- a/basic/source/sbx/sbxdbl.cxx +++ /dev/null @@ -1,265 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <config_features.h> - -#include <comphelper/errcode.hxx> -#include "sbxconv.hxx" -#include <runtime.hxx> - -double ImpGetDouble( const SbxValues* p ) -{ - double nRes; - switch( +p->eType ) - { - case SbxNULL: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); - [[fallthrough]]; - case SbxEMPTY: - nRes = 0; break; - case SbxCHAR: - nRes = p->nChar; break; - case SbxBYTE: - nRes = p->nByte; break; - case SbxINTEGER: - case SbxBOOL: - nRes = p->nInteger; break; - case SbxERROR: - case SbxUSHORT: - nRes = p->nUShort; break; - case SbxLONG: - nRes = p->nLong; break; - case SbxULONG: - nRes = p->nULong; break; - case SbxSINGLE: - nRes = p->nSingle; break; - case SbxDATE: - case SbxDOUBLE: - nRes = p->nDouble; break; - case SbxCURRENCY: - nRes = ImpCurrencyToDouble( p->nInt64 ); break; - case SbxSALINT64: - nRes = static_cast< double >(p->nInt64); break; - case SbxSALUINT64: - nRes = ImpSalUInt64ToDouble( p->uInt64 ); break; - case SbxDECIMAL: - case SbxBYREF | SbxDECIMAL: - if (!p->pDecimal || !p->pDecimal->getDouble(nRes)) - nRes = 0.0; - break; - case SbxBYREF | SbxSTRING: - case SbxSTRING: - case SbxLPSTR: - if( !p->pOUString ) - { - nRes = 0; -#if HAVE_FEATURE_SCRIPTING - if ( SbiRuntime::isVBAEnabled() )// VBA only behaviour - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); -#endif - } - else - { - double d; - SbxDataType t; - if( ImpScan( *p->pOUString, d, t, nullptr ) != ERRCODE_NONE ) - { - nRes = 0; -#if HAVE_FEATURE_SCRIPTING - if ( SbiRuntime::isVBAEnabled() )// VBA only behaviour - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); -#endif - } - else - nRes = d; - } - break; - case SbxOBJECT: - { - SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) - nRes = pVal->GetDouble(); - else - { - SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0; - } - break; - } - - case SbxBYREF | SbxCHAR: - nRes = *p->pChar; break; - case SbxBYREF | SbxBYTE: - nRes = *p->pByte; break; - case SbxBYREF | SbxINTEGER: - case SbxBYREF | SbxBOOL: - nRes = *p->pInteger; break; - case SbxBYREF | SbxLONG: - nRes = *p->pLong; break; - case SbxBYREF | SbxULONG: - nRes = *p->pULong; break; - case SbxBYREF | SbxERROR: - case SbxBYREF | SbxUSHORT: - nRes = *p->pUShort; break; - case SbxBYREF | SbxSINGLE: - nRes = *p->pSingle; break; - case SbxBYREF | SbxDATE: - case SbxBYREF | SbxDOUBLE: - nRes = *p->pDouble; break; - case SbxBYREF | SbxCURRENCY: - nRes = ImpCurrencyToDouble( *p->pnInt64 ); break; - case SbxBYREF | SbxSALINT64: - nRes = static_cast< double >(*p->pnInt64); break; - case SbxBYREF | SbxSALUINT64: - nRes = ImpSalUInt64ToDouble( *p->puInt64 ); break; - - default: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0; - } - return nRes; -} - -void ImpPutDouble( SbxValues* p, double n, bool bCoreString ) -{ - SbxValues aTmp; -start: - switch( +p->eType ) - { - // Here are tests necessary - case SbxCHAR: - aTmp.pChar = &p->nChar; goto direct; - case SbxBYTE: - aTmp.pByte = &p->nByte; goto direct; - case SbxINTEGER: - case SbxBOOL: - aTmp.pInteger = &p->nInteger; goto direct; - case SbxLONG: - aTmp.pLong = &p->nLong; goto direct; - case SbxULONG: - aTmp.pULong = &p->nULong; goto direct; - case SbxERROR: - case SbxUSHORT: - aTmp.pUShort = &p->nUShort; goto direct; - case SbxSINGLE: - aTmp.pSingle = &p->nSingle; goto direct; - case SbxDECIMAL: - case SbxBYREF | SbxDECIMAL: - { - SbxDecimal* pDec = ImpCreateDecimal( p ); - if( !pDec->setDouble( n ) ) - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - break; - } - direct: - aTmp.eType = SbxDataType( p->eType | SbxBYREF ); - p = &aTmp; goto start; - - case SbxCURRENCY: - if( n > SbxMAXCURR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXCURR; - } - else if( n < SbxMINCURR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINCURR; - } - p->nInt64 = ImpDoubleToCurrency( n ); - break; - - // from here on no longer - case SbxSALINT64: - p->nInt64 = ImpDoubleToSalInt64( n ); break; - case SbxSALUINT64: - p->uInt64 = ImpDoubleToSalUInt64( n ); break; - case SbxDATE: - case SbxDOUBLE: - p->nDouble = n; break; - - case SbxBYREF | SbxSTRING: - case SbxSTRING: - case SbxLPSTR: - if( !p->pOUString ) - p->pOUString = new OUString; - // tdf#107953 - show 17 significant digits - ImpCvtNum( n, 17, *p->pOUString, bCoreString ); - break; - case SbxOBJECT: - { - SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) - pVal->PutDouble( n ); - else - SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); - break; - } - case SbxBYREF | SbxCHAR: - *p->pChar = ImpDoubleToChar(n); break; - case SbxBYREF | SbxBYTE: - *p->pByte = ImpDoubleToByte(n); break; - case SbxBYREF | SbxINTEGER: - case SbxBYREF | SbxBOOL: - *p->pInteger = ImpDoubleToInteger(n); break; - case SbxBYREF | SbxERROR: - case SbxBYREF | SbxUSHORT: - *p->pUShort = ImpDoubleToUShort(n); break; - case SbxBYREF | SbxLONG: - *p->pLong = ImpDoubleToLong(n); break; - case SbxBYREF | SbxULONG: - *p->pULong = ImpDoubleToULong(n); break; - case SbxBYREF | SbxSINGLE: - if( n > SbxMAXSNG ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXSNG; - } - else if( n < SbxMINSNG ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINSNG; - } - else if( n > 0 && n < SbxMAXSNG2 ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXSNG2; - } - else if( n < 0 && n > SbxMINSNG2 ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINSNG2; - } - *p->pSingle = static_cast<float>(n); break; - case SbxBYREF | SbxSALINT64: - *p->pnInt64 = ImpDoubleToSalInt64( n ); break; - case SbxBYREF | SbxSALUINT64: - *p->puInt64 = ImpDoubleToSalUInt64( n ); break; - case SbxBYREF | SbxDATE: - case SbxBYREF | SbxDOUBLE: - *p->pDouble = n; break; - case SbxBYREF | SbxCURRENCY: - if( n > SbxMAXCURR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXCURR; - } - else if( n < SbxMINCURR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINCURR; - } - *p->pnInt64 = ImpDoubleToCurrency( n ); break; - - default: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); - } -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/basic/source/sbx/sbxdec.cxx b/basic/source/sbx/sbxdec.cxx index cad5601f2f7b..e6a8837fe7ee 100644 --- a/basic/source/sbx/sbxdec.cxx +++ b/basic/source/sbx/sbxdec.cxx @@ -157,6 +157,11 @@ void SbxDecimal::setLong( sal_Int32 val ) VarDecFromI4(static_cast<LONG>(val), &maDec); } +bool SbxDecimal::setHyper( sal_Int64 val ) +{ + return SUCCEEDED(VarDecFromI8(static_cast<LONG64>(val), &maDec)); +} + void SbxDecimal::setUShort( sal_uInt16 val ) { VarDecFromUI2( val, &maDec ); @@ -167,6 +172,11 @@ void SbxDecimal::setULong( sal_uInt32 val ) VarDecFromUI4( static_cast<ULONG>(val), &maDec ); } +bool SbxDecimal::setUHyper( sal_uInt64 val ) +{ + return SUCCEEDED(VarDecFromUI8( static_cast<ULONG64>(val), &maDec )); +} + bool SbxDecimal::setSingle( float val ) { bool bRet = ( VarDecFromR4( val, &maDec ) == S_OK ); @@ -241,6 +251,12 @@ bool SbxDecimal::getChar( sal_Unicode& rVal ) return bRet; } +bool SbxDecimal::getByte( sal_uInt8& rVal ) +{ + bool bRet = ( VarUI1FromDec( &maDec, &rVal ) == S_OK ); + return bRet; +} + bool SbxDecimal::getShort( sal_Int16& rVal ) { bool bRet = ( VarI2FromDec( &maDec, &rVal ) == S_OK ); @@ -253,6 +269,12 @@ bool SbxDecimal::getLong( sal_Int32& rVal ) return bRet; } +bool SbxDecimal::getHyper( sal_Int64& rVal ) +{ + bool bRet = ( VarI8FromDec( &maDec, &rVal ) == S_OK ); + return bRet; +} + bool SbxDecimal::getUShort( sal_uInt16& rVal ) { bool bRet = ( VarUI2FromDec( &maDec, &rVal ) == S_OK ); @@ -265,6 +287,12 @@ bool SbxDecimal::getULong( sal_uInt32& rVal ) return bRet; } +bool SbxDecimal::getUHyper( sal_uInt64& rVal ) +{ + bool bRet = ( VarUI8FromDec( &maDec, &rVal ) == S_OK ); + return bRet; +} + bool SbxDecimal::getSingle( float& rVal ) { bool bRet = ( VarR4FromDec( &maDec, &rVal ) == S_OK ); @@ -319,8 +347,10 @@ void SbxDecimal::setChar( SAL_UNUSED_PARAMETER sal_Unicode ) {} void SbxDecimal::setByte( SAL_UNUSED_PARAMETER sal_uInt8 ) {} void SbxDecimal::setShort( SAL_UNUSED_PARAMETER sal_Int16 ) {} void SbxDecimal::setLong( SAL_UNUSED_PARAMETER sal_Int32 ) {} +bool SbxDecimal::setHyper( SAL_UNUSED_PARAMETER sal_Int64 ) { return false; } void SbxDecimal::setUShort( SAL_UNUSED_PARAMETER sal_uInt16 ) {} void SbxDecimal::setULong( SAL_UNUSED_PARAMETER sal_uInt32 ) {} +bool SbxDecimal::setUHyper( SAL_UNUSED_PARAMETER sal_uInt64 ) { return false; } bool SbxDecimal::setSingle( SAL_UNUSED_PARAMETER float ) { return false; } bool SbxDecimal::setDouble( SAL_UNUSED_PARAMETER double ) { return false; } void SbxDecimal::setInt( SAL_UNUSED_PARAMETER int ) {} @@ -328,10 +358,13 @@ void SbxDecimal::setUInt( SAL_UNUSED_PARAMETER unsigned int ) {} bool SbxDecimal::setString( SAL_UNUSED_PARAMETER OUString* ) { return false; } bool SbxDecimal::getChar( SAL_UNUSED_PARAMETER sal_Unicode& ) { return false; } +bool SbxDecimal::getByte( SAL_UNUSED_PARAMETER sal_uInt8& ) { return false; } bool SbxDecimal::getShort( SAL_UNUSED_PARAMETER sal_Int16& ) { return false; } bool SbxDecimal::getLong( SAL_UNUSED_PARAMETER sal_Int32& ) { return false; } +bool SbxDecimal::getHyper( SAL_UNUSED_PARAMETER sal_Int64& ) { return false; } bool SbxDecimal::getUShort( SAL_UNUSED_PARAMETER sal_uInt16& ) { return false; } bool SbxDecimal::getULong( SAL_UNUSED_PARAMETER sal_uInt32& ) { return false; } +bool SbxDecimal::getUHyper( SAL_UNUSED_PARAMETER sal_uInt64& ) { return false; } bool SbxDecimal::getSingle( SAL_UNUSED_PARAMETER float& ) { return false; } bool SbxDecimal::getDouble( SAL_UNUSED_PARAMETER double& ) { return false; } @@ -373,6 +406,12 @@ void SbxDecimal::getString( OUString& rString ) #endif } +void SbxDecimal::HandleFailure(bool isSuccess) +{ + if (!isSuccess) + SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); +} + SbxDecimal* ImpCreateDecimal( SbxValues* p ) { if( !p ) @@ -389,25 +428,18 @@ SbxDecimal* ImpCreateDecimal( SbxValues* p ) SbxDecimal* ImpGetDecimal( const SbxValues* p ) { - SbxValues aTmp; - SbxDecimal* pnDecRes; - SbxDataType eType = p->eType; if( eType == SbxDECIMAL && p->pDecimal ) { - pnDecRes = new SbxDecimal( *p->pDecimal ); + SbxDecimal* pnDecRes = new SbxDecimal( *p->pDecimal ); pnDecRes->addRef(); return pnDecRes; } - pnDecRes = new SbxDecimal(); + SbxDecimal* pnDecRes = new SbxDecimal(); pnDecRes->addRef(); -start: switch( +eType ) { - case SbxNULL: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); - [[fallthrough]]; case SbxEMPTY: pnDecRes->setShort( 0 ); break; case SbxCHAR: @@ -425,35 +457,37 @@ start: case SbxULONG: pnDecRes->setULong( p->nULong ); break; case SbxSINGLE: - if( !pnDecRes->setSingle( p->nSingle ) ) - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); + pnDecRes->setWithOverflow(p->nSingle); + break; + case SbxBYREF | SbxSINGLE: + pnDecRes->setWithOverflow(*p->pSingle); break; case SbxCURRENCY: - { - if( !pnDecRes->setDouble( ImpCurrencyToDouble( p->nInt64 ) ) ) - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - break; - } + pnDecRes->setWithOverflow(CurTo<double>(p->nInt64)); + break; + case SbxBYREF | SbxCURRENCY: + pnDecRes->setWithOverflow(CurTo<double>(*p->pnInt64)); + break; case SbxSALINT64: - { - if( !pnDecRes->setDouble( static_cast<double>(p->nInt64) ) ) - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - break; - } + pnDecRes->setWithOverflow(p->nInt64); + break; + case SbxBYREF | SbxSALINT64: + pnDecRes->setWithOverflow(*p->pnInt64); + break; case SbxSALUINT64: - { - if( !pnDecRes->setDouble( static_cast<double>(p->uInt64) ) ) - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - break; - } + pnDecRes->setWithOverflow(p->uInt64); + break; + case SbxBYREF | SbxSALUINT64: + pnDecRes->setWithOverflow(*p->puInt64); + break; case SbxDATE: case SbxDOUBLE: - { - double dVal = p->nDouble; - if( !pnDecRes->setDouble( dVal ) ) - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); + pnDecRes->setWithOverflow(p->nDouble); + break; + case SbxBYREF | SbxDATE: + case SbxBYREF | SbxDOUBLE: + pnDecRes->setWithOverflow(*p->pDouble); break; - } case SbxLPSTR: case SbxSTRING: case SbxBYREF | SbxSTRING: @@ -461,9 +495,7 @@ start: pnDecRes->setString( p->pOUString ); break; case SbxOBJECT: - { - SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) + if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj)) pnDecRes->setDecimal( pVal->GetDecimal() ); else { @@ -471,7 +503,6 @@ start: pnDecRes->setShort( 0 ); } break; - } case SbxBYREF | SbxCHAR: pnDecRes->setChar( *p->pChar ); break; @@ -488,21 +519,6 @@ start: case SbxBYREF | SbxUSHORT: pnDecRes->setUShort( *p->pUShort ); break; - // from here on had to be tested - case SbxBYREF | SbxSINGLE: - aTmp.nSingle = *p->pSingle; goto ref; - case SbxBYREF | SbxDATE: - case SbxBYREF | SbxDOUBLE: - aTmp.nDouble = *p->pDouble; goto ref; - case SbxBYREF | SbxCURRENCY: - case SbxBYREF | SbxSALINT64: - aTmp.nInt64 = *p->pnInt64; goto ref; - case SbxBYREF | SbxSALUINT64: - aTmp.uInt64 = *p->puInt64; goto ref; - ref: - aTmp.eType = SbxDataType( p->eType & 0x0FFF ); - p = &aTmp; goto start; - default: SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); pnDecRes->setShort( 0 ); } @@ -514,39 +530,69 @@ void ImpPutDecimal( SbxValues* p, SbxDecimal* pDec ) if( !pDec ) return; - SbxValues aTmp; -start: switch( +p->eType ) { - // here had to be tested case SbxCHAR: - aTmp.pChar = &p->nChar; goto direct; + assignWithOverflowTo(p->nChar, *pDec); + break; + case SbxBYREF | SbxCHAR: + assignWithOverflowTo(*p->pChar, *pDec); + break; case SbxBYTE: - aTmp.pByte = &p->nByte; goto direct; - case SbxULONG: - aTmp.pULong = &p->nULong; goto direct; - case SbxERROR: - case SbxUSHORT: - aTmp.pUShort = &p->nUShort; goto direct; + assignWithOverflowTo(p->nByte, *pDec); + break; + case SbxBYREF | SbxBYTE: + assignWithOverflowTo(*p->pByte, *pDec); + break; case SbxINTEGER: case SbxBOOL: - aTmp.pInteger = &p->nInteger; goto direct; + assignWithOverflowTo(p->nInteger, *pDec); + break; + case SbxBYREF | SbxINTEGER: + case SbxBYREF | SbxBOOL: + assignWithOverflowTo(*p->pInteger, *pDec); + break; + case SbxERROR: + case SbxUSHORT: + assignWithOverflowTo(p->nUShort, *pDec); + break; + case SbxBYREF | SbxERROR: + case SbxBYREF | SbxUSHORT: + assignWithOverflowTo(*p->pUShort, *pDec); + break; case SbxLONG: - aTmp.pLong = &p->nLong; goto direct; + assignWithOverflowTo(p->nLong, *pDec); + break; + case SbxBYREF | SbxLONG: + assignWithOverflowTo(*p->pLong, *pDec); + break; + case SbxULONG: + assignWithOverflowTo(p->nULong, *pDec); + break; + case SbxBYREF | SbxULONG: + assignWithOverflowTo(*p->pULong, *pDec); + break; case SbxCURRENCY: + p->nInt64 = CurFrom(pDec->getWithOverflow<double>()); + break; + case SbxBYREF | SbxCURRENCY: + *p->pnInt64 = CurFrom(pDec->getWithOverflow<double>()); + break; case SbxSALINT64: - aTmp.pnInt64 = &p->nInt64; goto direct; + assignWithOverflowTo(p->nInt64, *pDec); + break; + case SbxBYREF | SbxSALINT64: + assignWithOverflowTo(*p->pnInt64, *pDec); + break; case SbxSALUINT64: - aTmp.puInt64 = &p->uInt64; goto direct; - - direct: - aTmp.eType = SbxDataType( p->eType | SbxBYREF ); - p = &aTmp; goto start; + assignWithOverflowTo(p->uInt64, *pDec); + break; + case SbxBYREF | SbxSALUINT64: + assignWithOverflowTo(*p->puInt64, *pDec); + break; - // from here on no longer case SbxDECIMAL: case SbxBYREF | SbxDECIMAL: - { if( pDec != p->pDecimal ) { releaseDecimalPtr( p->pDecimal ); @@ -555,22 +601,20 @@ start: pDec->addRef(); } break; - } case SbxSINGLE: - { - float f(0.0); - pDec->getSingle( f ); - p->nSingle = f; + assignWithOverflowTo(p->nSingle, *pDec); + break; + case SbxBYREF | SbxSINGLE: + assignWithOverflowTo(*p->pSingle, *pDec); break; - } case SbxDATE: case SbxDOUBLE: - { - double d(0.0); - pDec->getDouble( d ); - p->nDouble = d; + assignWithOverflowTo(p->nDouble, *pDec); + break; + case SbxBYREF | SbxDATE: + case SbxBYREF | SbxDOUBLE: + assignWithOverflowTo(*p->pDouble, *pDec); break; - } case SbxLPSTR: case SbxSTRING: @@ -580,100 +624,12 @@ start: pDec->getString( *p->pOUString ); break; case SbxOBJECT: - { - SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) + if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj)) pVal->PutDecimal( pDec ); else SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); break; - } - case SbxBYREF | SbxCHAR: - if( !pDec->getChar( *p->pChar ) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - *p->pChar = 0; - } - break; - case SbxBYREF | SbxBYTE: - if( !pDec->getChar( *p->pChar ) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - *p->pByte = 0; - } - break; - case SbxBYREF | SbxINTEGER: - case SbxBYREF | SbxBOOL: - if( !pDec->getShort( *p->pInteger ) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - *p->pInteger = 0; - } - break; - case SbxBYREF | SbxERROR: - case SbxBYREF | SbxUSHORT: - if( !pDec->getUShort( *p->pUShort ) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - *p->pUShort = 0; - } - break; - case SbxBYREF | SbxLONG: - if( !pDec->getLong( *p->pLong ) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - *p->pLong = 0; - } - break; - case SbxBYREF | SbxULONG: - if( !pDec->getULong( *p->pULong ) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - *p->pULong = 0; - } - break; - case SbxBYREF | SbxCURRENCY: - { - double d(0.0); - if( !pDec->getDouble( d ) ) - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - *p->pnInt64 = ImpDoubleToCurrency( d ); - } - break; - case SbxBYREF | SbxSALINT64: - { - double d(0.0); - if( !pDec->getDouble( d ) ) - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - else - *p->pnInt64 = ImpDoubleToSalInt64( d ); - } - break; - case SbxBYREF | SbxSALUINT64: - { - double d(0.0); - if( !pDec->getDouble( d ) ) - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - else - *p->puInt64 = ImpDoubleToSalUInt64( d ); - } - break; - case SbxBYREF | SbxSINGLE: - if( !pDec->getSingle( *p->pSingle ) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - *p->pSingle = 0; - } - break; - case SbxBYREF | SbxDATE: - case SbxBYREF | SbxDOUBLE: - if( !pDec->getDouble( *p->pDouble ) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); - *p->pDouble = 0; - } - break; default: SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); } diff --git a/basic/source/sbx/sbxdec.hxx b/basic/source/sbx/sbxdec.hxx index 756fdc9f9273..a7af21fa4f28 100644 --- a/basic/source/sbx/sbxdec.hxx +++ b/basic/source/sbx/sbxdec.hxx @@ -55,8 +55,10 @@ public: void setByte( sal_uInt8 val ); void setShort( sal_Int16 val ); void setLong( sal_Int32 val ); + bool setHyper( sal_Int64 val ); void setUShort( sal_uInt16 val ); void setULong( sal_uInt32 val ); + bool setUHyper( sal_uInt64 val ); bool setSingle( float val ); bool setDouble( double val ); void setInt( int val ); @@ -72,15 +74,31 @@ public: #endif } + void setWithOverflow(float val) { HandleFailure(setSingle(val)); } + void setWithOverflow(double val) { HandleFailure(setDouble(val)); } + void setWithOverflow(sal_Int64 val) { HandleFailure(setHyper(val)); } + void setWithOverflow(sal_uInt64 val) { HandleFailure(setUHyper(val)); } + bool getChar( sal_Unicode& rVal ); + bool getByte( sal_uInt8& rVal ); bool getShort( sal_Int16& rVal ); bool getLong( sal_Int32& rVal ); + bool getHyper( sal_Int64& rVal ); bool getUShort( sal_uInt16& rVal ); bool getULong( sal_uInt32& rVal ); + bool getUHyper( sal_uInt64& rVal ); bool getSingle( float& rVal ); bool getDouble( double& rVal ); void getString( OUString& rString ); + // Only handles types, which have corresponding getWithOverflow_impl + template <typename T> T getWithOverflow() + { + T n = 0; + HandleFailure(getWithOverflow_impl(n)); + return n; + } + bool operator -= ( const SbxDecimal &r ); bool operator += ( const SbxDecimal &r ); bool operator /= ( const SbxDecimal &r ); @@ -92,6 +110,20 @@ public: // must match the return values of the Microsoft VarDecCmp Automation function enum class CmpResult { LT, EQ, GT }; friend CmpResult compare( const SbxDecimal &rLeft, const SbxDecimal &rRight ); + +private: + bool getWithOverflow_impl(sal_Unicode& n) { return getChar(n); } + bool getWithOverflow_impl(sal_uInt8& n) { return getByte(n); } + bool getWithOverflow_impl(sal_Int16& n) { return getShort(n); } + bool getWithOverflow_impl(sal_uInt16& n) { return getUShort(n); } + bool getWithOverflow_impl(sal_Int32& n) { return getLong(n); } + bool getWithOverflow_impl(sal_uInt32& n) { return getULong(n); } + bool getWithOverflow_impl(sal_Int64& n) { return getHyper(n); } + bool getWithOverflow_impl(sal_uInt64& n) { return getUHyper(n); } + bool getWithOverflow_impl(float& n) { return getSingle(n); } + bool getWithOverflow_impl(double& n) { return getDouble(n); } + + void HandleFailure(bool isSuccess); }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/basic/source/sbx/sbxint.cxx b/basic/source/sbx/sbxint.cxx index 6a6721eb7840..a0693635a302 100644 --- a/basic/source/sbx/sbxint.cxx +++ b/basic/source/sbx/sbxint.cxx @@ -19,786 +19,266 @@ #include <sal/config.h> +#include <config_features.h> + #include <o3tl/safeint.hxx> #include <comphelper/errcode.hxx> #include <basic/sberrors.hxx> #include "sbxconv.hxx" +#include <runtime.hxx> #include <rtl/math.hxx> -sal_Int16 ImpGetInteger( const SbxValues* p ) +namespace +{ +template <class T> +concept number = std::is_arithmetic_v<T>; + +template <SbxDataType MySbxType, number N> N ImpGet(const SbxValues* p) { - SbxValues aTmp; - sal_Int16 nRes; -start: - switch( +p->eType ) + switch (+p->eType) { - case SbxNULL: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); - [[fallthrough]]; case SbxEMPTY: - nRes = 0; break; + return 0; case SbxCHAR: - nRes = p->nChar; break; + return ConvertWithOverflowTo<N>(p->nChar); + case SbxBYREF | SbxCHAR: + return ConvertWithOverflowTo<N>(*p->pChar); case SbxBYTE: - nRes = p->nByte; break; + return ConvertWithOverflowTo<N>(p->nByte); + case SbxBYREF | SbxBYTE: + return ConvertWithOverflowTo<N>(*p->pByte); case SbxINTEGER: case SbxBOOL: - nRes = p->nInteger; break; + return ConvertWithOverflowTo<N>(p->nInteger); + case SbxBYREF | SbxINTEGER: + case SbxBYREF | SbxBOOL: + return ConvertWithOverflowTo<N>(*p->pInteger); case SbxERROR: case SbxUSHORT: - if( p->nUShort > o3tl::make_unsigned(SbxMAXINT) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT; - } - else - nRes = static_cast<sal_Int16>(p->nUShort); - break; + return ConvertWithOverflowTo<N>(p->nUShort); + case SbxBYREF | SbxERROR: + case SbxBYREF | SbxUSHORT: + return ConvertWithOverflowTo<N>(*p->pUShort); case SbxLONG: - if( p->nLong > SbxMAXINT ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT; - } - else if( p->nLong < SbxMININT ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMININT; - } - else - nRes = static_cast<sal_Int16>(p->nLong); - break; + return ConvertWithOverflowTo<N>(p->nLong); + case SbxBYREF | SbxLONG: + return ConvertWithOverflowTo<N>(*p->pLong); case SbxULONG: - if( p->nULong > SbxMAXINT ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT; - } - else - nRes = static_cast<sal_Int16>(p->nULong); - break; - case SbxSINGLE: - nRes = ImpDoubleToInteger(p->nSingle); - break; + return ConvertWithOverflowTo<N>(p->nULong); + case SbxBYREF | SbxULONG: + return ConvertWithOverflowTo<N>(*p->pULong); case SbxCURRENCY: - nRes = CurTo<sal_Int16>(p->nInt64); - break; + return CurTo<N>(p->nInt64); + case SbxBYREF | SbxCURRENCY: + return CurTo<N>(*p->pnInt64); case SbxSALINT64: - if( p->nInt64 > SbxMAXINT ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT; - } - else if( p->nInt64 < SbxMININT ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMININT; - } - else - nRes = static_cast<sal_Int16>(p->nInt64); - break; + return ConvertWithOverflowTo<N>(p->nInt64); + case SbxBYREF | SbxSALINT64: + return ConvertWithOverflowTo<N>(*p->pnInt64); case SbxSALUINT64: - if( p->uInt64 > SbxMAXINT ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT; - } - else - nRes = static_cast<sal_Int16>(p->uInt64); - break; + return ConvertWithOverflowTo<N>(p->uInt64); + case SbxBYREF | SbxSALUINT64: + return ConvertWithOverflowTo<N>(*p->puInt64); + case SbxSINGLE: + return ConvertWithOverflowTo<N>(p->nSingle); + case SbxBYREF | SbxSINGLE: + return ConvertWithOverflowTo<N>(*p->pSingle); case SbxDATE: case SbxDOUBLE: + return ConvertWithOverflowTo<N>(p->nDouble); + case SbxBYREF | SbxDATE: + case SbxBYREF | SbxDOUBLE: + return ConvertWithOverflowTo<N>(*p->pDouble); case SbxDECIMAL: case SbxBYREF | SbxDECIMAL: - { - double dVal = 0.0; - if( p->eType == SbxDECIMAL ) - { - if( p->pDecimal ) - p->pDecimal->getDouble( dVal ); - } - else - dVal = p->nDouble; - - nRes = ImpDoubleToInteger(dVal); - break; - } - case SbxLPSTR: - case SbxSTRING: + if (p->pDecimal) + return p->pDecimal->getWithOverflow<N>(); + return 0; case SbxBYREF | SbxSTRING: - if( !p->pOUString ) - nRes = 0; - else + case SbxSTRING: + case SbxLPSTR: + if (p->pOUString) { double d; SbxDataType t; - if( ImpScan( *p->pOUString, d, t, nullptr ) != ERRCODE_NONE ) - nRes = 0; - else - nRes = ImpDoubleToInteger(d); - } - break; + if (ImpScan(*p->pOUString, d, t, nullptr) == ERRCODE_NONE) + return ConvertWithOverflowTo<N>(d); + } +#if HAVE_FEATURE_SCRIPTING + if (SbiRuntime::isVBAEnabled()) // VBA only behaviour + SbxBase::SetError(ERRCODE_BASIC_CONVERSION); +#endif + return 0; case SbxOBJECT: - { - SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) - nRes = pVal->GetInteger(); - else + if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj)) { - SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0; + SbxValues aObjVal(MySbxType); + pVal->Get(aObjVal); + return ImpGet<MySbxType, N>(&aObjVal); } - break; - } - - case SbxBYREF | SbxCHAR: - nRes = *p->pChar; break; - case SbxBYREF | SbxBYTE: - nRes = *p->pByte; break; - case SbxBYREF | SbxINTEGER: - case SbxBYREF | SbxBOOL: - nRes = *p->pInteger; break; - - // from here had to be tested - case SbxBYREF | SbxLONG: - aTmp.nLong = *p->pLong; goto ref; - case SbxBYREF | SbxULONG: - aTmp.nULong = *p->pULong; goto ref; - case SbxBYREF | SbxERROR: - case SbxBYREF | SbxUSHORT: - aTmp.nUShort = *p->pUShort; goto ref; - case SbxBYREF | SbxSINGLE: - aTmp.nSingle = *p->pSingle; goto ref; - case SbxBYREF | SbxDATE: - case SbxBYREF | SbxDOUBLE: - aTmp.nDouble = *p->pDouble; goto ref; - case SbxBYREF | SbxCURRENCY: - case SbxBYREF | SbxSALINT64: - aTmp.nInt64 = *p->pnInt64; goto ref; - case SbxBYREF | SbxSALUINT64: - aTmp.uInt64 = *p->puInt64; goto ref; - ref: - aTmp.eType = SbxDataType( p->eType & 0x0FFF ); - p = &aTmp; goto start; + SbxBase::SetError(ERRCODE_BASIC_NO_OBJECT); + return 0; default: - SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0; + SbxBase::SetError(ERRCODE_BASIC_CONVERSION); + return 0; } - return nRes; } -void ImpPutInteger( SbxValues* p, sal_Int16 n ) +template <typename T> void assignTo(SbxDecimal& dest, T n); // not defined +template <> void assignTo<sal_uInt8>(SbxDecimal& dest, sal_uInt8 n) { dest.setByte(n); } +template <> void assignTo<sal_Unicode>(SbxDecimal& dest, sal_Unicode n) { dest.setChar(n); } +template <> void assignTo<sal_Int16>(SbxDecimal& dest, sal_Int16 n) { dest.setShort(n); } +template <> void assignTo<sal_uInt16>(SbxDecimal& dest, sal_uInt16 n) { dest.setUShort(n); } +template <> void assignTo<sal_Int32>(SbxDecimal& dest, sal_Int32 n) { dest.setLong(n); } +template <> void assignTo<sal_uInt32>(SbxDecimal& dest, sal_uInt32 n) { dest.setULong(n); } +template <> void assignTo<sal_Int64>(SbxDecimal& dest, sal_Int64 n) { dest.setWithOverflow(n); } +template <> void assignTo<sal_uInt64>(SbxDecimal& dest, sal_uInt64 n) { dest.setWithOverflow(n); } +template <> void assignTo<double>(SbxDecimal& dest, double n) { dest.setWithOverflow(n); } +template <> void assignTo<float>(SbxDecimal& dest, float n) { dest.setWithOverflow(n); } + +template <std::integral I> void assignTo(OUString& dest, I n, bool) { dest = OUString::number(n); } +void assignTo(OUString& dest, double n, bool bCoreString) { - SbxValues aTmp; -start: - switch( +p->eType ) - { - // here had to be tested - case SbxCHAR: - aTmp.pChar = &p->nChar; goto direct; - case SbxBYTE: - aTmp.pByte = &p->nByte; goto direct; - case SbxULONG: - aTmp.pULong = &p->nULong; goto direct; - case SbxERROR: - case SbxUSHORT: - aTmp.pUShort = &p->nUShort; goto direct; - case SbxSALUINT64: - aTmp.puInt64 = &p->uInt64; goto direct; - direct: - aTmp.eType = SbxDataType( p->eType | SbxBYREF ); - p = &aTmp; goto start; - - // from here no tests needed - case SbxINTEGER: - case SbxBOOL: - p->nInteger = n; break; - case SbxLONG: - p->nLong = n; break; - case SbxSINGLE: - p->nSingle = n; break; - case SbxDATE: - case SbxDOUBLE: - p->nDouble = n; break; - case SbxCURRENCY: - p->nInt64 = CurFrom(n); break; - case SbxSALINT64: - p->nInt64 = n; break; - case SbxDECIMAL: - case SbxBYREF | SbxDECIMAL: - ImpCreateDecimal( p )->setInt( n ); - break; - - case SbxLPSTR: - case SbxSTRING: - case SbxBYREF | SbxSTRING: - if( !p->pOUString ) - p->pOUString = new OUString; - ImpCvtNum( static_cast<double>(n), 0, *p->pOUString ); - break; - case SbxOBJECT: - { - SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); - if( pVal ) - pVal->PutInteger( n ); - else - SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); - break; - } - case SbxBYREF | SbxCHAR: - if( n < SbxMINCHAR ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINCHAR; - } - *p->pChar = static_cast<char>(n); break; - case SbxBYREF | SbxBYTE: - if( n > SbxMAXBYTE ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXBYTE; - } - else if( n < 0 ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0; - } - *p->pByte = static_cast<sal_uInt8>(n); break; - case SbxBYREF | SbxINTEGER: - case SbxBYREF | SbxBOOL: - *p->pInteger = n; break; - case SbxBYREF | SbxERROR: - case SbxBYREF | SbxUSHORT: - if( n < 0 ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0; - } - *p->pUShort = static_cast<sal_uInt16>(n); break; - case SbxBYREF | SbxLONG: - *p->pLong = static_cast<sal_Int32>(n); break; - case SbxBYREF | SbxULONG: - if( n < 0 ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0; - } - *p->pULong = static_cast<sal_uInt32>(n); break; - case SbxBYREF | SbxCURRENCY: - *p->pnInt64 = CurFrom(n); break; - case SbxBYREF | SbxSALINT64: - *p->pnInt64 = n; break; -e ... etc. - the rest is truncated