1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_basic.hxx" 30 #include <tools/errcode.hxx> 31 #include <basic/sbx.hxx> 32 #include "sbxconv.hxx" 33 34 double ImpRound( double d ) 35 { 36 return d + ( d < 0 ? -0.5 : 0.5 ); 37 } 38 39 sal_Int16 ImpGetInteger( const SbxValues* p ) 40 { 41 SbxValues aTmp; 42 sal_Int16 nRes; 43 start: 44 switch( +p->eType ) 45 { 46 case SbxNULL: 47 SbxBase::SetError( SbxERR_CONVERSION ); 48 case SbxEMPTY: 49 nRes = 0; break; 50 case SbxCHAR: 51 nRes = p->nChar; break; 52 case SbxBYTE: 53 nRes = p->nByte; break; 54 case SbxINTEGER: 55 case SbxBOOL: 56 nRes = p->nInteger; break; 57 case SbxERROR: 58 case SbxUSHORT: 59 if( p->nUShort > (sal_uInt16) SbxMAXINT ) 60 { 61 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT; 62 } 63 else 64 nRes = (sal_Int16) p->nUShort; 65 break; 66 case SbxLONG: 67 if( p->nLong > SbxMAXINT ) 68 { 69 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT; 70 } 71 else if( p->nLong < SbxMININT ) 72 { 73 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT; 74 } 75 else 76 nRes = (sal_Int16) p->nLong; 77 break; 78 case SbxULONG: 79 if( p->nULong > SbxMAXINT ) 80 { 81 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT; 82 } 83 else 84 nRes = (sal_Int16) p->nULong; 85 break; 86 case SbxSINGLE: 87 if( p->nSingle > SbxMAXINT ) 88 { 89 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT; 90 } 91 else if( p->nSingle < SbxMININT ) 92 { 93 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT; 94 } 95 else 96 nRes = (sal_Int16) ImpRound( p->nSingle ); 97 break; 98 case SbxSALINT64: 99 if( p->nInt64 > SbxMAXINT ) 100 { 101 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT; 102 } 103 else if( p->nInt64 < SbxMININT ) 104 { 105 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT; 106 } 107 else 108 nRes = (sal_Int16) p->nInt64; 109 break; 110 case SbxSALUINT64: 111 if( p->uInt64 > SbxMAXINT ) 112 { 113 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT; 114 } 115 else 116 nRes = (sal_Int16) p->uInt64; 117 break; 118 case SbxDATE: 119 case SbxDOUBLE: 120 case SbxLONG64: 121 case SbxULONG64: 122 case SbxCURRENCY: 123 case SbxDECIMAL: 124 case SbxBYREF | SbxDECIMAL: 125 { 126 double dVal; 127 if( p->eType == SbxCURRENCY ) 128 dVal = ImpCurrencyToDouble( p->nLong64 ); 129 else if( p->eType == SbxLONG64 ) 130 dVal = ImpINT64ToDouble( p->nLong64 ); 131 else if( p->eType == SbxULONG64 ) 132 dVal = ImpUINT64ToDouble( p->nULong64 ); 133 else if( p->eType == SbxDECIMAL ) 134 { 135 dVal = 0.0; 136 if( p->pDecimal ) 137 p->pDecimal->getDouble( dVal ); 138 } 139 else 140 dVal = p->nDouble; 141 142 if( dVal > SbxMAXINT ) 143 { 144 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT; 145 } 146 else if( dVal < SbxMININT ) 147 { 148 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT; 149 } 150 else 151 nRes = (sal_Int16) ImpRound( dVal ); 152 break; 153 } 154 case SbxLPSTR: 155 case SbxSTRING: 156 case SbxBYREF | SbxSTRING: 157 if( !p->pOUString ) 158 nRes = 0; 159 else 160 { 161 double d; 162 SbxDataType t; 163 if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK ) 164 nRes = 0; 165 else if( d > SbxMAXINT ) 166 { 167 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT; 168 } 169 else if( d < SbxMININT ) 170 { 171 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT; 172 } 173 else 174 nRes = (sal_Int16) ImpRound( d ); 175 } 176 break; 177 case SbxOBJECT: 178 { 179 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj); 180 if( pVal ) 181 nRes = pVal->GetInteger(); 182 else 183 { 184 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0; 185 } 186 break; 187 } 188 189 case SbxBYREF | SbxCHAR: 190 nRes = *p->pChar; break; 191 case SbxBYREF | SbxBYTE: 192 nRes = *p->pByte; break; 193 case SbxBYREF | SbxINTEGER: 194 case SbxBYREF | SbxBOOL: 195 nRes = *p->pInteger; break; 196 197 // ab hier muss getestet werden 198 case SbxBYREF | SbxLONG: 199 aTmp.nLong = *p->pLong; goto ref; 200 case SbxBYREF | SbxULONG: 201 aTmp.nULong = *p->pULong; goto ref; 202 case SbxBYREF | SbxERROR: 203 case SbxBYREF | SbxUSHORT: 204 aTmp.nUShort = *p->pUShort; goto ref; 205 case SbxBYREF | SbxSINGLE: 206 aTmp.nSingle = *p->pSingle; goto ref; 207 case SbxBYREF | SbxDATE: 208 case SbxBYREF | SbxDOUBLE: 209 aTmp.nDouble = *p->pDouble; goto ref; 210 case SbxBYREF | SbxULONG64: 211 aTmp.nULong64 = *p->pULong64; goto ref; 212 case SbxBYREF | SbxLONG64: 213 case SbxBYREF | SbxCURRENCY: 214 aTmp.nLong64 = *p->pLong64; goto ref; 215 case SbxBYREF | SbxSALINT64: 216 aTmp.nInt64 = *p->pnInt64; goto ref; 217 case SbxBYREF | SbxSALUINT64: 218 aTmp.uInt64 = *p->puInt64; goto ref; 219 ref: 220 aTmp.eType = SbxDataType( p->eType & 0x0FFF ); 221 p = &aTmp; goto start; 222 223 default: 224 SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0; 225 } 226 return nRes; 227 } 228 229 void ImpPutInteger( SbxValues* p, sal_Int16 n ) 230 { 231 SbxValues aTmp; 232 start: 233 switch( +p->eType ) 234 { 235 // hier muss getestet werden 236 case SbxCHAR: 237 aTmp.pChar = &p->nChar; goto direct; 238 case SbxBYTE: 239 aTmp.pByte = &p->nByte; goto direct; 240 case SbxULONG: 241 aTmp.pULong = &p->nULong; goto direct; 242 case SbxERROR: 243 case SbxUSHORT: 244 aTmp.pUShort = &p->nUShort; goto direct; 245 case SbxSALUINT64: 246 aTmp.puInt64 = &p->uInt64; goto direct; 247 direct: 248 aTmp.eType = SbxDataType( p->eType | SbxBYREF ); 249 p = &aTmp; goto start; 250 251 // ab hier nicht mehr 252 case SbxINTEGER: 253 case SbxBOOL: 254 p->nInteger = n; break; 255 case SbxLONG: 256 p->nLong = n; break; 257 case SbxSINGLE: 258 p->nSingle = n; break; 259 case SbxDATE: 260 case SbxDOUBLE: 261 p->nDouble = n; break; 262 case SbxSALINT64: 263 p->nInt64 = n; break; 264 case SbxULONG64: 265 p->nULong64 = ImpDoubleToUINT64( (double)n ); break; 266 case SbxLONG64: 267 p->nLong64 = ImpDoubleToINT64( (double)n ); break; 268 case SbxCURRENCY: 269 p->nLong64 = ImpDoubleToCurrency( (double)n ); break; 270 case SbxDECIMAL: 271 case SbxBYREF | SbxDECIMAL: 272 ImpCreateDecimal( p )->setInt( n ); 273 break; 274 275 case SbxLPSTR: 276 case SbxSTRING: 277 case SbxBYREF | SbxSTRING: 278 if( !p->pOUString ) 279 p->pOUString = new ::rtl::OUString; 280 ImpCvtNum( (double) n, 0, *p->pOUString ); 281 break; 282 case SbxOBJECT: 283 { 284 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj); 285 if( pVal ) 286 pVal->PutInteger( n ); 287 else 288 SbxBase::SetError( SbxERR_NO_OBJECT ); 289 break; 290 } 291 case SbxBYREF | SbxCHAR: 292 if( n < SbxMINCHAR ) 293 { 294 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR; 295 } 296 *p->pChar = (char) n; break; 297 case SbxBYREF | SbxBYTE: 298 if( n > SbxMAXBYTE ) 299 { 300 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE; 301 } 302 else if( n < 0 ) 303 { 304 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0; 305 } 306 *p->pByte = (sal_uInt8) n; break; 307 case SbxBYREF | SbxINTEGER: 308 case SbxBYREF | SbxBOOL: 309 *p->pInteger = n; break; 310 case SbxBYREF | SbxERROR: 311 case SbxBYREF | SbxUSHORT: 312 if( n < 0 ) 313 { 314 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0; 315 } 316 *p->pUShort = (sal_uInt16) n; break; 317 case SbxBYREF | SbxLONG: 318 *p->pLong = (sal_Int32) n; break; 319 case SbxBYREF | SbxULONG: 320 if( n < 0 ) 321 { 322 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0; 323 } 324 *p->pULong = (sal_uInt32) n; break; 325 case SbxBYREF | SbxSALINT64: 326 *p->pnInt64 = n; break; 327 case SbxBYREF | SbxSALUINT64: 328 if( n < 0 ) 329 { 330 SbxBase::SetError( SbxERR_OVERFLOW ); *p->puInt64 = 0; 331 } 332 else 333 *p->puInt64 = n; 334 break; 335 case SbxBYREF | SbxSINGLE: 336 *p->pSingle = (float) n; break; 337 case SbxBYREF | SbxDATE: 338 case SbxBYREF | SbxDOUBLE: 339 *p->pDouble = (double) n; break; 340 case SbxBYREF | SbxULONG64: 341 *p->pULong64 = ImpDoubleToUINT64( (double)n ); break; 342 case SbxBYREF | SbxLONG64: 343 *p->pLong64 = ImpDoubleToINT64( (double)n ); break; 344 case SbxBYREF | SbxCURRENCY: 345 *p->pLong64 = ImpDoubleToCurrency( (double)n ); break; 346 347 default: 348 SbxBase::SetError( SbxERR_CONVERSION ); 349 } 350 } 351 352 353 // sal_Int64 / hyper 354 355 sal_Int64 ImpDoubleToSalInt64( double d ) 356 { 357 sal_Int64 nRes; 358 if( d > SbxMAXSALINT64 ) 359 { 360 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALINT64; 361 } 362 else if( d < SbxMINSALINT64 ) 363 { 364 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINSALINT64; 365 } 366 else 367 nRes = (sal_Int64) ImpRound( d ); 368 return nRes; 369 } 370 371 sal_uInt64 ImpDoubleToSalUInt64( double d ) 372 { 373 sal_uInt64 nRes; 374 if( d > SbxMAXSALUINT64 ) 375 { 376 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALUINT64; 377 } 378 else if( d < 0.0 ) 379 { 380 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0; 381 } 382 else 383 nRes = (sal_uInt64) ImpRound( d ); 384 return nRes; 385 } 386 387 double ImpSalUInt64ToDouble( sal_uInt64 n ) 388 { 389 double d = 0.0; 390 if( n > SbxMAXSALINT64 ) 391 SbxBase::SetError( SbxERR_CONVERSION ); 392 else 393 d = (double)(sal_Int64) n; 394 return d; 395 } 396 397 398 sal_Int64 ImpGetInt64( const SbxValues* p ) 399 { 400 SbxValues aTmp; 401 sal_Int64 nRes; 402 start: 403 switch( +p->eType ) 404 { 405 case SbxNULL: 406 SbxBase::SetError( SbxERR_CONVERSION ); 407 case SbxEMPTY: 408 nRes = 0; break; 409 case SbxCHAR: 410 nRes = p->nChar; break; 411 case SbxBYTE: 412 nRes = p->nByte; break; 413 case SbxINTEGER: 414 case SbxBOOL: 415 nRes = p->nInteger; break; 416 case SbxERROR: 417 case SbxUSHORT: 418 nRes = p->nUShort; break; 419 case SbxLONG: 420 nRes = p->nLong; break; 421 case SbxULONG: 422 nRes = (sal_Int64) p->nULong; break; 423 case SbxSINGLE: 424 nRes = ImpDoubleToSalInt64( (double)p->nSingle ); 425 break; 426 case SbxDATE: 427 case SbxDOUBLE: 428 case SbxLONG64: 429 case SbxULONG64: 430 case SbxCURRENCY: 431 { 432 double dVal; 433 if( p->eType == SbxCURRENCY ) 434 dVal = ImpCurrencyToDouble( p->nLong64 ); 435 else if( p->eType == SbxLONG64 ) 436 dVal = ImpINT64ToDouble( p->nLong64 ); 437 else if( p->eType == SbxULONG64 ) 438 dVal = ImpUINT64ToDouble( p->nULong64 ); 439 else 440 dVal = p->nDouble; 441 442 nRes = ImpDoubleToSalInt64( dVal ); 443 break; 444 } 445 case SbxSALINT64: 446 nRes = p->nInt64; break; 447 case SbxSALUINT64: 448 if( p->uInt64 > SbxMAXSALINT64 ) 449 { 450 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALINT64; 451 } 452 else 453 nRes = (sal_Int64) p->uInt64; 454 break; 455 456 case SbxBYREF | SbxSTRING: 457 case SbxSTRING: 458 case SbxLPSTR: 459 if( !p->pOUString ) 460 nRes = 0; 461 else 462 { 463 ::rtl::OString aOStr = ::rtl::OUStringToOString 464 ( *p->pOUString, RTL_TEXTENCODING_ASCII_US ); 465 nRes = aOStr.toInt64(); 466 if( nRes == 0 ) 467 { 468 // Check if really 0 or invalid conversion 469 double d; 470 SbxDataType t; 471 if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK ) 472 nRes = 0; 473 else 474 nRes = ImpDoubleToSalInt64( d ); 475 } 476 } 477 break; 478 case SbxOBJECT: 479 { 480 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj); 481 if( pVal ) 482 nRes = pVal->GetInt64(); 483 else 484 { 485 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0; 486 } 487 break; 488 } 489 490 case SbxBYREF | SbxCHAR: 491 nRes = *p->pChar; break; 492 case SbxBYREF | SbxBYTE: 493 nRes = *p->pByte; break; 494 case SbxBYREF | SbxINTEGER: 495 case SbxBYREF | SbxBOOL: 496 nRes = *p->pInteger; break; 497 case SbxBYREF | SbxLONG: 498 nRes = *p->pLong; break; 499 case SbxBYREF | SbxULONG: 500 nRes = *p->pULong; break; 501 case SbxBYREF | SbxSALINT64: 502 nRes = *p->pnInt64; break; 503 504 // from here the values has to be checked 505 case SbxBYREF | SbxERROR: 506 case SbxBYREF | SbxUSHORT: 507 aTmp.nUShort = *p->pUShort; goto ref; 508 case SbxBYREF | SbxSINGLE: 509 aTmp.nSingle = *p->pSingle; goto ref; 510 case SbxBYREF | SbxDATE: 511 case SbxBYREF | SbxDOUBLE: 512 aTmp.nDouble = *p->pDouble; goto ref; 513 case SbxBYREF | SbxULONG64: 514 aTmp.nULong64 = *p->pULong64; goto ref; 515 case SbxBYREF | SbxLONG64: 516 case SbxBYREF | SbxCURRENCY: 517 aTmp.nLong64 = *p->pLong64; goto ref; 518 case SbxBYREF | SbxSALUINT64: 519 aTmp.uInt64 = *p->puInt64; goto ref; 520 ref: 521 aTmp.eType = SbxDataType( p->eType & 0x0FFF ); 522 p = &aTmp; goto start; 523 524 default: 525 SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0; 526 } 527 return nRes; 528 } 529 530 void ImpPutInt64( SbxValues* p, sal_Int64 n ) 531 { 532 SbxValues aTmp; 533 534 start: 535 switch( +p->eType ) 536 { 537 // Check neccessary 538 case SbxCHAR: 539 aTmp.pChar = &p->nChar; goto direct; 540 case SbxBYTE: 541 aTmp.pByte = &p->nByte; goto direct; 542 case SbxINTEGER: 543 case SbxBOOL: 544 aTmp.pInteger = &p->nInteger; goto direct; 545 case SbxULONG64: 546 aTmp.pULong64 = &p->nULong64; goto direct; 547 case SbxLONG64: 548 case SbxCURRENCY: 549 aTmp.pLong64 = &p->nLong64; goto direct; 550 case SbxULONG: 551 aTmp.pULong = &p->nULong; goto direct; 552 case SbxERROR: 553 case SbxUSHORT: 554 aTmp.pUShort = &p->nUShort; goto direct; 555 case SbxLONG: 556 aTmp.pnInt64 = &p->nInt64; goto direct; 557 case SbxSALUINT64: 558 aTmp.puInt64 = &p->uInt64; goto direct; 559 560 direct: 561 aTmp.eType = SbxDataType( p->eType | SbxBYREF ); 562 p = &aTmp; goto start; 563 564 // Check not neccessary 565 case SbxSALINT64: 566 p->nInt64 = n; break; 567 case SbxSINGLE: 568 p->nSingle = (float) n; break; 569 case SbxDATE: 570 case SbxDOUBLE: 571 p->nDouble = (double) n; break; 572 573 case SbxBYREF | SbxSTRING: 574 case SbxSTRING: 575 case SbxLPSTR: 576 { 577 if( !p->pOUString ) 578 p->pOUString = new ::rtl::OUString; 579 580 ::rtl::OString aOStr = ::rtl::OString::valueOf( n ); 581 (*p->pOUString) = ::rtl::OStringToOUString 582 ( aOStr, RTL_TEXTENCODING_ASCII_US ); 583 break; 584 } 585 case SbxOBJECT: 586 { 587 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj); 588 if( pVal ) 589 pVal->PutInt64( n ); 590 else 591 SbxBase::SetError( SbxERR_NO_OBJECT ); 592 break; 593 } 594 case SbxBYREF | SbxCHAR: 595 if( n > SbxMAXCHAR ) 596 { 597 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR; 598 } 599 else if( n < SbxMINCHAR ) 600 { 601 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR; 602 } 603 *p->pChar = (xub_Unicode) n; break; 604 case SbxBYREF | SbxBYTE: 605 if( n > SbxMAXBYTE ) 606 { 607 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE; 608 } 609 else if( n < 0 ) 610 { 611 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0; 612 } 613 *p->pByte = (sal_uInt8) n; break; 614 case SbxBYREF | SbxINTEGER: 615 case SbxBYREF | SbxBOOL: 616 if( n > SbxMAXINT ) 617 { 618 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT; 619 } 620 else if( n < SbxMININT ) 621 { 622 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT; 623 } 624 *p->pInteger = (sal_Int16) n; break; 625 case SbxBYREF | SbxERROR: 626 case SbxBYREF | SbxUSHORT: 627 if( n > SbxMAXUINT ) 628 { 629 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT; 630 } 631 else if( n < 0 ) 632 { 633 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0; 634 } 635 *p->pUShort = (sal_uInt16) n; break; 636 case SbxBYREF | SbxLONG: 637 if( n > SbxMAXLNG ) 638 { 639 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG; 640 } 641 else if( n < SbxMINLNG ) 642 { 643 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG; 644 } 645 *p->pLong = (sal_Int32) n; break; 646 case SbxBYREF | SbxULONG: 647 if( n > SbxMAXULNG ) 648 { 649 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG; 650 } 651 else if( n < 0 ) 652 { 653 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0; 654 } 655 *p->pULong = (sal_uInt32) n; break; 656 case SbxBYREF | SbxSINGLE: 657 *p->pSingle = (float) n; break; 658 case SbxBYREF | SbxDATE: 659 case SbxBYREF | SbxDOUBLE: 660 *p->pDouble = (double) n; break; 661 case SbxBYREF | SbxCURRENCY: 662 if( n > SbxMAXCURR ) 663 { 664 SbxBase::SetError( SbxERR_OVERFLOW ); n = (sal_Int64) SbxMAXCURR; 665 } 666 else if( n < SbxMINCURR ) 667 { 668 SbxBase::SetError( SbxERR_OVERFLOW ); n = (sal_Int64) SbxMINCURR; 669 } 670 *p->pLong64 = ImpDoubleToCurrency( (double)n ); break; 671 672 case SbxBYREF | SbxSALINT64: 673 *p->pnInt64 = n; break; 674 case SbxBYREF | SbxSALUINT64: 675 if( n < 0 ) 676 { 677 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0; 678 } 679 *p->puInt64 = (sal_Int64) n; break; 680 681 default: 682 SbxBase::SetError( SbxERR_CONVERSION ); 683 } 684 } 685 686 sal_uInt64 ImpGetUInt64( const SbxValues* p ) 687 { 688 SbxValues aTmp; 689 sal_uInt64 nRes; 690 start: 691 switch( +p->eType ) 692 { 693 case SbxNULL: 694 SbxBase::SetError( SbxERR_CONVERSION ); 695 case SbxEMPTY: 696 nRes = 0; break; 697 case SbxCHAR: 698 nRes = p->nChar; break; 699 case SbxBYTE: 700 nRes = p->nByte; break; 701 case SbxINTEGER: 702 case SbxBOOL: 703 nRes = p->nInteger; break; 704 case SbxERROR: 705 case SbxUSHORT: 706 nRes = p->nUShort; break; 707 case SbxLONG: 708 nRes = p->nLong; break; 709 case SbxULONG: 710 nRes = (sal_uInt64) p->nULong; break; 711 case SbxSINGLE: 712 nRes = ImpDoubleToSalUInt64( (double)p->nSingle ); 713 break; 714 case SbxDATE: 715 case SbxDOUBLE: 716 case SbxLONG64: 717 case SbxULONG64: 718 case SbxCURRENCY: 719 { 720 double dVal; 721 if( p->eType == SbxCURRENCY ) 722 dVal = ImpCurrencyToDouble( p->nLong64 ); 723 else if( p->eType == SbxLONG64 ) 724 dVal = ImpINT64ToDouble( p->nLong64 ); 725 else if( p->eType == SbxULONG64 ) 726 dVal = ImpUINT64ToDouble( p->nULong64 ); 727 else 728 dVal = p->nDouble; 729 730 nRes = ImpDoubleToSalUInt64( dVal ); 731 break; 732 } 733 case SbxSALINT64: 734 if( p->nInt64 < 0 ) 735 { 736 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0; 737 } 738 else 739 nRes = (sal_uInt64) p->nInt64; 740 case SbxSALUINT64: 741 nRes = p->uInt64; break; 742 743 case SbxBYREF | SbxSTRING: 744 case SbxSTRING: 745 case SbxLPSTR: 746 if( !p->pOUString ) 747 nRes = 0; 748 else 749 { 750 ::rtl::OString aOStr = ::rtl::OUStringToOString 751 ( *p->pOUString, RTL_TEXTENCODING_ASCII_US ); 752 sal_Int64 n64 = aOStr.toInt64(); 753 if( n64 == 0 ) 754 { 755 // Check if really 0 or invalid conversion 756 double d; 757 SbxDataType t; 758 if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK ) 759 nRes = 0; 760 else if( d > SbxMAXSALUINT64 ) 761 { 762 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALUINT64; 763 } 764 else if( d < 0.0 ) 765 { 766 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0; 767 } 768 else 769 nRes = (sal_uInt64) ImpRound( d ); 770 } 771 else if( n64 < 0 ) 772 { 773 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0; 774 } 775 else 776 { 777 nRes = n64; 778 } 779 } 780 break; 781 case SbxOBJECT: 782 { 783 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj); 784 if( pVal ) 785 nRes = pVal->GetUInt64(); 786 else 787 { 788 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0; 789 } 790 break; 791 } 792 793 case SbxBYREF | SbxCHAR: 794 nRes = *p->pChar; break; 795 case SbxBYREF | SbxBYTE: 796 nRes = *p->pByte; break; 797 case SbxBYREF | SbxINTEGER: 798 case SbxBYREF | SbxBOOL: 799 nRes = *p->pInteger; break; 800 case SbxBYREF | SbxLONG: 801 nRes = *p->pLong; break; 802 case SbxBYREF | SbxULONG: 803 nRes = *p->pULong; break; 804 case SbxBYREF | SbxSALUINT64: 805 nRes = *p->puInt64; break; 806 807 // from here the values has to be checked 808 case SbxBYREF | SbxERROR: 809 case SbxBYREF | SbxUSHORT: 810 aTmp.nUShort = *p->pUShort; goto ref; 811 case SbxBYREF | SbxSINGLE: 812 aTmp.nSingle = *p->pSingle; goto ref; 813 case SbxBYREF | SbxDATE: 814 case SbxBYREF | SbxDOUBLE: 815 aTmp.nDouble = *p->pDouble; goto ref; 816 case SbxBYREF | SbxULONG64: 817 aTmp.nULong64 = *p->pULong64; goto ref; 818 case SbxBYREF | SbxLONG64: 819 case SbxBYREF | SbxCURRENCY: 820 aTmp.nLong64 = *p->pLong64; goto ref; 821 case SbxBYREF | SbxSALINT64: 822 aTmp.nInt64 = *p->pnInt64; goto ref; 823 ref: 824 aTmp.eType = SbxDataType( p->eType & 0x0FFF ); 825 p = &aTmp; goto start; 826 827 default: 828 SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0; 829 } 830 return nRes; 831 } 832 833 void ImpPutUInt64( SbxValues* p, sal_uInt64 n ) 834 { 835 SbxValues aTmp; 836 837 start: 838 switch( +p->eType ) 839 { 840 // Check neccessary 841 case SbxCHAR: 842 aTmp.pChar = &p->nChar; goto direct; 843 case SbxBYTE: 844 aTmp.pByte = &p->nByte; goto direct; 845 case SbxINTEGER: 846 case SbxBOOL: 847 aTmp.pInteger = &p->nInteger; goto direct; 848 case SbxULONG64: 849 aTmp.pULong64 = &p->nULong64; goto direct; 850 case SbxLONG64: 851 case SbxCURRENCY: 852 aTmp.pLong64 = &p->nLong64; goto direct; 853 case SbxULONG: 854 aTmp.pULong = &p->nULong; goto direct; 855 case SbxERROR: 856 case SbxUSHORT: 857 aTmp.pUShort = &p->nUShort; goto direct; 858 case SbxLONG: 859 aTmp.pnInt64 = &p->nInt64; goto direct; 860 case SbxSALINT64: 861 aTmp.pnInt64 = &p->nInt64; goto direct; 862 case SbxSINGLE: 863 aTmp.pSingle = &p->nSingle; goto direct; 864 case SbxDATE: 865 case SbxDOUBLE: 866 aTmp.pDouble = &p->nDouble; goto direct; 867 868 direct: 869 aTmp.eType = SbxDataType( p->eType | SbxBYREF ); 870 p = &aTmp; goto start; 871 872 // Check not neccessary 873 case SbxSALUINT64: 874 p->uInt64 = n; break; 875 876 case SbxBYREF | SbxSTRING: 877 case SbxSTRING: 878 case SbxLPSTR: 879 if( !p->pOUString ) 880 p->pOUString = new ::rtl::OUString; 881 if( n > SbxMAXSALINT64 ) 882 SbxBase::SetError( SbxERR_CONVERSION ); 883 else 884 { 885 ::rtl::OString aOStr = ::rtl::OString::valueOf( (sal_Int64)n ); 886 (*p->pOUString) = ::rtl::OStringToOUString 887 ( aOStr, RTL_TEXTENCODING_ASCII_US ); 888 } 889 break; 890 case SbxOBJECT: 891 { 892 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj); 893 if( pVal ) 894 pVal->PutUInt64( n ); 895 else 896 SbxBase::SetError( SbxERR_NO_OBJECT ); 897 break; 898 } 899 case SbxBYREF | SbxCHAR: 900 if( n > SbxMAXCHAR ) 901 { 902 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR; 903 } 904 *p->pChar = (xub_Unicode) n; break; 905 case SbxBYREF | SbxBYTE: 906 if( n > SbxMAXBYTE ) 907 { 908 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE; 909 } 910 *p->pByte = (sal_uInt8) n; break; 911 case SbxBYREF | SbxINTEGER: 912 case SbxBYREF | SbxBOOL: 913 if( n > SbxMAXINT ) 914 { 915 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT; 916 } 917 *p->pInteger = (sal_Int16) n; break; 918 case SbxBYREF | SbxERROR: 919 case SbxBYREF | SbxUSHORT: 920 if( n > SbxMAXUINT ) 921 { 922 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT; 923 } 924 *p->pUShort = (sal_uInt16) n; break; 925 case SbxBYREF | SbxLONG: 926 if( n > SbxMAXLNG ) 927 { 928 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG; 929 } 930 *p->pLong = (sal_Int32) n; break; 931 case SbxBYREF | SbxULONG: 932 if( n > SbxMAXULNG ) 933 { 934 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG; 935 } 936 *p->pULong = (sal_uInt32) n; break; 937 case SbxBYREF | SbxSINGLE: 938 *p->pDouble = (float)ImpSalUInt64ToDouble( n ); break; 939 case SbxBYREF | SbxDATE: 940 case SbxBYREF | SbxDOUBLE: 941 *p->pDouble = ImpSalUInt64ToDouble( n ); break; 942 case SbxBYREF | SbxCURRENCY: 943 if( n > SbxMAXSALINT64 || (sal_Int64)n > SbxMAXCURR ) 944 { 945 SbxBase::SetError( SbxERR_OVERFLOW ); n = (sal_Int64) SbxMAXCURR; 946 } 947 *p->pLong64 = ImpDoubleToCurrency( (double)(sal_Int64) n ); break; 948 949 case SbxBYREF | SbxSALUINT64: 950 *p->puInt64 = n; break; 951 case SbxBYREF | SbxSALINT64: 952 if( n > SbxMAXSALINT64 ) 953 { 954 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0; 955 } 956 *p->pnInt64 = (sal_Int64) n; break; 957 958 default: 959 SbxBase::SetError( SbxERR_CONVERSION ); 960 } 961 } 962 963 964