Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "index.hxx"
21 :
22 : #include <assert.h>
23 : #include <stdlib.h>
24 : #include <tools/solar.h>
25 : #include <tools/string.hxx>
26 :
27 100 : TYPEINIT0(SwIndexReg);
28 :
29 : // -------
30 : // SwIndex
31 : // -------
32 :
33 157462 : SwIndex::SwIndex(SwIndexReg *const pReg, xub_StrLen const nIdx)
34 : : m_nIndex( nIdx )
35 : , m_pIndexReg( pReg )
36 : , m_pNext( 0 )
37 157462 : , m_pPrev( 0 )
38 : {
39 157462 : Init(m_nIndex);
40 157462 : }
41 :
42 0 : SwIndex::SwIndex( const SwIndex& rIdx, short nDiff )
43 : : m_pIndexReg( rIdx.m_pIndexReg )
44 : , m_pNext( 0 )
45 0 : , m_pPrev( 0 )
46 : {
47 0 : ChgValue( rIdx, rIdx.m_nIndex + nDiff );
48 0 : }
49 :
50 133604 : SwIndex::SwIndex( const SwIndex& rIdx )
51 : : m_nIndex( rIdx.m_nIndex )
52 : , m_pIndexReg( rIdx.m_pIndexReg )
53 : , m_pNext( 0 )
54 133604 : , m_pPrev( 0 )
55 : {
56 133604 : ChgValue( rIdx, rIdx.m_nIndex );
57 133604 : }
58 :
59 191447 : void SwIndex::Init(xub_StrLen const nIdx)
60 : {
61 191447 : if (!m_pIndexReg)
62 : {
63 138448 : m_nIndex = 0; // always 0 if no IndexReg
64 : }
65 52999 : else if (!m_pIndexReg->m_pFirst) // first Index?
66 : {
67 : assert(!m_pIndexReg->m_pLast);
68 27744 : m_pIndexReg->m_pFirst = m_pIndexReg->m_pLast = this;
69 27744 : m_nIndex = nIdx;
70 : }
71 25255 : else if (nIdx > ((m_pIndexReg->m_pLast->m_nIndex
72 : - m_pIndexReg->m_pFirst->m_nIndex) / 2))
73 : {
74 6929 : ChgValue( *m_pIndexReg->m_pLast, nIdx );
75 : }
76 : else
77 : {
78 18326 : ChgValue( *m_pIndexReg->m_pFirst, nIdx );
79 : }
80 191447 : }
81 :
82 203138 : SwIndex& SwIndex::ChgValue( const SwIndex& rIdx, xub_StrLen nNewValue )
83 : {
84 : assert(m_pIndexReg == rIdx.m_pIndexReg);
85 203138 : if (!m_pIndexReg)
86 : {
87 56346 : return *this; // no IndexReg => no list to sort into; m_nIndex is 0
88 : }
89 146792 : SwIndex* pFnd = const_cast<SwIndex*>(&rIdx);
90 146792 : if (rIdx.m_nIndex > nNewValue) // move forwards
91 : {
92 : SwIndex* pPrv;
93 14702 : while ((0 != (pPrv = pFnd->m_pPrev)) && (pPrv->m_nIndex > nNewValue))
94 2294 : pFnd = pPrv;
95 :
96 6204 : if( pFnd != this )
97 : {
98 : // remove from list at old position
99 5627 : Remove();
100 :
101 5627 : m_pNext = pFnd;
102 5627 : m_pPrev = pFnd->m_pPrev;
103 5627 : if (m_pPrev)
104 783 : m_pPrev->m_pNext = this;
105 : else
106 4844 : m_pIndexReg->m_pFirst = this;
107 5627 : pFnd->m_pPrev = this;
108 : }
109 : }
110 140588 : else if (rIdx.m_nIndex < nNewValue)
111 : {
112 : SwIndex* pNxt;
113 62101 : while ((0 != (pNxt = pFnd->m_pNext)) && (pNxt->m_nIndex < nNewValue))
114 35471 : pFnd = pNxt;
115 :
116 13315 : if( pFnd != this )
117 : {
118 : // remove from list at old position
119 12561 : Remove();
120 :
121 12561 : m_pPrev = pFnd;
122 12561 : m_pNext = pFnd->m_pNext;
123 12561 : if (m_pNext)
124 2379 : m_pNext->m_pPrev = this;
125 : else
126 10182 : m_pIndexReg->m_pLast = this;
127 12561 : pFnd->m_pNext = this;
128 : }
129 : }
130 127273 : else if( pFnd != this )
131 : {
132 : // remove from list at old position
133 126649 : Remove();
134 :
135 126649 : m_pPrev = pFnd; // == &rIdx here
136 126649 : m_pNext = rIdx.m_pNext;
137 126649 : m_pPrev->m_pNext = this;
138 :
139 126649 : if (!m_pNext) // last in the list
140 102011 : m_pIndexReg->m_pLast = this;
141 : else
142 24638 : m_pNext->m_pPrev = this;
143 : }
144 :
145 146792 : if (m_pIndexReg->m_pFirst == m_pNext)
146 0 : m_pIndexReg->m_pFirst = this;
147 146792 : if (m_pIndexReg->m_pLast == m_pPrev)
148 0 : m_pIndexReg->m_pLast = this;
149 :
150 146792 : m_nIndex = nNewValue;
151 :
152 146792 : return *this;
153 : }
154 :
155 496315 : void SwIndex::Remove()
156 : {
157 496315 : if (!m_pIndexReg)
158 : {
159 : assert(!m_pPrev && !m_pNext);
160 688415 : return;
161 : }
162 :
163 304215 : if (m_pPrev)
164 : {
165 107534 : m_pPrev->m_pNext = m_pNext;
166 : }
167 196681 : else if (m_pIndexReg->m_pFirst == this)
168 : {
169 64738 : m_pIndexReg->m_pFirst = m_pNext;
170 : }
171 :
172 304215 : if (m_pNext)
173 : {
174 80405 : m_pNext->m_pPrev = m_pPrev;
175 : }
176 223810 : else if (m_pIndexReg->m_pLast == this)
177 : {
178 91867 : m_pIndexReg->m_pLast = m_pPrev;
179 : }
180 : }
181 :
182 44794 : SwIndex& SwIndex::operator=( const SwIndex& rIdx )
183 : {
184 : bool bEqual;
185 44794 : if (rIdx.m_pIndexReg != m_pIndexReg) // unregister!
186 : {
187 29429 : Remove();
188 29429 : m_pIndexReg = rIdx.m_pIndexReg;
189 29429 : m_pNext = m_pPrev = 0;
190 29429 : bEqual = false;
191 : }
192 : else
193 15365 : bEqual = rIdx.m_nIndex == m_nIndex;
194 :
195 44794 : if( !bEqual )
196 30678 : ChgValue( rIdx, rIdx.m_nIndex );
197 44794 : return *this;
198 : }
199 :
200 77090 : SwIndex& SwIndex::Assign( SwIndexReg* pArr, xub_StrLen nIdx )
201 : {
202 77090 : if (pArr != m_pIndexReg) // unregister!
203 : {
204 33985 : Remove();
205 33985 : m_pIndexReg = pArr;
206 33985 : m_pNext = m_pPrev = 0;
207 33985 : Init(nIdx);
208 : }
209 43105 : else if (m_nIndex != nIdx)
210 : {
211 11592 : ChgValue( *this, nIdx );
212 : }
213 77090 : return *this;
214 : }
215 :
216 : // ----------
217 : // SwIndexReg
218 : // ----------
219 :
220 52744 : SwIndexReg::SwIndexReg()
221 52744 : : m_pFirst( 0 ), m_pLast( 0 )
222 : {
223 52744 : }
224 :
225 51708 : SwIndexReg::~SwIndexReg()
226 : {
227 : assert(!m_pFirst && !m_pLast); // There are still indices registered
228 51708 : }
229 :
230 47907 : void SwIndexReg::Update( SwIndex const & rIdx, const xub_StrLen nDiff,
231 : const bool bNeg, const bool /* argument is only used in derived class*/ )
232 : {
233 47907 : SwIndex* pStt = const_cast<SwIndex*>(&rIdx);
234 47907 : xub_StrLen nNewVal = rIdx.m_nIndex;
235 47907 : if( bNeg )
236 : {
237 320 : xub_StrLen nLast = rIdx.GetIndex() + nDiff;
238 1023 : while (pStt && pStt->m_nIndex == nNewVal)
239 : {
240 383 : pStt->m_nIndex = nNewVal;
241 383 : pStt = pStt->m_pPrev;
242 : }
243 320 : pStt = rIdx.m_pNext;
244 1312 : while (pStt && pStt->m_nIndex >= nNewVal
245 : && pStt->m_nIndex <= nLast)
246 : {
247 672 : pStt->m_nIndex = nNewVal;
248 672 : pStt = pStt->m_pNext;
249 : }
250 659 : while( pStt )
251 : {
252 19 : pStt->m_nIndex = pStt->m_nIndex - nDiff;
253 19 : pStt = pStt->m_pNext;
254 : }
255 : }
256 : else
257 : {
258 145277 : while (pStt && pStt->m_nIndex == nNewVal)
259 : {
260 50103 : pStt->m_nIndex = pStt->m_nIndex + nDiff;
261 50103 : pStt = pStt->m_pPrev;
262 : }
263 47587 : pStt = rIdx.m_pNext;
264 100786 : while( pStt )
265 : {
266 5612 : pStt->m_nIndex = pStt->m_nIndex + nDiff;
267 5612 : pStt = pStt->m_pNext;
268 : }
269 : }
270 47907 : }
271 :
272 47907 : void SwIndexReg::MoveTo( SwIndexReg& rArr )
273 : {
274 47907 : if (this != &rArr && m_pFirst)
275 : {
276 716 : SwIndex * pIdx = const_cast<SwIndex*>(m_pFirst);
277 : SwIndex * pNext;
278 2166 : while( pIdx )
279 : {
280 734 : pNext = pIdx->m_pNext;
281 734 : pIdx->Assign( &rArr, pIdx->GetIndex() );
282 734 : pIdx = pNext;
283 : }
284 716 : m_pFirst = 0, m_pLast = 0;
285 : }
286 47907 : }
287 :
288 : #ifdef DBG_UTIL
289 :
290 : // -------
291 : // SwIndex
292 : // -------
293 :
294 : xub_StrLen SwIndex::operator++(int)
295 : {
296 : OSL_ASSERT( m_nIndex < INVALID_INDEX );
297 :
298 : xub_StrLen nOldIndex = m_nIndex;
299 : ChgValue( *this, m_nIndex+1 );
300 : return nOldIndex;
301 : }
302 :
303 : xub_StrLen SwIndex::operator++()
304 : {
305 : OSL_ASSERT( m_nIndex < INVALID_INDEX );
306 :
307 : ChgValue( *this, m_nIndex+1 );
308 : return m_nIndex;
309 : }
310 :
311 : xub_StrLen SwIndex::operator--(int)
312 : {
313 : OSL_ASSERT( m_nIndex );
314 :
315 : xub_StrLen nOldIndex = m_nIndex;
316 : ChgValue( *this, m_nIndex-1 );
317 : return nOldIndex;
318 : }
319 :
320 : xub_StrLen SwIndex::operator--()
321 : {
322 : OSL_ASSERT( m_nIndex );
323 : return ChgValue( *this, m_nIndex-1 ).m_nIndex;
324 : }
325 :
326 : xub_StrLen SwIndex::operator+=( xub_StrLen const nVal )
327 : {
328 : OSL_ASSERT( m_nIndex < INVALID_INDEX - nVal );
329 : return ChgValue( *this, m_nIndex + nVal ).m_nIndex;
330 : }
331 :
332 : xub_StrLen SwIndex::operator-=( xub_StrLen const nVal )
333 : {
334 : OSL_ASSERT( m_nIndex >= nVal );
335 : return ChgValue( *this, m_nIndex - nVal ).m_nIndex;
336 : }
337 :
338 : xub_StrLen SwIndex::operator+=( const SwIndex & rIndex )
339 : {
340 : OSL_ASSERT( m_nIndex < INVALID_INDEX - rIndex.m_nIndex );
341 : return ChgValue( *this, m_nIndex + rIndex.m_nIndex ).m_nIndex;
342 : }
343 :
344 : xub_StrLen SwIndex::operator-=( const SwIndex & rIndex )
345 : {
346 : OSL_ASSERT( m_nIndex >= rIndex.m_nIndex );
347 : return ChgValue( *this, m_nIndex - rIndex.m_nIndex ).m_nIndex;
348 : }
349 :
350 : bool SwIndex::operator< ( const SwIndex & rIndex ) const
351 : {
352 : // Attempt to compare indices into different arrays
353 : assert(m_pIndexReg == rIndex.m_pIndexReg);
354 : return m_nIndex < rIndex.m_nIndex;
355 : }
356 :
357 : bool SwIndex::operator<=( const SwIndex & rIndex ) const
358 : {
359 : // Attempt to compare indices into different arrays
360 : assert(m_pIndexReg == rIndex.m_pIndexReg);
361 : return m_nIndex <= rIndex.m_nIndex;
362 : }
363 :
364 : bool SwIndex::operator> ( const SwIndex & rIndex ) const
365 : {
366 : // Attempt to compare indices into different arrays
367 : assert(m_pIndexReg == rIndex.m_pIndexReg);
368 : return m_nIndex > rIndex.m_nIndex;
369 : }
370 :
371 : bool SwIndex::operator>=( const SwIndex & rIndex ) const
372 : {
373 : // Attempt to compare indices into different arrays
374 : assert(m_pIndexReg == rIndex.m_pIndexReg);
375 : return m_nIndex >= rIndex.m_nIndex;
376 : }
377 :
378 : SwIndex& SwIndex::operator= ( xub_StrLen const nVal )
379 : {
380 : if (m_nIndex != nVal)
381 : ChgValue( *this, nVal );
382 :
383 : return *this;
384 : }
385 :
386 : #endif
387 :
388 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|