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 #include <impcont.hxx>
27 #include <tools/unqidx.hxx>
28 #include <tools/unqid.hxx>
29
30 /*************************************************************************
31 |*
32 |* UniqueIndex::UniqueIndex()
33 |*
34 |* Beschreibung UNQIDX.SDW
35 |* Ersterstellung TH 24.09.91
36 |* Letzte Aenderung TH 24.09.91
37 |*
38 *************************************************************************/
39
UniqueIndex(sal_uIntPtr _nStartIndex,sal_uIntPtr _nInitSize,sal_uIntPtr _nReSize)40 UniqueIndex::UniqueIndex( sal_uIntPtr _nStartIndex,
41 sal_uIntPtr _nInitSize, sal_uIntPtr _nReSize ) :
42 Container( _nInitSize )
43 {
44 nReSize = _nReSize;
45 nStartIndex = _nStartIndex;
46 nUniqIndex = 0;
47 nCount = 0;
48 }
49
50 /*************************************************************************
51 |*
52 |* UniqueIndex::UniqueIndex()
53 |*
54 |* Beschreibung UNQIDX.SDW
55 |* Ersterstellung TH 24.09.91
56 |* Letzte Aenderung TH 24.09.91
57 |*
58 *************************************************************************/
59
UniqueIndex(const UniqueIndex & rIdx)60 UniqueIndex::UniqueIndex( const UniqueIndex& rIdx ) :
61 Container( rIdx )
62 {
63 nReSize = rIdx.nReSize;
64 nStartIndex = rIdx.nStartIndex;
65 nUniqIndex = rIdx.nUniqIndex;
66 nCount = rIdx.nCount;
67 }
68
69 /*************************************************************************
70 |*
71 |* UniqueIndex::Insert()
72 |*
73 |* Beschreibung UNQIDX.SDW
74 |* Ersterstellung TH 24.09.91
75 |* Letzte Aenderung TH 24.09.91
76 |*
77 *************************************************************************/
78
Insert(void * p)79 sal_uIntPtr UniqueIndex::Insert( void* p )
80 {
81 // NULL-Pointer ist nicht erlaubt
82 if ( !p )
83 return UNIQUEINDEX_ENTRY_NOTFOUND;
84
85 // Ist Array voll, dann expandieren
86 if ( nCount == Container::GetSize() )
87 SetSize( nCount + nReSize );
88
89 // Damit UniqIndex nicht ueberlaeuft, wenn Items geloescht wurden
90 nUniqIndex = nUniqIndex % Container::GetSize();
91
92 // Leeren Eintrag suchen
93 while ( Container::ImpGetObject( nUniqIndex ) != NULL )
94 nUniqIndex = (nUniqIndex+1) % Container::GetSize();
95
96 // Object im Array speichern
97 Container::Replace( p, nUniqIndex );
98
99 // Anzahl der Eintraege erhoehen und Index zurueckgeben
100 nCount++;
101 nUniqIndex++;
102 return ( nUniqIndex + nStartIndex - 1 );
103 }
104
105 /*************************************************************************
106 |*
107 |* UniqueIndex::Insert()
108 |*
109 |* Beschreibung UNQIDX.SDW
110 |* Ersterstellung MM 21.04.96
111 |* Letzte Aenderung MM 21.04.96
112 |*
113 *************************************************************************/
114
Insert(sal_uIntPtr nIndex,void * p)115 sal_uIntPtr UniqueIndex::Insert( sal_uIntPtr nIndex, void* p )
116 {
117 // NULL-Pointer ist nicht erlaubt
118 if ( !p )
119 return UNIQUEINDEX_ENTRY_NOTFOUND;
120
121 sal_uIntPtr nContIndex = nIndex - nStartIndex;
122 // Ist Array voll, dann expandieren
123 if ( nContIndex >= Container::GetSize() )
124 SetSize( nContIndex + nReSize );
125
126 // Object im Array speichern
127 Container::Replace( p, nContIndex );
128
129 // Anzahl der Eintraege erhoehen und Index zurueckgeben
130 nCount++;
131 return nIndex;
132 }
133
134 /*************************************************************************
135 |*
136 |* UniqueIndex::Remove()
137 |*
138 |* Beschreibung UNQIDX.SDW
139 |* Ersterstellung TH 24.09.91
140 |* Letzte Aenderung TH 24.09.91
141 |*
142 *************************************************************************/
143
Remove(sal_uIntPtr nIndex)144 void* UniqueIndex::Remove( sal_uIntPtr nIndex )
145 {
146 // Ist Index zulaessig
147 if ( (nIndex >= nStartIndex) &&
148 (nIndex < (Container::GetSize()+nStartIndex)) )
149 {
150 // Index-Eintrag als leeren Eintrag setzen und Anzahl der
151 // gespeicherten Indexe erniedriegen, wenn Eintrag belegt war
152 void* p = Container::Replace( NULL, nIndex-nStartIndex );
153 if ( p )
154 nCount--;
155 return p;
156 }
157 else
158 return NULL;
159 }
160
161 /*************************************************************************
162 |*
163 |* UniqueIndex::Replace()
164 |*
165 |* Beschreibung UNQIDX.SDW
166 |* Ersterstellung TH 24.09.91
167 |* Letzte Aenderung TH 24.09.91
168 |*
169 *************************************************************************/
170
Replace(sal_uIntPtr nIndex,void * p)171 void* UniqueIndex::Replace( sal_uIntPtr nIndex, void* p )
172 {
173 // NULL-Pointer ist nicht erlaubt
174 if ( !p )
175 return NULL;
176
177 // Ist Index zulaessig
178 if ( IsIndexValid( nIndex ) )
179 {
180 // Index-Eintrag ersetzen und alten zurueckgeben
181 return Container::Replace( p, nIndex-nStartIndex );
182 }
183 else
184 return NULL;
185 }
186
187 /*************************************************************************
188 |*
189 |* UniqueIndex::Get()
190 |*
191 |* Beschreibung UNQIDX.SDW
192 |* Ersterstellung TH 24.09.91
193 |* Letzte Aenderung TH 24.09.91
194 |*
195 *************************************************************************/
196
Get(sal_uIntPtr nIndex) const197 void* UniqueIndex::Get( sal_uIntPtr nIndex ) const
198 {
199 // Ist Index zulaessig
200 if ( (nIndex >= nStartIndex) &&
201 (nIndex < (Container::GetSize()+nStartIndex)) )
202 return Container::ImpGetObject( nIndex-nStartIndex );
203 else
204 return NULL;
205 }
206
207 /*************************************************************************
208 |*
209 |* UniqueIndex::GetCurIndex()
210 |*
211 |* Beschreibung UNQIDX.SDW
212 |* Ersterstellung TH 24.09.91
213 |* Letzte Aenderung TH 24.09.91
214 |*
215 *************************************************************************/
216
GetCurIndex() const217 sal_uIntPtr UniqueIndex::GetCurIndex() const
218 {
219 sal_uIntPtr nPos = Container::GetCurPos();
220
221 // Ist der Current-Index nicht belegt, dann gibt es keinen Current-Index
222 if ( !Container::ImpGetObject( nPos ) )
223 return UNIQUEINDEX_ENTRY_NOTFOUND;
224 else
225 return nPos+nStartIndex;
226 }
227
228 /*************************************************************************
229 |*
230 |* UniqueIndex::GetIndex()
231 |*
232 |* Beschreibung UNQIDX.SDW
233 |* Ersterstellung TH 24.09.91
234 |* Letzte Aenderung TH 24.09.91
235 |*
236 *************************************************************************/
237
GetIndex(const void * p) const238 sal_uIntPtr UniqueIndex::GetIndex( const void* p ) const
239 {
240 // Wird ein NULL-Pointer uebergeben, dann wurde Pointer nicht gefunden
241 if ( !p )
242 return UNIQUEINDEX_ENTRY_NOTFOUND;
243
244 sal_uIntPtr nIndex = Container::GetPos( p );
245
246 if ( nIndex != CONTAINER_ENTRY_NOTFOUND )
247 return nIndex+nStartIndex;
248 else
249 return UNIQUEINDEX_ENTRY_NOTFOUND;
250 }
251
252 /*************************************************************************
253 |*
254 |* UniqueIndex::IsIndexValid()
255 |*
256 |* Beschreibung UNQIDX.SDW
257 |* Ersterstellung TH 24.09.91
258 |* Letzte Aenderung TH 24.09.91
259 |*
260 *************************************************************************/
261
IsIndexValid(sal_uIntPtr nIndex) const262 sal_Bool UniqueIndex::IsIndexValid( sal_uIntPtr nIndex ) const
263 {
264 // Ist Index zulaessig
265 if ( (nIndex >= nStartIndex) &&
266 (nIndex < (Container::GetSize()+nStartIndex)) )
267 {
268 // Index ist nur zulaessig, wenn Eintrag auch belegt ist
269 if ( Container::ImpGetObject( nIndex-nStartIndex ) )
270 return sal_True;
271 else
272 return sal_False;
273 }
274 else
275 return sal_False;
276 }
277
278 /*************************************************************************
279 |*
280 |* UniqueIndex::Seek()
281 |*
282 |* Beschreibung UNQIDX.SDW
283 |* Ersterstellung TH 24.09.91
284 |* Letzte Aenderung TH 24.09.91
285 |*
286 *************************************************************************/
287
Seek(sal_uIntPtr nIndex)288 void* UniqueIndex::Seek( sal_uIntPtr nIndex )
289 {
290 // Index-Eintrag als aktuellen setzten, wenn er gueltig ist
291 if ( IsIndexValid( nIndex ) )
292 return Container::Seek( nIndex-nStartIndex );
293 else
294 return NULL;
295 }
296
297 /*************************************************************************
298 |*
299 |* UniqueIndex::Seek()
300 |*
301 |* Beschreibung UNQIDX.SDW
302 |* Ersterstellung TH 24.09.91
303 |* Letzte Aenderung TH 24.09.91
304 |*
305 *************************************************************************/
306
Seek(void * p)307 void* UniqueIndex::Seek( void* p )
308 {
309 // Wird ein NULL-Pointer uebergeben, dann wurde Pointer nicht gefunden
310 if ( !p )
311 return NULL;
312
313 sal_uIntPtr nIndex = GetIndex( p );
314
315 // Ist Index vorhanden, dann als aktuellen Eintrag setzen
316 if ( nIndex != UNIQUEINDEX_ENTRY_NOTFOUND )
317 return Container::Seek( nIndex-nStartIndex );
318 else
319 return NULL;
320 }
321
322 /*************************************************************************
323 |*
324 |* UniqueIndex::First()
325 |*
326 |* Beschreibung UNQIDX.SDW
327 |* Ersterstellung TH 24.09.91
328 |* Letzte Aenderung TH 24.09.91
329 |*
330 *************************************************************************/
331
First()332 void* UniqueIndex::First()
333 {
334 void* p = Container::First();
335
336 while ( !p && (Container::GetCurPos() < (Container::GetSize()-1)) )
337 p = Container::Next();
338
339 return p;
340 }
341
342 /*************************************************************************
343 |*
344 |* UniqueIndex::Last()
345 |*
346 |* Beschreibung UNQIDX.SDW
347 |* Ersterstellung TH 24.09.91
348 |* Letzte Aenderung TH 24.09.91
349 |*
350 *************************************************************************/
351
Last()352 void* UniqueIndex::Last()
353 {
354 void* p = Container::Last();
355
356 while ( !p && Container::GetCurPos() )
357 p = Container::Prev();
358
359 return p;
360 }
361
362 /*************************************************************************
363 |*
364 |* UniqueIndex::Next()
365 |*
366 |* Beschreibung UNQIDX.SDW
367 |* Ersterstellung TH 24.09.91
368 |* Letzte Aenderung TH 24.09.91
369 |*
370 *************************************************************************/
371
Next()372 void* UniqueIndex::Next()
373 {
374 void* p = NULL;
375
376 while ( !p && (Container::GetCurPos() < (Container::GetSize()-1)) )
377 p = Container::Next();
378
379 return p;
380 }
381
382 /*************************************************************************
383 |*
384 |* UniqueIndex::Prev()
385 |*
386 |* Beschreibung UNQIDX.SDW
387 |* Ersterstellung TH 24.09.91
388 |* Letzte Aenderung TH 24.09.91
389 |*
390 *************************************************************************/
391
Prev()392 void* UniqueIndex::Prev()
393 {
394 void* p = NULL;
395
396 while ( !p && Container::GetCurPos() )
397 p = Container::Prev();
398
399 return p;
400 }
401
402 /*************************************************************************
403 |*
404 |* UniqueIndex::operator =()
405 |*
406 |* Beschreibung UNQIDX.SDW
407 |* Ersterstellung TH 24.09.91
408 |* Letzte Aenderung TH 24.09.91
409 |*
410 *************************************************************************/
411
operator =(const UniqueIndex & rIdx)412 UniqueIndex& UniqueIndex::operator =( const UniqueIndex& rIdx )
413 {
414 // Neue Werte zuweisen
415 Container::operator =( rIdx );
416 nReSize = rIdx.nReSize;
417 nStartIndex = rIdx.nStartIndex;
418 nUniqIndex = rIdx.nUniqIndex;
419 nCount = rIdx.nCount;
420 return *this;
421 }
422
423 /*************************************************************************
424 |*
425 |* UniqueIndex::operator ==()
426 |*
427 |* Beschreibung UNQIDX.SDW
428 |* Ersterstellung TH 24.09.91
429 |* Letzte Aenderung TH 24.09.91
430 |*
431 *************************************************************************/
432
operator ==(const UniqueIndex & rIdx) const433 sal_Bool UniqueIndex::operator ==( const UniqueIndex& rIdx ) const
434 {
435 // Neue Werte zuweisen
436 if ( (nStartIndex == rIdx.nStartIndex) &&
437 (nCount == rIdx.nCount) &&
438 (Container::operator ==( rIdx )) )
439 return sal_True;
440 else
441 return sal_False;
442 }
443 /*************************************************************************
444 |*
445 |* UniqueIdContainer::UniqueIdContainer ()
446 |*
447 |* Beschreibung UNQIDX.SDW
448 |* Ersterstellung MM 29.04.96
449 |* Letzte Aenderung MM 29.04.96
450 |*
451 *************************************************************************/
452
UniqueIdContainer(const UniqueIdContainer & rObj)453 UniqueIdContainer::UniqueIdContainer( const UniqueIdContainer& rObj )
454 : UniqueIndex( rObj )
455 , nCollectCount( rObj.nCollectCount )
456 {
457 sal_uIntPtr nCur = GetCurIndex();
458
459 ImpUniqueId * pEle = (ImpUniqueId *)First();
460 while( pEle )
461 {
462 pEle->nRefCount++;
463 pEle = (ImpUniqueId *)Next();
464 }
465 Seek( nCur );
466 }
467
468 /*************************************************************************
469 |*
470 |* UniqueIdContainer::operator = ()
471 |*
472 |* Beschreibung UNQIDX.SDW
473 |* Ersterstellung MM 01.08.94
474 |* Letzte Aenderung MM 01.08.94
475 |*
476 *************************************************************************/
477
operator =(const UniqueIdContainer & rObj)478 UniqueIdContainer& UniqueIdContainer::operator = ( const UniqueIdContainer & rObj )
479 {
480 UniqueIndex::operator = ( rObj );
481 nCollectCount = rObj.nCollectCount;
482
483 sal_uIntPtr nCur = GetCurIndex();
484
485 ImpUniqueId * pEle = (ImpUniqueId *)First();
486 while( pEle )
487 {
488 pEle->nRefCount++;
489 pEle = (ImpUniqueId *)Next();
490 }
491 Seek( nCur );
492 return *this;
493 }
494
495 /*************************************************************************
496 |*
497 |* UniqueIdContainer::Clear()
498 |*
499 |* Beschreibung UNQIDX.SDW
500 |* Ersterstellung MM 01.08.94
501 |* Letzte Aenderung MM 01.08.94
502 |*
503 *************************************************************************/
504
Clear(sal_Bool bAll)505 void UniqueIdContainer::Clear( sal_Bool bAll )
506 {
507 sal_uInt16 nFree = bAll ? 0xFFFF : 1;
508
509 ImpUniqueId* pId = (ImpUniqueId*)Last();
510 sal_Bool bLast = sal_True;
511 while ( pId )
512 {
513 if ( pId->nRefCount <= nFree )
514 {
515 ((ImpUniqueId *)Remove( pId->nId ))->Release();
516 if( bLast )
517 pId = (ImpUniqueId *)Last();
518 else
519 pId = (ImpUniqueId *)Prev();
520 }
521 else
522 {
523 pId = (ImpUniqueId *)Prev();
524 bLast = sal_False;
525 }
526 }
527 }
528
529 /*************************************************************************
530 |*
531 |* UniqueIdContainer::CreateId()
532 |*
533 |* Beschreibung UNQIDX.SDW
534 |* Ersterstellung MM 01.08.94
535 |* Letzte Aenderung MM 01.08.94
536 |*
537 *************************************************************************/
538
CreateId()539 UniqueItemId UniqueIdContainer::CreateId()
540 {
541 if( nCollectCount > 50 )
542 { // aufraeumen
543 Clear( sal_False );
544 nCollectCount = 0;
545 }
546 nCollectCount++;
547
548 ImpUniqueId * pId = new ImpUniqueId;
549 pId->nRefCount = 1;
550 pId->nId = Insert( pId );
551 return UniqueItemId( pId );
552 }
553
554 /*************************************************************************
555 |*
556 |* UniqueIdContainer::CreateIdProt()
557 |*
558 |* Beschreibung UNQIDX.SDW
559 |* Ersterstellung MM 01.08.94
560 |* Letzte Aenderung MM 01.08.94
561 |*
562 *************************************************************************/
563
CreateFreeId(sal_uIntPtr nId)564 UniqueItemId UniqueIdContainer::CreateFreeId( sal_uIntPtr nId )
565 {
566 // Einfach erzeugen, fuer abgeleitete Klasse
567 ImpUniqueId * pId = new ImpUniqueId;
568 pId->nRefCount = 0;
569 pId->nId = nId;
570 return UniqueItemId( pId );
571 }
572
573 /*************************************************************************
574 |*
575 |* UniqueIdContainer::CreateIdProt()
576 |*
577 |* Beschreibung UNQIDX.SDW
578 |* Ersterstellung MM 01.08.94
579 |* Letzte Aenderung MM 01.08.94
580 |*
581 *************************************************************************/
582
CreateIdProt(sal_uIntPtr nId)583 UniqueItemId UniqueIdContainer::CreateIdProt( sal_uIntPtr nId )
584 {
585 if ( IsIndexValid( nId ) )
586 return UniqueItemId( (ImpUniqueId *)Get( nId ) );
587
588 ImpUniqueId * pId;
589 do
590 {
591 pId = new ImpUniqueId;
592 pId->nRefCount = 1;
593 pId->nId = Insert( pId );
594 }
595 while( pId->nId != nId );
596 return UniqueItemId( pId );
597 }
598