Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "index.hxx"
30 : :
31 : : #include <assert.h>
32 : : #include <stdlib.h>
33 : : #include <tools/solar.h>
34 : : #include <tools/string.hxx>
35 : :
36 [ - + ]: 240 : TYPEINIT0(SwIndexReg);
37 : :
38 : : // -------
39 : : // SwIndex
40 : : // -------
41 : :
42 : 864190 : SwIndex::SwIndex(SwIndexReg *const pReg, xub_StrLen const nIdx)
43 : : : m_nIndex( nIdx )
44 : : , m_pIndexReg( pReg )
45 : : , m_pNext( 0 )
46 : 864190 : , m_pPrev( 0 )
47 : : {
48 : 864190 : Init(m_nIndex);
49 : 864190 : }
50 : :
51 : 144 : SwIndex::SwIndex( const SwIndex& rIdx, short nDiff )
52 : : : m_pIndexReg( rIdx.m_pIndexReg )
53 : : , m_pNext( 0 )
54 : 144 : , m_pPrev( 0 )
55 : : {
56 : 144 : ChgValue( rIdx, rIdx.m_nIndex + nDiff );
57 : 144 : }
58 : :
59 : 1262370 : SwIndex::SwIndex( const SwIndex& rIdx )
60 : : : m_nIndex( rIdx.m_nIndex )
61 : : , m_pIndexReg( rIdx.m_pIndexReg )
62 : : , m_pNext( 0 )
63 : 1262370 : , m_pPrev( 0 )
64 : : {
65 : 1262370 : ChgValue( rIdx, rIdx.m_nIndex );
66 : 1262370 : }
67 : :
68 : 1004897 : void SwIndex::Init(xub_StrLen const nIdx)
69 : : {
70 [ + + ]: 1004897 : if (!m_pIndexReg)
71 : : {
72 : 737997 : m_nIndex = 0; // always 0 if no IndexReg
73 : : }
74 [ + + ]: 266900 : else if (!m_pIndexReg->m_pFirst) // first Index?
75 : : {
76 : : assert(!m_pIndexReg->m_pLast);
77 : 103372 : m_pIndexReg->m_pFirst = m_pIndexReg->m_pLast = this;
78 : 103372 : m_nIndex = nIdx;
79 : : }
80 [ + + ]: 163528 : else if (nIdx > ((m_pIndexReg->m_pLast->m_nIndex
81 : : - m_pIndexReg->m_pFirst->m_nIndex) / 2))
82 : : {
83 : 52213 : ChgValue( *m_pIndexReg->m_pLast, nIdx );
84 : : }
85 : : else
86 : : {
87 : 111315 : ChgValue( *m_pIndexReg->m_pFirst, nIdx );
88 : : }
89 : 1004897 : }
90 : :
91 : 1862377 : SwIndex& SwIndex::ChgValue( const SwIndex& rIdx, xub_StrLen nNewValue )
92 : : {
93 : : assert(m_pIndexReg == rIdx.m_pIndexReg);
94 [ + + ]: 1862377 : if (!m_pIndexReg)
95 : : {
96 : 286434 : return *this; // no IndexReg => no list to sort into; m_nIndex is 0
97 : : }
98 : 1575943 : SwIndex* pFnd = const_cast<SwIndex*>(&rIdx);
99 [ + + ]: 1575943 : if (rIdx.m_nIndex > nNewValue) // move forwards
100 : : {
101 : : SwIndex* pPrv;
102 [ + + ][ + + ]: 626068 : while ((0 != (pPrv = pFnd->m_pPrev)) && (pPrv->m_nIndex > nNewValue))
[ + + ]
103 : 488780 : pFnd = pPrv;
104 : :
105 [ + + ]: 137288 : if( pFnd != this )
106 : : {
107 : : // remove from list at old position
108 : 70983 : Remove();
109 : :
110 : 70983 : m_pNext = pFnd;
111 : 70983 : m_pPrev = pFnd->m_pPrev;
112 [ + + ]: 70983 : if (m_pPrev)
113 : 22330 : m_pPrev->m_pNext = this;
114 : : else
115 : 48653 : m_pIndexReg->m_pFirst = this;
116 : 70983 : pFnd->m_pPrev = this;
117 : : }
118 : : }
119 [ + + ]: 1438655 : else if (rIdx.m_nIndex < nNewValue)
120 : : {
121 : : SwIndex* pNxt;
122 [ + + ][ + + ]: 1118698 : while ((0 != (pNxt = pFnd->m_pNext)) && (pNxt->m_nIndex < nNewValue))
[ + + ]
123 : 972514 : pFnd = pNxt;
124 : :
125 [ + + ]: 146184 : if( pFnd != this )
126 : : {
127 : : // remove from list at old position
128 : 53298 : Remove();
129 : :
130 : 53298 : m_pPrev = pFnd;
131 : 53298 : m_pNext = pFnd->m_pNext;
132 [ + + ]: 53298 : if (m_pNext)
133 : 34059 : m_pNext->m_pPrev = this;
134 : : else
135 : 19239 : m_pIndexReg->m_pLast = this;
136 : 53298 : pFnd->m_pNext = this;
137 : : }
138 : : }
139 [ + + ]: 1292471 : else if( pFnd != this )
140 : : {
141 : : // remove from list at old position
142 : 1290201 : Remove();
143 : :
144 : 1290201 : m_pPrev = pFnd; // == &rIdx here
145 : 1290201 : m_pNext = rIdx.m_pNext;
146 : 1290201 : m_pPrev->m_pNext = this;
147 : :
148 [ + + ]: 1290201 : if (!m_pNext) // last in the list
149 : 529324 : m_pIndexReg->m_pLast = this;
150 : : else
151 : 760877 : m_pNext->m_pPrev = this;
152 : : }
153 : :
154 [ - + ]: 1575943 : if (m_pIndexReg->m_pFirst == m_pNext)
155 : 0 : m_pIndexReg->m_pFirst = this;
156 [ - + ]: 1575943 : if (m_pIndexReg->m_pLast == m_pPrev)
157 : 0 : m_pIndexReg->m_pLast = this;
158 : :
159 : 1575943 : m_nIndex = nNewValue;
160 : :
161 : 1862377 : return *this;
162 : : }
163 : :
164 : 3865998 : void SwIndex::Remove()
165 : : {
166 [ + + ]: 3865998 : if (!m_pIndexReg)
167 : : {
168 : : assert(!m_pPrev && !m_pNext);
169 : 3865998 : return;
170 : : }
171 : :
172 [ + + ]: 2843317 : if (m_pPrev)
173 : : {
174 : 1271111 : m_pPrev->m_pNext = m_pNext;
175 : : }
176 [ + + ]: 1572206 : else if (m_pIndexReg->m_pFirst == this)
177 : : {
178 : 246418 : m_pIndexReg->m_pFirst = m_pNext;
179 : : }
180 : :
181 [ + + ]: 2843317 : if (m_pNext)
182 : : {
183 : 1106151 : m_pNext->m_pPrev = m_pPrev;
184 : : }
185 [ + + ]: 1737166 : else if (m_pIndexReg->m_pLast == this)
186 : : {
187 : 411378 : m_pIndexReg->m_pLast = m_pPrev;
188 : : }
189 : : }
190 : :
191 : 314790 : SwIndex& SwIndex::operator=( const SwIndex& rIdx )
192 : : {
193 : : bool bEqual;
194 [ + + ]: 314790 : if (rIdx.m_pIndexReg != m_pIndexReg) // unregister!
195 : : {
196 : 186175 : Remove();
197 : 186175 : m_pIndexReg = rIdx.m_pIndexReg;
198 : 186175 : m_pNext = m_pPrev = 0;
199 : 186175 : bEqual = false;
200 : : }
201 : : else
202 : 128615 : bEqual = rIdx.m_nIndex == m_nIndex;
203 : :
204 [ + + ]: 314790 : if( !bEqual )
205 : 228437 : ChgValue( rIdx, rIdx.m_nIndex );
206 : 314790 : return *this;
207 : : }
208 : :
209 : 350048 : SwIndex& SwIndex::Assign( SwIndexReg* pArr, xub_StrLen nIdx )
210 : : {
211 [ + + ]: 350048 : if (pArr != m_pIndexReg) // unregister!
212 : : {
213 : 140707 : Remove();
214 : 140707 : m_pIndexReg = pArr;
215 : 140707 : m_pNext = m_pPrev = 0;
216 : 140707 : Init(nIdx);
217 : : }
218 [ + + ]: 209341 : else if (m_nIndex != nIdx)
219 : : {
220 : 30034 : ChgValue( *this, nIdx );
221 : : }
222 : 350048 : return *this;
223 : : }
224 : :
225 : : // ----------
226 : : // SwIndexReg
227 : : // ----------
228 : :
229 : 263143 : SwIndexReg::SwIndexReg()
230 : 263143 : : m_pFirst( 0 ), m_pLast( 0 )
231 : : {
232 : 263143 : }
233 : :
234 : 262498 : SwIndexReg::~SwIndexReg()
235 : : {
236 : : assert(!m_pFirst && !m_pLast); // There are still indices registered
237 [ - + ]: 262498 : }
238 : :
239 : 240582 : void SwIndexReg::Update( SwIndex const & rIdx, const xub_StrLen nDiff,
240 : : const bool bNeg, const bool /* argument is only used in derived class*/ )
241 : : {
242 : 240582 : SwIndex* pStt = const_cast<SwIndex*>(&rIdx);
243 : 240582 : xub_StrLen nNewVal = rIdx.m_nIndex;
244 [ + + ]: 240582 : if( bNeg )
245 : : {
246 : 3119 : xub_StrLen nLast = rIdx.GetIndex() + nDiff;
247 [ + + ][ + + ]: 6770 : while (pStt && pStt->m_nIndex == nNewVal)
[ + + ]
248 : : {
249 : 3651 : pStt->m_nIndex = nNewVal;
250 : 3651 : pStt = pStt->m_pPrev;
251 : : }
252 : 3119 : pStt = rIdx.m_pNext;
253 [ + + ][ + - ]: 16550 : while (pStt && pStt->m_nIndex >= nNewVal
[ + + ][ + + ]
254 : : && pStt->m_nIndex <= nLast)
255 : : {
256 : 13431 : pStt->m_nIndex = nNewVal;
257 : 13431 : pStt = pStt->m_pNext;
258 : : }
259 [ + + ]: 76837 : while( pStt )
260 : : {
261 : 73718 : pStt->m_nIndex = pStt->m_nIndex - nDiff;
262 : 73718 : pStt = pStt->m_pNext;
263 : : }
264 : : }
265 : : else
266 : : {
267 [ + + ][ + + ]: 501055 : while (pStt && pStt->m_nIndex == nNewVal)
[ + + ]
268 : : {
269 : 263592 : pStt->m_nIndex = pStt->m_nIndex + nDiff;
270 : 263592 : pStt = pStt->m_pPrev;
271 : : }
272 : 237463 : pStt = rIdx.m_pNext;
273 [ + + ]: 1514292 : while( pStt )
274 : : {
275 : 1276829 : pStt->m_nIndex = pStt->m_nIndex + nDiff;
276 : 1276829 : pStt = pStt->m_pNext;
277 : : }
278 : : }
279 : 240582 : }
280 : :
281 : 240582 : void SwIndexReg::MoveTo( SwIndexReg& rArr )
282 : : {
283 [ + - ][ + + ]: 240582 : if (this != &rArr && m_pFirst)
284 : : {
285 : 7536 : SwIndex * pIdx = const_cast<SwIndex*>(m_pFirst);
286 : : SwIndex * pNext;
287 [ + + ]: 16178 : while( pIdx )
288 : : {
289 : 8642 : pNext = pIdx->m_pNext;
290 : 8642 : pIdx->Assign( &rArr, pIdx->GetIndex() );
291 : 8642 : pIdx = pNext;
292 : : }
293 : 7536 : m_pFirst = 0, m_pLast = 0;
294 : : }
295 : 240582 : }
296 : :
297 : : #ifdef DBG_UTIL
298 : :
299 : : // -------
300 : : // SwIndex
301 : : // -------
302 : :
303 : : xub_StrLen SwIndex::operator++(int)
304 : : {
305 : : OSL_ASSERT( m_nIndex < INVALID_INDEX );
306 : :
307 : : xub_StrLen nOldIndex = m_nIndex;
308 : : ChgValue( *this, m_nIndex+1 );
309 : : return nOldIndex;
310 : : }
311 : :
312 : : xub_StrLen SwIndex::operator++()
313 : : {
314 : : OSL_ASSERT( m_nIndex < INVALID_INDEX );
315 : :
316 : : ChgValue( *this, m_nIndex+1 );
317 : : return m_nIndex;
318 : : }
319 : :
320 : : xub_StrLen SwIndex::operator--(int)
321 : : {
322 : : OSL_ASSERT( m_nIndex );
323 : :
324 : : xub_StrLen nOldIndex = m_nIndex;
325 : : ChgValue( *this, m_nIndex-1 );
326 : : return nOldIndex;
327 : : }
328 : :
329 : : xub_StrLen SwIndex::operator--()
330 : : {
331 : : OSL_ASSERT( m_nIndex );
332 : : return ChgValue( *this, m_nIndex-1 ).m_nIndex;
333 : : }
334 : :
335 : : xub_StrLen SwIndex::operator+=( xub_StrLen const nVal )
336 : : {
337 : : OSL_ASSERT( m_nIndex < INVALID_INDEX - nVal );
338 : : return ChgValue( *this, m_nIndex + nVal ).m_nIndex;
339 : : }
340 : :
341 : : xub_StrLen SwIndex::operator-=( xub_StrLen const nVal )
342 : : {
343 : : OSL_ASSERT( m_nIndex >= nVal );
344 : : return ChgValue( *this, m_nIndex - nVal ).m_nIndex;
345 : : }
346 : :
347 : : xub_StrLen SwIndex::operator+=( const SwIndex & rIndex )
348 : : {
349 : : OSL_ASSERT( m_nIndex < INVALID_INDEX - rIndex.m_nIndex );
350 : : return ChgValue( *this, m_nIndex + rIndex.m_nIndex ).m_nIndex;
351 : : }
352 : :
353 : : xub_StrLen SwIndex::operator-=( const SwIndex & rIndex )
354 : : {
355 : : OSL_ASSERT( m_nIndex >= rIndex.m_nIndex );
356 : : return ChgValue( *this, m_nIndex - rIndex.m_nIndex ).m_nIndex;
357 : : }
358 : :
359 : : bool SwIndex::operator< ( const SwIndex & rIndex ) const
360 : : {
361 : : // Attempt to compare indices into different arrays
362 : : assert(m_pIndexReg == rIndex.m_pIndexReg);
363 : : return m_nIndex < rIndex.m_nIndex;
364 : : }
365 : :
366 : : bool SwIndex::operator<=( const SwIndex & rIndex ) const
367 : : {
368 : : // Attempt to compare indices into different arrays
369 : : assert(m_pIndexReg == rIndex.m_pIndexReg);
370 : : return m_nIndex <= rIndex.m_nIndex;
371 : : }
372 : :
373 : : bool SwIndex::operator> ( const SwIndex & rIndex ) const
374 : : {
375 : : // Attempt to compare indices into different arrays
376 : : assert(m_pIndexReg == rIndex.m_pIndexReg);
377 : : return m_nIndex > rIndex.m_nIndex;
378 : : }
379 : :
380 : : bool SwIndex::operator>=( const SwIndex & rIndex ) const
381 : : {
382 : : // Attempt to compare indices into different arrays
383 : : assert(m_pIndexReg == rIndex.m_pIndexReg);
384 : : return m_nIndex >= rIndex.m_nIndex;
385 : : }
386 : :
387 : : SwIndex& SwIndex::operator= ( xub_StrLen const nVal )
388 : : {
389 : : if (m_nIndex != nVal)
390 : : ChgValue( *this, nVal );
391 : :
392 : : return *this;
393 : : }
394 : :
395 : : #endif
396 : :
397 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|