diff options
Diffstat (limited to 'binfilter/bf_sw/source/core/bastyp/sw_bparr.cxx')
-rw-r--r-- | binfilter/bf_sw/source/core/bastyp/sw_bparr.cxx | 586 |
1 files changed, 586 insertions, 0 deletions
diff --git a/binfilter/bf_sw/source/core/bastyp/sw_bparr.cxx b/binfilter/bf_sw/source/core/bastyp/sw_bparr.cxx new file mode 100644 index 000000000000..ee680a7532c6 --- /dev/null +++ b/binfilter/bf_sw/source/core/bastyp/sw_bparr.cxx @@ -0,0 +1,586 @@ +/* -*- 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <string.h> +#include <limits.h> +#include "bparr.hxx" +namespace binfilter { + +// die Blockverwaltung waechst/schrumpft immer um 20 Bloecke, das sind dann +// immer ~ 20 * MAXENTRY == 20000 Eintraege +const USHORT nBlockGrowSize = 20; + +#ifndef DBG_UTIL + +#define CHECKIDX( p, n, i, c ) + +#else + +#define CHECKIDX( p, n, i, c ) CheckIdx( p, n, i, c ); + +/*N*/ void CheckIdx( BlockInfo** ppInf, USHORT nBlock, ULONG nSize, USHORT nCur ) +/*N*/ { +/*N*/ DBG_ASSERT( !nSize || nCur < nBlock, "BigPtrArray: CurIndex steht falsch" ); +/*N*/ +/*N*/ ULONG nIdx = 0; +/*N*/ for( USHORT nCnt = 0; nCnt < nBlock; ++nCnt, ++ppInf ) +/*N*/ { +/*N*/ nIdx += (*ppInf)->nElem; +/*N*/ // Array mit Luecken darf es nicht geben +/*N*/ DBG_ASSERT( !nCnt || (*(ppInf-1))->nEnd + 1 == (*ppInf)->nStart, +/*N*/ "BigPtrArray: Luecke in der Verwaltung!" ); +/*N*/ } +/*N*/ +/*N*/ DBG_ASSERT( nIdx == nSize, "BigPtrArray: Anzahl ungueltig" ); +/*N*/ } + +#endif + + +/*N*/ BigPtrArray::BigPtrArray() +/*N*/ { +/*N*/ nBlock = nCur = 0; +/*N*/ nSize = 0; +/*N*/ nMaxBlock = nBlockGrowSize; // == 20 * 1000 Eintraege +/*N*/ ppInf = new BlockInfo* [ nMaxBlock ]; +/*N*/ } + + + +/*N*/ BigPtrArray::~BigPtrArray() +/*N*/ { +/*N*/ if( nBlock ) +/*N*/ { +/*N*/ BlockInfo** pp = ppInf; +/*N*/ for( USHORT n = 0; n < nBlock; ++n, ++pp ) +/*N*/ { +/*N*/ delete[] (*pp)->pData; +/*N*/ delete *pp; +/*N*/ } +/*N*/ } +/*N*/ delete[] ppInf; +/*N*/ } + +// Einfachst-Implementation, evtl. spaeter mal komplexer +#if 0 +#endif + +// Auch der Move ist schlicht. Optimieren ist hier wg. der +// Stueckelung des Feldes zwecklos! + + +// das Ende ist EXCLUSIV + + +/*N*/ void BigPtrArray::ForEach( ULONG nStart, ULONG nEnd, +/*N*/ FnForEach fn, void* pArgs ) +/*N*/ { +/*N*/ if( nEnd > nSize ) +/*N*/ nEnd = nSize; +/*N*/ +/*N*/ if( nStart < nEnd ) +/*N*/ { +/*N*/ USHORT cur = Index2Block( nStart ); +/*N*/ BlockInfo** pp = ppInf + cur; +/*N*/ BlockInfo* p = *pp; +/*N*/ USHORT nElem = USHORT( nStart - p->nStart ); +/*N*/ ElementPtr* pElem = p->pData + nElem; +/*N*/ nElem = p->nElem - nElem; +/*N*/ for(;;) +/*N*/ { +/*N*/ if( !(*fn)( *pElem++, pArgs ) || ++nStart >= nEnd ) +/*N*/ break; +/*N*/ +/*N*/ // naechstes Element +/*N*/ if( !--nElem ) +/*N*/ { +/*N*/ // neuer Block +/*N*/ p = *++pp; +/*N*/ pElem = p->pData; +/*N*/ nElem = p->nElem; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ ElementPtr BigPtrArray::operator[]( ULONG idx ) const +/*N*/ { +/*N*/ // weil die Funktion eben doch nicht const ist: +/*N*/ DBG_ASSERT( idx < nSize, "operator[]: Index aussserhalb" ); +/*N*/ BigPtrArray* pThis = (BigPtrArray*) this; +/*N*/ USHORT cur = Index2Block( idx ); +/*N*/ BlockInfo* p = ppInf[ cur ]; +/*N*/ pThis->nCur = cur; +/*N*/ return p->pData[ idx - p->nStart ]; +/*N*/ } + +/////////////////////////////////////////////////////////////////////////// + +// private Methoden + +// Suchen des Blocks einer bestimmten Position +// Algorithmus: +// 1. Test, ob der letzte Block der gesuchte Block ist +// 2. Sonderfall: Index = 0? +// 3. Test der Nachbarbloecke + +// 4. Binaere Suche + + + +/*N*/ USHORT BigPtrArray::Index2Block( ULONG pos ) const +/*N*/ { +/*N*/ // zuletzt verwendeter Block? +/*N*/ BlockInfo* p = ppInf[ nCur ]; +/*N*/ if( p->nStart <= pos && p->nEnd >= pos ) +/*N*/ return nCur; +/*N*/ // Index = 0? +/*N*/ if( !pos ) +/*N*/ return 0; +/*N*/ // Folgeblock? +/*N*/ if( nCur < ( nBlock - 1 ) ) +/*N*/ { +/*N*/ p = ppInf[ nCur+1 ]; +/*N*/ if( p->nStart <= pos && p->nEnd >= pos ) +/*N*/ return nCur+1; +/*N*/ } +/*N*/ // vorangehender Block? +/*N*/ else if( pos < p->nStart && nCur > 0 ) +/*N*/ { +/*N*/ p = ppInf[ nCur-1 ]; +/*N*/ if( p->nStart <= pos && p->nEnd >= pos ) +/*N*/ return nCur-1; +/*N*/ } +/*N*/ // Binaere Suche: +/*N*/ // Diese fuehrt immer zum Erfolg +/*N*/ USHORT lower = 0, upper = nBlock - 1; +/*N*/ USHORT cur = 0; +/*N*/ for(;;) +/*N*/ { +/*N*/ USHORT n = lower + ( upper - lower ) / 2; +/*N*/ cur = ( n == cur ) ? n+1 : n; +/*N*/ p = ppInf[ cur ]; +/*N*/ if( p->nStart <= pos && p->nEnd >= pos ) +/*N*/ return cur; +/*N*/ if( p->nStart > pos ) +/*N*/ upper = cur; +/*N*/ else +/*N*/ lower = cur; +/*N*/ } +/*N*/ } + + +// Update aller Indexbereiche ab einer bestimmten Position + +// pos bezeichnet den letzten korrekten Block + +/*N*/ void BigPtrArray::UpdIndex( USHORT pos ) +/*N*/ { +/*N*/ BlockInfo** pp = ppInf + pos; +/*N*/ ULONG idx = (*pp)->nEnd + 1; +/*N*/ BlockInfo* p; +/*N*/ while( ++pos < nBlock ) +/*N*/ { +/*N*/ p = *++pp; +/*N*/ p->nStart = idx; +/*N*/ idx += p->nElem; +/*N*/ p->nEnd = idx - 1; +/*N*/ } +/*N*/ } + +// Einrichten eines neuen Blocks an einer bestimmten Position + +// Vorhandene Blocks werden nach hinten verschoben + + + +/*N*/ BlockInfo* BigPtrArray::InsBlock( USHORT pos ) +/*N*/ { +/*N*/ if( nBlock == nMaxBlock ) +/*N*/ { +/*N*/ // dann sollte wir mal das Array erweitern +/*N*/ BlockInfo** ppNew = new BlockInfo* [ nMaxBlock + nBlockGrowSize ]; +/*N*/ memcpy( ppNew, ppInf, nMaxBlock * sizeof( BlockInfo* )); +/*N*/ delete[] ppInf; +/*N*/ nMaxBlock += nBlockGrowSize; +/*N*/ ppInf = ppNew; +/*N*/ } +/*N*/ if( pos != nBlock ) +/*N*/ memmove( ppInf + pos+1, ppInf + pos , +/*N*/ ( nBlock - pos ) * sizeof (BlockInfo*) ); +/*N*/ ++nBlock; +/*N*/ BlockInfo* p = new BlockInfo; +/*N*/ ppInf[ pos ] = p; +/*N*/ +/*N*/ if( pos ) +/*N*/ p->nStart = p->nEnd = ppInf[ pos-1 ]->nEnd + 1; +/*N*/ else +/*N*/ p->nStart = p->nEnd = 0; +/*N*/ p->nEnd--; // keine Elemente +/*N*/ p->nElem = 0; +/*N*/ p->pData = new ElementPtr [ MAXENTRY ]; +/*N*/ p->pBigArr = this; +/*N*/ return p; +/*N*/ } + +/*N*/ void BigPtrArray::BlockDel( USHORT nDel ) +/*N*/ { +/*N*/ nBlock -= nDel; +/*N*/ if( nMaxBlock - nBlock > nBlockGrowSize ) +/*N*/ { +/*N*/ // dann koennen wir wieder schrumpfen +/*N*/ nDel = (( nBlock / nBlockGrowSize ) + 1 ) * nBlockGrowSize; +/*N*/ BlockInfo** ppNew = new BlockInfo* [ nDel ]; +/*N*/ memcpy( ppNew, ppInf, nBlock * sizeof( BlockInfo* )); +/*N*/ delete[] ppInf; +/*N*/ ppInf = ppNew; +/*N*/ nMaxBlock = nDel; +/*N*/ } +/*N*/ } + + +/*N*/ void BigPtrArray::Insert( const ElementPtr& rElem, ULONG pos ) +/*N*/ { +/*N*/ CHECKIDX( ppInf, nBlock, nSize, nCur ); +/*N*/ +/*N*/ BlockInfo* p; +/*N*/ USHORT cur; +/*N*/ if( !nSize ) +/*N*/ // Sonderfall: erstes Element einfuegen +/*N*/ p = InsBlock( cur = 0 ); +/*N*/ else if( pos == nSize ) +/*N*/ { +/*N*/ // Sonderfall: Einfuegen am Ende +/*N*/ cur = nBlock - 1; +/*N*/ p = ppInf[ cur ]; +/*N*/ if( p->nElem == MAXENTRY ) +/*N*/ // Der letzte Block ist voll, neuen anlegen +/*?*/ p = InsBlock( ++cur ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Standardfall: +/*N*/ cur = Index2Block( pos ); +/*N*/ p = ppInf[ cur ]; +/*N*/ } +/*N*/ if( p->nElem == MAXENTRY ) +/*N*/ { +/*N*/ // passt der letzte Eintrag in den naechsten Block? +/*N*/ BlockInfo* q; +/*N*/ if( cur < ( nBlock - 1 ) && ppInf[ cur+1 ]->nElem < MAXENTRY ) +/*N*/ { +/*N*/ q = ppInf[ cur+1 ]; +/*N*/ if( q->nElem ) +/*N*/ { +/*N*/ register int nCount = q->nElem; +/*N*/ register ElementPtr *pFrom = q->pData + nCount, +/*N*/ *pTo = pFrom+1; +/*N*/ while( nCount-- ) +/*N*/ ++( *--pTo = *--pFrom )->nOffset; +/*N*/ } +/*N*/ q->nStart--; +/*N*/ q->nEnd--; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Wenn er auch nicht in den Folgeblock passt, muss ein +/*N*/ // neuer Block eingefuegt werden +/*N*/ // erst mal bei Bedarf komprimieren +/*N*/ +/*N*/ // wenn mehr als 50% "Luft" im Array ist, dann sollte man mal das +/*N*/ // Compress aufrufen +/*N*/ if( /*nBlock == nMaxBlock &&*/ +/*N*/ nBlock > ( nSize / ( MAXENTRY / 2 ) ) && +/*N*/ cur >= Compress() ) +/*N*/ { +/*N*/ // es wurde vor der akt. Pos etwas verschoben und alle +/*N*/ // Pointer koennen ungueltig sein. Also das Insert +/*N*/ // nochmals aufsetzen +/*?*/ Insert( rElem, pos ); +/*N*/ return ; +/*N*/ } +/*N*/ +/*N*/ q = InsBlock( cur+1 ); +/*N*/ } +/*N*/ +/*N*/ // Eintrag passt nicht mehr. Dann muss Platz gemacht werden +/*N*/ ElementPtr pLast = p->pData[ MAXENTRY-1 ]; +/*N*/ pLast->nOffset = 0; +/*N*/ pLast->pBlock = q; +/*N*/ +/*N*/ q->pData[ 0 ] = pLast; +/*N*/ q->nElem++; +/*N*/ q->nEnd++; +/*N*/ +/*N*/ p->nEnd--; +/*N*/ p->nElem--; +/*N*/ } +/*N*/ // Nun haben wir einen freien Block am Wickel: eintragen +/*N*/ pos -= p->nStart; +/*N*/ DBG_ASSERT( pos < MAXENTRY, "falsche Pos" ); +/*N*/ if( pos != p->nElem ) +/*N*/ { +/*N*/ register int nCount = p->nElem - USHORT(pos); +/*N*/ register ElementPtr *pFrom = p->pData + p->nElem, +/*N*/ *pTo = pFrom + 1; +/*N*/ while( nCount-- ) +/*N*/ ++( *--pTo = *--pFrom )->nOffset; +/*N*/ } +/*N*/ // Element eintragen und Indexe updaten +/*N*/ ((ElementPtr&)rElem)->nOffset = USHORT(pos); +/*N*/ ((ElementPtr&)rElem)->pBlock = p; +/*N*/ p->pData[ pos ] = rElem; +/*N*/ p->nEnd++; +/*N*/ p->nElem++; +/*N*/ nSize++; +/*N*/ if( cur != ( nBlock - 1 ) ) UpdIndex( cur ); +/*N*/ nCur = cur; +/*N*/ +/*N*/ CHECKIDX( ppInf, nBlock, nSize, nCur ); +/*N*/ } + +/*N*/ void BigPtrArray::Remove( ULONG pos, ULONG n ) +/*N*/ { +/*N*/ CHECKIDX( ppInf, nBlock, nSize, nCur ); +/*N*/ +/*N*/ USHORT nBlkdel = 0; // entfernte Bloecke +/*N*/ USHORT cur = Index2Block( pos ); // aktuelle Blocknr +/*N*/ USHORT nBlk1 = cur; // 1. behandelter Block +/*N*/ USHORT nBlk1del = USHRT_MAX; // 1. entfernter Block +/*N*/ BlockInfo* p = ppInf[ cur ]; +/*N*/ pos -= p->nStart; +/*N*/ ULONG nElem = n; +/*N*/ while( nElem ) +/*N*/ { +/*N*/ USHORT nel = p->nElem - USHORT(pos); +/*N*/ if( ULONG(nel) > nElem ) +/*N*/ nel = USHORT(nElem); +/*N*/ // Eventuell Elemente verschieben +/*N*/ if( ( pos + nel ) < ULONG(p->nElem) ) +/*N*/ { +/*N*/ register ElementPtr *pTo = p->pData + pos, +/*N*/ *pFrom = pTo + nel; +/*N*/ register int nCount = p->nElem - nel - USHORT(pos); +/*N*/ while( nCount-- ) +/*N*/ { +/*N*/ (*pTo++ = *pFrom++)->nOffset -= nel; +/*N*/ // (*pTo++)->nOffset -= nel; +/*N*/ } +/*N*/ } +/*N*/ p->nEnd -= nel; +/*N*/ p->nElem -= nel; +/*N*/ if( !p->nElem ) +/*N*/ { +/*N*/ // eventuell Block ganz entfernen +/*N*/ delete[] p->pData; +/*N*/ nBlkdel++; +/*N*/ if( USHRT_MAX == nBlk1del ) +/*N*/ nBlk1del = cur; +/*N*/ } +/*N*/ nElem -= nel; +/*N*/ if( !nElem ) +/*N*/ break; +/*N*/ p = ppInf[ ++cur ]; +/*N*/ pos = 0; +/*N*/ } +/*N*/ // Am Ende die Tabelle updaten, falls Bloecke geloescht waren +/*N*/ if( nBlkdel ) +/*N*/ { +/*N*/ // loeschen sollte man immer !! +/*N*/ for( USHORT i = nBlk1del; i < ( nBlk1del + nBlkdel ); i++ ) +/*N*/ delete ppInf[ i ]; +/*N*/ +/*N*/ if( ( nBlk1del + nBlkdel ) < nBlock ) +/*N*/ { +/*N*/ memmove( ppInf + nBlk1del, ppInf + nBlk1del + nBlkdel, +/*N*/ ( nBlock - nBlkdel - nBlk1del ) * sizeof( BlockInfo* ) ); +/*N*/ +/*N*/ // JP 19.07.95: nicht den ersten behandelten, sondern den davor!! +/*N*/ // UpdateIdx updatet nur alle Nachfolgende!! +/*N*/ if( !nBlk1 ) +/*N*/ { +/*N*/ p = ppInf[ 0 ]; +/*N*/ p->nStart = 0; +/*N*/ p->nEnd = p->nElem-1; +/*N*/ } +/*N*/ else +/*N*/ --nBlk1; +/*N*/ } +/*N*/ BlockDel( nBlkdel ); // es wurden Bloecke geloescht +/*N*/ } +/*N*/ +/*N*/ nSize -= n; +/*N*/ if( nBlk1 != ( nBlock - 1 ) && nSize ) +/*N*/ UpdIndex( nBlk1 ); +/*N*/ nCur = nBlk1; +/*N*/ +/*N*/ // wenn mehr als 50% "Luft" im Array ist, dann sollte man mal das +/*N*/ // Compress aufrufen +/*N*/ if( nBlock > ( nSize / ( MAXENTRY / 2 ) ) ) +/*N*/ Compress(); +/*N*/ +/*N*/ CHECKIDX( ppInf, nBlock, nSize, nCur ); +/*N*/ } + + +/*N*/ void BigPtrArray::Replace( ULONG idx, const ElementPtr& rElem) +/*N*/ { +/*N*/ // weil die Funktion eben doch nicht const ist: +/*N*/ DBG_ASSERT( idx < nSize, "Set: Index aussserhalb" ); +/*N*/ BigPtrArray* pThis = (BigPtrArray*) this; +/*N*/ USHORT cur = Index2Block( idx ); +/*N*/ BlockInfo* p = ppInf[ cur ]; +/*N*/ pThis->nCur = cur; +/*N*/ ((ElementPtr&)rElem)->nOffset = USHORT(idx - p->nStart); +/*N*/ ((ElementPtr&)rElem)->pBlock = p; +/*N*/ p->pData[ idx - p->nStart ] = rElem; +/*N*/ } + + +// Index eines Eintrags heraussuchen +// Dies ist der selbe Code wie in ForEach() mit dem Unterschied, +// dass statt einer Funktion ein Vergleich durchgefuehrt wird. +// Man haette auch ForEach() nehmen koennen, spart aber durch +// den fehlenden Call etwas Zeit. + + + +// Array komprimieren + +/*N*/ USHORT BigPtrArray::Compress( short nMax ) +/*N*/ { +/*N*/ CHECKIDX( ppInf, nBlock, nSize, nCur ); +/*N*/ +/*N*/ // Es wird von vorne nach hinten ueber das InfoBlock Array iteriert. +/*N*/ // Wenn zwischen durch Block gel”scht werden, dann mussen alle +/*N*/ // nachfolgenden verschoben werden. Dazu werden die Pointer pp und qq +/*N*/ // benutzt; wobei pp das "alte" Array, qq das "neue" Array ist. +/*N*/ BlockInfo** pp = ppInf, **qq = pp; +/*N*/ BlockInfo* p; +/*N*/ BlockInfo* pLast; // letzter nicht voller Block +/*N*/ USHORT nLast = 0; // fehlende Elemente +/*N*/ USHORT nBlkdel = 0; // Anzahl der geloeschte Bloecke +/*N*/ USHORT nFirstChgPos = USHRT_MAX; // ab welcher Pos gab es die 1. Aenderung? +/*N*/ +/*N*/ // von Fuell-Prozenten auf uebrige Eintrage umrechnen +/*N*/ nMax = MAXENTRY - (long) MAXENTRY * nMax / 100; +/*N*/ +/*N*/ for( USHORT cur = 0; cur < nBlock; ++cur ) +/*N*/ { +/*N*/ p = *pp++; +/*N*/ USHORT n = p->nElem; +/*N*/ // Testen, ob der noch nicht volle Block so gelassen wird +/*N*/ // dies ist der Fall, wenn der aktuelle Block gesplittet +/*N*/ // werden muesste, der noch nicht volle Block aber bereits +/*N*/ // ueber dem uebergebenen Break-Wert voll ist. In diesem +/*N*/ // Fall wird von einer weiteren Fuellung (die ja wegen dem +/*N*/ // zweifachen memmove() zeitaufwendig ist) abgesehen. +/*N*/ if( nLast && ( n > nLast ) && ( nLast < nMax ) ) +/*N*/ nLast = 0; +/*N*/ if( nLast ) +/*N*/ { +/*N*/ if( USHRT_MAX == nFirstChgPos ) +/*N*/ nFirstChgPos = cur; +/*N*/ +/*N*/ // ein nicht voller Block vorhanden: auffuellen +/*N*/ if( n > nLast ) +/*N*/ n = nLast; +/*N*/ +/*N*/ // Elemente uebertragen, vom akt. in den letzten +/*N*/ register ElementPtr* pElem = pLast->pData + pLast->nElem; +/*N*/ register ElementPtr* pFrom = p->pData; +/*N*/ for( register int nCount = n, nOff = pLast->nElem; +/*N*/ nCount; --nCount, ++pElem ) +/*N*/ *pElem = *pFrom++, +/*N*/ (*pElem)->pBlock = pLast, +/*N*/ (*pElem)->nOffset = nOff++; +/*N*/ +/*N*/ // korrigieren +/*N*/ pLast->nElem += n; +/*N*/ nLast -= n; +/*N*/ p->nElem -= n; +/*N*/ +/*N*/ // Ist der aktuelle Block dadurch leer geworden? +/*N*/ if( !p->nElem ) +/*N*/ { +/*N*/ // dann kann der entfernt werden +/*N*/ delete[] p->pData; +/*N*/ delete p, p = 0; +/*N*/ ++nBlkdel; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pElem = p->pData, pFrom = pElem + n; +/*N*/ register int nCount = p->nElem; +/*N*/ while( nCount-- ) +/*N*/ { +/*N*/ (*pElem++ = *pFrom++)->nOffset -= n; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( p ) // die Blockinfo wurde nicht geloescht +/*N*/ { +/*N*/ *qq++ = p; // dann setze sie an die richtige neue Position +/*N*/ +/*N*/ // eventuell den letzten halbvollen Block festhalten +/*N*/ if( !nLast && p->nElem < MAXENTRY ) +/*N*/ { +/*N*/ pLast = p; +/*N*/ nLast = MAXENTRY - p->nElem; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // Bloecke geloescht wurden, ggfs. das BlockInfo Array verkuerzen +/*N*/ if( nBlkdel ) +/*N*/ BlockDel( nBlkdel ); +/*N*/ +/*N*/ // Und neu durchindizieren +/*N*/ p = ppInf[ 0 ]; +/*N*/ p->nEnd = p->nElem - 1; +/*N*/ UpdIndex( 0 ); +/*N*/ +/*N*/ if( nCur >= nFirstChgPos ) +/*N*/ nCur = 0; +/*N*/ +/*N*/ CHECKIDX( ppInf, nBlock, nSize, nCur ); +/*N*/ +/*N*/ return nFirstChgPos; +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |