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 <sal/log.hxx>
24 :
25 6476 : TYPEINIT0(SwIndexReg);
26 :
27 36344245 : SwIndex::SwIndex(SwIndexReg *const pReg, sal_Int32 const nIdx)
28 : : m_nIndex( nIdx )
29 : , m_pIndexReg( pReg )
30 : , m_pNext( 0 )
31 : , m_pPrev( 0 )
32 36344245 : , m_pMark( 0 )
33 : {
34 36344245 : Init(m_nIndex);
35 36344245 : }
36 :
37 97 : SwIndex::SwIndex( const SwIndex& rIdx, short nDiff )
38 : : m_pIndexReg( rIdx.m_pIndexReg )
39 : , m_pNext( 0 )
40 : , m_pPrev( 0 )
41 97 : , m_pMark( 0 )
42 : {
43 97 : ChgValue( rIdx, rIdx.m_nIndex + nDiff );
44 97 : }
45 :
46 24866390 : SwIndex::SwIndex( const SwIndex& rIdx )
47 : : m_nIndex( rIdx.m_nIndex )
48 : , m_pIndexReg( rIdx.m_pIndexReg )
49 : , m_pNext( 0 )
50 : , m_pPrev( 0 )
51 24866390 : , m_pMark( 0 )
52 : {
53 24866390 : ChgValue( rIdx, rIdx.m_nIndex );
54 24866390 : }
55 :
56 36829194 : void SwIndex::Init(sal_Int32 const nIdx)
57 : {
58 36829194 : if (!m_pIndexReg)
59 : {
60 24481543 : m_nIndex = 0; // always 0 if no IndexReg
61 : }
62 12347651 : else if (!m_pIndexReg->m_pFirst) // first Index?
63 : {
64 : assert(!m_pIndexReg->m_pLast);
65 11761010 : m_pIndexReg->m_pFirst = m_pIndexReg->m_pLast = this;
66 11761010 : m_nIndex = nIdx;
67 : }
68 586641 : else if (nIdx > ((m_pIndexReg->m_pLast->m_nIndex
69 586641 : - m_pIndexReg->m_pFirst->m_nIndex) / 2))
70 : {
71 67162 : ChgValue( *m_pIndexReg->m_pLast, nIdx );
72 : }
73 : else
74 : {
75 519479 : ChgValue( *m_pIndexReg->m_pFirst, nIdx );
76 : }
77 36829194 : }
78 :
79 26217376 : SwIndex& SwIndex::ChgValue( const SwIndex& rIdx, sal_Int32 nNewValue )
80 : {
81 : assert(m_pIndexReg == rIdx.m_pIndexReg);
82 26217376 : if (!m_pIndexReg)
83 : {
84 23410079 : m_nIndex = 0;
85 23410079 : return *this; // no IndexReg => no list to sort into; m_nIndex is 0
86 : }
87 2807297 : SwIndex* pFnd = const_cast<SwIndex*>(&rIdx);
88 2807297 : if (rIdx.m_nIndex > nNewValue) // move forwards
89 : {
90 : SwIndex* pPrv;
91 1494582 : while ((0 != (pPrv = pFnd->m_pPrev)) && (pPrv->m_nIndex > nNewValue))
92 1103002 : pFnd = pPrv;
93 :
94 195790 : if( pFnd != this )
95 : {
96 : // remove from list at old position
97 151365 : Remove();
98 :
99 151365 : m_pNext = pFnd;
100 151365 : m_pPrev = pFnd->m_pPrev;
101 151365 : if (m_pPrev)
102 32797 : m_pPrev->m_pNext = this;
103 : else
104 118568 : m_pIndexReg->m_pFirst = this;
105 151365 : pFnd->m_pPrev = this;
106 : }
107 : }
108 2611507 : else if (rIdx.m_nIndex < nNewValue)
109 : {
110 : SwIndex* pNxt;
111 7678470 : while ((0 != (pNxt = pFnd->m_pNext)) && (pNxt->m_nIndex < nNewValue))
112 7351266 : pFnd = pNxt;
113 :
114 163602 : if( pFnd != this )
115 : {
116 : // remove from list at old position
117 105385 : Remove();
118 :
119 105385 : m_pPrev = pFnd;
120 105385 : m_pNext = pFnd->m_pNext;
121 105385 : if (m_pNext)
122 54448 : m_pNext->m_pPrev = this;
123 : else
124 50937 : m_pIndexReg->m_pLast = this;
125 105385 : pFnd->m_pNext = this;
126 : }
127 : }
128 2447905 : else if( pFnd != this )
129 : {
130 : // remove from list at old position
131 2438944 : Remove();
132 :
133 2438944 : m_pPrev = pFnd; // == &rIdx here
134 2438944 : m_pNext = rIdx.m_pNext;
135 2438944 : m_pPrev->m_pNext = this;
136 :
137 2438944 : if (!m_pNext) // last in the list
138 1317691 : m_pIndexReg->m_pLast = this;
139 : else
140 1121253 : m_pNext->m_pPrev = this;
141 : }
142 :
143 2807297 : if (m_pIndexReg->m_pFirst == m_pNext)
144 0 : m_pIndexReg->m_pFirst = this;
145 2807297 : if (m_pIndexReg->m_pLast == m_pPrev)
146 0 : m_pIndexReg->m_pLast = this;
147 :
148 2807297 : m_nIndex = nNewValue;
149 :
150 2807297 : return *this;
151 : }
152 :
153 64848130 : void SwIndex::Remove()
154 : {
155 64848130 : if (!m_pIndexReg)
156 : {
157 : assert(!m_pPrev && !m_pNext);
158 112739658 : return;
159 : }
160 :
161 16956602 : if (m_pPrev)
162 : {
163 2398475 : m_pPrev->m_pNext = m_pNext;
164 : }
165 14558127 : else if (m_pIndexReg->m_pFirst == this)
166 : {
167 12058208 : m_pIndexReg->m_pFirst = m_pNext;
168 : }
169 :
170 16956602 : if (m_pNext)
171 : {
172 1782051 : m_pNext->m_pPrev = m_pPrev;
173 : }
174 15174551 : else if (m_pIndexReg->m_pLast == this)
175 : {
176 12674632 : m_pIndexReg->m_pLast = m_pPrev;
177 : }
178 : }
179 :
180 647695 : SwIndex& SwIndex::operator=( const SwIndex& rIdx )
181 : {
182 : bool bEqual;
183 647695 : if (rIdx.m_pIndexReg != m_pIndexReg) // unregister!
184 : {
185 456870 : Remove();
186 456870 : m_pIndexReg = rIdx.m_pIndexReg;
187 456870 : m_pNext = m_pPrev = 0;
188 456870 : bEqual = false;
189 : }
190 : else
191 190825 : bEqual = rIdx.m_nIndex == m_nIndex;
192 :
193 647695 : if( !bEqual )
194 510556 : ChgValue( rIdx, rIdx.m_nIndex );
195 647695 : return *this;
196 : }
197 :
198 1154261 : SwIndex& SwIndex::Assign( SwIndexReg* pArr, sal_Int32 nIdx )
199 : {
200 1154261 : if (pArr != m_pIndexReg) // unregister!
201 : {
202 484949 : Remove();
203 484949 : m_pIndexReg = pArr;
204 484949 : m_pNext = m_pPrev = 0;
205 484949 : Init(nIdx);
206 : }
207 669312 : else if (m_nIndex != nIdx)
208 : {
209 90097 : ChgValue( *this, nIdx );
210 : }
211 1154261 : return *this;
212 : }
213 :
214 170980 : void SwIndex::SetMark(const sw::mark::IMark* pMark)
215 : {
216 170980 : m_pMark = pMark;
217 170980 : }
218 :
219 218116 : SwIndexReg::SwIndexReg()
220 218116 : : m_pFirst( 0 ), m_pLast( 0 )
221 : {
222 218116 : }
223 :
224 217274 : SwIndexReg::~SwIndexReg()
225 : {
226 : assert(!m_pFirst && !m_pLast && "There are still indices registered");
227 217274 : }
228 :
229 161106 : void SwIndexReg::Update(
230 : SwIndex const & rIdx,
231 : const sal_Int32 nDiff,
232 : const bool bNeg,
233 : const bool /* argument is only used in derived class*/ )
234 : {
235 161106 : SwIndex* pStt = const_cast<SwIndex*>(&rIdx);
236 161106 : const sal_Int32 nNewVal = rIdx.m_nIndex;
237 161106 : if( bNeg )
238 : {
239 6918 : const sal_Int32 nLast = rIdx.GetIndex() + nDiff;
240 24672 : while (pStt && pStt->m_nIndex == nNewVal)
241 : {
242 10836 : pStt->m_nIndex = nNewVal;
243 10836 : pStt = pStt->m_pPrev;
244 : }
245 6918 : pStt = rIdx.m_pNext;
246 33627 : while (pStt && pStt->m_nIndex >= nNewVal
247 20558 : && pStt->m_nIndex <= nLast)
248 : {
249 19791 : pStt->m_nIndex = nNewVal;
250 19791 : pStt = pStt->m_pNext;
251 : }
252 156990 : while( pStt )
253 : {
254 143154 : pStt->m_nIndex = pStt->m_nIndex - nDiff;
255 143154 : pStt = pStt->m_pNext;
256 : }
257 : }
258 : else
259 : {
260 559788 : while (pStt && pStt->m_nIndex == nNewVal)
261 : {
262 251412 : pStt->m_nIndex = pStt->m_nIndex + nDiff;
263 251412 : pStt = pStt->m_pPrev;
264 : }
265 154188 : pStt = rIdx.m_pNext;
266 1013312 : while( pStt )
267 : {
268 704936 : pStt->m_nIndex = pStt->m_nIndex + nDiff;
269 704936 : pStt = pStt->m_pNext;
270 : }
271 : }
272 161106 : }
273 :
274 161106 : void SwIndexReg::MoveTo( SwIndexReg& rArr )
275 : {
276 161106 : if (this != &rArr && m_pFirst)
277 : {
278 12725 : SwIndex * pIdx = const_cast<SwIndex*>(m_pFirst);
279 : SwIndex * pNext;
280 43102 : while( pIdx )
281 : {
282 17652 : pNext = pIdx->m_pNext;
283 17652 : pIdx->Assign( &rArr, pIdx->GetIndex() );
284 17652 : pIdx = pNext;
285 : }
286 12725 : m_pFirst = 0, m_pLast = 0;
287 : }
288 161106 : }
289 :
290 : #ifdef DBG_UTIL
291 :
292 : // SwIndex
293 :
294 : sal_Int32 SwIndex::operator++(int)
295 : {
296 : SAL_WARN_IF( !(m_nIndex < SAL_MAX_INT32), "sw.core",
297 : "SwIndex::operator++(int) wraps around" );
298 :
299 : const sal_Int32 nOldIndex = m_nIndex;
300 : ChgValue( *this, m_nIndex+1 );
301 : return nOldIndex;
302 : }
303 :
304 : sal_Int32 SwIndex::operator++()
305 : {
306 : SAL_WARN_IF( !(m_nIndex < SAL_MAX_INT32), "sw.core",
307 : "SwIndex::operator++() wraps around" );
308 :
309 : ChgValue( *this, m_nIndex+1 );
310 : return m_nIndex;
311 : }
312 :
313 : sal_Int32 SwIndex::operator--(int)
314 : {
315 : SAL_WARN_IF( !(m_nIndex > 0), "sw.core",
316 : "SwIndex::operator--(int) wraps around" );
317 :
318 : const sal_Int32 nOldIndex = m_nIndex;
319 : ChgValue( *this, m_nIndex-1 );
320 : return nOldIndex;
321 : }
322 :
323 : sal_Int32 SwIndex::operator--()
324 : {
325 : SAL_WARN_IF( !( m_nIndex > 0), "sw.core",
326 : "SwIndex::operator--() wraps around" );
327 : return ChgValue( *this, m_nIndex-1 ).m_nIndex;
328 : }
329 :
330 : sal_Int32 SwIndex::operator+=( sal_Int32 const nVal )
331 : {
332 : SAL_WARN_IF( !(m_nIndex <= SAL_MAX_INT32 - nVal), "sw.core",
333 : "SwIndex SwIndex::operator+=(sal_Int32) wraps around" );
334 : return ChgValue( *this, m_nIndex + nVal ).m_nIndex;
335 : }
336 :
337 : sal_Int32 SwIndex::operator-=( sal_Int32 const nVal )
338 : {
339 : SAL_WARN_IF( !(m_nIndex >= nVal), "sw.core",
340 : "SwIndex::operator-=(sal_Int32) wraps around" );
341 : return ChgValue( *this, m_nIndex - nVal ).m_nIndex;
342 : }
343 :
344 : sal_Int32 SwIndex::operator+=( const SwIndex & rIndex )
345 : {
346 : SAL_WARN_IF( !(m_nIndex <= SAL_MAX_INT32 - rIndex.m_nIndex), "sw.core",
347 : "SwIndex::operator+=(SwIndex) wraps around" );
348 : return ChgValue( *this, m_nIndex + rIndex.m_nIndex ).m_nIndex;
349 : }
350 :
351 : sal_Int32 SwIndex::operator-=( const SwIndex & rIndex )
352 : {
353 : SAL_WARN_IF( !(m_nIndex >= rIndex.m_nIndex), "sw.core",
354 : "SwIndex::operator-=(SwIndex) wraps around" );
355 : return ChgValue( *this, m_nIndex - rIndex.m_nIndex ).m_nIndex;
356 : }
357 :
358 : bool SwIndex::operator< ( const SwIndex & rIndex ) const
359 : {
360 : // Attempt to compare indices into different arrays
361 : assert(m_pIndexReg == rIndex.m_pIndexReg);
362 : return m_nIndex < rIndex.m_nIndex;
363 : }
364 :
365 : bool SwIndex::operator<=( const SwIndex & rIndex ) const
366 : {
367 : // Attempt to compare indices into different arrays
368 : assert(m_pIndexReg == rIndex.m_pIndexReg);
369 : return m_nIndex <= rIndex.m_nIndex;
370 : }
371 :
372 : bool SwIndex::operator> ( const SwIndex & rIndex ) const
373 : {
374 : // Attempt to compare indices into different arrays
375 : assert(m_pIndexReg == rIndex.m_pIndexReg);
376 : return m_nIndex > rIndex.m_nIndex;
377 : }
378 :
379 : bool SwIndex::operator>=( const SwIndex & rIndex ) const
380 : {
381 : // Attempt to compare indices into different arrays
382 : assert(m_pIndexReg == rIndex.m_pIndexReg);
383 : return m_nIndex >= rIndex.m_nIndex;
384 : }
385 :
386 : SwIndex& SwIndex::operator= ( sal_Int32 const nVal )
387 : {
388 : if (m_nIndex != nVal)
389 : ChgValue( *this, nVal );
390 :
391 : return *this;
392 : }
393 :
394 : #endif
395 :
396 0 : std::ostream& operator <<(std::ostream& s, const SwIndex& index)
397 : {
398 0 : return s << "SwIndex offset (" << index.GetIndex() << ")";
399 177 : }
400 :
401 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|