LibreOffice Module basic (master) 1
sbxsng.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
23#include <basic/sberrors.hxx>
24#include "sbxconv.hxx"
25#include <rtlproto.hxx>
26
27float ImpGetSingle( const SbxValues* p )
28{
29 SbxValues aTmp;
30 float nRes;
31start:
32 switch( +p->eType )
33 {
34 case SbxNULL:
36 [[fallthrough]];
37 case SbxEMPTY:
38 nRes = 0; break;
39 case SbxCHAR:
40 nRes = p->nChar; break;
41 case SbxBYTE:
42 nRes = p->nByte; break;
43 case SbxINTEGER:
44 case SbxBOOL:
45 nRes = p->nInteger; break;
46 case SbxERROR:
47 case SbxUSHORT:
48 nRes = p->nUShort; break;
49 case SbxLONG:
50 nRes = static_cast<float>(p->nLong); break;
51 case SbxULONG:
52 nRes = static_cast<float>(p->nULong); break;
53 case SbxSINGLE:
54 nRes = p->nSingle; break;
55 case SbxDECIMAL:
56 case SbxBYREF | SbxDECIMAL:
57 if (!p->pDecimal || !p->pDecimal->getSingle(nRes))
58 nRes = 0.0;
59 break;
60 case SbxDATE:
61 case SbxDOUBLE:
62 case SbxCURRENCY:
63 case SbxSALINT64:
64 case SbxSALUINT64:
65 {
66 double dVal;
67 if( p->eType == SbxCURRENCY )
68 dVal = ImpCurrencyToDouble( p->nInt64 );
69 else if( p->eType == SbxSALINT64 )
70 dVal = static_cast<float>(p->nInt64);
71 else if( p->eType == SbxSALUINT64 )
72 dVal = static_cast<float>(p->uInt64);
73 else
74 dVal = p->nDouble;
75
76 if( dVal > SbxMAXSNG )
77 {
79 nRes = static_cast< float >(SbxMAXSNG);
80 }
81 else if( dVal < SbxMINSNG )
82 {
84 nRes = static_cast< float >(SbxMINSNG);
85 }
86 // tests for underflow - storing value too small for precision of single
87 else if( dVal > 0 && dVal < SbxMAXSNG2 )
88 {
90 nRes = static_cast< float >(SbxMAXSNG2);
91 }
92 else if( dVal < 0 && dVal > SbxMINSNG2 )
93 {
95 nRes = static_cast< float >(SbxMINSNG2);
96 }
97 else
98 nRes = static_cast<float>(dVal);
99 break;
100 }
101 case SbxBYREF | SbxSTRING:
102 case SbxSTRING:
103 case SbxLPSTR:
104 if( !p->pOUString )
105 nRes = 0;
106 else
107 {
108 double d;
110 if( ImpScan( *p->pOUString, d, t, nullptr, !LibreOffice6FloatingPointMode() ) != ERRCODE_NONE )
111 nRes = 0;
112 else if( d > SbxMAXSNG )
113 {
115 nRes = static_cast< float >(SbxMAXSNG);
116 }
117 else if( d < SbxMINSNG )
118 {
120 nRes = static_cast< float >(SbxMINSNG);
121 }
122 else
123 nRes = static_cast<float>(d);
124 }
125 break;
126 case SbxOBJECT:
127 {
128 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
129 if( pVal )
130 nRes = pVal->GetSingle();
131 else
132 {
134 }
135 break;
136 }
137
138 case SbxBYREF | SbxCHAR:
139 nRes = *p->pChar; break;
140 case SbxBYREF | SbxBYTE:
141 nRes = *p->pByte; break;
142 case SbxBYREF | SbxINTEGER:
143 case SbxBYREF | SbxBOOL:
144 nRes = *p->pInteger; break;
145 case SbxBYREF | SbxLONG:
146 nRes = static_cast<float>(*p->pLong); break;
147 case SbxBYREF | SbxULONG:
148 nRes = static_cast<float>(*p->pULong); break;
149 case SbxBYREF | SbxERROR:
150 case SbxBYREF | SbxUSHORT:
151 nRes = *p->pUShort; break;
152 case SbxBYREF | SbxSINGLE:
153 nRes = *p->pSingle; break;
154 // from here had to be tested
155 case SbxBYREF | SbxDATE:
156 case SbxBYREF | SbxDOUBLE:
157 aTmp.nDouble = *p->pDouble; goto ref;
158 case SbxBYREF | SbxSALINT64:
159 case SbxBYREF | SbxCURRENCY:
160 aTmp.nInt64 = *p->pnInt64; goto ref;
161 case SbxBYREF | SbxSALUINT64:
162 aTmp.uInt64 = *p->puInt64; goto ref;
163 ref:
164 aTmp.eType = SbxDataType( p->eType & 0x0FFF );
165 p = &aTmp; goto start;
166
167 default:
169 }
170 return nRes;
171}
172
173void ImpPutSingle( SbxValues* p, float n )
174{
175 SbxValues aTmp;
176start:
177 switch( +p->eType )
178 {
179 case SbxCHAR:
180 aTmp.pChar = &p->nChar; goto direct;
181 case SbxBYTE:
182 aTmp.pByte = &p->nByte; goto direct;
183 case SbxINTEGER:
184 case SbxBOOL:
185 aTmp.pInteger = &p->nInteger; goto direct;
186 case SbxLONG:
187 aTmp.pLong = &p->nLong; goto direct;
188 case SbxULONG:
189 aTmp.pULong = &p->nULong; goto direct;
190 case SbxERROR:
191 case SbxUSHORT:
192 aTmp.pUShort = &p->nUShort; goto direct;
193 case SbxCURRENCY:
194 case SbxSALINT64:
195 aTmp.pnInt64 = &p->nInt64; goto direct;
196 case SbxSALUINT64:
197 aTmp.puInt64 = &p->uInt64; goto direct;
198 case SbxDECIMAL:
199 case SbxBYREF | SbxDECIMAL:
200 {
201 SbxDecimal* pDec = ImpCreateDecimal( p );
202 if( !pDec->setSingle( n ) )
204 break;
205 }
206 direct:
207 aTmp.eType = SbxDataType( p->eType | SbxBYREF );
208 p = &aTmp; goto start;
209
210 // from here no tests
211 case SbxSINGLE:
212 p->nSingle = n; break;
213 case SbxDATE:
214 case SbxDOUBLE:
215 p->nDouble = n; break;
216
217 case SbxBYREF | SbxSTRING:
218 case SbxSTRING:
219 case SbxLPSTR:
220 {
221 if( !p->pOUString )
222 p->pOUString = new OUString;
223 // tdf#107953 - show 9 significant digits
224 ImpCvtNum( static_cast<double>(n), 9, *p->pOUString );
225 break;
226 }
227 case SbxOBJECT:
228 {
229 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
230 if( pVal )
231 pVal->PutSingle( n );
232 else
234 break;
235 }
236 case SbxBYREF | SbxCHAR:
237 *p->pChar = ImpDoubleToChar(n); break;
238 case SbxBYREF | SbxBYTE:
239 *p->pByte = ImpDoubleToByte(n); break;
240 case SbxBYREF | SbxINTEGER:
241 case SbxBYREF | SbxBOOL:
242 *p->pInteger = ImpDoubleToInteger(n); break;
243 case SbxBYREF | SbxERROR:
244 case SbxBYREF | SbxUSHORT:
245 *p->pUShort = ImpDoubleToUShort(n); break;
246 case SbxBYREF | SbxLONG:
247 *p->pLong = ImpDoubleToLong(n); break;
248 case SbxBYREF | SbxULONG:
249 *p->pULong = ImpDoubleToULong(n); break;
250 case SbxBYREF | SbxSINGLE:
251 *p->pSingle = n; break;
252 case SbxBYREF | SbxDATE:
253 case SbxBYREF | SbxDOUBLE:
254 *p->pDouble = static_cast<double>(n); break;
255 case SbxBYREF | SbxSALINT64:
256 *p->pnInt64 = ImpDoubleToSalInt64(n); break;
257 case SbxBYREF | SbxSALUINT64:
258 *p->puInt64 = ImpDoubleToSalUInt64(n); break;
259 case SbxBYREF | SbxCURRENCY:
260 double d;
261 if( n > SbxMAXCURR )
262 {
264 }
265 else if( n < SbxMINCURR )
266 {
268 }
269 else
270 {
271 d = n;
272 }
273 *p->pnInt64 = ImpDoubleToCurrency( d ); break;
274
275 default:
277 }
278}
279
280/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XPropertyListType t
double d
static void SetError(ErrCode)
Definition: sbxbase.cxx:116
bool setSingle(float val)
Definition: sbxdec.cxx:324
bool PutSingle(float)
float GetSingle() const
Definition: sbxvar.hxx:149
#define ERRCODE_NONE
void * p
sal_Int64 n
bool LibreOffice6FloatingPointMode()
Definition: methods1.cxx:2946
#define ERRCODE_BASIC_NO_OBJECT
Definition: sberrors.hxx:34
#define ERRCODE_BASIC_MATH_OVERFLOW
Definition: sberrors.hxx:27
#define ERRCODE_BASIC_CONVERSION
Definition: sberrors.hxx:30
double ImpCurrencyToDouble(const sal_Int64 r)
Definition: sbxconv.hxx:113
auto ImpDoubleToChar(double f)
Definition: sbxconv.hxx:50
auto ImpDoubleToInteger(double f)
Definition: sbxconv.hxx:53
auto ImpDoubleToSalUInt64(double d)
Definition: sbxconv.hxx:56
auto ImpDoubleToLong(double f)
Definition: sbxconv.hxx:55
auto ImpDoubleToUShort(double f)
Definition: sbxconv.hxx:52
auto ImpDoubleToULong(double f)
Definition: sbxconv.hxx:54
ErrCode ImpScan(const OUString &rSrc, double &nVal, SbxDataType &rType, sal_uInt16 *pLen, bool bOnlyIntntl)
Definition: sbxscan.cxx:71
sal_Int64 ImpDoubleToCurrency(double d)
Definition: sbxconv.hxx:105
auto ImpDoubleToSalInt64(double d)
Definition: sbxconv.hxx:57
SbxDecimal * ImpCreateDecimal(SbxValues *p)
Definition: sbxdec.cxx:376
auto ImpDoubleToByte(double f)
Definition: sbxconv.hxx:51
void ImpCvtNum(double nNum, short nPrec, OUString &rRes, bool bCoreString=false)
Definition: sbxscan.cxx:290
constexpr auto SbxMINSNG2
Definition: sbxdef.hxx:208
constexpr auto SbxMAXSNG2
Definition: sbxdef.hxx:207
constexpr auto SbxMINSNG
Definition: sbxdef.hxx:206
constexpr auto SbxMINCURR
Definition: sbxdef.hxx:203
SbxBOOL
Definition: sbxdef.hxx:215
constexpr auto SbxMAXCURR
Definition: sbxdef.hxx:202
SbxDataType
Definition: sbxdef.hxx:37
@ SbxOBJECT
Definition: sbxdef.hxx:47
@ SbxSALINT64
Definition: sbxdef.hxx:75
@ SbxLONG
Definition: sbxdef.hxx:41
@ SbxSALUINT64
Definition: sbxdef.hxx:76
@ SbxNULL
Definition: sbxdef.hxx:39
@ SbxBYTE
Definition: sbxdef.hxx:55
@ SbxEMPTY
Definition: sbxdef.hxx:38
@ SbxDECIMAL
Definition: sbxdef.hxx:77
@ SbxULONG
Definition: sbxdef.hxx:57
@ SbxUSHORT
Definition: sbxdef.hxx:56
@ SbxERROR
Definition: sbxdef.hxx:48
@ SbxDATE
Definition: sbxdef.hxx:45
@ SbxCURRENCY
Definition: sbxdef.hxx:44
@ SbxLPSTR
Definition: sbxdef.hxx:68
@ SbxSINGLE
Definition: sbxdef.hxx:42
@ SbxBYREF
Definition: sbxdef.hxx:81
@ SbxCHAR
Definition: sbxdef.hxx:54
@ SbxSTRING
Definition: sbxdef.hxx:46
@ SbxINTEGER
Definition: sbxdef.hxx:40
@ SbxDOUBLE
Definition: sbxdef.hxx:43
constexpr auto SbxMAXSNG
Definition: sbxdef.hxx:205
float ImpGetSingle(const SbxValues *p)
Definition: sbxsng.cxx:27
void ImpPutSingle(SbxValues *p, float n)
Definition: sbxsng.cxx:173
sal_uInt64 * puInt64
Definition: sbxvar.hxx:69
sal_uInt8 * pByte
Definition: sbxvar.hxx:63
sal_uInt32 * pULong
Definition: sbxvar.hxx:67
sal_uInt16 * pUShort
Definition: sbxvar.hxx:64
sal_Int64 nInt64
Definition: sbxvar.hxx:53
double nDouble
Definition: sbxvar.hxx:56
sal_uInt64 uInt64
Definition: sbxvar.hxx:52
sal_Int16 * pInteger
Definition: sbxvar.hxx:66
sal_Int32 * pLong
Definition: sbxvar.hxx:68
SbxDataType eType
Definition: sbxvar.hxx:77
sal_Int64 * pnInt64
Definition: sbxvar.hxx:70
sal_Unicode * pChar
Definition: sbxvar.hxx:65