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
):
36 nGrow( nGrowSize
? nGrowSize
: 1 ),
39 sal_uInt16 nMSCBug
= nInitSize
;
42 pData
= new void*[nMSCBug
];
47 // -----------------------------------------------------------------------
49 SfxPtrArr::SfxPtrArr( const SfxPtrArr
& rOrig
)
53 nUnused
= rOrig
.nUnused
;
55 if ( rOrig
.pData
!= 0 )
57 pData
= new void*[nUsed
+nUnused
];
58 memcpy( pData
, rOrig
.pData
, nUsed
*sizeof(void*) );
64 // -----------------------------------------------------------------------
66 SfxPtrArr::~SfxPtrArr()
71 // -----------------------------------------------------------------------
73 SfxPtrArr
& SfxPtrArr::operator=( const SfxPtrArr
& rOrig
)
80 nUnused
= rOrig
.nUnused
;
82 if ( rOrig
.pData
!= 0 )
84 pData
= new void*[nUsed
+nUnused
];
85 memcpy( pData
, rOrig
.pData
, nUsed
*sizeof(void*) );
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?
100 sal_uInt16 nNewSize
= (nUsed
== 1) ? (nGrow
==1 ? 2 : nGrow
) : nUsed
+nGrow
;
101 void** pNewData
= new void*[nNewSize
];
104 DBG_ASSERT( nUsed
<= nNewSize
, "" );
105 memmove( pNewData
, pData
, sizeof(void*)*nUsed
);
108 nUnused
= sal::static_int_cast
< sal_uInt8
>(nNewSize
-nUsed
);
112 // now write at the back in the open space
113 pData
[nUsed
] = aElem
;
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!
129 // Maybe no one will remain
130 if ( (nUsed
-nLen
) == 0 )
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
];
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
) );
159 nUnused
= sal::static_int_cast
< sal_uInt8
>(nNewSize
- nNewUsed
);
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
);
171 // -----------------------------------------------------------------------
173 sal_Bool
SfxPtrArr::Remove( void* aElem
)
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);
190 // -----------------------------------------------------------------------
192 sal_Bool
SfxPtrArr::Contains( const void* rItem
) const
197 for ( sal_uInt16 n
= 0; n
< nUsed
; ++n
)
199 void* p
= GetObject(n
);
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?
215 // increase (rounded up ) to the next Grow-border
216 sal_uInt16 nNewSize
= nUsed
+nGrow
;
217 void** pNewData
= new void*[nNewSize
];
221 DBG_ASSERT( nUsed
< nNewSize
, "" );
222 memmove( pNewData
, pData
, sizeof(void*)*nUsed
);
225 nUnused
= sal::static_int_cast
< sal_uInt8
>(nNewSize
-nUsed
);
229 // Now move the rear part
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*) );
239 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */