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