xref: /aoo41x/main/svl/source/memtools/svarray.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svl.hxx"
30 
31 #define _SVARRAY_CXX
32 
33 #define _SVSTDARR_BOOLS
34 #define _SVSTDARR_BYTES
35 #define _SVSTDARR_ULONGS
36 #define _SVSTDARR_ULONGSSORT
37 #define _SVSTDARR_USHORTS
38 #define _SVSTDARR_LONGS
39 #define _SVSTDARR_LONGSSORT
40 #define _SVSTDARR_SHORTS
41 #define _SVSTDARR_STRINGS
42 #define _SVSTDARR_STRINGSDTOR
43 #define _SVSTDARR_STRINGSSORT
44 #define _SVSTDARR_STRINGSSORTDTOR
45 #define _SVSTDARR_STRINGSISORT
46 #define _SVSTDARR_STRINGSISORTDTOR
47 #define _SVSTDARR_USHORTSSORT
48 
49 #define _SVSTDARR_BYTESTRINGS
50 #define _SVSTDARR_BYTESTRINGSDTOR
51 #define _SVSTDARR_BYTESTRINGSSORT
52 #define _SVSTDARR_BYTESTRINGSSORTDTOR
53 #define _SVSTDARR_BYTESTRINGSISORT
54 #define _SVSTDARR_BYTESTRINGSISORTDTOR
55 
56 #define _SVSTDARR_XUB_STRLEN
57 #define _SVSTDARR_XUB_STRLENSORT
58 
59 #include <svl/svstdarr.hxx>
60 #include <tools/string.hxx>
61 #include <tools/debug.hxx>
62 
63 SV_IMPL_VARARR(SvPtrarr,VoidPtr)
64 
65 sal_uInt16 SvPtrarr::GetPos( const VoidPtr& aElement ) const
66 {	sal_uInt16 n;
67 	for( n=0; n < nA && *(GetData()+n) != aElement; ) n++;
68 	return ( n >= nA ? USHRT_MAX : n );
69 }
70 
71 SV_IMPL_VARARR( SvULongs, sal_uLong )
72 SV_IMPL_VARARR( SvUShorts, sal_uInt16 )
73 SV_IMPL_VARARR( SvLongs, long)
74 
75 SV_IMPL_VARARR_SORT( SvULongsSort, sal_uLong )
76 SV_IMPL_VARARR_SORT( SvLongsSort, long )
77 
78 SV_IMPL_PTRARR( SvStrings, StringPtr )
79 SV_IMPL_PTRARR( SvStringsDtor, StringPtr )
80 SV_IMPL_OP_PTRARR_SORT( SvStringsSort, StringPtr )
81 SV_IMPL_OP_PTRARR_SORT( SvStringsSortDtor, StringPtr )
82 
83 SV_IMPL_PTRARR( SvByteStrings, ByteStringPtr )
84 SV_IMPL_PTRARR( SvByteStringsDtor, ByteStringPtr )
85 SV_IMPL_OP_PTRARR_SORT( SvByteStringsSort, ByteStringPtr )
86 SV_IMPL_OP_PTRARR_SORT( SvByteStringsSortDtor, ByteStringPtr )
87 
88 
89 
90 // ---------------- strings -------------------------------------
91 
92 // Array mit anderer Seek-Methode!
93 _SV_IMPL_SORTAR_ALG( SvStringsISort, StringPtr )
94 void SvStringsISort::DeleteAndDestroy( sal_uInt16 nP, sal_uInt16 nL )
95 {
96 	if( nL )
97 	{
98 		DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );
99 		for( sal_uInt16 n=nP; n < nP + nL; n++ )
100 			delete *((StringPtr*)pData+n);
101 		SvPtrarr::Remove( nP, nL );
102 	}
103 }
104 sal_Bool SvStringsISort::Seek_Entry( const StringPtr aE, sal_uInt16* pP ) const
105 {
106 	register sal_uInt16 nO  = SvStringsISort_SAR::Count(),
107 			nM,
108 			nU = 0;
109 	if( nO > 0 )
110 	{
111 		nO--;
112 		while( nU <= nO )
113 		{
114 			nM = nU + ( nO - nU ) / 2;
115 			StringCompare eCmp = (*((StringPtr*)pData + nM))->
116 										CompareIgnoreCaseToAscii( *(aE) );
117 			if( COMPARE_EQUAL == eCmp )
118 			{
119 				if( pP ) *pP = nM;
120 				return sal_True;
121 			}
122 			else if( COMPARE_LESS == eCmp )
123 				nU = nM + 1;
124 			else if( nM == 0 )
125 			{
126 				if( pP ) *pP = nU;
127 				return sal_False;
128 			}
129 			else
130 				nO = nM - 1;
131 		}
132 	}
133 	if( pP ) *pP = nU;
134 	return sal_False;
135 }
136 
137 // ---------------- strings -------------------------------------
138 
139 // Array mit anderer Seek-Methode!
140 _SV_IMPL_SORTAR_ALG( SvStringsISortDtor, StringPtr )
141 void SvStringsISortDtor::DeleteAndDestroy( sal_uInt16 nP, sal_uInt16 nL )
142 {
143 	if( nL )
144 	{
145 		DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );
146 		for( sal_uInt16 n=nP; n < nP + nL; n++ )
147 			delete *((StringPtr*)pData+n);
148 		SvPtrarr::Remove( nP, nL );
149 	}
150 }
151 sal_Bool SvStringsISortDtor::Seek_Entry( const StringPtr aE, sal_uInt16* pP ) const
152 {
153 	register sal_uInt16 nO  = SvStringsISortDtor_SAR::Count(),
154 			nM,
155 			nU = 0;
156 	if( nO > 0 )
157 	{
158 		nO--;
159 		while( nU <= nO )
160 		{
161 			nM = nU + ( nO - nU ) / 2;
162 			StringCompare eCmp = (*((StringPtr*)pData + nM))->
163 									CompareIgnoreCaseToAscii( *(aE) );
164 			if( COMPARE_EQUAL == eCmp )
165 			{
166 				if( pP ) *pP = nM;
167 				return sal_True;
168 			}
169 			else if( COMPARE_LESS == eCmp )
170 				nU = nM + 1;
171 			else if( nM == 0 )
172 			{
173 				if( pP ) *pP = nU;
174 				return sal_False;
175 			}
176 			else
177 				nO = nM - 1;
178 		}
179 	}
180 	if( pP ) *pP = nU;
181 	return sal_False;
182 }
183 
184 // ---------------- Ushorts -------------------------------------
185 
186 /* SortArray fuer UShorts */
187 sal_Bool SvUShortsSort::Seek_Entry( const sal_uInt16 aE, sal_uInt16* pP ) const
188 {
189 	register sal_uInt16 nO  = SvUShorts::Count(),
190 			nM,
191 			nU = 0;
192 	if( nO > 0 )
193 	{
194 		nO--;
195 		while( nU <= nO )
196 		{
197 			nM = nU + ( nO - nU ) / 2;
198 			if( *(pData + nM) == aE )
199 			{
200 				if( pP ) *pP = nM;
201 				return sal_True;
202 			}
203 			else if( *(pData + nM) < aE )
204 				nU = nM + 1;
205 			else if( nM == 0 )
206 			{
207 				if( pP ) *pP = nU;
208 				return sal_False;
209 			}
210 			else
211 				nO = nM - 1;
212 		}
213 	}
214 	if( pP ) *pP = nU;
215 	return sal_False;
216 }
217 
218 void SvUShortsSort::Insert( const SvUShortsSort * pI, sal_uInt16 nS, sal_uInt16 nE )
219 {
220 	if( USHRT_MAX == nE )
221 		nE = pI->Count();
222 	sal_uInt16 nP;
223 	const sal_uInt16 * pIArr = pI->GetData();
224 	for( ; nS < nE; ++nS )
225 	{
226 		if( ! Seek_Entry( *(pIArr+nS), &nP) )
227 				SvUShorts::Insert( *(pIArr+nS), nP );
228 		if( ++nP >= Count() )
229 		{
230 			SvUShorts::Insert( pI, nP, nS+1, nE );
231 			nS = nE;
232 		}
233 	}
234 }
235 
236 sal_Bool SvUShortsSort::Insert( const sal_uInt16 aE )
237 {
238 	sal_uInt16 nP;
239 	sal_Bool bExist = Seek_Entry( aE, &nP );
240 	if( !bExist )
241 		SvUShorts::Insert( aE, nP );
242 	return !bExist;
243 }
244 
245 sal_Bool SvUShortsSort::Insert( const sal_uInt16 aE, sal_uInt16& rP )
246 {
247 	sal_Bool bExist = Seek_Entry( aE, &rP );
248 	if( !bExist )
249 		SvUShorts::Insert( aE, rP );
250 	return !bExist;
251 }
252 
253 void SvUShortsSort::Insert( const sal_uInt16* pE, sal_uInt16 nL)
254 {
255 	sal_uInt16 nP;
256 	for( sal_uInt16 n = 0; n < nL; ++n )
257 		if( ! Seek_Entry( *(pE+n), &nP ))
258 			SvUShorts::Insert( *(pE+n), nP );
259 }
260 
261 // remove ab Pos
262 void SvUShortsSort::RemoveAt( const sal_uInt16 nP, sal_uInt16 nL )
263 {
264 	if( nL )
265 		SvUShorts::Remove( nP, nL);
266 }
267 
268 // remove ab dem Eintrag
269 void SvUShortsSort::Remove( const sal_uInt16 aE, sal_uInt16 nL )
270 {
271 	sal_uInt16 nP;
272 	if( nL && Seek_Entry( aE, &nP ) )
273 		SvUShorts::Remove( nP, nL);
274 }
275 
276 // ---------------- bytestrings -------------------------------------
277 
278 // Array mit anderer Seek-Methode!
279 _SV_IMPL_SORTAR_ALG( SvByteStringsISort, ByteStringPtr )
280 void SvByteStringsISort::DeleteAndDestroy( sal_uInt16 nP, sal_uInt16 nL )
281 {
282 	if( nL )
283 	{
284 		DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );
285 		for( sal_uInt16 n=nP; n < nP + nL; n++ )
286 			delete *((ByteStringPtr*)pData+n);
287 		SvPtrarr::Remove( nP, nL );
288 	}
289 }
290 sal_Bool SvByteStringsISort::Seek_Entry( const ByteStringPtr aE, sal_uInt16* pP ) const
291 {
292 	register sal_uInt16 nO  = SvByteStringsISort_SAR::Count(),
293 			nM,
294 			nU = 0;
295 	if( nO > 0 )
296 	{
297 		nO--;
298 		while( nU <= nO )
299 		{
300 			nM = nU + ( nO - nU ) / 2;
301 			StringCompare eCmp = (*((ByteStringPtr*)pData + nM))->
302 						CompareIgnoreCaseToAscii( *(aE) );
303 			if( COMPARE_EQUAL == eCmp )
304 			{
305 				if( pP ) *pP = nM;
306 				return sal_True;
307 			}
308 			else if( COMPARE_LESS == eCmp )
309 				nU = nM + 1;
310 			else if( nM == 0 )
311 			{
312 				if( pP ) *pP = nU;
313 				return sal_False;
314 			}
315 			else
316 				nO = nM - 1;
317 		}
318 	}
319 	if( pP ) *pP = nU;
320 	return sal_False;
321 }
322 
323 
324 // Array mit anderer Seek-Methode!
325 _SV_IMPL_SORTAR_ALG( SvByteStringsISortDtor, ByteStringPtr )
326 void SvByteStringsISortDtor::DeleteAndDestroy( sal_uInt16 nP, sal_uInt16 nL )
327 {
328 	if( nL )
329 	{
330 		DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );
331 		for( sal_uInt16 n=nP; n < nP + nL; n++ )
332 			delete *((ByteStringPtr*)pData+n);
333 		SvPtrarr::Remove( nP, nL );
334 	}
335 }
336 sal_Bool SvByteStringsISortDtor::Seek_Entry( const ByteStringPtr aE, sal_uInt16* pP ) const
337 {
338 	register sal_uInt16 nO  = SvByteStringsISortDtor_SAR::Count(),
339 			nM,
340 			nU = 0;
341 	if( nO > 0 )
342 	{
343 		nO--;
344 		while( nU <= nO )
345 		{
346 			nM = nU + ( nO - nU ) / 2;
347 			StringCompare eCmp = (*((ByteStringPtr*)pData + nM))->
348 									CompareIgnoreCaseToAscii( *(aE) );
349 			if( COMPARE_EQUAL == eCmp )
350 			{
351 				if( pP ) *pP = nM;
352 				return sal_True;
353 			}
354 			else if( COMPARE_LESS == eCmp )
355 				nU = nM + 1;
356 			else if( nM == 0 )
357 			{
358 				if( pP ) *pP = nU;
359 				return sal_False;
360 			}
361 			else
362 				nO = nM - 1;
363 		}
364 	}
365 	if( pP ) *pP = nU;
366 	return sal_False;
367 }
368 
369