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: dirent.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_tools.hxx"
40 #if defined(UNX) || defined(OS2)
42 #include <sys/types.h>
51 #include <tools/debug.hxx>
52 #include <tools/list.hxx>
54 #include <tools/fsys.hxx>
56 #include <tools/urlobj.hxx>
61 #include <tools/stream.hxx>
63 #ifndef _VOS_MUTEX_HXX
64 #include <vos/mutex.hxx>
67 #include <osl/file.hxx>
68 #include <rtl/instance.hxx>
74 int ApiRet2ToSolarError_Impl( int nApiRet
);
76 //--------------------------------------------------------------------
77 int Sys2SolarError_Impl( int nSysErr
)
82 case NO_ERROR
: return ERRCODE_NONE
;
83 case ERROR_INVALID_FUNCTION
: return ERRCODE_IO_GENERAL
;
84 case ERROR_FILE_NOT_FOUND
: return ERRCODE_IO_NOTEXISTS
;
85 case ERROR_PATH_NOT_FOUND
: return ERRCODE_IO_NOTEXISTSPATH
;
86 case ERROR_TOO_MANY_OPEN_FILES
: return ERRCODE_IO_TOOMANYOPENFILES
;
87 case ERROR_ACCESS_DENIED
: return ERRCODE_IO_ACCESSDENIED
;
88 case ERROR_INVALID_HANDLE
: return ERRCODE_IO_GENERAL
;
89 case ERROR_NOT_ENOUGH_MEMORY
: return ERRCODE_IO_OUTOFMEMORY
;
90 case ERROR_INVALID_BLOCK
: return ERRCODE_IO_GENERAL
;
91 // case ERROR_BAD_ENVIRONMENT: return ERRCODE_IO_;
92 case ERROR_BAD_FORMAT
: return ERRCODE_IO_WRONGFORMAT
;
93 case ERROR_INVALID_ACCESS
: return ERRCODE_IO_ACCESSDENIED
;
94 // case ERROR_INVALID_DATA: return ERRCODE_IO_;
95 case ERROR_INVALID_DRIVE
: return ERRCODE_IO_INVALIDDEVICE
;
96 case ERROR_CURRENT_DIRECTORY
: return ERRCODE_IO_CURRENTDIR
;
97 case ERROR_NOT_SAME_DEVICE
: return ERRCODE_IO_NOTSAMEDEVICE
;
98 // case ERROR_NO_MORE_FILES: return ERRCODE_IO_;
99 case ERROR_WRITE_PROTECT
: return ERRCODE_IO_CANTWRITE
;
100 case ERROR_BAD_UNIT
: return ERRCODE_IO_INVALIDDEVICE
;
101 case ERROR_NOT_READY
: return ERRCODE_IO_DEVICENOTREADY
;
102 case ERROR_BAD_COMMAND
: return ERRCODE_IO_GENERAL
;
103 case ERROR_CRC
: return ERRCODE_IO_BADCRC
;
104 case ERROR_BAD_LENGTH
: return ERRCODE_IO_INVALIDLENGTH
;
105 case ERROR_SEEK
: return ERRCODE_IO_CANTSEEK
;
106 case ERROR_NOT_DOS_DISK
: return ERRCODE_IO_WRONGFORMAT
;
107 case ERROR_SECTOR_NOT_FOUND
: return ERRCODE_IO_GENERAL
;
108 case ERROR_WRITE_FAULT
: return ERRCODE_IO_CANTWRITE
;
109 case ERROR_READ_FAULT
: return ERRCODE_IO_CANTREAD
;
110 case ERROR_GEN_FAILURE
: return ERRCODE_IO_GENERAL
;
111 case ERROR_SHARING_VIOLATION
: return ERRCODE_IO_LOCKVIOLATION
;
112 case ERROR_LOCK_VIOLATION
: return ERRCODE_IO_LOCKVIOLATION
;
113 case ERROR_WRONG_DISK
: return ERRCODE_IO_INVALIDDEVICE
;
114 case ERROR_NOT_SUPPORTED
: return ERRCODE_IO_NOTSUPPORTED
;
116 case 0: return ERRCODE_NONE
;
117 case ENOENT
: return ERRCODE_IO_NOTEXISTS
;
118 case EACCES
: return ERRCODE_IO_ACCESSDENIED
;
119 case EEXIST
: return ERRCODE_IO_ALREADYEXISTS
;
120 case EINVAL
: return ERRCODE_IO_INVALIDPARAMETER
;
121 case EMFILE
: return ERRCODE_IO_TOOMANYOPENFILES
;
122 case ENOMEM
: return ERRCODE_IO_OUTOFMEMORY
;
123 case ENOSPC
: return ERRCODE_IO_OUTOFSPACE
;
127 DBG_TRACE1( "FSys: unknown system error %d occured", nSysErr
);
128 return FSYS_ERR_UNKNOWN
;
131 //--------------------------------------------------------------------
135 FSysRedirector
* FSysRedirector::_pRedirector
= 0;
136 BOOL
FSysRedirector::_bEnabled
= TRUE
;
138 BOOL bInRedirection
= TRUE
;
140 BOOL bInRedirection
= FALSE
;
142 static NAMESPACE_VOS( OMutex
)* pRedirectMutex
= 0;
144 //------------------------------------------------------------------------
145 void FSysRedirector::Register( FSysRedirector
*pRedirector
)
148 pRedirectMutex
= new NAMESPACE_VOS( OMutex
);
150 DELETEZ( pRedirectMutex
);
151 _pRedirector
= pRedirector
;
154 //------------------------------------------------------------------------
156 void FSysRedirector::DoRedirect( String
&rPath
)
160 // if redirection is disabled or not even registered do nothing
161 if ( !_bEnabled
|| !pRedirectMutex
)
164 // redirect only removable or remote volumes
165 if ( !IsRedirectable_Impl( ByteString( aURL
, osl_getThreadTextEncoding() ) ) )
168 // Redirection is acessible only by one thread per time
169 // dont move the guard behind the bInRedirection check!!!
170 // think of nested calls (when called from callback)
171 NAMESPACE_VOS( OGuard
) aGuard( pRedirectMutex
);
173 // if already in redirection, dont redirect
174 if ( bInRedirection
)
177 // dont redirect on nested calls
178 bInRedirection
= TRUE
;
182 for ( sal_Unicode
*p
= (sal_Unicode
*)aURL
.GetBuffer(); *p
; ++p
)
183 if ( '\\' == *p
) *p
= '/';
184 else if ( ':' == *p
) *p
= '|';
187 aURL
.Insert( String("file:///", osl_getThreadTextEncoding()), 0 );
192 bInRedirection
= FALSE
;
196 //------------------------------------------------------------------------
198 FSysRedirector
* FSysRedirector::Redirector()
201 Register( new FSysRedirector
);
207 //--------------------------------------------------------------------
209 class DirEntryStack
: public List
215 inline void Push( DirEntry
*pEntry
);
216 inline DirEntry
* Pop();
217 inline DirEntry
* Top();
218 inline DirEntry
* Bottom();
221 inline void DirEntryStack::Push( DirEntry
*pEntry
)
223 List::Insert( pEntry
, LIST_APPEND
);
226 inline DirEntry
* DirEntryStack::Pop()
228 return (DirEntry
*) List::Remove( Count() - 1 );
231 inline DirEntry
* DirEntryStack::Top()
233 return (DirEntry
*) List::GetObject( Count() - 1 );
236 inline DirEntry
* DirEntryStack::Bottom()
238 return (DirEntry
*) List::GetObject( 0 );
241 //--------------------------------------------------------------------
243 DBG_NAME( DirEntry
);
245 /*************************************************************************
247 |* DirEntry::~DirEntryStack()
249 |* Beschreibung FSYS.SDW
250 |* Ersterstellung MI 26.04.91
251 |* Letzte Aenderung MI 04.07.91
253 *************************************************************************/
255 DirEntryStack::~DirEntryStack()
261 /*************************************************************************
263 |* ImpCheckDirEntry()
265 |* Beschreibung Pruefung eines DirEntry fuer DBG_UTIL
266 |* Parameter void* p Zeiger auf den DirEntry
267 |* Return-Wert char* Fehlermeldungs-TExtension oder NULL
268 |* Ersterstellung MI 16.07.91
269 |* Letzte Aenderung MI 26.05.93
271 *************************************************************************/
274 const char* ImpCheckDirEntry( const void* p
)
276 DirEntry
* p0
= (DirEntry
*)p
;
279 DBG_CHKOBJ( p0
->pParent
, DirEntry
, ImpCheckDirEntry
);
285 /*************************************************************************
289 |* Beschreibung Fuegt ... ein, damit maximal nMaxChars lang
290 |* Ersterstellung MI 06.04.94
291 |* Letzte Aenderung DV 24.06.96
293 *************************************************************************/
295 ByteString
ImplCutPath( const ByteString
& rStr
, USHORT nMax
, char cAccDel
)
297 USHORT nMaxPathLen
= nMax
;
298 ByteString
aCutPath( rStr
);
299 BOOL bInsertPrefix
= FALSE
;
300 USHORT nBegin
= aCutPath
.Search( cAccDel
);
302 if( nBegin
== STRING_NOTFOUND
)
305 nMaxPathLen
+= 2; // fuer Prefix <Laufwerk>:
307 while( aCutPath
.Len() > nMaxPathLen
)
309 USHORT nEnd
= aCutPath
.Search( cAccDel
, nBegin
+ 1 );
312 if ( nEnd
!= STRING_NOTFOUND
)
314 nCount
= nEnd
- nBegin
;
315 aCutPath
.Erase( nBegin
, nCount
);
316 bInsertPrefix
= TRUE
;
322 if ( aCutPath
.Len() > nMaxPathLen
)
324 for ( USHORT n
= nMaxPathLen
; n
> nMaxPathLen
/2; --n
)
325 if ( !ByteString(aCutPath
.GetChar(n
)).IsAlphaNumericAscii() )
335 ByteString
aIns( cAccDel
);
337 aCutPath
.Insert( aIns
, nBegin
);
343 /*************************************************************************
345 |* DirEntry::ImpParseOs2Name()
347 |* Beschreibung FSYS.SDW
348 |* Ersterstellung MI 26.04.91
349 |* Letzte Aenderung MI 23.06.95
351 *************************************************************************/
353 FSysError
DirEntry::ImpParseOs2Name( const ByteString
& rPfad
, FSysPathStyle eStyle
)
355 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
357 // die einzelnen Namen auf einen Stack packen
358 String
aPfad( rPfad
, osl_getThreadTextEncoding() );
359 DirEntryStack aStack
;
363 // den Namen vor dem ersten "\\" abspalten,
364 // falls '\\' am Anfang, ist der Name '\\',
365 // der Rest immer ohne die fuehrenden '\\'.
366 // ein ":" trennt ebenfalls, gehoert aber zum Namen
367 // den ersten '\\', '/' oder ':' suchen
370 nPos
< aPfad
.Len() && //?O
371 aPfad
.GetChar(nPos
) != '\\' && aPfad
.GetChar(nPos
) != '/' && //?O
372 aPfad
.GetChar(nPos
) != ':'; //?O
376 // ist der Name ein UNC Pathname?
377 if ( nPos
== 0 && aPfad
.Len() > 1 &&
378 ( ( aPfad
.GetChar(0) == '\\' && aPfad
.GetChar(1) == '\\' ) ||
379 ( aPfad
.GetChar(0) == '/' && aPfad
.GetChar(1) == '/' ) ) )
381 for ( nPos
= 2; aPfad
.Len() > nPos
; ++nPos
)
382 if ( aPfad
.GetChar(nPos
) == '\\' || aPfad
.GetChar(nPos
) == '/' )
384 aName
= ByteString( aPfad
.Copy( 2, nPos
-2 ), osl_getThreadTextEncoding() );
385 aStack
.Push( new DirEntry( aName
, FSYS_FLAG_ABSROOT
, eStyle
) );
387 // ist der Name die Root des aktuellen Drives?
388 else if ( nPos
== 0 && aPfad
.Len() > 0 &&
389 ( aPfad
.GetChar(0) == '\\' || aPfad
.GetChar(0) == '/' ) )
391 // Root-Directory des aktuellen Drives
392 aStack
.Push( new DirEntry( FSYS_FLAG_ABSROOT
) );
396 // ist der Name ein Drive?
397 if ( nPos
< aPfad
.Len() && aPfad
.GetChar(nPos
) == ':' )
399 aName
= ByteString( aPfad
.Copy( 0, nPos
+ 1 ), osl_getThreadTextEncoding() );
401 // ist der Name die Root des Drives
402 if ( (nPos
+ 1) < aPfad
.Len() &&
403 ( aPfad
.GetChar(nPos
+1) == '\\' || aPfad
.GetChar(nPos
+1) == '/' ) )
405 // schon was auf dem Stack?
406 // oder Novell-Format? (not supported wegen URLs)
407 if ( aStack
.Count() || aName
.Len() > 2 )
410 return FSYS_ERR_MISPLACEDCHAR
;
412 // Root-Directory des Drive
413 aStack
.Push( new DirEntry( aName
, FSYS_FLAG_ABSROOT
, eStyle
) );
417 // liegt ein anderes Drive auf dem Stack?
418 if ( aStack
.Count() &&
419 COMPARE_EQUAL
!= aStack
.Bottom()->aName
.CompareIgnoreCaseToAscii(aName
) )
422 // liegt jetzt nichts mehr auf dem Stack?
423 if ( !aStack
.Count() )
424 aStack
.Push( new DirEntry( aName
, FSYS_FLAG_RELROOT
, eStyle
) );
431 // den Namen ohne Trenner abspalten
432 aName
= ByteString( aPfad
.Copy( 0, nPos
), osl_getThreadTextEncoding() );
434 // stellt der Name die aktuelle Directory dar?
438 // stellt der Name die Parent-Directory dar?
439 else if ( aName
== ".." )
441 // ist nichts, ein Parent oder eine relative Root
443 if ( ( aStack
.Count() == 0 ) ||
444 ( aStack
.Top()->eFlag
== FSYS_FLAG_PARENT
) ||
445 ( aStack
.Top()->eFlag
== FSYS_FLAG_RELROOT
) )
446 // fuehrende Parents kommen auf den Stack
447 aStack
.Push( new DirEntry( FSYS_FLAG_PARENT
) );
449 // ist es eine absolute Root
450 else if ( aStack
.Top()->eFlag
== FSYS_FLAG_ABSROOT
)
452 // die hat keine Parent-Directory
454 return FSYS_ERR_NOTEXISTS
;
457 // sonst hebt der Parent den TOS auf
463 if ( eStyle
== FSYS_STYLE_FAT
)
465 // ist der Name grundsaetzlich ungueltig?
468 for ( pChar
= aName
.GetBuffer();
469 nPunkte
< 2 && *pChar
!= 0;
475 nPunkte
+= ( *pChar
== '.' ) ? 1 : 0;
480 return FSYS_ERR_MISPLACEDCHAR
;
484 // normalen Entries kommen auf den Stack
485 DirEntry
*pNew
= new DirEntry( aName
, FSYS_FLAG_NORMAL
, eStyle
);
486 if ( !pNew
->IsValid() )
489 ErrCode eErr
= pNew
->GetError();
498 // den Restpfad bestimmen
499 aPfad
.Erase( 0, nPos
+ 1 );
500 while ( aPfad
.Len() && ( aPfad
.GetChar(0) == '\\' || aPfad
.GetChar(0) == '/' ) )
503 while ( aPfad
.Len() );
505 ULONG nErr
= ERRCODE_NONE
;
506 // Haupt-Entry (selbst) zuweisen
507 if ( aStack
.Count() == 0 )
509 eFlag
= FSYS_FLAG_CURRENT
;
514 eFlag
= aStack
.Top()->eFlag
;
515 aName
= aStack
.Top()->aName
;
516 nErr
= aStack
.Top()->nError
;
520 // die Parent-Entries vom Stack holen
521 DirEntry
** pTemp
= &pParent
; // Zeiger auf den Member pParent setzen
522 while ( aStack
.Count() )
524 *pTemp
= aStack
.Pop();
526 // Zeiger auf den Member pParent des eigenen Parent setzen
527 pTemp
= &( (*pTemp
)->pParent
);
530 // wird damit ein Volume beschrieben?
531 if ( !pParent
&& eFlag
== FSYS_FLAG_RELROOT
&& aName
.Len() )
532 eFlag
= FSYS_FLAG_VOLUME
;
534 // bei gesetztem ErrorCode den Namen komplett "ubernehmen
540 /*************************************************************************
542 |* DirEntry::ImpParseName()
544 |* Beschreibung FSYS.SDW
545 |* Ersterstellung MI 26.08.91
546 |* Letzte Aenderung MI 26.05.93
548 *************************************************************************/
550 FSysError
DirEntry::ImpParseName( const ByteString
& rbInitName
,
551 FSysPathStyle eStyle
)
553 String
rInitName( rbInitName
, osl_getThreadTextEncoding() );
554 if ( eStyle
== FSYS_STYLE_HOST
)
557 // KI-Division of FSys
558 if ( eStyle
== FSYS_STYLE_DETECT
)
560 sal_Unicode cFirst
= rInitName
.GetChar(0);
561 if ( rInitName
.Len() == 2 && rInitName
.GetChar(1) == ':' &&
562 ((cFirst
>= 'A' && cFirst
<= 'Z') ||
563 (cFirst
>= 'a' && cFirst
<= 'z')))
564 eStyle
= FSYS_STYLE_HPFS
;
565 else if ( rInitName
.Len() > 2 && rInitName
.GetChar(1) == ':' )
567 if ( rInitName
.Search( ':', 2 ) == STRING_NOTFOUND
)
568 eStyle
= FSYS_STYLE_HPFS
;
570 eStyle
= FSYS_STYLE_MAC
;
572 else if ( rInitName
.Search( '/' ) != STRING_NOTFOUND
)
573 eStyle
= FSYS_STYLE_BSD
;
574 else if ( rInitName
.Search( '\\' ) != STRING_NOTFOUND
)
575 eStyle
= FSYS_STYLE_HPFS
;
576 else if ( rInitName
.Search( ':' ) != STRING_NOTFOUND
)
577 eStyle
= FSYS_STYLE_MAC
;
579 eStyle
= FSYS_STYLE_HPFS
;
585 case FSYS_STYLE_VFAT
:
586 case FSYS_STYLE_HPFS
:
587 case FSYS_STYLE_NTFS
:
588 case FSYS_STYLE_NWFS
:
589 return ImpParseOs2Name( rbInitName
, eStyle
);
592 case FSYS_STYLE_SYSV
:
593 return ImpParseUnixName( rbInitName
, eStyle
);
599 return FSYS_ERR_UNKNOWN
;
603 /*************************************************************************
607 |* Beschreibung FSYS.SDW
608 |* Ersterstellung MI 15.11.91
609 |* Letzte Aenderung MI 15.11.91
611 *************************************************************************/
613 static FSysPathStyle
GetStyle( FSysPathStyle eStyle
)
615 if ( eStyle
== FSYS_STYLE_HOST
|| eStyle
== FSYS_STYLE_DETECT
)
621 /*************************************************************************
623 |* DirEntry::ImpTrim()
625 |* Beschreibung bringt den Namen auf Betriebssystem-Norm
626 |* z.B. 8.3 lower beim MS-DOS Formatter
627 |* wirkt nicht rekursiv
628 |* Ersterstellung MI 12.08.91
629 |* Letzte Aenderung MI 21.05.92
631 *************************************************************************/
633 void DirEntry::ImpTrim( FSysPathStyle eStyle
)
635 // Wildcards werden nicht geclipt
636 if ( ( aName
.Search( '*' ) != STRING_NOTFOUND
) ||
637 ( aName
.Search( '?' ) != STRING_NOTFOUND
) ||
638 ( aName
.Search( ';' ) != STRING_NOTFOUND
) )
645 USHORT nPunktPos
= aName
.Search( '.' );
646 if ( nPunktPos
== STRING_NOTFOUND
)
648 if ( aName
.Len() > 8 )
650 nError
= ERRCODE_IO_MISPLACEDCHAR
|ERRCODE_WARNING_MASK
;
658 nError
= ERRCODE_IO_MISPLACEDCHAR
|ERRCODE_WARNING_MASK
;
659 aName
.Erase( 8, nPunktPos
- 8 );
662 if ( aName
.Len() > nPunktPos
+ 3 )
664 if ( aName
.Len() - nPunktPos
> 4 )
666 nError
= ERRCODE_IO_MISPLACEDCHAR
|ERRCODE_WARNING_MASK
;
667 aName
.Erase( nPunktPos
+ 4 );
671 aName
.ToLowerAscii();
675 case FSYS_STYLE_VFAT
:
676 case FSYS_STYLE_HPFS
:
677 case FSYS_STYLE_NTFS
:
678 case FSYS_STYLE_NWFS
:
679 if ( aName
.Len() > 254 )
681 nError
= ERRCODE_IO_MISPLACEDCHAR
|ERRCODE_WARNING_MASK
;
685 if ( eStyle
== FSYS_STYLE_HPFS
&&
686 ( eFlag
== FSYS_FLAG_ABSROOT
|| eFlag
== FSYS_FLAG_RELROOT
) )
687 aName
.ToUpperAscii();
690 case FSYS_STYLE_SYSV
:
691 if ( aName
.Len() > 14 )
693 nError
= ERRCODE_IO_MISPLACEDCHAR
|ERRCODE_WARNING_MASK
;
699 if ( aName
.Len() > 250 )
701 nError
= ERRCODE_IO_MISPLACEDCHAR
|ERRCODE_WARNING_MASK
;
707 if ( eFlag
& ( FSYS_FLAG_ABSROOT
| FSYS_FLAG_VOLUME
) )
709 if ( aName
.Len() > 27 )
711 nError
= ERRCODE_IO_MISPLACEDCHAR
|ERRCODE_WARNING_MASK
;
717 if ( aName
.Len() > 31 )
719 nError
= ERRCODE_IO_MISPLACEDCHAR
|ERRCODE_WARNING_MASK
;
726 /* kann nicht sein */;
730 /*************************************************************************
732 |* DirEntry::DirEntry()
734 |* Beschreibung FSYS.SDW
735 |* Ersterstellung MI 26.04.91
736 |* Letzte Aenderung MA 02.12.91
738 *************************************************************************/
740 DirEntry::DirEntry( const ByteString
& rName
, DirEntryFlag eDirFlag
,
741 FSysPathStyle eStyle
) :
742 #ifdef FEAT_FSYS_DOUBLESPEED
747 DBG_CTOR( DirEntry
, ImpCheckDirEntry
);
751 nError
= FSYS_ERR_OK
;
756 /*************************************************************************
758 |* DirEntry::DirEntry()
760 |* Beschreibung FSYS.SDW
761 |* Ersterstellung MI 26.04.91
762 |* Letzte Aenderung MA 02.12.91
764 *************************************************************************/
766 DirEntry::DirEntry( const DirEntry
& rOrig
) :
767 #ifdef FEAT_FSYS_DOUBLESPEED
768 pStat( rOrig
.pStat
? new FileStat(*rOrig
.pStat
) : 0 ),
772 DBG_CTOR( DirEntry
, ImpCheckDirEntry
);
775 nError
= rOrig
.nError
;
779 pParent
= new DirEntry( *rOrig
.pParent
);
787 /*************************************************************************
789 |* DirEntry::DirEntry()
791 |* Beschreibung FSYS.SDW
792 |* Ersterstellung MI 26.04.91
793 |* Letzte Aenderung MA 02.12.91
795 *************************************************************************/
797 DirEntry::DirEntry( const String
& rInitName
, FSysPathStyle eStyle
)
798 #ifdef FEAT_FSYS_DOUBLESPEED
802 DBG_CTOR( DirEntry
, ImpCheckDirEntry
);
806 // schnelle Loesung fuer Leerstring
807 if ( !rInitName
.Len())
809 eFlag
= FSYS_FLAG_CURRENT
;
810 nError
= FSYS_ERR_OK
;
814 ByteString
aTmpName(rInitName
, osl_getThreadTextEncoding());
815 if( eStyle
== FSYS_STYLE_URL
|| aTmpName
.CompareIgnoreCaseToAscii("file:",5 ) == COMPARE_EQUAL
)
818 DBG_WARNING( "File URLs are not permitted but accepted" );
819 aTmpName
= ByteString(String(INetURLObject( rInitName
).PathToFileName()), osl_getThreadTextEncoding());
820 eStyle
= FSYS_STYLE_HOST
;
825 ::rtl::OUString aTmp
;
826 ::rtl::OUString aOInitName
;
827 if ( FileBase::getFileURLFromSystemPath( OUString( rInitName
), aTmp
) == FileBase::E_None
)
829 aOInitName
= OUString( rInitName
);
830 aTmpName
= ByteString( String(aOInitName
), osl_getThreadTextEncoding() );
834 // ASF nur bei Default eStyle, nicht z.B. aus MakeShortName()
835 if( eStyle
== FSYS_STYLE_HOST
&&
836 aTmpName
.Search( "://" ) != STRING_NOTFOUND
)
838 ByteString aErr
= "DirEntries akzeptieren nur File URLS: ";
840 DBG_WARNING( aErr
.GetBuffer() );
845 nError
= ImpParseName( aTmpName
, eStyle
);
847 if ( nError
!= FSYS_ERR_OK
)
848 eFlag
= FSYS_FLAG_INVALID
;
851 /*************************************************************************/
853 DirEntry::DirEntry( const ByteString
& rInitName
, FSysPathStyle eStyle
)
854 #ifdef FEAT_FSYS_DOUBLESPEED
858 DBG_CTOR( DirEntry
, ImpCheckDirEntry
);
862 // schnelle Loesung fuer Leerstring
863 if ( !rInitName
.Len() )
865 eFlag
= FSYS_FLAG_CURRENT
;
866 nError
= FSYS_ERR_OK
;
870 ByteString
aTmpName( rInitName
);
871 if( eStyle
== FSYS_STYLE_URL
|| rInitName
.CompareIgnoreCaseToAscii("file:",5 ) == COMPARE_EQUAL
)
874 DBG_WARNING( "File URLs are not permitted but accepted" );
875 aTmpName
= ByteString(String(INetURLObject( rInitName
).PathToFileName()), osl_getThreadTextEncoding());
876 eStyle
= FSYS_STYLE_HOST
;
881 // ASF nur bei Default eStyle, nicht z.B. aus MakeShortName()
882 if( eStyle
== FSYS_STYLE_HOST
&&
883 rInitName
.Search( "://" ) != STRING_NOTFOUND
)
885 ByteString aErr
= "DirEntries akzeptieren nur File URLS: ";
887 DBG_WARNING( aErr
.GetBuffer() );
891 nError
= ImpParseName( aTmpName
, eStyle
);
893 if ( nError
!= FSYS_ERR_OK
)
894 eFlag
= FSYS_FLAG_INVALID
;
897 /*************************************************************************
899 |* DirEntry::DirEntry()
901 |* Beschreibung FSYS.SDW
902 |* Ersterstellung MI 26.04.91
903 |* Letzte Aenderung MA 02.12.91
905 *************************************************************************/
907 DirEntry::DirEntry( DirEntryFlag eDirFlag
)
908 #ifdef FEAT_FSYS_DOUBLESPEED
912 DBG_CTOR( DirEntry
, ImpCheckDirEntry
);
915 nError
= ( eFlag
== FSYS_FLAG_INVALID
) ? FSYS_ERR_UNKNOWN
: FSYS_ERR_OK
;
919 /*************************************************************************
921 |* DirEntry::~DirEntry()
923 |* Beschreibung FSYS.SDW
924 |* Ersterstellung MI 26.04.91
925 |* Letzte Aenderung MA 02.12.91
927 *************************************************************************/
929 DirEntry::~DirEntry()
931 DBG_DTOR( DirEntry
, ImpCheckDirEntry
);
934 #ifdef FEAT_FSYS_DOUBLESPEED
940 /*************************************************************************
942 |* DirEntry::ImpGetTopPtr() const
944 |* Beschreibung FSYS.SDW
945 |* Ersterstellung MI 26.04.91
946 |* Letzte Aenderung MA 02.12.91
948 *************************************************************************/
950 const DirEntry
* DirEntry::ImpGetTopPtr() const
952 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
954 const DirEntry
*pTemp
= this;
955 while ( pTemp
->pParent
)
956 pTemp
= pTemp
->pParent
;
961 /*************************************************************************
963 |* DirEntry::ImpGetTopPtr()
965 |* Beschreibung FSYS.SDW
966 |* Ersterstellung MI 13.11.91
967 |* Letzte Aenderung MA 02.12.91
969 *************************************************************************/
971 DirEntry
* DirEntry::ImpGetTopPtr()
973 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
975 DirEntry
*pTemp
= this;
976 while ( pTemp
->pParent
)
977 pTemp
= pTemp
->pParent
;
982 /*************************************************************************
984 |* DirEntry::ImpGetPreTopPtr()
986 |* Beschreibung liefert einen Pointer auf den vorletzten Entry
987 |* Ersterstellung MI 01.11.91
988 |* Letzte Aenderung MA 02.12.91
990 *************************************************************************/
992 DirEntry
* DirEntry::ImpGetPreTopPtr()
994 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
996 DirEntry
*pTemp
= this;
997 if ( pTemp
->pParent
)
999 while ( pTemp
->pParent
->pParent
)
1000 pTemp
= pTemp
->pParent
;
1006 /*************************************************************************
1008 |* DirEntry::ImpChangeParent()
1010 |* Beschreibung FSYS.SDW
1011 |* Ersterstellung MI 26.04.91
1012 |* Letzte Aenderung MI 21.05.92
1014 *************************************************************************/
1016 DirEntry
* DirEntry::ImpChangeParent( DirEntry
* pNewParent
, BOOL bNormalize
)
1018 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1020 DirEntry
*pTemp
= pParent
;
1021 if ( bNormalize
&& pNewParent
&&
1022 pNewParent
->eFlag
== FSYS_FLAG_RELROOT
&& !pNewParent
->aName
.Len() )
1028 pParent
= pNewParent
;
1033 /*************************************************************************
1035 |* DirEntry::Exists()
1037 |* Beschreibung FSYS.SDW
1038 |* Ersterstellung MI 26.04.91
1039 |* Letzte Aenderung MI 24.09.91
1041 *************************************************************************/
1043 BOOL
DirEntry::Exists( FSysAccess nAccess
) const
1046 static NAMESPACE_VOS(OMutex
) aLocalMutex
;
1047 NAMESPACE_VOS(OGuard
) aGuard( aLocalMutex
);
1052 #if defined WNT || defined OS2
1053 // spezielle Filenamen sind vom System da
1054 if ( ( aName
.CompareIgnoreCaseToAscii("CLOCK$") == COMPARE_EQUAL
||
1055 aName
.CompareIgnoreCaseToAscii("CON") == COMPARE_EQUAL
||
1056 aName
.CompareIgnoreCaseToAscii("AUX") == COMPARE_EQUAL
||
1057 aName
.CompareIgnoreCaseToAscii("COM1") == COMPARE_EQUAL
||
1058 aName
.CompareIgnoreCaseToAscii("COM2") == COMPARE_EQUAL
||
1059 aName
.CompareIgnoreCaseToAscii("COM3") == COMPARE_EQUAL
||
1060 aName
.CompareIgnoreCaseToAscii("COM4") == COMPARE_EQUAL
||
1061 aName
.CompareIgnoreCaseToAscii("LPT1") == COMPARE_EQUAL
||
1062 aName
.CompareIgnoreCaseToAscii("LPT2") == COMPARE_EQUAL
||
1063 aName
.CompareIgnoreCaseToAscii("LPT3") == COMPARE_EQUAL
||
1064 aName
.CompareIgnoreCaseToAscii("NUL") == COMPARE_EQUAL
||
1065 aName
.CompareIgnoreCaseToAscii("PRN") == COMPARE_EQUAL
) )
1069 FSysFailOnErrorImpl();
1070 DirEntryKind eKind
= FileStat( *this, nAccess
).GetKind();
1071 if ( eKind
& ( FSYS_KIND_FILE
| FSYS_KIND_DIR
) )
1076 #if defined WNT || defined OS2
1077 if ( 0 != ( eKind
& FSYS_KIND_DEV
) )
1079 return DRIVE_EXISTS( ImpGetTopPtr()->aName
.GetChar(0) );
1083 return 0 != ( eKind
& ( FSYS_KIND_FILE
| FSYS_KIND_DIR
) );
1086 /*************************************************************************
1088 |* DirEntry::First()
1090 |* Beschreibung FSYS.SDW
1091 |* Ersterstellung MI 26.04.91
1092 |* Letzte Aenderung MA 15.01.92
1094 *************************************************************************/
1096 BOOL
DirEntry::First()
1098 FSysFailOnErrorImpl();
1100 String
aUniPathName( GetPath().GetFull() );
1102 FSysRedirector::DoRedirect( aUniPathName
);
1103 ByteString
aPathName(aUniPathName
, osl_getThreadTextEncoding());
1105 ByteString
aPathName(aUniPathName
, gsl_getSystemTextEncoding());
1107 aPathName
= GUI2FSYS( aPathName
);
1109 DIR *pDir
= opendir( (char*) aPathName
.GetBuffer() );
1113 WildCard
aWildeKarte( String(CMP_LOWER( aName
), osl_getThreadTextEncoding()) );
1115 WildCard
aWildeKarte( String(CMP_LOWER( aName
), gsl_getSystemTextEncoding()) );
1117 for ( dirent
* pEntry
= readdir( pDir
);
1119 pEntry
= readdir( pDir
) )
1121 ByteString
aFound( FSYS2GUI( ByteString( pEntry
->d_name
) ) );
1122 if ( aWildeKarte
.Matches( String(CMP_LOWER( aFound
), osl_getThreadTextEncoding())))
1134 /*************************************************************************
1136 |* DirEntry::GetFull()
1138 |* Beschreibung FSYS.SDW
1139 |* Ersterstellung MI 26.04.91
1140 |* Letzte Aenderung MA 02.12.91
1142 *************************************************************************/
1144 String
DirEntry::GetFull( FSysPathStyle eStyle
, BOOL bWithDelimiter
,
1145 USHORT nMaxChars
) const
1147 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1150 eStyle
= GetStyle( eStyle
);
1153 if ( ( pParent
->eFlag
== FSYS_FLAG_ABSROOT
||
1154 pParent
->eFlag
== FSYS_FLAG_RELROOT
||
1155 pParent
->eFlag
== FSYS_FLAG_VOLUME
) )
1157 aRet
= ByteString(pParent
->GetName( eStyle
), osl_getThreadTextEncoding());
1158 aRet
+= ByteString(GetName( eStyle
), osl_getThreadTextEncoding());
1162 aRet
= ByteString(pParent
->GetFull( eStyle
), osl_getThreadTextEncoding());
1163 aRet
+= ACCESSDELIM_C(eStyle
);
1164 aRet
+= ByteString(GetName( eStyle
), osl_getThreadTextEncoding());
1169 aRet
= ByteString(GetName( eStyle
), osl_getThreadTextEncoding());
1172 if ( ( eStyle
== FSYS_STYLE_MAC
) &&
1173 ( ImpGetTopPtr()->eFlag
!= FSYS_FLAG_VOLUME
) &&
1174 ( ImpGetTopPtr()->eFlag
!= FSYS_FLAG_ABSROOT
) &&
1175 ( aRet
.GetChar(0) != ':' ) )
1176 aRet
.Insert( ACCESSDELIM_C(eStyle
), 0 );
1179 if ( bWithDelimiter
)
1180 if ( aRet
.GetChar( aRet
.Len()-1 ) != ACCESSDELIM_C(eStyle
) )
1181 aRet
+= ACCESSDELIM_C(eStyle
);
1184 if ( nMaxChars
< STRING_MAXLEN
)
1185 aRet
= ImplCutPath( aRet
, nMaxChars
, ACCESSDELIM_C(eStyle
) );
1187 return String(aRet
, osl_getThreadTextEncoding());
1190 /*************************************************************************
1192 |* DirEntry::GetPath()
1194 |* Beschreibung FSYS.SDW
1195 |* Ersterstellung MI 26.04.91
1196 |* Letzte Aenderung MA 02.12.91
1198 *************************************************************************/
1200 DirEntry
DirEntry::GetPath() const
1202 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1205 return DirEntry( *pParent
);
1210 /*************************************************************************
1212 |* DirEntry::GetExtension()
1214 |* Beschreibung FSYS.SDW
1215 |* Ersterstellung MI 26.04.91
1216 |* Letzte Aenderung MA 02.12.91
1218 *************************************************************************/
1220 String
DirEntry::GetExtension( char cSep
) const
1222 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1224 const char *p0
= ( aName
.GetBuffer() );
1225 const char *p1
= p0
+ aName
.Len() - 1;
1226 while ( p1
>= p0
&& *p1
!= cSep
)
1230 // es wurde ein cSep an der Position p1 gefunden
1232 aName
.Copy( static_cast< xub_StrLen
>(p1
- p0
+ 1) ),
1233 osl_getThreadTextEncoding());
1237 /*************************************************************************
1239 |* DirEntry::GetBase()
1241 |* Beschreibung FSYS.SDW
1242 |* Ersterstellung MI 26.04.91
1243 |* Letzte Aenderung MA 02.12.91
1245 *************************************************************************/
1247 String
DirEntry::GetBase( char cSep
) const
1249 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1251 const char *p0
= ( aName
.GetBuffer() );
1252 const char *p1
= p0
+ aName
.Len() - 1;
1253 while ( p1
>= p0
&& *p1
!= cSep
)
1257 // es wurde ein cSep an der Position p1 gefunden
1259 aName
.Copy( 0, static_cast< xub_StrLen
>(p1
- p0
) ),
1260 osl_getThreadTextEncoding());
1263 // es wurde kein cSep gefunden
1264 return String(aName
, osl_getThreadTextEncoding());
1267 /*************************************************************************
1269 |* DirEntry::GetName()
1271 |* Beschreibung FSYS.SDW
1272 |* Ersterstellung MI 26.04.91
1273 |* Letzte Aenderung MA 02.12.91 13:47
1275 *************************************************************************/
1277 String
DirEntry::GetName( FSysPathStyle eStyle
) const
1279 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1282 eStyle
= GetStyle( eStyle
);
1286 case FSYS_FLAG_PARENT
:
1287 aRet
= ACTPARENT(eStyle
);
1290 case FSYS_FLAG_ABSROOT
:
1292 if ( eStyle
== FSYS_STYLE_URL
)
1300 if ( aName
.GetChar(aName
.Len()-1) == ':' )
1302 aRet
.SetChar(aRet
.Len()-1, '|');
1306 aRet
.Insert( '/', 5 );
1312 else if ( eStyle
!= FSYS_STYLE_MAC
&&
1313 aName
.Len() > 1 && aName
.GetChar( 1 ) != ':' )
1316 aRet
= ACCESSDELIM_C(eStyle
);
1317 aRet
+= ACCESSDELIM_C(eStyle
);
1319 aRet
+= ACCESSDELIM_C(eStyle
);
1324 aRet
+= ACCESSDELIM_C(eStyle
);
1329 case FSYS_FLAG_INVALID
:
1330 case FSYS_FLAG_VOLUME
:
1332 if ( eStyle
== FSYS_STYLE_URL
)
1337 if ( aName
.Len() && aName
.GetChar(aName
.Len()-1) == ':' )
1339 aRet
.SetChar(aRet
.Len()-1, '|');
1351 case FSYS_FLAG_RELROOT
:
1354 aRet
= ACTCURRENT(eStyle
);
1362 return String(aRet
, osl_getThreadTextEncoding());
1365 /*************************************************************************
1367 |* DirEntry::IsAbs()
1369 |* Beschreibung FSYS.SDW
1370 |* Ersterstellung MI 26.04.91
1371 |* Letzte Aenderung MA 02.12.91
1373 *************************************************************************/
1375 bool DirEntry::IsAbs() const
1377 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1380 return ( pParent
? pParent
->IsAbs() : eFlag
== FSYS_FLAG_ABSROOT
);
1382 return ( pParent
? pParent
->IsAbs() : eFlag
== FSYS_FLAG_ABSROOT
&& aName
.Len() > 0 );
1386 /*************************************************************************
1388 |* DirEntry::CutName()
1390 |* Beschreibung FSYS.SDW
1391 |* Ersterstellung MI 26.04.91
1392 |* Letzte Aenderung MA 02.12.91
1394 *************************************************************************/
1396 String
DirEntry::CutName( FSysPathStyle eStyle
)
1398 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1400 eStyle
= GetStyle( eStyle
);
1402 String
aOldName( GetName( eStyle
) );
1406 DirEntry
*pOldParent
= pParent
;
1409 pParent
= pOldParent
->pParent
;
1410 eFlag
= pOldParent
->eFlag
;
1411 aName
= pOldParent
->aName
;
1412 pOldParent
->pParent
= NULL
;
1417 eFlag
= FSYS_FLAG_CURRENT
;
1423 eFlag
= FSYS_FLAG_CURRENT
;
1432 /*************************************************************************
1434 |* DirEntry::NameCompare
1436 |* Beschreibung Vergleich nur die Namen (ohne Pfad, aber mit Gross/Klein)
1437 |* Ersterstellung MI 26.04.91
1438 |* Letzte Aenderung MA 02.12.91
1440 *************************************************************************/
1442 StringCompare
DirEntry::NameCompare( const DirEntry
&rWith
) const
1444 ByteString aThisName
;
1445 ByteString aParameterName
;
1449 aParameterName
= rWith
.aName
;
1451 aThisName
= ByteString(aName
).ToLowerAscii();
1452 aParameterName
= ByteString(rWith
.aName
).ToLowerAscii();
1455 return aThisName
.CompareTo( aParameterName
);
1459 /*************************************************************************
1461 |* DirEntry::operator==()
1463 |* Beschreibung FSYS.SDW
1464 |* Ersterstellung MI 26.04.91
1465 |* Letzte Aenderung MA 02.12.91
1467 *************************************************************************/
1469 BOOL
DirEntry::operator==( const DirEntry
& rEntry
) const
1471 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1473 // test wheather the contents are textual the same
1475 if ( nError
&& ( nError
== rEntry
.nError
) )
1477 if ( nError
|| rEntry
.nError
||
1478 ( eFlag
== FSYS_FLAG_INVALID
) ||
1479 ( rEntry
.eFlag
== FSYS_FLAG_INVALID
) )
1485 DirEntry
*pThis
= (DirEntry
*)this;
1489 DirEntry
*pWith
= (DirEntry
*)&rEntry
;
1490 while( pThis
&& pWith
&& (pThis
->eFlag
== pWith
->eFlag
) )
1492 if ( CMP_LOWER(pThis
->aName
) != CMP_LOWER(pWith
->aName
) )
1494 pThis
= pThis
->pParent
;
1495 pWith
= pWith
->pParent
;
1498 return ( !pThis
&& !pWith
);
1501 /*************************************************************************
1503 |* DirEntry::operator=()
1505 |* Beschreibung FSYS.SDW
1506 |* Ersterstellung MI 26.04.91
1507 |* Letzte Aenderung MA 02.12.91
1509 *************************************************************************/
1511 DirEntry
& DirEntry::operator=( const DirEntry
& rEntry
)
1513 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1515 if ( this == &rEntry
)
1517 if ( rEntry
.nError
!= FSYS_ERR_OK
) {
1518 DBG_ERROR("Zuweisung mit invalidem DirEntry");
1519 nError
= rEntry
.nError
;
1523 // Name und Typ uebernehmen, Refs beibehalten
1524 aName
= rEntry
.aName
;
1525 eFlag
= rEntry
.eFlag
;
1526 nError
= FSYS_ERR_OK
;
1528 DirEntry
*pOldParent
= pParent
;
1529 if ( rEntry
.pParent
)
1530 pParent
= new DirEntry( *rEntry
.pParent
);
1539 /*************************************************************************
1541 |* DirEntry::operator+()
1543 |* Beschreibung FSYS.SDW
1544 |* Ersterstellung MI 26.04.91
1545 |* Letzte Aenderung MA 02.12.91
1547 *************************************************************************/
1549 DirEntry
DirEntry::operator+( const DirEntry
& rEntry
) const
1551 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1553 static BOOL bTested
= FALSE
;
1561 const DirEntry
*pEntryTop
= rEntry
.ImpGetTopPtr();
1562 const DirEntry
*pThisTop
= ImpGetTopPtr();
1564 // "." + irgendwas oder irgendwas + "d:irgendwas"
1566 if ( ( eFlag == FSYS_FLAG_RELROOT && !aName ) ||
1567 ( pEntryTop->aName.Len() &&
1568 ( pEntryTop->eFlag == FSYS_FLAG_ABSROOT ||
1569 pEntryTop->eFlag == FSYS_FLAG_RELROOT ||
1570 pEntryTop->eFlag == FSYS_FLAG_VOLUME ) ) )
1575 (eFlag
== FSYS_FLAG_RELROOT
&& !aName
.Len()) ||
1577 (pEntryTop
->aName
.Len() ||
1578 ((rEntry
.Level()>1)?(rEntry
[rEntry
.Level()-2].aName
.CompareIgnoreCaseToAscii(RFS_IDENTIFIER
)==COMPARE_EQUAL
):FALSE
))
1580 (pEntryTop
->eFlag
== FSYS_FLAG_ABSROOT
||
1581 pEntryTop
->eFlag
== FSYS_FLAG_RELROOT
||
1582 pEntryTop
->eFlag
== FSYS_FLAG_VOLUME
)
1589 // irgendwas + "." (=> pEntryTop == &rEntry)
1590 if ( pEntryTop
->eFlag
== FSYS_FLAG_RELROOT
&& !pEntryTop
->aName
.Len() )
1592 DBG_ASSERT( pEntryTop
== &rEntry
, "DirEntry::op+ buggy" );
1596 // root += ".." (=> unmoeglich)
1597 if ( pEntryTop
->eFlag
== FSYS_FLAG_PARENT
&& pThisTop
== this &&
1598 ( eFlag
== FSYS_FLAG_ABSROOT
) )
1599 return DirEntry( FSYS_FLAG_INVALID
);
1601 // irgendwas += abs (=> nur Device uebernehmen falls vorhanden)
1602 if ( pEntryTop
->eFlag
== FSYS_FLAG_ABSROOT
)
1605 if ( pThisTop
->eFlag
== FSYS_FLAG_ABSROOT
)
1606 aDevice
= pThisTop
->aName
;
1607 DirEntry aRet
= rEntry
;
1608 if ( aDevice
.Len() )
1609 aRet
.ImpGetTopPtr()->aName
= aDevice
;
1613 // irgendwas += ".." (=> aufloesen)
1614 if ( eFlag
== FSYS_FLAG_NORMAL
&& pEntryTop
->eFlag
== FSYS_FLAG_PARENT
)
1616 String
aConcated( GetFull() );
1617 aConcated
+= ACCESSDELIM_C(FSYS_STYLE_HOST
);
1618 aConcated
+= rEntry
.GetFull();
1619 return DirEntry( aConcated
);
1622 // sonst einfach hintereinander haengen
1623 DirEntry
aRet( rEntry
);
1624 DirEntry
*pTop
= aRet
.ImpGetTopPtr();
1625 pTop
->pParent
= new DirEntry( *this );
1630 /*************************************************************************
1632 |* DirEntry::operator+=()
1634 |* Beschreibung FSYS.SDW
1635 |* Ersterstellung MI 26.04.91
1636 |* Letzte Aenderung MA 02.12.91
1638 *************************************************************************/
1640 DirEntry
&DirEntry::operator+=( const DirEntry
& rEntry
)
1642 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1644 return *this = *this + rEntry
;
1647 /*************************************************************************
1649 |* DirEntry::GetAccessDelimiter()
1651 |* Beschreibung FSYS.SDW
1652 |* Ersterstellung MI 27.05.93
1653 |* Letzte Aenderung MI 10.06.93
1655 *************************************************************************/
1657 String
DirEntry::GetAccessDelimiter( FSysPathStyle eFormatter
)
1659 return String( ACCESSDELIM_C( GetStyle( eFormatter
) ) );
1662 /*************************************************************************
1664 |* DirEntry::SetExtension()
1666 |* Beschreibung FSYS.SDW
1667 |* Ersterstellung MI 02.08.91
1668 |* Letzte Aenderung MA 02.12.91
1670 *************************************************************************/
1672 void DirEntry::SetExtension( const String
& rExtension
, char cSep
)
1674 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1676 // do not set extensions for drives
1677 if(eFlag
== FSYS_FLAG_ABSROOT
)
1679 nError
= FSYS_ERR_NOTSUPPORTED
;
1683 // cSep im Namen suchen
1684 const char *p0
= ( aName
.GetBuffer() );
1685 const char *p1
= p0
+ aName
.Len() - 1;
1686 while ( p1
>= p0
&& *p1
!= cSep
)
1690 // es wurde ein cSep an der Position p1 gefunden
1692 static_cast< xub_StrLen
>(
1693 p1
- p0
+ 1 - ( rExtension
.Len() ? 0 : 1 )) );
1694 aName
+= ByteString(rExtension
, osl_getThreadTextEncoding());
1696 else if ( rExtension
.Len() )
1698 // es wurde kein cSep gefunden
1700 aName
+= ByteString(rExtension
, osl_getThreadTextEncoding());
1704 /*************************************************************************
1706 |* DirEntry::CutExtension()
1708 |* Beschreibung FSYS.SDW
1709 |* Ersterstellung MI 23.07.93
1710 |* Letzte Aenderung MI 23.07.93
1712 *************************************************************************/
1714 String
DirEntry::CutExtension( char cSep
)
1716 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1718 const char *p0
= ( aName
.GetBuffer() );
1719 const char *p1
= p0
+ aName
.Len() - 1;
1720 while ( p1
>= p0
&& *p1
!= cSep
)
1725 // es wurde ein cSep an der Position p1 gefunden
1726 aName
.Erase( static_cast< xub_StrLen
>(p1
-p0
) );
1727 return String(p1
+ 1, osl_getThreadTextEncoding());
1733 /*************************************************************************
1735 |* DirEntry::SetName()
1737 |* Beschreibung FSYS.SDW
1738 |* Ersterstellung MI 04.09.93
1739 |* Letzte Aenderung MI 04.09.93
1741 *************************************************************************/
1743 void DirEntry::SetName( const String
& rName
, FSysPathStyle eFormatter
)
1745 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1747 if ( eFormatter
== FSYS_STYLE_HOST
|| eFormatter
== FSYS_STYLE_DETECT
)
1748 eFormatter
= DEFSTYLE
;
1749 ByteString
aAccDelim( ACCESSDELIM_C( eFormatter
) );
1751 if ( (eFlag
!= FSYS_FLAG_NORMAL
) ||
1752 (aName
.Search( ':' ) != STRING_NOTFOUND
) ||
1753 (aName
.Search( aAccDelim
) != STRING_NOTFOUND
) ||
1754 (eFormatter
== FSYS_STYLE_FAT
&& (aName
.GetTokenCount( '.' ) > 2) ) )
1756 eFlag
= FSYS_FLAG_INVALID
;
1760 aName
= ByteString(rName
, osl_getThreadTextEncoding());
1764 /*************************************************************************
1768 |* Beschreibung FSYS.SDW
1769 |* Ersterstellung MI 26.04.91
1770 |* Letzte Aenderung MA 02.12.91
1772 *************************************************************************/
1773 BOOL
DirEntry::Find( const String
& rPfad
, char cDelim
)
1775 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1777 if ( ImpGetTopPtr()->eFlag
== FSYS_FLAG_ABSROOT
)
1780 BOOL bWild
= aName
.Search( '*' ) != STRING_NOTFOUND
||
1781 aName
.Search( '?' ) != STRING_NOTFOUND
;
1783 cDelim
= SEARCHDELIM(DEFSTYLE
)[0];
1785 USHORT nTokenCount
= rPfad
.GetTokenCount( cDelim
);
1787 ByteString aThis
= ACCESSDELIM(DEFSTYLE
);
1788 aThis
+= ByteString(GetFull(), osl_getThreadTextEncoding());
1789 for ( USHORT nToken
= 0; nToken
< nTokenCount
; ++nToken
)
1791 ByteString aPath
= ByteString(rPfad
, osl_getThreadTextEncoding()).GetToken( 0, cDelim
, nIndex
);
1795 if (aPath
.GetChar(aPath
.Len()-1)== ACCESSDELIM(DEFSTYLE
)[0])
1796 aPath
.Erase(aPath
.Len()-1);
1798 DirEntry
aEntry( String(aPath
, osl_getThreadTextEncoding()));
1799 if ( aEntry
.ToAbs() &&
1800 ( ( !bWild
&& aEntry
.Exists() ) || ( bWild
&& aEntry
.First() ) ) )
1810 /*************************************************************************
1812 |* DirEntry::ImpToRel()
1815 |* Ersterstellung MI 17.06.93
1816 |* Letzte Aenderung MI 17.06.93
1818 *************************************************************************/
1820 BOOL
DirEntry::ImpToRel( String aCurStr
)
1822 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1824 DirEntry
aThis(*this);
1826 String
aThisStr( aThis
.GetFull( FSYS_STYLE_HPFS
) );
1828 // #109512 preserve case of path even if caseinsensitive
1829 String
aThisCompareStr( aThisStr
), aCurCompareStr( aCurStr
);
1830 if ( ! IsCaseSensitive() )
1832 aThisCompareStr
.ToLowerAscii();
1833 aCurCompareStr
.ToLowerAscii();
1836 // "Ubereinstimmung pr"ufen
1837 USHORT nPos
= aThisCompareStr
.Match( aCurCompareStr
);
1838 if ( nPos
== STRING_MATCH
&& aThisStr
.Len() != aCurStr
.Len() )
1839 nPos
= Min( aThisStr
.Len(), aCurStr
.Len() );
1841 // Sonderfall, die DirEntries sind identisch
1842 if ( nPos
== STRING_MATCH
)
1844 // dann ist der relative Pfad das aktuelle Verzeichnis
1849 // Sonderfall, die DirEntries sind total verschieden
1852 // dann ist der relativste Pfad absolut
1857 // sonst nehmen wir die identischen Einzelteile vorne weg
1858 while ( nPos
> 0 && aThisStr
.GetChar(nPos
) != '\\' )
1860 aThisStr
.Erase( 0, nPos
+ ( ( aThisStr
.GetChar(nPos
) == '\\' ) ? 1 : 0 ) );
1861 aCurStr
.Erase( 0, nPos
+ ( ( aCurStr
.GetChar(nPos
) == '\\' ) ? 1 : 0 ) );
1863 // und fuellen mit dem Level der Directories auf
1864 for ( nPos
= 0; nPos
< aCurStr
.Len(); ++nPos
)
1865 if ( aCurStr
.GetChar(nPos
) == '\\' )
1866 aThisStr
.Insert( String( "..\\", osl_getThreadTextEncoding() ), 0 );
1868 // das ist dann unser relativer Pfad
1869 *this = DirEntry( aThisStr
, FSYS_STYLE_HPFS
);
1873 /*************************************************************************
1875 |* DirEntry::CutRelParents()
1878 |* Ersterstellung MI 01.08.95
1879 |* Letzte Aenderung MI 01.08.95
1881 *************************************************************************/
1883 USHORT
DirEntry::CutRelParents()
1885 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1887 // erstes '..' finden
1892 pPar
&& pPar
->eFlag
!= FSYS_FLAG_PARENT
;
1893 pPar
= pPar
->pParent
)
1897 USHORT nParCount
= 0;
1898 while ( pPar
&& pPar
->eFlag
== FSYS_FLAG_PARENT
)
1901 pPar
= pPar
->pParent
;
1906 DELETEZ(pDir
->pParent
);
1908 eFlag
= FSYS_FLAG_CURRENT
;
1913 /*************************************************************************
1915 |* DirEntry::ToRel()
1917 |* Beschreibung FSYS.SDW
1918 |* Ersterstellung MI 26.06.93
1919 |* Letzte Aenderung MI 17.06.93
1921 *************************************************************************/
1923 BOOL
DirEntry::ToRel()
1925 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1929 return ImpToRel( aCur
.GetFull( FSYS_STYLE_HPFS
) );
1932 /*************************************************************************
1934 |* DirEntry::ToRel()
1936 |* Beschreibung FSYS.SDW
1937 |* Ersterstellung MI 26.04.91
1938 |* Letzte Aenderung MA 02.12.91
1940 *************************************************************************/
1942 BOOL
DirEntry::ToRel( const DirEntry
& rStart
)
1944 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1946 DirEntry
aStart( rStart
);
1948 return ImpToRel( aStart
.GetFull( FSYS_STYLE_HPFS
) );
1951 /*************************************************************************
1953 |* DirEntry::GetDevice()
1955 |* Beschreibung FSYS.SDW
1956 |* Ersterstellung MI 26.04.91
1957 |* Letzte Aenderung MA 02.12.91
1959 *************************************************************************/
1963 DirEntry
DirEntry::GetDevice() const
1965 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1967 const DirEntry
*pTop
= ImpGetTopPtr();
1969 if ( ( pTop
->eFlag
== FSYS_FLAG_ABSROOT
|| pTop
->eFlag
== FSYS_FLAG_RELROOT
) &&
1971 return DirEntry( pTop
->aName
, FSYS_FLAG_VOLUME
, FSYS_STYLE_HOST
);
1973 return DirEntry( ByteString(), FSYS_FLAG_INVALID
, FSYS_STYLE_HOST
);
1978 /*************************************************************************
1980 |* DirEntry::SetBase()
1982 |* Beschreibung FSYS.SDW
1983 |* Ersterstellung MI 23.10.91
1984 |* Letzte Aenderung MA 02.12.91
1986 *************************************************************************/
1988 void DirEntry::SetBase( const String
& rBase
, char cSep
)
1990 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
1992 const char *p0
= ( aName
.GetBuffer() );
1993 const char *p1
= p0
+ aName
.Len() - 1;
1994 while ( p1
>= p0
&& *p1
!= cSep
)
1999 // es wurde ein cSep an der Position p1 gefunden
2000 aName
.Erase( 0, static_cast< xub_StrLen
>(p1
- p0
) );
2001 aName
.Insert( ByteString(rBase
, osl_getThreadTextEncoding()), 0 );
2004 aName
= ByteString(rBase
, osl_getThreadTextEncoding());
2007 /*************************************************************************
2009 |* DirEntry::GetSearchDelimiter()
2011 |* Beschreibung FSYS.SDW
2012 |* Ersterstellung MI 10.06.93
2013 |* Letzte Aenderung MI 10.06.93
2015 *************************************************************************/
2017 String
DirEntry::GetSearchDelimiter( FSysPathStyle eFormatter
)
2019 return String( ByteString(SEARCHDELIM( GetStyle( eFormatter
) ) ), osl_getThreadTextEncoding());
2022 /*************************************************************************
2024 |* DirEntry::GetMaxNameLen()
2026 |* Beschreibung Liefert die maximale Anzahl von Zeichen in
2027 |* einzelnen Namensteile. Bei FileSystmen mit
2028 |* fester Extension (FAT) zaehlt diese nicht mit.
2029 |* Bei unbekannten FileSytemen und FSYS_STYLE_URL
2030 |* wird USHRT_MAX zurueckgegeben.
2031 |* Ersterstellung MI 17.06.97
2032 |* Letzte Aenderung MI 17.06.97
2034 *************************************************************************/
2036 USHORT
DirEntry::GetMaxNameLen( FSysPathStyle eFormatter
)
2038 eFormatter
= GetStyle( eFormatter
);
2039 switch ( eFormatter
)
2041 case FSYS_STYLE_MAC
: return 31;
2043 case FSYS_STYLE_FAT
: return 8;
2045 case FSYS_STYLE_VFAT
:
2046 case FSYS_STYLE_NTFS
:
2047 case FSYS_STYLE_NWFS
:
2048 case FSYS_STYLE_HPFS
: return 255;
2051 case FSYS_STYLE_SYSV
: return 14;
2053 case FSYS_STYLE_BSD
: return 250;
2060 /*************************************************************************
2062 |* DirEntry::TempName()
2064 |* Beschreibung FSYS.SDW - Aha, wo?
2065 |* Ersterstellung VB 06.09.93 (im SWG)
2066 |* Letzte Aenderung MI 06.02.98
2068 *************************************************************************/
2069 namespace { struct TempNameBase_Impl
: public rtl::Static
< DirEntry
, TempNameBase_Impl
> {}; }
2071 const DirEntry
& DirEntry::SetTempNameBase( const String
&rBase
)
2073 DirEntry aTempDir
= DirEntry().TempName().GetPath();
2074 aTempDir
+= DirEntry( rBase
);
2076 ByteString
aName( aTempDir
.GetFull(), osl_getThreadTextEncoding());
2077 if ( access( aName
.GetBuffer(), W_OK
| X_OK
| R_OK
) )
2079 // Create the directory and only on success give all rights to
2080 // everyone. Use mkdir instead of DirEntry::MakeDir because
2081 // this returns TRUE even if directory already exists.
2083 if ( !mkdir( aName
.GetBuffer(), S_IRWXU
| S_IRWXG
| S_IRWXO
) )
2084 chmod( aName
.GetBuffer(), S_IRWXU
| S_IRWXG
| S_IRWXO
);
2086 // This will not create a directory but perhaps FileStat called
2087 // there modifies the DirEntry
2094 DirEntry
&rEntry
= TempNameBase_Impl::get();
2095 rEntry
= aTempDir
.TempName( FSYS_KIND_DIR
);
2099 DirEntry
DirEntry::TempName( DirEntryKind eKind
) const
2101 // ggf. Base-Temp-Dir verwenden (macht Remote keinen Sinn => vorher)
2102 const DirEntry
&rEntry
= TempNameBase_Impl::get();
2103 if ( !pParent
&& FSYS_FLAG_CURRENT
!= rEntry
.eFlag
&& FSYS_FLAG_ABSROOT
!= eFlag
)
2106 DirEntry
aFactory( rEntry
);
2107 aFactory
+= GetName();
2108 return aFactory
.TempName();
2111 ByteString aDirName
; // hiermit hatte MPW C++ Probleme - immmer noch??
2115 // dertermine Directory, Prefix and Extension
2119 const char *pWild
= strchr( aName
.GetBuffer(), '*' );
2121 pWild
= strchr( aName
.GetBuffer(), '?' );
2126 aDirName
= ByteString(pParent
->GetFull(), osl_getThreadTextEncoding());
2127 strncpy( pfx
, aName
.GetBuffer(), Min( (int)5, (int)(pWild
-aName
.GetBuffer()) ) );
2128 pfx
[ pWild
-aName
.GetBuffer() ] = 0;
2129 const char *pExt
= strchr( pWild
, '.' );
2132 strncpy( ext
, pExt
, 4 );
2136 strcpy( ext
, ".tmp" );
2140 aDirName
= ByteString(GetFull(), osl_getThreadTextEncoding());
2141 strcpy( pfx
, "sv" );
2142 strcpy( ext
, ".tmp" );
2144 dir
= aDirName
.GetBuffer();
2146 // wurde kein Dir angegeben, dann nehmen wir ein passendes TEMP-Verz.
2147 char sBuf
[_MAX_PATH
];
2148 if ( eFlag
== FSYS_FLAG_CURRENT
|| ( !pParent
&& pWild
) )
2149 dir
= TempDirImpl(sBuf
);
2151 // ab hier leicht modifizierter Code von VB
2152 DirEntry
aRet(FSYS_FLAG_INVALID
);
2154 // need to add ?\\? + prefix + number + pid + .ext + '\0'
2155 # define TMPNAME_SIZE ( 1 + 5 + 5 + 10 + 4 + 1 )
2156 ret_val
= new char[i
+ TMPNAME_SIZE
];
2159 strcpy(ret_val
,dir
);
2161 /* Make sure directory ends with a separator */
2162 #if defined(WNT) || defined(OS2)
2163 if ( i
>0 && ret_val
[i
-1] != '\\' && ret_val
[i
-1] != '/' &&
2164 ret_val
[i
-1] != ':')
2165 ret_val
[i
++] = '\\';
2167 if (i
>0 && ret_val
[i
-1] != '/')
2170 #error unknown operating system
2173 strncpy(ret_val
+ i
, pfx
, 5);
2174 ret_val
[i
+ 5] = '\0'; /* strncpy doesn't put a 0 if more */
2175 i
= strlen(ret_val
); /* than 'n' chars. */
2177 /* Prefix can have 5 chars, leaving 3 for numbers. 26 ** 3 == 17576
2178 * Welcome to the 21st century, we can have longer filenames now ;)
2179 * New format: pfx + "5 char milli/micro second res" + "current pid" + ".tmp"
2181 #if (defined MSC || defined __MINGW32__) && defined WNT
2182 /* Milliseconds !! */
2183 static unsigned long u
= GetTickCount();
2184 unsigned long mypid
= static_cast<unsigned long>(_getpid());
2186 /* Microseconds !! */
2187 static unsigned long u
= clock();
2188 unsigned long mypid
= static_cast<unsigned long>(getpid());
2190 for ( unsigned long nOld
= u
; ++u
!= nOld
; ) /* Hae??? */
2192 u
%= 100000; /* on *NIX repeats every 100ms, maybe less if CLOCKS_PER_SEC > 10^6 */
2193 snprintf(ret_val
+i
, TMPNAME_SIZE
, "%05lu%lu", u
, mypid
);
2195 strcat(ret_val
,ext
);
2197 if ( FSYS_KIND_FILE
== eKind
)
2199 SvFileStream
aStream( String( ret_val
, osl_getThreadTextEncoding()),
2200 STREAM_WRITE
|STREAM_SHARE_DENYALL
);
2201 if ( aStream
.IsOpen() )
2203 aStream
.Seek( STREAM_SEEK_TO_END
);
2204 if ( 0 == aStream
.Tell() )
2206 aRet
= DirEntry( String( ret_val
, osl_getThreadTextEncoding()));
2215 String
aRetVal(ret_val
, osl_getThreadTextEncoding());
2216 String
aRedirected (aRetVal
);
2218 FSysRedirector::DoRedirect( aRedirected
);
2220 if ( FSYS_KIND_DIR
== eKind
)
2222 if ( 0 == _mkdir( ByteString(aRedirected
.GetBuffer(), osl_getThreadTextEncoding()).GetBuffer() ) )
2224 aRet
= DirEntry( aRetVal
);
2230 #if defined(UNX) || defined(OS2)
2231 if( access( ByteString(aRedirected
, osl_getThreadTextEncoding()).GetBuffer(), F_OK
) )
2233 aRet
= DirEntry( aRetVal
);
2238 if ( stat( ByteString(aRedirected
, osl_getThreadTextEncoding()).GetBuffer(), &aStat
) )
2240 aRet
= DirEntry( aRetVal
);
2255 /*************************************************************************
2257 |* DirEntry::operator[]()
2259 |* Beschreibung FSYS.SDW
2260 |* Ersterstellung MI 03.03.92
2261 |* Letzte Aenderung MI 03.03.92
2263 *************************************************************************/
2265 const DirEntry
&DirEntry::operator[]( USHORT nParentLevel
) const
2267 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
2269 //TPF: maybe to be implemented (FastFSys)
2271 const DirEntry
*pRes
= this;
2272 while ( pRes
&& nParentLevel
-- )
2273 pRes
= pRes
->pParent
;
2278 /*************************************************************************
2280 |* DirEntry::ImpParseUnixName()
2282 |* Beschreibung FSYS.SDW
2283 |* Ersterstellung MI 26.04.91
2284 |* Letzte Aenderung MI 26.05.93
2286 *************************************************************************/
2288 FSysError
DirEntry::ImpParseUnixName( const ByteString
& rPfad
, FSysPathStyle eStyle
)
2290 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
2292 // die einzelnen Namen auf einen Stack packen
2293 DirEntryStack aStack
;
2294 ByteString
aPfad( rPfad
);
2297 // den Namen vor dem ersten "/" abspalten,
2298 // falls '/' am Anfang, ist der Name '/',
2299 // der Rest immer ohne die fuehrenden '/'.
2300 // den ersten '/' suchen
2303 nPos
< aPfad
.Len() && aPfad
.GetChar(nPos
) != '/';
2307 // ist der Name die Root des aktuellen Drives?
2308 if ( nPos
== 0 && aPfad
.Len() > 0 && ( aPfad
.GetChar(0) == '/' ) )
2310 // Root-Directory des aktuellen Drives
2311 aStack
.Push( new DirEntry( FSYS_FLAG_ABSROOT
) );
2315 // den Namen ohne Trenner abspalten
2316 aName
= aPfad
.Copy( 0, nPos
);
2318 // stellt der Name die aktuelle Directory dar?
2323 // stellt der Name das User-Dir dar?
2324 else if ( aName
== "~" )
2326 DirEntry
aHome( String( (const char *) getenv( "HOME" ), osl_getThreadTextEncoding()) );
2327 for ( USHORT n
= aHome
.Level(); n
; --n
)
2328 aStack
.Push( new DirEntry( aHome
[ (USHORT
) n
-1 ] ) );
2332 // stellt der Name die Parent-Directory dar?
2333 else if ( aName
== ".." )
2335 // ist nichts, ein Parent oder eine relative Root
2337 if ( ( aStack
.Count() == 0 ) ||
2338 ( aStack
.Top()->eFlag
== FSYS_FLAG_PARENT
) )
2339 // fuehrende Parents kommen auf den Stack
2340 aStack
.Push( new DirEntry( ByteString(), FSYS_FLAG_PARENT
, eStyle
) );
2342 // ist es eine absolute Root
2343 else if ( aStack
.Top()->eFlag
== FSYS_FLAG_ABSROOT
) {
2344 // die hat keine Parent-Directory
2345 return FSYS_ERR_NOTEXISTS
;
2348 // sonst hebt der Parent den TOS auf
2349 delete aStack
.Pop();
2353 DirEntry
*pNew
= NULL
;
2354 // normalen Entries kommen auf den Stack
2355 pNew
= new DirEntry( aName
, FSYS_FLAG_NORMAL
, eStyle
);
2356 if ( !pNew
->IsValid() )
2359 ErrCode eErr
= pNew
->GetError();
2363 aStack
.Push( pNew
);
2367 // den Restpfad bestimmen
2368 aPfad
.Erase( 0, nPos
+ 1 );
2369 while ( aPfad
.Len() && ( aPfad
.GetChar(0) == '/' ) )
2370 aPfad
.Erase( 0, 1 );
2372 while ( aPfad
.Len() );
2374 // Haupt-Entry (selbst) zuweisen
2375 if ( aStack
.Count() == 0 )
2377 eFlag
= FSYS_FLAG_CURRENT
;
2382 eFlag
= aStack
.Top()->eFlag
;
2383 aName
= aStack
.Top()->aName
;
2384 delete aStack
.Pop();
2387 // die Parent-Entries vom Stack holen
2388 DirEntry
** pTemp
= &pParent
;
2389 while ( aStack
.Count() )
2391 *pTemp
= aStack
.Pop();
2392 pTemp
= &( (*pTemp
)->pParent
);
2398 /*************************************************************************
2400 |* DirEntry::MakeShortName()
2403 |* Ersterstellung TLX
2404 |* Letzte Aenderung PB 21.08.97 (in CreateEntry_Impl())
2406 *************************************************************************/
2408 ErrCode
CreateEntry_Impl( const DirEntry
&rPath
, DirEntryKind eKind
)
2410 // versuchen, anzulegen (ausser bei FSYS_KIND_ALL)
2411 ErrCode eErr
= ERRCODE_NONE
;
2412 if ( FSYS_KIND_FILE
== eKind
)
2414 SvFileStream
aStream( rPath
.GetFull(), STREAM_STD_WRITE
);
2415 aStream
.WriteLine( "" );
2416 eErr
= aStream
.GetError();
2418 else if ( FSYS_KIND_ALL
!= eKind
)
2419 eErr
= rPath
.MakeDir() ? ERRCODE_NONE
: ERRCODE_IO_UNKNOWN
;
2422 if ( !rPath
.Exists() )
2423 eErr
= ERRCODE_IO_UNKNOWN
; // Doch was schiefgegangen ?
2425 // ggf. wieder l"oschen
2426 if ( FSYS_KIND_NONE
== eKind
)
2429 // Fehlercode zur?ckliefern
2433 BOOL
IsValidEntry_Impl( const DirEntry
&rPath
,
2434 const String
&rLongName
,
2439 // Parameter-Pr"uefung
2440 DBG_ASSERT( eKind
== FSYS_KIND_NONE
|| eKind
== FSYS_KIND_ALL
||
2441 eKind
== FSYS_KIND_FILE
|| eKind
== FSYS_KIND_DIR
,
2442 "invalid entry-kind" );
2444 // Alle von MSDOS erreichbaren FSYS_STYLES muessen den
2445 // MSDOS Filenamenanforderungen genuegen. Sonst wird probiert,
2446 // ob sich eine Datei des gewuenschten Names anlegen laesst.
2447 FSysPathStyle eStyle
= DirEntry::GetPathStyle( rPath
.GetDevice().GetName() );
2448 DirEntry
aPath(rPath
);
2449 DirEntry
aName(rLongName
, eStyle
);
2450 if ( !aName
.IsValid() || aName
.Level() != 1 )
2453 if ( 1 == aPath
.Level() )
2455 if ( eStyle
== FSYS_STYLE_FAT
|| eStyle
== FSYS_STYLE_NWFS
||
2456 eStyle
== FSYS_STYLE_UNKNOWN
)
2458 DirEntry
aDosEntry( rLongName
, FSYS_STYLE_FAT
);
2459 if ( !aDosEntry
.IsValid() )
2463 // Pfad-Trenner sind nicht erlaubt (bei ungek"urzten auch nicht FSYS_SHORTNAME_DELIMITER)
2464 char cDelim
= bUseDelim
== 2 ? FSYS_SHORTNAME_DELIMITER
: char(0);
2466 rLongName
.Search(DirEntry::GetAccessDelimiter()) != STRING_NOTFOUND
||
2467 (!bIsShortened
&& rLongName
.Search(cDelim
) != STRING_NOTFOUND
)
2473 // MI: Abfrage nach 'CON:' etc. wird jetzt in Exists() mitgemacht
2474 if ( aPath
.Exists() )
2477 return (ERRCODE_NONE
== CreateEntry_Impl( aPath
, eKind
));
2480 //-------------------------------------------------------------------------
2482 #define MAX_EXT_FAT 3
2483 #define MAX_LEN_FAT 8
2484 #define INVALID_CHARS_FAT "\\/\"':|^<>[]?* "
2486 #define MAX_EXT_MAC 16 // nur wegen sinnvoller Namensk"rzung
2487 #define MAX_LEN_MAC 31
2488 #define INVALID_CHARS_MAC "\":"
2490 #define MAX_EXT_MAX 250
2491 #define MAX_LEN_MAX 255
2492 #define INVALID_CHARS_DEF "\\/\"':|^<>?*"
2494 BOOL
DirEntry::MakeShortName( const String
& rLongName
, DirEntryKind eKind
,
2495 BOOL bUseDelim
, FSysPathStyle eStyle
)
2497 String
aLongName(rLongName
);
2499 // Alle '#' aus den Dateinamen entfernen, weil das INetURLObject
2500 // damit Probleme hat. Siehe auch #51246#
2501 aLongName
.EraseAllChars( '#' );
2502 ByteString
bLongName(aLongName
, osl_getThreadTextEncoding());
2504 // Auf Novell-Servern (wegen der rottigen Clients) nur 7bit ASCII
2506 // HRO: #69627# Weg mit dem Scheiss. Wenn es Client gibt, die so einen
2507 // BUG haben, dann muss halt der Client ersetzt werden, aber doch nicht das
2508 // Office kastrieren !!!
2511 if ( FSYS_STYLE_NWFS
== GetPathStyle( ImpGetTopPtr()->GetName() ) )
2513 for ( USHORT n
= aLongName
.Len(); n
; --n
)
2515 short nChar
= aLongName(n
-1);
2516 if ( nChar
< 32 || nChar
>= 127 )
2517 aLongName
.Erase( n
-1, 1 );
2522 // bei FSYS_KIND_ALL den alten Namen merken und abh"angen (rename)
2523 ByteString aOldName
;
2524 if ( FSYS_KIND_ALL
== eKind
)
2526 aOldName
= ByteString(CutName(), osl_getThreadTextEncoding());
2527 aOldName
= CMP_LOWER(aOldName
);
2530 // ist der Langname direkt verwendbar?
2531 if ( IsValidEntry_Impl( *this, aLongName
, eKind
, FALSE
, bUseDelim
) )
2533 operator+=( DirEntry(aLongName
) );
2537 // max L"angen feststellen
2538 USHORT nMaxExt
, nMaxLen
;
2539 if ( FSYS_STYLE_DETECT
== eStyle
)
2540 eStyle
= DirEntry::GetPathStyle( GetDevice().GetName() );
2541 ByteString aInvalidChars
;
2544 case FSYS_STYLE_FAT
:
2545 nMaxExt
= MAX_EXT_FAT
;
2546 nMaxLen
= MAX_LEN_FAT
;
2547 aInvalidChars
= INVALID_CHARS_FAT
;
2550 case FSYS_STYLE_MAC
:
2551 nMaxExt
= MAX_EXT_MAC
;
2552 nMaxLen
= MAX_LEN_MAC
;
2553 aInvalidChars
= INVALID_CHARS_MAC
;
2557 nMaxExt
= MAX_EXT_MAX
;
2558 nMaxLen
= MAX_LEN_MAX
;
2559 aInvalidChars
= INVALID_CHARS_DEF
;
2562 // Extension abschneiden und kuerzen
2564 ByteString aFName
= bLongName
;
2565 if ( FSYS_STYLE_MAC
!= eStyle
)
2568 aUnparsed
.aName
= bLongName
;
2569 aExt
= ByteString(aUnparsed
.CutExtension(), osl_getThreadTextEncoding());
2570 aFName
= aUnparsed
.aName
;
2571 if ( aExt
.Len() > nMaxExt
)
2573 char c
= aExt
.GetChar( aExt
.Len() - 1 );
2574 aExt
.Erase(nMaxExt
-1);
2579 if ( FSYS_STYLE_FAT
!= eStyle
)
2581 // ausser auf einem FAT-System geh"ort die Extension zur
2582 // Maxl"ange. Muss also vorher mit dem Punkt abgezogen werden.
2583 nMaxLen
-= ( aExt
.Len() + 1 );
2588 for ( const char *pc
= aFName
.GetBuffer(); aSName
.Len() < nMaxLen
&& *pc
; ++pc
)
2590 if ( STRING_NOTFOUND
== aInvalidChars
.Search( *pc
) &&
2591 (unsigned char) *pc
>= (unsigned char) 32 &&
2592 ( !aSName
.Len() || *pc
!= ' ' || aSName
.GetChar(aSName
.Len()-1) != ' ' ) )
2595 aSName
.EraseTrailingChars();
2597 // HRO: #74246# Also cut leading spaces
2598 aSName
.EraseLeadingChars();
2600 if ( !aSName
.Len() )
2603 // kommt dabei der alte Name raus?
2604 ByteString aNewName
= aSName
;
2606 ( aNewName
+= '.' ) += aExt
;
2607 operator+=( DirEntry(String(aNewName
, osl_getThreadTextEncoding())) );
2608 if ( FSYS_KIND_ALL
== eKind
&& CMP_LOWER(aName
) == aOldName
)
2609 if ( FSYS_KIND_ALL
== eKind
&& CMP_LOWER(ByteString(GetName(), osl_getThreadTextEncoding())) == aOldName
)
2612 // kann der gek"urzte Name direkt verwendet werden?
2613 if ( !Exists() && (ERRCODE_NONE
== CreateEntry_Impl( *this, eKind
)) )
2616 // darf '?##' verwendet werden, um eindeutigen Name zu erzeugen?
2619 // eindeutigen Namen per '?##' erzeugen
2620 aSName
.Erase( nMaxLen
-3 );
2621 if ( bUseDelim
!= 2 )
2622 aSName
+= FSYS_SHORTNAME_DELIMITER
;
2623 for ( int n
= 1; n
< 99; ++n
)
2625 // Name zusammensetzen
2626 ByteString
aTmpStr( aSName
);
2627 aTmpStr
+= ByteString::CreateFromInt32(n
);
2629 ( aTmpStr
+= '.' ) += aExt
;
2631 // noch nicht vorhanden?
2632 SetName( String(aTmpStr
, osl_getThreadTextEncoding()) );
2636 // Fehler setzen !!!
2637 nError
= CreateEntry_Impl( *this, eKind
);
2638 return (ERRCODE_NONE
== nError
);
2643 // keine ## mehr frei / ?## soll nicht verwendet werden
2644 nError
= ERRCODE_IO_ALREADYEXISTS
;
2648 /*************************************************************************
2650 |* DirEntry::CreatePath()
2652 |* Beschreibung FSYS.SDW
2653 |* Ersterstellung MI 26.04.91
2654 |* Letzte Aenderung MA 02.12.91
2656 *************************************************************************/
2658 BOOL
DirEntry::MakeDir( BOOL bSloppy
) const
2660 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
2662 // Schnellpruefung, ob vorhanden
2663 if ( FileStat( *this ).IsKind( FSYS_KIND_DIR
) )
2665 if ( bSloppy
&& pParent
)
2666 if ( FileStat( *pParent
).IsKind( FSYS_KIND_DIR
) )
2669 const DirEntry
*pNewDir
= bSloppy
? pParent
: this;
2672 // den Path zum Dir erzeugen
2673 if ( pNewDir
->pParent
&& !pNewDir
->pParent
->MakeDir(FALSE
) )
2676 // das Dir selbst erzeugen
2677 if ( pNewDir
->eFlag
== FSYS_FLAG_ABSROOT
||
2678 pNewDir
->eFlag
== FSYS_FLAG_ABSROOT
||
2679 pNewDir
->eFlag
== FSYS_FLAG_VOLUME
)
2684 if ( FileStat( *pNewDir
).IsKind( FSYS_KIND_DIR
) )
2688 FSysFailOnErrorImpl();
2689 String
aDirName(pNewDir
->GetFull());
2691 FSysRedirector::DoRedirect( aDirName
);
2693 ByteString
bDirName( aDirName
, osl_getThreadTextEncoding() );
2694 bDirName
= GUI2FSYS( bDirName
);
2699 BOOL bResult
= (0 == _mkdir( (char*) bDirName
.GetBuffer() ));
2702 // Wer hat diese Methode const gemacht ?
2704 ((DirEntry
*)this)->SetError( Sys2SolarError_Impl( GetLastError() ) );
2706 ((DirEntry
*)this)->SetError( Sys2SolarError_Impl( errno
) );
2717 /*************************************************************************
2719 |* DirEntry::CopyTo()
2721 |* Beschreibung FSYS.SDW
2722 |* Ersterstellung MI 26.04.91
2723 |* Letzte Aenderung MI 07.08.96
2725 *************************************************************************/
2727 FSysError
DirEntry::CopyTo( const DirEntry
& rDest
, FSysAction nActions
) const
2729 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
2731 if ( FSYS_ACTION_COPYFILE
!= (nActions
& FSYS_ACTION_COPYFILE
) )
2735 HACK(redirection missing
)
2736 ByteString
aThis(GUI2FSYS(GetFull()), osl_getThreadTextEncoding());
2737 ByteString
aDest(GUI2FSYS(rDest
.GetFull()), osl_getThreadTextEncoding());
2738 if (link( aThis
.GetBuffer(), aDest
.GetBuffer() ) == -1)
2739 return Sys2SolarError_Impl( errno
);
2744 return FSYS_ERR_NOTSUPPORTED
;
2747 FileCopier
fc(*this, rDest
);
2748 return fc
.Execute(nActions
);
2751 /*************************************************************************
2753 |* DirEntry::MoveTo()
2755 |* Beschreibung FSYS.SDW
2756 |* Ersterstellung MI 26.04.91
2757 |* Letzte Aenderung HRO 24.03.99
2759 *************************************************************************/
2761 #if defined WNT || defined UNX || defined OS2
2763 FSysError
DirEntry::MoveTo( const DirEntry
& rNewName
) const
2765 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
2768 FileStat aSourceStat(*this);
2769 if ( !aSourceStat.IsKind(FSYS_KIND_FILE) )
2770 return FSYS_ERR_NOTAFILE;
2773 DirEntry
aDest(rNewName
);
2774 FileStat
aDestStat(rNewName
);
2775 if ( aDestStat
.IsKind(FSYS_KIND_DIR
) )
2777 aDest
+= String(aName
, osl_getThreadTextEncoding());
2779 if ( aDest
.Exists() )
2781 return FSYS_ERR_ALREADYEXISTS
;
2785 if ( FileStat(*this).IsKind(FSYS_KIND_DIR
) && aDest
.GetPath() != GetPath() )
2787 return FSYS_ERR_NOTSUPPORTED
;
2791 FSysFailOnErrorImpl();
2792 String
aFrom( GetFull() );
2795 FSysRedirector::DoRedirect(aFrom
);
2798 String
aTo( aDest
.GetFull() );
2801 FSysRedirector::DoRedirect(aTo
);
2804 ByteString
bFrom(aFrom
, osl_getThreadTextEncoding());
2805 ByteString
bTo(aTo
, osl_getThreadTextEncoding());
2806 bFrom
= GUI2FSYS(bFrom
);
2807 bTo
= GUI2FSYS(bTo
);
2810 // MoveTo nun atomar
2813 DirEntry
aFromDevice(String(bFrom
, osl_getThreadTextEncoding()));
2814 DirEntry
aToDevice(String(bTo
,osl_getThreadTextEncoding()));
2815 aFromDevice
.ToAbs();
2817 aFromDevice
=aFromDevice
.GetDevice();
2818 aToDevice
=aToDevice
.GetDevice();
2820 //Quelle und Ziel auf gleichem device?
2821 if (aFromDevice
==aToDevice
)
2823 // ja, also intra-device-move mit MoveFile
2824 MoveFile( bFrom
.GetBuffer(), bTo
.GetBuffer() );
2825 // MoveFile ist buggy bei cross-device operationen.
2826 // Der R?ckgabewert ist auch dann TRUE, wenn nur ein Teil der Operation geklappt hat.
2827 // Zudem zeigt MoveFile unterschiedliches Verhalten bei unterschiedlichen NT-Versionen.
2828 return Sys2SolarError_Impl( GetLastError() );
2832 //nein, also inter-device-move mit copy/delete
2833 FSysError nCopyError
= CopyTo(rNewName
, FSYS_ACTION_COPYFILE
);
2835 DirEntry
aKill(String(bTo
, osl_getThreadTextEncoding()));
2836 FileStat
aKillStat(String(bTo
, osl_getThreadTextEncoding()));
2837 if ( aKillStat
.IsKind(FSYS_KIND_DIR
) )
2839 aKill
+= String(aName
, osl_getThreadTextEncoding());
2842 if (nCopyError
==FSYS_ERR_OK
)
2844 if (Kill()==FSYS_ERR_OK
)
2851 return FSYS_ERR_ACCESSDENIED
;
2862 // on some nfs connections rename with from == to
2863 // leads to destruction of file
2864 if ( ( aFrom
!= aTo
) && ( 0 != rename( bFrom
.GetBuffer(), bTo
.GetBuffer() ) ) )
2865 #if !defined(UNX) && !defined(OS2)
2866 return Sys2SolarError_Impl( GetLastError() );
2869 if( errno
== EXDEV
)
2870 // cross device geht latuernich nicht mit rename
2872 FILE *fpIN
= fopen( bFrom
.GetBuffer(), "r" );
2873 FILE *fpOUT
= fopen( bTo
.GetBuffer(), "w" );
2877 int nBytes
, nWritten
, nErr
= 0;
2879 while( ( nBytes
= fread( pBuf
, 1, sizeof(pBuf
), fpIN
) ) && ! nErr
)
2881 nWritten
= fwrite( pBuf
, 1, nBytes
, fpOUT
);
2882 // Fehler im fwrite ?
2883 if( nWritten
< nBytes
)
2893 unlink( bTo
.GetBuffer() );
2894 return Sys2SolarError_Impl( nErr
);
2898 unlink( bFrom
.GetBuffer() );
2903 return Sys2SolarError_Impl( EXDEV
);
2908 return Sys2SolarError_Impl( errno
);
2913 return ERRCODE_NONE
;
2918 /*************************************************************************
2922 |* Beschreibung FSYS.SDW
2923 |* Ersterstellung MI 26.04.91
2924 |* Letzte Aenderung MI 07.08.96
2926 *************************************************************************/
2928 FSysError
DirEntry::Kill( FSysAction nActions
) const
2930 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
2932 FSysError eError
= FSYS_ERR_OK
;
2933 FSysFailOnErrorImpl();
2935 // Name als doppelt 0-terminierter String
2936 String
aTmpName( GetFull() );
2938 FSysRedirector::DoRedirect( aTmpName
);
2940 ByteString
bTmpName( aTmpName
, osl_getThreadTextEncoding());
2941 bTmpName
= GUI2FSYS(bTmpName
);
2943 char *pName
= new char[bTmpName
.Len()+2];
2944 strcpy( pName
, bTmpName
.GetBuffer() );
2945 pName
[bTmpName
.Len()+1] = (char) 0;
2947 //read-only files sollen auch geloescht werden koennen
2948 BOOL isReadOnly
= FileStat::GetReadOnlyFlag(*this);
2951 FileStat::SetReadOnlyFlag(*this, FALSE
);
2955 if ( FileStat( *this ).IsKind(FSYS_KIND_DIR
) )
2957 // Inhalte recursiv loeschen?
2958 if ( FSYS_ACTION_RECURSIVE
== (nActions
& FSYS_ACTION_RECURSIVE
) )
2960 Dir
aDir( *this, FSYS_KIND_DIR
|FSYS_KIND_FILE
);
2961 for ( USHORT n
= 0; eError
== FSYS_ERR_OK
&& n
< aDir
.Count(); ++n
)
2963 const DirEntry
&rSubDir
= aDir
[n
];
2964 DirEntryFlag flag
= rSubDir
.GetFlag();
2965 if ( flag
!= FSYS_FLAG_CURRENT
&& flag
!= FSYS_FLAG_PARENT
)
2966 eError
= rSubDir
.Kill(nActions
);
2970 // das Dir selbst loeschen
2974 if ( eError
== FSYS_ERR_OK
&& 0 != _rmdir( (char*) pName
) )
2977 // falls L"oschen nicht ging, CWD umsetzen
2979 eError
= Sys2SolarError_Impl( GetLastError() );
2981 eError
= Sys2SolarError_Impl( errno
);
2989 if (_rmdir( (char*) pName
) != 0)
2992 eError
= Sys2SolarError_Impl( GetLastError() );
2994 eError
= Sys2SolarError_Impl( errno
);
2999 eError
= FSYS_ERR_OK
;
3006 if ( FSYS_ACTION_USERECYCLEBIN
== (nActions
& FSYS_ACTION_USERECYCLEBIN
) )
3009 eError
= ApiRet2ToSolarError_Impl( DosDelete( (PSZ
) pName
) );
3013 aOp
.wFunc
= FO_DELETE
;
3016 aOp
.fFlags
= FOF_ALLOWUNDO
|FOF_SILENT
|FOF_NOCONFIRMATION
;
3017 aOp
.hNameMappings
= 0;
3018 aOp
.lpszProgressTitle
= 0;
3019 eError
= Sys2SolarError_Impl( SHFileOperation( &aOp
) );
3021 eError
= ERRCODE_IO_NOTSUPPORTED
;
3029 if ( 0 != _unlink( (char*) pName
) )
3032 eError
= Sys2SolarError_Impl( GetLastError() );
3034 eError
= Sys2SolarError_Impl( errno
);
3039 eError
= ERRCODE_NONE
;
3044 //falls Fehler, originales read-only flag wieder herstellen
3045 if ( isReadOnly
&& (eError
!=ERRCODE_NONE
) )
3047 FileStat::SetReadOnlyFlag(*this, isReadOnly
);
3054 /*************************************************************************
3056 |* DirEntry::Contains()
3058 |* Beschreibung ob rSubEntry direkt oder indirect in *this liegt
3059 |* Ersterstellung MI 20.03.97
3060 |* Letzte Aenderung MI 20.03.97
3062 *************************************************************************/
3064 BOOL
DirEntry::Contains( const DirEntry
&rSubEntry
) const
3066 DBG_ASSERT( IsAbs() && rSubEntry
.IsAbs(), "must be absolute entries" );
3068 USHORT nThisLevel
= Level();
3069 USHORT nSubLevel
= rSubEntry
.Level();
3070 if ( nThisLevel
< nSubLevel
)
3072 for ( ; nThisLevel
; --nThisLevel
, --nSubLevel
)
3073 if ( (*this)[nThisLevel
-1] != rSubEntry
[nSubLevel
-1] )
3080 /*************************************************************************
3082 |* DirEntry::Level()
3084 |* Beschreibung FSYS.SDW
3085 |* Ersterstellung MI 03.03.92
3086 |* Letzte Aenderung MI 03.03.92
3088 *************************************************************************/
3090 USHORT
DirEntry::Level() const
3092 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
3095 const DirEntry
*pRes
= this;
3098 pRes
= pRes
->pParent
;
3105 /*************************************************************************
3107 |* DirEntry::ConvertNameToSystem()
3110 |* Ersterstellung DV 29.03.96
3111 |* Letzte Aenderung DV 29.03.96
3113 *************************************************************************/
3115 String
DirEntry::ConvertNameToSystem( const String
&rName
)
3120 /*************************************************************************
3122 |* DirEntry::ConvertSystemToName()
3125 |* Ersterstellung DV 29.03.96
3126 |* Letzte Aenderung DV 29.03.96
3128 *************************************************************************/
3130 String
DirEntry::ConvertSystemToName( const String
&rName
)
3135 /*************************************************************************
3137 |* DirEntry::IsValid()
3140 |* Ersterstellung MI 18.09.93
3141 |* Letzte Aenderung TPF 18.09.98
3143 *************************************************************************/
3145 BOOL
DirEntry::IsValid() const
3147 return (nError
== FSYS_ERR_OK
);
3150 /*************************************************************************
3152 |* DirEntry::IsRFSAvailable()
3155 |* Ersterstellung TPF 21.10.98
3156 |* Letzte Aenderung TPF 21.10.98
3158 *************************************************************************/
3160 BOOL
DirEntry::IsRFSAvailable()
3165 /*************************************************************************
3167 |* IsLongNameOnFAT()
3169 |* Beschreibung ?berpr?ft , ob das DirEntry einen langen
3170 |* Filenamen auf einer FAT-Partition enth?lt (EAs).
3171 |* (eigentlich nur f?r OS2 interessant)
3172 |* Ersterstellung TPF 02.10.98
3173 |* Letzte Aenderung TPF 01.03.1999
3175 *************************************************************************/
3177 BOOL
DirEntry::IsLongNameOnFAT() const
3180 DirEntry
aTempDirEntry(*this);
3181 aTempDirEntry
.ToAbs();
3182 if (DirEntry::GetPathStyle(aTempDirEntry
.GetDevice().GetName().GetChar(0)) != FSYS_STYLE_FAT
)
3184 return FALSE
; // nein, also false
3187 // DirEntry-Kette auf lange Dateinamen pr?fen
3188 for( USHORT iLevel
= this->Level(); iLevel
> 0; iLevel
-- )
3190 const DirEntry
& rEntry
= (const DirEntry
&) (*this)[iLevel
-1];
3191 String
aBase( rEntry
.GetBase() );
3192 String
aExtension( rEntry
.GetExtension() );
3194 if (aBase
.Len()>8) // Name > 8?
3199 if (aExtension
.Len()>3) // Extension > 3?
3207 //========================================================================
3209 #if defined(DBG_UTIL)