Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / basic / source / sbx / sbxint.cxx
blob90f68bfaefb5c9fbe21bac4c476a8d42dd9abdb6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include <o3tl/float_int_conversion.hxx>
23 #include <vcl/errcode.hxx>
24 #include <basic/sberrors.hxx>
25 #include "sbxconv.hxx"
27 #include <rtl/math.hxx>
29 sal_Int16 ImpGetInteger( const SbxValues* p )
31 SbxValues aTmp;
32 sal_Int16 nRes;
33 start:
34 switch( +p->eType )
36 case SbxNULL:
37 SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
38 [[fallthrough]];
39 case SbxEMPTY:
40 nRes = 0; break;
41 case SbxCHAR:
42 nRes = p->nChar; break;
43 case SbxBYTE:
44 nRes = p->nByte; break;
45 case SbxINTEGER:
46 case SbxBOOL:
47 nRes = p->nInteger; break;
48 case SbxERROR:
49 case SbxUSHORT:
50 if( p->nUShort > sal_uInt16(SbxMAXINT) )
52 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT;
54 else
55 nRes = static_cast<sal_Int16>(p->nUShort);
56 break;
57 case SbxLONG:
58 if( p->nLong > SbxMAXINT )
60 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT;
62 else if( p->nLong < SbxMININT )
64 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMININT;
66 else
67 nRes = static_cast<sal_Int16>(p->nLong);
68 break;
69 case SbxULONG:
70 if( p->nULong > SbxMAXINT )
72 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT;
74 else
75 nRes = static_cast<sal_Int16>(p->nULong);
76 break;
77 case SbxSINGLE:
78 if( !o3tl::convertsToAtMost(o3tl::roundAway(p->nSingle), SbxMAXINT) )
80 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT;
82 else if( !o3tl::convertsToAtLeast(o3tl::roundAway(p->nSingle), SbxMININT) )
84 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMININT;
86 else
87 nRes = static_cast<sal_Int16>(rtl::math::round( p->nSingle ));
88 break;
89 case SbxCURRENCY:
91 sal_Int64 tstVal = p->nInt64 / sal_Int64(CURRENCY_FACTOR);
93 if( tstVal > SbxMAXINT )
95 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT;
97 else if( tstVal < SbxMININT )
99 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMININT;
101 else
102 nRes = static_cast<sal_Int16>(tstVal);
103 break;
105 case SbxSALINT64:
106 if( p->nInt64 > SbxMAXINT )
108 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT;
110 else if( p->nInt64 < SbxMININT )
112 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMININT;
114 else
115 nRes = static_cast<sal_Int16>(p->nInt64);
116 break;
117 case SbxSALUINT64:
118 if( p->uInt64 > SbxMAXINT )
120 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT;
122 else
123 nRes = static_cast<sal_Int16>(p->uInt64);
124 break;
125 case SbxDATE:
126 case SbxDOUBLE:
127 case SbxDECIMAL:
128 case SbxBYREF | SbxDECIMAL:
130 double dVal = 0.0;
131 if( p->eType == SbxDECIMAL )
133 if( p->pDecimal )
134 p->pDecimal->getDouble( dVal );
136 else
137 dVal = p->nDouble;
139 if( !o3tl::convertsToAtMost(o3tl::roundAway(dVal), SbxMAXINT) )
141 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT;
143 else if( !o3tl::convertsToAtLeast(o3tl::roundAway(dVal), SbxMININT) )
145 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMININT;
147 else
148 nRes = static_cast<sal_Int16>(rtl::math::round( dVal ));
149 break;
151 case SbxLPSTR:
152 case SbxSTRING:
153 case SbxBYREF | SbxSTRING:
154 if( !p->pOUString )
155 nRes = 0;
156 else
158 double d;
159 SbxDataType t;
160 if( ImpScan( *p->pOUString, d, t, nullptr, false ) != ERRCODE_NONE )
161 nRes = 0;
162 else if( !o3tl::convertsToAtMost(o3tl::roundAway(d), SbxMAXINT) )
164 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT;
166 else if( !o3tl::convertsToAtLeast(o3tl::roundAway(d), SbxMININT) )
168 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMININT;
170 else
171 nRes = static_cast<sal_Int16>(rtl::math::round( d ));
173 break;
174 case SbxOBJECT:
176 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
177 if( pVal )
178 nRes = pVal->GetInteger();
179 else
181 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0;
183 break;
186 case SbxBYREF | SbxCHAR:
187 nRes = *p->pChar; break;
188 case SbxBYREF | SbxBYTE:
189 nRes = *p->pByte; break;
190 case SbxBYREF | SbxINTEGER:
191 case SbxBYREF | SbxBOOL:
192 nRes = *p->pInteger; break;
194 // from here had to be tested
195 case SbxBYREF | SbxLONG:
196 aTmp.nLong = *p->pLong; goto ref;
197 case SbxBYREF | SbxULONG:
198 aTmp.nULong = *p->pULong; goto ref;
199 case SbxBYREF | SbxERROR:
200 case SbxBYREF | SbxUSHORT:
201 aTmp.nUShort = *p->pUShort; goto ref;
202 case SbxBYREF | SbxSINGLE:
203 aTmp.nSingle = *p->pSingle; goto ref;
204 case SbxBYREF | SbxDATE:
205 case SbxBYREF | SbxDOUBLE:
206 aTmp.nDouble = *p->pDouble; goto ref;
207 case SbxBYREF | SbxCURRENCY:
208 case SbxBYREF | SbxSALINT64:
209 aTmp.nInt64 = *p->pnInt64; goto ref;
210 case SbxBYREF | SbxSALUINT64:
211 aTmp.uInt64 = *p->puInt64; goto ref;
212 ref:
213 aTmp.eType = SbxDataType( p->eType & 0x0FFF );
214 p = &aTmp; goto start;
216 default:
217 SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0;
219 return nRes;
222 void ImpPutInteger( SbxValues* p, sal_Int16 n )
224 SbxValues aTmp;
225 start:
226 switch( +p->eType )
228 // here had to be tested
229 case SbxCHAR:
230 aTmp.pChar = &p->nChar; goto direct;
231 case SbxBYTE:
232 aTmp.pByte = &p->nByte; goto direct;
233 case SbxULONG:
234 aTmp.pULong = &p->nULong; goto direct;
235 case SbxERROR:
236 case SbxUSHORT:
237 aTmp.pUShort = &p->nUShort; goto direct;
238 case SbxSALUINT64:
239 aTmp.puInt64 = &p->uInt64; goto direct;
240 direct:
241 aTmp.eType = SbxDataType( p->eType | SbxBYREF );
242 p = &aTmp; goto start;
244 // from here no tests needed
245 case SbxINTEGER:
246 case SbxBOOL:
247 p->nInteger = n; break;
248 case SbxLONG:
249 p->nLong = n; break;
250 case SbxSINGLE:
251 p->nSingle = n; break;
252 case SbxDATE:
253 case SbxDOUBLE:
254 p->nDouble = n; break;
255 case SbxCURRENCY:
256 p->nInt64 = n * CURRENCY_FACTOR; break;
257 case SbxSALINT64:
258 p->nInt64 = n; break;
259 case SbxDECIMAL:
260 case SbxBYREF | SbxDECIMAL:
261 ImpCreateDecimal( p )->setInt( n );
262 break;
264 case SbxLPSTR:
265 case SbxSTRING:
266 case SbxBYREF | SbxSTRING:
267 if( !p->pOUString )
268 p->pOUString = new OUString;
269 ImpCvtNum( static_cast<double>(n), 0, *p->pOUString );
270 break;
271 case SbxOBJECT:
273 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
274 if( pVal )
275 pVal->PutInteger( n );
276 else
277 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
278 break;
280 case SbxBYREF | SbxCHAR:
281 if( n < SbxMINCHAR )
283 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINCHAR;
285 *p->pChar = static_cast<char>(n); break;
286 case SbxBYREF | SbxBYTE:
287 if( n > SbxMAXBYTE )
289 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXBYTE;
291 else if( n < 0 )
293 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
295 *p->pByte = static_cast<sal_uInt8>(n); break;
296 case SbxBYREF | SbxINTEGER:
297 case SbxBYREF | SbxBOOL:
298 *p->pInteger = n; break;
299 case SbxBYREF | SbxERROR:
300 case SbxBYREF | SbxUSHORT:
301 if( n < 0 )
303 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
305 *p->pUShort = static_cast<sal_uInt16>(n); break;
306 case SbxBYREF | SbxLONG:
307 *p->pLong = static_cast<sal_Int32>(n); break;
308 case SbxBYREF | SbxULONG:
309 if( n < 0 )
311 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
313 *p->pULong = static_cast<sal_uInt32>(n); break;
314 case SbxBYREF | SbxCURRENCY:
315 *p->pnInt64 = n * CURRENCY_FACTOR; break;
316 case SbxBYREF | SbxSALINT64:
317 *p->pnInt64 = n; break;
318 case SbxBYREF | SbxSALUINT64:
319 if( n < 0 )
321 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
322 *p->puInt64 = 0;
324 else
325 *p->puInt64 = n;
326 break;
327 case SbxBYREF | SbxSINGLE:
328 *p->pSingle = static_cast<float>(n); break;
329 case SbxBYREF | SbxDATE:
330 case SbxBYREF | SbxDOUBLE:
331 *p->pDouble = static_cast<double>(n); break;
333 default:
334 SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
339 // sal_Int64 / hyper
341 sal_Int64 ImpDoubleToSalInt64( double d )
343 sal_Int64 nRes;
344 if( !o3tl::convertsToAtMost(o3tl::roundAway(d), SAL_MAX_INT64) )
346 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SAL_MAX_INT64;
348 else if( !o3tl::convertsToAtLeast(o3tl::roundAway(d), SAL_MIN_INT64) )
350 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SAL_MIN_INT64;
352 else
353 nRes = static_cast<sal_Int64>(rtl::math::round( d ));
354 return nRes;
357 sal_uInt64 ImpDoubleToSalUInt64( double d )
359 sal_uInt64 nRes;
360 if( !o3tl::convertsToAtMost(o3tl::roundAway(d), SAL_MAX_UINT64) )
362 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SAL_MAX_UINT64;
364 else if( d < 0.0 )
366 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
368 else
369 nRes = static_cast<sal_uInt64>(rtl::math::round( d ));
370 return nRes;
374 double ImpSalUInt64ToDouble( sal_uInt64 n )
376 double d = 0.0;
377 if( n > SAL_MAX_INT64 )
378 SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
379 else
380 d = static_cast<double>(static_cast<sal_Int64>(n));
381 return d;
385 sal_Int64 ImpGetInt64( const SbxValues* p )
387 SbxValues aTmp;
388 sal_Int64 nRes;
389 start:
390 switch( +p->eType )
392 case SbxNULL:
393 SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
394 [[fallthrough]];
395 case SbxEMPTY:
396 nRes = 0; break;
397 case SbxCHAR:
398 nRes = p->nChar; break;
399 case SbxBYTE:
400 nRes = p->nByte; break;
401 case SbxINTEGER:
402 case SbxBOOL:
403 nRes = p->nInteger; break;
404 case SbxERROR:
405 case SbxUSHORT:
406 nRes = static_cast<sal_Int64>(p->nUShort); break;
407 case SbxLONG:
408 nRes = static_cast<sal_Int64>(p->nLong); break;
409 case SbxULONG:
410 nRes = static_cast<sal_Int64>(p->nULong); break;
411 case SbxSINGLE:
412 nRes = static_cast<sal_Int64>(p->nSingle);
413 break;
414 case SbxDATE:
415 case SbxDOUBLE:
416 nRes = static_cast<sal_Int64>(p->nDouble);
417 break;
418 case SbxCURRENCY:
419 nRes = p->nInt64 / CURRENCY_FACTOR; break;
420 case SbxSALINT64:
421 nRes = p->nInt64; break;
422 case SbxSALUINT64:
423 if( p->uInt64 > SAL_MAX_INT64 )
425 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SAL_MAX_INT64;
427 else
428 nRes = static_cast<sal_Int64>(p->uInt64);
429 break;
431 case SbxBYREF | SbxSTRING:
432 case SbxSTRING:
433 case SbxLPSTR:
434 if( !p->pOUString )
435 nRes = 0;
436 else
438 ::OString aOStr = OUStringToOString( *p->pOUString, RTL_TEXTENCODING_ASCII_US );
439 nRes = aOStr.toInt64();
440 if( nRes == 0 )
442 // Check if really 0 or invalid conversion
443 double d;
444 SbxDataType t;
445 if( ImpScan( *p->pOUString, d, t, nullptr, false ) != ERRCODE_NONE )
446 nRes = 0;
447 else
448 nRes = static_cast<sal_Int64>(d);
451 break;
452 case SbxOBJECT:
454 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
455 if( pVal )
456 nRes = pVal->GetInt64();
457 else
459 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0;
461 break;
464 case SbxBYREF | SbxCHAR:
465 nRes = *p->pChar; break;
466 case SbxBYREF | SbxBYTE:
467 nRes = *p->pByte; break;
468 case SbxBYREF | SbxINTEGER:
469 case SbxBYREF | SbxBOOL:
470 nRes = *p->pInteger; break;
471 case SbxBYREF | SbxLONG:
472 nRes = *p->pLong; break;
473 case SbxBYREF | SbxULONG:
474 nRes = *p->pULong; break;
475 case SbxBYREF | SbxCURRENCY:
476 nRes = p->nInt64 / CURRENCY_FACTOR; break;
477 case SbxBYREF | SbxSALINT64:
478 nRes = *p->pnInt64; break;
480 // from here the values has to be checked
481 case SbxBYREF | SbxSALUINT64:
482 aTmp.uInt64 = *p->puInt64; goto ref;
484 case SbxBYREF | SbxERROR:
485 case SbxBYREF | SbxUSHORT:
486 aTmp.nUShort = *p->pUShort; goto ref;
487 case SbxBYREF | SbxSINGLE:
488 aTmp.nSingle = *p->pSingle; goto ref;
489 case SbxBYREF | SbxDATE:
490 case SbxBYREF | SbxDOUBLE:
491 aTmp.nDouble = *p->pDouble; goto ref;
492 ref:
493 aTmp.eType = SbxDataType( p->eType & 0x0FFF );
494 p = &aTmp; goto start;
496 default:
497 SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0;
499 return nRes;
502 void ImpPutInt64( SbxValues* p, sal_Int64 n )
504 SbxValues aTmp;
506 start:
507 switch( +p->eType )
509 // Check necessary
510 case SbxCHAR:
511 aTmp.pChar = &p->nChar; goto direct;
512 case SbxBYTE:
513 aTmp.pByte = &p->nByte; goto direct;
514 case SbxINTEGER:
515 case SbxBOOL:
516 aTmp.pInteger = &p->nInteger; goto direct;
517 case SbxULONG:
518 aTmp.pULong = &p->nULong; goto direct;
519 case SbxERROR:
520 case SbxUSHORT:
521 aTmp.pUShort = &p->nUShort; goto direct;
522 case SbxLONG:
523 aTmp.pnInt64 = &p->nInt64; goto direct;
524 case SbxCURRENCY:
525 case SbxSALINT64:
526 aTmp.pnInt64 = &p->nInt64; goto direct;
527 case SbxSALUINT64:
528 aTmp.puInt64 = &p->uInt64; goto direct;
530 direct:
531 aTmp.eType = SbxDataType( p->eType | SbxBYREF );
532 p = &aTmp; goto start;
534 case SbxSINGLE:
535 p->nSingle = static_cast<float>(n); break;
536 case SbxDATE:
537 case SbxDOUBLE:
538 p->nDouble = static_cast<double>(n); break;
540 case SbxBYREF | SbxSTRING:
541 case SbxSTRING:
542 case SbxLPSTR:
544 if( !p->pOUString )
545 p->pOUString = new OUString;
547 ::OString aOStr = OString::number( n );
548 (*p->pOUString) = ::OStringToOUString( aOStr, RTL_TEXTENCODING_ASCII_US );
549 break;
551 case SbxOBJECT:
553 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
554 if( pVal )
555 pVal->PutInt64( n );
556 else
557 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
558 break;
560 case SbxBYREF | SbxCHAR:
561 if( n > SbxMAXCHAR )
563 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXCHAR;
565 else if( n < SbxMINCHAR )
567 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINCHAR;
569 *p->pChar = static_cast<sal_Unicode>(n); break;
570 case SbxBYREF | SbxBYTE:
571 if( n > SbxMAXBYTE )
573 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXBYTE;
575 else if( n < 0 )
577 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
579 *p->pByte = static_cast<sal_uInt8>(n); break;
580 case SbxBYREF | SbxINTEGER:
581 case SbxBYREF | SbxBOOL:
582 if( n > SbxMAXINT )
584 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXINT;
586 else if( n < SbxMININT )
588 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMININT;
590 *p->pInteger = static_cast<sal_Int16>(n); break;
591 case SbxBYREF | SbxERROR:
592 case SbxBYREF | SbxUSHORT:
593 if( n > SbxMAXUINT )
595 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXUINT;
597 else if( n < 0 )
599 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
601 *p->pUShort = static_cast<sal_uInt16>(n); break;
602 case SbxBYREF | SbxLONG:
603 if( n > SbxMAXLNG )
605 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXLNG;
607 else if( n < SbxMINLNG )
609 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINLNG;
611 *p->pLong = static_cast<sal_Int32>(n); break;
612 case SbxBYREF | SbxULONG:
613 if( n > SbxMAXULNG )
615 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXULNG;
617 else if( n < 0 )
619 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
621 *p->pULong = static_cast<sal_uInt32>(n); break;
622 case SbxBYREF | SbxSINGLE:
623 *p->pSingle = static_cast<float>(n); break;
624 case SbxBYREF | SbxDATE:
625 case SbxBYREF | SbxDOUBLE:
626 *p->pDouble = static_cast<double>(n); break;
627 case SbxBYREF | SbxCURRENCY:
628 *p->pnInt64 = n * CURRENCY_FACTOR; break;
629 case SbxBYREF | SbxSALINT64:
630 *p->pnInt64 = n; break;
631 case SbxBYREF | SbxSALUINT64:
632 if( n < 0 )
634 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
636 *p->puInt64 = n; break;
638 default:
639 SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
643 sal_uInt64 ImpGetUInt64( const SbxValues* p )
645 SbxValues aTmp;
646 sal_uInt64 nRes;
647 start:
648 switch( +p->eType )
650 case SbxNULL:
651 SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
652 [[fallthrough]];
653 case SbxEMPTY:
654 nRes = 0; break;
655 case SbxCHAR:
656 nRes = p->nChar; break;
657 case SbxBYTE:
658 nRes = p->nByte; break;
659 case SbxINTEGER:
660 case SbxBOOL:
661 nRes = p->nInteger; break;
662 case SbxERROR:
663 case SbxUSHORT:
664 nRes = p->nUShort; break;
665 case SbxLONG:
666 nRes = p->nLong; break;
667 case SbxULONG:
668 nRes = static_cast<sal_uInt64>(p->nULong); break;
669 case SbxSINGLE:
670 nRes = static_cast<sal_uInt64>(p->nSingle); break;
671 case SbxDATE:
672 case SbxDOUBLE:
674 //TODO overflow check
675 nRes = static_cast<sal_uInt64>(p->nDouble);
676 break;
678 case SbxCURRENCY:
679 nRes = p->nInt64 * CURRENCY_FACTOR; break;
680 case SbxSALINT64:
681 if( p->nInt64 < 0 )
683 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
685 else
686 nRes = static_cast<sal_uInt64>(p->nInt64);
687 break;
688 case SbxSALUINT64:
689 nRes = p->uInt64; break;
691 case SbxBYREF | SbxSTRING:
692 case SbxSTRING:
693 case SbxLPSTR:
694 if( !p->pOUString )
695 nRes = 0;
696 else
698 ::OString aOStr = OUStringToOString
699 ( *p->pOUString, RTL_TEXTENCODING_ASCII_US );
700 sal_Int64 n64 = aOStr.toInt64();
701 if( n64 == 0 )
703 // Check if really 0 or invalid conversion
704 double d;
705 SbxDataType t;
706 if( ImpScan( *p->pOUString, d, t, nullptr, false ) != ERRCODE_NONE )
707 nRes = 0;
708 else if( !o3tl::convertsToAtMost(o3tl::roundAway(d), SAL_MAX_UINT64) )
710 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SAL_MAX_UINT64;
712 else if( d < 0.0 )
714 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
716 else
717 nRes = static_cast<sal_uInt64>(rtl::math::round( d ));
719 else if( n64 < 0 )
721 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
723 else
725 nRes = n64;
728 break;
729 case SbxOBJECT:
731 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
732 if( pVal )
733 nRes = pVal->GetUInt64();
734 else
736 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0;
738 break;
741 case SbxBYREF | SbxCHAR:
742 nRes = *p->pChar; break;
743 case SbxBYREF | SbxBYTE:
744 nRes = *p->pByte; break;
745 case SbxBYREF | SbxINTEGER:
746 case SbxBYREF | SbxBOOL:
747 nRes = *p->pInteger; break;
748 case SbxBYREF | SbxLONG:
749 nRes = *p->pLong; break;
750 case SbxBYREF | SbxULONG:
751 nRes = *p->pULong; break;
752 case SbxBYREF | SbxSALUINT64:
753 nRes = *p->puInt64; break;
755 // from here on the value has to be checked
756 case SbxBYREF | SbxERROR:
757 case SbxBYREF | SbxUSHORT:
758 aTmp.nUShort = *p->pUShort; goto ref;
759 case SbxBYREF | SbxSINGLE:
760 aTmp.nSingle = *p->pSingle; goto ref;
761 case SbxBYREF | SbxDATE:
762 case SbxBYREF | SbxDOUBLE:
763 aTmp.nDouble = *p->pDouble; goto ref;
764 case SbxBYREF | SbxCURRENCY:
765 case SbxBYREF | SbxSALINT64:
766 aTmp.nInt64 = *p->pnInt64; goto ref;
767 ref:
768 aTmp.eType = SbxDataType( p->eType & 0x0FFF );
769 p = &aTmp; goto start;
771 default:
772 SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0;
774 return nRes;
777 void ImpPutUInt64( SbxValues* p, sal_uInt64 n )
779 SbxValues aTmp;
781 start:
782 switch( +p->eType )
784 // Check necessary
785 case SbxCHAR:
786 aTmp.pChar = &p->nChar; goto direct;
787 case SbxBYTE:
788 aTmp.pByte = &p->nByte; goto direct;
789 case SbxINTEGER:
790 case SbxBOOL:
791 aTmp.pInteger = &p->nInteger; goto direct;
792 case SbxULONG:
793 aTmp.pULong = &p->nULong; goto direct;
794 case SbxERROR:
795 case SbxUSHORT:
796 aTmp.pUShort = &p->nUShort; goto direct;
797 case SbxLONG:
798 aTmp.pnInt64 = &p->nInt64; goto direct;
799 case SbxCURRENCY:
800 case SbxSALINT64:
801 aTmp.pnInt64 = &p->nInt64; goto direct;
802 case SbxSINGLE:
803 aTmp.pSingle = &p->nSingle; goto direct;
804 case SbxDATE:
805 case SbxDOUBLE:
806 aTmp.pDouble = &p->nDouble; goto direct;
808 direct:
809 aTmp.eType = SbxDataType( p->eType | SbxBYREF );
810 p = &aTmp; goto start;
812 // Check not necessary
813 case SbxSALUINT64:
814 p->uInt64 = n; break;
816 case SbxBYREF | SbxSTRING:
817 case SbxSTRING:
818 case SbxLPSTR:
819 if( !p->pOUString )
820 p->pOUString = new OUString;
821 if( n > SAL_MAX_INT64 )
822 SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
823 else
825 ::OString aOStr = OString::number( n );
826 (*p->pOUString) = ::OStringToOUString( aOStr, RTL_TEXTENCODING_ASCII_US );
828 break;
829 case SbxOBJECT:
831 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
832 if( pVal )
833 pVal->PutUInt64( n );
834 else
835 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
836 break;
838 case SbxBYREF | SbxCHAR:
839 if( n > SbxMAXCHAR )
841 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXCHAR;
843 *p->pChar = static_cast<sal_Unicode>(n); break;
844 case SbxBYREF | SbxBYTE:
845 if( n > SbxMAXBYTE )
847 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXBYTE;
849 *p->pByte = static_cast<sal_uInt8>(n); break;
850 case SbxBYREF | SbxINTEGER:
851 case SbxBYREF | SbxBOOL:
852 if( n > SbxMAXINT )
854 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXINT;
856 *p->pInteger = static_cast<sal_Int16>(n); break;
857 case SbxBYREF | SbxERROR:
858 case SbxBYREF | SbxUSHORT:
859 if( n > SbxMAXUINT )
861 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXUINT;
863 *p->pUShort = static_cast<sal_uInt16>(n); break;
864 case SbxBYREF | SbxLONG:
865 if( n > SbxMAXLNG )
867 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXLNG;
869 *p->pLong = static_cast<sal_Int32>(n); break;
870 case SbxBYREF | SbxULONG:
871 if( n > SbxMAXULNG )
873 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXULNG;
875 *p->pULong = static_cast<sal_uInt32>(n); break;
876 case SbxBYREF | SbxSINGLE:
877 *p->pDouble = static_cast<float>(ImpSalUInt64ToDouble( n )); break;
878 case SbxBYREF | SbxDATE:
879 case SbxBYREF | SbxDOUBLE:
881 *p->pDouble = ImpSalUInt64ToDouble( n ); break;
882 case SbxBYREF | SbxCURRENCY:
883 if ( n > ( SAL_MAX_INT64 / CURRENCY_FACTOR ) )
885 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
886 n = SAL_MAX_INT64;
888 *p->pnInt64 = static_cast<sal_Int64>( n * CURRENCY_FACTOR ); break;
889 case SbxBYREF | SbxSALUINT64:
890 *p->puInt64 = n; break;
891 case SbxBYREF | SbxSALINT64:
892 if( n > SAL_MAX_INT64 )
894 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
896 *p->pnInt64 = static_cast<sal_Int64>(n); break;
898 default:
899 SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
904 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */