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