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
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_tools.hxx"
26
27 #ifndef _LIMITS_H
28 #include <limits.h>
29 #endif
30
31 #ifndef _STRING_H
32 #include <string.h>
33 #endif
34
35 #ifndef _STDIO_H
36 #include <stdio.h>
37 #endif
38 #include <tools/solar.h>
39 #include <impcont.hxx>
40 #include <tools/contnr.hxx>
41 #include <tools/debug.hxx>
42
43 // -----------------------------------------------------------------------
44
45 DBG_NAME( CBlock )
DBG_NAME(Container) const46 DBG_NAME( Container )
47
48 /*************************************************************************
49 |*
50 |* DbgCheckCBlock()
51 |*
52 |* Beschreibung Pruefung eines CBlock fuer Debug-Utilities
53 |* Ersterstellung MI 30.01.92
54 |* Letzte Aenderung TH 24.01.96
55 |*
56 *************************************************************************/
57
58 #ifdef DBG_UTIL
59 const char* CBlock::DbgCheckCBlock( const void* pBlock )
60 {
61 CBlock* p = (CBlock*)pBlock;
62
63 if ( p->nCount > p->nSize )
64 return "nCount > nSize";
65
66 if ( p->nSize && !p->pNodes )
67 return "nSize > 0 && pNodes == NULL";
68
69 return NULL;
70 }
71 #endif
72
73 /*************************************************************************
74 |*
75 |* CBlock::CBlock()
76 |*
77 |* Beschreibung Construktor des Verwaltungsblocks
78 |* Ersterstellung TH 17.09.91
79 |* Letzte Aenderung TH 17.09.91
80 |*
81 *************************************************************************/
82
CBlock(sal_uInt16 nInitSize,CBlock * _pPrev,CBlock * _pNext)83 CBlock::CBlock( sal_uInt16 nInitSize, CBlock* _pPrev, CBlock* _pNext )
84 {
85 DBG_CTOR( CBlock, DbgCheckCBlock );
86
87 pPrev = _pPrev;
88 pNext = _pNext;
89 nSize = nInitSize;
90 nCount = 0;
91
92 // Datenpuffer anlegen
93 pNodes = new PVOID[nSize];
94 }
95
96 /*************************************************************************
97 |*
98 |* CBlock::CBlock()
99 |*
100 |* Beschreibung Construktor des Verwaltungsblocks
101 |* Ersterstellung TH 17.09.91
102 |* Letzte Aenderung TH 17.09.91
103 |*
104 *************************************************************************/
105
CBlock(sal_uInt16 _nSize,CBlock * _pPrev)106 CBlock::CBlock( sal_uInt16 _nSize, CBlock* _pPrev )
107 {
108 DBG_CTOR( CBlock, DbgCheckCBlock );
109 DBG_ASSERT( _nSize, "CBlock::CBlock(): nSize == 0" );
110
111 pPrev = _pPrev;
112 pNext = NULL;
113 nSize = _nSize;
114 nCount = _nSize;
115
116 // Datenpuffer anlegen und initialisieren
117 pNodes = new PVOID[nSize];
118 memset( pNodes, 0, nSize*sizeof(PVOID) );
119 }
120
121 /*************************************************************************
122 |*
123 |* CBlock::CBlock()
124 |*
125 |* Beschreibung Copy-Construktor des Verwaltungsblocks
126 |* Ersterstellung TH 17.09.91
127 |* Letzte Aenderung TH 17.09.91
128 |*
129 *************************************************************************/
130
CBlock(const CBlock & r,CBlock * _pPrev)131 CBlock::CBlock( const CBlock& r, CBlock* _pPrev )
132 {
133 DBG_CTOR( CBlock, DbgCheckCBlock );
134 DBG_CHKOBJ( &r, CBlock, DbgCheckCBlock );
135
136 pPrev = _pPrev;
137 pNext = NULL;
138 nSize = r.nSize;
139 nCount = r.nCount;
140
141 // Datenpuffer anlegen und Daten kopieren
142 pNodes = new PVOID[nSize];
143 memcpy( pNodes, r.pNodes, nCount*sizeof(PVOID) );
144 }
145
146 /*************************************************************************
147 |*
148 |* CBlock::~CBlock()
149 |*
150 |* Beschreibung Destruktor des Verwaltungsblocks
151 |* Ersterstellung TH 17.09.91
152 |* Letzte Aenderung TH 17.09.91
153 |*
154 *************************************************************************/
155
~CBlock()156 inline CBlock::~CBlock()
157 {
158 DBG_DTOR( CBlock, DbgCheckCBlock );
159
160 // Daten loeschen
161 delete[] pNodes;
162 }
163
164 /*************************************************************************
165 |*
166 |* CBlock::Insert()
167 |*
168 |* Beschreibung Fuegt einen Pointer ein
169 |* Ersterstellung TH 17.09.91
170 |* Letzte Aenderung TH 17.09.91
171 |*
172 *************************************************************************/
173
Insert(void * p,sal_uInt16 nIndex,sal_uInt16 nReSize)174 void CBlock::Insert( void* p, sal_uInt16 nIndex, sal_uInt16 nReSize )
175 {
176 DBG_CHKTHIS( CBlock, DbgCheckCBlock );
177 DBG_ASSERT( nIndex <= nCount, "CBlock::Insert(): Index > nCount" );
178
179 // Muss Block realokiert werden
180 if ( nCount == nSize )
181 {
182 // Neue Daten anlegen
183 nSize = nSize + nReSize; // MSVC warns here if += is used
184 void** pNewNodes = new PVOID[nSize];
185
186 // Wird angehaengt
187 if ( nCount == nIndex )
188 {
189 // Daten kopieren
190 memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) );
191 }
192 else
193 {
194 // Daten kopieren
195 memcpy( pNewNodes, pNodes, nIndex*sizeof(PVOID) );
196 memcpy( pNewNodes + nIndex + 1,
197 pNodes + nIndex,
198 (nCount-nIndex)*sizeof(PVOID) );
199 }
200
201 // Alte Daten loeschen und neue setzen
202 delete[] pNodes;
203 pNodes = pNewNodes;
204 }
205 else
206 {
207 if ( nIndex < nCount )
208 {
209 memmove( pNodes + nIndex + 1,
210 pNodes + nIndex,
211 (nCount-nIndex)*sizeof(PVOID) );
212 }
213 }
214
215 // Neuen Pointer setzen und Elementgroesse erhoehen
216 pNodes[nIndex] = p;
217 nCount++;
218 }
219
220 /*************************************************************************
221 |*
222 |* CBlock::Split()
223 |*
224 |* Beschreibung Fuegt einen Pointer ein und splittet den Block
225 |* Ersterstellung TH 17.09.91
226 |* Letzte Aenderung TH 17.09.91
227 |*
228 *************************************************************************/
229
Split(void * p,sal_uInt16 nIndex,sal_uInt16 nReSize)230 CBlock* CBlock::Split( void* p, sal_uInt16 nIndex, sal_uInt16 nReSize )
231 {
232 DBG_CHKTHIS( CBlock, DbgCheckCBlock );
233
234 sal_uInt16 nNewSize;
235 sal_uInt16 nMiddle;
236 CBlock* pNewBlock;
237
238 nMiddle = nCount/2;
239
240 if ( ( nIndex == nCount ) || ( nIndex == 0 ) )
241 nNewSize = nReSize;
242 else
243 {
244 // Der aktuelle Block wird in der Mitte geteilt
245 nNewSize = (nCount+1) / 2;
246
247 if ( nNewSize < nReSize )
248 nNewSize = nReSize;
249 else
250 {
251 // Neue Groesse muss ein vielfaches von Resize sein
252 if ( nNewSize % nReSize )
253 nNewSize += nReSize - (nNewSize % nReSize);
254 else
255 nNewSize = nNewSize + nReSize; // MSVC warns here if += is used
256 }
257 }
258
259 // Vor oder hinter dem aktuellem Block einfuegen?
260 if ( nIndex > nMiddle )
261 {
262 // Neuen Split-Block anlegen und hinter dem aktuellem Block einfuegen
263 pNewBlock = new CBlock( nNewSize, this, pNext );
264
265 if ( pNext )
266 pNext->pPrev = pNewBlock;
267 pNext = pNewBlock;
268
269 if ( nIndex == nCount )
270 {
271 // Neuen Pointer einfuegen
272 pNewBlock->pNodes[0] = p;
273 pNewBlock->nCount = 1;
274 }
275 else
276 {
277 nIndex = nIndex - nMiddle; // MSVC warns here if += is used
278 // Alles von Mitte bis Index kopieren
279 if ( nIndex )
280 memcpy( pNewBlock->pNodes, pNodes+nMiddle, nIndex*sizeof(PVOID) );
281
282 // Neuen Pointer einfuegen
283 pNewBlock->pNodes[nIndex] = p;
284
285 // Alles von Mitte bis Ende hinter Index kopieren
286 memcpy( pNewBlock->pNodes+nIndex+1,
287 pNodes+nMiddle+nIndex,
288 (nCount-nMiddle-nIndex) * sizeof(PVOID) );
289
290 pNewBlock->nCount = (nCount-nMiddle+1);
291 nCount = nMiddle;
292
293 // Den aktuellen Datenbereich auch halbieren
294 if ( nSize != nNewSize )
295 {
296 void** pNewNodes = new PVOID[nNewSize];
297 memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) );
298 delete[] pNodes;
299 pNodes = pNewNodes;
300 nSize = nNewSize;
301 }
302 }
303 }
304 else
305 {
306 // Neuen Split-Block anlegen und vor dem aktuellem Block einfuegen
307 pNewBlock = new CBlock( nNewSize, pPrev, this );
308
309 if ( pPrev )
310 pPrev->pNext = pNewBlock;
311 pPrev = pNewBlock;
312
313 if ( nIndex == 0 )
314 {
315 // Neuen Pointer einfuegen
316 pNewBlock->pNodes[0] = p;
317 pNewBlock->nCount = 1;
318 }
319 else
320 {
321 // Alles von Anfang bis Index kopieren
322 memcpy( pNewBlock->pNodes, pNodes, nIndex*sizeof(PVOID) );
323
324 // Neuen Pointer einfuegen
325 pNewBlock->pNodes[nIndex] = p;
326
327 // Alles von Index bis Mitte hinter Index kopieren
328 if ( nIndex != nMiddle )
329 {
330 memcpy( pNewBlock->pNodes+nIndex+1,
331 pNodes+nIndex,
332 (nMiddle-nIndex) * sizeof(PVOID) );
333 }
334
335 pNewBlock->nCount = nMiddle+1;
336 nCount = nCount - nMiddle; // MSVC warns here if += is used
337
338 // Die zweite Haelfte in einen neuen Block kopieren
339 if ( nSize != nNewSize )
340 {
341 void** pNewNodes = new PVOID[nNewSize];
342 memcpy( pNewNodes, pNodes+nMiddle, nCount*sizeof(PVOID) );
343 delete[] pNodes;
344 pNodes = pNewNodes;
345 nSize = nNewSize;
346 }
347 else
348 memmove( pNodes, pNodes+nMiddle, nCount*sizeof(PVOID) );
349 }
350 }
351
352 // Neu angelegten Block zurueckgeben, da gegebenfalls die Blockpointer
353 // im Container angepast werden koennen
354 return pNewBlock;
355 }
356
357 /*************************************************************************
358 |*
359 |* CBlock::Remove()
360 |*
361 |* Beschreibung Entfernt einen Pointer
362 |* Ersterstellung TH 17.09.91
363 |* Letzte Aenderung TH 17.09.91
364 |*
365 *************************************************************************/
366
Remove(sal_uInt16 nIndex,sal_uInt16 nReSize)367 void* CBlock::Remove( sal_uInt16 nIndex, sal_uInt16 nReSize )
368 {
369 DBG_CHKTHIS( CBlock, DbgCheckCBlock );
370
371 // Alten Pointer sichern
372 void* pOld = pNodes[nIndex];
373
374 // 1 Element weniger
375 nCount--;
376
377 // Block verkleinern (wenn Reallokationsgroesse um 4 unterschritten wird)
378 if ( nCount == (nSize-nReSize-4) )
379 {
380 // Neue Daten anlegen
381 nSize = nSize - nReSize; // MSVC warns here if += is used
382 void** pNewNodes = new PVOID[nSize];
383
384 // Wird letzter Eintrag geloescht
385 if ( nIndex == nCount )
386 {
387 // Daten kopieren
388 memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) );
389 }
390 else
391 {
392 // Daten kopieren
393 memcpy( pNewNodes, pNodes, nIndex*sizeof(PVOID) );
394 memcpy( pNewNodes + nIndex, pNodes + nIndex+1,
395 (nCount-nIndex)*sizeof(PVOID) );
396 }
397
398 // Alte Daten loeschen und neue setzen
399 delete[] pNodes;
400 pNodes = pNewNodes;
401 }
402 else
403 {
404 // Wenn nicht das letzte Element, dann zusammenschieben
405 if ( nIndex < nCount )
406 {
407 memmove( pNodes + nIndex, pNodes + nIndex + 1,
408 (nCount-nIndex)*sizeof(PVOID) );
409 }
410 }
411
412 // Alten Pointer zurueckgeben
413 return pOld;
414 }
415
416 /*************************************************************************
417 |*
418 |* CBlock::Replace()
419 |*
420 |* Beschreibung Ersetzt einen Pointer
421 |* Ersterstellung TH 17.09.91
422 |* Letzte Aenderung TH 17.09.91
423 |*
424 *************************************************************************/
425
Replace(void * p,sal_uInt16 nIndex)426 inline void* CBlock::Replace( void* p, sal_uInt16 nIndex )
427 {
428 DBG_CHKTHIS( CBlock, DbgCheckCBlock );
429
430 // Alten Pointer sichern, neuen setzen und alten zurueckgeben
431 void* pOld = pNodes[nIndex];
432 pNodes[nIndex] = p;
433 return pOld;
434 }
435
436 /*************************************************************************
437 |*
438 |* CBlock::GetObjectPtr()
439 |*
440 |* Beschreibung Gibt einen Pointer auf den Pointer aus dem Block
441 |* zurueck
442 |* Ersterstellung TH 26.01.93
443 |* Letzte Aenderung TH 26.01.93
444 |*
445 *************************************************************************/
446
GetObjectPtr(sal_uInt16 nIndex)447 inline void** CBlock::GetObjectPtr( sal_uInt16 nIndex )
448 {
449 DBG_CHKTHIS( CBlock, DbgCheckCBlock );
450
451 return &(pNodes[nIndex]);
452 }
453
454 /*************************************************************************
455 |*
456 |* CBlock::SetSize()
457 |*
458 |* Beschreibung Aendert die Groesse des Blocks
459 |* Ersterstellung TH 17.09.91
460 |* Letzte Aenderung TH 17.09.91
461 |*
462 *************************************************************************/
463
SetSize(sal_uInt16 nNewSize)464 void CBlock::SetSize( sal_uInt16 nNewSize )
465 {
466 DBG_CHKTHIS( CBlock, DbgCheckCBlock );
467 DBG_ASSERT( nNewSize, "CBlock::SetSize(): nNewSize == 0" );
468
469 // Unterscheidet sich die Groesse
470 if ( nNewSize != nCount )
471 {
472 // Array erweitern
473 void** pNewNodes = new PVOID[nNewSize];
474
475 // Alte Tabelle in die Neue kopieren
476 if ( nNewSize < nCount )
477 memcpy( pNewNodes, pNodes, nNewSize*sizeof(PVOID) );
478 else
479 {
480 memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) );
481
482 // Array mit 0 initialisieren
483 memset( pNewNodes+nCount, 0, (nNewSize-nCount)*sizeof(PVOID) );
484 }
485
486 // Altes Array loeschen und neue Werte setzen
487 nSize = nNewSize;
488 nCount = nSize;
489 delete[] pNodes;
490 pNodes = pNewNodes;
491 }
492 }
493
494 //------------------------------------------------------------------------
495
496 /*************************************************************************
497 |*
498 |* DbgCheckContainer()
499 |*
500 |* Beschreibung Pruefung eines Container fuer Debug-Utilities
501 |* Ersterstellung MI 30.01.92
502 |* Letzte Aenderung TH 24.01.96
503 |*
504 *************************************************************************/
505
506 #ifdef DBG_UTIL
DbgCheckContainer(const void * pCont)507 const char* Container::DbgCheckContainer( const void* pCont )
508 {
509 Container* p = (Container*)pCont;
510
511 if ( p->nCount && (!p->pFirstBlock || !p->pLastBlock || !p->pCurBlock) )
512 return "nCount > 0 but no CBlocks";
513
514 return NULL;
515 }
516 #endif
517
518 /*************************************************************************
519 |*
520 |* ImpCopyContainer()
521 |*
522 |* Beschreibung Kopiert alle Daten des Containers
523 |* Ersterstellung TH 24.01.96
524 |* Letzte Aenderung TH 24.01.96
525 |*
526 *************************************************************************/
527
ImpCopyContainer(const Container * pCont2)528 void Container::ImpCopyContainer( const Container* pCont2 )
529 {
530 // Werte vom uebergebenen Container uebernehmen
531 nCount = pCont2->nCount;
532 nCurIndex = pCont2->nCurIndex;
533 nInitSize = pCont2->nInitSize;
534 nReSize = pCont2->nReSize;
535 nBlockSize = pCont2->nBlockSize;
536
537 // Alle Bloecke kopieren
538 if ( pCont2->nCount )
539 {
540 CBlock* pBlock1;
541 CBlock* pBlock2;
542 CBlock* pTempBlock;
543
544 // Erstmal ersten Block kopieren
545 pBlock2 = pCont2->pFirstBlock;
546 pFirstBlock = new CBlock( *pBlock2, NULL );
547 // Ist erster Block der Current-Block, dann Current-Block setzen
548 if ( pBlock2 == pCont2->pCurBlock )
549 pCurBlock = pFirstBlock;
550 pBlock1 = pFirstBlock;
551 pBlock2 = pBlock2->GetNextBlock();
552 while ( pBlock2 )
553 {
554 // Neuen Block anlegen und aus der uebergebenen Liste kopieren
555 pTempBlock = new CBlock( *pBlock2, pBlock1 );
556 pBlock1->SetNextBlock( pTempBlock );
557 pBlock1 = pTempBlock;
558
559 // Current-Block beruecksichtigen
560 if ( pBlock2 == pCont2->pCurBlock )
561 pCurBlock = pBlock1;
562
563 // Auf naechsten Block weitersetzen
564 pBlock2 = pBlock2->GetNextBlock();
565 }
566
567 // Letzten Block setzen
568 pLastBlock = pBlock1;
569 }
570 else
571 {
572 pFirstBlock = NULL;
573 pLastBlock = NULL;
574 pCurBlock = NULL;
575 }
576 }
577
578 /*************************************************************************
579 |*
580 |* Container::Container()
581 |*
582 |* Beschreibung CONTNR.SDW
583 |* Ersterstellung TH 17.09.91
584 |* Letzte Aenderung TH 17.09.91
585 |*
586 *************************************************************************/
587
Container(sal_uInt16 _nBlockSize,sal_uInt16 _nInitSize,sal_uInt16 _nReSize)588 Container::Container( sal_uInt16 _nBlockSize, sal_uInt16 _nInitSize, sal_uInt16 _nReSize )
589 {
590 DBG_CTOR( Container, DbgCheckContainer );
591
592 // BlockSize muss mindestens 4 sein und kleiner als 64 KB
593 if ( _nBlockSize < 4 )
594 nBlockSize = 4;
595 else
596 {
597 if ( _nBlockSize < CONTAINER_MAXBLOCKSIZE )
598 nBlockSize = _nBlockSize;
599 else
600 nBlockSize = CONTAINER_MAXBLOCKSIZE;
601 }
602
603 // ReSize muss mindestens 2 sein und kleiner als BlockSize
604 if ( _nReSize >= nBlockSize )
605 nReSize = nBlockSize;
606 else
607 {
608 if ( _nReSize < 2 )
609 nReSize = 2;
610 else
611 nReSize = _nReSize;
612
613 // BlockSize muss ein vielfaches der Resizegroesse sein
614 if ( nBlockSize % nReSize )
615 nBlockSize -= nReSize - (nBlockSize % nReSize);
616 }
617
618 // InitSize muss groesser gleich ReSize sein und kleiner als BlockSize
619 if ( _nInitSize <= nReSize )
620 nInitSize = nReSize;
621 else
622 {
623 if ( _nInitSize >= nBlockSize )
624 nInitSize = nBlockSize;
625 else
626 {
627 nInitSize = _nInitSize;
628
629 // InitSize muss ein vielfaches der Resizegroesse sein
630 if ( nInitSize % nReSize )
631 nInitSize -= nReSize - (nInitSize % nReSize);
632 }
633 }
634
635 // Werte initialisieren
636 pFirstBlock = NULL;
637 pLastBlock = NULL;
638 pCurBlock = NULL;
639 nCount = 0;
640 nCurIndex = 0;
641 }
642
643 /*************************************************************************
644 |*
645 |* Container::Container()
646 |*
647 |* Beschreibung CONTNR.SDW
648 |* Ersterstellung TH 17.09.91
649 |* Letzte Aenderung TH 17.09.91
650 |*
651 *************************************************************************/
652
Container(sal_uIntPtr nSize)653 Container::Container( sal_uIntPtr nSize )
654 {
655 DBG_CTOR( Container, DbgCheckContainer );
656
657 nCount = nSize;
658 nCurIndex = 0;
659 nBlockSize = CONTAINER_MAXBLOCKSIZE;
660 nInitSize = 1;
661 nReSize = 1;
662
663 if ( !nSize )
664 {
665 pFirstBlock = NULL;
666 pLastBlock = NULL;
667 pCurBlock = NULL;
668 }
669 else
670 {
671 // Muss mehr als ein Block angelegt werden
672 if ( nSize <= nBlockSize )
673 {
674 pFirstBlock = new CBlock( (sal_uInt16)nSize, NULL );
675 pLastBlock = pFirstBlock;
676 }
677 else
678 {
679 CBlock* pBlock1;
680 CBlock* pBlock2;
681
682 pFirstBlock = new CBlock( nBlockSize, NULL );
683 pBlock1 = pFirstBlock;
684 nSize -= nBlockSize;
685
686 // Solange die Blockgroesse ueberschritten wird, neue Bloecke anlegen
687 while ( nSize > nBlockSize )
688 {
689 pBlock2 = new CBlock( nBlockSize, pBlock1 );
690 pBlock1->SetNextBlock( pBlock2 );
691 pBlock1 = pBlock2;
692 nSize -= nBlockSize;
693 }
694
695 pLastBlock = new CBlock( (sal_uInt16)nSize, pBlock1 );
696 pBlock1->SetNextBlock( pLastBlock );
697 }
698
699 pCurBlock = pFirstBlock;
700 }
701 }
702
703 /*************************************************************************
704 |*
705 |* Container::Container()
706 |*
707 |* Beschreibung CONTNR.SDW
708 |* Ersterstellung TH 17.09.91
709 |* Letzte Aenderung TH 17.09.91
710 |*
711 *************************************************************************/
712
Container(const Container & r)713 Container::Container( const Container& r )
714 {
715 DBG_CTOR( Container, DbgCheckContainer );
716
717 // Daten kopieren
718 ImpCopyContainer( &r );
719 }
720
721 /*************************************************************************
722 |*
723 |* Container::~Container()
724 |*
725 |* Beschreibung CONTNR.SDW
726 |* Ersterstellung TH 17.09.91
727 |* Letzte Aenderung TH 17.09.91
728 |*
729 *************************************************************************/
730
~Container()731 Container::~Container()
732 {
733 DBG_DTOR( Container, DbgCheckContainer );
734
735 // Alle Bloecke loeschen
736 CBlock* pBlock = pFirstBlock;
737 while ( pBlock )
738 {
739 CBlock* pTemp = pBlock->GetNextBlock();
740 delete pBlock;
741 pBlock = pTemp;
742 }
743 }
744
745 /*************************************************************************
746 |*
747 |* Container::ImpInsert()
748 |*
749 |* Beschreibung Interne Methode zum Einfuegen eines Pointers
750 |* Ersterstellung TH 17.09.91
751 |* Letzte Aenderung DV 01.07.97
752 |*
753 *************************************************************************/
754
ImpInsert(void * p,CBlock * pBlock,sal_uInt16 nIndex)755 void Container::ImpInsert( void* p, CBlock* pBlock, sal_uInt16 nIndex )
756 {
757 DBG_CHKTHIS( Container, DbgCheckContainer );
758
759 if ( !nCount )
760 {
761 if ( !pBlock )
762 {
763 pFirstBlock = new CBlock( nInitSize, NULL, NULL );
764 pLastBlock = pFirstBlock;
765 pCurBlock = pFirstBlock;
766 }
767 pFirstBlock->Insert( p, nIndex, nReSize );
768 }
769 else
770 {
771 // Ist im Block die maximale Blockgroesse erreicht,
772 // dann neuen Block anlegen
773 if ( pBlock->Count() == nBlockSize )
774 {
775 // Block auftrennen
776 CBlock* pNewBlock = pBlock->Split( p, nIndex, nReSize );
777
778 // Wurde Block dahinter angehaegnt
779 if ( pBlock->pNext == pNewBlock )
780 {
781 // Gegebenenfalls LastBlock anpassen
782 if ( pBlock == pLastBlock )
783 pLastBlock = pNewBlock;
784
785 // Current-Position nachfuehren
786 if ( pBlock == pCurBlock )
787 {
788 if ( pBlock->nCount <= nCurIndex )
789 {
790 if ( nIndex <= nCurIndex )
791 nCurIndex++;
792 pCurBlock = pNewBlock;
793 nCurIndex = nCurIndex - pBlock->nCount; // MSVC warns here if += is used
794 }
795 }
796 }
797 else
798 {
799 // Gegebenenfalls FirstBlock anpassen
800 if ( pBlock == pFirstBlock )
801 pFirstBlock = pNewBlock;
802
803 // Current-Position nachfuehren
804 if ( pBlock == pCurBlock )
805 {
806 if ( nIndex <= nCurIndex )
807 nCurIndex++;
808 if ( pNewBlock->nCount <= nCurIndex )
809 nCurIndex = nCurIndex - pNewBlock->nCount; // MSVC warns here if += is used
810 else
811 pCurBlock = pNewBlock;
812 }
813 }
814 }
815 else
816 {
817 // Sonst reicht normales einfuegen in den Block
818 pBlock->Insert( p, nIndex, nReSize );
819
820 // Current-Position nachfuehren
821 if ( (pBlock == pCurBlock) && (nIndex <= nCurIndex) )
822 nCurIndex++;
823 }
824 }
825
826 // Ein neues Item im Container
827 nCount++;
828 }
829
830 /*************************************************************************
831 |*
832 |* Container::Insert()
833 |*
834 |* Beschreibung CONTNR.SDW
835 |* Ersterstellung TH 17.09.91
836 |* Letzte Aenderung TH 17.09.91
837 |*
838 *************************************************************************/
839
Insert(void * p)840 void Container::Insert( void* p )
841 {
842 ImpInsert( p, pCurBlock, nCurIndex );
843 }
844
845 /*************************************************************************
846 |*
847 |* Container::Insert()
848 |*
849 |* Beschreibung CONTNR.SDW
850 |* Ersterstellung TH 17.09.91
851 |* Letzte Aenderung TH 17.09.91
852 |*
853 *************************************************************************/
854
Insert(void * p,sal_uIntPtr nIndex)855 void Container::Insert( void* p, sal_uIntPtr nIndex )
856 {
857 if ( nCount <= nIndex )
858 {
859 if ( pLastBlock )
860 ImpInsert( p, pLastBlock, pLastBlock->Count() );
861 else
862 ImpInsert( p, NULL, 0 );
863 }
864 else
865 {
866 // Block suchen
867 CBlock* pTemp = pFirstBlock;
868 while ( pTemp->Count() < nIndex )
869 {
870 nIndex -= pTemp->Count();
871 pTemp = pTemp->GetNextBlock();
872 }
873
874 ImpInsert( p, pTemp, (sal_uInt16)nIndex );
875 }
876 }
877
878 /*************************************************************************
879 |*
880 |* Container::Insert()
881 |*
882 |* Beschreibung CONTNR.SDW
883 |* Ersterstellung TH 17.09.91
884 |* Letzte Aenderung TH 17.09.91
885 |*
886 *************************************************************************/
887
Insert(void * pNew,void * pOld)888 void Container::Insert( void* pNew, void* pOld )
889 {
890 sal_uIntPtr nIndex = GetPos( pOld );
891 if ( nIndex != CONTAINER_ENTRY_NOTFOUND )
892 Insert( pNew, nIndex );
893 }
894
895 /*************************************************************************
896 |*
897 |* Container::ImpRemove()
898 |*
899 |* Beschreibung Interne Methode zum Entfernen eines Pointers
900 |* Ersterstellung TH 17.09.91
901 |* Letzte Aenderung TH 17.09.91
902 |*
903 *************************************************************************/
904
ImpRemove(CBlock * pBlock,sal_uInt16 nIndex)905 void* Container::ImpRemove( CBlock* pBlock, sal_uInt16 nIndex )
906 {
907 DBG_CHKTHIS( Container, DbgCheckContainer );
908
909 void* pOld;
910
911 // Ist Liste danach leer
912 if ( nCount == 1 )
913 {
914 // Block und CurIndex zuruecksetzen
915 pOld = pBlock->GetObject( nIndex );
916 pBlock->Reset();
917 nCurIndex = 0;
918 }
919 else
920 {
921 // Ist Block nach Remove leer
922 if ( pBlock->Count() == 1 )
923 {
924 // dann Block entfernen und Block-Pointer umsetzen
925 if ( pBlock->GetPrevBlock() )
926 (pBlock->GetPrevBlock())->SetNextBlock( pBlock->GetNextBlock() );
927 else
928 pFirstBlock = pBlock->GetNextBlock();
929
930 if ( pBlock->GetNextBlock() )
931 (pBlock->GetNextBlock())->SetPrevBlock( pBlock->GetPrevBlock() );
932 else
933 pLastBlock = pBlock->GetPrevBlock();
934
935 // Current-Position nachfuehren
936 if ( pBlock == pCurBlock )
937 {
938 if ( pBlock->GetNextBlock() )
939 {
940 pCurBlock = pBlock->GetNextBlock();
941 nCurIndex = 0;
942 }
943 else
944 {
945 pCurBlock = pBlock->GetPrevBlock();
946 nCurIndex = pCurBlock->Count()-1;
947 }
948 }
949
950 pOld = pBlock->GetObject( nIndex );
951 delete pBlock;
952 }
953 else
954 {
955 // Sonst Item aus dem Block entfernen
956 pOld = pBlock->Remove( nIndex, nReSize );
957
958 // Current-Position nachfuehren
959 if ( (pBlock == pCurBlock) &&
960 ((nIndex < nCurIndex) || ((nCurIndex == pBlock->Count()) && nCurIndex)) )
961 nCurIndex--;
962 }
963 }
964
965 // Jetzt gibt es ein Item weniger
966 nCount--;
967
968 // Und den Pointer zurueckgeben, der entfernt wurde
969 return pOld;
970 }
971
972 /*************************************************************************
973 |*
974 |* Container::Remove()
975 |*
976 |* Beschreibung CONTNR.SDW
977 |* Ersterstellung TH 17.09.91
978 |* Letzte Aenderung TH 17.09.91
979 |*
980 *************************************************************************/
981
Remove()982 void* Container::Remove()
983 {
984 // Wenn kein Item vorhanden ist, NULL zurueckgeben
985 if ( !nCount )
986 return NULL;
987 else
988 return ImpRemove( pCurBlock, nCurIndex );
989 }
990
991 /*************************************************************************
992 |*
993 |* Container::Remove()
994 |*
995 |* Beschreibung CONTNR.SDW
996 |* Ersterstellung TH 17.09.91
997 |* Letzte Aenderung TH 17.09.91
998 |*
999 *************************************************************************/
1000
Remove(sal_uIntPtr nIndex)1001 void* Container::Remove( sal_uIntPtr nIndex )
1002 {
1003 // Ist Index nicht innerhalb des Containers, dann NULL zurueckgeben
1004 if ( nCount <= nIndex )
1005 return NULL;
1006 else
1007 {
1008 // Block suchen
1009 CBlock* pTemp = pFirstBlock;
1010 while ( pTemp->Count() <= nIndex )
1011 {
1012 nIndex -= pTemp->Count();
1013 pTemp = pTemp->GetNextBlock();
1014 }
1015
1016 return ImpRemove( pTemp, (sal_uInt16)nIndex );
1017 }
1018 }
1019
1020 /*************************************************************************
1021 |*
1022 |* Container::Replace()
1023 |*
1024 |* Beschreibung CONTNR.SDW
1025 |* Ersterstellung TH 17.09.91
1026 |* Letzte Aenderung TH 17.09.91
1027 |*
1028 *************************************************************************/
1029
Replace(void * p)1030 void* Container::Replace( void* p )
1031 {
1032 DBG_CHKTHIS( Container, DbgCheckContainer );
1033
1034 if ( !nCount )
1035 return NULL;
1036 else
1037 return pCurBlock->Replace( p, nCurIndex );
1038 }
1039
1040 /*************************************************************************
1041 |*
1042 |* Container::Replace()
1043 |*
1044 |* Beschreibung CONTNR.SDW
1045 |* Ersterstellung TH 17.09.91
1046 |* Letzte Aenderung TH 17.09.91
1047 |*
1048 *************************************************************************/
1049
Replace(void * p,sal_uIntPtr nIndex)1050 void* Container::Replace( void* p, sal_uIntPtr nIndex )
1051 {
1052 DBG_CHKTHIS( Container, DbgCheckContainer );
1053
1054 // Ist Index nicht innerhalb des Containers, dann NULL zurueckgeben
1055 if ( nCount <= nIndex )
1056 return NULL;
1057 else
1058 {
1059 // Block suchen
1060 CBlock* pTemp = pFirstBlock;
1061 while ( pTemp->Count() <= nIndex )
1062 {
1063 nIndex -= pTemp->Count();
1064 pTemp = pTemp->GetNextBlock();
1065 }
1066
1067 return pTemp->Replace( p, (sal_uInt16)nIndex );
1068 }
1069 }
1070
1071 /*************************************************************************
1072 |*
1073 |* Container::SetSize()
1074 |*
1075 |* Beschreibung CONTNR.SDW
1076 |* Ersterstellung TH 17.09.91
1077 |* Letzte Aenderung TH 17.09.91
1078 |*
1079 *************************************************************************/
1080
SetSize(sal_uIntPtr nNewSize)1081 void Container::SetSize( sal_uIntPtr nNewSize )
1082 {
1083 DBG_CHKTHIS( Container, DbgCheckContainer );
1084
1085 if ( nNewSize )
1086 {
1087 // Unterscheiden sich die Groessen
1088 if ( nNewSize != nCount )
1089 {
1090 CBlock* pTemp;
1091 sal_uIntPtr nTemp;
1092
1093 // Wird verkleinert
1094 if ( nNewSize < nCount )
1095 {
1096 pTemp = pFirstBlock;
1097 nTemp = 0;
1098 while ( (nTemp+pTemp->Count()) < nNewSize )
1099 {
1100 nTemp += pTemp->Count();
1101 pTemp = pTemp->GetNextBlock();
1102 }
1103
1104 // Alle folgenden Bloecke loeschen
1105 sal_Bool bLast = sal_False;
1106 CBlock* pDelNext;
1107 CBlock* pDelBlock = pTemp->GetNextBlock();
1108 while ( pDelBlock )
1109 {
1110 // Muss CurrentBlock umgesetzt werden
1111 if ( pDelBlock == pCurBlock )
1112 bLast = sal_True;
1113 pDelNext = pDelBlock->GetNextBlock();
1114 delete pDelBlock;
1115 pDelBlock = pDelNext;
1116 }
1117
1118 // Block in der Groesse anpassen, oder bei Groesse 0 loeschen
1119 if ( nNewSize > nTemp )
1120 {
1121 pLastBlock = pTemp;
1122 pTemp->SetNextBlock( NULL );
1123 pTemp->SetSize( (sal_uInt16)(nNewSize-nTemp) );
1124 }
1125 else
1126 {
1127 pLastBlock = pTemp->GetPrevBlock();
1128 pLastBlock->SetNextBlock( NULL );
1129 delete pTemp;
1130 }
1131
1132 nCount = nNewSize;
1133 if ( bLast )
1134 {
1135 pCurBlock = pLastBlock;
1136 nCurIndex = pCurBlock->Count()-1;
1137 }
1138 }
1139 else
1140 {
1141 // Auf den letzen Puffer setzen
1142 pTemp = pLastBlock;
1143 nTemp = nNewSize - nCount;
1144
1145 if ( !pTemp )
1146 {
1147 // Muss mehr als ein Block angelegt werden
1148 if ( nNewSize <= nBlockSize )
1149 {
1150 pFirstBlock = new CBlock( (sal_uInt16)nNewSize, NULL );
1151 pLastBlock = pFirstBlock;
1152 }
1153 else
1154 {
1155 CBlock* pBlock1;
1156 CBlock* pBlock2;
1157
1158 pFirstBlock = new CBlock( nBlockSize, NULL );
1159 pBlock1 = pFirstBlock;
1160 nNewSize -= nBlockSize;
1161
1162 // Solange die Blockgroesse ueberschritten wird, neue Bloecke anlegen
1163 while ( nNewSize > nBlockSize )
1164 {
1165 pBlock2 = new CBlock( nBlockSize, pBlock1 );
1166 pBlock1->SetNextBlock( pBlock2 );
1167 pBlock1 = pBlock2;
1168 nNewSize -= nBlockSize;
1169 }
1170
1171 pLastBlock = new CBlock( (sal_uInt16)nNewSize, pBlock1 );
1172 pBlock1->SetNextBlock( pLastBlock );
1173 }
1174
1175 pCurBlock = pFirstBlock;
1176 }
1177 // Reicht es, den letzen Puffer in der Groesse anzupassen
1178 else if ( (nTemp+pTemp->Count()) <= nBlockSize )
1179 pTemp->SetSize( (sal_uInt16)(nTemp+pTemp->Count()) );
1180 else
1181 {
1182 // Puffer auf max. Blockgroesse setzen
1183 nTemp -= nBlockSize - pTemp->GetSize();
1184 pTemp->SetSize( nBlockSize );
1185
1186 CBlock* pTemp2;
1187 // Solange die Blockgroesse ueberschritten wird,
1188 // neue Bloecke anlegen
1189 while ( nTemp > nBlockSize )
1190 {
1191 pTemp2 = new CBlock( nBlockSize, pTemp );
1192 pTemp->SetNextBlock( pTemp2 );
1193 pTemp = pTemp2;
1194 nTemp -= nBlockSize;
1195 }
1196
1197 // Den letzten Block anlegen
1198 if ( nTemp )
1199 {
1200 pLastBlock = new CBlock( (sal_uInt16)nTemp, pTemp );
1201 pTemp->SetNextBlock( pLastBlock );
1202 }
1203 else
1204 pLastBlock = pTemp;
1205 }
1206
1207 nCount = nNewSize;
1208 }
1209 }
1210 }
1211 else
1212 Clear();
1213 }
1214
1215 /*************************************************************************
1216 |*
1217 |* Container::Clear()
1218 |*
1219 |* Beschreibung CONTNR.SDW
1220 |* Ersterstellung TH 17.09.91
1221 |* Letzte Aenderung TH 17.09.91
1222 |*
1223 *************************************************************************/
1224
Clear()1225 void Container::Clear()
1226 {
1227 DBG_CHKTHIS( Container, DbgCheckContainer );
1228
1229 // Erst alle Bloecke loeschen
1230 CBlock* pBlock = pFirstBlock;
1231 while ( pBlock )
1232 {
1233 CBlock* pTemp = pBlock->GetNextBlock();
1234 delete pBlock;
1235 pBlock = pTemp;
1236 }
1237
1238 // Werte zuruecksetzen
1239 pFirstBlock = NULL;
1240 pLastBlock = NULL;
1241 pCurBlock = NULL;
1242 nCount = 0;
1243 nCurIndex = 0;
1244 }
1245
1246 /*************************************************************************
1247 |*
1248 |* Container::GetCurObject()
1249 |*
1250 |* Beschreibung CONTNR.SDW
1251 |* Ersterstellung TH 17.09.91
1252 |* Letzte Aenderung TH 17.09.91
1253 |*
1254 *************************************************************************/
1255
GetCurObject() const1256 void* Container::GetCurObject() const
1257 {
1258 DBG_CHKTHIS( Container, DbgCheckContainer );
1259
1260 // NULL, wenn Container leer
1261 if ( !nCount )
1262 return NULL;
1263 else
1264 return pCurBlock->GetObject( nCurIndex );
1265 }
1266
1267 /*************************************************************************
1268 |*
1269 |* Container::GetCurPos()
1270 |*
1271 |* Beschreibung CONTNR.SDW
1272 |* Ersterstellung TH 17.09.91
1273 |* Letzte Aenderung TH 17.09.91
1274 |*
1275 *************************************************************************/
1276
GetCurPos() const1277 sal_uIntPtr Container::GetCurPos() const
1278 {
1279 DBG_CHKTHIS( Container, DbgCheckContainer );
1280
1281 // CONTAINER_ENTRY_NOTFOUND, wenn Container leer
1282 if ( !nCount )
1283 return CONTAINER_ENTRY_NOTFOUND;
1284 else
1285 {
1286 // Block suchen
1287 CBlock* pTemp = pFirstBlock;
1288 sal_uIntPtr nTemp = 0;
1289 while ( pTemp != pCurBlock )
1290 {
1291 nTemp += pTemp->Count();
1292 pTemp = pTemp->GetNextBlock();
1293 }
1294
1295 return nTemp+nCurIndex;
1296 }
1297 }
1298
1299 /*************************************************************************
1300 |*
1301 |* Container::GetObjectPtr()
1302 |*
1303 |* Beschreibung Interne Methode fuer Referenz-Container
1304 |* Ersterstellung TH 26.01.93
1305 |* Letzte Aenderung TH 26.01.93
1306 |*
1307 *************************************************************************/
1308
GetObjectPtr(sal_uIntPtr nIndex)1309 void** Container::GetObjectPtr( sal_uIntPtr nIndex )
1310 {
1311 DBG_CHKTHIS( Container, DbgCheckContainer );
1312
1313 // Ist Index nicht innerhalb des Containers, dann NULL zurueckgeben
1314 if ( nCount <= nIndex )
1315 return NULL;
1316 else
1317 {
1318 // Block suchen
1319 CBlock* pTemp = pFirstBlock;
1320 while ( pTemp->Count() <= nIndex )
1321 {
1322 nIndex -= pTemp->Count();
1323 pTemp = pTemp->GetNextBlock();
1324 }
1325
1326 // Item innerhalb des gefundenen Blocks zurueckgeben
1327 return pTemp->GetObjectPtr( (sal_uInt16)nIndex );
1328 }
1329 }
1330
1331 /*************************************************************************
1332 |*
1333 |* Container::GetObject()
1334 |*
1335 |* Beschreibung CONTNR.SDW
1336 |* Ersterstellung TH 17.09.91
1337 |* Letzte Aenderung TH 17.09.91
1338 |*
1339 *************************************************************************/
1340
GetObject(sal_uIntPtr nIndex) const1341 void* Container::GetObject( sal_uIntPtr nIndex ) const
1342 {
1343 DBG_CHKTHIS( Container, DbgCheckContainer );
1344
1345 // Ist Index nicht innerhalb des Containers, dann NULL zurueckgeben
1346 if ( nCount <= nIndex )
1347 return NULL;
1348 else
1349 {
1350 // Block suchen
1351 CBlock* pTemp = pFirstBlock;
1352 while ( pTemp->Count() <= nIndex )
1353 {
1354 nIndex -= pTemp->Count();
1355 pTemp = pTemp->GetNextBlock();
1356 }
1357
1358 // Item innerhalb des gefundenen Blocks zurueckgeben
1359 return pTemp->GetObject( (sal_uInt16)nIndex );
1360 }
1361 }
1362
1363 /*************************************************************************
1364 |*
1365 |* Container::GetPos()
1366 |*
1367 |* Beschreibung CONTNR.SDW
1368 |* Ersterstellung TH 17.09.91
1369 |* Letzte Aenderung TH 17.09.91
1370 |*
1371 *************************************************************************/
1372
GetPos(const void * p) const1373 sal_uIntPtr Container::GetPos( const void* p ) const
1374 {
1375 DBG_CHKTHIS( Container, DbgCheckContainer );
1376
1377 void** pNodes;
1378 CBlock* pTemp;
1379 sal_uIntPtr nTemp;
1380 sal_uInt16 nBlockCount;
1381 sal_uInt16 i;
1382
1383 // Block suchen
1384 pTemp = pFirstBlock;
1385 nTemp = 0;
1386 while ( pTemp )
1387 {
1388 pNodes = pTemp->GetNodes();
1389 i = 0;
1390 nBlockCount = pTemp->Count();
1391 while ( i < nBlockCount )
1392 {
1393 if ( p == *pNodes )
1394 return nTemp+i;
1395 pNodes++;
1396 i++;
1397 }
1398 nTemp += nBlockCount;
1399 pTemp = pTemp->GetNextBlock();
1400 }
1401
1402 return CONTAINER_ENTRY_NOTFOUND;
1403 }
1404
1405 /*************************************************************************
1406 |*
1407 |* Container::GetPos()
1408 |*
1409 |* Beschreibung CONTNR.SDW
1410 |* Ersterstellung TH 14.09.94
1411 |* Letzte Aenderung TH 14.09.94
1412 |*
1413 *************************************************************************/
1414
GetPos(const void * p,sal_uIntPtr nStartIndex,sal_Bool bForward) const1415 sal_uIntPtr Container::GetPos( const void* p, sal_uIntPtr nStartIndex,
1416 sal_Bool bForward ) const
1417 {
1418 DBG_CHKTHIS( Container, DbgCheckContainer );
1419
1420 // Ist Index nicht innerhalb des Containers, dann NOTFOUND zurueckgeben
1421 if ( nCount <= nStartIndex )
1422 return CONTAINER_ENTRY_NOTFOUND;
1423 else
1424 {
1425 void** pNodes;
1426 sal_uInt16 nBlockCount;
1427 sal_uInt16 i;
1428
1429 // Block suchen
1430 CBlock* pTemp = pFirstBlock;
1431 sal_uIntPtr nTemp = 0;
1432 while ( nTemp+pTemp->Count() <= nStartIndex )
1433 {
1434 nTemp += pTemp->Count();
1435 pTemp = pTemp->GetNextBlock();
1436 }
1437
1438 // Jetzt den Pointer suchen
1439 if ( bForward )
1440 {
1441 // Alle Bloecke durchrsuchen
1442 i = (sal_uInt16)(nStartIndex - nTemp);
1443 pNodes = pTemp->GetObjectPtr( i );
1444 do
1445 {
1446 nBlockCount = pTemp->Count();
1447 while ( i < nBlockCount )
1448 {
1449 if ( p == *pNodes )
1450 return nTemp+i;
1451 pNodes++;
1452 i++;
1453 }
1454 nTemp += nBlockCount;
1455 pTemp = pTemp->GetNextBlock();
1456 if ( pTemp )
1457 {
1458 i = 0;
1459 pNodes = pTemp->GetNodes();
1460 }
1461 else
1462 break;
1463 }
1464 while ( sal_True );
1465 }
1466 else
1467 {
1468 // Alle Bloecke durchrsuchen
1469 i = (sal_uInt16)(nStartIndex-nTemp)+1;
1470 pNodes = pTemp->GetObjectPtr( i-1 );
1471 do
1472 {
1473 do
1474 {
1475 if ( p == *pNodes )
1476 return nTemp+i-1;
1477 pNodes--;
1478 i--;
1479 }
1480 while ( i );
1481 nTemp -= pTemp->Count();
1482 pTemp = pTemp->GetPrevBlock();
1483 if ( pTemp )
1484 {
1485 i = pTemp->Count();
1486 // Leere Bloecke in der Kette darf es nicht geben. Nur
1487 // wenn ein Block existiert, darf dieser leer sein
1488 pNodes = pTemp->GetObjectPtr( i-1 );
1489 }
1490 else
1491 break;
1492 }
1493 while ( sal_True );
1494 }
1495 }
1496
1497 return CONTAINER_ENTRY_NOTFOUND;
1498 }
1499
1500 /*************************************************************************
1501 |*
1502 |* Container::Seek()
1503 |*
1504 |* Beschreibung CONTNR.SDW
1505 |* Ersterstellung TH 17.09.91
1506 |* Letzte Aenderung TH 17.09.91
1507 |*
1508 *************************************************************************/
1509
Seek(sal_uIntPtr nIndex)1510 void* Container::Seek( sal_uIntPtr nIndex )
1511 {
1512 DBG_CHKTHIS( Container, DbgCheckContainer );
1513
1514 // Ist der Container leer, dann NULL zurueckgeben
1515 if ( nCount <= nIndex )
1516 return NULL;
1517 else
1518 {
1519 // Block suchen
1520 CBlock* pTemp = pFirstBlock;
1521 while ( pTemp->Count() <= nIndex )
1522 {
1523 nIndex -= pTemp->Count();
1524 pTemp = pTemp->GetNextBlock();
1525 }
1526
1527 // Item innerhalb des gefundenen Blocks zurueckgeben
1528 pCurBlock = pTemp;
1529 nCurIndex = (sal_uInt16)nIndex;
1530 return pCurBlock->GetObject( nCurIndex );
1531 }
1532 }
1533
1534 /*************************************************************************
1535 |*
1536 |* Container::First()
1537 |*
1538 |* Beschreibung CONTNR.SDW
1539 |* Ersterstellung TH 17.09.91
1540 |* Letzte Aenderung TH 17.09.91
1541 |*
1542 *************************************************************************/
1543
First()1544 void* Container::First()
1545 {
1546 DBG_CHKTHIS( Container, DbgCheckContainer );
1547
1548 // Ist Container leer, dann NULL zurueckgeben
1549 if ( !nCount )
1550 return NULL;
1551 else
1552 {
1553 // Block und Index setzen und ersten Pointer zurueckgeben
1554 pCurBlock = pFirstBlock;
1555 nCurIndex = 0;
1556 return pCurBlock->GetObject( nCurIndex );
1557 }
1558 }
1559
1560 /*************************************************************************
1561 |*
1562 |* Container::Last()
1563 |*
1564 |* Beschreibung CONTNR.SDW
1565 |* Ersterstellung TH 17.09.91
1566 |* Letzte Aenderung TH 17.09.91
1567 |*
1568 *************************************************************************/
1569
Last()1570 void* Container::Last()
1571 {
1572 DBG_CHKTHIS( Container, DbgCheckContainer );
1573
1574 // Ist Container leer, dann NULL zurueckgeben
1575 if ( !nCount )
1576 return NULL;
1577 else
1578 {
1579 // Block und Index setzen und ersten Pointer zurueckgeben
1580 pCurBlock = pLastBlock;
1581 nCurIndex = pCurBlock->Count()-1;
1582 return pCurBlock->GetObject( nCurIndex );
1583 }
1584 }
1585
1586 /*************************************************************************
1587 |*
1588 |* Container::Next()
1589 |*
1590 |* Beschreibung CONTNR.SDW
1591 |* Ersterstellung TH 17.09.91
1592 |* Letzte Aenderung TH 17.09.91
1593 |*
1594 *************************************************************************/
1595
Next()1596 void* Container::Next()
1597 {
1598 DBG_CHKTHIS( Container, DbgCheckContainer );
1599
1600 // Ist Container leer, dann NULL zurueckgeben, ansonsten preufen ob
1601 // naechste Position noch im aktuellen Block ist. Falls nicht, dann
1602 // einen Block weiterschalten (geht ohne Gefahr, da leere Bloecke
1603 // nicht vorkommen duerfen, es sein denn, es ist der einzige).
1604 if ( !nCount )
1605 return NULL;
1606 else if ( (nCurIndex+1) < pCurBlock->Count() )
1607 return pCurBlock->GetObject( ++nCurIndex );
1608 else if ( pCurBlock->GetNextBlock() )
1609 {
1610 pCurBlock = pCurBlock->GetNextBlock();
1611 nCurIndex = 0;
1612 return pCurBlock->GetObject( nCurIndex );
1613 }
1614 else
1615 return NULL;
1616 }
1617
1618 /*************************************************************************
1619 |*
1620 |* Container::Prev()
1621 |*
1622 |* Beschreibung CONTNR.SDW
1623 |* Ersterstellung TH 17.09.91
1624 |* Letzte Aenderung TH 17.09.91
1625 |*
1626 *************************************************************************/
1627
Prev()1628 void* Container::Prev()
1629 {
1630 DBG_CHKTHIS( Container, DbgCheckContainer );
1631
1632 // Ist Container leer, dann NULL zurueckgeben, ansonsten preufen ob
1633 // vorherige Position noch im aktuellen Block ist. Falls nicht, dann
1634 // einen Block zurueckschalten (geht ohne Gefahr, da leere Bloecke
1635 // nicht vorkommen duerfen, es sein denn, es ist der einzige).
1636 if ( !nCount )
1637 return NULL;
1638 else if ( nCurIndex )
1639 return pCurBlock->GetObject( --nCurIndex );
1640 else if ( pCurBlock->GetPrevBlock() )
1641 {
1642 pCurBlock = pCurBlock->GetPrevBlock();
1643 nCurIndex = pCurBlock->Count() - 1;
1644 return pCurBlock->GetObject( nCurIndex );
1645 }
1646 else
1647 return NULL;
1648 }
1649
1650 /*************************************************************************
1651 |*
1652 |* Container::operator =()
1653 |*
1654 |* Beschreibung CONTNR.SDW
1655 |* Ersterstellung TH 17.09.91
1656 |* Letzte Aenderung TH 17.09.91
1657 |*
1658 *************************************************************************/
1659
operator =(const Container & r)1660 Container& Container::operator =( const Container& r )
1661 {
1662 DBG_CHKTHIS( Container, DbgCheckContainer );
1663
1664 // Erst alle Bloecke loeschen
1665 CBlock* pBlock = pFirstBlock;
1666 while ( pBlock )
1667 {
1668 CBlock* pTemp = pBlock->GetNextBlock();
1669 delete pBlock;
1670 pBlock = pTemp;
1671 }
1672
1673 // Daten kopieren
1674 ImpCopyContainer( &r );
1675 return *this;
1676 }
1677
1678 /*************************************************************************
1679 |*
1680 |* Container::operator ==()
1681 |*
1682 |* Beschreibung CONTNR.SDW
1683 |* Ersterstellung TH 17.09.91
1684 |* Letzte Aenderung TH 17.09.91
1685 |*
1686 *************************************************************************/
1687
operator ==(const Container & r) const1688 sal_Bool Container::operator ==( const Container& r ) const
1689 {
1690 DBG_CHKTHIS( Container, DbgCheckContainer );
1691
1692 if ( nCount != r.nCount )
1693 return sal_False;
1694
1695 sal_uIntPtr i = 0;
1696 while ( i < nCount )
1697 {
1698 if ( GetObject( i ) != r.GetObject( i ) )
1699 return sal_False;
1700 i++;
1701 }
1702
1703 return sal_True;
1704 }
1705