blob: 05bcd20dd360441660df67d0340fde9db6ea0a02 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sfx2.hxx"
#ifndef GCC
#endif
#include <sfx2/minarray.hxx>
// -----------------------------------------------------------------------
SfxPtrArr::SfxPtrArr( sal_uInt8 nInitSize, sal_uInt8 nGrowSize ):
nUsed( 0 ),
nGrow( nGrowSize ? nGrowSize : 1 ),
nUnused( nInitSize )
{
DBG_MEMTEST();
sal_uInt16 nMSCBug = nInitSize;
if ( nMSCBug > 0 )
pData = new void*[nMSCBug];
else
pData = 0;
}
// -----------------------------------------------------------------------
SfxPtrArr::SfxPtrArr( const SfxPtrArr& rOrig )
{
DBG_MEMTEST();
nUsed = rOrig.nUsed;
nGrow = rOrig.nGrow;
nUnused = rOrig.nUnused;
if ( rOrig.pData != 0 )
{
pData = new void*[nUsed+nUnused];
memcpy( pData, rOrig.pData, nUsed*sizeof(void*) );
}
else
pData = 0;
}
// -----------------------------------------------------------------------
SfxPtrArr::~SfxPtrArr()
{
DBG_MEMTEST();
delete [] pData;
}
// -----------------------------------------------------------------------
SfxPtrArr& SfxPtrArr::operator=( const SfxPtrArr& rOrig )
{
DBG_MEMTEST();
delete [] pData;
nUsed = rOrig.nUsed;
nGrow = rOrig.nGrow;
nUnused = rOrig.nUnused;
if ( rOrig.pData != 0 )
{
pData = new void*[nUsed+nUnused];
memcpy( pData, rOrig.pData, nUsed*sizeof(void*) );
}
else
pData = 0;
return *this;
}
// -----------------------------------------------------------------------
void SfxPtrArr::Append( void* aElem )
{
DBG_MEMTEST();
DBG_ASSERT( sal::static_int_cast< unsigned >(nUsed+1) < ( USHRT_MAX / sizeof(void*) ), "array too large" );
// musz das Array umkopiert werden?
if ( nUnused == 0 )
{
sal_uInt16 nNewSize = (nUsed == 1) ? (nGrow==1 ? 2 : nGrow) : nUsed+nGrow;
void** pNewData = new void*[nNewSize];
if ( pData )
{
DBG_ASSERT( nUsed <= nNewSize, "" );
memmove( pNewData, pData, sizeof(void*)*nUsed );
delete [] pData;
}
nUnused = sal::static_int_cast< sal_uInt8 >(nNewSize-nUsed);
pData = pNewData;
}
// jetzt hinten in den freien Raum schreiben
pData[nUsed] = aElem;
++nUsed;
--nUnused;
}
// -----------------------------------------------------------------------
sal_uInt16 SfxPtrArr::Remove( sal_uInt16 nPos, sal_uInt16 nLen )
{
DBG_MEMTEST();
// nLen adjustieren, damit nicht ueber das Ende hinaus geloescht wird
nLen = Min( (sal_uInt16)(nUsed-nPos), nLen );
// einfache Aufgaben erfordern einfache Loesungen!
if ( nLen == 0 )
return 0;
// bleibt vielleicht keiner uebrig
if ( (nUsed-nLen) == 0 )
{
delete [] pData;
pData = 0;
nUsed = 0;
nUnused = 0;
return nLen;
}
// feststellen, ob das Array dadurch physikalisch schrumpft...
if ( (nUnused+nLen) >= nGrow )
{
// auf die naechste Grow-Grenze aufgerundet verkleinern
sal_uInt16 nNewUsed = nUsed-nLen;
sal_uInt16 nNewSize = ((nNewUsed+nGrow-1)/nGrow) * nGrow;
DBG_ASSERT( nNewUsed <= nNewSize && nNewUsed+nGrow > nNewSize,
"shrink size computation failed" );
void** pNewData = new void*[nNewSize];
if ( nPos > 0 )
{
DBG_ASSERT( nPos <= nNewSize, "" );
memmove( pNewData, pData, sizeof(void*)*nPos );
}
if ( nNewUsed != nPos )
memmove( pNewData+nPos, pData+nPos+nLen,
sizeof(void*)*(nNewUsed-nPos) );
delete [] pData;
pData = pNewData;
nUsed = nNewUsed;
nUnused = sal::static_int_cast< sal_uInt8 >(nNewSize - nNewUsed);
return nLen;
}
// in allen anderen Faellen nur zusammenschieben
if ( nUsed-nPos-nLen > 0 )
memmove( pData+nPos, pData+nPos+nLen, (nUsed-nPos-nLen)*sizeof(void*) );
nUsed = nUsed - nLen;
nUnused = sal::static_int_cast< sal_uInt8 >(nUnused + nLen);
return nLen;
}
// -----------------------------------------------------------------------
sal_Bool SfxPtrArr::Remove( void* aElem )
{
DBG_MEMTEST();
// einfache Aufgaben ...
if ( nUsed == 0 )
return sal_False;
// rueckwaerts, da meist der letzte zuerst wieder entfernt wird
void* *pIter = pData + nUsed - 1;
for ( sal_uInt16 n = 0; n < nUsed; ++n, --pIter )
if ( *pIter == aElem )
{
Remove(nUsed-n-1, 1);
return sal_True;
}
return sal_False;
}
// -----------------------------------------------------------------------
sal_Bool SfxPtrArr::Replace( void* aOldElem, void* aNewElem )
{
DBG_MEMTEST();
// einfache Aufgaben ...
if ( nUsed == 0 )
return sal_False;
// rueckwaerts, da meist der letzte zuerst wieder entfernt wird
void* *pIter = pData + nUsed - 1;
for ( sal_uInt16 n = 0; n < nUsed; ++n, --pIter )
if ( *pIter == aOldElem )
{
pData[nUsed-n-1] = aNewElem;
return sal_True;
}
return sal_False;
}
// -----------------------------------------------------------------------
sal_Bool SfxPtrArr::Contains( const void* rItem ) const
{
DBG_MEMTEST();
if ( !nUsed )
return sal_False;
for ( sal_uInt16 n = 0; n < nUsed; ++n )
{
void* p = GetObject(n);
if ( p == rItem )
return sal_True;
}
return sal_False;
}
// -----------------------------------------------------------------------
void SfxPtrArr::Insert( sal_uInt16 nPos, void* rElem )
{
DBG_MEMTEST();
DBG_ASSERT( sal::static_int_cast< unsigned >(nUsed+1) < ( USHRT_MAX / sizeof(void*) ), "array too large" );
// musz das Array umkopiert werden?
if ( nUnused == 0 )
{
// auf die naechste Grow-Grenze aufgerundet vergroeszern
sal_uInt16 nNewSize = nUsed+nGrow;
void** pNewData = new void*[nNewSize];
if ( pData )
{
DBG_ASSERT( nUsed < nNewSize, "" );
memmove( pNewData, pData, sizeof(void*)*nUsed );
delete [] pData;
}
nUnused = sal::static_int_cast< sal_uInt8 >(nNewSize-nUsed);
pData = pNewData;
}
// jetzt den hinteren Teil verschieben
if ( nPos < nUsed )
memmove( pData+nPos+1, pData+nPos, (nUsed-nPos)*sizeof(void*) );
// jetzt in den freien Raum schreiben
memmove( pData+nPos, &rElem, sizeof(void*) );
nUsed += 1;
nUnused -= 1;
}
// class ByteArr ---------------------------------------------------------
ByteArr::ByteArr( sal_uInt8 nInitSize, sal_uInt8 nGrowSize ):
nUsed( 0 ),
nGrow( nGrowSize ? nGrowSize : 1 ),
nUnused( nInitSize )
{
DBG_MEMTEST();
sal_uInt16 nMSCBug = nInitSize;
if ( nInitSize > 0 )
pData = new char[nMSCBug];
else
pData = 0;
}
// -----------------------------------------------------------------------
ByteArr::ByteArr( const ByteArr& rOrig )
{
DBG_MEMTEST();
nUsed = rOrig.nUsed;
nGrow = rOrig.nGrow;
nUnused = rOrig.nUnused;
if ( rOrig.pData != 0 )
{
pData = new char[nUsed+nUnused];
memcpy( pData, rOrig.pData, nUsed*sizeof(char) );
}
else
pData = 0;
}
// -----------------------------------------------------------------------
ByteArr::~ByteArr()
{
DBG_MEMTEST();
delete [] pData;
}
// -----------------------------------------------------------------------
ByteArr& ByteArr::operator=( const ByteArr& rOrig )
{
DBG_MEMTEST();
delete [] pData;
nUsed = rOrig.nUsed;
nGrow = rOrig.nGrow;
nUnused = rOrig.nUnused;
if ( rOrig.pData != 0 )
{
pData = new char[nUsed+nUnused];
memcpy( pData, rOrig.pData, nUsed*sizeof(char) );
}
else
pData = 0;
return *this;
}
// -----------------------------------------------------------------------
void ByteArr::Append( char aElem )
{
DBG_MEMTEST();
// musz das Array umkopiert werden?
if ( nUnused == 0 )
{
sal_uInt16 nNewSize = (nUsed == 1) ? (nGrow==1 ? 2 : nGrow) : nUsed+nGrow;
char* pNewData = new char[nNewSize];
if ( pData )
{
DBG_ASSERT( nUsed <= nNewSize, "" );
memmove( pNewData, pData, sizeof(char)*nUsed );
delete [] pData;
}
nUnused = sal::static_int_cast< sal_uInt8 >(nNewSize-nUsed);
pData = pNewData;
}
// jetzt hinten in den freien Raum schreiben
pData[nUsed] = aElem;
++nUsed;
--nUnused;
}
// -----------------------------------------------------------------------
sal_uInt16 ByteArr::Remove( sal_uInt16 nPos, sal_uInt16 nLen )
{
DBG_MEMTEST();
// nLen adjustieren, damit nicht ueber das Ende hinaus geloescht wird
nLen = Min( (sal_uInt16)(nUsed-nPos), nLen );
// einfache Aufgaben erfordern einfache Loesungen!
if ( nLen == 0 )
return 0;
// bleibt vielleicht keiner uebrig
if ( (nUsed-nLen) == 0 )
{
delete [] pData;
pData = 0;
nUsed = 0;
nUnused = 0;
return nLen;
}
// feststellen, ob das Array dadurch physikalisch schrumpft...
if ( (nUnused+nLen) >= nGrow )
{
// auf die naechste Grow-Grenze aufgerundet verkleinern
sal_uInt16 nNewUsed = nUsed-nLen;
sal_uInt16 nNewSize = ((nNewUsed+nGrow-1)/nGrow) * nGrow;
DBG_ASSERT( nNewUsed <= nNewSize && nNewUsed+nGrow > nNewSize,
"shrink size computation failed" );
char* pNewData = new char[nNewSize];
if ( nPos > 0 )
{
DBG_ASSERT( nPos <= nNewSize, "" );
memmove( pNewData, pData, sizeof(char)*nPos );
}
if ( nNewUsed != nPos )
memmove( pNewData+nPos, pData+nPos+nLen,
sizeof(char)*(nNewUsed-nPos) );
delete [] pData;
pData = pNewData;
nUsed = nNewUsed;
nUnused = sal::static_int_cast< sal_uInt8 >(nNewSize - nNewUsed);
return nLen;
}
// in allen anderen Faellen nur zusammenschieben
if ( nUsed-nPos-nLen > 0 )
memmove( pData+nPos, pData+nPos+nLen, (nUsed-nPos-nLen)*sizeof(char) );
nUsed = nUsed - nLen;
nUnused = sal::static_int_cast< sal_uInt8 >(nUnused + nLen);
return nLen;
}
// -----------------------------------------------------------------------
sal_Bool ByteArr::Remove( char aElem )
{
DBG_MEMTEST();
// einfache Aufgaben ...
if ( nUsed == 0 )
return sal_False;
// rueckwaerts, da meist der letzte zuerst wieder entfernt wird
char *pIter = pData + nUsed - 1;
for ( sal_uInt16 n = 0; n < nUsed; ++n, --pIter )
if ( *pIter == aElem )
{
Remove(nUsed-n-1, 1);
return sal_True;
}
return sal_False;
}
// -----------------------------------------------------------------------
sal_Bool ByteArr::Contains( const char rItem ) const
{
DBG_MEMTEST();
if ( !nUsed )
return sal_False;
for ( sal_uInt16 n = 0; n < nUsed; ++n )
{
char p = GetObject(n);
if ( p == rItem )
return sal_True;
}
return sal_False;
}
// -----------------------------------------------------------------------
void ByteArr::Insert( sal_uInt16 nPos, char rElem )
{
DBG_MEMTEST();
// musz das Array umkopiert werden?
if ( nUnused == 0 )
{
// auf die naechste Grow-Grenze aufgerundet vergroeszern
sal_uInt16 nNewSize = nUsed+nGrow;
char* pNewData = new char[nNewSize];
if ( pData )
{
DBG_ASSERT( nUsed < nNewSize, "" );
memmove( pNewData, pData, sizeof(char)*nUsed );
delete [] pData;
}
nUnused = sal::static_int_cast< sal_uInt8 >(nNewSize-nUsed);
pData = pNewData;
}
// jetzt den hinteren Teil verschieben
if ( nPos < nUsed )
memmove( pData+nPos+1, pData+nPos, (nUsed-nPos)*sizeof(char) );
// jetzt in den freien Raum schreiben
memmove( pData+nPos, &rElem, sizeof(char) );
nUsed += 1;
nUnused -= 1;
}
// -----------------------------------------------------------------------
char ByteArr::operator[]( sal_uInt16 nPos ) const
{
DBG_MEMTEST();
DBG_ASSERT( nPos < nUsed, "" );
return *(pData+nPos);
}
// -----------------------------------------------------------------------
char& ByteArr::operator [] (sal_uInt16 nPos)
{
DBG_MEMTEST();
DBG_ASSERT( nPos < nUsed, "" );
return *(pData+nPos);
}
// class WordArr ---------------------------------------------------------
WordArr::WordArr( sal_uInt8 nInitSize, sal_uInt8 nGrowSize ):
nUsed( 0 ),
nGrow( nGrowSize ? nGrowSize : 1 ),
nUnused( nInitSize )
{
DBG_MEMTEST();
sal_uInt16 nMSCBug = nInitSize;
if ( nInitSize > 0 )
pData = new short[nMSCBug];
else
pData = 0;
}
// -----------------------------------------------------------------------
WordArr::WordArr( const WordArr& rOrig )
{
DBG_MEMTEST();
nUsed = rOrig.nUsed;
nGrow = rOrig.nGrow;
nUnused = rOrig.nUnused;
if ( rOrig.pData != 0 )
{
pData = new short[nUsed+nUnused];
memcpy( pData, rOrig.pData, nUsed*sizeof(short) );
}
else
pData = 0;
}
// -----------------------------------------------------------------------
WordArr::~WordArr()
{
DBG_MEMTEST();
delete [] pData;
}
// -----------------------------------------------------------------------
WordArr& WordArr::operator=( const WordArr& rOrig )
{
DBG_MEMTEST();
delete [] pData;
nUsed = rOrig.nUsed;
nGrow = rOrig.nGrow;
nUnused = rOrig.nUnused;
if ( rOrig.pData != 0 )
{
pData = new short[nUsed+nUnused];
memcpy( pData, rOrig.pData, nUsed*sizeof(short) );
}
else
pData = 0;
return *this;
}
// -----------------------------------------------------------------------
void WordArr::Append( short aElem )
{
DBG_MEMTEST();
// musz das Array umkopiert werden?
if ( nUnused == 0 )
{
sal_uInt16 nNewSize = (nUsed == 1) ? (nGrow==1 ? 2 : nGrow) : nUsed+nGrow;
short* pNewData = new short[nNewSize];
if ( pData )
{
DBG_ASSERT( nUsed <= nNewSize, " " );
memmove( pNewData, pData, sizeof(short)*nUsed );
delete [] pData;
}
nUnused = sal::static_int_cast< sal_uInt8 >(nNewSize-nUsed);
pData = pNewData;
}
// jetzt hinten in den freien Raum schreiben
pData[nUsed] = aElem;
++nUsed;
--nUnused;
}
// -----------------------------------------------------------------------
sal_uInt16 WordArr::Remove( sal_uInt16 nPos, sal_uInt16 nLen )
{
DBG_MEMTEST();
// nLen adjustieren, damit nicht ueber das Ende hinaus geloescht wird
nLen = Min( (sal_uInt16)(nUsed-nPos), nLen );
// einfache Aufgaben erfordern einfache Loesungen!
if ( nLen == 0 )
return 0;
// bleibt vielleicht keiner uebrig
if ( (nUsed-nLen) == 0 )
{
delete [] pData;
pData = 0;
nUsed = 0;
nUnused = 0;
return nLen;
}
// feststellen, ob das Array dadurch physikalisch schrumpft...
if ( (nUnused+nLen) >= nGrow )
{
// auf die naechste Grow-Grenze aufgerundet verkleinern
sal_uInt16 nNewUsed = nUsed-nLen;
sal_uInt16 nNewSize = ((nNewUsed+nGrow-1)/nGrow) * nGrow;
DBG_ASSERT( nNewUsed <= nNewSize && nNewUsed+nGrow > nNewSize,
"shrink size computation failed" );
short* pNewData = new short[nNewSize];
if ( nPos > 0 )
{
DBG_ASSERT( nPos <= nNewSize, "" );
memmove( pNewData, pData, sizeof(short)*nPos );
}
if ( nNewUsed != nPos )
memmove( pNewData+nPos, pData+nPos+nLen,
sizeof(short)*(nNewUsed-nPos) );
delete [] pData;
pData = pNewData;
nUsed = nNewUsed;
nUnused = sal::static_int_cast< sal_uInt8 >(nNewSize - nNewUsed);
return nLen;
}
// in allen anderen Faellen nur zusammenschieben
if ( nUsed-nPos-nLen > 0 )
memmove( pData+nPos, pData+nPos+nLen, (nUsed-nPos-nLen)*sizeof(short) );
nUsed = nUsed - nLen;
nUnused = sal::static_int_cast< sal_uInt8 >(nUnused + nLen);
return nLen;
}
// -----------------------------------------------------------------------
sal_Bool WordArr::Remove( short aElem )
{
DBG_MEMTEST();
// einfache Aufgaben ...
if ( nUsed == 0 )
return sal_False;
// rueckwaerts, da meist der letzte zuerst wieder entfernt wird
short *pIter = pData + nUsed - 1;
for ( sal_uInt16 n = 0; n < nUsed; ++n, --pIter )
if ( *pIter == aElem )
{
Remove(nUsed-n-1, 1);
return sal_True;
}
return sal_False;
}
// -----------------------------------------------------------------------
sal_Bool WordArr::Contains( const short rItem ) const
{
DBG_MEMTEST();
if ( !nUsed )
return sal_False;
for ( sal_uInt16 n = 0; n < nUsed; ++n )
{
short p = GetObject(n);
if ( p == rItem )
return sal_True;
}
return sal_False;
}
// -----------------------------------------------------------------------
void WordArr::Insert( sal_uInt16 nPos, short rElem )
{
DBG_MEMTEST();
// musz das Array umkopiert werden?
if ( nUnused == 0 )
{
// auf die naechste Grow-Grenze aufgerundet vergroeszern
sal_uInt16 nNewSize = nUsed+nGrow;
short* pNewData = new short[nNewSize];
if ( pData )
{
DBG_ASSERT( nUsed < nNewSize, "" );
memmove( pNewData, pData, sizeof(short)*nUsed );
delete [] pData;
}
nUnused = sal::static_int_cast< sal_uInt8 >(nNewSize-nUsed);
pData = pNewData;
}
// jetzt den hinteren Teil verschieben
if ( nPos < nUsed )
memmove( pData+nPos+1, pData+nPos, (nUsed-nPos)*sizeof(short) );
// jetzt in den freien Raum schreiben
memmove( pData+nPos, &rElem, sizeof(short) );
nUsed += 1;
nUnused -= 1;
}
// -----------------------------------------------------------------------
short WordArr::operator[]( sal_uInt16 nPos ) const
{
DBG_MEMTEST();
DBG_ASSERT( nPos < nUsed, "" );
return *(pData+nPos);
}
// -----------------------------------------------------------------------
short& WordArr::operator [] (sal_uInt16 nPos)
{
DBG_MEMTEST();
DBG_ASSERT( nPos < nUsed, "" );
return *(pData+nPos);
}