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 200 : TYPEINIT0(SwIndexReg);
28 :
29 : // -------
30 : // SwIndex
31 : // -------
32 :
33 320505 : SwIndex::SwIndex(SwIndexReg *const pReg, xub_StrLen const nIdx)
34 : : m_nIndex( nIdx )
35 : , m_pIndexReg( pReg )
36 : , m_pNext( 0 )
37 320505 : , m_pPrev( 0 )
38 : {
39 320505 : Init(m_nIndex);
40 320505 : }
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 273859 : SwIndex::SwIndex( const SwIndex& rIdx )
51 : : m_nIndex( rIdx.m_nIndex )
52 : , m_pIndexReg( rIdx.m_pIndexReg )
53 : , m_pNext( 0 )
54 273859 : , m_pPrev( 0 )
55 : {
56 273859 : ChgValue( rIdx, rIdx.m_nIndex );
57 273859 : }
58 :
59 389373 : void SwIndex::Init(xub_StrLen const nIdx)
60 : {
61 389373 : if (!m_pIndexReg)
62 : {
63 280746 : m_nIndex = 0; // always 0 if no IndexReg
64 : }
65 108627 : else if (!m_pIndexReg->m_pFirst) // first Index?
66 : {
67 : assert(!m_pIndexReg->m_pLast);
68 57004 : m_pIndexReg->m_pFirst = m_pIndexReg->m_pLast = this;
69 57004 : m_nIndex = nIdx;
70 : }
71 51623 : else if (nIdx > ((m_pIndexReg->m_pLast->m_nIndex
72 : - m_pIndexReg->m_pFirst->m_nIndex) / 2))
73 : {
74 13676 : ChgValue( *m_pIndexReg->m_pLast, nIdx );
75 : }
76 : else
77 : {
78 37947 : ChgValue( *m_pIndexReg->m_pFirst, nIdx );
79 : }
80 389373 : }
81 :
82 415800 : SwIndex& SwIndex::ChgValue( const SwIndex& rIdx, xub_StrLen nNewValue )
83 : {
84 : assert(m_pIndexReg == rIdx.m_pIndexReg);
85 415800 : if (!m_pIndexReg)
86 : {
87 115253 : return *this; // no IndexReg => no list to sort into; m_nIndex is 0
88 : }
89 300547 : SwIndex* pFnd = const_cast<SwIndex*>(&rIdx);
90 300547 : if (rIdx.m_nIndex > nNewValue) // move forwards
91 : {
92 : SwIndex* pPrv;
93 29843 : while ((0 != (pPrv = pFnd->m_pPrev)) && (pPrv->m_nIndex > nNewValue))
94 4719 : pFnd = pPrv;
95 :
96 12562 : if( pFnd != this )
97 : {
98 : // remove from list at old position
99 11374 : Remove();
100 :
101 11374 : m_pNext = pFnd;
102 11374 : m_pPrev = pFnd->m_pPrev;
103 11374 : if (m_pPrev)
104 1573 : m_pPrev->m_pNext = this;
105 : else
106 9801 : m_pIndexReg->m_pFirst = this;
107 11374 : pFnd->m_pPrev = this;
108 : }
109 : }
110 287985 : else if (rIdx.m_nIndex < nNewValue)
111 : {
112 : SwIndex* pNxt;
113 108898 : while ((0 != (pNxt = pFnd->m_pNext)) && (pNxt->m_nIndex < nNewValue))
114 55400 : pFnd = pNxt;
115 :
116 26749 : if( pFnd != this )
117 : {
118 : // remove from list at old position
119 25109 : Remove();
120 :
121 25109 : m_pPrev = pFnd;
122 25109 : m_pNext = pFnd->m_pNext;
123 25109 : if (m_pNext)
124 4727 : m_pNext->m_pPrev = this;
125 : else
126 20382 : m_pIndexReg->m_pLast = this;
127 25109 : pFnd->m_pNext = this;
128 : }
129 : }
130 261236 : else if( pFnd != this )
131 : {
132 : // remove from list at old position
133 260000 : Remove();
134 :
135 260000 : m_pPrev = pFnd; // == &rIdx here
136 260000 : m_pNext = rIdx.m_pNext;
137 260000 : m_pPrev->m_pNext = this;
138 :
139 260000 : if (!m_pNext) // last in the list
140 207771 : m_pIndexReg->m_pLast = this;
141 : else
142 52229 : m_pNext->m_pPrev = this;
143 : }
144 :
145 300547 : if (m_pIndexReg->m_pFirst == m_pNext)
146 0 : m_pIndexReg->m_pFirst = this;
147 300547 : if (m_pIndexReg->m_pLast == m_pPrev)
148 0 : m_pIndexReg->m_pLast = this;
149 :
150 300547 : m_nIndex = nNewValue;
151 :
152 300547 : return *this;
153 : }
154 :
155 1012840 : void SwIndex::Remove()
156 : {
157 1012840 : if (!m_pIndexReg)
158 : {
159 : assert(!m_pPrev && !m_pNext);
160 1402731 : return;
161 : }
162 :
163 622949 : if (m_pPrev)
164 : {
165 220830 : m_pPrev->m_pNext = m_pNext;
166 : }
167 402119 : else if (m_pIndexReg->m_pFirst == this)
168 : {
169 131895 : m_pIndexReg->m_pFirst = m_pNext;
170 : }
171 :
172 622949 : if (m_pNext)
173 : {
174 164874 : m_pNext->m_pPrev = m_pPrev;
175 : }
176 458075 : else if (m_pIndexReg->m_pLast == this)
177 : {
178 187851 : m_pIndexReg->m_pLast = m_pPrev;
179 : }
180 : }
181 :
182 91759 : SwIndex& SwIndex::operator=( const SwIndex& rIdx )
183 : {
184 : bool bEqual;
185 91759 : if (rIdx.m_pIndexReg != m_pIndexReg) // unregister!
186 : {
187 59993 : Remove();
188 59993 : m_pIndexReg = rIdx.m_pIndexReg;
189 59993 : m_pNext = m_pPrev = 0;
190 59993 : bEqual = false;
191 : }
192 : else
193 31766 : bEqual = rIdx.m_nIndex == m_nIndex;
194 :
195 91759 : if( !bEqual )
196 62744 : ChgValue( rIdx, rIdx.m_nIndex );
197 91759 : return *this;
198 : }
199 :
200 156161 : SwIndex& SwIndex::Assign( SwIndexReg* pArr, xub_StrLen nIdx )
201 : {
202 156161 : if (pArr != m_pIndexReg) // unregister!
203 : {
204 68868 : Remove();
205 68868 : m_pIndexReg = pArr;
206 68868 : m_pNext = m_pPrev = 0;
207 68868 : Init(nIdx);
208 : }
209 87293 : else if (m_nIndex != nIdx)
210 : {
211 23464 : ChgValue( *this, nIdx );
212 : }
213 156161 : return *this;
214 : }
215 :
216 : // ----------
217 : // SwIndexReg
218 : // ----------
219 :
220 106795 : SwIndexReg::SwIndexReg()
221 106795 : : m_pFirst( 0 ), m_pLast( 0 )
222 : {
223 106795 : }
224 :
225 104591 : SwIndexReg::~SwIndexReg()
226 : {
227 : assert(!m_pFirst && !m_pLast); // There are still indices registered
228 104591 : }
229 :
230 96822 : 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 96822 : SwIndex* pStt = const_cast<SwIndex*>(&rIdx);
234 96822 : xub_StrLen nNewVal = rIdx.m_nIndex;
235 96822 : if( bNeg )
236 : {
237 646 : xub_StrLen nLast = rIdx.GetIndex() + nDiff;
238 2070 : while (pStt && pStt->m_nIndex == nNewVal)
239 : {
240 778 : pStt->m_nIndex = nNewVal;
241 778 : pStt = pStt->m_pPrev;
242 : }
243 646 : pStt = rIdx.m_pNext;
244 2660 : while (pStt && pStt->m_nIndex >= nNewVal
245 : && pStt->m_nIndex <= nLast)
246 : {
247 1368 : pStt->m_nIndex = nNewVal;
248 1368 : pStt = pStt->m_pNext;
249 : }
250 1330 : while( pStt )
251 : {
252 38 : pStt->m_nIndex = pStt->m_nIndex - nDiff;
253 38 : pStt = pStt->m_pNext;
254 : }
255 : }
256 : else
257 : {
258 293681 : while (pStt && pStt->m_nIndex == nNewVal)
259 : {
260 101329 : pStt->m_nIndex = pStt->m_nIndex + nDiff;
261 101329 : pStt = pStt->m_pPrev;
262 : }
263 96176 : pStt = rIdx.m_pNext;
264 203665 : while( pStt )
265 : {
266 11313 : pStt->m_nIndex = pStt->m_nIndex + nDiff;
267 11313 : pStt = pStt->m_pNext;
268 : }
269 : }
270 96822 : }
271 :
272 96822 : void SwIndexReg::MoveTo( SwIndexReg& rArr )
273 : {
274 96822 : if (this != &rArr && m_pFirst)
275 : {
276 1447 : SwIndex * pIdx = const_cast<SwIndex*>(m_pFirst);
277 : SwIndex * pNext;
278 4389 : while( pIdx )
279 : {
280 1495 : pNext = pIdx->m_pNext;
281 1495 : pIdx->Assign( &rArr, pIdx->GetIndex() );
282 1495 : pIdx = pNext;
283 : }
284 1447 : m_pFirst = 0, m_pLast = 0;
285 : }
286 96822 : }
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: */
|