xref: /trunk/main/tools/source/fsys/tdir.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_tools.hxx"
30 
31 #define _DIR_CXX
32 
33 #include <stdlib.h>
34 #include <cstdarg>
35 #include <limits.h>
36 #include <tools/debug.hxx>
37 #include <tools/list.hxx>
38 
39 #ifndef _COMPED_HXX
40 #include "comdep.hxx"
41 #endif
42 #include <tools/fsys.hxx>
43 
44 
45 DBG_NAME( Dir )
46 
47 DECLARE_LIST( DirEntryList, DirEntry* )
48 DECLARE_LIST( FSysSortList, FSysSort* )
49 DECLARE_LIST( FileStatList, FileStat* )
50 
51 #define APPEND (sal_uInt16) 65535
52 
53 /*************************************************************************
54 |*
55 |*    Dir::InsertPointReached()
56 |*
57 |*    Beschreibung      stellt fest, ob eingefuegt werden musz
58 |*    Ersterstellung    MA 05.11.91
59 |*    Letzte Aenderung  MI 05.02.92
60 |*
61 *************************************************************************/
62 
63 sal_Bool Dir::ImpInsertPointReached( const DirEntry& rNewEntry,
64                                  const FileStat& rNewStat,
65                                  sal_uIntPtr nCurPos, sal_uIntPtr nSortIndex ) const
66 {
67 #define VALUE( nKindFlags ) \
68     ( ( FSYS_KIND_FILE | FSYS_KIND_DIR | FSYS_KIND_DEV | \
69         FSYS_KIND_CHAR | FSYS_KIND_BLOCK ) & nKindFlags )
70 
71     // einfache Dinge erfordern einfache Loesungen
72     if ( !pLst->Count() )
73         return sal_True;
74 
75     FSysSort  nSort      = *( pSortLst->GetObject( nSortIndex ) );
76     FileStat *pOldStat   = NULL;
77     DirEntry *pCurLstObj = pLst->GetObject( nCurPos );
78     if ( pStatLst )
79         pOldStat = pStatLst->GetObject( nCurPos );
80 
81     switch( nSort )
82     {
83         case  FSYS_SORT_NAME:
84         case (FSYS_SORT_NAME | FSYS_SORT_ASCENDING):
85             if ( pCurLstObj->aName > rNewEntry.aName )
86                 return sal_True;
87             if ( !(pCurLstObj->aName == rNewEntry.aName) )
88                 return sal_False;
89             break;
90         case (FSYS_SORT_NAME | FSYS_SORT_DESCENDING):
91             if ( pCurLstObj->aName < rNewEntry.aName )
92                 return sal_True;
93             if ( !(pCurLstObj->aName == rNewEntry.aName) )
94                 return sal_False;
95             break;
96 
97         case  FSYS_SORT_EXT:
98         case (FSYS_SORT_EXT | FSYS_SORT_ASCENDING):
99         {
100             if ( pCurLstObj->GetExtension() > rNewEntry.GetExtension() )
101                 return sal_True;
102             if ( !(pCurLstObj->GetExtension() == rNewEntry.GetExtension()) )
103                 return sal_False;
104             break;
105         }
106         case (FSYS_SORT_EXT | FSYS_SORT_DESCENDING):
107         {
108             if ( pCurLstObj->GetExtension() < rNewEntry.GetExtension() )
109                 return sal_True;
110             if ( !(pCurLstObj->GetExtension() == rNewEntry.GetExtension()) )
111                 return sal_False;
112             break;
113         }
114 
115         case  FSYS_SORT_KIND:
116         case (FSYS_SORT_KIND | FSYS_SORT_ASCENDING ):
117             if ( VALUE(pOldStat->nKindFlags) > VALUE(rNewStat.nKindFlags) )
118                 return sal_True;
119             if ( !(VALUE(pOldStat->nKindFlags) == VALUE(rNewStat.nKindFlags)) )
120                 return sal_False;
121             break;
122         case (FSYS_SORT_KIND | FSYS_SORT_DESCENDING):
123             if ( VALUE(pOldStat->nKindFlags) < VALUE(rNewStat.nKindFlags) )
124                 return sal_True;
125             if ( !(VALUE(pOldStat->nKindFlags) == VALUE(rNewStat.nKindFlags)) )
126                 return sal_False;
127             break;
128 
129         case  FSYS_SORT_SIZE:
130         case (FSYS_SORT_SIZE | FSYS_SORT_ASCENDING):
131             if ( pOldStat->nSize > rNewStat.nSize )
132                 return sal_True;
133             if ( !(pOldStat->nSize == rNewStat.nSize) )
134                 return sal_False;
135             break;
136         case (FSYS_SORT_SIZE | FSYS_SORT_DESCENDING):
137             if ( pOldStat->nSize < rNewStat.nSize )
138                 return sal_True;
139             if ( !(pOldStat->nSize == rNewStat.nSize) )
140                 return sal_False;
141             break;
142 
143         case  FSYS_SORT_MODIFYED:
144         case (FSYS_SORT_MODIFYED | FSYS_SORT_ASCENDING):
145             if ( (pOldStat->aDateModified >= rNewStat.aDateModified) &&
146                  (pOldStat->aTimeModified >  rNewStat.aTimeModified) )
147                  return sal_True;
148             if ( !((pOldStat->aDateModified == rNewStat.aDateModified) &&
149                    (pOldStat->aTimeModified == rNewStat.aTimeModified)) )
150                 return sal_False;
151             break;
152         case (FSYS_SORT_MODIFYED | FSYS_SORT_DESCENDING):
153             if ( (pOldStat->aDateModified <= rNewStat.aDateModified) &&
154                  (pOldStat->aTimeModified <  rNewStat.aTimeModified) )
155                  return sal_True;
156             if ( !((pOldStat->aDateModified == rNewStat.aDateModified) &&
157                    (pOldStat->aTimeModified == rNewStat.aTimeModified)) )
158                 return sal_False;
159             break;
160 
161         case  FSYS_SORT_CREATED:
162         case (FSYS_SORT_CREATED | FSYS_SORT_ASCENDING):
163             if ( (pOldStat->aDateCreated >= rNewStat.aDateCreated) &&
164                  (pOldStat->aTimeCreated >  rNewStat.aTimeCreated) )
165                  return sal_True;
166             if ( !((pOldStat->aDateCreated == rNewStat.aDateCreated) &&
167                    (pOldStat->aTimeCreated == rNewStat.aTimeCreated)) )
168                 return sal_False;
169             break;
170         case (FSYS_SORT_CREATED | FSYS_SORT_DESCENDING):
171             if ( (pOldStat->aDateCreated <= rNewStat.aDateCreated) &&
172                  (pOldStat->aTimeCreated <  rNewStat.aTimeCreated) )
173                  return sal_True;
174             if ( !((pOldStat->aDateCreated == rNewStat.aDateCreated) &&
175                    (pOldStat->aTimeCreated == rNewStat.aTimeCreated)) )
176                 return sal_False;
177             break;
178 
179         case  FSYS_SORT_ACCESSED:
180         case (FSYS_SORT_ACCESSED | FSYS_SORT_ASCENDING):
181             if ( (pOldStat->aDateAccessed >= rNewStat.aDateAccessed) &&
182                  (pOldStat->aTimeAccessed >  rNewStat.aTimeAccessed) )
183                  return sal_True;
184             if ( !((pOldStat->aDateAccessed == rNewStat.aDateAccessed) &&
185                    (pOldStat->aTimeAccessed == rNewStat.aTimeAccessed)) )
186                 return sal_False;
187             break;
188         case (FSYS_SORT_ACCESSED | FSYS_SORT_DESCENDING):
189             if ( (pOldStat->aDateAccessed <= rNewStat.aDateAccessed) &&
190                  (pOldStat->aTimeAccessed <  rNewStat.aTimeAccessed) )
191                  return sal_True;
192             if ( !((pOldStat->aDateAccessed == rNewStat.aDateAccessed) &&
193                    (pOldStat->aTimeAccessed == rNewStat.aTimeAccessed)) )
194                 return sal_False;
195             break;
196         default: /* Kann nicht sein */;
197     }
198 
199     if ( nSortIndex == ( pSortLst->Count() - 1 ) )
200         return sal_True;
201     else
202         //Rekursion
203         return ImpInsertPointReached( rNewEntry, rNewStat,
204                                       nCurPos, nSortIndex + 1 );
205 #undef VALUE
206 }
207 
208 /*************************************************************************
209 |*
210 |*    Dir::ImpSortedInsert()
211 |*
212 |*    Beschreibung      fuegt sortiert ein
213 |*    Ersterstellung    MA 05.11.91
214 |*    Letzte Aenderung  MA 03.12.91
215 |*
216 *************************************************************************/
217 
218 void Dir::ImpSortedInsert( const DirEntry *pNewEntry, const FileStat *pNewStat )
219 {
220     //Sonderfall, keine Sortierung gewuenscht.
221     if ( !pSortLst ) {
222         pLst->Insert( (DirEntry*)pNewEntry, APPEND );
223         return;
224     }
225 
226     pLst->First();
227     do {
228         if ( ImpInsertPointReached( *pNewEntry, *pNewStat, pLst->GetCurPos(),
229                                     (sal_uIntPtr)0  ) )
230         {
231             if ( pStatLst )
232                 pStatLst->Insert( (FileStat*)pNewStat, pLst->GetCurPos() );
233             pLst->Insert( (DirEntry*)pNewEntry );
234             return;
235         }
236     } while( pLst->Next() );
237 
238     if ( pStatLst )
239         pStatLst->Insert( (FileStat*)pNewStat, APPEND );
240     pLst->Insert( (DirEntry*)pNewEntry, APPEND );
241 }
242 
243 /*************************************************************************
244 |*
245 |*    Dir::Construct()
246 |*
247 |*    Beschreibung      gemeinsame Implementation der Ctoren
248 |*    Ersterstellung    MI 02.06.93
249 |*    Letzte Aenderung  MI 02.06.93
250 |*
251 *************************************************************************/
252 
253 void Dir::Construct( DirEntryKind nKindFlags )
254 {
255     pLst     = NULL;
256     pSortLst = NULL;
257     pStatLst = NULL;
258     eAttrMask = nKindFlags;
259     ByteString aTempName( GetName(), osl_getThreadTextEncoding() );
260     if ( aTempName.Search( "*" ) != STRING_NOTFOUND ||
261          aTempName.Search( "?" ) != STRING_NOTFOUND )
262 #if defined( WNT ) && !defined( WTC )
263     {
264         ByteString aTStr(CutName(), osl_getThreadTextEncoding());
265         char* pBuffer = new char[aTStr.Len()+1];
266         strcpy( pBuffer, aTStr.GetBuffer() );
267         CharLowerBuff( pBuffer, aTStr.Len() );
268         aNameMask = WildCard( String(pBuffer, osl_getThreadTextEncoding()), ';' );
269         delete [] pBuffer;
270     }
271 #else
272     aNameMask = WildCard( CutName(), ';' );
273 #endif
274     else
275         aNameMask = String("*", osl_getThreadTextEncoding());
276 }
277 
278 /*************************************************************************
279 |*
280 |*    Dir::Update()
281 |*
282 |*    Beschreibung      FSYS.SDW
283 |*    Ersterstellung    MI 16.05.91
284 |*    Letzte Aenderung  MI 19.09.96
285 |*
286 *************************************************************************/
287 
288 sal_Bool Dir::Update()
289 {
290 	Reset();
291 	return Scan( USHRT_MAX ) > 0;
292 }
293 
294 /*************************************************************************
295 |*
296 |*    Dir::Reset()
297 |*
298 |*    Beschreibung
299 |*    Ersterstellung    MI 22.10.96
300 |*    Letzte Aenderung  MI 22.10.96
301 |*
302 *************************************************************************/
303 
304 void Dir::Reset()
305 {
306 	// ggf. alten Reader l"oschen
307 	if ( pReader && pReader->bInUse )
308 		DELETEZ(pReader);
309 
310 	// alle DirEntries aus der Liste entfernen und deren Speicher freigeben
311 	if ( pLst )
312 	{
313 		DirEntry* pEntry = pLst->First();
314 		while (pEntry)
315 		{
316 			DirEntry* pNext = pLst->Next();
317 			delete pEntry;
318 			pEntry = pNext;
319 		}
320 		pLst->Clear();
321 	}
322 	else
323 		pLst = new DirEntryList();
324 
325 	//	Alte File-Stat's Loeschen
326 	if ( pStatLst )
327 	{
328 		//Erstmal die alten Loeschen
329 		FileStat* pEntry = pStatLst->First();
330 		while (pEntry)
331 		{
332 			FileStat*  pNext = pStatLst->Next();
333 			delete pEntry;
334 			pEntry = pNext;
335 		}
336 		pStatLst->Clear();
337 		delete pStatLst;
338 	}
339 
340 	// Verlangen die Sortierkriterien FileStat's?
341 	if ( pSortLst )
342 	{
343 		pSortLst->First();
344 		do
345 		{
346 			if ( *( pSortLst->GetCurObject() ) &
347 					( FSYS_SORT_KIND | FSYS_SORT_SIZE |
348 					FSYS_SORT_CREATED | FSYS_SORT_MODIFYED | FSYS_SORT_ACCESSED ) )
349 				pStatLst = new FileStatList();
350 		} while ( !pStatLst && pSortLst->Next() );
351 	}
352 
353 #ifndef BOOTSTRAP
354 	// ggf. einen neuen Reader aufsetzen
355 	if ( !pReader )
356 		pReader = new DirReader_Impl( *this );
357 #endif
358 
359 	// gibt es das zu oeffnende Verzeichnis ueberhaupt?
360 #if !defined(UNX) && !defined(OS2) //explanation: see DirReader_Impl::Read() in unx.cxx
361 	if( !pReader->pDosDir )
362 	{
363 		nError = FSYS_ERR_NOTADIRECTORY;
364 		DELETEZ( pReader );
365 		return;
366 	}
367 #endif
368 }
369 
370 /*************************************************************************
371 |*
372 |*    Dir::Scan()
373 |*
374 |*    Beschreibung      FSYS.SDW
375 |*    Ersterstellung    MI 18.09.96
376 |*    Letzte Aenderung  MI 19.09.96
377 |*
378 *************************************************************************/
379 
380 sal_uInt16 Dir::Scan( sal_uInt16 nCount )
381 {
382 
383 	sal_uInt16 nRead = 0; // Anzahl in dieser Runde gelesener Eintr"age
384 	FSysFailOnErrorImpl();
385 
386 	// noch nicht fertig gewesen
387 	if ( pReader )
388 	{
389 		// frischer Reader?
390 		if ( !pLst->Count() )
391 		{
392 			// dann ggf. Laufwerke scannen
393 			pReader->bInUse = sal_True;
394 			nRead = pReader->Init();
395 		}
396 
397 		// weiterlesen...
398 		while ( nRead <= nCount && !pReader->bReady )
399 			nRead = nRead + pReader->Read();
400 
401 		// fertig?
402 		if ( pReader && pReader->bReady )
403 			DELETEZ( pReader );
404 	}
405 
406 	// Anzahl der gelesenen zur"uckgeben
407 	return nRead;
408 }
409 
410 /*************************************************************************
411 |*
412 |*    Dir::Dir()
413 |*
414 |*    Beschreibung      FSYS.SDW
415 |*    Ersterstellung    MI 16.05.91
416 |*    Letzte Aenderung  MI 04.03.92
417 |*
418 *************************************************************************/
419 
420 Dir::Dir( const DirEntry& rDirEntry, DirEntryKind nKindFlags, FSysSort nSort, ... ):
421     DirEntry( rDirEntry ),
422 	pReader( 0 )
423 {
424     DBG_CTOR( Dir, NULL );
425 
426     Construct( nKindFlags );
427 
428     std::va_list pArgs;
429     va_start( pArgs, nSort );
430     ImpSetSort( pArgs, nSort );
431 
432 	Reset();
433 }
434 
435 /*************************************************************************
436 |*
437 |*    Dir::Dir()
438 |*
439 |*    Beschreibung      FSYS.SDW
440 |*    Ersterstellung    MI 02.06.93
441 |*    Letzte Aenderung  MI 02.06.93
442 |*
443 *************************************************************************/
444 
445 Dir::Dir( const DirEntry& rDirEntry, DirEntryKind nKindFlags ):
446     DirEntry( rDirEntry ),
447 	pReader( 0 )
448 {
449     DBG_CTOR( Dir, NULL );
450 
451     Construct( nKindFlags );
452     Reset();
453 }
454 
455 /*************************************************************************
456 |*
457 |*    Dir::Dir()
458 |*
459 |*    Beschreibung      FSYS.SDW
460 |*    Ersterstellung    MI 16.05.91
461 |*    Letzte Aenderung  MA 04.11.91
462 |*
463 *************************************************************************/
464 
465 Dir::Dir():
466 	pReader( 0 )
467 {
468     DBG_CTOR( Dir, NULL );
469 
470     pLst     = NULL;
471     pSortLst = NULL;
472     pStatLst = NULL;
473     eAttrMask = FSYS_KIND_ALL;
474     aNameMask = String("*", osl_getThreadTextEncoding());
475 }
476 
477 /*************************************************************************
478 |*
479 |*    Dir::~Dir()
480 |*
481 |*    Beschreibung      FSYS.SDW
482 |*    Ersterstellung    MI 16.05.91
483 |*    Letzte Aenderung  MA 04.11.91
484 |*
485 *************************************************************************/
486 
487 Dir::~Dir()
488 {
489     DBG_DTOR( Dir, NULL );
490 
491     // alle DirEntries aus der Liste entfernen und deren Speicher freigeben
492     if ( pLst )
493     {
494 		DirEntry* pEntry = pLst->First();
495 		while (pEntry)
496 		{
497 			DirEntry* pNext = pLst->Next();
498 			delete pEntry;
499 			pEntry = pNext;
500 		}
501 		pLst->Clear();
502 
503         delete pLst;
504     }
505 
506     // alle Sorts aus der Liste entfernen und deren Speicher freigeben
507     if ( pSortLst )
508     {
509 		FSysSort* pEntry = pSortLst->First();
510 		while (pEntry)
511 		{
512 			FSysSort*  pNext = pSortLst->Next();
513 			delete pEntry;
514 			pEntry = pNext;
515 		}
516 		pSortLst->Clear();
517 
518         delete pSortLst;
519     }
520 
521     // alle FileStat's aus der Liste entfernen und deren Speicher freigeben
522     if ( pStatLst )
523     {
524 		FileStat* pEntry = pStatLst->First();
525 		while (pEntry)
526 		{
527 			FileStat*  pNext = pStatLst->Next();
528 			delete pEntry;
529 			pEntry = pNext;
530 		}
531 		pStatLst->Clear();
532         delete pStatLst;
533     }
534 
535 	// ggf. laufenden Reader freigeben
536 	delete pReader;
537 }
538 
539 /*************************************************************************
540 |*
541 |*    Dir::ImpSetSort()
542 |*
543 |*    Beschreibung      FSYS.SDW
544 |*    Ersterstellung    MA 04.11.91
545 |*    Letzte Aenderung  MI 05.02.92
546 |*
547 *************************************************************************/
548 
549 FSysError Dir::ImpSetSort( std::va_list pArgs, int nFirstSort )
550 {
551     sal_Bool             bLast;
552     FSysSort        *pSort;
553     FSysSortList    *pNewSortLst = new FSysSortList;
554 
555 	*( pSort = new FSysSort ) = nFirstSort;
556     do
557     {
558 		// letztes Kriterium?
559         bLast = FSYS_SORT_END == (*pSort & FSYS_SORT_END);
560         *pSort &= ~FSYS_SORT_END;
561 
562 		FSysSort nSort = *pSort & ~(sal_uInt16)FSYS_SORT_ASCENDING
563 							  &  ~(sal_uInt16)FSYS_SORT_DESCENDING;
564 
565 		// g"utliges Sortierkriterium?
566         if ( ( nSort ==  FSYS_SORT_NAME ) ||
567              ( nSort ==  FSYS_SORT_SIZE ) ||
568              ( nSort ==  FSYS_SORT_EXT )  ||
569              ( nSort ==  FSYS_SORT_CREATED ) ||
570              ( nSort ==  FSYS_SORT_MODIFYED ) ||
571              ( nSort ==  FSYS_SORT_ACCESSED ) ||
572 			 ( nSort ==  FSYS_SORT_KIND ) )
573         {
574             pNewSortLst->Insert( pSort, APPEND );
575             *(pSort = new FSysSort) = va_arg( pArgs, FSysSort );
576         }
577         else
578         {   // ungueltiger Sort oder FSYS_SORT_NONE
579 			FSysSort* pEntry = pNewSortLst->First();
580 			while (pEntry)
581 			{
582 				FSysSort* pNext = pNewSortLst->Next();
583 				delete pEntry;
584 				pEntry = pNext;
585 			}
586 			pNewSortLst->Clear();
587             delete pNewSortLst;
588             if ( *pSort ==  FSYS_SORT_NONE )
589 			{
590                 delete pSort;
591                 if ( pSortLst )
592                     delete pSortLst;
593                 return FSYS_ERR_OK;
594             }
595             else
596 			{
597                 delete pSort;
598                 return FSYS_ERR_NOTSUPPORTED;
599             }
600         }
601     } while ( !bLast );
602 
603     va_end( pArgs );
604 	delete pSort;			// JP:6.3.00 - delete the initial pointer
605 
606     //Enfernen der alten Sort-Elemente
607     if ( pSortLst )
608 	{
609 		FSysSort* pEntry = pSortLst->First();
610 		while (pEntry)
611 		{
612 			FSysSort* pNext = pSortLst->Next();
613 			delete pEntry;
614 			pEntry = pNext;
615 		}
616 		pSortLst->Clear();
617 		delete pSortLst;
618 	}
619     pSortLst = pNewSortLst;
620 
621     //Jetzt noch neu Sortieren...
622 
623     //Wenn keine FileStats da sind, aber nun welche gebraucht werden,
624     //ist der Aufruf von Update() die einfachste Moeglichkeit
625     if ( !pStatLst && pSortLst )
626     {
627         pSortLst->First();
628         do
629         {
630             if ( *(pSortLst->GetCurObject()) &
631                   ( FSYS_SORT_CREATED | FSYS_SORT_MODIFYED | FSYS_SORT_SIZE |
632                     FSYS_SORT_ACCESSED | FSYS_SORT_KIND ) )
633             {
634                 Update();
635                 return FSYS_ERR_OK;
636             }
637         } while ( !pStatLst && pSortLst->Next() );
638     }
639 
640     if ( pLst ) { //Keine DirEntry's, kein Sort.
641         DirEntryList    *pOldLst = pLst; //alte Liste merken
642         pLst = new DirEntryList();       //neue Liste (zu Sortieren)
643 
644         FileStatList *pOldStatLst = NULL; //alte StatListe merken
645         if ( pStatLst ) {
646             pOldStatLst = pStatLst;
647             pStatLst = new FileStatList(); //neue StatListe (zu Sortieren)
648         }
649         pOldLst->First();
650         do
651         {
652             //Sortiertes Einfuegen der Elemente aus den gemerkten Listen
653             //in die 'richtigen' Listen
654             if ( pOldStatLst )
655                 ImpSortedInsert( pOldLst->GetCurObject(),
656                                  pOldStatLst->GetObject( pOldLst->GetCurPos() ) );
657             else
658                 ImpSortedInsert( pOldLst->GetCurObject(), NULL );
659         } while( pOldLst->Next() );
660 
661         delete pOldLst;
662         if ( pOldStatLst )
663             delete pOldStatLst;
664     }
665     return FSYS_ERR_OK;
666 }
667 
668 /*************************************************************************
669 |*
670 |*    Dir::SetSort()
671 |*
672 |*    Beschreibung      FSYS.SDW
673 |*    Ersterstellung    MA 04.11.91
674 |*    Letzte Aenderung  MI 05.02.92
675 |*
676 *************************************************************************/
677 
678 FSysError Dir::SetSort( FSysSort nSort, ... )
679 {
680     std::va_list pArgs;
681     va_start( pArgs, nSort );
682     return ImpSetSort( pArgs, nSort );
683 }
684 
685 /*************************************************************************
686 |*
687 |*    Dir::operator[]()
688 |*
689 |*    Beschreibung      FSYS.SDW
690 |*    Ersterstellung    MI 16.05.91
691 |*    Letzte Aenderung  MI 16.05.91
692 |*
693 *************************************************************************/
694 
695 DirEntry& Dir::operator[] ( sal_uInt16 nIndex ) const
696 {
697     DBG_ASSERT( nIndex < Count(), "Dir::operator[] : nIndex > Count()" );
698 
699     DirEntry *pEntry = pLst->GetObject( nIndex );
700 	return *pEntry;
701 }
702 
703 /*************************************************************************
704 |*
705 |*    Dir::operator+= ()
706 |*
707 |*    Beschreibung      FSYS.SDW
708 |*    Ersterstellung    MI 16.05.91
709 |*    Letzte Aenderung  MI 16.05.91
710 |*
711 *************************************************************************/
712 
713 Dir& Dir::operator+=( const Dir& rDir )
714 {
715 	// ggf. erst den Rest lesen
716 	if ( pReader )
717 		Scan( USHRT_MAX );
718 	DBG_ASSERT( !rDir.pReader, "Dir::+= with incomplete Dir" );
719 
720 	// ggf. initiale Liste erzeugen
721     if ( !pLst )
722         pLst = new DirEntryList();
723 
724     //Verlangen die Sortierkriterien FileStat's?
725     sal_Bool bStat = sal_False;
726     if ( pSortLst ) {
727         pSortLst->First();
728         do {
729             if ( *(pSortLst->GetCurObject()) &
730                   ( FSYS_SORT_CREATED | FSYS_SORT_MODIFYED | FSYS_SORT_SIZE |
731                     FSYS_SORT_ACCESSED | FSYS_SORT_KIND ) )
732                 bStat = sal_True;
733         } while ( !bStat && pSortLst->Next() );
734     }
735     FileStat * stat = NULL;
736     for ( sal_uInt16 nNr = 0; nNr < rDir.Count(); nNr++ )
737     {
738         if ( bStat )
739         {
740             if ( rDir.pStatLst )
741                 stat = new FileStat( *rDir.pStatLst->GetObject(nNr) );
742             else
743                 stat = new FileStat( rDir[nNr] );
744         }
745         ImpSortedInsert( new DirEntry( rDir[nNr] ), stat );
746     }
747     return *this;
748 }
749 
750 /*************************************************************************
751 |*
752 |*    Dir::Count()
753 |*
754 |*    Beschreibung      FSYS.SDW
755 |*    Ersterstellung    MI 16.05.91
756 |*    Letzte Aenderung  MI 18.09.96
757 |*
758 *************************************************************************/
759 
760 
761 sal_uInt16 Dir::Count( sal_Bool bUpdated ) const
762 {
763 	// ggf. erst den Rest lesen
764 	if ( bUpdated && pReader )
765 		((Dir*)this)->Scan( USHRT_MAX );
766 
767 	return pLst == NULL ? 0 : (sal_uInt16) pLst->Count();
768 }
769