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
ChkArr()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
SwIndex(SwIndexReg * const pArr,xub_StrLen const nIdx)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
SwIndex(const SwIndex & rIdx,short nIdx)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
SwIndex(const SwIndex & rIdx)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
ChgValue(const SwIndex & rIdx,xub_StrLen nNewValue)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
Remove()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
operator =(const SwIndex & rIdx)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
Assign(SwIndexReg * pArr,xub_StrLen nIdx)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
SwIndexReg()347 SwIndexReg::SwIndexReg()
348 : pFirst( 0 ), pLast( 0 )
349 {
350 }
351
352
353
~SwIndexReg()354 SwIndexReg::~SwIndexReg()
355 {
356 ASSERT( !pFirst || !pLast, "Es sind noch Indizies angemeldet" );
357 }
358
359
Update(SwIndex const & rIdx,const xub_StrLen nDiff,const bool bNeg,const bool)360 void SwIndexReg::Update(
361 SwIndex const & rIdx,
362 const xub_StrLen nDiff,
363 const bool bNeg,
364 const bool /* argument is only used in derived class*/ )
365 {
366 SwIndex* pStt = const_cast<SwIndex*>(&rIdx);
367 const xub_StrLen nNewVal = rIdx.nIndex;
368 if( bNeg )
369 {
370 const xub_StrLen nLast = rIdx.GetIndex() + nDiff;
371 while( pStt && pStt->nIndex == nNewVal )
372 {
373 pStt->nIndex = nNewVal;
374 pStt = pStt->pPrev;
375 }
376 pStt = rIdx.pNext;
377 while( pStt && pStt->nIndex >= nNewVal &&
378 pStt->nIndex <= nLast )
379 {
380 pStt->nIndex = nNewVal;
381 pStt = pStt->pNext;
382 }
383 while( pStt )
384 {
385 pStt->nIndex = pStt->nIndex - nDiff;
386 pStt = pStt->pNext;
387 }
388 }
389 else
390 {
391 while( pStt && pStt->nIndex == nNewVal )
392 {
393 pStt->nIndex = pStt->nIndex + nDiff;
394 pStt = pStt->pPrev;
395 }
396 pStt = rIdx.pNext;
397 while( pStt )
398 {
399 pStt->nIndex = pStt->nIndex + nDiff;
400 pStt = pStt->pNext;
401 }
402 }
403 ARR_CHK_ARRAY
404 }
405
406 #ifdef DBG_UTIL
407 #ifndef CFRONT
408
409 /*************************************************************************
410 |*
411 |* SwIndex::operator++()
412 |*
413 |* Beschreibung
414 |* Ersterstellung JP 07.11.90
415 |* Letzte Aenderung JP 07.03.94
416 |*
417 *************************************************************************/
operator ++(int)418 xub_StrLen SwIndex::operator++(int)
419 {
420 ASSERT_ID( nIndex < INVALID_INDEX, ERR_OUTOFSCOPE );
421
422 xub_StrLen nOldIndex = nIndex;
423 ChgValue( *this, nIndex+1 );
424 return nOldIndex;
425 }
426
427 #endif
428
operator ++()429 xub_StrLen SwIndex::operator++()
430 {
431 ASSERT_ID( nIndex < INVALID_INDEX, ERR_OUTOFSCOPE );
432
433 ChgValue( *this, nIndex+1 );
434 return nIndex;
435 }
436
437 /*************************************************************************
438 |*
439 |* SwIndex::operator--()
440 |*
441 |* Beschreibung
442 |* Ersterstellung JP 07.11.90
443 |* Letzte Aenderung JP 07.03.94
444 |*
445 *************************************************************************/
446
447 #ifndef CFRONT
448
operator --(int)449 xub_StrLen SwIndex::operator--(int)
450 {
451 ASSERT_ID( nIndex, ERR_OUTOFSCOPE );
452
453 xub_StrLen nOldIndex = nIndex;
454 ChgValue( *this, nIndex-1 );
455 return nOldIndex;
456 }
457
458 #endif
459
operator --()460 xub_StrLen SwIndex::operator--()
461 {
462 ASSERT_ID( nIndex, ERR_OUTOFSCOPE );
463 return ChgValue( *this, nIndex-1 ).nIndex;
464 }
465
466 /*************************************************************************
467 |*
468 |* SwIndex::operator+=( xub_StrLen )
469 |*
470 |* Beschreibung
471 |* Ersterstellung JP 07.11.90
472 |* Letzte Aenderung JP 07.03.94
473 |*
474 *************************************************************************/
475
operator +=(xub_StrLen nWert)476 xub_StrLen SwIndex::operator+=( xub_StrLen nWert )
477 {
478 ASSERT_ID( nIndex < INVALID_INDEX - nWert, ERR_OUTOFSCOPE);
479 return ChgValue( *this, nIndex + nWert ).nIndex;
480 }
481
482 /*************************************************************************
483 |*
484 |* SwIndex::operator-=( xub_StrLen )
485 |*
486 |* Beschreibung
487 |* Ersterstellung JP 07.11.90
488 |* Letzte Aenderung JP 07.03.94
489 |*
490 *************************************************************************/
491
operator -=(xub_StrLen nWert)492 xub_StrLen SwIndex::operator-=( xub_StrLen nWert )
493 {
494 ASSERT_ID( nIndex >= nWert, ERR_OUTOFSCOPE );
495 return ChgValue( *this, nIndex - nWert ).nIndex;
496 }
497
498 /*************************************************************************
499 |*
500 |* SwIndex::operator+=( const SwIndex & )
501 |*
502 |* Beschreibung
503 |* Ersterstellung JP 07.11.90
504 |* Letzte Aenderung JP 07.03.94
505 |*
506 *************************************************************************/
507
operator +=(const SwIndex & rIndex)508 xub_StrLen SwIndex::operator+=( const SwIndex & rIndex )
509 {
510 ASSERT_ID( nIndex < INVALID_INDEX - rIndex.nIndex, ERR_OUTOFSCOPE );
511 return ChgValue( *this, nIndex + rIndex.nIndex ).nIndex;
512 }
513
514 /*************************************************************************
515 |*
516 |* SwIndex::operator-=( const SwIndex & )
517 |*
518 |* Beschreibung
519 |* Ersterstellung JP 07.11.90
520 |* Letzte Aenderung JP 07.03.94
521 |*
522 *************************************************************************/
523
operator -=(const SwIndex & rIndex)524 xub_StrLen SwIndex::operator-=( const SwIndex & rIndex )
525 {
526 ASSERT_ID( nIndex >= rIndex.nIndex, ERR_OUTOFSCOPE );
527 return ChgValue( *this, nIndex - rIndex.nIndex ).nIndex;
528 }
529
530 /*************************************************************************
531 |*
532 |* SwIndex::operator<( const SwIndex & )
533 |*
534 |* Beschreibung
535 |* Ersterstellung JP 07.11.90
536 |* Letzte Aenderung JP 07.03.94
537 |*
538 *************************************************************************/
539
operator <(const SwIndex & rIndex) const540 sal_Bool SwIndex::operator<( const SwIndex & rIndex ) const
541 {
542 ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays.");
543 return nIndex < rIndex.nIndex;
544 }
545
546 /*************************************************************************
547 |*
548 |* SwIndex::operator<=( const SwIndex & )
549 |*
550 |* Beschreibung
551 |* Ersterstellung JP 07.11.90
552 |* Letzte Aenderung JP 04.06.92
553 |*
554 *************************************************************************/
555
operator <=(const SwIndex & rIndex) const556 sal_Bool SwIndex::operator<=( const SwIndex & rIndex ) const
557 {
558 ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays.");
559 return nIndex <= rIndex.nIndex;
560 }
561
562 /*************************************************************************
563 |*
564 |* SwIndex::operator>( const SwIndex & )
565 |*
566 |* Beschreibung
567 |* Ersterstellung JP 07.11.90
568 |* Letzte Aenderung JP 04.06.92
569 |*
570 *************************************************************************/
571
operator >(const SwIndex & rIndex) const572 sal_Bool SwIndex::operator>( const SwIndex & rIndex ) const
573 {
574 ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays.");
575 return nIndex > rIndex.nIndex;
576 }
577
578 /*************************************************************************
579 |*
580 |* SwIndex::operator>=( const SwIndex & )
581 |*
582 |* Beschreibung
583 |* Ersterstellung JP 07.11.90
584 |* Letzte Aenderung JP 04.06.92
585 |*
586 *************************************************************************/
587
operator >=(const SwIndex & rIndex) const588 sal_Bool SwIndex::operator>=( const SwIndex & rIndex ) const
589 {
590 ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays.");
591 return nIndex >= rIndex.nIndex;
592 }
593
594 /*************************************************************************
595 |*
596 |* SwIndex & SwIndex::operator=( xub_StrLen )
597 |*
598 |* Beschreibung
599 |* Ersterstellung JP 10.12.90
600 |* Letzte Aenderung JP 07.03.94
601 |*
602 *************************************************************************/
603
operator =(xub_StrLen nWert)604 SwIndex& SwIndex::operator=( xub_StrLen nWert )
605 {
606 // Werte kopieren und im neuen Array anmelden
607 if( nIndex != nWert )
608 ChgValue( *this, nWert );
609
610 return *this;
611 }
612
613 #endif // ifndef PRODUCT
614
MoveTo(SwIndexReg & rArr)615 void SwIndexReg::MoveTo( SwIndexReg& rArr )
616 {
617 if( this != &rArr && pFirst )
618 {
619 SwIndex* pIdx = (SwIndex*)pFirst, *pNext;
620 while( pIdx )
621 {
622 pNext = pIdx->pNext;
623 pIdx->Assign( &rArr, pIdx->GetIndex() );
624 pIdx = pNext;
625 }
626 pFirst = 0, pLast = 0;
627 }
628 }
629