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 #include <tools/stream.hxx> 27 #include <basic/sbx.hxx> 28 #include "runtime.hxx" 29 #include <vector> 30 using namespace std; 31 32 struct SbxDim { // eine Array-Dimension: 33 SbxDim* pNext; // Link 34 sal_Int32 nLbound, nUbound; // Begrenzungen 35 sal_Int32 nSize; // Anzahl Elemente 36 }; 37 38 class SbxVarEntry : public SbxVariableRef { 39 public: 40 XubString* pAlias; 41 SbxVarEntry() : SbxVariableRef(), pAlias( NULL ) {} 42 ~SbxVarEntry() { delete pAlias; } 43 }; 44 45 typedef SbxVarEntry* SbxVarEntryPtr; 46 typedef vector< SbxVarEntryPtr > SbxVarEntryPtrVector; 47 class SbxVarRefs : public SbxVarEntryPtrVector 48 { 49 public: 50 SbxVarRefs( void ) {} 51 }; 52 53 54 TYPEINIT1(SbxArray,SbxBase) 55 TYPEINIT1(SbxDimArray,SbxArray) 56 57 ////////////////////////////////////////////////////////////////////////// 58 // 59 // SbxArray 60 // 61 ////////////////////////////////////////////////////////////////////////// 62 63 SbxArray::SbxArray( SbxDataType t ) : SbxBase() 64 { 65 pData = new SbxVarRefs; 66 eType = t; 67 if( t != SbxVARIANT ) 68 SetFlag( SBX_FIXED ); 69 } 70 71 SbxArray::SbxArray( const SbxArray& rArray ) : 72 SvRefBase( rArray ), SbxBase() 73 { 74 pData = new SbxVarRefs; 75 if( rArray.eType != SbxVARIANT ) 76 SetFlag( SBX_FIXED ); 77 *this = rArray; 78 } 79 80 SbxArray& SbxArray::operator=( const SbxArray& rArray ) 81 { 82 if( &rArray != this ) 83 { 84 eType = rArray.eType; 85 Clear(); 86 SbxVarRefs* pSrc = rArray.pData; 87 for( sal_uInt32 i = 0; i < pSrc->size(); i++ ) 88 { 89 SbxVarEntryPtr pSrcRef = (*pSrc)[i]; 90 const SbxVariable* pSrc_ = *pSrcRef; 91 if( !pSrc_ ) 92 continue; 93 SbxVarEntryPtr pDstRef = new SbxVarEntry; 94 *((SbxVariableRef*) pDstRef) = *((SbxVariableRef*) pSrcRef); 95 if( pSrcRef->pAlias ) 96 pDstRef->pAlias = new XubString( *pSrcRef->pAlias ); 97 if( eType != SbxVARIANT ) 98 // Keine Objekte konvertieren 99 if( eType != SbxOBJECT || pSrc_->GetClass() != SbxCLASS_OBJECT ) 100 ((SbxVariable*) pSrc_)->Convert( eType ); 101 pData->push_back( pDstRef ); 102 } 103 } 104 return *this; 105 } 106 107 SbxArray::~SbxArray() 108 { 109 Clear(); 110 delete pData; 111 } 112 113 SbxDataType SbxArray::GetType() const 114 { 115 return (SbxDataType) ( eType | SbxARRAY ); 116 } 117 118 SbxClassType SbxArray::GetClass() const 119 { 120 return SbxCLASS_ARRAY; 121 } 122 123 void SbxArray::Clear() 124 { 125 sal_uInt32 nSize = pData->size(); 126 for( sal_uInt32 i = 0 ; i < nSize ; i++ ) 127 { 128 SbxVarEntry* pEntry = (*pData)[i]; 129 delete pEntry; 130 } 131 pData->clear(); 132 } 133 134 sal_uInt32 SbxArray::Count32() const 135 { 136 return pData->size(); 137 } 138 139 sal_uInt16 SbxArray::Count() const 140 { 141 sal_uInt32 nCount = pData->size(); 142 DBG_ASSERT( nCount <= SBX_MAXINDEX, "SBX: Array-Index > SBX_MAXINDEX" ); 143 return (sal_uInt16)nCount; 144 } 145 146 SbxVariableRef& SbxArray::GetRef32( sal_uInt32 nIdx ) 147 { 148 // Array ggf. vergroessern 149 DBG_ASSERT( nIdx <= SBX_MAXINDEX32, "SBX: Array-Index > SBX_MAXINDEX32" ); 150 // Very Hot Fix 151 if( nIdx > SBX_MAXINDEX32 ) 152 { 153 SetError( SbxERR_BOUNDS ); 154 nIdx = 0; 155 } 156 while( pData->size() <= nIdx ) 157 { 158 const SbxVarEntryPtr p = new SbxVarEntry; 159 pData->push_back( p ); 160 } 161 return *((*pData)[nIdx]); 162 } 163 164 SbxVariableRef& SbxArray::GetRef( sal_uInt16 nIdx ) 165 { 166 // Array ggf. vergroessern 167 DBG_ASSERT( nIdx <= SBX_MAXINDEX, "SBX: Array-Index > SBX_MAXINDEX" ); 168 // Very Hot Fix 169 if( nIdx > SBX_MAXINDEX ) 170 { 171 SetError( SbxERR_BOUNDS ); 172 nIdx = 0; 173 } 174 while( pData->size() <= nIdx ) 175 { 176 const SbxVarEntryPtr p = new SbxVarEntry; 177 pData->push_back( p ); 178 } 179 return *((*pData)[nIdx]); 180 } 181 182 SbxVariable* SbxArray::Get32( sal_uInt32 nIdx ) 183 { 184 if( !CanRead() ) 185 { 186 SetError( SbxERR_PROP_WRITEONLY ); 187 return NULL; 188 } 189 SbxVariableRef& rRef = GetRef32( nIdx ); 190 191 if ( !rRef.Is() ) 192 rRef = new SbxVariable( eType ); 193 #ifdef DBG_UTIL 194 else 195 DBG_CHKOBJ( rRef, SbxBase, 0 ); 196 #endif 197 198 return rRef; 199 } 200 201 SbxVariable* SbxArray::Get( sal_uInt16 nIdx ) 202 { 203 if( !CanRead() ) 204 { 205 SetError( SbxERR_PROP_WRITEONLY ); 206 return NULL; 207 } 208 SbxVariableRef& rRef = GetRef( nIdx ); 209 210 if ( !rRef.Is() ) 211 rRef = new SbxVariable( eType ); 212 #ifdef DBG_UTIL 213 else 214 DBG_CHKOBJ( rRef, SbxBase, 0 ); 215 #endif 216 217 return rRef; 218 } 219 220 void SbxArray::Put32( SbxVariable* pVar, sal_uInt32 nIdx ) 221 { 222 if( !CanWrite() ) 223 SetError( SbxERR_PROP_READONLY ); 224 else 225 { 226 if( pVar ) 227 if( eType != SbxVARIANT ) 228 // Keine Objekte konvertieren 229 if( eType != SbxOBJECT || pVar->GetClass() != SbxCLASS_OBJECT ) 230 pVar->Convert( eType ); 231 SbxVariableRef& rRef = GetRef32( nIdx ); 232 if( (SbxVariable*) rRef != pVar ) 233 { 234 rRef = pVar; 235 SetFlag( SBX_MODIFIED ); 236 } 237 } 238 } 239 240 void SbxArray::Put( SbxVariable* pVar, sal_uInt16 nIdx ) 241 { 242 if( !CanWrite() ) 243 SetError( SbxERR_PROP_READONLY ); 244 else 245 { 246 if( pVar ) 247 if( eType != SbxVARIANT ) 248 // Keine Objekte konvertieren 249 if( eType != SbxOBJECT || pVar->GetClass() != SbxCLASS_OBJECT ) 250 pVar->Convert( eType ); 251 SbxVariableRef& rRef = GetRef( nIdx ); 252 if( (SbxVariable*) rRef != pVar ) 253 { 254 rRef = pVar; 255 SetFlag( SBX_MODIFIED ); 256 } 257 } 258 } 259 260 const XubString& SbxArray::GetAlias( sal_uInt16 nIdx ) 261 { 262 if( !CanRead() ) 263 { 264 SetError( SbxERR_PROP_WRITEONLY ); 265 return String::EmptyString(); 266 } 267 SbxVarEntry& rRef = (SbxVarEntry&) GetRef( nIdx ); 268 269 if ( !rRef.pAlias ) 270 return String::EmptyString(); 271 #ifdef DBG_UTIL 272 else 273 DBG_CHKOBJ( rRef, SbxBase, 0 ); 274 #endif 275 276 return *rRef.pAlias; 277 } 278 279 void SbxArray::PutAlias( const XubString& rAlias, sal_uInt16 nIdx ) 280 { 281 if( !CanWrite() ) 282 SetError( SbxERR_PROP_READONLY ); 283 else 284 { 285 SbxVarEntry& rRef = (SbxVarEntry&) GetRef( nIdx ); 286 if( !rRef.pAlias ) 287 rRef.pAlias = new XubString( rAlias ); 288 else 289 *rRef.pAlias = rAlias; 290 } 291 } 292 293 void SbxArray::Insert32( SbxVariable* pVar, sal_uInt32 nIdx ) 294 { 295 DBG_ASSERT( pData->size() <= SBX_MAXINDEX32, "SBX: Array wird zu gross" ); 296 if( pData->size() > SBX_MAXINDEX32 ) 297 return; 298 SbxVarEntryPtr p = new SbxVarEntry; 299 *((SbxVariableRef*) p) = pVar; 300 SbxVarEntryPtrVector::size_type nSize = pData->size(); 301 if( nIdx > nSize ) 302 nIdx = nSize; 303 if( eType != SbxVARIANT && pVar ) 304 (*p)->Convert( eType ); 305 if( nIdx == nSize ) 306 { 307 pData->push_back( p ); 308 } 309 else 310 { 311 pData->insert( pData->begin() + nIdx, p ); 312 } 313 SetFlag( SBX_MODIFIED ); 314 } 315 316 void SbxArray::Insert( SbxVariable* pVar, sal_uInt16 nIdx ) 317 { 318 DBG_ASSERT( pData->size() <= 0x3FF0, "SBX: Array wird zu gross" ); 319 if( pData->size() > 0x3FF0 ) 320 return; 321 Insert32( pVar, nIdx ); 322 } 323 324 void SbxArray::Remove32( sal_uInt32 nIdx ) 325 { 326 if( nIdx < pData->size() ) 327 { 328 SbxVariableRef* pRef = (*pData)[nIdx]; 329 pData->erase( pData->begin() + nIdx ); 330 delete pRef; 331 SetFlag( SBX_MODIFIED ); 332 } 333 } 334 335 void SbxArray::Remove( sal_uInt16 nIdx ) 336 { 337 if( nIdx < pData->size() ) 338 { 339 SbxVariableRef* pRef = (*pData)[nIdx]; 340 pData->erase( pData->begin() + nIdx ); 341 delete pRef; 342 SetFlag( SBX_MODIFIED ); 343 } 344 } 345 346 void SbxArray::Remove( SbxVariable* pVar ) 347 { 348 if( pVar ) 349 { 350 for( sal_uInt32 i = 0; i < pData->size(); i++ ) 351 { 352 SbxVariableRef* pRef = (*pData)[i]; 353 // SbxVariableRef* pRef = pData->GetObject( i ); 354 if( *pRef == pVar ) 355 { 356 Remove32( i ); break; 357 } 358 } 359 } 360 } 361 362 // Uebernahme der Daten aus dem uebergebenen Array, wobei 363 // gleichnamige Variable ueberschrieben werden. 364 365 void SbxArray::Merge( SbxArray* p ) 366 { 367 if( p ) 368 { 369 sal_uInt32 nSize = p->Count(); 370 for( sal_uInt32 i = 0; i < nSize; i++ ) 371 { 372 SbxVarEntryPtr pRef1 = (*(p->pData))[i]; 373 // Ist das Element by name schon drin? 374 // Dann ueberschreiben! 375 SbxVariable* pVar = *pRef1; 376 if( pVar ) 377 { 378 XubString aName = pVar->GetName(); 379 sal_uInt16 nHash = pVar->GetHashCode(); 380 for( sal_uInt32 j = 0; j < pData->size(); j++ ) 381 { 382 SbxVariableRef* pRef2 = (*pData)[j]; 383 if( (*pRef2)->GetHashCode() == nHash 384 && (*pRef2)->GetName().EqualsIgnoreCaseAscii( aName ) ) 385 { 386 *pRef2 = pVar; pRef1 = NULL; 387 break; 388 } 389 } 390 if( pRef1 ) 391 { 392 SbxVarEntryPtr pRef = new SbxVarEntry; 393 const SbxVarEntryPtr pTemp = pRef; 394 pData->push_back( pTemp ); 395 *((SbxVariableRef*) pRef) = *((SbxVariableRef*) pRef1); 396 if( pRef1->pAlias ) 397 pRef->pAlias = new XubString( *pRef1->pAlias ); 398 } 399 } 400 } 401 } 402 } 403 404 // Suchen eines Elements ueber die Userdaten. Falls ein Element 405 // ein Objekt ist, wird dieses ebenfalls durchsucht. 406 407 SbxVariable* SbxArray::FindUserData( sal_uInt32 nData ) 408 { 409 SbxVariable* p = NULL; 410 for( sal_uInt32 i = 0; i < pData->size(); i++ ) 411 { 412 SbxVariableRef* pRef = (*pData)[i]; 413 SbxVariable* pVar = *pRef; 414 if( pVar ) 415 { 416 if( pVar->IsVisible() && pVar->GetUserData() == nData ) 417 { 418 p = pVar; 419 p->ResetFlag( SBX_EXTFOUND ); 420 break; // JSM 06.10.95 421 } 422 // Haben wir ein Array/Objekt mit Extended Search? 423 else if( pVar->IsSet( SBX_EXTSEARCH ) ) 424 { 425 switch( pVar->GetClass() ) 426 { 427 case SbxCLASS_OBJECT: 428 { 429 // Objekte duerfen ihren Parent nicht durchsuchen 430 sal_uInt16 nOld = pVar->GetFlags(); 431 pVar->ResetFlag( SBX_GBLSEARCH ); 432 p = ((SbxObject*) pVar)->FindUserData( nData ); 433 pVar->SetFlags( nOld ); 434 break; 435 } 436 case SbxCLASS_ARRAY: 437 p = ((SbxArray*) pVar)->FindUserData( nData ); 438 break; 439 default: break; 440 } 441 if( p ) 442 { 443 p->SetFlag( SBX_EXTFOUND ); 444 break; 445 } 446 } 447 } 448 } 449 return p; 450 } 451 452 // Suchen eines Elements ueber den Namen und den Typ. Falls ein Element 453 // ein Objekt ist, wird dieses ebenfalls durchsucht. 454 455 SbxVariable* SbxArray::Find( const XubString& rName, SbxClassType t ) 456 { 457 SbxVariable* p = NULL; 458 sal_uInt32 nCount = pData->size(); 459 if( !nCount ) 460 return NULL; 461 sal_Bool bExtSearch = IsSet( SBX_EXTSEARCH ); 462 sal_uInt16 nHash = SbxVariable::MakeHashCode( rName ); 463 for( sal_uInt32 i = 0; i < nCount; i++ ) 464 { 465 SbxVariableRef* pRef = (*pData)[i]; 466 SbxVariable* pVar = *pRef; 467 if( pVar && pVar->IsVisible() ) 468 { 469 // Die ganz sichere Suche klappt auch, wenn es 470 // keinen Hascode gibt! 471 sal_uInt16 nVarHash = pVar->GetHashCode(); 472 if( ( !nVarHash || nVarHash == nHash ) 473 && ( t == SbxCLASS_DONTCARE || pVar->GetClass() == t ) 474 && ( pVar->GetName().EqualsIgnoreCaseAscii( rName ) ) ) 475 { 476 p = pVar; 477 p->ResetFlag( SBX_EXTFOUND ); 478 break; 479 } 480 // Haben wir ein Array/Objekt mit Extended Search? 481 else if( bExtSearch && pVar->IsSet( SBX_EXTSEARCH ) ) 482 { 483 switch( pVar->GetClass() ) 484 { 485 case SbxCLASS_OBJECT: 486 { 487 // Objekte duerfen ihren Parent nicht durchsuchen 488 sal_uInt16 nOld = pVar->GetFlags(); 489 pVar->ResetFlag( SBX_GBLSEARCH ); 490 p = ((SbxObject*) pVar)->Find( rName, t ); 491 pVar->SetFlags( nOld ); 492 break; 493 } 494 case SbxCLASS_ARRAY: 495 p = ((SbxArray*) pVar)->Find( rName, t ); 496 break; 497 default: break; 498 } 499 if( p ) 500 { 501 p->SetFlag( SBX_EXTFOUND ); 502 break; 503 } 504 } 505 } 506 } 507 return p; 508 } 509 510 sal_Bool SbxArray::LoadData( SvStream& rStrm, sal_uInt16 nVer ) 511 { 512 sal_uInt16 nElem; 513 Clear(); 514 sal_Bool bRes = sal_True; 515 sal_uInt16 f = nFlags; 516 nFlags |= SBX_WRITE; 517 rStrm >> nElem; 518 nElem &= 0x7FFF; 519 for( sal_uInt32 n = 0; n < nElem; n++ ) 520 { 521 sal_uInt16 nIdx; 522 rStrm >> nIdx; 523 SbxVariable* pVar = (SbxVariable*) Load( rStrm ); 524 if( pVar ) 525 { 526 SbxVariableRef& rRef = GetRef( nIdx ); 527 rRef = pVar; 528 } 529 else 530 { 531 bRes = sal_False; break; 532 } 533 } 534 if( bRes ) 535 bRes = LoadPrivateData( rStrm, nVer ); 536 nFlags = f; 537 return bRes; 538 } 539 540 sal_Bool SbxArray::StoreData( SvStream& rStrm ) const 541 { 542 sal_uInt32 nElem = 0; 543 sal_uInt32 n; 544 // Welche Elemente sind ueberhaupt definiert? 545 for( n = 0; n < pData->size(); n++ ) 546 { 547 SbxVariableRef* pRef = (*pData)[n]; 548 SbxVariable* p = *pRef; 549 if( p && !( p->GetFlags() & SBX_DONTSTORE ) ) 550 nElem++; 551 } 552 rStrm << (sal_uInt16) nElem; 553 for( n = 0; n < pData->size(); n++ ) 554 { 555 SbxVariableRef* pRef = (*pData)[n]; 556 SbxVariable* p = *pRef; 557 if( p && !( p->GetFlags() & SBX_DONTSTORE ) ) 558 { 559 rStrm << (sal_uInt16) n; 560 if( !p->Store( rStrm ) ) 561 return sal_False; 562 } 563 } 564 return StorePrivateData( rStrm ); 565 } 566 567 // #100883 Method to set method directly to parameter array 568 void SbxArray::PutDirect( SbxVariable* pVar, sal_uInt32 nIdx ) 569 { 570 SbxVariableRef& rRef = GetRef32( nIdx ); 571 rRef = pVar; 572 } 573 574 575 ////////////////////////////////////////////////////////////////////////// 576 // 577 // SbxArray 578 // 579 ////////////////////////////////////////////////////////////////////////// 580 581 SbxDimArray::SbxDimArray( SbxDataType t ) : SbxArray( t ), mbHasFixedSize( false ) 582 { 583 pFirst = pLast = NULL; 584 nDim = 0; 585 } 586 587 SbxDimArray::SbxDimArray( const SbxDimArray& rArray ) 588 : SvRefBase( rArray ), SbxArray( rArray.eType ) 589 { 590 pFirst = pLast = NULL; 591 nDim = 0; 592 *this = rArray; 593 } 594 595 SbxDimArray& SbxDimArray::operator=( const SbxDimArray& rArray ) 596 { 597 if( &rArray != this ) 598 { 599 SbxArray::operator=( (const SbxArray&) rArray ); 600 SbxDim* p = rArray.pFirst; 601 while( p ) 602 { 603 AddDim32( p->nLbound, p->nUbound ); 604 p = p->pNext; 605 } 606 this->mbHasFixedSize = rArray.mbHasFixedSize; 607 } 608 return *this; 609 } 610 611 SbxDimArray::~SbxDimArray() 612 { 613 Clear(); 614 } 615 616 void SbxDimArray::Clear() 617 { 618 SbxDim* p = pFirst; 619 while( p ) 620 { 621 SbxDim* q = p->pNext; 622 delete p; 623 p = q; 624 } 625 pFirst = pLast = NULL; 626 nDim = 0; 627 } 628 629 // Dimension hinzufuegen 630 631 void SbxDimArray::AddDimImpl32( sal_Int32 lb, sal_Int32 ub, sal_Bool bAllowSize0 ) 632 { 633 SbxError eRes = SbxERR_OK; 634 if( ub < lb && !bAllowSize0 ) 635 { 636 eRes = SbxERR_BOUNDS; 637 ub = lb; 638 } 639 SbxDim* p = new SbxDim; 640 p->nLbound = lb; 641 p->nUbound = ub; 642 p->nSize = ub - lb + 1; 643 p->pNext = NULL; 644 if( !pFirst ) 645 pFirst = pLast = p; 646 else 647 pLast->pNext = p, pLast = p; 648 nDim++; 649 if( eRes ) 650 SetError( eRes ); 651 } 652 653 void SbxDimArray::AddDim( short lb, short ub ) 654 { 655 AddDimImpl32( lb, ub, sal_False ); 656 } 657 658 void SbxDimArray::unoAddDim( short lb, short ub ) 659 { 660 AddDimImpl32( lb, ub, sal_True ); 661 } 662 663 void SbxDimArray::AddDim32( sal_Int32 lb, sal_Int32 ub ) 664 { 665 AddDimImpl32( lb, ub, sal_False ); 666 } 667 668 void SbxDimArray::unoAddDim32( sal_Int32 lb, sal_Int32 ub ) 669 { 670 AddDimImpl32( lb, ub, sal_True ); 671 } 672 673 674 // Dimensionsdaten auslesen 675 676 sal_Bool SbxDimArray::GetDim32( sal_Int32 n, sal_Int32& rlb, sal_Int32& rub ) const 677 { 678 if( n < 1 || n > nDim ) 679 { 680 SetError( SbxERR_BOUNDS ); rub = rlb = 0; return sal_False; 681 } 682 SbxDim* p = pFirst; 683 while( --n ) 684 p = p->pNext; 685 rub = p->nUbound; 686 rlb = p->nLbound; 687 return sal_True; 688 } 689 690 sal_Bool SbxDimArray::GetDim( short n, short& rlb, short& rub ) const 691 { 692 sal_Int32 rlb32, rub32; 693 sal_Bool bRet = GetDim32( n, rlb32, rub32 ); 694 if( bRet ) 695 { 696 if( rlb32 < -SBX_MAXINDEX || rub32 > SBX_MAXINDEX ) 697 { 698 SetError( SbxERR_BOUNDS ); 699 return sal_False; 700 } 701 rub = (short)rub32; 702 rlb = (short)rlb32; 703 } 704 return bRet; 705 } 706 707 // Element-Ptr anhand einer Index-Liste 708 709 sal_uInt32 SbxDimArray::Offset32( const sal_Int32* pIdx ) 710 { 711 sal_uInt32 nPos = 0; 712 for( SbxDim* p = pFirst; p; p = p->pNext ) 713 { 714 sal_Int32 nIdx = *pIdx++; 715 if( nIdx < p->nLbound || nIdx > p->nUbound ) 716 { 717 nPos = (sal_uInt32)SBX_MAXINDEX32 + 1; break; 718 } 719 nPos = nPos * p->nSize + nIdx - p->nLbound; 720 } 721 if( nDim == 0 || nPos > SBX_MAXINDEX32 ) 722 { 723 SetError( SbxERR_BOUNDS ); nPos = 0; 724 } 725 return nPos; 726 } 727 728 sal_uInt16 SbxDimArray::Offset( const short* pIdx ) 729 { 730 long nPos = 0; 731 for( SbxDim* p = pFirst; p; p = p->pNext ) 732 { 733 short nIdx = *pIdx++; 734 if( nIdx < p->nLbound || nIdx > p->nUbound ) 735 { 736 nPos = SBX_MAXINDEX + 1; break; 737 } 738 nPos = nPos * p->nSize + nIdx - p->nLbound; 739 } 740 if( nDim == 0 || nPos > SBX_MAXINDEX ) 741 { 742 SetError( SbxERR_BOUNDS ); nPos = 0; 743 } 744 return (sal_uInt16) nPos; 745 } 746 747 SbxVariableRef& SbxDimArray::GetRef( const short* pIdx ) 748 { 749 return SbxArray::GetRef( Offset( pIdx ) ); 750 } 751 752 SbxVariable* SbxDimArray::Get( const short* pIdx ) 753 { 754 return SbxArray::Get( Offset( pIdx ) ); 755 } 756 757 void SbxDimArray::Put( SbxVariable* p, const short* pIdx ) 758 { 759 SbxArray::Put( p, Offset( pIdx ) ); 760 } 761 762 SbxVariableRef& SbxDimArray::GetRef32( const sal_Int32* pIdx ) 763 { 764 return SbxArray::GetRef32( Offset32( pIdx ) ); 765 } 766 767 SbxVariable* SbxDimArray::Get32( const sal_Int32* pIdx ) 768 { 769 return SbxArray::Get32( Offset32( pIdx ) ); 770 } 771 772 void SbxDimArray::Put32( SbxVariable* p, const sal_Int32* pIdx ) 773 { 774 SbxArray::Put32( p, Offset32( pIdx ) ); 775 } 776 777 778 // Element-Nr anhand eines Parameter-Arrays 779 780 sal_uInt32 SbxDimArray::Offset32( SbxArray* pPar ) 781 { 782 if( nDim == 0 || !pPar || ( ( nDim != ( pPar->Count() - 1 ) ) && SbiRuntime::isVBAEnabled() ) ) 783 { 784 SetError( SbxERR_BOUNDS ); return 0; 785 } 786 sal_uInt32 nPos = 0; 787 sal_uInt16 nOff = 1; // Nicht Element 0! 788 for( SbxDim* p = pFirst; p && !IsError(); p = p->pNext ) 789 { 790 sal_Int32 nIdx = pPar->Get( nOff++ )->GetLong(); 791 if( nIdx < p->nLbound || nIdx > p->nUbound ) 792 { 793 nPos = (sal_uInt32) SBX_MAXINDEX32+1; break; 794 } 795 nPos = nPos * p->nSize + nIdx - p->nLbound; 796 } 797 if( nPos > (sal_uInt32) SBX_MAXINDEX32 ) 798 { 799 SetError( SbxERR_BOUNDS ); nPos = 0; 800 } 801 return nPos; 802 } 803 804 sal_uInt16 SbxDimArray::Offset( SbxArray* pPar ) 805 { 806 sal_uInt32 nPos = Offset32( pPar ); 807 if( nPos > (long) SBX_MAXINDEX ) 808 { 809 SetError( SbxERR_BOUNDS ); nPos = 0; 810 } 811 return (sal_uInt16) nPos; 812 } 813 814 SbxVariableRef& SbxDimArray::GetRef( SbxArray* pPar ) 815 { 816 return SbxArray::GetRef32( Offset32( pPar ) ); 817 } 818 819 SbxVariable* SbxDimArray::Get( SbxArray* pPar ) 820 { 821 return SbxArray::Get32( Offset32( pPar ) ); 822 } 823 824 void SbxDimArray::Put( SbxVariable* p, SbxArray* pPar ) 825 { 826 SbxArray::Put32( p, Offset32( pPar ) ); 827 } 828 829 sal_Bool SbxDimArray::LoadData( SvStream& rStrm, sal_uInt16 nVer ) 830 { 831 short nDimension; 832 rStrm >> nDimension; 833 for( short i = 0; i < nDimension && rStrm.GetError() == SVSTREAM_OK; i++ ) 834 { 835 sal_Int16 lb, ub; 836 rStrm >> lb >> ub; 837 AddDim( lb, ub ); 838 } 839 return SbxArray::LoadData( rStrm, nVer ); 840 } 841 842 sal_Bool SbxDimArray::StoreData( SvStream& rStrm ) const 843 { 844 rStrm << (sal_Int16) nDim; 845 for( short i = 0; i < nDim; i++ ) 846 { 847 short lb, ub; 848 GetDim( i, lb, ub ); 849 rStrm << (sal_Int16) lb << (sal_Int16) ub; 850 } 851 return SbxArray::StoreData( rStrm ); 852 } 853 854