1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23 #ifndef _SFXVARARR_HXX
24 #define _SFXVARARR_HXX
25
26 #include "sal/config.h"
27 #include "sfx2/dllapi.h"
28
29 #include <limits.h>
30 #include <string.h>
31 #include <tools/solar.h>
32 #include <tools/debug.hxx>
33 //#include "typecast.hxx"
34
35 #if defined (ALPHA) && defined (UNX)
36 #define DEL_ARRAY( X )
37 #else
38 #define DEL_ARRAY( X ) X
39 #endif
40
41 #define DECL_OBJARRAY( ARR, T, nI, nG ) \
42 class ARR\
43 {\
44 private:\
45 T* pData;\
46 sal_uInt16 nUsed;\
47 sal_uInt8 nGrow;\
48 sal_uInt8 nUnused;\
49 public:\
50 ARR( sal_uInt8 nInitSize = nI, sal_uInt8 nGrowSize = nG );\
51 ARR( const ARR& rOrig );\
52 ~ARR();\
53 \
54 ARR& operator= ( const ARR& rOrig );\
55 \
56 const T& GetObject( sal_uInt16 nPos ) const; \
57 T& GetObject( sal_uInt16 nPos ); \
58 \
59 void Insert( sal_uInt16 nPos, ARR& rIns, sal_uInt16 nStart = 0, sal_uInt16 nEnd = USHRT_MAX );\
60 void Insert( sal_uInt16 nPos, const T& rElem );\
61 void Insert( sal_uInt16 nPos, const T& rElems, sal_uInt16 nLen );\
62 void Append( const T& rElem );\
63 \
64 sal_Bool Remove( const T& rElem );\
65 sal_uInt16 Remove( sal_uInt16 nPos, sal_uInt16 nLen );\
66 \
67 sal_uInt16 Count() const { return nUsed; }\
68 T* operator*();\
69 const T& operator[]( sal_uInt16 nPos ) const;\
70 T& operator[]( sal_uInt16 nPos );\
71 \
72 sal_Bool Contains( const T& rItem ) const;\
73 void Clear() { Remove( 0, Count() ); }\
74 };\
75 \
76 inline void ARR::Insert( sal_uInt16 nPos, ARR& rIns, sal_uInt16 nStart, sal_uInt16 nEnd )\
77 {\
78 Insert( nPos, *(rIns.pData+(sizeof(T)*nStart)), nStart-nEnd+1 );\
79 }\
80 \
81 inline void ARR::Insert( sal_uInt16 nPos, const T& rElem )\
82 {\
83 Insert( nPos, rElem, 1 );\
84 }\
85 \
86 inline T* ARR::operator*()\
87 {\
88 return ( nUsed==0 ? 0 : pData );\
89 } \
90 inline const T& ARR::operator[]( sal_uInt16 nPos ) const\
91 {\
92 DBG_ASSERT( nPos < nUsed, "" ); \
93 return *(pData+nPos);\
94 } \
95 inline T& ARR::operator [] (sal_uInt16 nPos) \
96 {\
97 DBG_ASSERT( nPos < nUsed, "" ); \
98 return *(pData+nPos); \
99 } \
100 inline const T& ARR::GetObject( sal_uInt16 nPos ) const { return operator[](nPos); } \
101 inline T& ARR::GetObject( sal_uInt16 nPos ) { return operator[](nPos); } \
102
103 #ifndef _lint
104 // String too long
105
106 #define IMPL_OBJARRAY( ARR, T ) \
107 ARR::ARR( sal_uInt8 nInitSize, sal_uInt8 nGrowSize ): \
108 nUsed(0), \
109 nGrow( nGrowSize ? nGrowSize : 1 ), \
110 nUnused(nInitSize) \
111 { \
112 if ( nInitSize != 0 ) \
113 { \
114 size_t nBytes = nInitSize * sizeof(T); \
115 pData = (T*) new char[ nBytes ]; \
116 memset( pData, 0, nBytes ); \
117 } \
118 else \
119 pData = 0; \
120 } \
121 \
122 ARR::ARR( const ARR& rOrig ) \
123 { \
124 nUsed = rOrig.nUsed; \
125 nGrow = rOrig.nGrow; \
126 nUnused = rOrig.nUnused; \
127 \
128 if ( rOrig.pData != 0 ) \
129 { \
130 size_t nBytes = (nUsed + nUnused) * sizeof(T); \
131 pData = (T*) new char [ nBytes ]; \
132 memset( pData, 0, nBytes ); \
133 for ( sal_uInt16 n = 0; n < nUsed; ++n ) \
134 *(pData+n) = *(rOrig.pData+n); \
135 } \
136 else \
137 pData = 0; \
138 } \
139 \
140 ARR::~ARR() \
141 { \
142 for ( sal_uInt16 n = 0; n < nUsed; ++n ) \
143 ( pData+n )->T::~T(); \
144 delete[] (char*) pData;\
145 } \
146 \
147 ARR& ARR::operator= ( const ARR& rOrig )\
148 { \
149 for ( sal_uInt16 n = 0; n < nUsed; ++n ) \
150 ( pData+n )->T::~T(); \
151 delete[] (char*) pData;\
152 \
153 nUsed = rOrig.nUsed; \
154 nGrow = rOrig.nGrow; \
155 nUnused = rOrig.nUnused; \
156 \
157 if ( rOrig.pData != 0 ) \
158 { \
159 size_t nBytes = (nUsed + nUnused) * sizeof(T); \
160 pData = (T*) new char[ nBytes ]; \
161 memset( pData, 0, nBytes ); \
162 for ( sal_uInt16 n = 0; n < nUsed; ++n ) \
163 *(pData+n) = *(rOrig.pData+n); \
164 } \
165 else \
166 pData = 0; \
167 return *this; \
168 } \
169 \
170 void ARR::Append( const T& aElem ) \
171 { \
172 \
173 if ( nUnused == 0 ) \
174 { \
175 sal_uInt16 nNewSize = (nUsed == 1) ? (nGrow==1 ? 2 : nGrow) : nUsed+nGrow; \
176 size_t nBytes = nNewSize * sizeof(T); \
177 T* pNewData = (T*) new char[ nBytes ]; \
178 memset( pNewData, 0, nBytes ); \
179 if ( pData ) \
180 { \
181 memcpy( pNewData, pData, nUsed * sizeof(T) ); \
182 delete[] (char*) pData;\
183 } \
184 nUnused = (sal_uInt8)(nNewSize-nUsed); \
185 pData = pNewData; \
186 } \
187 \
188 \
189 pData[nUsed] = aElem; \
190 ++nUsed; \
191 --nUnused; \
192 } \
193 \
194 sal_uInt16 ARR::Remove( sal_uInt16 nPos, sal_uInt16 nLen ) \
195 { \
196 DBG_ASSERT( (nPos+nLen) < (nUsed+1), "" ); \
197 DBG_ASSERT( nLen > 0, "" ); \
198 \
199 nLen = Min( (sal_uInt16)(nUsed-nPos), (sal_uInt16)nLen ); \
200 \
201 if ( nLen == 0 ) \
202 return 0; \
203 \
204 for ( sal_uInt16 n = nPos; n < (nPos+nLen); ++n ) \
205 ( pData+n )->T::~T(); \
206 \
207 if ( (nUsed-nLen) == 0 ) \
208 { \
209 delete[] (char*) pData;\
210 pData = 0; \
211 nUsed = 0; \
212 nUnused = 0; \
213 return nLen; \
214 } \
215 \
216 if ( (nUnused+nLen) >= nGrow ) \
217 { \
218 sal_uInt16 nNewUsed = nUsed-nLen; \
219 sal_uInt16 nNewSize = ((nNewUsed+nGrow-1)/nGrow) * nGrow; \
220 DBG_ASSERT( nNewUsed <= nNewSize && nNewUsed+nGrow > nNewSize, \
221 "shrink size computation failed" ); \
222 size_t nBytes = nNewSize * sizeof(T); \
223 T* pNewData = (T*) new char[ nBytes ]; \
224 memset( pNewData, 0, nBytes ); \
225 if ( nPos > 0 ) \
226 memcpy( pNewData, pData, nPos * sizeof(T) ); \
227 if ( nNewUsed != nPos ) \
228 memcpy(pNewData+nPos, pData+nPos+nLen, (nNewUsed-nPos) * sizeof(T) ); \
229 delete[] (char*) pData;\
230 pData = pNewData; \
231 nUsed = nNewUsed; \
232 nUnused = (sal_uInt8)(nNewSize - nNewUsed); \
233 return nLen; \
234 } \
235 \
236 \
237 if ( nUsed-nPos-nLen > 0 ) \
238 { \
239 memmove(pData+nPos, pData+nPos+nLen, (nUsed-nPos-nLen) * sizeof(T));\
240 } \
241 nUsed = nUsed - nLen; \
242 nUnused = sal::static_int_cast< sal_uInt8 >(nUnused + nLen); \
243 return nLen; \
244 } \
245 \
246 sal_Bool ARR::Remove( const T& aElem ) \
247 { \
248 if ( nUsed == 0 ) \
249 return sal_False; \
250 \
251 const T *pIter = pData + nUsed - 1; \
252 for ( sal_uInt16 n = 0; n < nUsed; ++n, --pIter ) \
253 if ( *pIter == aElem ) \
254 { \
255 Remove(nUsed-n-1, 1); \
256 return sal_True; \
257 } \
258 return sal_False; \
259 } \
260 \
261 sal_Bool ARR::Contains( const T& rItem ) const \
262 { \
263 if ( !nUsed ) \
264 return sal_False; \
265 for ( sal_uInt16 n = 0; n < nUsed; ++n ) \
266 { \
267 const T& r2ndItem = GetObject(n); \
268 if ( r2ndItem == rItem ) \
269 return sal_True; \
270 } \
271 return sal_False; \
272 } \
273 \
274 void ARR::Insert( sal_uInt16 nPos, const T& rElems, sal_uInt16 nLen ) \
275 { \
276 DBG_ASSERT( nPos <= nUsed, "" ); \
277 \
278 if ( nUnused == 0 ) \
279 { \
280 \
281 /* auf die naechste Grow-Grenze aufgerundet vergroeszern */ \
282 sal_uInt16 nNewSize; \
283 for ( nNewSize = nUsed+nGrow; nNewSize < (nUsed + nLen); ++nNewSize ) \
284 /* empty loop */; \
285 size_t nBytes = nNewSize * sizeof(T); \
286 T* pNewData = (T*) new char[ nBytes ]; \
287 memset( pNewData, 0, nBytes ); \
288 \
289 if ( pData ) \
290 { \
291 DBG_ASSERT( nUsed < nNewSize, "" ); \
292 memcpy( pNewData, pData, nUsed * sizeof(T) ); \
293 delete (char*) pData;\
294 } \
295 nUnused = (sal_uInt8)(nNewSize-nUsed); \
296 pData = pNewData; \
297 } \
298 \
299 \
300 if ( nPos < nUsed ) \
301 { \
302 memmove(pData+nPos+nLen-1, pData+nPos-1, sizeof(T) * (nUsed-nPos)); \
303 } \
304 \
305 memmove(pData+nPos, &rElems, sizeof(T) * nLen); \
306 nUsed = nUsed + nLen; \
307 nUnused = sal::static_int_cast< sal_uInt8 >(nUnused - nLen); \
308 }
309
310 // _lint
311 #endif
312
313 class SFX2_DLLPUBLIC SfxPtrArr
314 {
315 private:
316 void** pData;
317 sal_uInt16 nUsed;
318 sal_uInt8 nGrow;
319 sal_uInt8 nUnused;
320 public:
321 SfxPtrArr( sal_uInt8 nInitSize = 0, sal_uInt8 nGrowSize = 8 );
322 SfxPtrArr( const SfxPtrArr& rOrig );
323 ~SfxPtrArr();
324 SfxPtrArr& operator= ( const SfxPtrArr& rOrig );
GetObject(sal_uInt16 nPos) const325 void* GetObject( sal_uInt16 nPos ) const { return operator[](nPos); }
GetObject(sal_uInt16 nPos)326 void*& GetObject( sal_uInt16 nPos ) { return operator[](nPos); }
327 void Insert( sal_uInt16 nPos, void* rElem );
328 void Append( void* rElem );
329 sal_Bool Replace( void* pOldElem, void* pNewElem );
330 sal_Bool Remove( void* rElem );
331 sal_uInt16 Remove( sal_uInt16 nPos, sal_uInt16 nLen );
Count() const332 sal_uInt16 Count() const { return nUsed; }
333 inline void** operator*();
334 inline void* operator[]( sal_uInt16 nPos ) const;
335 inline void*& operator[]( sal_uInt16 nPos );
336 sal_Bool Contains( const void* rItem ) const;
Clear()337 void Clear() { Remove( 0, Count() ); }
338 };
339
operator *()340 inline void** SfxPtrArr::operator*()
341 {
342 return ( nUsed==0 ? 0 : pData );
343 }
344
operator [](sal_uInt16 nPos) const345 inline void* SfxPtrArr::operator[]( sal_uInt16 nPos ) const
346 {
347 DBG_ASSERT( nPos < nUsed, "" );
348 return *(pData+nPos);
349 }
350
operator [](sal_uInt16 nPos)351 inline void*& SfxPtrArr::operator [] (sal_uInt16 nPos)
352 {
353 DBG_ASSERT( nPos < nUsed, "" );
354 return *(pData+nPos);
355 }
356
357
358 #define DECL_PTRARRAY(ARR, T, nI, nG)\
359 class ARR: public SfxPtrArr\
360 {\
361 public:\
362 ARR( sal_uInt8 nIni=nI, sal_uInt8 nGrowValue=nG ):\
363 SfxPtrArr(nIni,nGrowValue) \
364 {}\
365 ARR( const ARR& rOrig ):\
366 SfxPtrArr(rOrig) \
367 {}\
368 T GetObject( sal_uInt16 nPos ) const { return operator[](nPos); } \
369 T& GetObject( sal_uInt16 nPos ) { return operator[](nPos); } \
370 void Insert( sal_uInt16 nPos, T aElement ) {\
371 SfxPtrArr::Insert(nPos,(void *)aElement);\
372 }\
373 void Append( T aElement ) {\
374 SfxPtrArr::Append((void *)aElement);\
375 }\
376 sal_Bool Replace( T aOldElem, T aNewElem ) {\
377 return SfxPtrArr::Replace((void *)aOldElem, (void*) aNewElem);\
378 }\
379 void Remove( T aElement ) {\
380 SfxPtrArr::Remove((void*)aElement);\
381 }\
382 void Remove( sal_uInt16 nPos, sal_uInt16 nLen = 1 ) {\
383 SfxPtrArr::Remove( nPos, nLen ); \
384 }\
385 T* operator *() {\
386 return (T*) SfxPtrArr::operator*();\
387 }\
388 T operator[]( sal_uInt16 nPos ) const { \
389 return (T) SfxPtrArr::operator[](nPos); } \
390 T& operator[]( sal_uInt16 nPos ) { \
391 return (T&) SfxPtrArr::operator[](nPos); } \
392 void Clear() { Remove( 0, Count() ); }\
393 };
394
395 class ByteArr
396 {
397 private:
398 char* pData;
399 sal_uInt16 nUsed;
400 sal_uInt8 nGrow;
401 sal_uInt8 nUnused;
402 public:
403 ByteArr( sal_uInt8 nInitSize = 0, sal_uInt8 nGrowSize = 8 );
404 ByteArr( const ByteArr& rOrig );
405 ~ByteArr();
406 ByteArr& operator= ( const ByteArr& rOrig );
GetObject(sal_uInt16 nPos) const407 char GetObject( sal_uInt16 nPos ) const { return operator[](nPos); }
GetObject(sal_uInt16 nPos)408 char& GetObject( sal_uInt16 nPos ) { return operator[](nPos); }
409 void Insert( sal_uInt16 nPos, char rElem );
410 void Append( char rElem );
411 sal_Bool Remove( char rElem );
412 sal_uInt16 Remove( sal_uInt16 nPos, sal_uInt16 nLen );
Count() const413 sal_uInt16 Count() const { return nUsed; }
414 char* operator*();
415 char operator[]( sal_uInt16 nPos ) const;
416 char& operator[]( sal_uInt16 nPos );
417 sal_Bool Contains( const char rItem ) const;
Clear()418 void Clear() { Remove( 0, Count() ); }
419 };
420
operator *()421 inline char* ByteArr::operator*()
422 {
423 return ( nUsed==0 ? 0 : pData );
424 }
425
426 #define DECL_1BYTEARRAY(ARR, T, nI, nG)\
427 class ARR: public ByteArr\
428 {\
429 public:\
430 ARR( sal_uInt8 nIni=nI, sal_uInt8 nGrow=nG ):\
431 ByteArr(nIni,nGrow) \
432 {}\
433 ARR( const ARR& rOrig ):\
434 ByteArr(rOrig) \
435 {}\
436 T GetObject( sal_uInt16 nPos ) const { return operator[](nPos); } \
437 T& GetObject( sal_uInt16 nPos ) { return operator[](nPos); } \
438 void Insert( sal_uInt16 nPos, T aElement ) {\
439 ByteArr::Insert(nPos,(char)aElement);\
440 }\
441 void Append( T aElement ) {\
442 ByteArr::Append((char)aElement);\
443 }\
444 void Remove( T aElement ) {\
445 ByteArr::Remove((char)aElement);\
446 }\
447 void Remove( sal_uInt16 nPos, sal_uInt16 nLen = 1 ) {\
448 ByteArr::Remove( nPos, nLen ); \
449 }\
450 T* operator *() {\
451 return (T*) ByteArr::operator*();\
452 }\
453 T operator[]( sal_uInt16 nPos ) const { \
454 return (T) ByteArr::operator[](nPos); } \
455 T& operator[]( sal_uInt16 nPos ) { \
456 return (T&) ByteArr::operator[](nPos); } \
457 void Clear() { Remove( 0, Count() ); }\
458 };
459
460 class WordArr
461 {
462 private:
463 short* pData;
464 sal_uInt16 nUsed;
465 sal_uInt8 nGrow;
466 sal_uInt8 nUnused;
467 public:
468 WordArr( sal_uInt8 nInitSize = 0, sal_uInt8 nGrowSize = 8 );
469 WordArr( const WordArr& rOrig );
470 ~WordArr();
471 WordArr& operator= ( const WordArr& rOrig );
GetObject(sal_uInt16 nPos) const472 short GetObject( sal_uInt16 nPos ) const { return operator[](nPos); }
GetObject(sal_uInt16 nPos)473 short& GetObject( sal_uInt16 nPos ) { return operator[](nPos); }
474 void Insert( sal_uInt16 nPos, short rElem );
475 void Append( short rElem );
476 sal_Bool Remove( short rElem );
477 sal_uInt16 Remove( sal_uInt16 nPos, sal_uInt16 nLen );
Count() const478 sal_uInt16 Count() const { return nUsed; }
479 short* operator*();
480 short operator[]( sal_uInt16 nPos ) const;
481 short& operator[]( sal_uInt16 nPos );
482 sal_Bool Contains( const short rItem ) const;
Clear()483 void Clear() { Remove( 0, Count() ); }
484 };
485
operator *()486 inline short* WordArr::operator*()
487 {
488 return ( nUsed==0 ? 0 : pData );
489 }
490
491 #define DECL_2BYTEARRAY(ARR, T, nI, nG)\
492 class ARR: public WordArr\
493 {\
494 public:\
495 ARR( sal_uInt8 nIni=nI, sal_uInt8 nGrowValue=nG ):\
496 WordArr(nIni,nGrowValue) \
497 {}\
498 ARR( const ARR& rOrig ):\
499 WordArr(rOrig) \
500 {}\
501 T GetObject( sal_uInt16 nPos ) const { return operator[](nPos); } \
502 T& GetObject( sal_uInt16 nPos ) { return operator[](nPos); } \
503 void Insert( sal_uInt16 nPos, T aElement ) {\
504 WordArr::Insert(nPos,(short)aElement);\
505 }\
506 void Append( T aElement ) {\
507 WordArr::Append((short)aElement);\
508 }\
509 void Remove( T aElement ) {\
510 WordArr::Remove((short)aElement);\
511 }\
512 void Remove( sal_uInt16 nPos, sal_uInt16 nLen = 1 ) {\
513 WordArr::Remove( nPos, nLen ); \
514 }\
515 T* operator *() {\
516 return (T*) WordArr::operator*();\
517 }\
518 T operator[]( sal_uInt16 nPos ) const { \
519 return (T) WordArr::operator[](nPos); } \
520 T& operator[]( sal_uInt16 nPos ) { \
521 return (T&) WordArr::operator[](nPos); } \
522 void Clear() { Remove( 0, Count() ); }\
523 };
524
525 #endif
526