Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / sfx2 / source / bastyp / minarray.cxx
blobb6d6a0413446b0a6ca9cf85eaeb1026eedb87344
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
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.
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).
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.
27 ************************************************************************/
30 #include <sfx2/minarray.hxx>
32 // -----------------------------------------------------------------------
34 SfxPtrArr::SfxPtrArr( sal_uInt8 nInitSize, sal_uInt8 nGrowSize ):
35 nUsed( 0 ),
36 nGrow( nGrowSize ? nGrowSize : 1 ),
37 nUnused( nInitSize )
39 sal_uInt16 nMSCBug = nInitSize;
41 if ( nMSCBug > 0 )
42 pData = new void*[nMSCBug];
43 else
44 pData = 0;
47 // -----------------------------------------------------------------------
49 SfxPtrArr::SfxPtrArr( const SfxPtrArr& rOrig )
51 nUsed = rOrig.nUsed;
52 nGrow = rOrig.nGrow;
53 nUnused = rOrig.nUnused;
55 if ( rOrig.pData != 0 )
57 pData = new void*[nUsed+nUnused];
58 memcpy( pData, rOrig.pData, nUsed*sizeof(void*) );
60 else
61 pData = 0;
64 // -----------------------------------------------------------------------
66 SfxPtrArr::~SfxPtrArr()
68 delete [] pData;
71 // -----------------------------------------------------------------------
73 SfxPtrArr& SfxPtrArr::operator=( const SfxPtrArr& rOrig )
76 delete [] pData;
78 nUsed = rOrig.nUsed;
79 nGrow = rOrig.nGrow;
80 nUnused = rOrig.nUnused;
82 if ( rOrig.pData != 0 )
84 pData = new void*[nUsed+nUnused];
85 memcpy( pData, rOrig.pData, nUsed*sizeof(void*) );
87 else
88 pData = 0;
89 return *this;
92 // -----------------------------------------------------------------------
94 void SfxPtrArr::Append( void* aElem )
96 DBG_ASSERT( sal::static_int_cast< unsigned >(nUsed+1) < ( USHRT_MAX / sizeof(void*) ), "array too large" );
97 // Does the Array need to be copied?
98 if ( nUnused == 0 )
100 sal_uInt16 nNewSize = (nUsed == 1) ? (nGrow==1 ? 2 : nGrow) : nUsed+nGrow;
101 void** pNewData = new void*[nNewSize];
102 if ( pData )
104 DBG_ASSERT( nUsed <= nNewSize, "" );
105 memmove( pNewData, pData, sizeof(void*)*nUsed );
106 delete [] pData;
108 nUnused = sal::static_int_cast< sal_uInt8 >(nNewSize-nUsed);
109 pData = pNewData;
112 // now write at the back in the open space
113 pData[nUsed] = aElem;
114 ++nUsed;
115 --nUnused;
118 // -----------------------------------------------------------------------
120 sal_uInt16 SfxPtrArr::Remove( sal_uInt16 nPos, sal_uInt16 nLen )
122 // Adjust nLen, thus to avoid deleting beyond the end
123 nLen = Min( (sal_uInt16)(nUsed-nPos), nLen );
125 // simple problems require simple solutions!
126 if ( nLen == 0 )
127 return 0;
129 // Maybe no one will remain
130 if ( (nUsed-nLen) == 0 )
132 delete [] pData;
133 pData = 0;
134 nUsed = 0;
135 nUnused = 0;
136 return nLen;
139 // Determine whether the array has physically shrunk...
140 if ( (nUnused+nLen) >= nGrow )
142 // reduce (rounded up) to the next Grow-border
143 sal_uInt16 nNewUsed = nUsed-nLen;
144 sal_uInt16 nNewSize = ((nNewUsed+nGrow-1)/nGrow) * nGrow;
145 DBG_ASSERT( nNewUsed <= nNewSize && nNewUsed+nGrow > nNewSize,
146 "shrink size computation failed" );
147 void** pNewData = new void*[nNewSize];
148 if ( nPos > 0 )
150 DBG_ASSERT( nPos <= nNewSize, "" );
151 memmove( pNewData, pData, sizeof(void*)*nPos );
153 if ( nNewUsed != nPos )
154 memmove( pNewData+nPos, pData+nPos+nLen,
155 sizeof(void*)*(nNewUsed-nPos) );
156 delete [] pData;
157 pData = pNewData;
158 nUsed = nNewUsed;
159 nUnused = sal::static_int_cast< sal_uInt8 >(nNewSize - nNewUsed);
160 return nLen;
163 // in all other cases, only push together
164 if ( nUsed-nPos-nLen > 0 )
165 memmove( pData+nPos, pData+nPos+nLen, (nUsed-nPos-nLen)*sizeof(void*) );
166 nUsed = nUsed - nLen;
167 nUnused = sal::static_int_cast< sal_uInt8 >(nUnused + nLen);
168 return nLen;
171 // -----------------------------------------------------------------------
173 sal_Bool SfxPtrArr::Remove( void* aElem )
175 // simple tasks ...
176 if ( nUsed == 0 )
177 return sal_False;
179 // backwards, since most of the last is first removed
180 void* *pIter = pData + nUsed - 1;
181 for ( sal_uInt16 n = 0; n < nUsed; ++n, --pIter )
182 if ( *pIter == aElem )
184 Remove(nUsed-n-1, 1);
185 return sal_True;
187 return sal_False;
190 // -----------------------------------------------------------------------
192 sal_Bool SfxPtrArr::Contains( const void* rItem ) const
194 if ( !nUsed )
195 return sal_False;
197 for ( sal_uInt16 n = 0; n < nUsed; ++n )
199 void* p = GetObject(n);
200 if ( p == rItem )
201 return sal_True;
204 return sal_False;
207 // -----------------------------------------------------------------------
209 void SfxPtrArr::Insert( sal_uInt16 nPos, void* rElem )
211 DBG_ASSERT( sal::static_int_cast< unsigned >(nUsed+1) < ( USHRT_MAX / sizeof(void*) ), "array too large" );
212 // Does the Array have to be copied?
213 if ( nUnused == 0 )
215 // increase (rounded up ) to the next Grow-border
216 sal_uInt16 nNewSize = nUsed+nGrow;
217 void** pNewData = new void*[nNewSize];
219 if ( pData )
221 DBG_ASSERT( nUsed < nNewSize, "" );
222 memmove( pNewData, pData, sizeof(void*)*nUsed );
223 delete [] pData;
225 nUnused = sal::static_int_cast< sal_uInt8 >(nNewSize-nUsed);
226 pData = pNewData;
229 // Now move the rear part
230 if ( nPos < nUsed )
231 memmove( pData+nPos+1, pData+nPos, (nUsed-nPos)*sizeof(void*) );
233 // Now write into the free space.
234 memmove( pData+nPos, &rElem, sizeof(void*) );
235 nUsed += 1;
236 nUnused -= 1;
239 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */