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 22 #include <o3tl/float_int_conversion.hxx> 23 #include <o3tl/safeint.hxx> 24 #include <vcl/errcode.hxx> 25 #include <basic/sberrors.hxx> 26 #include "sbxconv.hxx" 27 28 #include <rtl/math.hxx> 29 30 sal_Int16 ImpGetInteger( const SbxValues* p ) 31 { 32 SbxValues aTmp; 33 sal_Int16 nRes; 34 start: 35 switch( +p->eType ) 36 { 37 case SbxNULL: 38 SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); 39 [[fallthrough]]; 40 case SbxEMPTY: 41 nRes = 0; break; 42 case SbxCHAR: 43 nRes = p->nChar; break; 44 case SbxBYTE: 45 nRes = p->nByte; break; 46 case SbxINTEGER: 47 case SbxBOOL: 48 nRes = p->nInteger; break; 49 case SbxERROR: 50 case SbxUSHORT: 51 if( p->nUShort > o3tl::make_unsigned(SbxMAXINT) ) 52 { 53 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT; 54 } 55 else 56 nRes = static_cast<sal_Int16>(p->nUShort); 57 break; 58 case SbxLONG: 59 if( p->nLong > SbxMAXINT ) 60 { 61 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT; 62 } 63 else if( p->nLong < SbxMININT ) 64 { 65 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMININT; 66 } 67 else 68 nRes = static_cast<sal_Int16>(p->nLong); 69 break; 70 case SbxULONG: 71 if( p->nULong > SbxMAXINT ) 72 { 73 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT; 74 } 75 else 76 nRes = static_cast<sal_Int16>(p->nULong); 77 break; 78 case SbxSINGLE: 79 if( !o3tl::convertsToAtMost(o3tl::roundAway(p->nSingle), SbxMAXINT) ) 80 { 81 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT; 82 } 83 else if( !o3tl::convertsToAtLeast(o3tl::roundAway(p->nSingle), SbxMININT) ) 84 { 85 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMININT; 86 } 87 else 88 nRes = static_cast<sal_Int16>(rtl::math::round( p->nSingle )); 89 break; 90 case SbxCURRENCY: 91 { 92 sal_Int64 tstVal = p->nInt64 / sal_Int64(CURRENCY_FACTOR); 93 94 if( tstVal > SbxMAXINT ) 95 { 96 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT; 97 } 98 else if( tstVal < SbxMININT ) 99 { 100 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMININT; 101 } 102 else 103 nRes = static_cast<sal_Int16>(tstVal); 104 break; 105 } 106 case SbxSALINT64: 107 if( p->nInt64 > SbxMAXINT ) 108 { 109 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT; 110 } 111 else if( p->nInt64 < SbxMININT ) 112 { 113 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMININT; 114 } 115 else 116 nRes = static_cast<sal_Int16>(p->nInt64); 117 break; 118 case SbxSALUINT64: 119 if( p->uInt64 > SbxMAXINT ) 120 { 121 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT; 122 } 123 else 124 nRes = static_cast<sal_Int16>(p->uInt64); 125 break; 126 case SbxDATE: 127 case SbxDOUBLE: 128 case SbxDECIMAL: 129 case SbxBYREF | SbxDECIMAL: 130 { 131 double dVal = 0.0; 132 if( p->eType == SbxDECIMAL ) 133 { 134 if( p->pDecimal ) 135 p->pDecimal->getDouble( dVal ); 136 } 137 else 138 dVal = p->nDouble; 139 140 if( !o3tl::convertsToAtMost(o3tl::roundAway(dVal), SbxMAXINT) ) 141 { 142 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT; 143 } 144 else if( !o3tl::convertsToAtLeast(o3tl::roundAway(dVal), SbxMININT) ) 145 { 146 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMININT; 147 } 148 else 149 nRes = static_cast<sal_Int16>(rtl::math::round( dVal )); 150 break; 151 } 152 case SbxLPSTR: 153 case SbxSTRING: 154 case SbxBYREF | SbxSTRING: 155 if( !p->pOUString ) 156 nRes = 0; 157 else 158 { 159 double d; 160 SbxDataType t; 161 if( ImpScan( *p->pOUString, d, t, nullptr, true ) != ERRCODE_NONE ) 162 nRes = 0; 163 else if( !o3tl::convertsToAtMost(o3tl::roundAway(d), SbxMAXINT) ) 164 { 165 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMAXINT; 166 } 167 else if( !o3tl::convertsToAtLeast(o3tl::roundAway(d), SbxMININT) ) 168 { 169 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SbxMININT; 170 } 171 else 172 nRes = static_cast<sal_Int16>(rtl::math::round( d )); 173 } 174 break; 175 case SbxOBJECT: 176 { 177 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); 178 if( pVal ) 179 nRes = pVal->GetInteger(); 180 else 181 { 182 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0; 183 } 184 break; 185 } 186 187 case SbxBYREF | SbxCHAR: 188 nRes = *p->pChar; break; 189 case SbxBYREF | SbxBYTE: 190 nRes = *p->pByte; break; 191 case SbxBYREF | SbxINTEGER: 192 case SbxBYREF | SbxBOOL: 193 nRes = *p->pInteger; break; 194 195 // from here had to be tested 196 case SbxBYREF | SbxLONG: 197 aTmp.nLong = *p->pLong; goto ref; 198 case SbxBYREF | SbxULONG: 199 aTmp.nULong = *p->pULong; goto ref; 200 case SbxBYREF | SbxERROR: 201 case SbxBYREF | SbxUSHORT: 202 aTmp.nUShort = *p->pUShort; goto ref; 203 case SbxBYREF | SbxSINGLE: 204 aTmp.nSingle = *p->pSingle; goto ref; 205 case SbxBYREF | SbxDATE: 206 case SbxBYREF | SbxDOUBLE: 207 aTmp.nDouble = *p->pDouble; goto ref; 208 case SbxBYREF | SbxCURRENCY: 209 case SbxBYREF | SbxSALINT64: 210 aTmp.nInt64 = *p->pnInt64; goto ref; 211 case SbxBYREF | SbxSALUINT64: 212 aTmp.uInt64 = *p->puInt64; goto ref; 213 ref: 214 aTmp.eType = SbxDataType( p->eType & 0x0FFF ); 215 p = &aTmp; goto start; 216 217 default: 218 SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0; 219 } 220 return nRes; 221 } 222 223 void ImpPutInteger( SbxValues* p, sal_Int16 n ) 224 { 225 SbxValues aTmp; 226 start: 227 switch( +p->eType ) 228 { 229 // here had to be tested 230 case SbxCHAR: 231 aTmp.pChar = &p->nChar; goto direct; 232 case SbxBYTE: 233 aTmp.pByte = &p->nByte; goto direct; 234 case SbxULONG: 235 aTmp.pULong = &p->nULong; goto direct; 236 case SbxERROR: 237 case SbxUSHORT: 238 aTmp.pUShort = &p->nUShort; goto direct; 239 case SbxSALUINT64: 240 aTmp.puInt64 = &p->uInt64; goto direct; 241 direct: 242 aTmp.eType = SbxDataType( p->eType | SbxBYREF ); 243 p = &aTmp; goto start; 244 245 // from here no tests needed 246 case SbxINTEGER: 247 case SbxBOOL: 248 p->nInteger = n; break; 249 case SbxLONG: 250 p->nLong = n; break; 251 case SbxSINGLE: 252 p->nSingle = n; break; 253 case SbxDATE: 254 case SbxDOUBLE: 255 p->nDouble = n; break; 256 case SbxCURRENCY: 257 p->nInt64 = n * CURRENCY_FACTOR; break; 258 case SbxSALINT64: 259 p->nInt64 = n; break; 260 case SbxDECIMAL: 261 case SbxBYREF | SbxDECIMAL: 262 ImpCreateDecimal( p )->setInt( n ); 263 break; 264 265 case SbxLPSTR: 266 case SbxSTRING: 267 case SbxBYREF | SbxSTRING: 268 if( !p->pOUString ) 269 p->pOUString = new OUString; 270 ImpCvtNum( static_cast<double>(n), 0, *p->pOUString ); 271 break; 272 case SbxOBJECT: 273 { 274 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); 275 if( pVal ) 276 pVal->PutInteger( n ); 277 else 278 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); 279 break; 280 } 281 case SbxBYREF | SbxCHAR: 282 if( n < SbxMINCHAR ) 283 { 284 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINCHAR; 285 } 286 *p->pChar = static_cast<char>(n); break; 287 case SbxBYREF | SbxBYTE: 288 if( n > SbxMAXBYTE ) 289 { 290 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXBYTE; 291 } 292 else if( n < 0 ) 293 { 294 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0; 295 } 296 *p->pByte = static_cast<sal_uInt8>(n); break; 297 case SbxBYREF | SbxINTEGER: 298 case SbxBYREF | SbxBOOL: 299 *p->pInteger = n; break; 300 case SbxBYREF | SbxERROR: 301 case SbxBYREF | SbxUSHORT: 302 if( n < 0 ) 303 { 304 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0; 305 } 306 *p->pUShort = static_cast<sal_uInt16>(n); break; 307 case SbxBYREF | SbxLONG: 308 *p->pLong = static_cast<sal_Int32>(n); break; 309 case SbxBYREF | SbxULONG: 310 if( n < 0 ) 311 { 312 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0; 313 } 314 *p->pULong = static_cast<sal_uInt32>(n); break; 315 case SbxBYREF | SbxCURRENCY: 316 *p->pnInt64 = n * CURRENCY_FACTOR; break; 317 case SbxBYREF | SbxSALINT64: 318 *p->pnInt64 = n; break; 319 case SbxBYREF | SbxSALUINT64: 320 if( n < 0 ) 321 { 322 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); 323 *p->puInt64 = 0; 324 } 325 else 326 *p->puInt64 = n; 327 break; 328 case SbxBYREF | SbxSINGLE: 329 *p->pSingle = static_cast<float>(n); break; 330 case SbxBYREF | SbxDATE: 331 case SbxBYREF | SbxDOUBLE: 332 *p->pDouble = static_cast<double>(n); break; 333 334 default: 335 SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); 336 } 337 } 338 339 340 // sal_Int64 / hyper 341 342 sal_Int64 ImpDoubleToSalInt64( double d ) 343 { 344 sal_Int64 nRes; 345 if( !o3tl::convertsToAtMost(o3tl::roundAway(d), SAL_MAX_INT64) ) 346 { 347 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SAL_MAX_INT64; 348 } 349 else if( !o3tl::convertsToAtLeast(o3tl::roundAway(d), SAL_MIN_INT64) ) 350 { 351 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SAL_MIN_INT64; 352 } 353 else 354 nRes = static_cast<sal_Int64>(rtl::math::round( d )); 355 return nRes; 356 } 357 358 sal_uInt64 ImpDoubleToSalUInt64( double d ) 359 { 360 sal_uInt64 nRes; 361 if( !o3tl::convertsToAtMost(o3tl::roundAway(d), SAL_MAX_UINT64) ) 362 { 363 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SAL_MAX_UINT64; 364 } 365 else if( d < 0.0 ) 366 { 367 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0; 368 } 369 else 370 nRes = static_cast<sal_uInt64>(rtl::math::round( d )); 371 return nRes; 372 } 373 374 375 double ImpSalUInt64ToDouble( sal_uInt64 n ) 376 { 377 double d = 0.0; 378 if( n > SAL_MAX_INT64 ) 379 SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); 380 else 381 d = static_cast<double>(static_cast<sal_Int64>(n)); 382 return d; 383 } 384 385 386 sal_Int64 ImpGetInt64( const SbxValues* p ) 387 { 388 SbxValues aTmp; 389 sal_Int64 nRes; 390 start: 391 switch( +p->eType ) 392 { 393 case SbxNULL: 394 SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); 395 [[fallthrough]]; 396 case SbxEMPTY: 397 nRes = 0; break; 398 case SbxCHAR: 399 nRes = p->nChar; break; 400 case SbxBYTE: 401 nRes = p->nByte; break; 402 case SbxINTEGER: 403 case SbxBOOL: 404 nRes = p->nInteger; break; 405 case SbxERROR: 406 case SbxUSHORT: 407 nRes = static_cast<sal_Int64>(p->nUShort); break; 408 case SbxLONG: 409 nRes = static_cast<sal_Int64>(p->nLong); break; 410 case SbxULONG: 411 nRes = static_cast<sal_Int64>(p->nULong); break; 412 case SbxSINGLE: 413 nRes = static_cast<sal_Int64>(p->nSingle); 414 break; 415 case SbxDATE: 416 case SbxDOUBLE: 417 nRes = static_cast<sal_Int64>(p->nDouble); 418 break; 419 case SbxCURRENCY: 420 nRes = p->nInt64 / CURRENCY_FACTOR; break; 421 case SbxSALINT64: 422 nRes = p->nInt64; break; 423 case SbxSALUINT64: 424 if( p->uInt64 > SAL_MAX_INT64 ) 425 { 426 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SAL_MAX_INT64; 427 } 428 else 429 nRes = static_cast<sal_Int64>(p->uInt64); 430 break; 431 432 case SbxBYREF | SbxSTRING: 433 case SbxSTRING: 434 case SbxLPSTR: 435 if( !p->pOUString ) 436 nRes = 0; 437 else 438 { 439 ::OString aOStr = OUStringToOString( *p->pOUString, RTL_TEXTENCODING_ASCII_US ); 440 nRes = aOStr.toInt64(); 441 if( nRes == 0 ) 442 { 443 // Check if really 0 or invalid conversion 444 double d; 445 SbxDataType t; 446 if( ImpScan( *p->pOUString, d, t, nullptr, true ) != ERRCODE_NONE ) 447 nRes = 0; 448 else 449 nRes = static_cast<sal_Int64>(d); 450 } 451 } 452 break; 453 case SbxOBJECT: 454 { 455 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); 456 if( pVal ) 457 nRes = pVal->GetInt64(); 458 else 459 { 460 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0; 461 } 462 break; 463 } 464 465 case SbxBYREF | SbxCHAR: 466 nRes = *p->pChar; break; 467 case SbxBYREF | SbxBYTE: 468 nRes = *p->pByte; break; 469 case SbxBYREF | SbxINTEGER: 470 case SbxBYREF | SbxBOOL: 471 nRes = *p->pInteger; break; 472 case SbxBYREF | SbxLONG: 473 nRes = *p->pLong; break; 474 case SbxBYREF | SbxULONG: 475 nRes = *p->pULong; break; 476 case SbxBYREF | SbxCURRENCY: 477 nRes = p->nInt64 / CURRENCY_FACTOR; break; 478 case SbxBYREF | SbxSALINT64: 479 nRes = *p->pnInt64; break; 480 481 // from here the values has to be checked 482 case SbxBYREF | SbxSALUINT64: 483 aTmp.uInt64 = *p->puInt64; goto ref; 484 485 case SbxBYREF | SbxERROR: 486 case SbxBYREF | SbxUSHORT: 487 aTmp.nUShort = *p->pUShort; goto ref; 488 case SbxBYREF | SbxSINGLE: 489 aTmp.nSingle = *p->pSingle; goto ref; 490 case SbxBYREF | SbxDATE: 491 case SbxBYREF | SbxDOUBLE: 492 aTmp.nDouble = *p->pDouble; goto ref; 493 ref: 494 aTmp.eType = SbxDataType( p->eType & 0x0FFF ); 495 p = &aTmp; goto start; 496 497 default: 498 SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0; 499 } 500 return nRes; 501 } 502 503 void ImpPutInt64( SbxValues* p, sal_Int64 n ) 504 { 505 SbxValues aTmp; 506 507 start: 508 switch( +p->eType ) 509 { 510 // Check necessary 511 case SbxCHAR: 512 aTmp.pChar = &p->nChar; goto direct; 513 case SbxBYTE: 514 aTmp.pByte = &p->nByte; goto direct; 515 case SbxINTEGER: 516 case SbxBOOL: 517 aTmp.pInteger = &p->nInteger; goto direct; 518 case SbxULONG: 519 aTmp.pULong = &p->nULong; goto direct; 520 case SbxERROR: 521 case SbxUSHORT: 522 aTmp.pUShort = &p->nUShort; goto direct; 523 case SbxLONG: 524 aTmp.pnInt64 = &p->nInt64; goto direct; 525 case SbxCURRENCY: 526 case SbxSALINT64: 527 aTmp.pnInt64 = &p->nInt64; goto direct; 528 case SbxSALUINT64: 529 aTmp.puInt64 = &p->uInt64; goto direct; 530 531 direct: 532 aTmp.eType = SbxDataType( p->eType | SbxBYREF ); 533 p = &aTmp; goto start; 534 535 case SbxSINGLE: 536 p->nSingle = static_cast<float>(n); break; 537 case SbxDATE: 538 case SbxDOUBLE: 539 p->nDouble = static_cast<double>(n); break; 540 541 case SbxBYREF | SbxSTRING: 542 case SbxSTRING: 543 case SbxLPSTR: 544 { 545 if( !p->pOUString ) 546 p->pOUString = new OUString; 547 548 ::OString aOStr = OString::number( n ); 549 (*p->pOUString) = ::OStringToOUString( aOStr, RTL_TEXTENCODING_ASCII_US ); 550 break; 551 } 552 case SbxOBJECT: 553 { 554 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); 555 if( pVal ) 556 pVal->PutInt64( n ); 557 else 558 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); 559 break; 560 } 561 case SbxBYREF | SbxCHAR: 562 if( n > SbxMAXCHAR ) 563 { 564 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXCHAR; 565 } 566 else if( n < SbxMINCHAR ) 567 { 568 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINCHAR; 569 } 570 *p->pChar = static_cast<sal_Unicode>(n); break; 571 case SbxBYREF | SbxBYTE: 572 if( n > SbxMAXBYTE ) 573 { 574 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXBYTE; 575 } 576 else if( n < 0 ) 577 { 578 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0; 579 } 580 *p->pByte = static_cast<sal_uInt8>(n); break; 581 case SbxBYREF | SbxINTEGER: 582 case SbxBYREF | SbxBOOL: 583 if( n > SbxMAXINT ) 584 { 585 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXINT; 586 } 587 else if( n < SbxMININT ) 588 { 589 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMININT; 590 } 591 *p->pInteger = static_cast<sal_Int16>(n); break; 592 case SbxBYREF | SbxERROR: 593 case SbxBYREF | SbxUSHORT: 594 if( n > SbxMAXUINT ) 595 { 596 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXUINT; 597 } 598 else if( n < 0 ) 599 { 600 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0; 601 } 602 *p->pUShort = static_cast<sal_uInt16>(n); break; 603 case SbxBYREF | SbxLONG: 604 if( n > SbxMAXLNG ) 605 { 606 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXLNG; 607 } 608 else if( n < SbxMINLNG ) 609 { 610 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINLNG; 611 } 612 *p->pLong = static_cast<sal_Int32>(n); break; 613 case SbxBYREF | SbxULONG: 614 if( n > SbxMAXULNG ) 615 { 616 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXULNG; 617 } 618 else if( n < 0 ) 619 { 620 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0; 621 } 622 *p->pULong = static_cast<sal_uInt32>(n); break; 623 case SbxBYREF | SbxSINGLE: 624 *p->pSingle = static_cast<float>(n); break; 625 case SbxBYREF | SbxDATE: 626 case SbxBYREF | SbxDOUBLE: 627 *p->pDouble = static_cast<double>(n); break; 628 case SbxBYREF | SbxCURRENCY: 629 *p->pnInt64 = n * CURRENCY_FACTOR; break; 630 case SbxBYREF | SbxSALINT64: 631 *p->pnInt64 = n; break; 632 case SbxBYREF | SbxSALUINT64: 633 if( n < 0 ) 634 { 635 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0; 636 } 637 *p->puInt64 = n; break; 638 639 default: 640 SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); 641 } 642 } 643 644 sal_uInt64 ImpGetUInt64( const SbxValues* p ) 645 { 646 SbxValues aTmp; 647 sal_uInt64 nRes; 648 start: 649 switch( +p->eType ) 650 { 651 case SbxNULL: 652 SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); 653 [[fallthrough]]; 654 case SbxEMPTY: 655 nRes = 0; break; 656 case SbxCHAR: 657 nRes = p->nChar; break; 658 case SbxBYTE: 659 nRes = p->nByte; break; 660 case SbxINTEGER: 661 case SbxBOOL: 662 nRes = p->nInteger; break; 663 case SbxERROR: 664 case SbxUSHORT: 665 nRes = p->nUShort; break; 666 case SbxLONG: 667 nRes = p->nLong; break; 668 case SbxULONG: 669 nRes = static_cast<sal_uInt64>(p->nULong); break; 670 case SbxSINGLE: 671 nRes = static_cast<sal_uInt64>(p->nSingle); break; 672 case SbxDATE: 673 case SbxDOUBLE: 674 { 675 //TODO overflow check 676 nRes = static_cast<sal_uInt64>(p->nDouble); 677 break; 678 } 679 case SbxCURRENCY: 680 nRes = p->nInt64 * CURRENCY_FACTOR; break; 681 case SbxSALINT64: 682 if( p->nInt64 < 0 ) 683 { 684 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0; 685 } 686 else 687 nRes = static_cast<sal_uInt64>(p->nInt64); 688 break; 689 case SbxSALUINT64: 690 nRes = p->uInt64; break; 691 692 case SbxBYREF | SbxSTRING: 693 case SbxSTRING: 694 case SbxLPSTR: 695 if( !p->pOUString ) 696 nRes = 0; 697 else 698 { 699 ::OString aOStr = OUStringToOString 700 ( *p->pOUString, RTL_TEXTENCODING_ASCII_US ); 701 sal_Int64 n64 = aOStr.toInt64(); 702 if( n64 == 0 ) 703 { 704 // Check if really 0 or invalid conversion 705 double d; 706 SbxDataType t; 707 if( ImpScan( *p->pOUString, d, t, nullptr, true ) != ERRCODE_NONE ) 708 nRes = 0; 709 else if( !o3tl::convertsToAtMost(o3tl::roundAway(d), SAL_MAX_UINT64) ) 710 { 711 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = SAL_MAX_UINT64; 712 } 713 else if( d < 0.0 ) 714 { 715 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0; 716 } 717 else 718 nRes = static_cast<sal_uInt64>(rtl::math::round( d )); 719 } 720 else if( n64 < 0 ) 721 { 722 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0; 723 } 724 else 725 { 726 nRes = n64; 727 } 728 } 729 break; 730 case SbxOBJECT: 731 { 732 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); 733 if( pVal ) 734 nRes = pVal->GetUInt64(); 735 else 736 { 737 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0; 738 } 739 break; 740 } 741 742 case SbxBYREF | SbxCHAR: 743 nRes = *p->pChar; break; 744 case SbxBYREF | SbxBYTE: 745 nRes = *p->pByte; break; 746 case SbxBYREF | SbxINTEGER: 747 case SbxBYREF | SbxBOOL: 748 nRes = *p->pInteger; break; 749 case SbxBYREF | SbxLONG: 750 nRes = *p->pLong; break; 751 case SbxBYREF | SbxULONG: 752 nRes = *p->pULong; break; 753 case SbxBYREF | SbxSALUINT64: 754 nRes = *p->puInt64; break; 755 756 // from here on the value has to be checked 757 case SbxBYREF | SbxERROR: 758 case SbxBYREF | SbxUSHORT: 759 aTmp.nUShort = *p->pUShort; goto ref; 760 case SbxBYREF | SbxSINGLE: 761 aTmp.nSingle = *p->pSingle; goto ref; 762 case SbxBYREF | SbxDATE: 763 case SbxBYREF | SbxDOUBLE: 764 aTmp.nDouble = *p->pDouble; goto ref; 765 case SbxBYREF | SbxCURRENCY: 766 case SbxBYREF | SbxSALINT64: 767 aTmp.nInt64 = *p->pnInt64; goto ref; 768 ref: 769 aTmp.eType = SbxDataType( p->eType & 0x0FFF ); 770 p = &aTmp; goto start; 771 772 default: 773 SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0; 774 } 775 return nRes; 776 } 777 778 void ImpPutUInt64( SbxValues* p, sal_uInt64 n ) 779 { 780 SbxValues aTmp; 781 782 start: 783 switch( +p->eType ) 784 { 785 // Check necessary 786 case SbxCHAR: 787 aTmp.pChar = &p->nChar; goto direct; 788 case SbxBYTE: 789 aTmp.pByte = &p->nByte; goto direct; 790 case SbxINTEGER: 791 case SbxBOOL: 792 aTmp.pInteger = &p->nInteger; goto direct; 793 case SbxULONG: 794 aTmp.pULong = &p->nULong; goto direct; 795 case SbxERROR: 796 case SbxUSHORT: 797 aTmp.pUShort = &p->nUShort; goto direct; 798 case SbxLONG: 799 aTmp.pnInt64 = &p->nInt64; goto direct; 800 case SbxCURRENCY: 801 case SbxSALINT64: 802 aTmp.pnInt64 = &p->nInt64; goto direct; 803 case SbxSINGLE: 804 aTmp.pSingle = &p->nSingle; goto direct; 805 case SbxDATE: 806 case SbxDOUBLE: 807 aTmp.pDouble = &p->nDouble; goto direct; 808 809 direct: 810 aTmp.eType = SbxDataType( p->eType | SbxBYREF ); 811 p = &aTmp; goto start; 812 813 // Check not necessary 814 case SbxSALUINT64: 815 p->uInt64 = n; break; 816 817 case SbxBYREF | SbxSTRING: 818 case SbxSTRING: 819 case SbxLPSTR: 820 if( !p->pOUString ) 821 p->pOUString = new OUString; 822 if( n > SAL_MAX_INT64 ) 823 SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); 824 else 825 { 826 ::OString aOStr = OString::number( n ); 827 (*p->pOUString) = ::OStringToOUString( aOStr, RTL_TEXTENCODING_ASCII_US ); 828 } 829 break; 830 case SbxOBJECT: 831 { 832 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj ); 833 if( pVal ) 834 pVal->PutUInt64( n ); 835 else 836 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); 837 break; 838 } 839 case SbxBYREF | SbxCHAR: 840 if( n > SbxMAXCHAR ) 841 { 842 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXCHAR; 843 } 844 *p->pChar = static_cast<sal_Unicode>(n); break; 845 case SbxBYREF | SbxBYTE: 846 if( n > SbxMAXBYTE ) 847 { 848 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXBYTE; 849 } 850 *p->pByte = static_cast<sal_uInt8>(n); break; 851 case SbxBYREF | SbxINTEGER: 852 case SbxBYREF | SbxBOOL: 853 if( n > SbxMAXINT ) 854 { 855 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXINT; 856 } 857 *p->pInteger = static_cast<sal_Int16>(n); break; 858 case SbxBYREF | SbxERROR: 859 case SbxBYREF | SbxUSHORT: 860 if( n > SbxMAXUINT ) 861 { 862 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXUINT; 863 } 864 *p->pUShort = static_cast<sal_uInt16>(n); break; 865 case SbxBYREF | SbxLONG: 866 if( n > SbxMAXLNG ) 867 { 868 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXLNG; 869 } 870 *p->pLong = static_cast<sal_Int32>(n); break; 871 case SbxBYREF | SbxULONG: 872 if( n > SbxMAXULNG ) 873 { 874 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXULNG; 875 } 876 *p->pULong = static_cast<sal_uInt32>(n); break; 877 case SbxBYREF | SbxSINGLE: 878 *p->pDouble = static_cast<float>(ImpSalUInt64ToDouble( n )); break; 879 case SbxBYREF | SbxDATE: 880 case SbxBYREF | SbxDOUBLE: 881 882 *p->pDouble = ImpSalUInt64ToDouble( n ); break; 883 case SbxBYREF | SbxCURRENCY: 884 if ( n > ( SAL_MAX_INT64 / CURRENCY_FACTOR ) ) 885 { 886 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); 887 n = SAL_MAX_INT64; 888 } 889 *p->pnInt64 = static_cast<sal_Int64>( n * CURRENCY_FACTOR ); break; 890 case SbxBYREF | SbxSALUINT64: 891 *p->puInt64 = n; break; 892 case SbxBYREF | SbxSALINT64: 893 if( n > SAL_MAX_INT64 ) 894 { 895 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0; 896 } 897 *p->pnInt64 = static_cast<sal_Int64>(n); break; 898 899 default: 900 SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); 901 } 902 } 903 904 905 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 906
