1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: minarray.cxx,v $
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"
37 #include <sfx2/minarray.hxx>
39 // -----------------------------------------------------------------------
41 SfxPtrArr::SfxPtrArr( BYTE nInitSize
, BYTE nGrowSize
):
43 nGrow( nGrowSize
? nGrowSize
: 1 ),
47 USHORT nMSCBug
= nInitSize
;
50 pData
= new void*[nMSCBug
];
55 // -----------------------------------------------------------------------
57 SfxPtrArr::SfxPtrArr( const SfxPtrArr
& rOrig
)
62 nUnused
= rOrig
.nUnused
;
64 if ( rOrig
.pData
!= 0 )
66 pData
= new void*[nUsed
+nUnused
];
67 memcpy( pData
, rOrig
.pData
, nUsed
*sizeof(void*) );
73 // -----------------------------------------------------------------------
75 SfxPtrArr::~SfxPtrArr()
81 // -----------------------------------------------------------------------
83 SfxPtrArr
& SfxPtrArr::operator=( const SfxPtrArr
& rOrig
)
91 nUnused
= rOrig
.nUnused
;
93 if ( rOrig
.pData
!= 0 )
95 pData
= new void*[nUsed
+nUnused
];
96 memcpy( pData
, rOrig
.pData
, nUsed
*sizeof(void*) );
103 // -----------------------------------------------------------------------
105 void SfxPtrArr::Append( void* aElem
)
108 DBG_ASSERT( sal::static_int_cast
< unsigned >(nUsed
+1) < ( USHRT_MAX
/ sizeof(void*) ), "array too large" );
109 // musz das Array umkopiert werden?
112 USHORT nNewSize
= (nUsed
== 1) ? (nGrow
==1 ? 2 : nGrow
) : nUsed
+nGrow
;
113 void** pNewData
= new void*[nNewSize
];
116 DBG_ASSERT( nUsed
<= nNewSize
, "" );
117 memmove( pNewData
, pData
, sizeof(void*)*nUsed
);
120 nUnused
= sal::static_int_cast
< BYTE
>(nNewSize
-nUsed
);
124 // jetzt hinten in den freien Raum schreiben
125 pData
[nUsed
] = aElem
;
130 // -----------------------------------------------------------------------
132 USHORT
SfxPtrArr::Remove( USHORT nPos
, USHORT nLen
)
135 // nLen adjustieren, damit nicht ueber das Ende hinaus geloescht wird
136 nLen
= Min( (USHORT
)(nUsed
-nPos
), nLen
);
138 // einfache Aufgaben erfordern einfache Loesungen!
142 // bleibt vielleicht keiner uebrig
143 if ( (nUsed
-nLen
) == 0 )
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
];
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
) );
172 nUnused
= sal::static_int_cast
< BYTE
>(nNewSize
- nNewUsed
);
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
);
184 // -----------------------------------------------------------------------
186 BOOL
SfxPtrArr::Remove( void* aElem
)
189 // einfache Aufgaben ...
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);
204 // -----------------------------------------------------------------------
206 BOOL
SfxPtrArr::Replace( void* aOldElem
, void* aNewElem
)
209 // einfache Aufgaben ...
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
;
224 // -----------------------------------------------------------------------
226 BOOL
SfxPtrArr::Contains( const void* rItem
) const
232 for ( USHORT n
= 0; n
< nUsed
; ++n
)
234 void* p
= GetObject(n
);
242 // -----------------------------------------------------------------------
244 void SfxPtrArr::Insert( USHORT nPos
, void* rElem
)
247 DBG_ASSERT( sal::static_int_cast
< unsigned >(nUsed
+1) < ( USHRT_MAX
/ sizeof(void*) ), "array too large" );
248 // musz das Array umkopiert werden?
251 // auf die naechste Grow-Grenze aufgerundet vergroeszern
252 USHORT nNewSize
= nUsed
+nGrow
;
253 void** pNewData
= new void*[nNewSize
];
257 DBG_ASSERT( nUsed
< nNewSize
, "" );
258 memmove( pNewData
, pData
, sizeof(void*)*nUsed
);
261 nUnused
= sal::static_int_cast
< BYTE
>(nNewSize
-nUsed
);
265 // jetzt den hinteren Teil verschieben
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*) );
275 // class ByteArr ---------------------------------------------------------
277 ByteArr::ByteArr( BYTE nInitSize
, BYTE nGrowSize
):
279 nGrow( nGrowSize
? nGrowSize
: 1 ),
283 USHORT nMSCBug
= nInitSize
;
286 pData
= new char[nMSCBug
];
291 // -----------------------------------------------------------------------
293 ByteArr::ByteArr( const ByteArr
& rOrig
)
298 nUnused
= rOrig
.nUnused
;
300 if ( rOrig
.pData
!= 0 )
302 pData
= new char[nUsed
+nUnused
];
303 memcpy( pData
, rOrig
.pData
, nUsed
*sizeof(char) );
309 // -----------------------------------------------------------------------
317 // -----------------------------------------------------------------------
319 ByteArr
& ByteArr::operator=( const ByteArr
& rOrig
)
327 nUnused
= rOrig
.nUnused
;
329 if ( rOrig
.pData
!= 0 )
331 pData
= new char[nUsed
+nUnused
];
332 memcpy( pData
, rOrig
.pData
, nUsed
*sizeof(char) );
339 // -----------------------------------------------------------------------
341 void ByteArr::Append( char aElem
)
344 // musz das Array umkopiert werden?
347 USHORT nNewSize
= (nUsed
== 1) ? (nGrow
==1 ? 2 : nGrow
) : nUsed
+nGrow
;
348 char* pNewData
= new char[nNewSize
];
351 DBG_ASSERT( nUsed
<= nNewSize
, "" );
352 memmove( pNewData
, pData
, sizeof(char)*nUsed
);
355 nUnused
= sal::static_int_cast
< BYTE
>(nNewSize
-nUsed
);
359 // jetzt hinten in den freien Raum schreiben
360 pData
[nUsed
] = aElem
;
365 // -----------------------------------------------------------------------
367 USHORT
ByteArr::Remove( USHORT nPos
, USHORT nLen
)
370 // nLen adjustieren, damit nicht ueber das Ende hinaus geloescht wird
371 nLen
= Min( (USHORT
)(nUsed
-nPos
), nLen
);
373 // einfache Aufgaben erfordern einfache Loesungen!
377 // bleibt vielleicht keiner uebrig
378 if ( (nUsed
-nLen
) == 0 )
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
];
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
) );
407 nUnused
= sal::static_int_cast
< BYTE
>(nNewSize
- nNewUsed
);
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
);
419 // -----------------------------------------------------------------------
421 BOOL
ByteArr::Remove( char aElem
)
424 // einfache Aufgaben ...
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);
439 // -----------------------------------------------------------------------
441 BOOL
ByteArr::Contains( const char rItem
) const
447 for ( USHORT n
= 0; n
< nUsed
; ++n
)
449 char p
= GetObject(n
);
457 // -----------------------------------------------------------------------
459 void ByteArr::Insert( USHORT nPos
, char rElem
)
462 // musz das Array umkopiert werden?
465 // auf die naechste Grow-Grenze aufgerundet vergroeszern
466 USHORT nNewSize
= nUsed
+nGrow
;
467 char* pNewData
= new char[nNewSize
];
471 DBG_ASSERT( nUsed
< nNewSize
, "" );
472 memmove( pNewData
, pData
, sizeof(char)*nUsed
);
475 nUnused
= sal::static_int_cast
< BYTE
>(nNewSize
-nUsed
);
479 // jetzt den hinteren Teil verschieben
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) );
489 // -----------------------------------------------------------------------
491 char ByteArr::operator[]( USHORT nPos
) const
494 DBG_ASSERT( nPos
< nUsed
, "" );
495 return *(pData
+nPos
);
498 // -----------------------------------------------------------------------
500 char& ByteArr::operator [] (USHORT nPos
)
503 DBG_ASSERT( nPos
< nUsed
, "" );
504 return *(pData
+nPos
);
507 // class WordArr ---------------------------------------------------------
509 WordArr::WordArr( BYTE nInitSize
, BYTE nGrowSize
):
511 nGrow( nGrowSize
? nGrowSize
: 1 ),
515 USHORT nMSCBug
= nInitSize
;
518 pData
= new short[nMSCBug
];
523 // -----------------------------------------------------------------------
525 WordArr::WordArr( const WordArr
& rOrig
)
530 nUnused
= rOrig
.nUnused
;
532 if ( rOrig
.pData
!= 0 )
534 pData
= new short[nUsed
+nUnused
];
535 memcpy( pData
, rOrig
.pData
, nUsed
*sizeof(short) );
541 // -----------------------------------------------------------------------
549 // -----------------------------------------------------------------------
551 WordArr
& WordArr::operator=( const WordArr
& rOrig
)
559 nUnused
= rOrig
.nUnused
;
561 if ( rOrig
.pData
!= 0 )
563 pData
= new short[nUsed
+nUnused
];
564 memcpy( pData
, rOrig
.pData
, nUsed
*sizeof(short) );
571 // -----------------------------------------------------------------------
573 void WordArr::Append( short aElem
)
576 // musz das Array umkopiert werden?
579 USHORT nNewSize
= (nUsed
== 1) ? (nGrow
==1 ? 2 : nGrow
) : nUsed
+nGrow
;
580 short* pNewData
= new short[nNewSize
];
583 DBG_ASSERT( nUsed
<= nNewSize
, " " );
584 memmove( pNewData
, pData
, sizeof(short)*nUsed
);
587 nUnused
= sal::static_int_cast
< BYTE
>(nNewSize
-nUsed
);
591 // jetzt hinten in den freien Raum schreiben
592 pData
[nUsed
] = aElem
;
597 // -----------------------------------------------------------------------
599 USHORT
WordArr::Remove( USHORT nPos
, USHORT nLen
)
602 // nLen adjustieren, damit nicht ueber das Ende hinaus geloescht wird
603 nLen
= Min( (USHORT
)(nUsed
-nPos
), nLen
);
605 // einfache Aufgaben erfordern einfache Loesungen!
609 // bleibt vielleicht keiner uebrig
610 if ( (nUsed
-nLen
) == 0 )
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
];
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
) );
639 nUnused
= sal::static_int_cast
< BYTE
>(nNewSize
- nNewUsed
);
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
);
651 // -----------------------------------------------------------------------
653 BOOL
WordArr::Remove( short aElem
)
656 // einfache Aufgaben ...
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);
671 // -----------------------------------------------------------------------
673 BOOL
WordArr::Contains( const short rItem
) const
679 for ( USHORT n
= 0; n
< nUsed
; ++n
)
681 short p
= GetObject(n
);
689 // -----------------------------------------------------------------------
691 void WordArr::Insert( USHORT nPos
, short rElem
)
694 // musz das Array umkopiert werden?
697 // auf die naechste Grow-Grenze aufgerundet vergroeszern
698 USHORT nNewSize
= nUsed
+nGrow
;
699 short* pNewData
= new short[nNewSize
];
703 DBG_ASSERT( nUsed
< nNewSize
, "" );
704 memmove( pNewData
, pData
, sizeof(short)*nUsed
);
707 nUnused
= sal::static_int_cast
< BYTE
>(nNewSize
-nUsed
);
711 // jetzt den hinteren Teil verschieben
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) );
721 // -----------------------------------------------------------------------
723 short WordArr::operator[]( USHORT nPos
) const
726 DBG_ASSERT( nPos
< nUsed
, "" );
727 return *(pData
+nPos
);
730 // -----------------------------------------------------------------------
732 short& WordArr::operator [] (USHORT nPos
)
735 DBG_ASSERT( nPos
< nUsed
, "" );
736 return *(pData
+nPos
);