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_tools.hxx" 26 27 #ifndef _LIMITS_H 28 #include <limits.h> 29 #endif 30 31 #ifndef _STRING_H 32 #include <string.h> 33 #endif 34 35 #ifndef _STDIO_H 36 #include <stdio.h> 37 #endif 38 #include <tools/solar.h> 39 #include <impcont.hxx> 40 #include <tools/contnr.hxx> 41 #include <tools/debug.hxx> 42 43 // ----------------------------------------------------------------------- 44 45 DBG_NAME( CBlock ) 46 DBG_NAME( Container ) 47 48 /************************************************************************* 49 |* 50 |* DbgCheckCBlock() 51 |* 52 |* Beschreibung Pruefung eines CBlock fuer Debug-Utilities 53 |* Ersterstellung MI 30.01.92 54 |* Letzte Aenderung TH 24.01.96 55 |* 56 *************************************************************************/ 57 58 #ifdef DBG_UTIL 59 const char* CBlock::DbgCheckCBlock( const void* pBlock ) 60 { 61 CBlock* p = (CBlock*)pBlock; 62 63 if ( p->nCount > p->nSize ) 64 return "nCount > nSize"; 65 66 if ( p->nSize && !p->pNodes ) 67 return "nSize > 0 && pNodes == NULL"; 68 69 return NULL; 70 } 71 #endif 72 73 /************************************************************************* 74 |* 75 |* CBlock::CBlock() 76 |* 77 |* Beschreibung Construktor des Verwaltungsblocks 78 |* Ersterstellung TH 17.09.91 79 |* Letzte Aenderung TH 17.09.91 80 |* 81 *************************************************************************/ 82 83 CBlock::CBlock( sal_uInt16 nInitSize, CBlock* _pPrev, CBlock* _pNext ) 84 { 85 DBG_CTOR( CBlock, DbgCheckCBlock ); 86 87 pPrev = _pPrev; 88 pNext = _pNext; 89 nSize = nInitSize; 90 nCount = 0; 91 92 // Datenpuffer anlegen 93 pNodes = new PVOID[nSize]; 94 } 95 96 /************************************************************************* 97 |* 98 |* CBlock::CBlock() 99 |* 100 |* Beschreibung Construktor des Verwaltungsblocks 101 |* Ersterstellung TH 17.09.91 102 |* Letzte Aenderung TH 17.09.91 103 |* 104 *************************************************************************/ 105 106 CBlock::CBlock( sal_uInt16 _nSize, CBlock* _pPrev ) 107 { 108 DBG_CTOR( CBlock, DbgCheckCBlock ); 109 DBG_ASSERT( _nSize, "CBlock::CBlock(): nSize == 0" ); 110 111 pPrev = _pPrev; 112 pNext = NULL; 113 nSize = _nSize; 114 nCount = _nSize; 115 116 // Datenpuffer anlegen und initialisieren 117 pNodes = new PVOID[nSize]; 118 memset( pNodes, 0, nSize*sizeof(PVOID) ); 119 } 120 121 /************************************************************************* 122 |* 123 |* CBlock::CBlock() 124 |* 125 |* Beschreibung Copy-Construktor des Verwaltungsblocks 126 |* Ersterstellung TH 17.09.91 127 |* Letzte Aenderung TH 17.09.91 128 |* 129 *************************************************************************/ 130 131 CBlock::CBlock( const CBlock& r, CBlock* _pPrev ) 132 { 133 DBG_CTOR( CBlock, DbgCheckCBlock ); 134 DBG_CHKOBJ( &r, CBlock, DbgCheckCBlock ); 135 136 pPrev = _pPrev; 137 pNext = NULL; 138 nSize = r.nSize; 139 nCount = r.nCount; 140 141 // Datenpuffer anlegen und Daten kopieren 142 pNodes = new PVOID[nSize]; 143 memcpy( pNodes, r.pNodes, nCount*sizeof(PVOID) ); 144 } 145 146 /************************************************************************* 147 |* 148 |* CBlock::~CBlock() 149 |* 150 |* Beschreibung Destruktor des Verwaltungsblocks 151 |* Ersterstellung TH 17.09.91 152 |* Letzte Aenderung TH 17.09.91 153 |* 154 *************************************************************************/ 155 156 inline CBlock::~CBlock() 157 { 158 DBG_DTOR( CBlock, DbgCheckCBlock ); 159 160 // Daten loeschen 161 delete[] pNodes; 162 } 163 164 /************************************************************************* 165 |* 166 |* CBlock::Insert() 167 |* 168 |* Beschreibung Fuegt einen Pointer ein 169 |* Ersterstellung TH 17.09.91 170 |* Letzte Aenderung TH 17.09.91 171 |* 172 *************************************************************************/ 173 174 void CBlock::Insert( void* p, sal_uInt16 nIndex, sal_uInt16 nReSize ) 175 { 176 DBG_CHKTHIS( CBlock, DbgCheckCBlock ); 177 DBG_ASSERT( nIndex <= nCount, "CBlock::Insert(): Index > nCount" ); 178 179 // Muss Block realokiert werden 180 if ( nCount == nSize ) 181 { 182 // Neue Daten anlegen 183 nSize = nSize + nReSize; // MSVC warns here if += is used 184 void** pNewNodes = new PVOID[nSize]; 185 186 // Wird angehaengt 187 if ( nCount == nIndex ) 188 { 189 // Daten kopieren 190 memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) ); 191 } 192 else 193 { 194 // Daten kopieren 195 memcpy( pNewNodes, pNodes, nIndex*sizeof(PVOID) ); 196 memcpy( pNewNodes + nIndex + 1, 197 pNodes + nIndex, 198 (nCount-nIndex)*sizeof(PVOID) ); 199 } 200 201 // Alte Daten loeschen und neue setzen 202 delete[] pNodes; 203 pNodes = pNewNodes; 204 } 205 else 206 { 207 if ( nIndex < nCount ) 208 { 209 memmove( pNodes + nIndex + 1, 210 pNodes + nIndex, 211 (nCount-nIndex)*sizeof(PVOID) ); 212 } 213 } 214 215 // Neuen Pointer setzen und Elementgroesse erhoehen 216 pNodes[nIndex] = p; 217 nCount++; 218 } 219 220 /************************************************************************* 221 |* 222 |* CBlock::Split() 223 |* 224 |* Beschreibung Fuegt einen Pointer ein und splittet den Block 225 |* Ersterstellung TH 17.09.91 226 |* Letzte Aenderung TH 17.09.91 227 |* 228 *************************************************************************/ 229 230 CBlock* CBlock::Split( void* p, sal_uInt16 nIndex, sal_uInt16 nReSize ) 231 { 232 DBG_CHKTHIS( CBlock, DbgCheckCBlock ); 233 234 sal_uInt16 nNewSize; 235 sal_uInt16 nMiddle; 236 CBlock* pNewBlock; 237 238 nMiddle = nCount/2; 239 240 if ( ( nIndex == nCount ) || ( nIndex == 0 ) ) 241 nNewSize = nReSize; 242 else 243 { 244 // Der aktuelle Block wird in der Mitte geteilt 245 nNewSize = (nCount+1) / 2; 246 247 if ( nNewSize < nReSize ) 248 nNewSize = nReSize; 249 else 250 { 251 // Neue Groesse muss ein vielfaches von Resize sein 252 if ( nNewSize % nReSize ) 253 nNewSize += nReSize - (nNewSize % nReSize); 254 else 255 nNewSize = nNewSize + nReSize; // MSVC warns here if += is used 256 } 257 } 258 259 // Vor oder hinter dem aktuellem Block einfuegen? 260 if ( nIndex > nMiddle ) 261 { 262 // Neuen Split-Block anlegen und hinter dem aktuellem Block einfuegen 263 pNewBlock = new CBlock( nNewSize, this, pNext ); 264 265 if ( pNext ) 266 pNext->pPrev = pNewBlock; 267 pNext = pNewBlock; 268 269 if ( nIndex == nCount ) 270 { 271 // Neuen Pointer einfuegen 272 pNewBlock->pNodes[0] = p; 273 pNewBlock->nCount = 1; 274 } 275 else 276 { 277 nIndex = nIndex - nMiddle; // MSVC warns here if += is used 278 // Alles von Mitte bis Index kopieren 279 if ( nIndex ) 280 memcpy( pNewBlock->pNodes, pNodes+nMiddle, nIndex*sizeof(PVOID) ); 281 282 // Neuen Pointer einfuegen 283 pNewBlock->pNodes[nIndex] = p; 284 285 // Alles von Mitte bis Ende hinter Index kopieren 286 memcpy( pNewBlock->pNodes+nIndex+1, 287 pNodes+nMiddle+nIndex, 288 (nCount-nMiddle-nIndex) * sizeof(PVOID) ); 289 290 pNewBlock->nCount = (nCount-nMiddle+1); 291 nCount = nMiddle; 292 293 // Den aktuellen Datenbereich auch halbieren 294 if ( nSize != nNewSize ) 295 { 296 void** pNewNodes = new PVOID[nNewSize]; 297 memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) ); 298 delete[] pNodes; 299 pNodes = pNewNodes; 300 nSize = nNewSize; 301 } 302 } 303 } 304 else 305 { 306 // Neuen Split-Block anlegen und vor dem aktuellem Block einfuegen 307 pNewBlock = new CBlock( nNewSize, pPrev, this ); 308 309 if ( pPrev ) 310 pPrev->pNext = pNewBlock; 311 pPrev = pNewBlock; 312 313 if ( nIndex == 0 ) 314 { 315 // Neuen Pointer einfuegen 316 pNewBlock->pNodes[0] = p; 317 pNewBlock->nCount = 1; 318 } 319 else 320 { 321 // Alles von Anfang bis Index kopieren 322 memcpy( pNewBlock->pNodes, pNodes, nIndex*sizeof(PVOID) ); 323 324 // Neuen Pointer einfuegen 325 pNewBlock->pNodes[nIndex] = p; 326 327 // Alles von Index bis Mitte hinter Index kopieren 328 if ( nIndex != nMiddle ) 329 { 330 memcpy( pNewBlock->pNodes+nIndex+1, 331 pNodes+nIndex, 332 (nMiddle-nIndex) * sizeof(PVOID) ); 333 } 334 335 pNewBlock->nCount = nMiddle+1; 336 nCount = nCount - nMiddle; // MSVC warns here if += is used 337 338 // Die zweite Haelfte in einen neuen Block kopieren 339 if ( nSize != nNewSize ) 340 { 341 void** pNewNodes = new PVOID[nNewSize]; 342 memcpy( pNewNodes, pNodes+nMiddle, nCount*sizeof(PVOID) ); 343 delete[] pNodes; 344 pNodes = pNewNodes; 345 nSize = nNewSize; 346 } 347 else 348 memmove( pNodes, pNodes+nMiddle, nCount*sizeof(PVOID) ); 349 } 350 } 351 352 // Neu angelegten Block zurueckgeben, da gegebenfalls die Blockpointer 353 // im Container angepast werden koennen 354 return pNewBlock; 355 } 356 357 /************************************************************************* 358 |* 359 |* CBlock::Remove() 360 |* 361 |* Beschreibung Entfernt einen Pointer 362 |* Ersterstellung TH 17.09.91 363 |* Letzte Aenderung TH 17.09.91 364 |* 365 *************************************************************************/ 366 367 void* CBlock::Remove( sal_uInt16 nIndex, sal_uInt16 nReSize ) 368 { 369 DBG_CHKTHIS( CBlock, DbgCheckCBlock ); 370 371 // Alten Pointer sichern 372 void* pOld = pNodes[nIndex]; 373 374 // 1 Element weniger 375 nCount--; 376 377 // Block verkleinern (wenn Reallokationsgroesse um 4 unterschritten wird) 378 if ( nCount == (nSize-nReSize-4) ) 379 { 380 // Neue Daten anlegen 381 nSize = nSize - nReSize; // MSVC warns here if += is used 382 void** pNewNodes = new PVOID[nSize]; 383 384 // Wird letzter Eintrag geloescht 385 if ( nIndex == nCount ) 386 { 387 // Daten kopieren 388 memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) ); 389 } 390 else 391 { 392 // Daten kopieren 393 memcpy( pNewNodes, pNodes, nIndex*sizeof(PVOID) ); 394 memcpy( pNewNodes + nIndex, pNodes + nIndex+1, 395 (nCount-nIndex)*sizeof(PVOID) ); 396 } 397 398 // Alte Daten loeschen und neue setzen 399 delete[] pNodes; 400 pNodes = pNewNodes; 401 } 402 else 403 { 404 // Wenn nicht das letzte Element, dann zusammenschieben 405 if ( nIndex < nCount ) 406 { 407 memmove( pNodes + nIndex, pNodes + nIndex + 1, 408 (nCount-nIndex)*sizeof(PVOID) ); 409 } 410 } 411 412 // Alten Pointer zurueckgeben 413 return pOld; 414 } 415 416 /************************************************************************* 417 |* 418 |* CBlock::Replace() 419 |* 420 |* Beschreibung Ersetzt einen Pointer 421 |* Ersterstellung TH 17.09.91 422 |* Letzte Aenderung TH 17.09.91 423 |* 424 *************************************************************************/ 425 426 inline void* CBlock::Replace( void* p, sal_uInt16 nIndex ) 427 { 428 DBG_CHKTHIS( CBlock, DbgCheckCBlock ); 429 430 // Alten Pointer sichern, neuen setzen und alten zurueckgeben 431 void* pOld = pNodes[nIndex]; 432 pNodes[nIndex] = p; 433 return pOld; 434 } 435 436 /************************************************************************* 437 |* 438 |* CBlock::GetObjectPtr() 439 |* 440 |* Beschreibung Gibt einen Pointer auf den Pointer aus dem Block 441 |* zurueck 442 |* Ersterstellung TH 26.01.93 443 |* Letzte Aenderung TH 26.01.93 444 |* 445 *************************************************************************/ 446 447 inline void** CBlock::GetObjectPtr( sal_uInt16 nIndex ) 448 { 449 DBG_CHKTHIS( CBlock, DbgCheckCBlock ); 450 451 return &(pNodes[nIndex]); 452 } 453 454 /************************************************************************* 455 |* 456 |* CBlock::SetSize() 457 |* 458 |* Beschreibung Aendert die Groesse des Blocks 459 |* Ersterstellung TH 17.09.91 460 |* Letzte Aenderung TH 17.09.91 461 |* 462 *************************************************************************/ 463 464 void CBlock::SetSize( sal_uInt16 nNewSize ) 465 { 466 DBG_CHKTHIS( CBlock, DbgCheckCBlock ); 467 DBG_ASSERT( nNewSize, "CBlock::SetSize(): nNewSize == 0" ); 468 469 // Unterscheidet sich die Groesse 470 if ( nNewSize != nCount ) 471 { 472 // Array erweitern 473 void** pNewNodes = new PVOID[nNewSize]; 474 475 // Alte Tabelle in die Neue kopieren 476 if ( nNewSize < nCount ) 477 memcpy( pNewNodes, pNodes, nNewSize*sizeof(PVOID) ); 478 else 479 { 480 memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) ); 481 482 // Array mit 0 initialisieren 483 memset( pNewNodes+nCount, 0, (nNewSize-nCount)*sizeof(PVOID) ); 484 } 485 486 // Altes Array loeschen und neue Werte setzen 487 nSize = nNewSize; 488 nCount = nSize; 489 delete[] pNodes; 490 pNodes = pNewNodes; 491 } 492 } 493 494 //------------------------------------------------------------------------ 495 496 /************************************************************************* 497 |* 498 |* DbgCheckContainer() 499 |* 500 |* Beschreibung Pruefung eines Container fuer Debug-Utilities 501 |* Ersterstellung MI 30.01.92 502 |* Letzte Aenderung TH 24.01.96 503 |* 504 *************************************************************************/ 505 506 #ifdef DBG_UTIL 507 const char* Container::DbgCheckContainer( const void* pCont ) 508 { 509 Container* p = (Container*)pCont; 510 511 if ( p->nCount && (!p->pFirstBlock || !p->pLastBlock || !p->pCurBlock) ) 512 return "nCount > 0 but no CBlocks"; 513 514 return NULL; 515 } 516 #endif 517 518 /************************************************************************* 519 |* 520 |* ImpCopyContainer() 521 |* 522 |* Beschreibung Kopiert alle Daten des Containers 523 |* Ersterstellung TH 24.01.96 524 |* Letzte Aenderung TH 24.01.96 525 |* 526 *************************************************************************/ 527 528 void Container::ImpCopyContainer( const Container* pCont2 ) 529 { 530 // Werte vom uebergebenen Container uebernehmen 531 nCount = pCont2->nCount; 532 nCurIndex = pCont2->nCurIndex; 533 nInitSize = pCont2->nInitSize; 534 nReSize = pCont2->nReSize; 535 nBlockSize = pCont2->nBlockSize; 536 537 // Alle Bloecke kopieren 538 if ( pCont2->nCount ) 539 { 540 CBlock* pBlock1; 541 CBlock* pBlock2; 542 CBlock* pTempBlock; 543 544 // Erstmal ersten Block kopieren 545 pBlock2 = pCont2->pFirstBlock; 546 pFirstBlock = new CBlock( *pBlock2, NULL ); 547 // Ist erster Block der Current-Block, dann Current-Block setzen 548 if ( pBlock2 == pCont2->pCurBlock ) 549 pCurBlock = pFirstBlock; 550 pBlock1 = pFirstBlock; 551 pBlock2 = pBlock2->GetNextBlock(); 552 while ( pBlock2 ) 553 { 554 // Neuen Block anlegen und aus der uebergebenen Liste kopieren 555 pTempBlock = new CBlock( *pBlock2, pBlock1 ); 556 pBlock1->SetNextBlock( pTempBlock ); 557 pBlock1 = pTempBlock; 558 559 // Current-Block beruecksichtigen 560 if ( pBlock2 == pCont2->pCurBlock ) 561 pCurBlock = pBlock1; 562 563 // Auf naechsten Block weitersetzen 564 pBlock2 = pBlock2->GetNextBlock(); 565 } 566 567 // Letzten Block setzen 568 pLastBlock = pBlock1; 569 } 570 else 571 { 572 pFirstBlock = NULL; 573 pLastBlock = NULL; 574 pCurBlock = NULL; 575 } 576 } 577 578 /************************************************************************* 579 |* 580 |* Container::Container() 581 |* 582 |* Beschreibung CONTNR.SDW 583 |* Ersterstellung TH 17.09.91 584 |* Letzte Aenderung TH 17.09.91 585 |* 586 *************************************************************************/ 587 588 Container::Container( sal_uInt16 _nBlockSize, sal_uInt16 _nInitSize, sal_uInt16 _nReSize ) 589 { 590 DBG_CTOR( Container, DbgCheckContainer ); 591 592 // BlockSize muss mindestens 4 sein und kleiner als 64 KB 593 if ( _nBlockSize < 4 ) 594 nBlockSize = 4; 595 else 596 { 597 if ( _nBlockSize < CONTAINER_MAXBLOCKSIZE ) 598 nBlockSize = _nBlockSize; 599 else 600 nBlockSize = CONTAINER_MAXBLOCKSIZE; 601 } 602 603 // ReSize muss mindestens 2 sein und kleiner als BlockSize 604 if ( _nReSize >= nBlockSize ) 605 nReSize = nBlockSize; 606 else 607 { 608 if ( _nReSize < 2 ) 609 nReSize = 2; 610 else 611 nReSize = _nReSize; 612 613 // BlockSize muss ein vielfaches der Resizegroesse sein 614 if ( nBlockSize % nReSize ) 615 nBlockSize -= nReSize - (nBlockSize % nReSize); 616 } 617 618 // InitSize muss groesser gleich ReSize sein und kleiner als BlockSize 619 if ( _nInitSize <= nReSize ) 620 nInitSize = nReSize; 621 else 622 { 623 if ( _nInitSize >= nBlockSize ) 624 nInitSize = nBlockSize; 625 else 626 { 627 nInitSize = _nInitSize; 628 629 // InitSize muss ein vielfaches der Resizegroesse sein 630 if ( nInitSize % nReSize ) 631 nInitSize -= nReSize - (nInitSize % nReSize); 632 } 633 } 634 635 // Werte initialisieren 636 pFirstBlock = NULL; 637 pLastBlock = NULL; 638 pCurBlock = NULL; 639 nCount = 0; 640 nCurIndex = 0; 641 } 642 643 /************************************************************************* 644 |* 645 |* Container::Container() 646 |* 647 |* Beschreibung CONTNR.SDW 648 |* Ersterstellung TH 17.09.91 649 |* Letzte Aenderung TH 17.09.91 650 |* 651 *************************************************************************/ 652 653 Container::Container( sal_uIntPtr nSize ) 654 { 655 DBG_CTOR( Container, DbgCheckContainer ); 656 657 nCount = nSize; 658 nCurIndex = 0; 659 nBlockSize = CONTAINER_MAXBLOCKSIZE; 660 nInitSize = 1; 661 nReSize = 1; 662 663 if ( !nSize ) 664 { 665 pFirstBlock = NULL; 666 pLastBlock = NULL; 667 pCurBlock = NULL; 668 } 669 else 670 { 671 // Muss mehr als ein Block angelegt werden 672 if ( nSize <= nBlockSize ) 673 { 674 pFirstBlock = new CBlock( (sal_uInt16)nSize, NULL ); 675 pLastBlock = pFirstBlock; 676 } 677 else 678 { 679 CBlock* pBlock1; 680 CBlock* pBlock2; 681 682 pFirstBlock = new CBlock( nBlockSize, NULL ); 683 pBlock1 = pFirstBlock; 684 nSize -= nBlockSize; 685 686 // Solange die Blockgroesse ueberschritten wird, neue Bloecke anlegen 687 while ( nSize > nBlockSize ) 688 { 689 pBlock2 = new CBlock( nBlockSize, pBlock1 ); 690 pBlock1->SetNextBlock( pBlock2 ); 691 pBlock1 = pBlock2; 692 nSize -= nBlockSize; 693 } 694 695 pLastBlock = new CBlock( (sal_uInt16)nSize, pBlock1 ); 696 pBlock1->SetNextBlock( pLastBlock ); 697 } 698 699 pCurBlock = pFirstBlock; 700 } 701 } 702 703 /************************************************************************* 704 |* 705 |* Container::Container() 706 |* 707 |* Beschreibung CONTNR.SDW 708 |* Ersterstellung TH 17.09.91 709 |* Letzte Aenderung TH 17.09.91 710 |* 711 *************************************************************************/ 712 713 Container::Container( const Container& r ) 714 { 715 DBG_CTOR( Container, DbgCheckContainer ); 716 717 // Daten kopieren 718 ImpCopyContainer( &r ); 719 } 720 721 /************************************************************************* 722 |* 723 |* Container::~Container() 724 |* 725 |* Beschreibung CONTNR.SDW 726 |* Ersterstellung TH 17.09.91 727 |* Letzte Aenderung TH 17.09.91 728 |* 729 *************************************************************************/ 730 731 Container::~Container() 732 { 733 DBG_DTOR( Container, DbgCheckContainer ); 734 735 // Alle Bloecke loeschen 736 CBlock* pBlock = pFirstBlock; 737 while ( pBlock ) 738 { 739 CBlock* pTemp = pBlock->GetNextBlock(); 740 delete pBlock; 741 pBlock = pTemp; 742 } 743 } 744 745 /************************************************************************* 746 |* 747 |* Container::ImpInsert() 748 |* 749 |* Beschreibung Interne Methode zum Einfuegen eines Pointers 750 |* Ersterstellung TH 17.09.91 751 |* Letzte Aenderung DV 01.07.97 752 |* 753 *************************************************************************/ 754 755 void Container::ImpInsert( void* p, CBlock* pBlock, sal_uInt16 nIndex ) 756 { 757 DBG_CHKTHIS( Container, DbgCheckContainer ); 758 759 if ( !nCount ) 760 { 761 if ( !pBlock ) 762 { 763 pFirstBlock = new CBlock( nInitSize, NULL, NULL ); 764 pLastBlock = pFirstBlock; 765 pCurBlock = pFirstBlock; 766 } 767 pFirstBlock->Insert( p, nIndex, nReSize ); 768 } 769 else 770 { 771 // Ist im Block die maximale Blockgroesse erreicht, 772 // dann neuen Block anlegen 773 if ( pBlock->Count() == nBlockSize ) 774 { 775 // Block auftrennen 776 CBlock* pNewBlock = pBlock->Split( p, nIndex, nReSize ); 777 778 // Wurde Block dahinter angehaegnt 779 if ( pBlock->pNext == pNewBlock ) 780 { 781 // Gegebenenfalls LastBlock anpassen 782 if ( pBlock == pLastBlock ) 783 pLastBlock = pNewBlock; 784 785 // Current-Position nachfuehren 786 if ( pBlock == pCurBlock ) 787 { 788 if ( pBlock->nCount <= nCurIndex ) 789 { 790 if ( nIndex <= nCurIndex ) 791 nCurIndex++; 792 pCurBlock = pNewBlock; 793 nCurIndex = nCurIndex - pBlock->nCount; // MSVC warns here if += is used 794 } 795 } 796 } 797 else 798 { 799 // Gegebenenfalls FirstBlock anpassen 800 if ( pBlock == pFirstBlock ) 801 pFirstBlock = pNewBlock; 802 803 // Current-Position nachfuehren 804 if ( pBlock == pCurBlock ) 805 { 806 if ( nIndex <= nCurIndex ) 807 nCurIndex++; 808 if ( pNewBlock->nCount <= nCurIndex ) 809 nCurIndex = nCurIndex - pNewBlock->nCount; // MSVC warns here if += is used 810 else 811 pCurBlock = pNewBlock; 812 } 813 } 814 } 815 else 816 { 817 // Sonst reicht normales einfuegen in den Block 818 pBlock->Insert( p, nIndex, nReSize ); 819 820 // Current-Position nachfuehren 821 if ( (pBlock == pCurBlock) && (nIndex <= nCurIndex) ) 822 nCurIndex++; 823 } 824 } 825 826 // Ein neues Item im Container 827 nCount++; 828 } 829 830 /************************************************************************* 831 |* 832 |* Container::Insert() 833 |* 834 |* Beschreibung CONTNR.SDW 835 |* Ersterstellung TH 17.09.91 836 |* Letzte Aenderung TH 17.09.91 837 |* 838 *************************************************************************/ 839 840 void Container::Insert( void* p ) 841 { 842 ImpInsert( p, pCurBlock, nCurIndex ); 843 } 844 845 /************************************************************************* 846 |* 847 |* Container::Insert() 848 |* 849 |* Beschreibung CONTNR.SDW 850 |* Ersterstellung TH 17.09.91 851 |* Letzte Aenderung TH 17.09.91 852 |* 853 *************************************************************************/ 854 855 void Container::Insert( void* p, sal_uIntPtr nIndex ) 856 { 857 if ( nCount <= nIndex ) 858 { 859 if ( pLastBlock ) 860 ImpInsert( p, pLastBlock, pLastBlock->Count() ); 861 else 862 ImpInsert( p, NULL, 0 ); 863 } 864 else 865 { 866 // Block suchen 867 CBlock* pTemp = pFirstBlock; 868 while ( pTemp->Count() < nIndex ) 869 { 870 nIndex -= pTemp->Count(); 871 pTemp = pTemp->GetNextBlock(); 872 } 873 874 ImpInsert( p, pTemp, (sal_uInt16)nIndex ); 875 } 876 } 877 878 /************************************************************************* 879 |* 880 |* Container::Insert() 881 |* 882 |* Beschreibung CONTNR.SDW 883 |* Ersterstellung TH 17.09.91 884 |* Letzte Aenderung TH 17.09.91 885 |* 886 *************************************************************************/ 887 888 void Container::Insert( void* pNew, void* pOld ) 889 { 890 sal_uIntPtr nIndex = GetPos( pOld ); 891 if ( nIndex != CONTAINER_ENTRY_NOTFOUND ) 892 Insert( pNew, nIndex ); 893 } 894 895 /************************************************************************* 896 |* 897 |* Container::ImpRemove() 898 |* 899 |* Beschreibung Interne Methode zum Entfernen eines Pointers 900 |* Ersterstellung TH 17.09.91 901 |* Letzte Aenderung TH 17.09.91 902 |* 903 *************************************************************************/ 904 905 void* Container::ImpRemove( CBlock* pBlock, sal_uInt16 nIndex ) 906 { 907 DBG_CHKTHIS( Container, DbgCheckContainer ); 908 909 void* pOld; 910 911 // Ist Liste danach leer 912 if ( nCount == 1 ) 913 { 914 // Block und CurIndex zuruecksetzen 915 pOld = pBlock->GetObject( nIndex ); 916 pBlock->Reset(); 917 nCurIndex = 0; 918 } 919 else 920 { 921 // Ist Block nach Remove leer 922 if ( pBlock->Count() == 1 ) 923 { 924 // dann Block entfernen und Block-Pointer umsetzen 925 if ( pBlock->GetPrevBlock() ) 926 (pBlock->GetPrevBlock())->SetNextBlock( pBlock->GetNextBlock() ); 927 else 928 pFirstBlock = pBlock->GetNextBlock(); 929 930 if ( pBlock->GetNextBlock() ) 931 (pBlock->GetNextBlock())->SetPrevBlock( pBlock->GetPrevBlock() ); 932 else 933 pLastBlock = pBlock->GetPrevBlock(); 934 935 // Current-Position nachfuehren 936 if ( pBlock == pCurBlock ) 937 { 938 if ( pBlock->GetNextBlock() ) 939 { 940 pCurBlock = pBlock->GetNextBlock(); 941 nCurIndex = 0; 942 } 943 else 944 { 945 pCurBlock = pBlock->GetPrevBlock(); 946 nCurIndex = pCurBlock->Count()-1; 947 } 948 } 949 950 pOld = pBlock->GetObject( nIndex ); 951 delete pBlock; 952 } 953 else 954 { 955 // Sonst Item aus dem Block entfernen 956 pOld = pBlock->Remove( nIndex, nReSize ); 957 958 // Current-Position nachfuehren 959 if ( (pBlock == pCurBlock) && 960 ((nIndex < nCurIndex) || ((nCurIndex == pBlock->Count()) && nCurIndex)) ) 961 nCurIndex--; 962 } 963 } 964 965 // Jetzt gibt es ein Item weniger 966 nCount--; 967 968 // Und den Pointer zurueckgeben, der entfernt wurde 969 return pOld; 970 } 971 972 /************************************************************************* 973 |* 974 |* Container::Remove() 975 |* 976 |* Beschreibung CONTNR.SDW 977 |* Ersterstellung TH 17.09.91 978 |* Letzte Aenderung TH 17.09.91 979 |* 980 *************************************************************************/ 981 982 void* Container::Remove() 983 { 984 // Wenn kein Item vorhanden ist, NULL zurueckgeben 985 if ( !nCount ) 986 return NULL; 987 else 988 return ImpRemove( pCurBlock, nCurIndex ); 989 } 990 991 /************************************************************************* 992 |* 993 |* Container::Remove() 994 |* 995 |* Beschreibung CONTNR.SDW 996 |* Ersterstellung TH 17.09.91 997 |* Letzte Aenderung TH 17.09.91 998 |* 999 *************************************************************************/ 1000 1001 void* Container::Remove( sal_uIntPtr nIndex ) 1002 { 1003 // Ist Index nicht innerhalb des Containers, dann NULL zurueckgeben 1004 if ( nCount <= nIndex ) 1005 return NULL; 1006 else 1007 { 1008 // Block suchen 1009 CBlock* pTemp = pFirstBlock; 1010 while ( pTemp->Count() <= nIndex ) 1011 { 1012 nIndex -= pTemp->Count(); 1013 pTemp = pTemp->GetNextBlock(); 1014 } 1015 1016 return ImpRemove( pTemp, (sal_uInt16)nIndex ); 1017 } 1018 } 1019 1020 /************************************************************************* 1021 |* 1022 |* Container::Replace() 1023 |* 1024 |* Beschreibung CONTNR.SDW 1025 |* Ersterstellung TH 17.09.91 1026 |* Letzte Aenderung TH 17.09.91 1027 |* 1028 *************************************************************************/ 1029 1030 void* Container::Replace( void* p ) 1031 { 1032 DBG_CHKTHIS( Container, DbgCheckContainer ); 1033 1034 if ( !nCount ) 1035 return NULL; 1036 else 1037 return pCurBlock->Replace( p, nCurIndex ); 1038 } 1039 1040 /************************************************************************* 1041 |* 1042 |* Container::Replace() 1043 |* 1044 |* Beschreibung CONTNR.SDW 1045 |* Ersterstellung TH 17.09.91 1046 |* Letzte Aenderung TH 17.09.91 1047 |* 1048 *************************************************************************/ 1049 1050 void* Container::Replace( void* p, sal_uIntPtr nIndex ) 1051 { 1052 DBG_CHKTHIS( Container, DbgCheckContainer ); 1053 1054 // Ist Index nicht innerhalb des Containers, dann NULL zurueckgeben 1055 if ( nCount <= nIndex ) 1056 return NULL; 1057 else 1058 { 1059 // Block suchen 1060 CBlock* pTemp = pFirstBlock; 1061 while ( pTemp->Count() <= nIndex ) 1062 { 1063 nIndex -= pTemp->Count(); 1064 pTemp = pTemp->GetNextBlock(); 1065 } 1066 1067 return pTemp->Replace( p, (sal_uInt16)nIndex ); 1068 } 1069 } 1070 1071 /************************************************************************* 1072 |* 1073 |* Container::SetSize() 1074 |* 1075 |* Beschreibung CONTNR.SDW 1076 |* Ersterstellung TH 17.09.91 1077 |* Letzte Aenderung TH 17.09.91 1078 |* 1079 *************************************************************************/ 1080 1081 void Container::SetSize( sal_uIntPtr nNewSize ) 1082 { 1083 DBG_CHKTHIS( Container, DbgCheckContainer ); 1084 1085 if ( nNewSize ) 1086 { 1087 // Unterscheiden sich die Groessen 1088 if ( nNewSize != nCount ) 1089 { 1090 CBlock* pTemp; 1091 sal_uIntPtr nTemp; 1092 1093 // Wird verkleinert 1094 if ( nNewSize < nCount ) 1095 { 1096 pTemp = pFirstBlock; 1097 nTemp = 0; 1098 while ( (nTemp+pTemp->Count()) < nNewSize ) 1099 { 1100 nTemp += pTemp->Count(); 1101 pTemp = pTemp->GetNextBlock(); 1102 } 1103 1104 // Alle folgenden Bloecke loeschen 1105 sal_Bool bLast = sal_False; 1106 CBlock* pDelNext; 1107 CBlock* pDelBlock = pTemp->GetNextBlock(); 1108 while ( pDelBlock ) 1109 { 1110 // Muss CurrentBlock umgesetzt werden 1111 if ( pDelBlock == pCurBlock ) 1112 bLast = sal_True; 1113 pDelNext = pDelBlock->GetNextBlock(); 1114 delete pDelBlock; 1115 pDelBlock = pDelNext; 1116 } 1117 1118 // Block in der Groesse anpassen, oder bei Groesse 0 loeschen 1119 if ( nNewSize > nTemp ) 1120 { 1121 pLastBlock = pTemp; 1122 pTemp->SetNextBlock( NULL ); 1123 pTemp->SetSize( (sal_uInt16)(nNewSize-nTemp) ); 1124 } 1125 else 1126 { 1127 pLastBlock = pTemp->GetPrevBlock(); 1128 pLastBlock->SetNextBlock( NULL ); 1129 delete pTemp; 1130 } 1131 1132 nCount = nNewSize; 1133 if ( bLast ) 1134 { 1135 pCurBlock = pLastBlock; 1136 nCurIndex = pCurBlock->Count()-1; 1137 } 1138 } 1139 else 1140 { 1141 // Auf den letzen Puffer setzen 1142 pTemp = pLastBlock; 1143 nTemp = nNewSize - nCount; 1144 1145 if ( !pTemp ) 1146 { 1147 // Muss mehr als ein Block angelegt werden 1148 if ( nNewSize <= nBlockSize ) 1149 { 1150 pFirstBlock = new CBlock( (sal_uInt16)nNewSize, NULL ); 1151 pLastBlock = pFirstBlock; 1152 } 1153 else 1154 { 1155 CBlock* pBlock1; 1156 CBlock* pBlock2; 1157 1158 pFirstBlock = new CBlock( nBlockSize, NULL ); 1159 pBlock1 = pFirstBlock; 1160 nNewSize -= nBlockSize; 1161 1162 // Solange die Blockgroesse ueberschritten wird, neue Bloecke anlegen 1163 while ( nNewSize > nBlockSize ) 1164 { 1165 pBlock2 = new CBlock( nBlockSize, pBlock1 ); 1166 pBlock1->SetNextBlock( pBlock2 ); 1167 pBlock1 = pBlock2; 1168 nNewSize -= nBlockSize; 1169 } 1170 1171 pLastBlock = new CBlock( (sal_uInt16)nNewSize, pBlock1 ); 1172 pBlock1->SetNextBlock( pLastBlock ); 1173 } 1174 1175 pCurBlock = pFirstBlock; 1176 } 1177 // Reicht es, den letzen Puffer in der Groesse anzupassen 1178 else if ( (nTemp+pTemp->Count()) <= nBlockSize ) 1179 pTemp->SetSize( (sal_uInt16)(nTemp+pTemp->Count()) ); 1180 else 1181 { 1182 // Puffer auf max. Blockgroesse setzen 1183 nTemp -= nBlockSize - pTemp->GetSize(); 1184 pTemp->SetSize( nBlockSize ); 1185 1186 CBlock* pTemp2; 1187 // Solange die Blockgroesse ueberschritten wird, 1188 // neue Bloecke anlegen 1189 while ( nTemp > nBlockSize ) 1190 { 1191 pTemp2 = new CBlock( nBlockSize, pTemp ); 1192 pTemp->SetNextBlock( pTemp2 ); 1193 pTemp = pTemp2; 1194 nTemp -= nBlockSize; 1195 } 1196 1197 // Den letzten Block anlegen 1198 if ( nTemp ) 1199 { 1200 pLastBlock = new CBlock( (sal_uInt16)nTemp, pTemp ); 1201 pTemp->SetNextBlock( pLastBlock ); 1202 } 1203 else 1204 pLastBlock = pTemp; 1205 } 1206 1207 nCount = nNewSize; 1208 } 1209 } 1210 } 1211 else 1212 Clear(); 1213 } 1214 1215 /************************************************************************* 1216 |* 1217 |* Container::Clear() 1218 |* 1219 |* Beschreibung CONTNR.SDW 1220 |* Ersterstellung TH 17.09.91 1221 |* Letzte Aenderung TH 17.09.91 1222 |* 1223 *************************************************************************/ 1224 1225 void Container::Clear() 1226 { 1227 DBG_CHKTHIS( Container, DbgCheckContainer ); 1228 1229 // Erst alle Bloecke loeschen 1230 CBlock* pBlock = pFirstBlock; 1231 while ( pBlock ) 1232 { 1233 CBlock* pTemp = pBlock->GetNextBlock(); 1234 delete pBlock; 1235 pBlock = pTemp; 1236 } 1237 1238 // Werte zuruecksetzen 1239 pFirstBlock = NULL; 1240 pLastBlock = NULL; 1241 pCurBlock = NULL; 1242 nCount = 0; 1243 nCurIndex = 0; 1244 } 1245 1246 /************************************************************************* 1247 |* 1248 |* Container::GetCurObject() 1249 |* 1250 |* Beschreibung CONTNR.SDW 1251 |* Ersterstellung TH 17.09.91 1252 |* Letzte Aenderung TH 17.09.91 1253 |* 1254 *************************************************************************/ 1255 1256 void* Container::GetCurObject() const 1257 { 1258 DBG_CHKTHIS( Container, DbgCheckContainer ); 1259 1260 // NULL, wenn Container leer 1261 if ( !nCount ) 1262 return NULL; 1263 else 1264 return pCurBlock->GetObject( nCurIndex ); 1265 } 1266 1267 /************************************************************************* 1268 |* 1269 |* Container::GetCurPos() 1270 |* 1271 |* Beschreibung CONTNR.SDW 1272 |* Ersterstellung TH 17.09.91 1273 |* Letzte Aenderung TH 17.09.91 1274 |* 1275 *************************************************************************/ 1276 1277 sal_uIntPtr Container::GetCurPos() const 1278 { 1279 DBG_CHKTHIS( Container, DbgCheckContainer ); 1280 1281 // CONTAINER_ENTRY_NOTFOUND, wenn Container leer 1282 if ( !nCount ) 1283 return CONTAINER_ENTRY_NOTFOUND; 1284 else 1285 { 1286 // Block suchen 1287 CBlock* pTemp = pFirstBlock; 1288 sal_uIntPtr nTemp = 0; 1289 while ( pTemp != pCurBlock ) 1290 { 1291 nTemp += pTemp->Count(); 1292 pTemp = pTemp->GetNextBlock(); 1293 } 1294 1295 return nTemp+nCurIndex; 1296 } 1297 } 1298 1299 /************************************************************************* 1300 |* 1301 |* Container::GetObjectPtr() 1302 |* 1303 |* Beschreibung Interne Methode fuer Referenz-Container 1304 |* Ersterstellung TH 26.01.93 1305 |* Letzte Aenderung TH 26.01.93 1306 |* 1307 *************************************************************************/ 1308 1309 void** Container::GetObjectPtr( sal_uIntPtr nIndex ) 1310 { 1311 DBG_CHKTHIS( Container, DbgCheckContainer ); 1312 1313 // Ist Index nicht innerhalb des Containers, dann NULL zurueckgeben 1314 if ( nCount <= nIndex ) 1315 return NULL; 1316 else 1317 { 1318 // Block suchen 1319 CBlock* pTemp = pFirstBlock; 1320 while ( pTemp->Count() <= nIndex ) 1321 { 1322 nIndex -= pTemp->Count(); 1323 pTemp = pTemp->GetNextBlock(); 1324 } 1325 1326 // Item innerhalb des gefundenen Blocks zurueckgeben 1327 return pTemp->GetObjectPtr( (sal_uInt16)nIndex ); 1328 } 1329 } 1330 1331 /************************************************************************* 1332 |* 1333 |* Container::GetObject() 1334 |* 1335 |* Beschreibung CONTNR.SDW 1336 |* Ersterstellung TH 17.09.91 1337 |* Letzte Aenderung TH 17.09.91 1338 |* 1339 *************************************************************************/ 1340 1341 void* Container::GetObject( sal_uIntPtr nIndex ) const 1342 { 1343 DBG_CHKTHIS( Container, DbgCheckContainer ); 1344 1345 // Ist Index nicht innerhalb des Containers, dann NULL zurueckgeben 1346 if ( nCount <= nIndex ) 1347 return NULL; 1348 else 1349 { 1350 // Block suchen 1351 CBlock* pTemp = pFirstBlock; 1352 while ( pTemp->Count() <= nIndex ) 1353 { 1354 nIndex -= pTemp->Count(); 1355 pTemp = pTemp->GetNextBlock(); 1356 } 1357 1358 // Item innerhalb des gefundenen Blocks zurueckgeben 1359 return pTemp->GetObject( (sal_uInt16)nIndex ); 1360 } 1361 } 1362 1363 /************************************************************************* 1364 |* 1365 |* Container::GetPos() 1366 |* 1367 |* Beschreibung CONTNR.SDW 1368 |* Ersterstellung TH 17.09.91 1369 |* Letzte Aenderung TH 17.09.91 1370 |* 1371 *************************************************************************/ 1372 1373 sal_uIntPtr Container::GetPos( const void* p ) const 1374 { 1375 DBG_CHKTHIS( Container, DbgCheckContainer ); 1376 1377 void** pNodes; 1378 CBlock* pTemp; 1379 sal_uIntPtr nTemp; 1380 sal_uInt16 nBlockCount; 1381 sal_uInt16 i; 1382 1383 // Block suchen 1384 pTemp = pFirstBlock; 1385 nTemp = 0; 1386 while ( pTemp ) 1387 { 1388 pNodes = pTemp->GetNodes(); 1389 i = 0; 1390 nBlockCount = pTemp->Count(); 1391 while ( i < nBlockCount ) 1392 { 1393 if ( p == *pNodes ) 1394 return nTemp+i; 1395 pNodes++; 1396 i++; 1397 } 1398 nTemp += nBlockCount; 1399 pTemp = pTemp->GetNextBlock(); 1400 } 1401 1402 return CONTAINER_ENTRY_NOTFOUND; 1403 } 1404 1405 /************************************************************************* 1406 |* 1407 |* Container::GetPos() 1408 |* 1409 |* Beschreibung CONTNR.SDW 1410 |* Ersterstellung TH 14.09.94 1411 |* Letzte Aenderung TH 14.09.94 1412 |* 1413 *************************************************************************/ 1414 1415 sal_uIntPtr Container::GetPos( const void* p, sal_uIntPtr nStartIndex, 1416 sal_Bool bForward ) const 1417 { 1418 DBG_CHKTHIS( Container, DbgCheckContainer ); 1419 1420 // Ist Index nicht innerhalb des Containers, dann NOTFOUND zurueckgeben 1421 if ( nCount <= nStartIndex ) 1422 return CONTAINER_ENTRY_NOTFOUND; 1423 else 1424 { 1425 void** pNodes; 1426 sal_uInt16 nBlockCount; 1427 sal_uInt16 i; 1428 1429 // Block suchen 1430 CBlock* pTemp = pFirstBlock; 1431 sal_uIntPtr nTemp = 0; 1432 while ( nTemp+pTemp->Count() <= nStartIndex ) 1433 { 1434 nTemp += pTemp->Count(); 1435 pTemp = pTemp->GetNextBlock(); 1436 } 1437 1438 // Jetzt den Pointer suchen 1439 if ( bForward ) 1440 { 1441 // Alle Bloecke durchrsuchen 1442 i = (sal_uInt16)(nStartIndex - nTemp); 1443 pNodes = pTemp->GetObjectPtr( i ); 1444 do 1445 { 1446 nBlockCount = pTemp->Count(); 1447 while ( i < nBlockCount ) 1448 { 1449 if ( p == *pNodes ) 1450 return nTemp+i; 1451 pNodes++; 1452 i++; 1453 } 1454 nTemp += nBlockCount; 1455 pTemp = pTemp->GetNextBlock(); 1456 if ( pTemp ) 1457 { 1458 i = 0; 1459 pNodes = pTemp->GetNodes(); 1460 } 1461 else 1462 break; 1463 } 1464 while ( sal_True ); 1465 } 1466 else 1467 { 1468 // Alle Bloecke durchrsuchen 1469 i = (sal_uInt16)(nStartIndex-nTemp)+1; 1470 pNodes = pTemp->GetObjectPtr( i-1 ); 1471 do 1472 { 1473 do 1474 { 1475 if ( p == *pNodes ) 1476 return nTemp+i-1; 1477 pNodes--; 1478 i--; 1479 } 1480 while ( i ); 1481 nTemp -= pTemp->Count(); 1482 pTemp = pTemp->GetPrevBlock(); 1483 if ( pTemp ) 1484 { 1485 i = pTemp->Count(); 1486 // Leere Bloecke in der Kette darf es nicht geben. Nur 1487 // wenn ein Block existiert, darf dieser leer sein 1488 pNodes = pTemp->GetObjectPtr( i-1 ); 1489 } 1490 else 1491 break; 1492 } 1493 while ( sal_True ); 1494 } 1495 } 1496 1497 return CONTAINER_ENTRY_NOTFOUND; 1498 } 1499 1500 /************************************************************************* 1501 |* 1502 |* Container::Seek() 1503 |* 1504 |* Beschreibung CONTNR.SDW 1505 |* Ersterstellung TH 17.09.91 1506 |* Letzte Aenderung TH 17.09.91 1507 |* 1508 *************************************************************************/ 1509 1510 void* Container::Seek( sal_uIntPtr nIndex ) 1511 { 1512 DBG_CHKTHIS( Container, DbgCheckContainer ); 1513 1514 // Ist der Container leer, dann NULL zurueckgeben 1515 if ( nCount <= nIndex ) 1516 return NULL; 1517 else 1518 { 1519 // Block suchen 1520 CBlock* pTemp = pFirstBlock; 1521 while ( pTemp->Count() <= nIndex ) 1522 { 1523 nIndex -= pTemp->Count(); 1524 pTemp = pTemp->GetNextBlock(); 1525 } 1526 1527 // Item innerhalb des gefundenen Blocks zurueckgeben 1528 pCurBlock = pTemp; 1529 nCurIndex = (sal_uInt16)nIndex; 1530 return pCurBlock->GetObject( nCurIndex ); 1531 } 1532 } 1533 1534 /************************************************************************* 1535 |* 1536 |* Container::First() 1537 |* 1538 |* Beschreibung CONTNR.SDW 1539 |* Ersterstellung TH 17.09.91 1540 |* Letzte Aenderung TH 17.09.91 1541 |* 1542 *************************************************************************/ 1543 1544 void* Container::First() 1545 { 1546 DBG_CHKTHIS( Container, DbgCheckContainer ); 1547 1548 // Ist Container leer, dann NULL zurueckgeben 1549 if ( !nCount ) 1550 return NULL; 1551 else 1552 { 1553 // Block und Index setzen und ersten Pointer zurueckgeben 1554 pCurBlock = pFirstBlock; 1555 nCurIndex = 0; 1556 return pCurBlock->GetObject( nCurIndex ); 1557 } 1558 } 1559 1560 /************************************************************************* 1561 |* 1562 |* Container::Last() 1563 |* 1564 |* Beschreibung CONTNR.SDW 1565 |* Ersterstellung TH 17.09.91 1566 |* Letzte Aenderung TH 17.09.91 1567 |* 1568 *************************************************************************/ 1569 1570 void* Container::Last() 1571 { 1572 DBG_CHKTHIS( Container, DbgCheckContainer ); 1573 1574 // Ist Container leer, dann NULL zurueckgeben 1575 if ( !nCount ) 1576 return NULL; 1577 else 1578 { 1579 // Block und Index setzen und ersten Pointer zurueckgeben 1580 pCurBlock = pLastBlock; 1581 nCurIndex = pCurBlock->Count()-1; 1582 return pCurBlock->GetObject( nCurIndex ); 1583 } 1584 } 1585 1586 /************************************************************************* 1587 |* 1588 |* Container::Next() 1589 |* 1590 |* Beschreibung CONTNR.SDW 1591 |* Ersterstellung TH 17.09.91 1592 |* Letzte Aenderung TH 17.09.91 1593 |* 1594 *************************************************************************/ 1595 1596 void* Container::Next() 1597 { 1598 DBG_CHKTHIS( Container, DbgCheckContainer ); 1599 1600 // Ist Container leer, dann NULL zurueckgeben, ansonsten preufen ob 1601 // naechste Position noch im aktuellen Block ist. Falls nicht, dann 1602 // einen Block weiterschalten (geht ohne Gefahr, da leere Bloecke 1603 // nicht vorkommen duerfen, es sein denn, es ist der einzige). 1604 if ( !nCount ) 1605 return NULL; 1606 else if ( (nCurIndex+1) < pCurBlock->Count() ) 1607 return pCurBlock->GetObject( ++nCurIndex ); 1608 else if ( pCurBlock->GetNextBlock() ) 1609 { 1610 pCurBlock = pCurBlock->GetNextBlock(); 1611 nCurIndex = 0; 1612 return pCurBlock->GetObject( nCurIndex ); 1613 } 1614 else 1615 return NULL; 1616 } 1617 1618 /************************************************************************* 1619 |* 1620 |* Container::Prev() 1621 |* 1622 |* Beschreibung CONTNR.SDW 1623 |* Ersterstellung TH 17.09.91 1624 |* Letzte Aenderung TH 17.09.91 1625 |* 1626 *************************************************************************/ 1627 1628 void* Container::Prev() 1629 { 1630 DBG_CHKTHIS( Container, DbgCheckContainer ); 1631 1632 // Ist Container leer, dann NULL zurueckgeben, ansonsten preufen ob 1633 // vorherige Position noch im aktuellen Block ist. Falls nicht, dann 1634 // einen Block zurueckschalten (geht ohne Gefahr, da leere Bloecke 1635 // nicht vorkommen duerfen, es sein denn, es ist der einzige). 1636 if ( !nCount ) 1637 return NULL; 1638 else if ( nCurIndex ) 1639 return pCurBlock->GetObject( --nCurIndex ); 1640 else if ( pCurBlock->GetPrevBlock() ) 1641 { 1642 pCurBlock = pCurBlock->GetPrevBlock(); 1643 nCurIndex = pCurBlock->Count() - 1; 1644 return pCurBlock->GetObject( nCurIndex ); 1645 } 1646 else 1647 return NULL; 1648 } 1649 1650 /************************************************************************* 1651 |* 1652 |* Container::operator =() 1653 |* 1654 |* Beschreibung CONTNR.SDW 1655 |* Ersterstellung TH 17.09.91 1656 |* Letzte Aenderung TH 17.09.91 1657 |* 1658 *************************************************************************/ 1659 1660 Container& Container::operator =( const Container& r ) 1661 { 1662 DBG_CHKTHIS( Container, DbgCheckContainer ); 1663 1664 // Erst alle Bloecke loeschen 1665 CBlock* pBlock = pFirstBlock; 1666 while ( pBlock ) 1667 { 1668 CBlock* pTemp = pBlock->GetNextBlock(); 1669 delete pBlock; 1670 pBlock = pTemp; 1671 } 1672 1673 // Daten kopieren 1674 ImpCopyContainer( &r ); 1675 return *this; 1676 } 1677 1678 /************************************************************************* 1679 |* 1680 |* Container::operator ==() 1681 |* 1682 |* Beschreibung CONTNR.SDW 1683 |* Ersterstellung TH 17.09.91 1684 |* Letzte Aenderung TH 17.09.91 1685 |* 1686 *************************************************************************/ 1687 1688 sal_Bool Container::operator ==( const Container& r ) const 1689 { 1690 DBG_CHKTHIS( Container, DbgCheckContainer ); 1691 1692 if ( nCount != r.nCount ) 1693 return sal_False; 1694 1695 sal_uIntPtr i = 0; 1696 while ( i < nCount ) 1697 { 1698 if ( GetObject( i ) != r.GetObject( i ) ) 1699 return sal_False; 1700 i++; 1701 } 1702 1703 return sal_True; 1704 } 1705