1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_tools.hxx" 30 #include <impcont.hxx> 31 #include <tools/unqidx.hxx> 32 #include <tools/unqid.hxx> 33 34 /************************************************************************* 35 |* 36 |* UniqueIndex::UniqueIndex() 37 |* 38 |* Beschreibung UNQIDX.SDW 39 |* Ersterstellung TH 24.09.91 40 |* Letzte Aenderung TH 24.09.91 41 |* 42 *************************************************************************/ 43 44 UniqueIndex::UniqueIndex( sal_uIntPtr _nStartIndex, 45 sal_uIntPtr _nInitSize, sal_uIntPtr _nReSize ) : 46 Container( _nInitSize ) 47 { 48 nReSize = _nReSize; 49 nStartIndex = _nStartIndex; 50 nUniqIndex = 0; 51 nCount = 0; 52 } 53 54 /************************************************************************* 55 |* 56 |* UniqueIndex::UniqueIndex() 57 |* 58 |* Beschreibung UNQIDX.SDW 59 |* Ersterstellung TH 24.09.91 60 |* Letzte Aenderung TH 24.09.91 61 |* 62 *************************************************************************/ 63 64 UniqueIndex::UniqueIndex( const UniqueIndex& rIdx ) : 65 Container( rIdx ) 66 { 67 nReSize = rIdx.nReSize; 68 nStartIndex = rIdx.nStartIndex; 69 nUniqIndex = rIdx.nUniqIndex; 70 nCount = rIdx.nCount; 71 } 72 73 /************************************************************************* 74 |* 75 |* UniqueIndex::Insert() 76 |* 77 |* Beschreibung UNQIDX.SDW 78 |* Ersterstellung TH 24.09.91 79 |* Letzte Aenderung TH 24.09.91 80 |* 81 *************************************************************************/ 82 83 sal_uIntPtr UniqueIndex::Insert( void* p ) 84 { 85 // NULL-Pointer ist nicht erlaubt 86 if ( !p ) 87 return UNIQUEINDEX_ENTRY_NOTFOUND; 88 89 // Ist Array voll, dann expandieren 90 if ( nCount == Container::GetSize() ) 91 SetSize( nCount + nReSize ); 92 93 // Damit UniqIndex nicht ueberlaeuft, wenn Items geloescht wurden 94 nUniqIndex = nUniqIndex % Container::GetSize(); 95 96 // Leeren Eintrag suchen 97 while ( Container::ImpGetObject( nUniqIndex ) != NULL ) 98 nUniqIndex = (nUniqIndex+1) % Container::GetSize(); 99 100 // Object im Array speichern 101 Container::Replace( p, nUniqIndex ); 102 103 // Anzahl der Eintraege erhoehen und Index zurueckgeben 104 nCount++; 105 nUniqIndex++; 106 return ( nUniqIndex + nStartIndex - 1 ); 107 } 108 109 /************************************************************************* 110 |* 111 |* UniqueIndex::Insert() 112 |* 113 |* Beschreibung UNQIDX.SDW 114 |* Ersterstellung MM 21.04.96 115 |* Letzte Aenderung MM 21.04.96 116 |* 117 *************************************************************************/ 118 119 sal_uIntPtr UniqueIndex::Insert( sal_uIntPtr nIndex, void* p ) 120 { 121 // NULL-Pointer ist nicht erlaubt 122 if ( !p ) 123 return UNIQUEINDEX_ENTRY_NOTFOUND; 124 125 sal_uIntPtr nContIndex = nIndex - nStartIndex; 126 // Ist Array voll, dann expandieren 127 if ( nContIndex >= Container::GetSize() ) 128 SetSize( nContIndex + nReSize ); 129 130 // Object im Array speichern 131 Container::Replace( p, nContIndex ); 132 133 // Anzahl der Eintraege erhoehen und Index zurueckgeben 134 nCount++; 135 return nIndex; 136 } 137 138 /************************************************************************* 139 |* 140 |* UniqueIndex::Remove() 141 |* 142 |* Beschreibung UNQIDX.SDW 143 |* Ersterstellung TH 24.09.91 144 |* Letzte Aenderung TH 24.09.91 145 |* 146 *************************************************************************/ 147 148 void* UniqueIndex::Remove( sal_uIntPtr nIndex ) 149 { 150 // Ist Index zulaessig 151 if ( (nIndex >= nStartIndex) && 152 (nIndex < (Container::GetSize()+nStartIndex)) ) 153 { 154 // Index-Eintrag als leeren Eintrag setzen und Anzahl der 155 // gespeicherten Indexe erniedriegen, wenn Eintrag belegt war 156 void* p = Container::Replace( NULL, nIndex-nStartIndex ); 157 if ( p ) 158 nCount--; 159 return p; 160 } 161 else 162 return NULL; 163 } 164 165 /************************************************************************* 166 |* 167 |* UniqueIndex::Replace() 168 |* 169 |* Beschreibung UNQIDX.SDW 170 |* Ersterstellung TH 24.09.91 171 |* Letzte Aenderung TH 24.09.91 172 |* 173 *************************************************************************/ 174 175 void* UniqueIndex::Replace( sal_uIntPtr nIndex, void* p ) 176 { 177 // NULL-Pointer ist nicht erlaubt 178 if ( !p ) 179 return NULL; 180 181 // Ist Index zulaessig 182 if ( IsIndexValid( nIndex ) ) 183 { 184 // Index-Eintrag ersetzen und alten zurueckgeben 185 return Container::Replace( p, nIndex-nStartIndex ); 186 } 187 else 188 return NULL; 189 } 190 191 /************************************************************************* 192 |* 193 |* UniqueIndex::Get() 194 |* 195 |* Beschreibung UNQIDX.SDW 196 |* Ersterstellung TH 24.09.91 197 |* Letzte Aenderung TH 24.09.91 198 |* 199 *************************************************************************/ 200 201 void* UniqueIndex::Get( sal_uIntPtr nIndex ) const 202 { 203 // Ist Index zulaessig 204 if ( (nIndex >= nStartIndex) && 205 (nIndex < (Container::GetSize()+nStartIndex)) ) 206 return Container::ImpGetObject( nIndex-nStartIndex ); 207 else 208 return NULL; 209 } 210 211 /************************************************************************* 212 |* 213 |* UniqueIndex::GetCurIndex() 214 |* 215 |* Beschreibung UNQIDX.SDW 216 |* Ersterstellung TH 24.09.91 217 |* Letzte Aenderung TH 24.09.91 218 |* 219 *************************************************************************/ 220 221 sal_uIntPtr UniqueIndex::GetCurIndex() const 222 { 223 sal_uIntPtr nPos = Container::GetCurPos(); 224 225 // Ist der Current-Index nicht belegt, dann gibt es keinen Current-Index 226 if ( !Container::ImpGetObject( nPos ) ) 227 return UNIQUEINDEX_ENTRY_NOTFOUND; 228 else 229 return nPos+nStartIndex; 230 } 231 232 /************************************************************************* 233 |* 234 |* UniqueIndex::GetIndex() 235 |* 236 |* Beschreibung UNQIDX.SDW 237 |* Ersterstellung TH 24.09.91 238 |* Letzte Aenderung TH 24.09.91 239 |* 240 *************************************************************************/ 241 242 sal_uIntPtr UniqueIndex::GetIndex( const void* p ) const 243 { 244 // Wird ein NULL-Pointer uebergeben, dann wurde Pointer nicht gefunden 245 if ( !p ) 246 return UNIQUEINDEX_ENTRY_NOTFOUND; 247 248 sal_uIntPtr nIndex = Container::GetPos( p ); 249 250 if ( nIndex != CONTAINER_ENTRY_NOTFOUND ) 251 return nIndex+nStartIndex; 252 else 253 return UNIQUEINDEX_ENTRY_NOTFOUND; 254 } 255 256 /************************************************************************* 257 |* 258 |* UniqueIndex::IsIndexValid() 259 |* 260 |* Beschreibung UNQIDX.SDW 261 |* Ersterstellung TH 24.09.91 262 |* Letzte Aenderung TH 24.09.91 263 |* 264 *************************************************************************/ 265 266 sal_Bool UniqueIndex::IsIndexValid( sal_uIntPtr nIndex ) const 267 { 268 // Ist Index zulaessig 269 if ( (nIndex >= nStartIndex) && 270 (nIndex < (Container::GetSize()+nStartIndex)) ) 271 { 272 // Index ist nur zulaessig, wenn Eintrag auch belegt ist 273 if ( Container::ImpGetObject( nIndex-nStartIndex ) ) 274 return sal_True; 275 else 276 return sal_False; 277 } 278 else 279 return sal_False; 280 } 281 282 /************************************************************************* 283 |* 284 |* UniqueIndex::Seek() 285 |* 286 |* Beschreibung UNQIDX.SDW 287 |* Ersterstellung TH 24.09.91 288 |* Letzte Aenderung TH 24.09.91 289 |* 290 *************************************************************************/ 291 292 void* UniqueIndex::Seek( sal_uIntPtr nIndex ) 293 { 294 // Index-Eintrag als aktuellen setzten, wenn er gueltig ist 295 if ( IsIndexValid( nIndex ) ) 296 return Container::Seek( nIndex-nStartIndex ); 297 else 298 return NULL; 299 } 300 301 /************************************************************************* 302 |* 303 |* UniqueIndex::Seek() 304 |* 305 |* Beschreibung UNQIDX.SDW 306 |* Ersterstellung TH 24.09.91 307 |* Letzte Aenderung TH 24.09.91 308 |* 309 *************************************************************************/ 310 311 void* UniqueIndex::Seek( void* p ) 312 { 313 // Wird ein NULL-Pointer uebergeben, dann wurde Pointer nicht gefunden 314 if ( !p ) 315 return NULL; 316 317 sal_uIntPtr nIndex = GetIndex( p ); 318 319 // Ist Index vorhanden, dann als aktuellen Eintrag setzen 320 if ( nIndex != UNIQUEINDEX_ENTRY_NOTFOUND ) 321 return Container::Seek( nIndex-nStartIndex ); 322 else 323 return NULL; 324 } 325 326 /************************************************************************* 327 |* 328 |* UniqueIndex::First() 329 |* 330 |* Beschreibung UNQIDX.SDW 331 |* Ersterstellung TH 24.09.91 332 |* Letzte Aenderung TH 24.09.91 333 |* 334 *************************************************************************/ 335 336 void* UniqueIndex::First() 337 { 338 void* p = Container::First(); 339 340 while ( !p && (Container::GetCurPos() < (Container::GetSize()-1)) ) 341 p = Container::Next(); 342 343 return p; 344 } 345 346 /************************************************************************* 347 |* 348 |* UniqueIndex::Last() 349 |* 350 |* Beschreibung UNQIDX.SDW 351 |* Ersterstellung TH 24.09.91 352 |* Letzte Aenderung TH 24.09.91 353 |* 354 *************************************************************************/ 355 356 void* UniqueIndex::Last() 357 { 358 void* p = Container::Last(); 359 360 while ( !p && Container::GetCurPos() ) 361 p = Container::Prev(); 362 363 return p; 364 } 365 366 /************************************************************************* 367 |* 368 |* UniqueIndex::Next() 369 |* 370 |* Beschreibung UNQIDX.SDW 371 |* Ersterstellung TH 24.09.91 372 |* Letzte Aenderung TH 24.09.91 373 |* 374 *************************************************************************/ 375 376 void* UniqueIndex::Next() 377 { 378 void* p = NULL; 379 380 while ( !p && (Container::GetCurPos() < (Container::GetSize()-1)) ) 381 p = Container::Next(); 382 383 return p; 384 } 385 386 /************************************************************************* 387 |* 388 |* UniqueIndex::Prev() 389 |* 390 |* Beschreibung UNQIDX.SDW 391 |* Ersterstellung TH 24.09.91 392 |* Letzte Aenderung TH 24.09.91 393 |* 394 *************************************************************************/ 395 396 void* UniqueIndex::Prev() 397 { 398 void* p = NULL; 399 400 while ( !p && Container::GetCurPos() ) 401 p = Container::Prev(); 402 403 return p; 404 } 405 406 /************************************************************************* 407 |* 408 |* UniqueIndex::operator =() 409 |* 410 |* Beschreibung UNQIDX.SDW 411 |* Ersterstellung TH 24.09.91 412 |* Letzte Aenderung TH 24.09.91 413 |* 414 *************************************************************************/ 415 416 UniqueIndex& UniqueIndex::operator =( const UniqueIndex& rIdx ) 417 { 418 // Neue Werte zuweisen 419 Container::operator =( rIdx ); 420 nReSize = rIdx.nReSize; 421 nStartIndex = rIdx.nStartIndex; 422 nUniqIndex = rIdx.nUniqIndex; 423 nCount = rIdx.nCount; 424 return *this; 425 } 426 427 /************************************************************************* 428 |* 429 |* UniqueIndex::operator ==() 430 |* 431 |* Beschreibung UNQIDX.SDW 432 |* Ersterstellung TH 24.09.91 433 |* Letzte Aenderung TH 24.09.91 434 |* 435 *************************************************************************/ 436 437 sal_Bool UniqueIndex::operator ==( const UniqueIndex& rIdx ) const 438 { 439 // Neue Werte zuweisen 440 if ( (nStartIndex == rIdx.nStartIndex) && 441 (nCount == rIdx.nCount) && 442 (Container::operator ==( rIdx )) ) 443 return sal_True; 444 else 445 return sal_False; 446 } 447 /************************************************************************* 448 |* 449 |* UniqueIdContainer::UniqueIdContainer () 450 |* 451 |* Beschreibung UNQIDX.SDW 452 |* Ersterstellung MM 29.04.96 453 |* Letzte Aenderung MM 29.04.96 454 |* 455 *************************************************************************/ 456 457 UniqueIdContainer::UniqueIdContainer( const UniqueIdContainer& rObj ) 458 : UniqueIndex( rObj ) 459 , nCollectCount( rObj.nCollectCount ) 460 { 461 sal_uIntPtr nCur = GetCurIndex(); 462 463 ImpUniqueId * pEle = (ImpUniqueId *)First(); 464 while( pEle ) 465 { 466 pEle->nRefCount++; 467 pEle = (ImpUniqueId *)Next(); 468 } 469 Seek( nCur ); 470 } 471 472 /************************************************************************* 473 |* 474 |* UniqueIdContainer::operator = () 475 |* 476 |* Beschreibung UNQIDX.SDW 477 |* Ersterstellung MM 01.08.94 478 |* Letzte Aenderung MM 01.08.94 479 |* 480 *************************************************************************/ 481 482 UniqueIdContainer& UniqueIdContainer::operator = ( const UniqueIdContainer & rObj ) 483 { 484 UniqueIndex::operator = ( rObj ); 485 nCollectCount = rObj.nCollectCount; 486 487 sal_uIntPtr nCur = GetCurIndex(); 488 489 ImpUniqueId * pEle = (ImpUniqueId *)First(); 490 while( pEle ) 491 { 492 pEle->nRefCount++; 493 pEle = (ImpUniqueId *)Next(); 494 } 495 Seek( nCur ); 496 return *this; 497 } 498 499 /************************************************************************* 500 |* 501 |* UniqueIdContainer::Clear() 502 |* 503 |* Beschreibung UNQIDX.SDW 504 |* Ersterstellung MM 01.08.94 505 |* Letzte Aenderung MM 01.08.94 506 |* 507 *************************************************************************/ 508 509 void UniqueIdContainer::Clear( sal_Bool bAll ) 510 { 511 sal_uInt16 nFree = bAll ? 0xFFFF : 1; 512 513 ImpUniqueId* pId = (ImpUniqueId*)Last(); 514 sal_Bool bLast = sal_True; 515 while ( pId ) 516 { 517 if ( pId->nRefCount <= nFree ) 518 { 519 ((ImpUniqueId *)Remove( pId->nId ))->Release(); 520 if( bLast ) 521 pId = (ImpUniqueId *)Last(); 522 else 523 pId = (ImpUniqueId *)Prev(); 524 } 525 else 526 { 527 pId = (ImpUniqueId *)Prev(); 528 bLast = sal_False; 529 } 530 } 531 } 532 533 /************************************************************************* 534 |* 535 |* UniqueIdContainer::CreateId() 536 |* 537 |* Beschreibung UNQIDX.SDW 538 |* Ersterstellung MM 01.08.94 539 |* Letzte Aenderung MM 01.08.94 540 |* 541 *************************************************************************/ 542 543 UniqueItemId UniqueIdContainer::CreateId() 544 { 545 if( nCollectCount > 50 ) 546 { // aufraeumen 547 Clear( sal_False ); 548 nCollectCount = 0; 549 } 550 nCollectCount++; 551 552 ImpUniqueId * pId = new ImpUniqueId; 553 pId->nRefCount = 1; 554 pId->nId = Insert( pId ); 555 return UniqueItemId( pId ); 556 } 557 558 /************************************************************************* 559 |* 560 |* UniqueIdContainer::CreateIdProt() 561 |* 562 |* Beschreibung UNQIDX.SDW 563 |* Ersterstellung MM 01.08.94 564 |* Letzte Aenderung MM 01.08.94 565 |* 566 *************************************************************************/ 567 568 UniqueItemId UniqueIdContainer::CreateFreeId( sal_uIntPtr nId ) 569 { 570 // Einfach erzeugen, fuer abgeleitete Klasse 571 ImpUniqueId * pId = new ImpUniqueId; 572 pId->nRefCount = 0; 573 pId->nId = nId; 574 return UniqueItemId( pId ); 575 } 576 577 /************************************************************************* 578 |* 579 |* UniqueIdContainer::CreateIdProt() 580 |* 581 |* Beschreibung UNQIDX.SDW 582 |* Ersterstellung MM 01.08.94 583 |* Letzte Aenderung MM 01.08.94 584 |* 585 *************************************************************************/ 586 587 UniqueItemId UniqueIdContainer::CreateIdProt( sal_uIntPtr nId ) 588 { 589 if ( IsIndexValid( nId ) ) 590 return UniqueItemId( (ImpUniqueId *)Get( nId ) ); 591 592 ImpUniqueId * pId; 593 do 594 { 595 pId = new ImpUniqueId; 596 pId->nRefCount = 1; 597 pId->nId = Insert( pId ); 598 } 599 while( pId->nId != nId ); 600 return UniqueItemId( pId ); 601 } 602