Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : :
21 : : #include <sfx2/minarray.hxx>
22 : :
23 : : // -----------------------------------------------------------------------
24 : :
25 : 21513 : SfxPtrArr::SfxPtrArr( sal_uInt8 nInitSize, sal_uInt8 nGrowSize ):
26 : : nUsed( 0 ),
27 : : nGrow( nGrowSize ? nGrowSize : 1 ),
28 [ + - ]: 21513 : nUnused( nInitSize )
29 : : {
30 : 21513 : sal_uInt16 nMSCBug = nInitSize;
31 : :
32 [ + + ]: 21513 : if ( nMSCBug > 0 )
33 : 21415 : pData = new void*[nMSCBug];
34 : : else
35 : 98 : pData = 0;
36 : 21513 : }
37 : :
38 : : // -----------------------------------------------------------------------
39 : :
40 : 2995 : SfxPtrArr::SfxPtrArr( const SfxPtrArr& rOrig )
41 : : {
42 : 2995 : nUsed = rOrig.nUsed;
43 : 2995 : nGrow = rOrig.nGrow;
44 : 2995 : nUnused = rOrig.nUnused;
45 : :
46 [ + - ]: 2995 : if ( rOrig.pData != 0 )
47 : : {
48 : 2995 : pData = new void*[nUsed+nUnused];
49 : 2995 : memcpy( pData, rOrig.pData, nUsed*sizeof(void*) );
50 : : }
51 : : else
52 : 0 : pData = 0;
53 : 2995 : }
54 : :
55 : : // -----------------------------------------------------------------------
56 : :
57 : 16619 : SfxPtrArr::~SfxPtrArr()
58 : : {
59 [ + + ]: 16619 : delete [] pData;
60 : 16619 : }
61 : :
62 : : // -----------------------------------------------------------------------
63 : :
64 : 0 : SfxPtrArr& SfxPtrArr::operator=( const SfxPtrArr& rOrig )
65 : : {
66 : :
67 [ # # ]: 0 : delete [] pData;
68 : :
69 : 0 : nUsed = rOrig.nUsed;
70 : 0 : nGrow = rOrig.nGrow;
71 : 0 : nUnused = rOrig.nUnused;
72 : :
73 [ # # ]: 0 : if ( rOrig.pData != 0 )
74 : : {
75 : 0 : pData = new void*[nUsed+nUnused];
76 : 0 : memcpy( pData, rOrig.pData, nUsed*sizeof(void*) );
77 : : }
78 : : else
79 : 0 : pData = 0;
80 : 0 : return *this;
81 : : }
82 : :
83 : : // -----------------------------------------------------------------------
84 : :
85 : 31373 : void SfxPtrArr::Append( void* aElem )
86 : : {
87 : : DBG_ASSERT( sal::static_int_cast< unsigned >(nUsed+1) < ( USHRT_MAX / sizeof(void*) ), "array too large" );
88 : : // Does the Array need to be copied?
89 [ + + ]: 31373 : if ( nUnused == 0 )
90 : : {
91 [ - + ][ # # ]: 3939 : sal_uInt16 nNewSize = (nUsed == 1) ? (nGrow==1 ? 2 : nGrow) : nUsed+nGrow;
92 : 3939 : void** pNewData = new void*[nNewSize];
93 [ + - ]: 3939 : if ( pData )
94 : : {
95 : : DBG_ASSERT( nUsed <= nNewSize, "" );
96 : 3939 : memmove( pNewData, pData, sizeof(void*)*nUsed );
97 [ + - ]: 3939 : delete [] pData;
98 : : }
99 : 3939 : nUnused = sal::static_int_cast< sal_uInt8 >(nNewSize-nUsed);
100 : 3939 : pData = pNewData;
101 : : }
102 : :
103 : : // now write at the back in the open space
104 : 31373 : pData[nUsed] = aElem;
105 : 31373 : ++nUsed;
106 : 31373 : --nUnused;
107 : 31373 : }
108 : :
109 : : // -----------------------------------------------------------------------
110 : :
111 : 212589 : sal_uInt16 SfxPtrArr::Remove( sal_uInt16 nPos, sal_uInt16 nLen )
112 : : {
113 : : // Adjust nLen, thus to avoid deleting beyond the end
114 : 212589 : nLen = Min( (sal_uInt16)(nUsed-nPos), nLen );
115 : :
116 : : // simple problems require simple solutions!
117 [ + + ]: 212589 : if ( nLen == 0 )
118 : 56 : return 0;
119 : :
120 : : // Maybe no one will remain
121 [ + + ]: 212533 : if ( (nUsed-nLen) == 0 )
122 : : {
123 [ + - ]: 7314 : delete [] pData;
124 : 7314 : pData = 0;
125 : 7314 : nUsed = 0;
126 : 7314 : nUnused = 0;
127 : 7314 : return nLen;
128 : : }
129 : :
130 : : // Determine whether the array has physically shrunk...
131 [ + + ]: 205219 : if ( (nUnused+nLen) >= nGrow )
132 : : {
133 : : // reduce (rounded up) to the next Grow-border
134 : 37977 : sal_uInt16 nNewUsed = nUsed-nLen;
135 : 37977 : sal_uInt16 nNewSize = ((nNewUsed+nGrow-1)/nGrow) * nGrow;
136 : : DBG_ASSERT( nNewUsed <= nNewSize && nNewUsed+nGrow > nNewSize,
137 : : "shrink size computation failed" );
138 : 37977 : void** pNewData = new void*[nNewSize];
139 [ + + ]: 37977 : if ( nPos > 0 )
140 : : {
141 : : DBG_ASSERT( nPos <= nNewSize, "" );
142 : 9543 : memmove( pNewData, pData, sizeof(void*)*nPos );
143 : : }
144 [ + + ]: 37977 : if ( nNewUsed != nPos )
145 : 57164 : memmove( pNewData+nPos, pData+nPos+nLen,
146 : 28582 : sizeof(void*)*(nNewUsed-nPos) );
147 [ + - ]: 37977 : delete [] pData;
148 : 37977 : pData = pNewData;
149 : 37977 : nUsed = nNewUsed;
150 : 37977 : nUnused = sal::static_int_cast< sal_uInt8 >(nNewSize - nNewUsed);
151 : 37977 : return nLen;
152 : : }
153 : :
154 : : // in all other cases, only push together
155 [ + + ]: 167242 : if ( nUsed-nPos-nLen > 0 )
156 : 33101 : memmove( pData+nPos, pData+nPos+nLen, (nUsed-nPos-nLen)*sizeof(void*) );
157 : 167242 : nUsed = nUsed - nLen;
158 : 167242 : nUnused = sal::static_int_cast< sal_uInt8 >(nUnused + nLen);
159 : 212589 : return nLen;
160 : : }
161 : :
162 : : // -----------------------------------------------------------------------
163 : :
164 : 0 : sal_Bool SfxPtrArr::Remove( void* aElem )
165 : : {
166 : : // simple tasks ...
167 [ # # ]: 0 : if ( nUsed == 0 )
168 : 0 : return sal_False;
169 : :
170 : : // backwards, since most of the last is first removed
171 : 0 : void* *pIter = pData + nUsed - 1;
172 [ # # ]: 0 : for ( sal_uInt16 n = 0; n < nUsed; ++n, --pIter )
173 [ # # ]: 0 : if ( *pIter == aElem )
174 : : {
175 : 0 : Remove(nUsed-n-1, 1);
176 : 0 : return sal_True;
177 : : }
178 : 0 : return sal_False;
179 : : }
180 : :
181 : : // -----------------------------------------------------------------------
182 : :
183 : 2995 : sal_Bool SfxPtrArr::Contains( const void* rItem ) const
184 : : {
185 [ - + ]: 2995 : if ( !nUsed )
186 : 0 : return sal_False;
187 : :
188 [ + + ]: 14991 : for ( sal_uInt16 n = 0; n < nUsed; ++n )
189 : : {
190 : 13502 : void* p = GetObject(n);
191 [ + + ]: 13502 : if ( p == rItem )
192 : 1506 : return sal_True;
193 : : }
194 : :
195 : 2995 : return sal_False;
196 : : }
197 : :
198 : : // -----------------------------------------------------------------------
199 : :
200 : 232885 : void SfxPtrArr::Insert( sal_uInt16 nPos, void* rElem )
201 : : {
202 : : DBG_ASSERT( sal::static_int_cast< unsigned >(nUsed+1) < ( USHRT_MAX / sizeof(void*) ), "array too large" );
203 : : // Does the Array have to be copied?
204 [ + + ]: 232885 : if ( nUnused == 0 )
205 : : {
206 : : // increase (rounded up ) to the next Grow-border
207 : 49900 : sal_uInt16 nNewSize = nUsed+nGrow;
208 : 49900 : void** pNewData = new void*[nNewSize];
209 : :
210 [ + + ]: 49900 : if ( pData )
211 : : {
212 : : DBG_ASSERT( nUsed < nNewSize, "" );
213 : 48310 : memmove( pNewData, pData, sizeof(void*)*nUsed );
214 [ + - ]: 48310 : delete [] pData;
215 : : }
216 : 49900 : nUnused = sal::static_int_cast< sal_uInt8 >(nNewSize-nUsed);
217 : 49900 : pData = pNewData;
218 : : }
219 : :
220 : : // Now move the rear part
221 [ + + ]: 232885 : if ( nPos < nUsed )
222 : 147547 : memmove( pData+nPos+1, pData+nPos, (nUsed-nPos)*sizeof(void*) );
223 : :
224 : : // Now write into the free space.
225 : 232885 : memmove( pData+nPos, &rElem, sizeof(void*) );
226 : 232885 : nUsed += 1;
227 : 232885 : nUnused -= 1;
228 : 232885 : }
229 : :
230 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|