/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sw.hxx" #include // fuer qsort #include #include "index.hxx" #if OSL_DEBUG_LEVEL > 1 int SwIndex::nSerial = 0; #endif TYPEINIT0(SwIndexReg); // rtti SwIndex::SwIndex(SwIndexReg *const pArr, xub_StrLen const nIdx) : nIndex( nIdx ), pArray( pArr ), pNext( 0 ), pPrev( 0 ) { if( !pArray ) { pArray = SwIndexReg::pEmptyIndexArray; nIndex = 0; // steht immer auf 0 !!! } if( !pArray->pFirst || !pArray->pLast ) // 1. Index ?? pArray->pFirst = pArray->pLast = this; else if( nIdx > ((pArray->pLast->nIndex - pArray->pFirst->nIndex) / 2) ) ChgValue( *pArray->pLast, nIdx ); else ChgValue( *pArray->pFirst, nIdx ); #if OSL_DEBUG_LEVEL > 1 MySerial = ++nSerial; // nur in der nicht PRODUCT-Version #endif } SwIndex::SwIndex( const SwIndex& rIdx, short nIdx ) : pArray( rIdx.pArray ), pNext( 0 ), pPrev( 0 ) { ChgValue( rIdx, rIdx.nIndex + nIdx ); #if OSL_DEBUG_LEVEL > 1 MySerial = ++nSerial; // nur in der nicht PRODUCT-Version #endif } SwIndex::SwIndex( const SwIndex& rIdx ) : nIndex( rIdx.nIndex ), pArray( rIdx.pArray ), pNext( 0 ), pPrev( 0 ) { ChgValue( rIdx, rIdx.nIndex ); #if OSL_DEBUG_LEVEL > 1 MySerial = ++nSerial; // nur in der nicht PRODUCT-Version #endif } SwIndex& SwIndex::ChgValue( const SwIndex& rIdx, xub_StrLen nNewValue ) { SwIndex* pFnd = (SwIndex*)&rIdx; if( rIdx.nIndex > nNewValue ) // nach vorne versuchen { SwIndex* pPrv; while( 0 != ( pPrv = pFnd->pPrev ) && pPrv->nIndex > nNewValue ) pFnd = pPrv; if( pFnd != this ) { // an alter Position ausketten // erstmal an alter Position ausketten if( pPrev ) pPrev->pNext = pNext; else if( pArray->pFirst == this ) pArray->pFirst = pNext; if( pNext ) pNext->pPrev = pPrev; else if( pArray->pLast == this ) pArray->pLast = pPrev; pNext = pFnd; pPrev = pFnd->pPrev; if( pPrev ) pPrev->pNext = this; else pArray->pFirst = this; pFnd->pPrev = this; } } else if( rIdx.nIndex < nNewValue ) { SwIndex* pNxt; while( 0 != ( pNxt = pFnd->pNext ) && pNxt->nIndex < nNewValue ) pFnd = pNxt; if( pFnd != this ) { // erstmal an alter Position ausketten if( pPrev ) pPrev->pNext = pNext; else if( pArray->pFirst == this ) pArray->pFirst = pNext; if( pNext ) pNext->pPrev = pPrev; else if( pArray->pLast == this ) pArray->pLast = pPrev; pPrev = pFnd; pNext = pFnd->pNext; if( pNext ) pNext->pPrev = this; else pArray->pLast = this; pFnd->pNext = this; } } else if( pFnd != this ) { // erstmal an alter Position ausketten if( pPrev ) pPrev->pNext = pNext; else if( pArray->pFirst == this ) pArray->pFirst = pNext; if( pNext ) pNext->pPrev = pPrev; else if( pArray->pLast == this ) pArray->pLast = pPrev; pPrev = (SwIndex*)&rIdx; pNext = rIdx.pNext; pPrev->pNext = this; if( !pNext ) // im IndexArray als letzes pArray->pLast = this; else pNext->pPrev = this; } pArray = rIdx.pArray; if( pArray->pFirst == pNext ) pArray->pFirst = this; if( pArray->pLast == pPrev ) pArray->pLast = this; nIndex = nNewValue; return *this; } void SwIndex::Remove() { if( !pPrev ) pArray->pFirst = pNext; else pPrev->pNext = pNext; if( !pNext ) pArray->pLast = pPrev; else pNext->pPrev = pPrev; } /************************************************************************* |* SwIndex & SwIndex::operator=( const SwIndex & aSwIndex ) *************************************************************************/ SwIndex& SwIndex::operator=( const SwIndex& rIdx ) { int bEqual; if( rIdx.pArray != pArray ) // im alten abmelden !! { Remove(); pArray = rIdx.pArray; pNext = pPrev = 0; bEqual = sal_False; } else bEqual = rIdx.nIndex == nIndex; if( !bEqual ) ChgValue( rIdx, rIdx.nIndex ); return *this; } /************************************************************************* |* SwIndex &SwIndex::Assign *************************************************************************/ SwIndex& SwIndex::Assign( SwIndexReg* pArr, xub_StrLen nIdx ) { if( !pArr ) { pArr = SwIndexReg::pEmptyIndexArray; nIdx = 0; // steht immer auf 0 !!! } if( pArr != pArray ) // im alten abmelden !! { Remove(); pArray = pArr; pNext = pPrev = 0; if( !pArr->pFirst ) // 1. Index ?? { pArr->pFirst = pArr->pLast = this; nIndex = nIdx; } else if( pArr->pLast && (nIdx > ((pArr->pLast->nIndex - pArr->pFirst->nIndex) / 2)) ) ChgValue( *pArr->pLast, nIdx ); else ChgValue( *pArr->pFirst, nIdx ); } else if( nIndex != nIdx ) ChgValue( *this, nIdx ); return *this; } SwIndexReg::SwIndexReg() : pFirst( 0 ), pLast( 0 ) { } SwIndexReg::~SwIndexReg() { OSL_ENSURE( !pFirst || !pLast, "Es sind noch Indizies angemeldet" ); } void SwIndexReg::Update( SwIndex const & rIdx, const xub_StrLen nDiff, const bool bNeg, const bool /* argument is only used in derived class*/ ) { SwIndex* pStt = const_cast(&rIdx); xub_StrLen nNewVal = rIdx.nIndex; if( bNeg ) { xub_StrLen nLast = rIdx.GetIndex() + nDiff; while( pStt && pStt->nIndex == nNewVal ) { pStt->nIndex = nNewVal; pStt = pStt->pPrev; } pStt = rIdx.pNext; while( pStt && pStt->nIndex >= nNewVal && pStt->nIndex <= nLast ) { pStt->nIndex = nNewVal; pStt = pStt->pNext; } while( pStt ) { pStt->nIndex = pStt->nIndex - nDiff; pStt = pStt->pNext; } } else { while( pStt && pStt->nIndex == nNewVal ) { pStt->nIndex = pStt->nIndex + nDiff; pStt = pStt->pPrev; } pStt = rIdx.pNext; while( pStt ) { pStt->nIndex = pStt->nIndex + nDiff; pStt = pStt->pNext; } } } #if OSL_DEBUG_LEVEL > 1 /************************************************************************* |* SwIndex::operator++() *************************************************************************/ xub_StrLen SwIndex::operator++(int) { OSL_ASSERT( nIndex < INVALID_INDEX ); xub_StrLen nOldIndex = nIndex; ChgValue( *this, nIndex+1 ); return nOldIndex; } xub_StrLen SwIndex::operator++() { OSL_ASSERT( nIndex < INVALID_INDEX ); ChgValue( *this, nIndex+1 ); return nIndex; } /************************************************************************* |* SwIndex::operator--() *************************************************************************/ xub_StrLen SwIndex::operator--(int) { OSL_ASSERT( nIndex ); xub_StrLen nOldIndex = nIndex; ChgValue( *this, nIndex-1 ); return nOldIndex; } xub_StrLen SwIndex::operator--() { OSL_ASSERT( nIndex ); return ChgValue( *this, nIndex-1 ).nIndex; } /************************************************************************* |* SwIndex::operator+=( xub_StrLen ) *************************************************************************/ xub_StrLen SwIndex::operator+=( xub_StrLen nWert ) { OSL_ASSERT( nIndex < INVALID_INDEX - nWert ); return ChgValue( *this, nIndex + nWert ).nIndex; } /************************************************************************* |* SwIndex::operator-=( xub_StrLen ) *************************************************************************/ xub_StrLen SwIndex::operator-=( xub_StrLen nWert ) { OSL_ASSERT( nIndex >= nWert ); return ChgValue( *this, nIndex - nWert ).nIndex; } /************************************************************************* |* SwIndex::operator+=( const SwIndex & ) *************************************************************************/ xub_StrLen SwIndex::operator+=( const SwIndex & rIndex ) { OSL_ASSERT( nIndex < INVALID_INDEX - rIndex.nIndex ); return ChgValue( *this, nIndex + rIndex.nIndex ).nIndex; } /************************************************************************* |* SwIndex::operator-=( const SwIndex & ) *************************************************************************/ xub_StrLen SwIndex::operator-=( const SwIndex & rIndex ) { OSL_ASSERT( nIndex >= rIndex.nIndex ); return ChgValue( *this, nIndex - rIndex.nIndex ).nIndex; } /************************************************************************* |* SwIndex::operator<( const SwIndex & ) *************************************************************************/ sal_Bool SwIndex::operator<( const SwIndex & rIndex ) const { OSL_ENSURE( pArray == rIndex.pArray, "Attempt to compare indices into different arrays."); return nIndex < rIndex.nIndex; } /************************************************************************* |* SwIndex::operator<=( const SwIndex & ) *************************************************************************/ sal_Bool SwIndex::operator<=( const SwIndex & rIndex ) const { OSL_ENSURE( pArray == rIndex.pArray, "Attempt to compare indices into different arrays."); return nIndex <= rIndex.nIndex; } /************************************************************************* |* SwIndex::operator>( const SwIndex & ) *************************************************************************/ sal_Bool SwIndex::operator>( const SwIndex & rIndex ) const { OSL_ENSURE( pArray == rIndex.pArray, "Attempt to compare indices into different arrays."); return nIndex > rIndex.nIndex; } /************************************************************************* |* SwIndex::operator>=( const SwIndex & ) *************************************************************************/ sal_Bool SwIndex::operator>=( const SwIndex & rIndex ) const { OSL_ENSURE( pArray == rIndex.pArray, "Attempt to compare indices into different arrays."); return nIndex >= rIndex.nIndex; } /************************************************************************* |* SwIndex & SwIndex::operator=( xub_StrLen ) *************************************************************************/ SwIndex& SwIndex::operator=( xub_StrLen nWert ) { // Werte kopieren und im neuen Array anmelden if( nIndex != nWert ) ChgValue( *this, nWert ); return *this; } #endif // ifndef PRODUCT void SwIndexReg::MoveTo( SwIndexReg& rArr ) { if( this != &rArr && pFirst ) { SwIndex* pIdx = (SwIndex*)pFirst, *pNext; while( pIdx ) { pNext = pIdx->pNext; pIdx->Assign( &rArr, pIdx->GetIndex() ); pIdx = pNext; } pFirst = 0, pLast = 0; } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */