xref: /trunk/main/svl/source/memtools/svarray.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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