/* -*- 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 . */ #pragma once #include "sbxdec.hxx" #include #include #include #include #include #include #include #include class SbxArray; template inline I DoubleTo(double f, I min, I max) { f = rtl::math::round(f); if (!o3tl::convertsToAtMost(f, max)) { SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); return max; } if (!o3tl::convertsToAtLeast(f, min)) { SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); return min; } return f; } inline auto ImpDoubleToChar(double f) { return DoubleTo(f, SbxMINCHAR, SbxMAXCHAR); } inline auto ImpDoubleToByte(double f) { return DoubleTo(f, 0, SbxMAXBYTE); } inline auto ImpDoubleToUShort(double f) { return DoubleTo(f, 0, SbxMAXUINT); } inline auto ImpDoubleToInteger(double f) { return DoubleTo(f, SbxMININT, SbxMAXINT); } inline auto ImpDoubleToULong(double f) { return DoubleTo(f, 0, SbxMAXULNG); } inline auto ImpDoubleToLong(double f) { return DoubleTo(f, SbxMINLNG, SbxMAXLNG); } inline auto ImpDoubleToSalUInt64(double d) { return DoubleTo(d, 0, SAL_MAX_UINT64); } inline auto ImpDoubleToSalInt64(double d) { return DoubleTo(d, SAL_MIN_INT64, SAL_MAX_INT64); } // SBXSCAN.CXX extern void ImpCvtNum( double nNum, short nPrec, OUString& rRes, bool bCoreString=false ); extern ErrCode ImpScan ( const OUString& rSrc, double& nVal, SbxDataType& rType, sal_uInt16* pLen, bool bOnlyIntntl ); // A version that uses defaults / compatibility settings for bOnlyIntntl extern ErrCode ImpScan ( const OUString& rSrc, double& nVal, SbxDataType& rType, sal_uInt16* pLen ); // with advanced evaluation (International, "TRUE"/"FALSE") extern bool ImpConvStringExt( OUString& rSrc, SbxDataType eTargetType ); void ImpGetIntntlSep( sal_Unicode& rcDecimalSep, sal_Unicode& rcThousandSep, sal_Unicode& rcDecimalSepAlt ); // SBXINT.CXX sal_Int16 ImpGetInteger( const SbxValues* ); void ImpPutInteger( SbxValues*, sal_Int16 ); 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 ); // SBXCURR.CXX sal_Int64 ImpGetCurrency( const SbxValues* ); void ImpPutCurrency( SbxValues*, const sal_Int64 ); inline sal_Int64 ImpDoubleToCurrency( 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 { SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); return SAL_MAX_INT64; } if (result < double(SAL_MIN_INT64)) { SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); return SAL_MIN_INT64; } return result; } template requires std::is_integral_v inline sal_Int64 CurFrom(I n) { using ValidRange = o3tl::ValidRange; if (ValidRange::isAbove(n)) { SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); return SAL_MAX_INT64; } if (ValidRange::isBelow(n)) { SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); return SAL_MIN_INT64; } return n * CURRENCY_FACTOR; } inline double ImpCurrencyToDouble(sal_Int64 r) { return static_cast(r) / CURRENCY_FACTOR; } template requires std::is_integral_v inline I CurTo(sal_Int64 cur_val) { sal_Int64 i = CurTo(cur_val); if (o3tl::ValidRange::isAbove(i)) { SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); return std::numeric_limits::max(); } if (o3tl::ValidRange::isBelow(i)) { SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW); return std::numeric_limits::min(); } return i; } template <> inline sal_Int64 CurTo(sal_Int64 cur_val) { sal_Int64 i = cur_val / CURRENCY_FACTOR; // Rounding (half-to-even) int f = cur_val % CURRENCY_FACTOR; if (i % 2 == 1) { if (f < 0) --f; else ++f; } if (f > CURRENCY_FACTOR / 2) ++i; else if (f < -CURRENCY_FACTOR / 2) --i; return i; } // SBXDEC.CXX SbxDecimal* ImpCreateDecimal( SbxValues* p ); SbxDecimal* ImpGetDecimal( const SbxValues* p ); void ImpPutDecimal( SbxValues* p, SbxDecimal* pDec ); // SBXDATE.CXX double ImpGetDate( const SbxValues* ); void ImpPutDate( SbxValues*, double ); // SBXSTR.CXX 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* ); void ImpPutBool( SbxValues*, sal_Int16 ); // ByteArray <--> String SbxArray* StringToByteArray(const OUString& rStr); OUString ByteArrayToString(SbxArray* pArr); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */