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.kaganski@collabora.com>
This commit is contained in:
Mike Kaganski
2025-06-07 12:30:17 +02:00
parent 2f16890daf
commit 2143c0a694
15 changed files with 686 additions and 3309 deletions
-7
View File
@@ -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 \
))
+92 -109
View File
@@ -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 SbxLONG:
p->nLong = n; break;
case SbxULONG:
p->nULong = static_cast<sal_uInt32>(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 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 );
}
-309
View File
@@ -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: */
-295
View File
@@ -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: */
+91 -72
View File
@@ -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)
{
return DoubleTo<sal_Int64>(d, SAL_MIN_INT64, SAL_MAX_INT64);
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)
{
// 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* );
+43 -79
View File
@@ -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 );
}
+104 -174
View File
@@ -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;
-265
View File
@@ -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: */
+126 -170
View File
@@ -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;
assignWithOverflowTo(p->uInt64, *pDec);
break;
case SbxBYREF | SbxSALUINT64:
assignWithOverflowTo(*p->puInt64, *pDec);
break;
direct:
aTmp.eType = SbxDataType( p->eType | SbxBYREF );
p = &aTmp; goto start;
// 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 );
}
+32
View File
@@ -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: */
+198 -718
View File
@@ -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
{
SbxValues aTmp;
sal_Int16 nRes;
start:
switch( +p->eType )
template <class T>
concept number = std::is_arithmetic_v<T>;
template <SbxDataType MySbxType, number N> N ImpGet(const SbxValues* p)
{
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);
if (ImpScan(*p->pOUString, d, t, nullptr) == ERRCODE_NONE)
return ConvertWithOverflowTo<N>(d);
}
break;
#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 )
{
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;
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); }
// from here no tests needed
template <std::integral I> void assignTo(OUString& dest, I n, bool) { dest = OUString::number(n); }
void assignTo(OUString& dest, double n, bool bCoreString)
{
// tdf#107953 - show 17 significant digits
ImpCvtNum(n, 17, dest, bCoreString);
}
void assignTo(OUString& dest, float n, bool)
{
// tdf#107953 - show 9 significant digits
ImpCvtNum(n, 9, dest);
}
template <SbxDataType MySbxType, number N> void ImpPut(SbxValues* p, N n, bool bCoreString)
{
switch (+p->eType)
{
case SbxCHAR:
assignWithOverflowTo(p->nChar, n);
break;
case SbxBYREF | SbxCHAR:
assignWithOverflowTo(*p->pChar, n);
break;
case SbxBYTE:
assignWithOverflowTo(p->nByte, n);
break;
case SbxBYREF | SbxBYTE:
assignWithOverflowTo(*p->pByte, n);
break;
case SbxINTEGER:
case SbxBOOL:
p->nInteger = n; break;
assignWithOverflowTo(p->nInteger, n);
break;
case SbxBYREF | SbxINTEGER:
case SbxBYREF | SbxBOOL:
assignWithOverflowTo(*p->pInteger, n);
break;
case SbxERROR:
case SbxUSHORT:
assignWithOverflowTo(p->nUShort, n);
break;
case SbxBYREF | SbxERROR:
case SbxBYREF | SbxUSHORT:
assignWithOverflowTo(*p->pUShort, n);
break;
case SbxLONG:
p->nLong = n; break;
case SbxSINGLE:
p->nSingle = n; break;
case SbxDATE:
case SbxDOUBLE:
p->nDouble = n; break;
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:
p->nInt64 = CurFrom(n); break;
assignWithOverflowTo(p->nInt64, CurFrom(n));
break;
case SbxBYREF | SbxCURRENCY:
assignWithOverflowTo(*p->pnInt64, CurFrom(n));
break;
case SbxSALINT64:
p->nInt64 = n; break;
assignWithOverflowTo(p->nInt64, n);
break;
case SbxBYREF | SbxSALINT64:
assignWithOverflowTo(*p->pnInt64, n);
break;
case SbxSALUINT64:
assignWithOverflowTo(p->uInt64, n);
break;
case SbxBYREF | SbxSALUINT64:
assignWithOverflowTo(*p->puInt64, n);
break;
case SbxDECIMAL:
case SbxBYREF | SbxDECIMAL:
ImpCreateDecimal( p )->setInt( n );
assignTo(*ImpCreateDecimal(p), n);
break;
case SbxSINGLE:
assignWithOverflowTo(p->nSingle, n);
break;
case SbxBYREF | SbxSINGLE:
assignWithOverflowTo(*p->pSingle, n);
break;
case SbxDATE:
case SbxDOUBLE:
assignWithOverflowTo(p->nDouble, n);
break;
case SbxBYREF | SbxDATE:
case SbxBYREF | SbxDOUBLE:
assignWithOverflowTo(*p->pDouble, n);
break;
case SbxLPSTR:
case SbxSTRING:
case SbxBYREF | SbxSTRING:
if( !p->pOUString )
case SbxSTRING:
case SbxLPSTR:
if (!p->pOUString)
p->pOUString = new OUString;
ImpCvtNum( static_cast<double>(n), 0, *p->pOUString );
assignTo(*p->pOUString, n, bCoreString);
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 )
if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj))
{
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;
case SbxBYREF | SbxSALUINT64:
if( n < 0 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
*p->puInt64 = 0;
SbxValues newVal(MySbxType);
ImpPut<MySbxType, N>(&newVal, n, bCoreString);
pVal->Put(newVal);
}
else
*p->puInt64 = n;
SbxBase::SetError(ERRCODE_BASIC_NO_OBJECT);
break;
case SbxBYREF | SbxSINGLE:
*p->pSingle = static_cast<float>(n); break;
case SbxBYREF | SbxDATE:
case SbxBYREF | SbxDOUBLE:
*p->pDouble = static_cast<double>(n); break;
default:
SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
SbxBase::SetError(ERRCODE_BASIC_CONVERSION);
}
}
// sal_Int64 / hyper
double ImpSalUInt64ToDouble( sal_uInt64 n )
{
double d = 0.0;
if( n > SAL_MAX_INT64 )
SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
else
d = static_cast<double>(static_cast<sal_Int64>(n));
return d;
}
sal_Unicode ImpGetChar(const SbxValues* p) { return ImpGet<SbxCHAR, sal_Unicode>(p); }
sal_uInt8 ImpGetByte(const SbxValues* p) { return ImpGet<SbxBYTE, sal_uInt8>(p); }
sal_Int16 ImpGetInteger(const SbxValues* p) { return ImpGet<SbxINTEGER, sal_Int16>(p); }
sal_uInt16 ImpGetUShort(const SbxValues* p) { return ImpGet<SbxUSHORT, sal_uInt16>(p); }
sal_Int32 ImpGetLong(const SbxValues* p) { return ImpGet<SbxLONG, sal_Int32>(p); }
sal_uInt32 ImpGetULong(const SbxValues* p) { return ImpGet<SbxULONG, sal_uInt32>(p); }
sal_Int64 ImpGetInt64(const SbxValues* p) { return ImpGet<SbxSALINT64, sal_Int64>(p); }
sal_uInt64 ImpGetUInt64(const SbxValues* p) { return ImpGet<SbxSALUINT64, sal_uInt64>(p); }
double ImpGetDouble(const SbxValues* p) { return ImpGet<SbxDOUBLE, double>(p); }
float ImpGetSingle(const SbxValues* p) { return ImpGet<SbxSINGLE, float>(p); }
sal_Int64 ImpGetInt64( const SbxValues* p )
{
SbxValues aTmp;
sal_Int64 nRes;
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 = p->nByte; break;
case SbxINTEGER:
case SbxBOOL:
nRes = p->nInteger; break;
case SbxERROR:
case SbxUSHORT:
nRes = static_cast<sal_Int64>(p->nUShort); break;
case SbxLONG:
nRes = static_cast<sal_Int64>(p->nLong); break;
case SbxULONG:
nRes = static_cast<sal_Int64>(p->nULong); break;
case SbxSINGLE:
nRes = ImpDoubleToSalInt64(p->nSingle);
break;
case SbxDATE:
case SbxDOUBLE:
nRes = ImpDoubleToSalInt64(p->nDouble);
break;
case SbxCURRENCY:
nRes = CurTo<sal_Int64>(p->nInt64); break;
case SbxSALINT64:
nRes = p->nInt64; break;
case SbxSALUINT64:
if( p->uInt64 > SAL_MAX_INT64 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SAL_MAX_INT64;
}
else
nRes = static_cast<sal_Int64>(p->uInt64);
break;
case SbxBYREF | SbxSTRING:
case SbxSTRING:
case SbxLPSTR:
if( !p->pOUString )
nRes = 0;
else
{
nRes = p->pOUString->toInt64();
if( nRes == 0 )
{
// Check if really 0 or invalid conversion
double d;
SbxDataType t;
if( ImpScan( *p->pOUString, d, t, nullptr ) != ERRCODE_NONE )
nRes = 0;
else
nRes = ImpDoubleToSalInt64(d);
}
}
break;
case SbxOBJECT:
{
SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
if( pVal )
nRes = pVal->GetInt64();
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 | SbxCURRENCY:
nRes = CurTo<sal_Int64>(*p->pnInt64); break;
case SbxBYREF | SbxSALINT64:
nRes = *p->pnInt64; break;
// from here the values has to be checked
case SbxBYREF | SbxSALUINT64:
aTmp.uInt64 = *p->puInt64; 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;
ref:
aTmp.eType = SbxDataType( p->eType & 0x0FFF );
p = &aTmp; goto start;
default:
SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0;
}
return nRes;
}
void ImpPutInt64( SbxValues* p, sal_Int64 n )
{
SbxValues aTmp;
start:
switch( +p->eType )
{
// Check 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 SbxULONG:
aTmp.pULong = &p->nULong; goto direct;
case SbxERROR:
case SbxUSHORT:
aTmp.pUShort = &p->nUShort; goto direct;
case SbxLONG:
aTmp.pnInt64 = &p->nInt64; goto direct;
case SbxCURRENCY:
case SbxSALINT64:
aTmp.pnInt64 = &p->nInt64; goto direct;
case SbxSALUINT64:
aTmp.puInt64 = &p->uInt64; goto direct;
direct:
aTmp.eType = SbxDataType( p->eType | SbxBYREF );
p = &aTmp; goto start;
case SbxSINGLE:
p->nSingle = static_cast<float>(n); break;
case SbxDATE:
case SbxDOUBLE:
p->nDouble = static_cast<double>(n); break;
case SbxBYREF | SbxSTRING:
case SbxSTRING:
case SbxLPSTR:
{
if( !p->pOUString )
p->pOUString = new OUString;
(*p->pOUString) = OUString::number(n);
break;
}
case SbxOBJECT:
{
SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
if( pVal )
pVal->PutInt64( n );
else
SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
break;
}
case SbxBYREF | SbxCHAR:
if( n > SbxMAXCHAR )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXCHAR;
}
else if( n < SbxMINCHAR )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINCHAR;
}
*p->pChar = static_cast<sal_Unicode>(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:
if( n > SbxMAXINT )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXINT;
}
else if( n < SbxMININT )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMININT;
}
*p->pInteger = static_cast<sal_Int16>(n); break;
case SbxBYREF | SbxERROR:
case SbxBYREF | SbxUSHORT:
if( n > SbxMAXUINT )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXUINT;
}
else if( n < 0 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
}
*p->pUShort = static_cast<sal_uInt16>(n); break;
case SbxBYREF | SbxLONG:
if( n > SbxMAXLNG )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXLNG;
}
else if( n < SbxMINLNG )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINLNG;
}
*p->pLong = static_cast<sal_Int32>(n); break;
case SbxBYREF | SbxULONG:
if( n > SbxMAXULNG )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXULNG;
}
else if( n < 0 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
}
*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->pnInt64 = CurFrom(n); break;
case SbxBYREF | SbxSALINT64:
*p->pnInt64 = n; break;
case SbxBYREF | SbxSALUINT64:
if( n < 0 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
}
*p->puInt64 = n; break;
default:
SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
}
}
sal_uInt64 ImpGetUInt64( const SbxValues* p )
{
SbxValues aTmp;
sal_uInt64 nRes;
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 = 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 = static_cast<sal_uInt64>(p->nULong); break;
case SbxSINGLE:
nRes = ImpDoubleToSalUInt64(p->nSingle); break;
case SbxDATE:
case SbxDOUBLE:
nRes = ImpDoubleToSalUInt64(p->nDouble);
break;
case SbxCURRENCY:
nRes = CurFrom(p->nInt64); break;
case SbxSALINT64:
if( p->nInt64 < 0 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
}
else
nRes = static_cast<sal_uInt64>(p->nInt64);
break;
case SbxSALUINT64:
nRes = p->uInt64; break;
case SbxBYREF | SbxSTRING:
case SbxSTRING:
case SbxLPSTR:
if( !p->pOUString )
nRes = 0;
else
{
nRes = p->pOUString->toUInt64();
if( nRes == 0 )
{
// Check if really 0 or invalid conversion
double d;
SbxDataType t;
if( ImpScan( *p->pOUString, d, t, nullptr ) != ERRCODE_NONE )
nRes = 0;
else
nRes = ImpDoubleToSalUInt64(d);
}
}
break;
case SbxOBJECT:
{
SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
if( pVal )
nRes = pVal->GetUInt64();
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 | SbxSALUINT64:
nRes = *p->puInt64; break;
// from here on the value has to be checked
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;
ref:
aTmp.eType = SbxDataType( p->eType & 0x0FFF );
p = &aTmp; goto start;
default:
SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0;
}
return nRes;
}
void ImpPutUInt64( SbxValues* p, sal_uInt64 n )
{
SbxValues aTmp;
start:
switch( +p->eType )
{
// Check 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 SbxULONG:
aTmp.pULong = &p->nULong; goto direct;
case SbxERROR:
case SbxUSHORT:
aTmp.pUShort = &p->nUShort; goto direct;
case SbxLONG:
aTmp.pnInt64 = &p->nInt64; goto direct;
case SbxCURRENCY:
case SbxSALINT64:
aTmp.pnInt64 = &p->nInt64; goto direct;
case SbxSINGLE:
aTmp.pSingle = &p->nSingle; goto direct;
case SbxDATE:
case SbxDOUBLE:
aTmp.pDouble = &p->nDouble; goto direct;
direct:
aTmp.eType = SbxDataType( p->eType | SbxBYREF );
p = &aTmp; goto start;
// Check not necessary
case SbxSALUINT64:
p->uInt64 = n; break;
case SbxBYREF | SbxSTRING:
case SbxSTRING:
case SbxLPSTR:
if( !p->pOUString )
p->pOUString = new OUString;
if( n > SAL_MAX_INT64 )
SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
else
{
(*p->pOUString) = OUString::number(n);
}
break;
case SbxOBJECT:
{
SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
if( pVal )
pVal->PutUInt64( n );
else
SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
break;
}
case SbxBYREF | SbxCHAR:
if( n > SbxMAXCHAR )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXCHAR;
}
*p->pChar = static_cast<sal_Unicode>(n); break;
case SbxBYREF | SbxBYTE:
if( n > SbxMAXBYTE )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXBYTE;
}
*p->pByte = static_cast<sal_uInt8>(n); break;
case SbxBYREF | SbxINTEGER:
case SbxBYREF | SbxBOOL:
if( n > SbxMAXINT )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXINT;
}
*p->pInteger = static_cast<sal_Int16>(n); break;
case SbxBYREF | SbxERROR:
case SbxBYREF | SbxUSHORT:
if( n > SbxMAXUINT )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXUINT;
}
*p->pUShort = static_cast<sal_uInt16>(n); break;
case SbxBYREF | SbxLONG:
if( n > SbxMAXLNG )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXLNG;
}
*p->pLong = static_cast<sal_Int32>(n); break;
case SbxBYREF | SbxULONG:
if( n > SbxMAXULNG )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXULNG;
}
*p->pULong = static_cast<sal_uInt32>(n); break;
case SbxBYREF | SbxSINGLE:
*p->pDouble = static_cast<float>(ImpSalUInt64ToDouble( n )); break;
case SbxBYREF | SbxDATE:
case SbxBYREF | SbxDOUBLE:
*p->pDouble = ImpSalUInt64ToDouble( n ); break;
case SbxBYREF | SbxCURRENCY:
*p->pnInt64 = CurFrom(n);
break;
case SbxBYREF | SbxSALUINT64:
*p->puInt64 = n; break;
case SbxBYREF | SbxSALINT64:
if( n > SAL_MAX_INT64 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
}
*p->pnInt64 = static_cast<sal_Int64>(n); break;
default:
SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
}
}
void ImpPutChar(SbxValues* p, sal_Unicode n) { ImpPut<SbxCHAR>(p, n, false); }
void ImpPutByte(SbxValues* p, sal_uInt8 n) { ImpPut<SbxBYTE>(p, n, false); }
void ImpPutInteger(SbxValues* p, sal_Int16 n) { ImpPut<SbxINTEGER>(p, n, false); }
void ImpPutUShort(SbxValues* p, sal_uInt16 n) { ImpPut<SbxUSHORT>(p, n, false); }
void ImpPutLong(SbxValues* p, sal_Int32 n) { ImpPut<SbxLONG>(p, n, false); }
void ImpPutULong(SbxValues* p, sal_uInt32 n) { ImpPut<SbxULONG>(p, n, false); }
void ImpPutInt64(SbxValues* p, sal_Int64 n) { ImpPut<SbxSALINT64>(p, n, false); }
void ImpPutUInt64(SbxValues* p, sal_uInt64 n) { ImpPut<SbxSALUINT64>(p, n, false); }
void ImpPutDouble(SbxValues* p, double n, bool bCoreString) { ImpPut<SbxDOUBLE>(p, n, bCoreString); }
void ImpPutSingle(SbxValues* p, float n) { ImpPut<SbxSINGLE>(p, n, false); }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-285
View File
@@ -1,285 +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 <comphelper/errcode.hxx>
#include <basic/sberrors.hxx>
#include "sbxconv.hxx"
#include <rtl/math.hxx>
sal_Int32 ImpGetLong( const SbxValues* p )
{
SbxValues aTmp;
sal_Int32 nRes;
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 = 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:
if( p->nULong > SbxMAXLNG )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXLNG;
}
else
nRes = static_cast<sal_Int32>(p->nULong);
break;
case SbxSINGLE:
nRes = ImpDoubleToLong(p->nSingle);
break;
case SbxSALINT64:
nRes = p->nInt64;
break;
case SbxSALUINT64:
nRes = p->uInt64;
break;
case SbxCURRENCY:
nRes = CurTo<sal_Int32>(p->nInt64);
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;
nRes = ImpDoubleToLong(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
nRes = ImpDoubleToLong(d);
}
break;
case SbxOBJECT:
{
SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
if( pVal )
nRes = pVal->GetLong();
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;
// from here had to be tested
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 ImpPutLong( SbxValues* p, sal_Int32 n )
{
SbxValues aTmp;
start:
switch( +p->eType )
{
// From here had to be tested
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 SbxULONG:
aTmp.pULong = &p->nULong; goto direct;
case SbxSALUINT64:
aTmp.puInt64 = &p->uInt64; goto direct;
case SbxERROR:
case SbxUSHORT:
aTmp.pUShort = &p->nUShort;
direct:
aTmp.eType = SbxDataType( p->eType | SbxBYREF );
p = &aTmp; goto start;
// from here no longer
case SbxLONG:
p->nLong = n; break;
case SbxSINGLE:
p->nSingle = static_cast<float>(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 )->setLong( 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->PutLong( n );
else
SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
break;
}
case SbxBYREF | SbxCHAR:
if( n > SbxMAXCHAR )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXCHAR;
}
else if( n < SbxMINCHAR )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINCHAR;
}
*p->pChar = static_cast<sal_Unicode>(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:
if( n > SbxMAXINT )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXINT;
}
else if( n < SbxMININT )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMININT;
}
*p->pInteger = static_cast<sal_Int16>(n); break;
case SbxBYREF | SbxERROR:
case SbxBYREF | SbxUSHORT:
if( n > SbxMAXUINT )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXUINT;
}
else if( n < 0 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
}
*p->pUShort = static_cast<sal_uInt16>(n); break;
case SbxBYREF | SbxLONG:
*p->pLong = 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 | SbxSALINT64:
*p->pnInt64 = n; break;
case SbxBYREF | SbxSALUINT64:
if( n < 0 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); *p->puInt64 = 0;
}
else
*p->puInt64 = 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->pnInt64 = CurFrom(n); break;
default:
SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-279
View File
@@ -1,279 +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 <comphelper/errcode.hxx>
#include <basic/sberrors.hxx>
#include "sbxconv.hxx"
float ImpGetSingle( const SbxValues* p )
{
SbxValues aTmp;
float nRes;
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 = p->nByte; break;
case SbxINTEGER:
case SbxBOOL:
nRes = p->nInteger; break;
case SbxERROR:
case SbxUSHORT:
nRes = p->nUShort; break;
case SbxLONG:
nRes = static_cast<float>(p->nLong); break;
case SbxULONG:
nRes = static_cast<float>(p->nULong); break;
case SbxSINGLE:
nRes = p->nSingle; break;
case SbxDECIMAL:
case SbxBYREF | SbxDECIMAL:
if (!p->pDecimal || !p->pDecimal->getSingle(nRes))
nRes = 0.0;
break;
case SbxDATE:
case SbxDOUBLE:
case SbxCURRENCY:
case SbxSALINT64:
case SbxSALUINT64:
{
double dVal;
if( p->eType == SbxCURRENCY )
dVal = ImpCurrencyToDouble( p->nInt64 );
else if( p->eType == SbxSALINT64 )
dVal = static_cast<float>(p->nInt64);
else if( p->eType == SbxSALUINT64 )
dVal = static_cast<float>(p->uInt64);
else
dVal = p->nDouble;
if( dVal > SbxMAXSNG )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
nRes = static_cast< float >(SbxMAXSNG);
}
else if( dVal < SbxMINSNG )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
nRes = static_cast< float >(SbxMINSNG);
}
// tests for underflow - storing value too small for precision of single
else if( dVal > 0 && dVal < SbxMAXSNG2 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
nRes = static_cast< float >(SbxMAXSNG2);
}
else if( dVal < 0 && dVal > SbxMINSNG2 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
nRes = static_cast< float >(SbxMINSNG2);
}
else
nRes = static_cast<float>(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 > SbxMAXSNG )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
nRes = static_cast< float >(SbxMAXSNG);
}
else if( d < SbxMINSNG )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
nRes = static_cast< float >(SbxMINSNG);
}
else
nRes = static_cast<float>(d);
}
break;
case SbxOBJECT:
{
SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
if( pVal )
nRes = pVal->GetSingle();
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 = static_cast<float>(*p->pLong); break;
case SbxBYREF | SbxULONG:
nRes = static_cast<float>(*p->pULong); break;
case SbxBYREF | SbxERROR:
case SbxBYREF | SbxUSHORT:
nRes = *p->pUShort; break;
case SbxBYREF | SbxSINGLE:
nRes = *p->pSingle; break;
// from here had to be tested
case SbxBYREF | SbxDATE:
case SbxBYREF | SbxDOUBLE:
aTmp.nDouble = *p->pDouble; goto ref;
case SbxBYREF | SbxSALINT64:
case SbxBYREF | SbxCURRENCY:
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 ImpPutSingle( SbxValues* p, float n )
{
SbxValues aTmp;
start:
switch( +p->eType )
{
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 SbxCURRENCY:
case SbxSALINT64:
aTmp.pnInt64 = &p->nInt64; goto direct;
case SbxSALUINT64:
aTmp.puInt64 = &p->uInt64; goto direct;
case SbxDECIMAL:
case SbxBYREF | SbxDECIMAL:
{
SbxDecimal* pDec = ImpCreateDecimal( p );
if( !pDec->setSingle( n ) )
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
break;
}
direct:
aTmp.eType = SbxDataType( p->eType | SbxBYREF );
p = &aTmp; goto start;
// from here no tests
case SbxSINGLE:
p->nSingle = 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 9 significant digits
ImpCvtNum( static_cast<double>(n), 9, *p->pOUString );
break;
}
case SbxOBJECT:
{
SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
if( pVal )
pVal->PutSingle( 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:
*p->pSingle = n; break;
case SbxBYREF | SbxDATE:
case SbxBYREF | SbxDOUBLE:
*p->pDouble = static_cast<double>(n); break;
case SbxBYREF | SbxSALINT64:
*p->pnInt64 = ImpDoubleToSalInt64(n); break;
case SbxBYREF | SbxSALUINT64:
*p->puInt64 = ImpDoubleToSalUInt64(n); break;
case SbxBYREF | SbxCURRENCY:
double d;
if( n > SbxMAXCURR )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); d = SbxMAXCURR;
}
else if( n < SbxMINCURR )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); d = SbxMINCURR;
}
else
{
d = n;
}
*p->pnInt64 = ImpDoubleToCurrency( d ); break;
default:
SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-281
View File
@@ -1,281 +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 <comphelper/errcode.hxx>
#include <basic/sberrors.hxx>
#include "sbxconv.hxx"
sal_uInt16 ImpGetUShort( const SbxValues* p )
{
SbxValues aTmp;
sal_uInt16 nRes;
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 = p->nByte; break;
case SbxINTEGER:
case SbxBOOL:
if( p->nInteger < 0 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
}
else
nRes = p->nInteger;
break;
case SbxERROR:
case SbxUSHORT:
nRes = p->nUShort;
break;
case SbxLONG:
if( p->nLong > SbxMAXUINT )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXUINT;
}
else if( p->nLong < 0 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
}
else
nRes = static_cast<sal_uInt16>(p->nLong);
break;
case SbxULONG:
if( p->nULong > SbxMAXUINT )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXUINT;
}
else
nRes = static_cast<sal_uInt16>(p->nULong);
break;
case SbxCURRENCY:
nRes = CurTo<sal_uInt16>(p->nInt64);
break;
case SbxSALINT64:
if( p->nInt64 > SbxMAXUINT )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXUINT;
}
else if( p->nInt64 < 0 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
}
else
nRes = static_cast<sal_uInt16>(p->nInt64);
break;
case SbxSALUINT64:
if( p->uInt64 > SbxMAXUINT )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXUINT;
}
else
nRes = static_cast<sal_uInt16>(p->uInt64);
break;
case SbxSINGLE:
nRes = ImpDoubleToUShort(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;
nRes = ImpDoubleToUShort(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
nRes = ImpDoubleToUShort(d);
}
break;
case SbxOBJECT:
{
SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
if( pVal )
nRes = pVal->GetUShort();
else
{
SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0;
}
break;
}
case SbxBYREF | SbxBYTE:
nRes = *p->pByte; break;
case SbxBYREF | SbxERROR:
case SbxBYREF | SbxUSHORT:
nRes = *p->pUShort; 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 | 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 ImpPutUShort( SbxValues* p, sal_uInt16 n )
{
SbxValues aTmp;
start:
switch( +p->eType )
{
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 )->setUInt( n );
break;
// from here on tests
case SbxCHAR:
aTmp.pChar = &p->nChar; goto direct;
case SbxBYTE:
aTmp.pByte = &p->nByte; goto direct;
case SbxINTEGER:
case SbxBOOL:
aTmp.pInteger = &p->nInteger;
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;
ImpCvtNum( static_cast<double>(n), 0, *p->pOUString );
break;
case SbxOBJECT:
{
SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
if( pVal )
pVal->PutUShort( n );
else
SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
break;
}
case SbxBYREF | SbxCHAR:
*p->pChar = static_cast<sal_Unicode>(n); break;
case SbxBYREF | SbxBYTE:
if( n > SbxMAXBYTE )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXBYTE;
}
*p->pByte = static_cast<sal_uInt8>(n); break;
case SbxBYREF | SbxINTEGER:
case SbxBYREF | SbxBOOL:
if( n > SbxMAXINT )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXINT;
}
*p->pInteger = static_cast<sal_Int16>(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->pnInt64 = 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: */
-266
View File
@@ -1,266 +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 <comphelper/errcode.hxx>
#include <basic/sberrors.hxx>
#include "sbxconv.hxx"
sal_uInt32 ImpGetULong( const SbxValues* p )
{
SbxValues aTmp;
sal_uInt32 nRes;
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 = p->nByte; break;
case SbxINTEGER:
case SbxBOOL:
if( p->nInteger < 0 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
}
else
nRes = p->nInteger;
break;
case SbxERROR:
case SbxUSHORT:
nRes = p->nUShort;
break;
case SbxLONG:
if( p->nLong < 0 )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
}
else
nRes = p->nLong;
break;
case SbxULONG:
nRes = p->nULong; break;
case SbxSINGLE:
nRes = ImpDoubleToULong(p->nSingle);
break;
case SbxDATE:
case SbxDOUBLE:
case SbxSALINT64:
case SbxSALUINT64:
case SbxCURRENCY:
case SbxDECIMAL:
case SbxBYREF | SbxDECIMAL:
{
double dVal;
if( p->eType == SbxCURRENCY )
dVal = ImpCurrencyToDouble( p->nInt64 );
else if( p->eType == SbxSALINT64 )
dVal = static_cast< double >(p->nInt64);
else if( p->eType == SbxSALUINT64 )
dVal = ImpSalUInt64ToDouble( p->uInt64 );
else if( p->eType == SbxDECIMAL )
{
dVal = 0.0;
if( p->pDecimal )
p->pDecimal->getDouble( dVal );
}
else
dVal = p->nDouble;
nRes = ImpDoubleToULong(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
nRes = ImpDoubleToULong(d);
}
break;
case SbxOBJECT:
{
SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
if( pVal )
nRes = pVal->GetULong();
else
{
SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0;
}
break;
}
case SbxBYREF | SbxBYTE:
nRes = *p->pByte; break;
case SbxBYREF | SbxERROR:
case SbxBYREF | SbxUSHORT:
nRes = *p->pUShort; break;
case SbxBYREF | SbxULONG:
nRes = *p->pULong; break;
// from here on tests
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 | 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 ImpPutULong( SbxValues* p, sal_uInt32 n )
{
SbxValues aTmp;
start:
switch( +p->eType )
{
case SbxULONG:
p->nULong = n; break;
case SbxSINGLE:
p->nSingle = static_cast<float>(n); break;
case SbxDATE:
case SbxDOUBLE:
p->nDouble = n; break;
case SbxCURRENCY:
case SbxSALINT64:
aTmp.pnInt64 = &p->nInt64; goto direct;
case SbxSALUINT64:
p->uInt64 = n; break;
case SbxDECIMAL:
case SbxBYREF | SbxDECIMAL:
ImpCreateDecimal( p )->setULong( n );
break;
// from here on tests
case SbxCHAR:
aTmp.pChar = &p->nChar; goto direct;
case SbxUINT:
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 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;
ImpCvtNum( static_cast<double>(n), 0, *p->pOUString );
break;
case SbxOBJECT:
{
SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
if( pVal )
pVal->PutULong( n );
else
SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
break;
}
case SbxBYREF | SbxCHAR:
if( n > SbxMAXCHAR )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXCHAR;
}
*p->pChar = static_cast<sal_Unicode>(n); break;
case SbxBYREF | SbxBYTE:
if( n > SbxMAXBYTE )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXBYTE;
}
*p->pByte = static_cast<sal_uInt8>(n); break;
case SbxBYREF | SbxINTEGER:
case SbxBYREF | SbxBOOL:
if( n > SbxMAXINT )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXINT;
}
*p->pInteger = static_cast<sal_Int16>(n); break;
case SbxBYREF | SbxERROR:
case SbxBYREF | SbxUSHORT:
if( n > SbxMAXUINT )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXUINT;
}
*p->pUShort = static_cast<sal_uInt16>(n); break;
case SbxBYREF | SbxLONG:
if( n > SbxMAXLNG )
{
SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXLNG;
}
*p->pLong = static_cast<sal_Int32>(n); break;
case SbxBYREF | SbxULONG:
*p->pULong = n; break;
case SbxBYREF | SbxSINGLE:
*p->pSingle = static_cast<float>(n); break;
case SbxBYREF | SbxDATE:
case SbxBYREF | SbxDOUBLE:
*p->pDouble = n; break;
case SbxBYREF | SbxCURRENCY:
*p->pnInt64 = 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: */