merge the formfield patch from ooo-build
[ooovba.git] / sfx2 / source / bastyp / minarray.cxx
blob592e20f15b799e3ce1fd8f6e508579035c3f0ca7
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: minarray.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
34 #ifndef GCC
35 #endif
37 #include <sfx2/minarray.hxx>
39 // -----------------------------------------------------------------------
41 SfxPtrArr::SfxPtrArr( BYTE nInitSize, BYTE nGrowSize ):
42 nUsed( 0 ),
43 nGrow( nGrowSize ? nGrowSize : 1 ),
44 nUnused( nInitSize )
46 DBG_MEMTEST();
47 USHORT nMSCBug = nInitSize;
49 if ( nMSCBug > 0 )
50 pData = new void*[nMSCBug];
51 else
52 pData = 0;
55 // -----------------------------------------------------------------------
57 SfxPtrArr::SfxPtrArr( const SfxPtrArr& rOrig )
59 DBG_MEMTEST();
60 nUsed = rOrig.nUsed;
61 nGrow = rOrig.nGrow;
62 nUnused = rOrig.nUnused;
64 if ( rOrig.pData != 0 )
66 pData = new void*[nUsed+nUnused];
67 memcpy( pData, rOrig.pData, nUsed*sizeof(void*) );
69 else
70 pData = 0;
73 // -----------------------------------------------------------------------
75 SfxPtrArr::~SfxPtrArr()
77 DBG_MEMTEST();
78 delete [] pData;
81 // -----------------------------------------------------------------------
83 SfxPtrArr& SfxPtrArr::operator=( const SfxPtrArr& rOrig )
85 DBG_MEMTEST();
87 delete [] pData;
89 nUsed = rOrig.nUsed;
90 nGrow = rOrig.nGrow;
91 nUnused = rOrig.nUnused;
93 if ( rOrig.pData != 0 )
95 pData = new void*[nUsed+nUnused];
96 memcpy( pData, rOrig.pData, nUsed*sizeof(void*) );
98 else
99 pData = 0;
100 return *this;
103 // -----------------------------------------------------------------------
105 void SfxPtrArr::Append( void* aElem )
107 DBG_MEMTEST();
108 DBG_ASSERT( sal::static_int_cast< unsigned >(nUsed+1) < ( USHRT_MAX / sizeof(void*) ), "array too large" );
109 // musz das Array umkopiert werden?
110 if ( nUnused == 0 )
112 USHORT nNewSize = (nUsed == 1) ? (nGrow==1 ? 2 : nGrow) : nUsed+nGrow;
113 void** pNewData = new void*[nNewSize];
114 if ( pData )
116 DBG_ASSERT( nUsed <= nNewSize, "" );
117 memmove( pNewData, pData, sizeof(void*)*nUsed );
118 delete [] pData;
120 nUnused = sal::static_int_cast< BYTE >(nNewSize-nUsed);
121 pData = pNewData;
124 // jetzt hinten in den freien Raum schreiben
125 pData[nUsed] = aElem;
126 ++nUsed;
127 --nUnused;
130 // -----------------------------------------------------------------------
132 USHORT SfxPtrArr::Remove( USHORT nPos, USHORT nLen )
134 DBG_MEMTEST();
135 // nLen adjustieren, damit nicht ueber das Ende hinaus geloescht wird
136 nLen = Min( (USHORT)(nUsed-nPos), nLen );
138 // einfache Aufgaben erfordern einfache Loesungen!
139 if ( nLen == 0 )
140 return 0;
142 // bleibt vielleicht keiner uebrig
143 if ( (nUsed-nLen) == 0 )
145 delete [] pData;
146 pData = 0;
147 nUsed = 0;
148 nUnused = 0;
149 return nLen;
152 // feststellen, ob das Array dadurch physikalisch schrumpft...
153 if ( (nUnused+nLen) >= nGrow )
155 // auf die naechste Grow-Grenze aufgerundet verkleinern
156 USHORT nNewUsed = nUsed-nLen;
157 USHORT nNewSize = ((nNewUsed+nGrow-1)/nGrow) * nGrow;
158 DBG_ASSERT( nNewUsed <= nNewSize && nNewUsed+nGrow > nNewSize,
159 "shrink size computation failed" );
160 void** pNewData = new void*[nNewSize];
161 if ( nPos > 0 )
163 DBG_ASSERT( nPos <= nNewSize, "" );
164 memmove( pNewData, pData, sizeof(void*)*nPos );
166 if ( nNewUsed != nPos )
167 memmove( pNewData+nPos, pData+nPos+nLen,
168 sizeof(void*)*(nNewUsed-nPos) );
169 delete [] pData;
170 pData = pNewData;
171 nUsed = nNewUsed;
172 nUnused = sal::static_int_cast< BYTE >(nNewSize - nNewUsed);
173 return nLen;
176 // in allen anderen Faellen nur zusammenschieben
177 if ( nUsed-nPos-nLen > 0 )
178 memmove( pData+nPos, pData+nPos+nLen, (nUsed-nPos-nLen)*sizeof(void*) );
179 nUsed = nUsed - nLen;
180 nUnused = sal::static_int_cast< BYTE >(nUnused + nLen);
181 return nLen;
184 // -----------------------------------------------------------------------
186 BOOL SfxPtrArr::Remove( void* aElem )
188 DBG_MEMTEST();
189 // einfache Aufgaben ...
190 if ( nUsed == 0 )
191 return FALSE;
193 // rueckwaerts, da meist der letzte zuerst wieder entfernt wird
194 void* *pIter = pData + nUsed - 1;
195 for ( USHORT n = 0; n < nUsed; ++n, --pIter )
196 if ( *pIter == aElem )
198 Remove(nUsed-n-1, 1);
199 return TRUE;
201 return FALSE;
204 // -----------------------------------------------------------------------
206 BOOL SfxPtrArr::Replace( void* aOldElem, void* aNewElem )
208 DBG_MEMTEST();
209 // einfache Aufgaben ...
210 if ( nUsed == 0 )
211 return FALSE;
213 // rueckwaerts, da meist der letzte zuerst wieder entfernt wird
214 void* *pIter = pData + nUsed - 1;
215 for ( USHORT n = 0; n < nUsed; ++n, --pIter )
216 if ( *pIter == aOldElem )
218 pData[nUsed-n-1] = aNewElem;
219 return TRUE;
221 return FALSE;
224 // -----------------------------------------------------------------------
226 BOOL SfxPtrArr::Contains( const void* rItem ) const
228 DBG_MEMTEST();
229 if ( !nUsed )
230 return FALSE;
232 for ( USHORT n = 0; n < nUsed; ++n )
234 void* p = GetObject(n);
235 if ( p == rItem )
236 return TRUE;
239 return FALSE;
242 // -----------------------------------------------------------------------
244 void SfxPtrArr::Insert( USHORT nPos, void* rElem )
246 DBG_MEMTEST();
247 DBG_ASSERT( sal::static_int_cast< unsigned >(nUsed+1) < ( USHRT_MAX / sizeof(void*) ), "array too large" );
248 // musz das Array umkopiert werden?
249 if ( nUnused == 0 )
251 // auf die naechste Grow-Grenze aufgerundet vergroeszern
252 USHORT nNewSize = nUsed+nGrow;
253 void** pNewData = new void*[nNewSize];
255 if ( pData )
257 DBG_ASSERT( nUsed < nNewSize, "" );
258 memmove( pNewData, pData, sizeof(void*)*nUsed );
259 delete [] pData;
261 nUnused = sal::static_int_cast< BYTE >(nNewSize-nUsed);
262 pData = pNewData;
265 // jetzt den hinteren Teil verschieben
266 if ( nPos < nUsed )
267 memmove( pData+nPos+1, pData+nPos, (nUsed-nPos)*sizeof(void*) );
269 // jetzt in den freien Raum schreiben
270 memmove( pData+nPos, &rElem, sizeof(void*) );
271 nUsed += 1;
272 nUnused -= 1;
275 // class ByteArr ---------------------------------------------------------
277 ByteArr::ByteArr( BYTE nInitSize, BYTE nGrowSize ):
278 nUsed( 0 ),
279 nGrow( nGrowSize ? nGrowSize : 1 ),
280 nUnused( nInitSize )
282 DBG_MEMTEST();
283 USHORT nMSCBug = nInitSize;
285 if ( nInitSize > 0 )
286 pData = new char[nMSCBug];
287 else
288 pData = 0;
291 // -----------------------------------------------------------------------
293 ByteArr::ByteArr( const ByteArr& rOrig )
295 DBG_MEMTEST();
296 nUsed = rOrig.nUsed;
297 nGrow = rOrig.nGrow;
298 nUnused = rOrig.nUnused;
300 if ( rOrig.pData != 0 )
302 pData = new char[nUsed+nUnused];
303 memcpy( pData, rOrig.pData, nUsed*sizeof(char) );
305 else
306 pData = 0;
309 // -----------------------------------------------------------------------
311 ByteArr::~ByteArr()
313 DBG_MEMTEST();
314 delete [] pData;
317 // -----------------------------------------------------------------------
319 ByteArr& ByteArr::operator=( const ByteArr& rOrig )
321 DBG_MEMTEST();
323 delete [] pData;
325 nUsed = rOrig.nUsed;
326 nGrow = rOrig.nGrow;
327 nUnused = rOrig.nUnused;
329 if ( rOrig.pData != 0 )
331 pData = new char[nUsed+nUnused];
332 memcpy( pData, rOrig.pData, nUsed*sizeof(char) );
334 else
335 pData = 0;
336 return *this;
339 // -----------------------------------------------------------------------
341 void ByteArr::Append( char aElem )
343 DBG_MEMTEST();
344 // musz das Array umkopiert werden?
345 if ( nUnused == 0 )
347 USHORT nNewSize = (nUsed == 1) ? (nGrow==1 ? 2 : nGrow) : nUsed+nGrow;
348 char* pNewData = new char[nNewSize];
349 if ( pData )
351 DBG_ASSERT( nUsed <= nNewSize, "" );
352 memmove( pNewData, pData, sizeof(char)*nUsed );
353 delete [] pData;
355 nUnused = sal::static_int_cast< BYTE >(nNewSize-nUsed);
356 pData = pNewData;
359 // jetzt hinten in den freien Raum schreiben
360 pData[nUsed] = aElem;
361 ++nUsed;
362 --nUnused;
365 // -----------------------------------------------------------------------
367 USHORT ByteArr::Remove( USHORT nPos, USHORT nLen )
369 DBG_MEMTEST();
370 // nLen adjustieren, damit nicht ueber das Ende hinaus geloescht wird
371 nLen = Min( (USHORT)(nUsed-nPos), nLen );
373 // einfache Aufgaben erfordern einfache Loesungen!
374 if ( nLen == 0 )
375 return 0;
377 // bleibt vielleicht keiner uebrig
378 if ( (nUsed-nLen) == 0 )
380 delete [] pData;
381 pData = 0;
382 nUsed = 0;
383 nUnused = 0;
384 return nLen;
387 // feststellen, ob das Array dadurch physikalisch schrumpft...
388 if ( (nUnused+nLen) >= nGrow )
390 // auf die naechste Grow-Grenze aufgerundet verkleinern
391 USHORT nNewUsed = nUsed-nLen;
392 USHORT nNewSize = ((nNewUsed+nGrow-1)/nGrow) * nGrow;
393 DBG_ASSERT( nNewUsed <= nNewSize && nNewUsed+nGrow > nNewSize,
394 "shrink size computation failed" );
395 char* pNewData = new char[nNewSize];
396 if ( nPos > 0 )
398 DBG_ASSERT( nPos <= nNewSize, "" );
399 memmove( pNewData, pData, sizeof(char)*nPos );
401 if ( nNewUsed != nPos )
402 memmove( pNewData+nPos, pData+nPos+nLen,
403 sizeof(char)*(nNewUsed-nPos) );
404 delete [] pData;
405 pData = pNewData;
406 nUsed = nNewUsed;
407 nUnused = sal::static_int_cast< BYTE >(nNewSize - nNewUsed);
408 return nLen;
411 // in allen anderen Faellen nur zusammenschieben
412 if ( nUsed-nPos-nLen > 0 )
413 memmove( pData+nPos, pData+nPos+nLen, (nUsed-nPos-nLen)*sizeof(char) );
414 nUsed = nUsed - nLen;
415 nUnused = sal::static_int_cast< BYTE >(nUnused + nLen);
416 return nLen;
419 // -----------------------------------------------------------------------
421 BOOL ByteArr::Remove( char aElem )
423 DBG_MEMTEST();
424 // einfache Aufgaben ...
425 if ( nUsed == 0 )
426 return FALSE;
428 // rueckwaerts, da meist der letzte zuerst wieder entfernt wird
429 char *pIter = pData + nUsed - 1;
430 for ( USHORT n = 0; n < nUsed; ++n, --pIter )
431 if ( *pIter == aElem )
433 Remove(nUsed-n-1, 1);
434 return TRUE;
436 return FALSE;
439 // -----------------------------------------------------------------------
441 BOOL ByteArr::Contains( const char rItem ) const
443 DBG_MEMTEST();
444 if ( !nUsed )
445 return FALSE;
447 for ( USHORT n = 0; n < nUsed; ++n )
449 char p = GetObject(n);
450 if ( p == rItem )
451 return TRUE;
454 return FALSE;
457 // -----------------------------------------------------------------------
459 void ByteArr::Insert( USHORT nPos, char rElem )
461 DBG_MEMTEST();
462 // musz das Array umkopiert werden?
463 if ( nUnused == 0 )
465 // auf die naechste Grow-Grenze aufgerundet vergroeszern
466 USHORT nNewSize = nUsed+nGrow;
467 char* pNewData = new char[nNewSize];
469 if ( pData )
471 DBG_ASSERT( nUsed < nNewSize, "" );
472 memmove( pNewData, pData, sizeof(char)*nUsed );
473 delete [] pData;
475 nUnused = sal::static_int_cast< BYTE >(nNewSize-nUsed);
476 pData = pNewData;
479 // jetzt den hinteren Teil verschieben
480 if ( nPos < nUsed )
481 memmove( pData+nPos+1, pData+nPos, (nUsed-nPos)*sizeof(char) );
483 // jetzt in den freien Raum schreiben
484 memmove( pData+nPos, &rElem, sizeof(char) );
485 nUsed += 1;
486 nUnused -= 1;
489 // -----------------------------------------------------------------------
491 char ByteArr::operator[]( USHORT nPos ) const
493 DBG_MEMTEST();
494 DBG_ASSERT( nPos < nUsed, "" );
495 return *(pData+nPos);
498 // -----------------------------------------------------------------------
500 char& ByteArr::operator [] (USHORT nPos)
502 DBG_MEMTEST();
503 DBG_ASSERT( nPos < nUsed, "" );
504 return *(pData+nPos);
507 // class WordArr ---------------------------------------------------------
509 WordArr::WordArr( BYTE nInitSize, BYTE nGrowSize ):
510 nUsed( 0 ),
511 nGrow( nGrowSize ? nGrowSize : 1 ),
512 nUnused( nInitSize )
514 DBG_MEMTEST();
515 USHORT nMSCBug = nInitSize;
517 if ( nInitSize > 0 )
518 pData = new short[nMSCBug];
519 else
520 pData = 0;
523 // -----------------------------------------------------------------------
525 WordArr::WordArr( const WordArr& rOrig )
527 DBG_MEMTEST();
528 nUsed = rOrig.nUsed;
529 nGrow = rOrig.nGrow;
530 nUnused = rOrig.nUnused;
532 if ( rOrig.pData != 0 )
534 pData = new short[nUsed+nUnused];
535 memcpy( pData, rOrig.pData, nUsed*sizeof(short) );
537 else
538 pData = 0;
541 // -----------------------------------------------------------------------
543 WordArr::~WordArr()
545 DBG_MEMTEST();
546 delete [] pData;
549 // -----------------------------------------------------------------------
551 WordArr& WordArr::operator=( const WordArr& rOrig )
553 DBG_MEMTEST();
555 delete [] pData;
557 nUsed = rOrig.nUsed;
558 nGrow = rOrig.nGrow;
559 nUnused = rOrig.nUnused;
561 if ( rOrig.pData != 0 )
563 pData = new short[nUsed+nUnused];
564 memcpy( pData, rOrig.pData, nUsed*sizeof(short) );
566 else
567 pData = 0;
568 return *this;
571 // -----------------------------------------------------------------------
573 void WordArr::Append( short aElem )
575 DBG_MEMTEST();
576 // musz das Array umkopiert werden?
577 if ( nUnused == 0 )
579 USHORT nNewSize = (nUsed == 1) ? (nGrow==1 ? 2 : nGrow) : nUsed+nGrow;
580 short* pNewData = new short[nNewSize];
581 if ( pData )
583 DBG_ASSERT( nUsed <= nNewSize, " " );
584 memmove( pNewData, pData, sizeof(short)*nUsed );
585 delete [] pData;
587 nUnused = sal::static_int_cast< BYTE >(nNewSize-nUsed);
588 pData = pNewData;
591 // jetzt hinten in den freien Raum schreiben
592 pData[nUsed] = aElem;
593 ++nUsed;
594 --nUnused;
597 // -----------------------------------------------------------------------
599 USHORT WordArr::Remove( USHORT nPos, USHORT nLen )
601 DBG_MEMTEST();
602 // nLen adjustieren, damit nicht ueber das Ende hinaus geloescht wird
603 nLen = Min( (USHORT)(nUsed-nPos), nLen );
605 // einfache Aufgaben erfordern einfache Loesungen!
606 if ( nLen == 0 )
607 return 0;
609 // bleibt vielleicht keiner uebrig
610 if ( (nUsed-nLen) == 0 )
612 delete [] pData;
613 pData = 0;
614 nUsed = 0;
615 nUnused = 0;
616 return nLen;
619 // feststellen, ob das Array dadurch physikalisch schrumpft...
620 if ( (nUnused+nLen) >= nGrow )
622 // auf die naechste Grow-Grenze aufgerundet verkleinern
623 USHORT nNewUsed = nUsed-nLen;
624 USHORT nNewSize = ((nNewUsed+nGrow-1)/nGrow) * nGrow;
625 DBG_ASSERT( nNewUsed <= nNewSize && nNewUsed+nGrow > nNewSize,
626 "shrink size computation failed" );
627 short* pNewData = new short[nNewSize];
628 if ( nPos > 0 )
630 DBG_ASSERT( nPos <= nNewSize, "" );
631 memmove( pNewData, pData, sizeof(short)*nPos );
633 if ( nNewUsed != nPos )
634 memmove( pNewData+nPos, pData+nPos+nLen,
635 sizeof(short)*(nNewUsed-nPos) );
636 delete [] pData;
637 pData = pNewData;
638 nUsed = nNewUsed;
639 nUnused = sal::static_int_cast< BYTE >(nNewSize - nNewUsed);
640 return nLen;
643 // in allen anderen Faellen nur zusammenschieben
644 if ( nUsed-nPos-nLen > 0 )
645 memmove( pData+nPos, pData+nPos+nLen, (nUsed-nPos-nLen)*sizeof(short) );
646 nUsed = nUsed - nLen;
647 nUnused = sal::static_int_cast< BYTE >(nUnused + nLen);
648 return nLen;
651 // -----------------------------------------------------------------------
653 BOOL WordArr::Remove( short aElem )
655 DBG_MEMTEST();
656 // einfache Aufgaben ...
657 if ( nUsed == 0 )
658 return FALSE;
660 // rueckwaerts, da meist der letzte zuerst wieder entfernt wird
661 short *pIter = pData + nUsed - 1;
662 for ( USHORT n = 0; n < nUsed; ++n, --pIter )
663 if ( *pIter == aElem )
665 Remove(nUsed-n-1, 1);
666 return TRUE;
668 return FALSE;
671 // -----------------------------------------------------------------------
673 BOOL WordArr::Contains( const short rItem ) const
675 DBG_MEMTEST();
676 if ( !nUsed )
677 return FALSE;
679 for ( USHORT n = 0; n < nUsed; ++n )
681 short p = GetObject(n);
682 if ( p == rItem )
683 return TRUE;
686 return FALSE;
689 // -----------------------------------------------------------------------
691 void WordArr::Insert( USHORT nPos, short rElem )
693 DBG_MEMTEST();
694 // musz das Array umkopiert werden?
695 if ( nUnused == 0 )
697 // auf die naechste Grow-Grenze aufgerundet vergroeszern
698 USHORT nNewSize = nUsed+nGrow;
699 short* pNewData = new short[nNewSize];
701 if ( pData )
703 DBG_ASSERT( nUsed < nNewSize, "" );
704 memmove( pNewData, pData, sizeof(short)*nUsed );
705 delete [] pData;
707 nUnused = sal::static_int_cast< BYTE >(nNewSize-nUsed);
708 pData = pNewData;
711 // jetzt den hinteren Teil verschieben
712 if ( nPos < nUsed )
713 memmove( pData+nPos+1, pData+nPos, (nUsed-nPos)*sizeof(short) );
715 // jetzt in den freien Raum schreiben
716 memmove( pData+nPos, &rElem, sizeof(short) );
717 nUsed += 1;
718 nUnused -= 1;
721 // -----------------------------------------------------------------------
723 short WordArr::operator[]( USHORT nPos ) const
725 DBG_MEMTEST();
726 DBG_ASSERT( nPos < nUsed, "" );
727 return *(pData+nPos);
730 // -----------------------------------------------------------------------
732 short& WordArr::operator [] (USHORT nPos)
734 DBG_MEMTEST();
735 DBG_ASSERT( nPos < nUsed, "" );
736 return *(pData+nPos);