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_sw.hxx" 26 27 28 #include <stdlib.h> // fuer qsort 29 #include <tools/solar.h> 30 31 #include "errhdl.hxx" // fuers ASSERT 32 #include "index.hxx" 33 #include "error.h" // fuers ASSERT 34 35 #ifdef DBG_UTIL 36 int SwIndex::nSerial = 0; 37 #endif 38 39 40 TYPEINIT0(SwIndexReg); // rtti 41 42 43 #ifdef CHK 44 45 #define IDX_CHK_ARRAY pArray->ChkArr(); 46 #define AR R_CHK_ARRAY ChkArr(); 47 48 void SwIndexReg::ChkArr() 49 { 50 if ( ! ((pFirst && pLast) || (!pFirst && !pLast))) 51 { 52 ASSERT(false, "array not correctly indexed"); 53 } 54 55 if( !pFirst ) 56 return; 57 58 xub_StrLen nVal = 0; 59 const SwIndex* pIdx = pFirst, *pPrev = 0; 60 if ( ! (!pIdx->pPrev)) 61 { 62 ASSERT(false, "array-pFirst not at beginning"); 63 } 64 65 while( pIdx != pLast ) 66 { 67 if ( ! (pIdx->pPrev != pIdx && pIdx->pNext != pIdx)) 68 { 69 ASSERT(false, "index points to itself"); 70 } 71 72 if ( ! (pIdx->nIndex >= nVal)) 73 { 74 ASSERT(false, "wrong order"); 75 } 76 if ( ! (pPrev == pIdx->pPrev)) 77 { 78 ASSERT(false, "wrong array pointers"); 79 } 80 if ( ! (this == pIdx->pArray)) 81 { 82 ASSERT(false, "wrong array/child relationship"); 83 } 84 pPrev = pIdx; 85 pIdx = pIdx->pNext; 86 nVal = pPrev->nIndex; 87 } 88 } 89 90 #else // CHK 91 92 #define IDX_CHK_ARRAY 93 #define ARR_CHK_ARRAY 94 95 #endif // CHK 96 97 98 99 SwIndex::SwIndex(SwIndexReg *const pArr, xub_StrLen const nIdx) 100 : nIndex( nIdx ), pArray( pArr ), pNext( 0 ), pPrev( 0 ) 101 { 102 if( !pArray ) 103 { 104 pArray = SwIndexReg::pEmptyIndexArray; 105 nIndex = 0; // steht immer auf 0 !!! 106 } 107 108 if( !pArray->pFirst ) // 1. Index ?? 109 pArray->pFirst = pArray->pLast = this; 110 else if( nIdx > ((pArray->pLast->nIndex - pArray->pFirst->nIndex) / 2) ) 111 ChgValue( *pArray->pLast, nIdx ); 112 else 113 ChgValue( *pArray->pFirst, nIdx ); 114 115 #ifdef DBG_UTIL 116 MySerial = ++nSerial; // nur in der nicht PRODUCT-Version 117 #endif 118 IDX_CHK_ARRAY 119 } 120 121 122 SwIndex::SwIndex( const SwIndex& rIdx, short nIdx ) 123 : pArray( rIdx.pArray ), pNext( 0 ), pPrev( 0 ) 124 { 125 ChgValue( rIdx, rIdx.nIndex + nIdx ); 126 127 #ifdef DBG_UTIL 128 MySerial = ++nSerial; // nur in der nicht PRODUCT-Version 129 #endif 130 IDX_CHK_ARRAY 131 } 132 133 134 SwIndex::SwIndex( const SwIndex& rIdx ) 135 : nIndex( rIdx.nIndex ), pArray( rIdx.pArray ), pNext( 0 ), pPrev( 0 ) 136 { 137 ChgValue( rIdx, rIdx.nIndex ); 138 #ifdef DBG_UTIL 139 MySerial = ++nSerial; // nur in der nicht PRODUCT-Version 140 #endif 141 IDX_CHK_ARRAY 142 } 143 144 145 SwIndex& SwIndex::ChgValue( const SwIndex& rIdx, xub_StrLen nNewValue ) 146 { 147 SwIndex* pFnd = (SwIndex*)&rIdx; 148 if( rIdx.nIndex > nNewValue ) // nach vorne versuchen 149 { 150 SwIndex* pPrv; 151 while( 0 != ( pPrv = pFnd->pPrev ) && pPrv->nIndex > nNewValue ) 152 pFnd = pPrv; 153 154 if( pFnd != this ) 155 { 156 // an alter Position ausketten 157 // erstmal an alter Position ausketten 158 if( pPrev ) 159 pPrev->pNext = pNext; 160 else if( pArray->pFirst == this ) 161 pArray->pFirst = pNext; 162 163 if( pNext ) 164 pNext->pPrev = pPrev; 165 else if( pArray->pLast == this ) 166 pArray->pLast = pPrev; 167 168 pNext = pFnd; 169 pPrev = pFnd->pPrev; 170 if( pPrev ) 171 pPrev->pNext = this; 172 else 173 pArray->pFirst = this; 174 pFnd->pPrev = this; 175 } 176 } 177 else if( rIdx.nIndex < nNewValue ) 178 { 179 SwIndex* pNxt; 180 while( 0 != ( pNxt = pFnd->pNext ) && pNxt->nIndex < nNewValue ) 181 pFnd = pNxt; 182 183 if( pFnd != this ) 184 { 185 // erstmal an alter Position ausketten 186 if( pPrev ) 187 pPrev->pNext = pNext; 188 else if( pArray->pFirst == this ) 189 pArray->pFirst = pNext; 190 191 if( pNext ) 192 pNext->pPrev = pPrev; 193 else if( pArray->pLast == this ) 194 pArray->pLast = pPrev; 195 196 pPrev = pFnd; 197 pNext = pFnd->pNext; 198 if( pNext ) 199 pNext->pPrev = this; 200 else 201 pArray->pLast = this; 202 pFnd->pNext = this; 203 } 204 } 205 else if( pFnd != this ) 206 { 207 // erstmal an alter Position ausketten 208 if( pPrev ) 209 pPrev->pNext = pNext; 210 else if( pArray->pFirst == this ) 211 pArray->pFirst = pNext; 212 213 if( pNext ) 214 pNext->pPrev = pPrev; 215 else if( pArray->pLast == this ) 216 pArray->pLast = pPrev; 217 218 pPrev = (SwIndex*)&rIdx; 219 pNext = rIdx.pNext; 220 pPrev->pNext = this; 221 222 if( !pNext ) // im IndexArray als letzes 223 pArray->pLast = this; 224 else 225 pNext->pPrev = this; 226 } 227 pArray = rIdx.pArray; 228 229 if( pArray->pFirst == pNext ) 230 pArray->pFirst = this; 231 if( pArray->pLast == pPrev ) 232 pArray->pLast = this; 233 234 nIndex = nNewValue; 235 236 IDX_CHK_ARRAY 237 238 return *this; } 239 240 241 void SwIndex::Remove() 242 { 243 if (pArray->pFirst==NULL && pArray->pLast==NULL) 244 { 245 // The index object is not a member of its list and therefore 246 // can not be removed. 247 return; 248 } 249 250 if (pPrev==NULL && pNext==NULL) 251 { 252 // Removing last element in list. 253 pArray->pFirst = NULL; 254 pArray->pLast = NULL; 255 } 256 else 257 { 258 if( !pPrev ) 259 { 260 OSL_ASSERT(pNext!=NULL); 261 pArray->pFirst = pNext; 262 } 263 else 264 pPrev->pNext = pNext; 265 266 if( !pNext ) 267 { 268 OSL_ASSERT(pPrev!=NULL); 269 pArray->pLast = pPrev; 270 } 271 else 272 pNext->pPrev = pPrev; 273 } 274 IDX_CHK_ARRAY 275 } 276 277 /************************************************************************* 278 |* 279 |* SwIndex & SwIndex::operator=( const SwIndex & aSwIndex ) 280 |* 281 |* Beschreibung 282 |* Ersterstellung JP 07.11.90 283 |* Letzte Aenderung JP 07.03.94 284 |* 285 *************************************************************************/ 286 287 288 SwIndex& SwIndex::operator=( const SwIndex& rIdx ) 289 { 290 int bEqual; 291 if( rIdx.pArray != pArray ) // im alten abmelden !! 292 { 293 Remove(); 294 pArray = rIdx.pArray; 295 pNext = pPrev = 0; 296 bEqual = sal_False; 297 } 298 else 299 bEqual = rIdx.nIndex == nIndex; 300 301 if( !bEqual ) 302 ChgValue( rIdx, rIdx.nIndex ); 303 return *this; 304 } 305 306 /************************************************************************* 307 |* 308 |* SwIndex &SwIndex::Assign 309 |* 310 |* Beschreibung 311 |* Ersterstellung VB 25.03.91 312 |* Letzte Aenderung JP 07.03.94 313 |* 314 *************************************************************************/ 315 316 317 SwIndex& SwIndex::Assign( SwIndexReg* pArr, xub_StrLen nIdx ) 318 { 319 if( !pArr ) 320 { 321 pArr = SwIndexReg::pEmptyIndexArray; 322 nIdx = 0; // steht immer auf 0 !!! 323 } 324 325 if( pArr != pArray ) // im alten abmelden !! 326 { 327 Remove(); 328 pArray = pArr; 329 pNext = pPrev = 0; 330 if( !pArr->pFirst ) // 1. Index ?? 331 { 332 pArr->pFirst = pArr->pLast = this; 333 nIndex = nIdx; 334 } 335 else if( pArr->pLast && (nIdx > ((pArr->pLast->nIndex - pArr->pFirst->nIndex) / 2)) ) 336 ChgValue( *pArr->pLast, nIdx ); 337 else 338 ChgValue( *pArr->pFirst, nIdx ); 339 } 340 else if( nIndex != nIdx ) 341 ChgValue( *this, nIdx ); 342 IDX_CHK_ARRAY 343 return *this; 344 } 345 346 347 SwIndexReg::SwIndexReg() 348 : pFirst( 0 ), pLast( 0 ) 349 { 350 } 351 352 353 354 SwIndexReg::~SwIndexReg() 355 { 356 ASSERT( !pFirst || !pLast, "Es sind noch Indizies angemeldet" ); 357 } 358 359 360 361 void SwIndexReg::Update( SwIndex const & rIdx, const xub_StrLen nDiff, 362 const bool bNeg, const bool /* argument is only used in derived class*/ ) 363 { 364 SwIndex* pStt = const_cast<SwIndex*>(&rIdx); 365 xub_StrLen nNewVal = rIdx.nIndex; 366 if( bNeg ) 367 { 368 xub_StrLen nLast = rIdx.GetIndex() + nDiff; 369 while( pStt && pStt->nIndex == nNewVal ) 370 { 371 pStt->nIndex = nNewVal; 372 pStt = pStt->pPrev; 373 } 374 pStt = rIdx.pNext; 375 while( pStt && pStt->nIndex >= nNewVal && 376 pStt->nIndex <= nLast ) 377 { 378 pStt->nIndex = nNewVal; 379 pStt = pStt->pNext; 380 } 381 while( pStt ) 382 { 383 pStt->nIndex = pStt->nIndex - nDiff; 384 pStt = pStt->pNext; 385 } 386 } 387 else 388 { 389 while( pStt && pStt->nIndex == nNewVal ) 390 { 391 pStt->nIndex = pStt->nIndex + nDiff; 392 pStt = pStt->pPrev; 393 } 394 pStt = rIdx.pNext; 395 while( pStt ) 396 { 397 pStt->nIndex = pStt->nIndex + nDiff; 398 pStt = pStt->pNext; 399 } 400 } 401 ARR_CHK_ARRAY 402 } 403 404 #ifdef DBG_UTIL 405 #ifndef CFRONT 406 407 /************************************************************************* 408 |* 409 |* SwIndex::operator++() 410 |* 411 |* Beschreibung 412 |* Ersterstellung JP 07.11.90 413 |* Letzte Aenderung JP 07.03.94 414 |* 415 *************************************************************************/ 416 xub_StrLen SwIndex::operator++(int) 417 { 418 ASSERT_ID( nIndex < INVALID_INDEX, ERR_OUTOFSCOPE ); 419 420 xub_StrLen nOldIndex = nIndex; 421 ChgValue( *this, nIndex+1 ); 422 return nOldIndex; 423 } 424 425 #endif 426 427 xub_StrLen SwIndex::operator++() 428 { 429 ASSERT_ID( nIndex < INVALID_INDEX, ERR_OUTOFSCOPE ); 430 431 ChgValue( *this, nIndex+1 ); 432 return nIndex; 433 } 434 435 /************************************************************************* 436 |* 437 |* SwIndex::operator--() 438 |* 439 |* Beschreibung 440 |* Ersterstellung JP 07.11.90 441 |* Letzte Aenderung JP 07.03.94 442 |* 443 *************************************************************************/ 444 445 #ifndef CFRONT 446 447 xub_StrLen SwIndex::operator--(int) 448 { 449 ASSERT_ID( nIndex, ERR_OUTOFSCOPE ); 450 451 xub_StrLen nOldIndex = nIndex; 452 ChgValue( *this, nIndex-1 ); 453 return nOldIndex; 454 } 455 456 #endif 457 458 xub_StrLen SwIndex::operator--() 459 { 460 ASSERT_ID( nIndex, ERR_OUTOFSCOPE ); 461 return ChgValue( *this, nIndex-1 ).nIndex; 462 } 463 464 /************************************************************************* 465 |* 466 |* SwIndex::operator+=( xub_StrLen ) 467 |* 468 |* Beschreibung 469 |* Ersterstellung JP 07.11.90 470 |* Letzte Aenderung JP 07.03.94 471 |* 472 *************************************************************************/ 473 474 xub_StrLen SwIndex::operator+=( xub_StrLen nWert ) 475 { 476 ASSERT_ID( nIndex < INVALID_INDEX - nWert, ERR_OUTOFSCOPE); 477 return ChgValue( *this, nIndex + nWert ).nIndex; 478 } 479 480 /************************************************************************* 481 |* 482 |* SwIndex::operator-=( xub_StrLen ) 483 |* 484 |* Beschreibung 485 |* Ersterstellung JP 07.11.90 486 |* Letzte Aenderung JP 07.03.94 487 |* 488 *************************************************************************/ 489 490 xub_StrLen SwIndex::operator-=( xub_StrLen nWert ) 491 { 492 ASSERT_ID( nIndex >= nWert, ERR_OUTOFSCOPE ); 493 return ChgValue( *this, nIndex - nWert ).nIndex; 494 } 495 496 /************************************************************************* 497 |* 498 |* SwIndex::operator+=( const SwIndex & ) 499 |* 500 |* Beschreibung 501 |* Ersterstellung JP 07.11.90 502 |* Letzte Aenderung JP 07.03.94 503 |* 504 *************************************************************************/ 505 506 xub_StrLen SwIndex::operator+=( const SwIndex & rIndex ) 507 { 508 ASSERT_ID( nIndex < INVALID_INDEX - rIndex.nIndex, ERR_OUTOFSCOPE ); 509 return ChgValue( *this, nIndex + rIndex.nIndex ).nIndex; 510 } 511 512 /************************************************************************* 513 |* 514 |* SwIndex::operator-=( const SwIndex & ) 515 |* 516 |* Beschreibung 517 |* Ersterstellung JP 07.11.90 518 |* Letzte Aenderung JP 07.03.94 519 |* 520 *************************************************************************/ 521 522 xub_StrLen SwIndex::operator-=( const SwIndex & rIndex ) 523 { 524 ASSERT_ID( nIndex >= rIndex.nIndex, ERR_OUTOFSCOPE ); 525 return ChgValue( *this, nIndex - rIndex.nIndex ).nIndex; 526 } 527 528 /************************************************************************* 529 |* 530 |* SwIndex::operator<( const SwIndex & ) 531 |* 532 |* Beschreibung 533 |* Ersterstellung JP 07.11.90 534 |* Letzte Aenderung JP 07.03.94 535 |* 536 *************************************************************************/ 537 538 sal_Bool SwIndex::operator<( const SwIndex & rIndex ) const 539 { 540 ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays."); 541 return nIndex < rIndex.nIndex; 542 } 543 544 /************************************************************************* 545 |* 546 |* SwIndex::operator<=( const SwIndex & ) 547 |* 548 |* Beschreibung 549 |* Ersterstellung JP 07.11.90 550 |* Letzte Aenderung JP 04.06.92 551 |* 552 *************************************************************************/ 553 554 sal_Bool SwIndex::operator<=( const SwIndex & rIndex ) const 555 { 556 ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays."); 557 return nIndex <= rIndex.nIndex; 558 } 559 560 /************************************************************************* 561 |* 562 |* SwIndex::operator>( const SwIndex & ) 563 |* 564 |* Beschreibung 565 |* Ersterstellung JP 07.11.90 566 |* Letzte Aenderung JP 04.06.92 567 |* 568 *************************************************************************/ 569 570 sal_Bool SwIndex::operator>( const SwIndex & rIndex ) const 571 { 572 ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays."); 573 return nIndex > rIndex.nIndex; 574 } 575 576 /************************************************************************* 577 |* 578 |* SwIndex::operator>=( const SwIndex & ) 579 |* 580 |* Beschreibung 581 |* Ersterstellung JP 07.11.90 582 |* Letzte Aenderung JP 04.06.92 583 |* 584 *************************************************************************/ 585 586 sal_Bool SwIndex::operator>=( const SwIndex & rIndex ) const 587 { 588 ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays."); 589 return nIndex >= rIndex.nIndex; 590 } 591 592 /************************************************************************* 593 |* 594 |* SwIndex & SwIndex::operator=( xub_StrLen ) 595 |* 596 |* Beschreibung 597 |* Ersterstellung JP 10.12.90 598 |* Letzte Aenderung JP 07.03.94 599 |* 600 *************************************************************************/ 601 602 SwIndex& SwIndex::operator=( xub_StrLen nWert ) 603 { 604 // Werte kopieren und im neuen Array anmelden 605 if( nIndex != nWert ) 606 ChgValue( *this, nWert ); 607 608 return *this; 609 } 610 611 #endif // ifndef PRODUCT 612 613 void SwIndexReg::MoveTo( SwIndexReg& rArr ) 614 { 615 if( this != &rArr && pFirst ) 616 { 617 SwIndex* pIdx = (SwIndex*)pFirst, *pNext; 618 while( pIdx ) 619 { 620 pNext = pIdx->pNext; 621 pIdx->Assign( &rArr, pIdx->GetIndex() ); 622 pIdx = pNext; 623 } 624 pFirst = 0, pLast = 0; 625 } 626 } 627