1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_basic.hxx" 26 27 #define _TLBIGINT_INT64 28 #include <tools/bigint.hxx> 29 #include <tools/stream.hxx> 30 31 #include <basic/sbx.hxx> 32 #include "sbxconv.hxx" 33 #include <math.h> 34 #include "runtime.hxx" 35 // AB 29.10.99 Unicode 36 #ifndef _USE_NO_NAMESPACE 37 using namespace rtl; 38 #endif 39 40 41 TYPEINIT1(SbxValue,SbxBase) 42 43 /////////////////////////// SbxINT64 ///////////////////////////////////// 44 SbxINT64 &SbxINT64::operator -= ( const SbxINT64 &r ) 45 { 46 BigInt b( *this ); 47 b -= BigInt( r ); 48 b.INT64( this ); 49 return *this; 50 } 51 SbxINT64 &SbxINT64::operator += ( const SbxINT64 &r ) 52 { 53 BigInt b( *this ); 54 b += BigInt( r ); 55 b.INT64( this ); 56 return *this; 57 } 58 SbxINT64 &SbxINT64::operator *= ( const SbxINT64 &r ) 59 { 60 BigInt b( *this ); 61 b *= BigInt( r ); 62 b.INT64( this ); 63 return *this; 64 } 65 SbxINT64 &SbxINT64::operator %= ( const SbxINT64 &r ) 66 { 67 BigInt b( *this ); 68 b %= BigInt( r ); 69 b.INT64( this ); 70 return *this; 71 } 72 SbxINT64 &SbxINT64::operator /= ( const SbxINT64 &r ) 73 { 74 BigInt b( *this ); 75 b /= BigInt( r ); 76 b.INT64( this ); 77 return *this; 78 } 79 SbxINT64 &SbxINT64::operator &= ( const SbxINT64 &r ) 80 { 81 nHigh &= r.nHigh; 82 nLow &= r.nLow; 83 return *this; 84 } 85 SbxINT64 &SbxINT64::operator |= ( const SbxINT64 &r ) 86 { 87 nHigh |= r.nHigh; 88 nLow |= r.nLow; 89 return *this; 90 } 91 SbxINT64 &SbxINT64::operator ^= ( const SbxINT64 &r ) 92 { 93 nHigh ^= r.nHigh; 94 nLow ^= r.nLow; 95 return *this; 96 } 97 98 SbxINT64 operator - ( const SbxINT64 &l, const SbxINT64 &r ) 99 { 100 SbxINT64 a(l); 101 a -= r; 102 return a; 103 } 104 SbxINT64 operator + ( const SbxINT64 &l, const SbxINT64 &r ) 105 { 106 SbxINT64 a(l); 107 a += r; 108 return a; 109 } 110 SbxINT64 operator / ( const SbxINT64 &l, const SbxINT64 &r ) 111 { 112 SbxINT64 a(l); 113 a /= r; 114 return a; 115 } 116 SbxINT64 operator % ( const SbxINT64 &l, const SbxINT64 &r ) 117 { 118 SbxINT64 a(l); 119 a %= r; 120 return a; 121 } 122 SbxINT64 operator * ( const SbxINT64 &l, const SbxINT64 &r ) 123 { 124 SbxINT64 a(l); 125 a *= r; 126 return a; 127 } 128 SbxINT64 operator & ( const SbxINT64 &l, const SbxINT64 &r ) 129 { 130 SbxINT64 a; 131 a.nHigh = r.nHigh & l.nHigh; 132 a.nLow = r.nLow & l.nLow; 133 return a; 134 } 135 SbxINT64 operator | ( const SbxINT64 &l, const SbxINT64 &r ) 136 { 137 SbxINT64 a; 138 a.nHigh = r.nHigh | l.nHigh; 139 a.nLow = r.nLow | l.nLow; 140 return a; 141 } 142 SbxINT64 operator ^ ( const SbxINT64 &r, const SbxINT64 &l ) 143 { 144 SbxINT64 a; 145 a.nHigh = r.nHigh ^ l.nHigh; 146 a.nLow = r.nLow ^ l.nLow; 147 return a; 148 } 149 150 SbxINT64 operator - ( const SbxINT64 &r ) 151 { 152 SbxINT64 a( r ); 153 a.CHS(); 154 return a; 155 } 156 SbxINT64 operator ~ ( const SbxINT64 &r ) 157 { 158 SbxINT64 a; 159 a.nHigh = ~r.nHigh; 160 a.nLow = ~r.nLow; 161 return a; 162 } 163 164 SbxUINT64 &SbxUINT64::operator %= ( const SbxUINT64 &r ) 165 { 166 BigInt b( *this ); 167 b %= BigInt( r ); 168 b.UINT64( this ); 169 return *this; 170 } 171 SbxUINT64 &SbxUINT64::operator /= ( const SbxUINT64 &r ) 172 { 173 BigInt b( *this ); 174 b /= BigInt( r ); 175 b.UINT64( this ); 176 return *this; 177 } 178 /////////////////////////// Fehlerbehandlung ///////////////////////////// 179 180 #ifdef _USED 181 // NOCH NACHZUBAUEN! 182 183 // Das Default-Handling setzt nur den Fehlercode. 184 185 #ifndef WNT 186 #if defined ( UNX ) 187 int matherr( struct exception* p ) 188 #else 189 int matherr( struct _exception* p ) 190 #endif 191 { 192 switch( p->type ) 193 { 194 #if defined ( UNX ) 195 case OVERFLOW: SbxBase::SetError( SbxERR_OVERFLOW ); break; 196 #else 197 case _OVERFLOW: SbxBase::SetError( SbxERR_OVERFLOW ); break; 198 #endif 199 default: SbxBase::SetError( SbxERR_NOTIMP ); break; 200 } 201 return sal_True; 202 } 203 #endif 204 205 #endif // _USED 206 207 208 ///////////////////////////// Konstruktoren ////////////////////////////// 209 210 SbxValue::SbxValue() : SbxBase() 211 { 212 aData.eType = SbxEMPTY; 213 } 214 215 SbxValue::SbxValue( SbxDataType t, void* p ) : SbxBase() 216 { 217 int n = t & 0x0FFF; 218 if( p ) 219 n |= SbxBYREF; 220 if( n == SbxVARIANT ) 221 n = SbxEMPTY; 222 else 223 SetFlag( SBX_FIXED ); 224 if( p ) 225 switch( t & 0x0FFF ) 226 { 227 case SbxINTEGER: n |= SbxBYREF; aData.pInteger = (sal_Int16*) p; break; 228 case SbxULONG64: n |= SbxBYREF; aData.pULong64 = (SbxUINT64*) p; break; 229 case SbxLONG64: 230 case SbxCURRENCY: n |= SbxBYREF; aData.pLong64 = (SbxINT64*) p; break; 231 case SbxLONG: n |= SbxBYREF; aData.pLong = (sal_Int32*) p; break; 232 case SbxSINGLE: n |= SbxBYREF; aData.pSingle = (float*) p; break; 233 case SbxDATE: 234 case SbxDOUBLE: n |= SbxBYREF; aData.pDouble = (double*) p; break; 235 case SbxSTRING: n |= SbxBYREF; aData.pOUString = (::rtl::OUString*) p; break; 236 case SbxERROR: 237 case SbxUSHORT: 238 case SbxBOOL: n |= SbxBYREF; aData.pUShort = (sal_uInt16*) p; break; 239 case SbxULONG: n |= SbxBYREF; aData.pULong = (sal_uInt32*) p; break; 240 case SbxCHAR: n |= SbxBYREF; aData.pChar = (xub_Unicode*) p; break; 241 case SbxBYTE: n |= SbxBYREF; aData.pByte = (sal_uInt8*) p; break; 242 case SbxINT: n |= SbxBYREF; aData.pInt = (int*) p; break; 243 case SbxOBJECT: 244 aData.pObj = (SbxBase*) p; 245 if( p ) 246 aData.pObj->AddRef(); 247 break; 248 case SbxDECIMAL: 249 aData.pDecimal = (SbxDecimal*) p; 250 if( p ) 251 aData.pDecimal->addRef(); 252 break; 253 default: 254 DBG_ASSERT( !this, "Angabe eines Pointers unzulaessig" ); 255 n = SbxNULL; 256 } 257 else 258 memset( &aData, 0, sizeof( SbxValues ) ); 259 aData.eType = SbxDataType( n ); 260 } 261 262 SbxValue::SbxValue( const SbxValue& r ) 263 : SvRefBase( r ), SbxBase( r ) 264 { 265 if( !r.CanRead() ) 266 { 267 SetError( SbxERR_PROP_WRITEONLY ); 268 if( !IsFixed() ) 269 aData.eType = SbxNULL; 270 } 271 else 272 { 273 ((SbxValue*) &r)->Broadcast( SBX_HINT_DATAWANTED ); 274 aData = r.aData; 275 // Pointer kopieren, Referenzen inkrementieren 276 switch( aData.eType ) 277 { 278 case SbxSTRING: 279 if( aData.pOUString ) 280 aData.pOUString = new ::rtl::OUString( *aData.pOUString ); 281 break; 282 case SbxOBJECT: 283 if( aData.pObj ) 284 aData.pObj->AddRef(); 285 break; 286 case SbxDECIMAL: 287 if( aData.pDecimal ) 288 aData.pDecimal->addRef(); 289 break; 290 default: break; 291 } 292 } 293 } 294 295 SbxValue& SbxValue::operator=( const SbxValue& r ) 296 { 297 if( &r != this ) 298 { 299 if( !CanWrite() ) 300 SetError( SbxERR_PROP_READONLY ); 301 else 302 { 303 // string -> byte array 304 if( IsFixed() && (aData.eType == SbxOBJECT) 305 && aData.pObj && ( aData.pObj->GetType() == (SbxARRAY | SbxBYTE) ) 306 && (r.aData.eType == SbxSTRING) ) 307 { 308 ::rtl::OUString aStr = r.GetString(); 309 SbxArray* pArr = StringToByteArray(aStr); 310 PutObject(pArr); 311 return *this; 312 } 313 // byte array -> string 314 if( r.IsFixed() && (r.aData.eType == SbxOBJECT) 315 && r.aData.pObj && ( r.aData.pObj->GetType() == (SbxARRAY | SbxBYTE) ) 316 && (aData.eType == SbxSTRING) ) 317 { 318 SbxBase* pObj = r.GetObject(); 319 SbxArray* pArr = PTR_CAST(SbxArray, pObj); 320 if( pArr ) 321 { 322 ::rtl::OUString aStr = ByteArrayToString( pArr ); 323 PutString(aStr); 324 return *this; 325 } 326 } 327 // Den Inhalt der Variablen auslesen 328 SbxValues aNew; 329 if( IsFixed() ) 330 // fest: dann muss der Typ stimmen 331 aNew.eType = aData.eType; 332 else if( r.IsFixed() ) 333 // Quelle fest: Typ uebernehmen 334 aNew.eType = SbxDataType( r.aData.eType & 0x0FFF ); 335 else 336 // beides Variant: dann isses egal 337 aNew.eType = SbxVARIANT; 338 if( r.Get( aNew ) ) 339 Put( aNew ); 340 } 341 } 342 return *this; 343 } 344 345 SbxValue::~SbxValue() 346 { 347 #ifndef C50 348 Broadcast( SBX_HINT_DYING ); 349 SetFlag( SBX_WRITE ); 350 SbxValue::Clear(); 351 #else 352 // Provisorischer Fix fuer Solaris 5.0 Compiler Bug 353 // bei Nutzung virtueller Vererbung. Virtuelle Calls 354 // im Destruktor vermeiden. Statt Clear() zu rufen 355 // moegliche Objekt-Referenzen direkt freigeben. 356 if( aData.eType == SbxOBJECT ) 357 { 358 if( aData.pObj && aData.pObj != this ) 359 { 360 HACK(nicht bei Parent-Prop - sonst CyclicRef) 361 SbxVariable *pThisVar = PTR_CAST(SbxVariable, this); 362 sal_Bool bParentProp = pThisVar && 5345 == 363 ( (sal_Int16) ( pThisVar->GetUserData() & 0xFFFF ) ); 364 if ( !bParentProp ) 365 aData.pObj->ReleaseRef(); 366 } 367 } 368 else if( aData.eType == SbxDECIMAL ) 369 { 370 releaseDecimalPtr( aData.pDecimal ); 371 } 372 #endif 373 } 374 375 void SbxValue::Clear() 376 { 377 switch( aData.eType ) 378 { 379 case SbxNULL: 380 case SbxEMPTY: 381 case SbxVOID: 382 break; 383 case SbxSTRING: 384 delete aData.pOUString; aData.pOUString = NULL; 385 break; 386 case SbxOBJECT: 387 if( aData.pObj ) 388 { 389 if( aData.pObj != this ) 390 { 391 HACK(nicht bei Parent-Prop - sonst CyclicRef) 392 SbxVariable *pThisVar = PTR_CAST(SbxVariable, this); 393 sal_Bool bParentProp = pThisVar && 5345 == 394 ( (sal_Int16) ( pThisVar->GetUserData() & 0xFFFF ) ); 395 if ( !bParentProp ) 396 aData.pObj->ReleaseRef(); 397 } 398 aData.pObj = NULL; 399 } 400 break; 401 case SbxDECIMAL: 402 if( aData.eType == SbxDECIMAL ) 403 releaseDecimalPtr( aData.pDecimal ); 404 break; 405 case SbxDATAOBJECT: 406 aData.pData = NULL; break; 407 default: 408 { 409 SbxValues aEmpty; 410 memset( &aEmpty, 0, sizeof( SbxValues ) ); 411 aEmpty.eType = GetType(); 412 Put( aEmpty ); 413 } 414 } 415 } 416 417 // Dummy 418 419 void SbxValue::Broadcast( sal_uIntPtr ) 420 {} 421 422 //////////////////////////// Daten auslesen ////////////////////////////// 423 424 // Ermitteln der "richtigen" Variablen. Falls es ein Objekt ist, wird 425 // entweder das Objekt selbst oder dessen Default-Property angesprochen. 426 // Falls die Variable eine Variable oder ein Objekt enthaelt, wird 427 // dieses angesprochen. 428 429 SbxValue* SbxValue::TheRealValue() const 430 { 431 return TheRealValue( sal_True ); 432 } 433 434 // #55226 Zusaetzliche Info transportieren 435 bool handleToStringForCOMObjects( SbxObject* pObj, SbxValue* pVal ); // sbunoobj.cxx 436 437 SbxValue* SbxValue::TheRealValue( sal_Bool bObjInObjError ) const 438 { 439 SbxValue* p = (SbxValue*) this; 440 for( ;; ) 441 { 442 SbxDataType t = SbxDataType( p->aData.eType & 0x0FFF ); 443 if( t == SbxOBJECT ) 444 { 445 // Der Block enthaelt ein Objekt oder eine Variable 446 SbxObject* pObj = PTR_CAST(SbxObject,p->aData.pObj); 447 if( pObj ) 448 { 449 // Hat das Objekt eine Default-Property? 450 SbxVariable* pDflt = pObj->GetDfltProperty(); 451 452 // Falls dies ein Objekt ist und sich selbst enthaelt, 453 // koennen wir nicht darauf zugreifen 454 // #55226# Die alte Bedingung, um einen Fehler zu setzen, 455 // ist nicht richtig, da z.B. eine ganz normale Variant- 456 // Variable mit Objekt davon betroffen sein kann, wenn ein 457 // anderer Wert zugewiesen werden soll. Daher mit Flag. 458 if( bObjInObjError && !pDflt && 459 ((SbxValue*) pObj)->aData.eType == SbxOBJECT && 460 ((SbxValue*) pObj)->aData.pObj == pObj ) 461 { 462 bool bSuccess = handleToStringForCOMObjects( pObj, p ); 463 if( !bSuccess ) 464 { 465 SetError( SbxERR_BAD_PROP_VALUE ); 466 p = NULL; 467 } 468 } 469 else if( pDflt ) 470 p = pDflt; 471 /* ALT: 472 else 473 p = pDflt ? pDflt : (SbxVariable*) pObj; 474 */ 475 break; 476 } 477 // Haben wir ein Array? 478 SbxArray* pArray = PTR_CAST(SbxArray,p->aData.pObj); 479 if( pArray ) 480 { 481 // Ggf. Parameter holen 482 SbxArray* pPar = NULL; 483 SbxVariable* pVar = PTR_CAST(SbxVariable,p); 484 if( pVar ) 485 pPar = pVar->GetParameters(); 486 if( pPar ) 487 { 488 // Haben wir ein dimensioniertes Array? 489 SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,p->aData.pObj); 490 if( pDimArray ) 491 p = pDimArray->Get( pPar ); 492 else 493 p = pArray->Get( pPar->Get( 1 )->GetInteger() ); 494 break; 495 } 496 } 497 // Sonst einen SbxValue annehmen 498 SbxValue* pVal = PTR_CAST(SbxValue,p->aData.pObj); 499 if( pVal ) 500 p = pVal; 501 else 502 break; 503 } 504 else 505 break; 506 } 507 return p; 508 } 509 510 sal_Bool SbxValue::Get( SbxValues& rRes ) const 511 { 512 sal_Bool bRes = sal_False; 513 SbxError eOld = GetError(); 514 if( eOld != SbxERR_OK ) 515 ResetError(); 516 if( !CanRead() ) 517 { 518 SetError( SbxERR_PROP_WRITEONLY ); 519 rRes.pObj = NULL; 520 } 521 else 522 { 523 // Falls nach einem Objekt oder einem VARIANT gefragt wird, nicht 524 // die wahren Werte suchen 525 SbxValue* p = (SbxValue*) this; 526 if( rRes.eType != SbxOBJECT && rRes.eType != SbxVARIANT ) 527 p = TheRealValue(); 528 if( p ) 529 { 530 p->Broadcast( SBX_HINT_DATAWANTED ); 531 switch( rRes.eType ) 532 { 533 case SbxEMPTY: 534 case SbxVOID: 535 case SbxNULL: break; 536 case SbxVARIANT: rRes = p->aData; break; 537 case SbxINTEGER: rRes.nInteger = ImpGetInteger( &p->aData ); break; 538 case SbxLONG: rRes.nLong = ImpGetLong( &p->aData ); break; 539 case SbxSALINT64: rRes.nInt64 = ImpGetInt64( &p->aData ); break; 540 case SbxSALUINT64: rRes.uInt64 = ImpGetUInt64( &p->aData ); break; 541 case SbxSINGLE: rRes.nSingle = ImpGetSingle( &p->aData ); break; 542 case SbxDOUBLE: rRes.nDouble = ImpGetDouble( &p->aData ); break; 543 case SbxCURRENCY:rRes.nLong64 = ImpGetCurrency( &p->aData ); break; 544 case SbxDECIMAL: rRes.pDecimal = ImpGetDecimal( &p->aData ); break; 545 case SbxDATE: rRes.nDouble = ImpGetDate( &p->aData ); break; 546 case SbxBOOL: 547 rRes.nUShort = sal::static_int_cast< sal_uInt16 >( 548 ImpGetBool( &p->aData ) ); 549 break; 550 case SbxCHAR: rRes.nChar = ImpGetChar( &p->aData ); break; 551 case SbxBYTE: rRes.nByte = ImpGetByte( &p->aData ); break; 552 case SbxUSHORT: rRes.nUShort = ImpGetUShort( &p->aData ); break; 553 case SbxULONG: rRes.nULong = ImpGetULong( &p->aData ); break; 554 case SbxLPSTR: 555 case SbxSTRING: p->aPic = ImpGetString( &p->aData ); 556 rRes.pOUString = &p->aPic; break; 557 case SbxCoreSTRING: p->aPic = ImpGetCoreString( &p->aData ); 558 rRes.pOUString = &p->aPic; break; 559 case SbxINT: 560 #if SAL_TYPES_SIZEOFINT == 2 561 rRes.nInt = (int) ImpGetInteger( &p->aData ); 562 #else 563 rRes.nInt = (int) ImpGetLong( &p->aData ); 564 #endif 565 break; 566 case SbxUINT: 567 #if SAL_TYPES_SIZEOFINT == 2 568 rRes.nUInt = (int) ImpGetUShort( &p->aData ); 569 #else 570 rRes.nUInt = (int) ImpGetULong( &p->aData ); 571 #endif 572 break; 573 case SbxOBJECT: 574 if( p->aData.eType == SbxOBJECT ) 575 rRes.pObj = p->aData.pObj; 576 else 577 { 578 SetError( SbxERR_NO_OBJECT ); 579 rRes.pObj = NULL; 580 } 581 break; 582 default: 583 if( p->aData.eType == rRes.eType ) 584 rRes = p->aData; 585 else 586 { 587 SetError( SbxERR_CONVERSION ); 588 rRes.pObj = NULL; 589 } 590 } 591 } 592 else 593 { 594 // Objekt enthielt sich selbst 595 SbxDataType eTemp = rRes.eType; 596 memset( &rRes, 0, sizeof( SbxValues ) ); 597 rRes.eType = eTemp; 598 } 599 } 600 if( !IsError() ) 601 { 602 bRes = sal_True; 603 if( eOld != SbxERR_OK ) 604 SetError( eOld ); 605 } 606 return bRes; 607 } 608 609 sal_Bool SbxValue::GetNoBroadcast( SbxValues& rRes ) 610 { 611 sal_uInt16 nFlags_ = GetFlags(); 612 SetFlag( SBX_NO_BROADCAST ); 613 sal_Bool bRes = Get( rRes ); 614 SetFlags( nFlags_ ); 615 return bRes; 616 } 617 618 const XubString& SbxValue::GetString() const 619 { 620 SbxValues aRes; 621 aRes.eType = SbxSTRING; 622 if( Get( aRes ) ) 623 ((SbxValue*) this)->aToolString = *aRes.pOUString; 624 else 625 ((SbxValue*) this)->aToolString.Erase(); 626 627 return aToolString; 628 } 629 630 const XubString& SbxValue::GetCoreString() const 631 { 632 SbxValues aRes; 633 aRes.eType = SbxCoreSTRING; 634 if( Get( aRes ) ) 635 ((SbxValue*) this)->aToolString = *aRes.pOUString; 636 else 637 ((SbxValue*) this)->aToolString.Erase(); 638 639 return aToolString; 640 } 641 642 ::rtl::OUString SbxValue::GetOUString() const 643 { 644 ::rtl::OUString aResult; 645 SbxValues aRes; 646 aRes.eType = SbxSTRING; 647 if( Get( aRes ) ) 648 aResult = *aRes.pOUString; 649 650 return aResult; 651 } 652 653 sal_Bool SbxValue::HasObject() const 654 { 655 ErrCode eErr = GetError(); 656 SbxValues aRes; 657 aRes.eType = SbxOBJECT; 658 Get( aRes ); 659 SetError( eErr ); 660 return 0 != aRes.pObj; 661 } 662 663 sal_Bool SbxValue::GetBool() const 664 { 665 SbxValues aRes; 666 aRes.eType = SbxBOOL; 667 Get( aRes ); 668 return sal_Bool( aRes.nUShort != 0 ); 669 } 670 671 #define GET( g, e, t, m ) \ 672 t SbxValue::g() const { SbxValues aRes(e); Get( aRes ); return aRes.m; } 673 674 GET( GetByte, SbxBYTE, sal_uInt8, nByte ) 675 GET( GetChar, SbxCHAR, xub_Unicode, nChar ) 676 GET( GetCurrency, SbxCURRENCY, SbxINT64, nLong64 ) 677 GET( GetDate, SbxDATE, double, nDouble ) 678 GET( GetData, SbxDATAOBJECT, void*, pData ) 679 GET( GetDouble, SbxDOUBLE, double, nDouble ) 680 GET( GetErr, SbxERROR, sal_uInt16, nUShort ) 681 GET( GetInt, SbxINT, int, nInt ) 682 GET( GetInteger, SbxINTEGER, sal_Int16, nInteger ) 683 GET( GetLong, SbxLONG, sal_Int32, nLong ) 684 GET( GetLong64, SbxLONG64, SbxINT64, nLong64 ) 685 GET( GetObject, SbxOBJECT, SbxBase*, pObj ) 686 GET( GetSingle, SbxSINGLE, float, nSingle ) 687 GET( GetULong, SbxULONG, sal_uInt32, nULong ) 688 GET( GetULong64, SbxULONG64, SbxUINT64, nULong64 ) 689 GET( GetUShort, SbxUSHORT, sal_uInt16, nUShort ) 690 GET( GetInt64, SbxSALINT64, sal_Int64, nInt64 ) 691 GET( GetUInt64, SbxSALUINT64, sal_uInt64, uInt64 ) 692 GET( GetDecimal, SbxDECIMAL, SbxDecimal*, pDecimal ) 693 694 695 //////////////////////////// Daten schreiben ///////////////////////////// 696 697 sal_Bool SbxValue::Put( const SbxValues& rVal ) 698 { 699 sal_Bool bRes = sal_False; 700 SbxError eOld = GetError(); 701 if( eOld != SbxERR_OK ) 702 ResetError(); 703 if( !CanWrite() ) 704 SetError( SbxERR_PROP_READONLY ); 705 else if( rVal.eType & 0xF000 ) 706 SetError( SbxERR_NOTIMP ); 707 else 708 { 709 // Falls nach einem Objekt gefragt wird, nicht 710 // die wahren Werte suchen 711 SbxValue* p = this; 712 if( rVal.eType != SbxOBJECT ) 713 p = TheRealValue( sal_False ); // #55226 Hier keinen Fehler erlauben 714 if( p ) 715 { 716 if( !p->CanWrite() ) 717 SetError( SbxERR_PROP_READONLY ); 718 else if( p->IsFixed() || p->SetType( (SbxDataType) ( rVal.eType & 0x0FFF ) ) ) 719 switch( rVal.eType & 0x0FFF ) 720 { 721 case SbxEMPTY: 722 case SbxVOID: 723 case SbxNULL: break; 724 case SbxINTEGER: ImpPutInteger( &p->aData, rVal.nInteger ); break; 725 case SbxLONG: ImpPutLong( &p->aData, rVal.nLong ); break; 726 case SbxSALINT64: ImpPutInt64( &p->aData, rVal.nInt64 ); break; 727 case SbxSALUINT64: ImpPutUInt64( &p->aData, rVal.uInt64 ); break; 728 case SbxSINGLE: ImpPutSingle( &p->aData, rVal.nSingle ); break; 729 case SbxDOUBLE: ImpPutDouble( &p->aData, rVal.nDouble ); break; 730 case SbxCURRENCY: ImpPutCurrency( &p->aData, rVal.nLong64 ); break; 731 case SbxDECIMAL: ImpPutDecimal( &p->aData, rVal.pDecimal ); break; 732 case SbxDATE: ImpPutDate( &p->aData, rVal.nDouble ); break; 733 case SbxBOOL: ImpPutBool( &p->aData, rVal.nInteger ); break; 734 case SbxCHAR: ImpPutChar( &p->aData, rVal.nChar ); break; 735 case SbxBYTE: ImpPutByte( &p->aData, rVal.nByte ); break; 736 case SbxUSHORT: ImpPutUShort( &p->aData, rVal.nUShort ); break; 737 case SbxULONG: ImpPutULong( &p->aData, rVal.nULong ); break; 738 case SbxLPSTR: 739 case SbxSTRING: ImpPutString( &p->aData, rVal.pOUString ); break; 740 case SbxINT: 741 #if SAL_TYPES_SIZEOFINT == 2 742 ImpPutInteger( &p->aData, (sal_Int16) rVal.nInt ); 743 #else 744 ImpPutLong( &p->aData, (sal_Int32) rVal.nInt ); 745 #endif 746 break; 747 case SbxUINT: 748 #if SAL_TYPES_SIZEOFINT == 2 749 ImpPutUShort( &p->aData, (sal_uInt16) rVal.nUInt ); 750 #else 751 ImpPutULong( &p->aData, (sal_uInt32) rVal.nUInt ); 752 #endif 753 break; 754 case SbxOBJECT: 755 if( !p->IsFixed() || p->aData.eType == SbxOBJECT ) 756 { 757 // ist schon drin 758 if( p->aData.eType == SbxOBJECT && p->aData.pObj == rVal.pObj ) 759 break; 760 761 // Nur den Werteteil loeschen! 762 p->SbxValue::Clear(); 763 764 // eingentliche Zuweisung 765 p->aData.pObj = rVal.pObj; 766 767 // ggf. Ref-Count mitzaehlen 768 if( p->aData.pObj && p->aData.pObj != p ) 769 { 770 if ( p != this ) 771 { 772 DBG_ERROR( "TheRealValue" ); 773 } 774 HACK(nicht bei Parent-Prop - sonst CyclicRef) 775 SbxVariable *pThisVar = PTR_CAST(SbxVariable, this); 776 sal_Bool bParentProp = pThisVar && 5345 == 777 ( (sal_Int16) ( pThisVar->GetUserData() & 0xFFFF ) ); 778 if ( !bParentProp ) 779 p->aData.pObj->AddRef(); 780 } 781 } 782 else 783 SetError( SbxERR_CONVERSION ); 784 break; 785 default: 786 if( p->aData.eType == rVal.eType ) 787 p->aData = rVal; 788 else 789 { 790 SetError( SbxERR_CONVERSION ); 791 if( !p->IsFixed() ) 792 p->aData.eType = SbxNULL; 793 } 794 } 795 if( !IsError() ) 796 { 797 p->SetModified( sal_True ); 798 p->Broadcast( SBX_HINT_DATACHANGED ); 799 if( eOld != SbxERR_OK ) 800 SetError( eOld ); 801 bRes = sal_True; 802 } 803 } 804 } 805 return bRes; 806 } 807 808 // AB, 28.3.96: 809 // Methode, um bei speziellen Typen eine Vorbehandlung des Strings 810 // durchzufuehren. Insbesondere erforderlich fuer BASIC-IDE, damit 811 // die Ausgaben im Watch-Fenster mit PutStringExt zurueckgeschrieben 812 // werden koennen, wenn Floats mit ',' als Dezimaltrenner oder BOOLs 813 // explizit mit "TRUE" oder "FALSE" angegeben werden. 814 // Implementierung in ImpConvStringExt (SBXSCAN.CXX) 815 sal_Bool SbxValue::PutStringExt( const ::rtl::OUString& r ) 816 { 817 // Kopieren, bei Unicode gleich konvertieren 818 ::rtl::OUString aStr( r ); 819 820 // Eigenen Typ bestimmen (nicht wie in Put() mit TheRealValue(), 821 // Objekte werden sowieso nicht behandelt) 822 SbxDataType eTargetType = SbxDataType( aData.eType & 0x0FFF ); 823 824 // Source-Value basteln 825 SbxValues aRes; 826 aRes.eType = SbxSTRING; 827 828 // Nur, wenn wirklich was konvertiert wurde, Kopie nehmen, 829 // sonst Original (Unicode bleibt erhalten) 830 sal_Bool bRet; 831 if( ImpConvStringExt( aStr, eTargetType ) ) 832 aRes.pOUString = (::rtl::OUString*)&aStr; 833 else 834 aRes.pOUString = (::rtl::OUString*)&r; 835 836 // #34939: Bei Strings. die eine Zahl enthalten und wenn this einen 837 // Num-Typ hat, Fixed-Flag setzen, damit der Typ nicht veraendert wird 838 sal_uInt16 nFlags_ = GetFlags(); 839 if( ( eTargetType >= SbxINTEGER && eTargetType <= SbxCURRENCY ) || 840 ( eTargetType >= SbxCHAR && eTargetType <= SbxUINT ) || 841 eTargetType == SbxBOOL ) 842 { 843 SbxValue aVal; 844 aVal.Put( aRes ); 845 if( aVal.IsNumeric() ) 846 SetFlag( SBX_FIXED ); 847 } 848 849 Put( aRes ); 850 bRet = sal_Bool( !IsError() ); 851 852 // Falls das mit dem FIXED einen Error gegeben hat, zuruecksetzen 853 // (UI-Aktion sollte keinen Error ergeben, sondern nur scheitern) 854 if( !bRet ) 855 ResetError(); 856 857 SetFlags( nFlags_ ); 858 return bRet; 859 } 860 861 sal_Bool SbxValue::PutString( const xub_Unicode* p ) 862 { 863 ::rtl::OUString aVal( p ); 864 SbxValues aRes; 865 aRes.eType = SbxSTRING; 866 aRes.pOUString = &aVal; 867 Put( aRes ); 868 return sal_Bool( !IsError() ); 869 } 870 871 sal_Bool SbxValue::PutBool( sal_Bool b ) 872 { 873 SbxValues aRes; 874 aRes.eType = SbxBOOL; 875 aRes.nUShort = sal::static_int_cast< sal_uInt16 >(b ? SbxTRUE : SbxFALSE); 876 Put( aRes ); 877 return sal_Bool( !IsError() ); 878 } 879 880 sal_Bool SbxValue::PutEmpty() 881 { 882 sal_Bool bRet = SetType( SbxEMPTY ); 883 SetModified( sal_True ); 884 return bRet; 885 } 886 887 sal_Bool SbxValue::PutNull() 888 { 889 sal_Bool bRet = SetType( SbxNULL ); 890 if( bRet ) 891 SetModified( sal_True ); 892 return bRet; 893 } 894 895 896 // Special decimal methods 897 sal_Bool SbxValue::PutDecimal( com::sun::star::bridge::oleautomation::Decimal& rAutomationDec ) 898 { 899 SbxValue::Clear(); 900 aData.pDecimal = new SbxDecimal( rAutomationDec ); 901 aData.pDecimal->addRef(); 902 aData.eType = SbxDECIMAL; 903 return sal_True; 904 } 905 906 sal_Bool SbxValue::fillAutomationDecimal 907 ( com::sun::star::bridge::oleautomation::Decimal& rAutomationDec ) 908 { 909 SbxDecimal* pDecimal = GetDecimal(); 910 if( pDecimal != NULL ) 911 { 912 pDecimal->fillAutomationDecimal( rAutomationDec ); 913 return sal_True; 914 } 915 return sal_False; 916 } 917 918 919 sal_Bool SbxValue::PutpChar( const xub_Unicode* p ) 920 { 921 ::rtl::OUString aVal( p ); 922 SbxValues aRes; 923 aRes.eType = SbxLPSTR; 924 aRes.pOUString = &aVal; 925 Put( aRes ); 926 return sal_Bool( !IsError() ); 927 } 928 929 sal_Bool SbxValue::PutString( const ::rtl::OUString& r ) 930 { 931 SbxValues aRes; 932 aRes.eType = SbxSTRING; 933 aRes.pOUString = (::rtl::OUString*) &r; 934 Put( aRes ); 935 return sal_Bool( !IsError() ); 936 } 937 938 939 #define PUT( p, e, t, m ) \ 940 sal_Bool SbxValue::p( t n ) \ 941 { SbxValues aRes(e); aRes.m = n; Put( aRes ); return sal_Bool( !IsError() ); } 942 943 PUT( PutByte, SbxBYTE, sal_uInt8, nByte ) 944 PUT( PutChar, SbxCHAR, xub_Unicode, nChar ) 945 PUT( PutCurrency, SbxCURRENCY, const SbxINT64&, nLong64 ) 946 PUT( PutDate, SbxDATE, double, nDouble ) 947 PUT( PutData, SbxDATAOBJECT, void*, pData ) 948 PUT( PutDouble, SbxDOUBLE, double, nDouble ) 949 PUT( PutErr, SbxERROR, sal_uInt16, nUShort ) 950 PUT( PutInt, SbxINT, int, nInt ) 951 PUT( PutInteger, SbxINTEGER, sal_Int16, nInteger ) 952 PUT( PutLong, SbxLONG, sal_Int32, nLong ) 953 PUT( PutLong64, SbxLONG64, const SbxINT64&, nLong64 ) 954 PUT( PutObject, SbxOBJECT, SbxBase*, pObj ) 955 PUT( PutSingle, SbxSINGLE, float, nSingle ) 956 PUT( PutULong, SbxULONG, sal_uInt32, nULong ) 957 PUT( PutULong64, SbxULONG64, const SbxUINT64&, nULong64 ) 958 PUT( PutUShort, SbxUSHORT, sal_uInt16, nUShort ) 959 PUT( PutInt64, SbxSALINT64, sal_Int64, nInt64 ) 960 PUT( PutUInt64, SbxSALUINT64, sal_uInt64, uInt64 ) 961 PUT( PutDecimal, SbxDECIMAL, SbxDecimal*, pDecimal ) 962 963 964 ////////////////////////// Setzen des Datentyps /////////////////////////// 965 966 sal_Bool SbxValue::IsFixed() const 967 { 968 return ( (GetFlags() & SBX_FIXED) | (aData.eType & SbxBYREF) ) != 0; 969 } 970 971 // Eine Variable ist numerisch, wenn sie EMPTY oder wirklich numerisch ist 972 // oder einen vollstaendig konvertierbaren String enthaelt 973 974 // #41692, fuer RTL und Basic-Core getrennt implementieren 975 sal_Bool SbxValue::IsNumeric() const 976 { 977 return ImpIsNumeric( /*bOnlyIntntl*/sal_False ); 978 } 979 980 sal_Bool SbxValue::IsNumericRTL() const 981 { 982 return ImpIsNumeric( /*bOnlyIntntl*/sal_True ); 983 } 984 985 sal_Bool SbxValue::ImpIsNumeric( sal_Bool bOnlyIntntl ) const 986 { 987 988 if( !CanRead() ) 989 { 990 SetError( SbxERR_PROP_WRITEONLY ); return sal_False; 991 } 992 // Downcast pruefen!!! 993 if( this->ISA(SbxVariable) ) 994 ((SbxVariable*)this)->Broadcast( SBX_HINT_DATAWANTED ); 995 SbxDataType t = GetType(); 996 if( t == SbxSTRING ) 997 { 998 if( aData.pOUString ) 999 { 1000 ::rtl::OUString s( *aData.pOUString ); 1001 double n; 1002 SbxDataType t2; 1003 sal_uInt16 nLen = 0; 1004 if( ImpScan( s, n, t2, &nLen, /*bAllowIntntl*/sal_False, bOnlyIntntl ) == SbxERR_OK ) 1005 return sal_Bool( nLen == s.getLength() ); 1006 } 1007 return sal_False; 1008 } 1009 else 1010 return sal_Bool( t == SbxEMPTY 1011 || ( t >= SbxINTEGER && t <= SbxCURRENCY ) 1012 || ( t >= SbxCHAR && t <= SbxUINT ) ); 1013 } 1014 1015 SbxClassType SbxValue::GetClass() const 1016 { 1017 return SbxCLASS_VALUE; 1018 } 1019 1020 SbxDataType SbxValue::GetType() const 1021 { 1022 return SbxDataType( aData.eType & 0x0FFF ); 1023 } 1024 1025 SbxDataType SbxValue::GetFullType() const 1026 { 1027 return aData.eType; 1028 } 1029 1030 sal_Bool SbxValue::SetType( SbxDataType t ) 1031 { 1032 DBG_ASSERT( !( t & 0xF000 ), "Setzen von BYREF|ARRAY verboten!" ); 1033 if( ( t == SbxEMPTY && aData.eType == SbxVOID ) 1034 || ( aData.eType == SbxEMPTY && t == SbxVOID ) ) 1035 return sal_True; 1036 if( ( t & 0x0FFF ) == SbxVARIANT ) 1037 { 1038 // Versuch, den Datentyp auf Variant zu setzen 1039 ResetFlag( SBX_FIXED ); 1040 if( IsFixed() ) 1041 { 1042 SetError( SbxERR_CONVERSION ); return sal_False; 1043 } 1044 t = SbxEMPTY; 1045 } 1046 if( ( t & 0x0FFF ) != ( aData.eType & 0x0FFF ) ) 1047 { 1048 if( !CanWrite() || IsFixed() ) 1049 { 1050 SetError( SbxERR_CONVERSION ); return sal_False; 1051 } 1052 else 1053 { 1054 // Eventuelle Objekte freigeben 1055 switch( aData.eType ) 1056 { 1057 case SbxSTRING: 1058 delete aData.pOUString; 1059 break; 1060 case SbxOBJECT: 1061 if( aData.pObj && aData.pObj != this ) 1062 { 1063 HACK(nicht bei Parent-Prop - sonst CyclicRef) 1064 SbxVariable *pThisVar = PTR_CAST(SbxVariable, this); 1065 sal_uInt16 nSlotId = pThisVar 1066 ? ( (sal_Int16) ( pThisVar->GetUserData() & 0xFFFF ) ) 1067 : 0; 1068 DBG_ASSERT( nSlotId != 5345 || pThisVar->GetName() == UniString::CreateFromAscii( "Parent" ), 1069 "SID_PARENTOBJECT heisst nicht 'Parent'" ); 1070 sal_Bool bParentProp = 5345 == nSlotId; 1071 if ( !bParentProp ) 1072 aData.pObj->ReleaseRef(); 1073 } 1074 break; 1075 default: break; 1076 } 1077 // Das klappt immer, da auch die Float-Repraesentationen 0 sind. 1078 memset( &aData, 0, sizeof( SbxValues ) ); 1079 aData.eType = t; 1080 } 1081 } 1082 return sal_True; 1083 } 1084 1085 sal_Bool SbxValue::Convert( SbxDataType eTo ) 1086 { 1087 eTo = SbxDataType( eTo & 0x0FFF ); 1088 if( ( aData.eType & 0x0FFF ) == eTo ) 1089 return sal_True; 1090 if( !CanWrite() ) 1091 return sal_False; 1092 if( eTo == SbxVARIANT ) 1093 { 1094 // Versuch, den Datentyp auf Variant zu setzen 1095 ResetFlag( SBX_FIXED ); 1096 if( IsFixed() ) 1097 { 1098 SetError( SbxERR_CONVERSION ); return sal_False; 1099 } 1100 else 1101 return sal_True; 1102 } 1103 // Convert from Null geht niemals. Einmal Null, immer Null! 1104 if( aData.eType == SbxNULL ) 1105 { 1106 SetError( SbxERR_CONVERSION ); return sal_False; 1107 } 1108 1109 // Konversion der Daten: 1110 SbxValues aNew; 1111 aNew.eType = eTo; 1112 if( Get( aNew ) ) 1113 { 1114 // Der Datentyp konnte konvertiert werden. Bei Fixed-Elementen 1115 // ist hier Ende, da die Daten nicht uebernommen zu werden brauchen 1116 if( !IsFixed() ) 1117 { 1118 SetType( eTo ); 1119 Put( aNew ); 1120 SetModified( sal_True ); 1121 } 1122 Broadcast( SBX_HINT_CONVERTED ); 1123 return sal_True; 1124 } 1125 else 1126 return sal_False; 1127 } 1128 ////////////////////////////////// Rechnen ///////////////////////////////// 1129 1130 sal_Bool SbxValue::Compute( SbxOperator eOp, const SbxValue& rOp ) 1131 { 1132 bool bVBAInterop = SbiRuntime::isVBAEnabled(); 1133 1134 SbxDataType eThisType = GetType(); 1135 SbxDataType eOpType = rOp.GetType(); 1136 SbxError eOld = GetError(); 1137 if( eOld != SbxERR_OK ) 1138 ResetError(); 1139 if( !CanWrite() ) 1140 SetError( SbxERR_PROP_READONLY ); 1141 else if( !rOp.CanRead() ) 1142 SetError( SbxERR_PROP_WRITEONLY ); 1143 // Sonderregel 1: Ist ein Operand Null, ist das Ergebnis Null 1144 else if( eThisType == SbxNULL || eOpType == SbxNULL ) 1145 SetType( SbxNULL ); 1146 // Sonderregel 2: Ist ein Operand Empty, ist das Ergebnis der 2. Operand 1147 else if( eThisType == SbxEMPTY 1148 && !bVBAInterop 1149 ) 1150 *this = rOp; 1151 // 13.2.96: Nicht schon vor Get auf SbxEMPTY pruefen 1152 else 1153 { 1154 SbxValues aL, aR; 1155 bool bDecimal = false; 1156 if( bVBAInterop && ( ( eThisType == SbxSTRING && eOpType != SbxSTRING ) || 1157 ( eThisType != SbxSTRING && eOpType == SbxSTRING ) ) && 1158 ( eOp == SbxMUL || eOp == SbxDIV || eOp == SbxPLUS || eOp == SbxMINUS ) ) 1159 { 1160 goto Lbl_OpIsDouble; 1161 } 1162 else if( eThisType == SbxSTRING || eOp == SbxCAT || ( bVBAInterop && ( eOpType == SbxSTRING ) && ( eOp == SbxPLUS ) ) ) 1163 { 1164 if( eOp == SbxCAT || eOp == SbxPLUS ) 1165 { 1166 // AB 5.11.1999, OUString beruecksichtigen 1167 aL.eType = aR.eType = SbxSTRING; 1168 rOp.Get( aR ); 1169 // AB 8.12.1999, #70399: Hier wieder GetType() rufen, Get() kann Typ aendern! 1170 if( rOp.GetType() == SbxEMPTY ) 1171 goto Lbl_OpIsEmpty; 1172 Get( aL ); 1173 1174 // #30576: Erstmal testen, ob Wandlung geklappt hat 1175 if( aL.pOUString != NULL && aR.pOUString != NULL ) 1176 { 1177 *aL.pOUString += *aR.pOUString; 1178 } 1179 // Nicht einmal Left OK? 1180 else if( aL.pOUString == NULL ) 1181 { 1182 aL.pOUString = new ::rtl::OUString(); 1183 } 1184 Put( aL ); 1185 } 1186 else 1187 SetError( SbxERR_CONVERSION ); 1188 } 1189 else if( eOpType == SbxSTRING && rOp.IsFixed() ) 1190 { // Numerisch: rechts darf kein String stehen 1191 SetError( SbxERR_CONVERSION ); 1192 } 1193 else if( ( eOp >= SbxIDIV && eOp <= SbxNOT ) || eOp == SbxMOD ) 1194 { 1195 if( GetType() == eOpType ) 1196 { 1197 if( GetType() == SbxULONG64 1198 || GetType() == SbxLONG64 1199 || GetType() == SbxCURRENCY 1200 || GetType() == SbxULONG ) 1201 aL.eType = aR.eType = GetType(); 1202 // else if( GetType() == SbxDouble || GetType() == SbxSingle ) 1203 // aL.eType = aR.eType = SbxLONG64; 1204 else 1205 aL.eType = aR.eType = SbxLONG; 1206 } 1207 else if( GetType() == SbxCURRENCY || eOpType == SbxCURRENCY 1208 || GetType() == SbxULONG64 || eOpType == SbxULONG64 1209 || GetType() == SbxLONG64 || eOpType == SbxLONG64 ) 1210 aL.eType = aR.eType = SbxLONG64; 1211 // else if( GetType() == SbxDouble || rOP.GetType() == SbxDouble 1212 // || GetType() == SbxSingle || rOP.GetType() == SbxSingle ) 1213 // aL.eType = aR.eType = SbxLONG64; 1214 else 1215 aL.eType = aR.eType = SbxLONG; 1216 1217 if( rOp.Get( aR ) ) 1218 { 1219 if( rOp.GetType() == SbxEMPTY ) 1220 { 1221 if ( !bVBAInterop || ( bVBAInterop && ( eOp != SbxNOT ) ) ) 1222 goto Lbl_OpIsEmpty; 1223 } 1224 if( Get( aL ) ) switch( eOp ) 1225 { 1226 case SbxIDIV: 1227 if( aL.eType == SbxCURRENCY ) 1228 aL.eType = SbxLONG64; 1229 if( aL.eType == SbxLONG64 ) 1230 if( !aR.nLong64 ) SetError( SbxERR_ZERODIV ); 1231 else aL.nLong64 /= aR.nLong64; 1232 else if( aL.eType == SbxULONG64 ) 1233 if( !aR.nULong64 ) SetError( SbxERR_ZERODIV ); 1234 else aL.nULong64 /= aR.nULong64; 1235 else if( aL.eType == SbxLONG ) 1236 if( !aR.nLong ) SetError( SbxERR_ZERODIV ); 1237 else aL.nLong /= aR.nLong; 1238 else 1239 if( !aR.nULong ) SetError( SbxERR_ZERODIV ); 1240 else aL.nULong /= aR.nULong; 1241 break; 1242 case SbxMOD: 1243 if( aL.eType == SbxCURRENCY ) 1244 aL.eType = SbxLONG64; 1245 if( aL.eType == SbxLONG64 ) 1246 if( !aR.nLong64 ) SetError( SbxERR_ZERODIV ); 1247 else aL.nLong64 %= aR.nLong64; 1248 else if( aL.eType == SbxULONG64 ) 1249 if( !aR.nULong64 ) SetError( SbxERR_ZERODIV ); 1250 else aL.nULong64 %= aR.nULong64; 1251 else if( aL.eType == SbxLONG ) 1252 if( !aR.nLong ) SetError( SbxERR_ZERODIV ); 1253 else aL.nLong %= aR.nLong; 1254 else 1255 if( !aR.nULong ) SetError( SbxERR_ZERODIV ); 1256 else aL.nULong %= aR.nULong; 1257 break; 1258 case SbxAND: 1259 if( aL.eType != SbxLONG && aL.eType != SbxULONG ) 1260 aL.nLong64 &= aR.nLong64; 1261 else 1262 aL.nLong &= aR.nLong; 1263 break; 1264 case SbxOR: 1265 if( aL.eType != SbxLONG && aL.eType != SbxULONG ) 1266 aL.nLong64 |= aR.nLong64; 1267 else 1268 aL.nLong |= aR.nLong; 1269 break; 1270 case SbxXOR: 1271 if( aL.eType != SbxLONG && aL.eType != SbxULONG ) 1272 aL.nLong64 ^= aR.nLong64; 1273 else 1274 aL.nLong ^= aR.nLong; 1275 break; 1276 case SbxEQV: 1277 if( aL.eType != SbxLONG && aL.eType != SbxULONG ) 1278 aL.nLong64 = (aL.nLong64 & aR.nLong64) | (~aL.nLong64 & ~aR.nLong64); 1279 else 1280 aL.nLong = (aL.nLong & aR.nLong) | (~aL.nLong & ~aR.nLong); 1281 break; 1282 case SbxIMP: 1283 if( aL.eType != SbxLONG && aL.eType != SbxULONG ) 1284 aL.nLong64 = ~aL.nLong64 | aR.nLong64; 1285 else 1286 aL.nLong = ~aL.nLong | aR.nLong; 1287 break; 1288 case SbxNOT: 1289 if( aL.eType != SbxLONG && aL.eType != SbxULONG ) 1290 aL.nLong64 = ~aL.nLong64; 1291 else 1292 aL.nLong = ~aL.nLong; 1293 break; 1294 default: break; 1295 } 1296 } 1297 } 1298 else if( ( GetType() == SbxDECIMAL || rOp.GetType() == SbxDECIMAL ) && 1299 ( eOp == SbxMUL || eOp == SbxDIV || eOp == SbxPLUS || eOp == SbxMINUS || eOp == SbxNEG ) ) 1300 { 1301 aL.eType = aR.eType = SbxDECIMAL; 1302 bDecimal = true; 1303 if( rOp.Get( aR ) ) 1304 { 1305 if( rOp.GetType() == SbxEMPTY ) 1306 { 1307 releaseDecimalPtr( aL.pDecimal ); 1308 goto Lbl_OpIsEmpty; 1309 } 1310 if( Get( aL ) ) 1311 { 1312 if( aL.pDecimal && aR.pDecimal ) 1313 { 1314 bool bOk = true; 1315 switch( eOp ) 1316 { 1317 case SbxMUL: 1318 bOk = ( *(aL.pDecimal) *= *(aR.pDecimal) ); 1319 break; 1320 case SbxDIV: 1321 if( aR.pDecimal->isZero() ) 1322 SetError( SbxERR_ZERODIV ); 1323 else 1324 bOk = ( *(aL.pDecimal) /= *(aR.pDecimal) ); 1325 break; 1326 case SbxPLUS: 1327 bOk = ( *(aL.pDecimal) += *(aR.pDecimal) ); 1328 break; 1329 case SbxMINUS: 1330 bOk = ( *(aL.pDecimal) -= *(aR.pDecimal) ); 1331 break; 1332 case SbxNEG: 1333 bOk = ( aL.pDecimal->neg() ); 1334 break; 1335 default: 1336 SetError( SbxERR_NOTIMP ); 1337 } 1338 if( !bOk ) 1339 SetError( SbxERR_OVERFLOW ); 1340 } 1341 else 1342 { 1343 SetError( SbxERR_CONVERSION ); 1344 } 1345 } 1346 } 1347 } 1348 else if( GetType() == SbxCURRENCY || rOp.GetType() == SbxCURRENCY ) 1349 { 1350 aL.eType = SbxCURRENCY; 1351 aR.eType = SbxCURRENCY; 1352 1353 if( rOp.Get( aR ) ) 1354 { 1355 static BigInt n10K( 10000 ); 1356 1357 if( rOp.GetType() == SbxEMPTY ) 1358 goto Lbl_OpIsEmpty; 1359 1360 if( Get( aL ) ) switch( eOp ) 1361 { 1362 case SbxMUL: 1363 { 1364 // #i20704 Implement directly 1365 BigInt b1( aL.nLong64 ); 1366 BigInt b2( aR.nLong64 ); 1367 b1 *= b2; 1368 b1 /= n10K; 1369 double d = double( b1 ) / 10000.0; 1370 if( d > SbxMAXCURR || d < SbxMINCURR ) 1371 SetError( SbxERR_OVERFLOW ); 1372 else 1373 b1.INT64( &aL.nLong64 ); 1374 break; 1375 } 1376 case SbxDIV: 1377 if( !aR.nLong64 ) 1378 { 1379 SetError( SbxERR_ZERODIV ); 1380 } 1381 else 1382 { 1383 // #i20704 Implement directly 1384 BigInt b1( aL.nLong64 ); 1385 BigInt b2( aR.nLong64 ); 1386 b1 *= n10K; 1387 b1 /= b2; 1388 double d = double( b1 ) / 10000.0; 1389 if( d > SbxMAXCURR || d < SbxMINCURR ) 1390 SetError( SbxERR_OVERFLOW ); 1391 else 1392 b1.INT64( &aL.nLong64 ); 1393 } 1394 break; 1395 case SbxPLUS: 1396 aL.nLong64 += aR.nLong64; break; 1397 case SbxMINUS: 1398 aL.nLong64 -= aR.nLong64; break; 1399 case SbxNEG: 1400 aL.nLong64 = -aL.nLong64; break; 1401 default: 1402 SetError( SbxERR_NOTIMP ); 1403 } 1404 } 1405 } 1406 else 1407 Lbl_OpIsDouble: 1408 { // Andere Operatoren 1409 aL.eType = aR.eType = SbxDOUBLE; 1410 if( rOp.Get( aR ) ) 1411 { 1412 if( rOp.GetType() == SbxEMPTY ) 1413 { 1414 if ( !bVBAInterop || ( bVBAInterop && ( eOp != SbxNEG ) ) ) 1415 goto Lbl_OpIsEmpty; 1416 } 1417 if( Get( aL ) ) 1418 { 1419 switch( eOp ) 1420 { 1421 case SbxEXP: 1422 aL.nDouble = pow( aL.nDouble, aR.nDouble ); 1423 break; 1424 case SbxMUL: 1425 aL.nDouble *= aR.nDouble; break; 1426 case SbxDIV: 1427 if( !aR.nDouble ) SetError( SbxERR_ZERODIV ); 1428 else aL.nDouble /= aR.nDouble; break; 1429 case SbxPLUS: 1430 aL.nDouble += aR.nDouble; break; 1431 case SbxMINUS: 1432 aL.nDouble -= aR.nDouble; break; 1433 case SbxNEG: 1434 aL.nDouble = -aL.nDouble; break; 1435 default: 1436 SetError( SbxERR_NOTIMP ); 1437 } 1438 1439 // #45465 Date braucht bei + eine Spezial-Behandlung 1440 if( eOp == SbxPLUS && (GetType() == SbxDATE || rOp.GetType() == SbxDATE ) ) 1441 aL.eType = SbxDATE; 1442 } 1443 } 1444 1445 } 1446 if( !IsError() ) 1447 Put( aL ); 1448 if( bDecimal ) 1449 { 1450 releaseDecimalPtr( aL.pDecimal ); 1451 releaseDecimalPtr( aR.pDecimal ); 1452 } 1453 } 1454 Lbl_OpIsEmpty: 1455 1456 sal_Bool bRes = sal_Bool( !IsError() ); 1457 if( bRes && eOld != SbxERR_OK ) 1458 SetError( eOld ); 1459 return bRes; 1460 } 1461 1462 // Die Vergleichs-Routine liefert sal_True oder sal_False. 1463 1464 sal_Bool SbxValue::Compare( SbxOperator eOp, const SbxValue& rOp ) const 1465 { 1466 bool bVBAInterop = SbiRuntime::isVBAEnabled(); 1467 1468 sal_Bool bRes = sal_False; 1469 SbxError eOld = GetError(); 1470 if( eOld != SbxERR_OK ) 1471 ResetError(); 1472 if( !CanRead() || !rOp.CanRead() ) 1473 SetError( SbxERR_PROP_WRITEONLY ); 1474 else if( GetType() == SbxNULL && rOp.GetType() == SbxNULL && !bVBAInterop ) 1475 { 1476 bRes = sal_True; 1477 } 1478 else if( GetType() == SbxEMPTY && rOp.GetType() == SbxEMPTY ) 1479 bRes = !bVBAInterop ? sal_True : ( eOp == SbxEQ ? sal_True : sal_False ); 1480 // Sonderregel 1: Ist ein Operand Null, ist das Ergebnis FALSE 1481 else if( GetType() == SbxNULL || rOp.GetType() == SbxNULL ) 1482 bRes = sal_False; 1483 // Sonderregel 2: Wenn beide Variant sind und einer ist numerisch, 1484 // und der andere ein String, ist num < str 1485 else if( !IsFixed() && !rOp.IsFixed() 1486 && ( rOp.GetType() == SbxSTRING && GetType() != SbxSTRING && IsNumeric() ) && !bVBAInterop 1487 ) 1488 bRes = sal_Bool( eOp == SbxLT || eOp == SbxLE || eOp == SbxNE ); 1489 else if( !IsFixed() && !rOp.IsFixed() 1490 && ( GetType() == SbxSTRING && rOp.GetType() != SbxSTRING && rOp.IsNumeric() ) 1491 && !bVBAInterop 1492 ) 1493 bRes = sal_Bool( eOp == SbxGT || eOp == SbxGE || eOp == SbxNE ); 1494 else 1495 { 1496 SbxValues aL, aR; 1497 // Wenn einer der Operanden ein String ist, 1498 // findet ein Stringvergleich statt 1499 if( GetType() == SbxSTRING || rOp.GetType() == SbxSTRING ) 1500 { 1501 aL.eType = aR.eType = SbxSTRING; 1502 if( Get( aL ) && rOp.Get( aR ) ) switch( eOp ) 1503 { 1504 case SbxEQ: 1505 bRes = sal_Bool( *aL.pOUString == *aR.pOUString ); break; 1506 case SbxNE: 1507 bRes = sal_Bool( *aL.pOUString != *aR.pOUString ); break; 1508 case SbxLT: 1509 bRes = sal_Bool( *aL.pOUString < *aR.pOUString ); break; 1510 case SbxGT: 1511 bRes = sal_Bool( *aL.pOUString > *aR.pOUString ); break; 1512 case SbxLE: 1513 bRes = sal_Bool( *aL.pOUString <= *aR.pOUString ); break; 1514 case SbxGE: 1515 bRes = sal_Bool( *aL.pOUString >= *aR.pOUString ); break; 1516 default: 1517 SetError( SbxERR_NOTIMP ); 1518 } 1519 } 1520 // AB 19.12.95: Wenn SbxSINGLE beteiligt, auf SINGLE konvertieren, 1521 // sonst gibt es numerische Fehler 1522 else if( GetType() == SbxSINGLE || rOp.GetType() == SbxSINGLE ) 1523 { 1524 aL.eType = aR.eType = SbxSINGLE; 1525 if( Get( aL ) && rOp.Get( aR ) ) 1526 switch( eOp ) 1527 { 1528 case SbxEQ: 1529 bRes = sal_Bool( aL.nSingle == aR.nSingle ); break; 1530 case SbxNE: 1531 bRes = sal_Bool( aL.nSingle != aR.nSingle ); break; 1532 case SbxLT: 1533 bRes = sal_Bool( aL.nSingle < aR.nSingle ); break; 1534 case SbxGT: 1535 bRes = sal_Bool( aL.nSingle > aR.nSingle ); break; 1536 case SbxLE: 1537 bRes = sal_Bool( aL.nSingle <= aR.nSingle ); break; 1538 case SbxGE: 1539 bRes = sal_Bool( aL.nSingle >= aR.nSingle ); break; 1540 default: 1541 SetError( SbxERR_NOTIMP ); 1542 } 1543 } 1544 else if( GetType() == SbxDECIMAL && rOp.GetType() == SbxDECIMAL ) 1545 { 1546 aL.eType = aR.eType = SbxDECIMAL; 1547 Get( aL ); 1548 rOp.Get( aR ); 1549 if( aL.pDecimal && aR.pDecimal ) 1550 { 1551 SbxDecimal::CmpResult eRes = compare( *aL.pDecimal, *aR.pDecimal ); 1552 switch( eOp ) 1553 { 1554 case SbxEQ: 1555 bRes = sal_Bool( eRes == SbxDecimal::EQ ); break; 1556 case SbxNE: 1557 bRes = sal_Bool( eRes != SbxDecimal::EQ ); break; 1558 case SbxLT: 1559 bRes = sal_Bool( eRes == SbxDecimal::LT ); break; 1560 case SbxGT: 1561 bRes = sal_Bool( eRes == SbxDecimal::GT ); break; 1562 case SbxLE: 1563 bRes = sal_Bool( eRes != SbxDecimal::GT ); break; 1564 case SbxGE: 1565 bRes = sal_Bool( eRes != SbxDecimal::LT ); break; 1566 default: 1567 SetError( SbxERR_NOTIMP ); 1568 } 1569 } 1570 else 1571 { 1572 SetError( SbxERR_CONVERSION ); 1573 } 1574 releaseDecimalPtr( aL.pDecimal ); 1575 releaseDecimalPtr( aR.pDecimal ); 1576 } 1577 // Alles andere auf SbxDOUBLE-Basis vergleichen 1578 else 1579 { 1580 aL.eType = aR.eType = SbxDOUBLE; 1581 //if( Get( aL ) && rOp.Get( aR ) ) 1582 bool bGetL = Get( aL ); 1583 bool bGetR = rOp.Get( aR ); 1584 if( bGetL && bGetR ) 1585 switch( eOp ) 1586 { 1587 case SbxEQ: 1588 bRes = sal_Bool( aL.nDouble == aR.nDouble ); break; 1589 case SbxNE: 1590 bRes = sal_Bool( aL.nDouble != aR.nDouble ); break; 1591 case SbxLT: 1592 bRes = sal_Bool( aL.nDouble < aR.nDouble ); break; 1593 case SbxGT: 1594 bRes = sal_Bool( aL.nDouble > aR.nDouble ); break; 1595 case SbxLE: 1596 bRes = sal_Bool( aL.nDouble <= aR.nDouble ); break; 1597 case SbxGE: 1598 bRes = sal_Bool( aL.nDouble >= aR.nDouble ); break; 1599 default: 1600 SetError( SbxERR_NOTIMP ); 1601 } 1602 // at least one value was got 1603 // if this is VBA then a conversion error for one 1604 // side will yield a false result of an equality test 1605 else if ( bGetR || bGetL ) 1606 { 1607 if ( bVBAInterop && eOp == SbxEQ && GetError() == SbxERR_CONVERSION ) 1608 { 1609 ResetError(); 1610 bRes = sal_False; 1611 } 1612 } 1613 } 1614 } 1615 if( eOld != SbxERR_OK ) 1616 SetError( eOld ); 1617 return bRes; 1618 } 1619 1620 ///////////////////////////// Lesen/Schreiben //////////////////////////// 1621 1622 sal_Bool SbxValue::LoadData( SvStream& r, sal_uInt16 ) 1623 { 1624 SbxValue::Clear(); 1625 sal_uInt16 nType; 1626 r >> nType; 1627 aData.eType = SbxDataType( nType ); 1628 switch( nType ) 1629 { 1630 case SbxBOOL: 1631 case SbxINTEGER: 1632 r >> aData.nInteger; break; 1633 case SbxLONG: 1634 r >> aData.nLong; break; 1635 case SbxSINGLE: 1636 { 1637 // Floats als ASCII 1638 XubString aVal; 1639 r.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US ); 1640 double d; 1641 SbxDataType t; 1642 if( ImpScan( aVal, d, t, NULL ) != SbxERR_OK || t == SbxDOUBLE ) 1643 { 1644 aData.nSingle = 0.0F; 1645 return sal_False; 1646 } 1647 aData.nSingle = (float) d; 1648 break; 1649 } 1650 case SbxDATE: 1651 case SbxDOUBLE: 1652 { 1653 // Floats als ASCII 1654 XubString aVal; 1655 r.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US ); 1656 SbxDataType t; 1657 if( ImpScan( aVal, aData.nDouble, t, NULL ) != SbxERR_OK ) 1658 { 1659 aData.nDouble = 0.0; 1660 return sal_False; 1661 } 1662 break; 1663 } 1664 case SbxULONG64: 1665 { 1666 r >> aData.nULong64.nHigh >> aData.nULong64.nLow; 1667 break; 1668 } 1669 case SbxLONG64: 1670 case SbxCURRENCY: 1671 { 1672 r >> aData.nLong64.nHigh >> aData.nLong64.nLow; 1673 break; 1674 } 1675 case SbxSTRING: 1676 { 1677 XubString aVal; 1678 r.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US ); 1679 if( aVal.Len() ) 1680 aData.pOUString = new ::rtl::OUString( aVal ); 1681 else 1682 aData.pOUString = NULL; // JSM 22.09.1995 1683 break; 1684 } 1685 case SbxERROR: 1686 case SbxUSHORT: 1687 r >> aData.nUShort; break; 1688 case SbxOBJECT: 1689 { 1690 sal_uInt8 nMode; 1691 r >> nMode; 1692 switch( nMode ) 1693 { 1694 case 0: 1695 aData.pObj = NULL; 1696 break; 1697 case 1: 1698 aData.pObj = SbxBase::Load( r ); 1699 return sal_Bool( aData.pObj != NULL ); 1700 case 2: 1701 aData.pObj = this; 1702 break; 1703 } 1704 break; 1705 } 1706 case SbxCHAR: 1707 { 1708 char c; 1709 r >> c; 1710 aData.nChar = c; 1711 break; 1712 } 1713 case SbxBYTE: 1714 r >> aData.nByte; break; 1715 case SbxULONG: 1716 r >> aData.nULong; break; 1717 case SbxINT: 1718 { 1719 sal_uInt8 n; 1720 r >> n; 1721 // Passt der Int auf diesem System? 1722 if( n > SAL_TYPES_SIZEOFINT ) 1723 r >> aData.nLong, aData.eType = SbxLONG; 1724 else 1725 r >> aData.nInt; 1726 break; 1727 } 1728 case SbxUINT: 1729 { 1730 sal_uInt8 n; 1731 r >> n; 1732 // Passt der UInt auf diesem System? 1733 if( n > SAL_TYPES_SIZEOFINT ) 1734 r >> aData.nULong, aData.eType = SbxULONG; 1735 else 1736 r >> (sal_uInt32&)aData.nUInt; 1737 break; 1738 } 1739 case SbxEMPTY: 1740 case SbxNULL: 1741 case SbxVOID: 1742 break; 1743 case SbxDATAOBJECT: 1744 r >> aData.nLong; 1745 break; 1746 // #78919 For backwards compatibility 1747 case SbxWSTRING: 1748 case SbxWCHAR: 1749 break; 1750 default: 1751 memset (&aData,0,sizeof(aData)); 1752 ResetFlag(SBX_FIXED); 1753 aData.eType = SbxNULL; 1754 DBG_ASSERT( !this, "Nicht unterstuetzer Datentyp geladen" ); 1755 return sal_False; 1756 } 1757 return sal_True; 1758 } 1759 1760 sal_Bool SbxValue::StoreData( SvStream& r ) const 1761 { 1762 sal_uInt16 nType = sal::static_int_cast< sal_uInt16 >(aData.eType); 1763 r << nType; 1764 switch( nType & 0x0FFF ) 1765 { 1766 case SbxBOOL: 1767 case SbxINTEGER: 1768 r << aData.nInteger; break; 1769 case SbxLONG: 1770 r << aData.nLong; break; 1771 case SbxDATE: 1772 // #49935: Als double speichern, sonst Fehler beim Einlesen 1773 ((SbxValue*)this)->aData.eType = (SbxDataType)( ( nType & 0xF000 ) | SbxDOUBLE ); 1774 r.WriteByteString( GetCoreString(), RTL_TEXTENCODING_ASCII_US ); 1775 ((SbxValue*)this)->aData.eType = (SbxDataType)nType; 1776 break; 1777 case SbxSINGLE: 1778 case SbxDOUBLE: 1779 r.WriteByteString( GetCoreString(), RTL_TEXTENCODING_ASCII_US ); 1780 break; 1781 case SbxULONG64: 1782 { 1783 r << aData.nULong64.nHigh << aData.nULong64.nLow; 1784 break; 1785 } 1786 case SbxLONG64: 1787 case SbxCURRENCY: 1788 { 1789 r << aData.nLong64.nHigh << aData.nLong64.nLow; 1790 break; 1791 } 1792 case SbxSTRING: 1793 if( aData.pOUString ) 1794 { 1795 r.WriteByteString( *aData.pOUString, RTL_TEXTENCODING_ASCII_US ); 1796 } 1797 else 1798 { 1799 String aEmpty; 1800 r.WriteByteString( aEmpty, RTL_TEXTENCODING_ASCII_US ); 1801 } 1802 break; 1803 case SbxERROR: 1804 case SbxUSHORT: 1805 r << aData.nUShort; break; 1806 case SbxOBJECT: 1807 // sich selbst als Objektptr speichern geht nicht! 1808 if( aData.pObj ) 1809 { 1810 if( PTR_CAST(SbxValue,aData.pObj) != this ) 1811 { 1812 r << (sal_uInt8) 1; 1813 return aData.pObj->Store( r ); 1814 } 1815 else 1816 r << (sal_uInt8) 2; 1817 } 1818 else 1819 r << (sal_uInt8) 0; 1820 break; 1821 case SbxCHAR: 1822 { 1823 char c = sal::static_int_cast< char >(aData.nChar); 1824 r << c; 1825 break; 1826 } 1827 case SbxBYTE: 1828 r << aData.nByte; break; 1829 case SbxULONG: 1830 r << aData.nULong; break; 1831 case SbxINT: 1832 { 1833 sal_uInt8 n = SAL_TYPES_SIZEOFINT; 1834 r << n << (sal_Int32)aData.nInt; 1835 break; 1836 } 1837 case SbxUINT: 1838 { 1839 sal_uInt8 n = SAL_TYPES_SIZEOFINT; 1840 r << n << (sal_uInt32)aData.nUInt; 1841 break; 1842 } 1843 case SbxEMPTY: 1844 case SbxNULL: 1845 case SbxVOID: 1846 break; 1847 case SbxDATAOBJECT: 1848 r << aData.nLong; 1849 break; 1850 // #78919 For backwards compatibility 1851 case SbxWSTRING: 1852 case SbxWCHAR: 1853 break; 1854 default: 1855 DBG_ASSERT( !this, "Speichern eines nicht unterstuetzten Datentyps" ); 1856 return sal_False; 1857 } 1858 return sal_True; 1859 } 1860 1861