LCOV - code coverage report
Current view: top level - tools/source/fsys - dirent.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 290 587 49.4 %
Date: 2012-08-25 Functions: 33 47 70.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 309 1184 26.1 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       5                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       6                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : #if !defined UNX
      21                 :            : #ifdef WNT
      22                 :            : #include <windows.h>
      23                 :            : #undef GetObject
      24                 :            : #endif
      25                 :            : #include <io.h>
      26                 :            : #include <process.h>
      27                 :            : #endif
      28                 :            : 
      29                 :            : #if defined(UNX)
      30                 :            : #include <unistd.h>
      31                 :            : #include <sys/types.h>
      32                 :            : #include <sys/stat.h>
      33                 :            : #endif
      34                 :            : 
      35                 :            : #include <ctype.h>
      36                 :            : #include <errno.h>
      37                 :            : #include <stdlib.h>
      38                 :            : #include <stdio.h>
      39                 :            : #include <string.h>
      40                 :            : #include <tools/debug.hxx>
      41                 :            : #include "comdep.hxx"
      42                 :            : #include <tools/fsys.hxx>
      43                 :            : #define _TOOLS_HXX
      44                 :            : #include <tools/urlobj.hxx>
      45                 :            : #include <vector>
      46                 :            : 
      47                 :            : #ifdef UNX
      48                 :            : #define _MAX_PATH 260
      49                 :            : #endif
      50                 :            : 
      51                 :            : #include <tools/stream.hxx>
      52                 :            : #include <osl/mutex.hxx>
      53                 :            : #include <osl/file.hxx>
      54                 :            : #include <rtl/instance.hxx>
      55                 :            : #include <comphelper/string.hxx>
      56                 :            : 
      57                 :            : using namespace osl;
      58                 :            : using ::rtl::OUString;
      59                 :            : 
      60                 :            : int ApiRet2ToSolarError_Impl( int nApiRet );
      61                 :            : 
      62                 :          0 : int Sys2SolarError_Impl( int nSysErr )
      63                 :            : {
      64   [ #  #  #  #  :          0 :     switch ( nSysErr )
             #  #  #  #  
                      # ]
      65                 :            :     {
      66                 :            : #ifdef WNT
      67                 :            :         case NO_ERROR:                  return ERRCODE_NONE;
      68                 :            :         case ERROR_INVALID_FUNCTION:    return ERRCODE_IO_GENERAL;
      69                 :            :         case ERROR_FILE_NOT_FOUND:      return ERRCODE_IO_NOTEXISTS;
      70                 :            :         case ERROR_PATH_NOT_FOUND:      return ERRCODE_IO_NOTEXISTSPATH;
      71                 :            :         case ERROR_TOO_MANY_OPEN_FILES: return ERRCODE_IO_TOOMANYOPENFILES;
      72                 :            :         case ERROR_ACCESS_DENIED:       return ERRCODE_IO_ACCESSDENIED;
      73                 :            :         case ERROR_INVALID_HANDLE:      return ERRCODE_IO_GENERAL;
      74                 :            :         case ERROR_NOT_ENOUGH_MEMORY:   return ERRCODE_IO_OUTOFMEMORY;
      75                 :            :         case ERROR_INVALID_BLOCK:       return ERRCODE_IO_GENERAL;
      76                 :            :         case ERROR_BAD_FORMAT:          return ERRCODE_IO_WRONGFORMAT;
      77                 :            :         case ERROR_INVALID_ACCESS:      return ERRCODE_IO_ACCESSDENIED;
      78                 :            :         case ERROR_INVALID_DRIVE:       return ERRCODE_IO_INVALIDDEVICE;
      79                 :            :         case ERROR_CURRENT_DIRECTORY:   return ERRCODE_IO_CURRENTDIR;
      80                 :            :         case ERROR_NOT_SAME_DEVICE:     return ERRCODE_IO_NOTSAMEDEVICE;
      81                 :            :         case ERROR_WRITE_PROTECT:       return ERRCODE_IO_CANTWRITE;
      82                 :            :         case ERROR_BAD_UNIT:            return ERRCODE_IO_INVALIDDEVICE;
      83                 :            :         case ERROR_NOT_READY:           return ERRCODE_IO_DEVICENOTREADY;
      84                 :            :         case ERROR_BAD_COMMAND:         return ERRCODE_IO_GENERAL;
      85                 :            :         case ERROR_CRC:                 return ERRCODE_IO_BADCRC;
      86                 :            :         case ERROR_BAD_LENGTH:          return ERRCODE_IO_INVALIDLENGTH;
      87                 :            :         case ERROR_SEEK:                return ERRCODE_IO_CANTSEEK;
      88                 :            :         case ERROR_NOT_DOS_DISK:        return ERRCODE_IO_WRONGFORMAT;
      89                 :            :         case ERROR_SECTOR_NOT_FOUND:    return ERRCODE_IO_GENERAL;
      90                 :            :         case ERROR_WRITE_FAULT:         return ERRCODE_IO_CANTWRITE;
      91                 :            :         case ERROR_READ_FAULT:          return ERRCODE_IO_CANTREAD;
      92                 :            :         case ERROR_GEN_FAILURE:         return ERRCODE_IO_GENERAL;
      93                 :            :         case ERROR_SHARING_VIOLATION:   return ERRCODE_IO_LOCKVIOLATION;
      94                 :            :         case ERROR_LOCK_VIOLATION:      return ERRCODE_IO_LOCKVIOLATION;
      95                 :            :         case ERROR_WRONG_DISK:          return ERRCODE_IO_INVALIDDEVICE;
      96                 :            :         case ERROR_NOT_SUPPORTED:       return ERRCODE_IO_NOTSUPPORTED;
      97                 :            : #else
      98                 :          0 :         case 0:         return ERRCODE_NONE;
      99                 :          0 :         case ENOENT:    return ERRCODE_IO_NOTEXISTS;
     100                 :          0 :         case EACCES:    return ERRCODE_IO_ACCESSDENIED;
     101                 :          0 :         case EEXIST:    return ERRCODE_IO_ALREADYEXISTS;
     102                 :          0 :         case EINVAL:    return ERRCODE_IO_INVALIDPARAMETER;
     103                 :          0 :         case EMFILE:    return ERRCODE_IO_TOOMANYOPENFILES;
     104                 :          0 :         case ENOMEM:    return ERRCODE_IO_OUTOFMEMORY;
     105                 :          0 :         case ENOSPC:    return ERRCODE_IO_OUTOFSPACE;
     106                 :            : #endif
     107                 :            :     }
     108                 :            : 
     109                 :            :     OSL_TRACE( "FSys: unknown system error %d occurred", nSysErr );
     110                 :          0 :     return FSYS_ERR_UNKNOWN;
     111                 :            : }
     112                 :            : 
     113                 :            : class DirEntryStack
     114                 :            : {
     115                 :            : private:
     116                 :            :     ::std::vector< DirEntry* >  maStack;
     117                 :            : 
     118                 :            : public:
     119                 :      35542 :                         DirEntryStack() {};
     120                 :            :                         ~DirEntryStack();
     121                 :            : 
     122                 :            :     inline  void        Push( DirEntry *pEntry );
     123                 :            :     inline  DirEntry*   Pop();
     124                 :            :     inline  DirEntry*   Top();
     125                 :            :     inline  DirEntry*   Bottom();
     126                 :            :     inline  bool        Empty();
     127                 :            :     inline  void        Clear();
     128                 :            : };
     129                 :            : 
     130                 :     234079 : inline void DirEntryStack::Push( DirEntry *pEntry )
     131                 :            : {
     132                 :     234079 :     maStack.push_back( pEntry );
     133                 :     234079 : }
     134                 :            : 
     135                 :     234079 : inline DirEntry* DirEntryStack::Pop()
     136                 :            : {
     137                 :     234079 :     DirEntry*   pEntry = NULL;
     138         [ +  - ]:     234079 :     if ( !maStack.empty() ) {
     139                 :     234079 :         pEntry = maStack.back();
     140                 :     234079 :         maStack.pop_back();
     141                 :            :     }
     142                 :     234079 :     return pEntry;
     143                 :            : }
     144                 :            : 
     145                 :      71084 : inline DirEntry* DirEntryStack::Top()
     146                 :            : {
     147         [ -  + ]:      71084 :     return maStack.empty() ? NULL : maStack.back();
     148                 :            : }
     149                 :            : 
     150                 :            : inline DirEntry* DirEntryStack::Bottom()
     151                 :            : {
     152                 :            :     return maStack.empty() ? NULL : maStack.front();
     153                 :            : }
     154                 :            : 
     155                 :     269621 : inline bool DirEntryStack::Empty()
     156                 :            : {
     157                 :     269621 :     return maStack.empty();
     158                 :            : }
     159                 :            : 
     160                 :            : inline void DirEntryStack::Clear()
     161                 :            : {
     162                 :            :     maStack.clear();
     163                 :            : }
     164                 :            : 
     165                 :            : DBG_NAME( DirEntry );
     166                 :            : 
     167                 :      35542 : DirEntryStack::~DirEntryStack()
     168                 :            : {
     169                 :      35542 :     maStack.clear();
     170                 :      35542 : }
     171                 :            : 
     172                 :            : #ifdef DBG_UTIL
     173                 :            : /** Check DirEntry for DBG_UTIL
     174                 :            : 
     175                 :            :     @param p Pointer to DirEntry
     176                 :            :     @return char* Error-TExtension or NULL
     177                 :            : */
     178                 :            : const char* ImpCheckDirEntry( const void* p )
     179                 :            : {
     180                 :            :     DirEntry* p0 = (DirEntry*)p;
     181                 :            : 
     182                 :            :     if ( p0->pParent )
     183                 :            :         DBG_CHKOBJ( p0->pParent, DirEntry, ImpCheckDirEntry );
     184                 :            : 
     185                 :            :     return NULL;
     186                 :            : }
     187                 :            : #endif
     188                 :            : 
     189                 :            : /** Insert "..." for max length of nMaxChars */
     190                 :          0 : rtl::OString ImplCutPath( const rtl::OString& rStr, sal_Int32 nMax, char cAccDel )
     191                 :            : {
     192                 :          0 :     sal_Int32 nMaxPathLen = nMax;
     193                 :          0 :     sal_Bool bInsertPrefix = sal_False;
     194                 :          0 :     sal_Int32 nBegin = rStr.indexOf(cAccDel);
     195         [ #  # ]:          0 :     rtl::OStringBuffer aCutPath(rStr);
     196                 :            : 
     197         [ #  # ]:          0 :     if( nBegin == -1 )
     198                 :          0 :         nBegin = 0;
     199                 :            :     else
     200                 :          0 :         nMaxPathLen += 2;   // Prefix <Disk>:
     201                 :            : 
     202         [ #  # ]:          0 :     while( aCutPath.getLength() > nMaxPathLen )
     203                 :            :     {
     204                 :          0 :         sal_Int32 nEnd = aCutPath.toString().indexOf(cAccDel, nBegin + 1);
     205                 :            :         sal_Int32 nCount;
     206                 :            : 
     207         [ #  # ]:          0 :         if ( nEnd != -1 )
     208                 :            :         {
     209                 :          0 :             nCount = nEnd - nBegin;
     210         [ #  # ]:          0 :             aCutPath.remove(nBegin, nCount);
     211                 :          0 :             bInsertPrefix = sal_True;
     212                 :            :         }
     213                 :            :         else
     214                 :          0 :             break;
     215                 :            :     }
     216                 :            : 
     217         [ #  # ]:          0 :     if ( aCutPath.getLength() > nMaxPathLen )
     218                 :            :     {
     219         [ #  # ]:          0 :         for ( sal_Int32 n = nMaxPathLen; n > nMaxPathLen/2; --n )
     220                 :            :         {
     221 [ #  # ][ #  # ]:          0 :             if (!comphelper::string::isalnumAscii(aCutPath[n]))
     222                 :            :             {
     223         [ #  # ]:          0 :                 comphelper::string::truncateToLength(aCutPath, n);
     224         [ #  # ]:          0 :                 aCutPath.append(RTL_CONSTASCII_STRINGPARAM("..."));
     225                 :          0 :                 break;
     226                 :            :             }
     227                 :            :         }
     228                 :            :     }
     229                 :            : 
     230         [ #  # ]:          0 :     if ( bInsertPrefix )
     231                 :            :     {
     232                 :          0 :         rtl::OStringBuffer aIns;
     233 [ #  # ][ #  # ]:          0 :         aIns.append(cAccDel).append(RTL_CONSTASCII_STRINGPARAM("..."));
     234         [ #  # ]:          0 :         aCutPath.insert(nBegin, aIns.makeStringAndClear());
     235                 :            :     }
     236                 :            : 
     237                 :          0 :     return aCutPath.makeStringAndClear();
     238                 :            : }
     239                 :            : 
     240                 :      35542 : FSysError DirEntry::ImpParseName( const rtl::OString& rPfad )
     241                 :            : {
     242                 :            : #if defined(WNT)
     243                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
     244                 :            : 
     245                 :            :     // put single names onto stack
     246                 :            :     String aPfad(rtl::OStringToOUString(rPfad, osl_getThreadTextEncoding()));
     247                 :            :     DirEntryStack   aStack;
     248                 :            : 
     249                 :            :     do
     250                 :            :     {
     251                 :            :         // split name before first "\\",
     252                 :            :         // if '\\' is at beginning of string, name is set to '\\'.
     253                 :            :         // ":" also splits the string and belongs to the name.
     254                 :            : 
     255                 :            :         // search first occurance of '\\', '/' or ':'
     256                 :            :         sal_uInt16 nPos;
     257                 :            :         for ( nPos = 0;
     258                 :            :               nPos < aPfad.Len() &&                             //?O
     259                 :            :                   aPfad.GetChar(nPos) != '\\' && aPfad.GetChar(nPos) != '/' &&      //?O
     260                 :            :                   aPfad.GetChar(nPos) != ':';                               //?O
     261                 :            :               nPos++ )
     262                 :            :             /* do nothing */;
     263                 :            : 
     264                 :            :         // is the name a UNC pathname?
     265                 :            :         if ( nPos == 0 && aPfad.Len() > 1 &&
     266                 :            :              ( ( aPfad.GetChar(0) == '\\' && aPfad.GetChar(1) == '\\' ) ||
     267                 :            :                ( aPfad.GetChar(0) == '/' && aPfad.GetChar(1) == '/' ) ) )
     268                 :            :         {
     269                 :            :             for ( nPos = 2; aPfad.Len() > nPos; ++nPos )
     270                 :            :                 if ( aPfad.GetChar(nPos) == '\\' || aPfad.GetChar(nPos) == '/' )
     271                 :            :                     break;
     272                 :            :             aName = rtl::OUStringToOString(aPfad.Copy( 2, nPos-2 ), osl_getThreadTextEncoding());
     273                 :            :             aStack.Push( new DirEntry( aName, FSYS_FLAG_ABSROOT ) );
     274                 :            :         }
     275                 :            :         // Is the name the root of the current drive?
     276                 :            :         else if ( nPos == 0 && aPfad.Len() > 0 &&
     277                 :            :                   ( aPfad.GetChar(0) == '\\' || aPfad.GetChar(0) == '/' ) )
     278                 :            :         {
     279                 :            :             // Push root directory of current drive
     280                 :            :             aStack.Push( new DirEntry( FSYS_FLAG_ABSROOT ) );
     281                 :            :         }
     282                 :            :         else
     283                 :            :         {
     284                 :            :             // Is the name itself a drive?
     285                 :            :             if ( nPos < aPfad.Len() && aPfad.GetChar(nPos) == ':' )
     286                 :            :             {
     287                 :            :                 aName = rtl::OUStringToOString(aPfad.Copy( 0, nPos + 1 ), osl_getThreadTextEncoding());
     288                 :            : 
     289                 :            :                 // Is the name the root of a drive?
     290                 :            :                 if ( (nPos + 1) < aPfad.Len() &&
     291                 :            :                      ( aPfad.GetChar(nPos+1) == '\\' || aPfad.GetChar(nPos+1) == '/' ) )
     292                 :            :                 {
     293                 :            :                     // unsupported if stack not empty or is a Novell format (URL)
     294                 :            :                     if ( !aStack.Empty() || aName.getLength() > 2 )
     295                 :            :                     {
     296                 :            :                         aName = rPfad;
     297                 :            :                         return FSYS_ERR_MISPLACEDCHAR;
     298                 :            :                     }
     299                 :            :                     // Push as root directory of drive
     300                 :            :                     aStack.Push( new DirEntry( aName, FSYS_FLAG_ABSROOT ) );
     301                 :            :                 }
     302                 :            :                 else
     303                 :            :                 {
     304                 :            :                     // clear stack if another drive is currently on it
     305                 :            :                     if ( !aStack.Empty() )
     306                 :            :                     {
     307                 :            :                         rtl::OString aThis(aStack.Bottom()->aName);
     308                 :            :                         aThis = aThis.toAsciiLowerCase();
     309                 :            :                         rtl::OString aOther(aName);
     310                 :            :                         aOther = aOther.toAsciiLowerCase();
     311                 :            :                         if (aThis.compareTo(aOther) != 0)
     312                 :            :                             aStack.Clear();
     313                 :            :                     }
     314                 :            : 
     315                 :            :                     if ( aStack.Empty() )
     316                 :            :                         aStack.Push( new DirEntry( aName, FSYS_FLAG_RELROOT ) );
     317                 :            :                 }
     318                 :            :             }
     319                 :            :             // Name is not a drive
     320                 :            :             else
     321                 :            :             {
     322                 :            :                 // split the name without seperator
     323                 :            :                 aName = rtl::OUStringToOString(aPfad.Copy( 0, nPos ), osl_getThreadTextEncoding());
     324                 :            : 
     325                 :            :                 // Is the name the current directory?
     326                 :            :                 if ( aName == "." )
     327                 :            :                     /* do nothing */;
     328                 :            : 
     329                 :            :                 // Is the name the parent directory?
     330                 :            :                 else if ( aName == ".." )
     331                 :            :                 {
     332                 :            :                     // Is the stack empty, or a parent (or relative root) on it?
     333                 :            :                     if ( ( aStack.Empty() ) ||
     334                 :            :                          ( aStack.Top()->eFlag == FSYS_FLAG_PARENT ) ||
     335                 :            :                          ( aStack.Top()->eFlag == FSYS_FLAG_RELROOT ) )
     336                 :            :                         // add leading parent to stack
     337                 :            :                         aStack.Push( new DirEntry( FSYS_FLAG_PARENT ) );
     338                 :            : 
     339                 :            :                     // It's an absolute root path
     340                 :            :                     else if ( aStack.Top()->eFlag == FSYS_FLAG_ABSROOT )
     341                 :            :                     {
     342                 :            :                         // Then there is no parent directory
     343                 :            :                         aName = rPfad;
     344                 :            :                         return FSYS_ERR_NOTEXISTS;
     345                 :            :                     }
     346                 :            :                     else
     347                 :            :                         // Otherwise removee parent TOS
     348                 :            :                         delete aStack.Pop();
     349                 :            :                 }
     350                 :            : 
     351                 :            :                 else
     352                 :            :                 {
     353                 :            :                     // add ordinary entries to the stack
     354                 :            :                     DirEntry *pNew = new DirEntry( aName, FSYS_FLAG_NORMAL );
     355                 :            :                     if ( !pNew->IsValid() )
     356                 :            :                     {
     357                 :            :                         aName = rPfad;
     358                 :            :                         ErrCode eErr = pNew->GetError();
     359                 :            :                         delete pNew;
     360                 :            :                         return eErr;
     361                 :            :                     }
     362                 :            :                     aStack.Push( pNew );
     363                 :            :                 }
     364                 :            :             }
     365                 :            :         }
     366                 :            : 
     367                 :            :         // determine remainder of path
     368                 :            :         aPfad.Erase( 0, nPos + 1 );
     369                 :            :         while ( aPfad.Len() && ( aPfad.GetChar(0) == '\\' || aPfad.GetChar(0) == '/' ) )
     370                 :            :             aPfad.Erase( 0, 1 );
     371                 :            :     }
     372                 :            :     while ( aPfad.Len() );
     373                 :            : 
     374                 :            :     sal_uIntPtr nErr = ERRCODE_NONE;
     375                 :            :     // Set the main entry itself
     376                 :            :     if ( aStack.Empty() )
     377                 :            :     {
     378                 :            :         eFlag = FSYS_FLAG_CURRENT;
     379                 :            :         aName = rtl::OString();
     380                 :            :     }
     381                 :            :     else
     382                 :            :     {
     383                 :            :         eFlag = aStack.Top()->eFlag;
     384                 :            :         aName = aStack.Top()->aName;
     385                 :            :         nErr = aStack.Top()->nError;
     386                 :            :         delete aStack.Pop();
     387                 :            :     }
     388                 :            : 
     389                 :            :     // pop parent entry from stack
     390                 :            :     DirEntry** pTemp = &pParent;
     391                 :            :     while ( !aStack.Empty() )
     392                 :            :     {
     393                 :            :         *pTemp = aStack.Pop();
     394                 :            : 
     395                 :            :         // set member pointer to the pParent of the member's own parent
     396                 :            :         pTemp = &( (*pTemp)->pParent );
     397                 :            :     }
     398                 :            : 
     399                 :            :     // Does this describe a volume?
     400                 :            :     if ( !pParent && eFlag == FSYS_FLAG_RELROOT && !aName.isEmpty() )
     401                 :            :         eFlag = FSYS_FLAG_VOLUME;
     402                 :            : 
     403                 :            :     // use full aName if error code was set
     404                 :            :     if ( nErr )
     405                 :            :         aName = rPfad;
     406                 :            :     return nErr;
     407                 :            : #else
     408                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
     409                 :            : 
     410                 :            :     // Add single names to the stack
     411         [ +  - ]:      35542 :     DirEntryStack   aStack;
     412                 :      35542 :     rtl::OString aPfad(rPfad);
     413         [ +  + ]:     234079 :     do
     414                 :            :     {
     415                 :            :         // split names on the first occurance of "/",
     416                 :            :         // if '/' starts the string, it itself becomes the name
     417                 :            : 
     418                 :            :         // search first occurance of "/"
     419                 :            :         sal_uInt16 nPos;
     420   [ +  +  +  + ]:    3460383 :         for ( nPos = 0;
                 [ +  + ]
     421                 :    3226304 :               nPos < aPfad.getLength() && aPfad[nPos] != '/';
     422                 :            :               nPos++ )
     423                 :            :             /* do nothing */;
     424                 :            : 
     425                 :            :         // is the name the root of the current drive?
     426 [ +  + ][ +  - ]:     234079 :         if ( nPos == 0 && !aPfad.isEmpty() && ( aPfad[0] == '/' ) )
         [ +  - ][ +  + ]
     427                 :            :         {
     428                 :            :             // push root directory of current drive to stack
     429 [ +  - ][ +  - ]:      24543 :             aStack.Push( new DirEntry( FSYS_FLAG_ABSROOT ) );
                 [ +  - ]
     430                 :            :         }
     431                 :            :         else
     432                 :            :         {
     433                 :            :             // split name without seperator
     434                 :     209536 :             aName = aPfad.copy(0, nPos);
     435                 :            : 
     436                 :            :             // Is the name the current directory?
     437         [ +  - ]:     209536 :             if ( aName == "." )
     438                 :            :                 /* do nothing */;
     439                 :            : 
     440                 :            : #ifdef UNX
     441                 :            :             // Is the name the user's home directory?
     442         [ -  + ]:     209536 :             else if ( aName == "~" )
     443                 :            :             {
     444 [ #  # ][ #  # ]:          0 :                 DirEntry aHome( String( (const char *) getenv( "HOME" ), osl_getThreadTextEncoding()) );
         [ #  # ][ #  # ]
     445 [ #  # ][ #  # ]:          0 :                 for ( sal_uInt16 n = aHome.Level(); n; --n )
     446 [ #  # ][ #  # ]:          0 :                     aStack.Push( new DirEntry( aHome[ (sal_uInt16) n-1 ] ) );
         [ #  # ][ #  # ]
                 [ #  # ]
     447                 :            :             }
     448                 :            : #endif
     449                 :            :             // Is the name the current parent directory?
     450         [ -  + ]:     209536 :             else if ( aName == ".." )
     451                 :            :             {
     452                 :            :                 // Is the stack empty, or a parent (or relative root) is on top?
     453 [ #  # ][ #  # ]:          0 :                 if ( ( aStack.Empty() ) || ( aStack.Top()->eFlag == FSYS_FLAG_PARENT ) )
         [ #  # ][ #  # ]
     454                 :            :                 {
     455                 :            :                     // push leading parents to stack
     456 [ #  # ][ #  # ]:          0 :                     aStack.Push( new DirEntry(rtl::OString(), FSYS_FLAG_PARENT) );
                 [ #  # ]
     457                 :            :                 }
     458                 :            :                 // Is the name an absolute root?
     459 [ #  # ][ #  # ]:          0 :                 else if ( aStack.Top()->eFlag == FSYS_FLAG_ABSROOT )
     460                 :            :                 {
     461                 :            :                     // they do not have parent directories
     462                 :          0 :                     return FSYS_ERR_NOTEXISTS;
     463                 :            :                 }
     464                 :            :                 else
     465                 :            :                     // otherwise remove parent TOS from stack
     466 [ #  # ][ #  # ]:          0 :                     delete aStack.Pop();
                 [ #  # ]
     467                 :            :             }
     468                 :            :             else
     469                 :            :             {
     470                 :     209536 :                 DirEntry *pNew = NULL;
     471                 :            :                 // push ordinary entries on the stack
     472 [ +  - ][ +  - ]:     209536 :                 pNew = new DirEntry( aName, FSYS_FLAG_NORMAL );
     473 [ +  - ][ -  + ]:     209536 :                 if ( !pNew->IsValid() )
     474                 :            :                 {
     475                 :          0 :                     aName = rPfad;
     476                 :          0 :                     ErrCode eErr = pNew->GetError();
     477 [ #  # ][ #  # ]:          0 :                     delete pNew;
     478                 :          0 :                     return eErr;
     479                 :            :                 }
     480         [ +  - ]:     209536 :                 aStack.Push( pNew );
     481                 :            :             }
     482                 :            :         }
     483                 :            : 
     484                 :            :         // get remainder of path
     485                 :     234079 :         aPfad = nPos < aPfad.getLength()
     486         [ +  + ]:     234079 :             ? aPfad.copy(nPos + 1) : rtl::OString();
     487 [ +  + ][ -  + ]:     234079 :         while ( !aPfad.isEmpty() && ( aPfad[0] == '/' ) )
                 [ -  + ]
     488                 :          0 :             aPfad = aPfad.copy(1);
     489                 :            :     }
     490                 :     234079 :     while (!aPfad.isEmpty());
     491                 :            : 
     492                 :            :     // insert main entry itself
     493         [ -  + ]:      35542 :     if ( aStack.Empty() )
     494                 :            :     {
     495                 :          0 :         eFlag = FSYS_FLAG_CURRENT;
     496                 :          0 :         aName = rtl::OString();
     497                 :            :     }
     498                 :            :     else
     499                 :            :     {
     500         [ +  - ]:      35542 :         eFlag = aStack.Top()->eFlag;
     501         [ +  - ]:      35542 :         aName = aStack.Top()->aName;
     502 [ +  - ][ +  - ]:      35542 :         delete aStack.Pop();
                 [ +  - ]
     503                 :            :     }
     504                 :            : 
     505                 :            :     // Get parent entries from stack
     506                 :      35542 :     DirEntry** pTemp = &pParent;
     507         [ +  + ]:     234079 :     while ( !aStack.Empty() )
     508                 :            :     {
     509         [ +  - ]:     198537 :         *pTemp = aStack.Pop();
     510                 :     198537 :         pTemp = &( (*pTemp)->pParent );
     511                 :            :     }
     512                 :            : 
     513                 :      35542 :     return FSYS_ERR_OK;
     514                 :            : #endif
     515                 :            : }
     516                 :            : 
     517                 :     527847 : static FSysPathStyle GetStyle( FSysPathStyle eStyle )
     518                 :            : {
     519 [ +  + ][ -  + ]:     527847 :     if ( eStyle == FSYS_STYLE_HOST || eStyle == FSYS_STYLE_DETECT )
     520                 :      51617 :         return DEFSTYLE;
     521                 :            :     else
     522                 :     527847 :         return eStyle;
     523                 :            : }
     524                 :            : 
     525                 :            : /** Convert name to match OS norm. */
     526                 :     209536 : void DirEntry::ImpTrim()
     527                 :            : {
     528                 :            :     // Do not trim wildcard characters
     529   [ +  -  +  -  :     628608 :     if ( ( aName.indexOf( '*' ) != -1 ) ||
           -  + ][ -  + ]
     530                 :     209536 :          ( aName.indexOf( '?' ) != -1 ) ||
     531                 :     209536 :          ( aName.indexOf( ';' ) != -1 ) )
     532                 :     209536 :         return;
     533                 :            : 
     534                 :            : #if defined(WNT)
     535                 :            :     if ( aName.getLength() > 254 )
     536                 :            :     {
     537                 :            :         nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
     538                 :            :         aName = aName.copy(254);
     539                 :            :     }
     540                 :            : #else
     541         [ -  + ]:     209536 :     if ( aName.getLength() > 250 )
     542                 :            :     {
     543                 :          0 :         nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
     544                 :          0 :         aName = aName.copy(250);
     545                 :            :     }
     546                 :            : #endif
     547                 :            : }
     548                 :            : 
     549                 :     209536 : DirEntry::DirEntry( const rtl::OString& rName, DirEntryFlag eDirFlag ) :
     550                 :            : #ifdef FEAT_FSYS_DOUBLESPEED
     551                 :            :             pStat( 0 ),
     552                 :            : #endif
     553                 :     209536 :             aName( rName )
     554                 :            : {
     555                 :            :     DBG_CTOR( DirEntry, ImpCheckDirEntry );
     556                 :            : 
     557                 :     209536 :     pParent         = NULL;
     558                 :     209536 :     eFlag           = eDirFlag;
     559                 :     209536 :     nError          = FSYS_ERR_OK;
     560                 :            : 
     561         [ +  - ]:     209536 :     ImpTrim();
     562                 :     209536 : }
     563                 :            : 
     564                 :     504759 : DirEntry::DirEntry( const DirEntry& rOrig ) :
     565                 :            : #ifdef FEAT_FSYS_DOUBLESPEED
     566         [ #  # ]:          0 :             pStat( rOrig.pStat ? new FileStat(*rOrig.pStat) : 0 ),
     567                 :            : #endif
     568         [ -  + ]:     504759 :             aName( rOrig.aName )
     569                 :            : {
     570                 :            :     DBG_CTOR( DirEntry, ImpCheckDirEntry );
     571                 :            : 
     572                 :     504759 :     eFlag           = rOrig.eFlag;
     573                 :     504759 :     nError          = rOrig.nError;
     574                 :            : 
     575         [ +  + ]:     504759 :     if ( rOrig.pParent )
     576                 :            :     {
     577 [ +  - ][ +  - ]:     440212 :         pParent = new DirEntry( *rOrig.pParent );
     578                 :            :     }
     579                 :            :     else
     580                 :            :     {
     581                 :      64547 :         pParent = NULL;
     582                 :            :     }
     583                 :     504759 : }
     584                 :            : 
     585                 :      35542 : DirEntry::DirEntry( const String& rInitName, FSysPathStyle eStyle )
     586                 :            : #ifdef FEAT_FSYS_DOUBLESPEED
     587                 :      35542 :             : pStat( 0 )
     588                 :            : #endif
     589                 :            : {
     590                 :            :     DBG_CTOR( DirEntry, ImpCheckDirEntry );
     591                 :            : 
     592                 :            :     (void) eStyle; // only used for DBG_UTIL
     593                 :            : 
     594                 :      35542 :     pParent         = NULL;
     595                 :            : 
     596                 :            :     // faster check for empty string
     597         [ -  + ]:      35542 :     if ( !rInitName.Len())
     598                 :            :     {
     599                 :          0 :         eFlag                   = FSYS_FLAG_CURRENT;
     600                 :          0 :         nError                  = FSYS_ERR_OK;
     601                 :      35542 :         return;
     602                 :            :     }
     603                 :            : 
     604 [ +  - ][ +  - ]:      35542 :     rtl::OString aTmpName(rtl::OUStringToOString(rInitName, osl_getThreadTextEncoding()));
                 [ +  - ]
     605         [ -  + ]:      35542 :     if (aTmpName.matchIgnoreAsciiCase(rtl::OString(RTL_CONSTASCII_STRINGPARAM("file:"))))
     606                 :            :     {
     607                 :            :         DBG_WARNING( "File URLs are not permitted but accepted" );
     608 [ #  # ][ #  # ]:          0 :         aTmpName = rtl::OUStringToOString(INetURLObject( rInitName ).PathToFileName(), osl_getThreadTextEncoding());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     609                 :            : #ifdef DBG_UTIL
     610                 :            :                 eStyle = FSYS_STYLE_HOST;
     611                 :            : #endif
     612                 :            :     }
     613                 :            :     else
     614                 :            :     {
     615                 :      35542 :         ::rtl::OUString aTmp;
     616                 :      35542 :         ::rtl::OUString aOInitName;
     617 [ +  - ][ +  - ]:      35542 :         if ( FileBase::getFileURLFromSystemPath( OUString( rInitName ), aTmp ) == FileBase::E_None )
                 [ +  - ]
     618                 :            :         {
     619         [ +  - ]:      35542 :             aOInitName = OUString( rInitName );
     620 [ +  - ][ +  - ]:      35542 :             aTmpName = rtl::OUStringToOString(aOInitName, osl_getThreadTextEncoding());
     621                 :      35542 :         }
     622                 :            : 
     623                 :            : #ifdef DBG_UTIL
     624                 :            :         if (eStyle == FSYS_STYLE_HOST && aTmpName.indexOf( "://" ) != -1)
     625                 :            :         {
     626                 :            :             rtl::OStringBuffer aErr(RTL_CONSTASCII_STRINGPARAM("DirEntries akzeptieren nur File URLS: "));
     627                 :            :             aErr.append(aTmpName);
     628                 :            :             DBG_WARNING(aErr.getStr());
     629                 :            :         }
     630                 :            : #endif
     631                 :            :     }
     632                 :            : 
     633         [ +  - ]:      35542 :     nError  = ImpParseName( aTmpName );
     634                 :            : 
     635         [ -  + ]:      35542 :     if ( nError != FSYS_ERR_OK )
     636                 :      35542 :         eFlag = FSYS_FLAG_INVALID;
     637                 :            : }
     638                 :            : 
     639                 :          0 : DirEntry::DirEntry( const rtl::OString& rInitName, FSysPathStyle eStyle )
     640                 :            : #ifdef FEAT_FSYS_DOUBLESPEED
     641                 :          0 :             : pStat( 0 )
     642                 :            : #endif
     643                 :            : {
     644                 :            :     DBG_CTOR( DirEntry, ImpCheckDirEntry );
     645                 :            : 
     646                 :            :     (void) eStyle; // only used for DBG_UTIL
     647                 :            : 
     648                 :          0 :     pParent         = NULL;
     649                 :            : 
     650                 :            :     // faster check for empty string
     651         [ #  # ]:          0 :     if ( rInitName.isEmpty() )
     652                 :            :     {
     653                 :          0 :         eFlag                   = FSYS_FLAG_CURRENT;
     654                 :          0 :         nError                  = FSYS_ERR_OK;
     655                 :          0 :         return;
     656                 :            :     }
     657                 :            : 
     658                 :          0 :     rtl::OString aTmpName( rInitName );
     659         [ #  # ]:          0 :     if (aTmpName.matchIgnoreAsciiCase(rtl::OString(RTL_CONSTASCII_STRINGPARAM("file:"))))
     660                 :            :     {
     661                 :            :         DBG_WARNING( "File URLs are not permitted but accepted" );
     662 [ #  # ][ #  # ]:          0 :         aTmpName = rtl::OUStringToOString(INetURLObject( rInitName ).PathToFileName(), osl_getThreadTextEncoding());
         [ #  # ][ #  # ]
                 [ #  # ]
     663                 :            : #ifdef DBG_UTIL
     664                 :            :         eStyle = FSYS_STYLE_HOST;
     665                 :            : #endif
     666                 :            :     }
     667                 :            : #ifdef DBG_UTIL
     668                 :            :     else
     669                 :            :     {
     670                 :            :         if( eStyle == FSYS_STYLE_HOST && rInitName.indexOf("://") != -1 )
     671                 :            :         {
     672                 :            :             rtl::OStringBuffer aErr(RTL_CONSTASCII_STRINGPARAM("DirEntries akzeptieren nur File URLS: "));
     673                 :            :             aErr.append(rInitName);
     674                 :            :             DBG_WARNING(aErr.getStr());
     675                 :            :         }
     676                 :            :     }
     677                 :            : #endif
     678                 :            : 
     679         [ #  # ]:          0 :     nError  = ImpParseName( aTmpName );
     680                 :            : 
     681         [ #  # ]:          0 :     if ( nError != FSYS_ERR_OK )
     682                 :          0 :         eFlag = FSYS_FLAG_INVALID;
     683                 :            : }
     684                 :            : 
     685                 :      25971 : DirEntry::DirEntry( DirEntryFlag eDirFlag )
     686                 :            : #ifdef FEAT_FSYS_DOUBLESPEED
     687                 :      25971 :             : pStat( 0 )
     688                 :            : #endif
     689                 :            : {
     690                 :            :     DBG_CTOR( DirEntry, ImpCheckDirEntry );
     691                 :            : 
     692                 :      25971 :     eFlag           = eDirFlag;
     693         [ +  + ]:      25971 :     nError          = ( eFlag == FSYS_FLAG_INVALID ) ? FSYS_ERR_UNKNOWN : FSYS_ERR_OK;
     694                 :      25971 :     pParent         = NULL;
     695                 :      25971 : }
     696                 :            : 
     697                 :     775808 : DirEntry::~DirEntry()
     698                 :            : {
     699                 :            :     DBG_DTOR( DirEntry, ImpCheckDirEntry );
     700                 :            : 
     701 [ +  + ][ +  - ]:     775808 :     delete pParent;
     702                 :            : #ifdef FEAT_FSYS_DOUBLESPEED
     703 [ -  + ][ #  # ]:     775808 :     delete pStat;
     704                 :            : #endif
     705                 :            : 
     706                 :     775808 : }
     707                 :            : 
     708                 :      21340 : const DirEntry* DirEntry::ImpGetTopPtr() const
     709                 :            : {
     710                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
     711                 :            : 
     712                 :      21340 :     const DirEntry *pTemp = this;
     713         [ +  + ]:     108531 :     while ( pTemp->pParent )
     714                 :      87191 :         pTemp = pTemp->pParent;
     715                 :            : 
     716                 :      21340 :     return pTemp;
     717                 :            : }
     718                 :            : 
     719                 :      11060 : DirEntry* DirEntry::ImpGetTopPtr()
     720                 :            : {
     721                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
     722                 :            : 
     723                 :      11060 :     DirEntry *pTemp = this;
     724         [ +  + ]:      11853 :     while ( pTemp->pParent )
     725                 :        793 :         pTemp = pTemp->pParent;
     726                 :            : 
     727                 :      11060 :     return pTemp;
     728                 :            : }
     729                 :            : 
     730                 :          0 : DirEntry* DirEntry::ImpChangeParent( DirEntry* pNewParent, sal_Bool bNormalize )
     731                 :            : {
     732                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
     733                 :            : 
     734                 :          0 :     DirEntry *pTemp = pParent;
     735 [ #  # ][ #  # ]:          0 :     if ( bNormalize && pNewParent &&
           [ #  #  #  # ]
                 [ #  # ]
     736                 :          0 :          pNewParent->eFlag == FSYS_FLAG_RELROOT && pNewParent->aName.isEmpty() )
     737                 :            :     {
     738                 :          0 :         pParent = 0;
     739         [ #  # ]:          0 :         delete pNewParent;
     740                 :            :     }
     741                 :            :     else
     742                 :          0 :         pParent = pNewParent;
     743                 :            : 
     744                 :          0 :     return pTemp;
     745                 :            : }
     746                 :            : 
     747                 :       1143 : sal_Bool DirEntry::Exists( FSysAccess nAccess ) const
     748                 :            : {
     749 [ +  + ][ +  - ]:       1143 :     static osl::Mutex aLocalMutex;
         [ +  - ][ #  # ]
     750         [ +  - ]:       1143 :     osl::MutexGuard aGuard( aLocalMutex );
     751 [ +  - ][ -  + ]:       1143 :         if ( !IsValid() )
     752                 :          0 :                 return sal_False;
     753                 :            : 
     754                 :            : #if defined WNT
     755                 :            :     // get special file names from system
     756                 :            :     if ( aName.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("CLOCK$")) ||
     757                 :            :            aName.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("CON")) ||
     758                 :            :            aName.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("AUX")) ||
     759                 :            :            aName.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("COM1")) ||
     760                 :            :            aName.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("COM2")) ||
     761                 :            :            aName.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("COM3")) ||
     762                 :            :            aName.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("COM4")) ||
     763                 :            :            aName.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("LPT1")) ||
     764                 :            :            aName.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("LPT2")) ||
     765                 :            :            aName.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("LPT3")) ||
     766                 :            :            aName.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("NUL")) ||
     767                 :            :            aName.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("PRN")) )
     768                 :            :         return sal_True;
     769                 :            : #endif
     770                 :            : 
     771                 :            :         FSysFailOnErrorImpl();
     772 [ +  - ][ +  - ]:       1143 :         DirEntryKind eKind = FileStat( *this, nAccess ).GetKind();
     773         [ +  + ]:       1143 :         if ( eKind & ( FSYS_KIND_FILE | FSYS_KIND_DIR ) )
     774                 :            :         {
     775                 :        329 :             return sal_True;
     776                 :            :         }
     777                 :            : 
     778                 :            : #if defined WNT
     779                 :            :         if ( 0 != ( eKind & FSYS_KIND_DEV ) )
     780                 :            :         {
     781                 :            :             return DRIVE_EXISTS( ImpGetTopPtr()->aName[0] );
     782                 :            :         }
     783                 :            : #endif
     784                 :            : 
     785         [ +  - ]:       1143 :         return 0 != ( eKind & ( FSYS_KIND_FILE | FSYS_KIND_DIR ) );
     786                 :            : }
     787                 :            : 
     788                 :          0 : sal_Bool DirEntry::First()
     789                 :            : {
     790                 :            :     FSysFailOnErrorImpl();
     791                 :            : 
     792 [ #  # ][ #  # ]:          0 :         String    aUniPathName( GetPath().GetFull() );
                 [ #  # ]
     793 [ #  # ][ #  # ]:          0 :         rtl::OString aPathName(rtl::OUStringToOString(aUniPathName, osl_getThreadTextEncoding()));
                 [ #  # ]
     794                 :            : 
     795         [ #  # ]:          0 :         DIR *pDir = opendir(aPathName.getStr());
     796         [ #  # ]:          0 :         if ( pDir )
     797                 :            :         {
     798 [ #  # ][ #  # ]:          0 :                 WildCard aWildeKarte(rtl::OStringToOUString(CMP_LOWER(aName), osl_getThreadTextEncoding()));
                 [ #  # ]
     799 [ #  # ][ #  # ]:          0 :                 for ( dirent* pEntry = readdir( pDir );
                 [ #  # ]
     800                 :            :                           pEntry;
     801                 :            :                           pEntry = readdir( pDir ) )
     802                 :            :                 {
     803                 :          0 :                         rtl::OString aFound(pEntry->d_name);
     804 [ #  # ][ #  # ]:          0 :                         if (aWildeKarte.Matches(rtl::OStringToOUString(CMP_LOWER(aFound), osl_getThreadTextEncoding())))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     805                 :            :                         {
     806                 :          0 :                                 aName = aFound;
     807         [ #  # ]:          0 :                                 closedir( pDir );
     808                 :          0 :                                 return sal_True;
     809                 :            :                         }
     810         [ #  # ]:          0 :                 }
     811 [ #  # ][ #  # ]:          0 :                 closedir( pDir );
                 [ #  # ]
     812                 :            :         }
     813         [ #  # ]:          0 :         return sal_False;
     814                 :            : }
     815                 :            : 
     816                 :     238706 : String DirEntry::GetFull( FSysPathStyle eStyle, sal_Bool bWithDelimiter,
     817                 :            :                           sal_uInt16 nMaxChars ) const
     818                 :            : {
     819                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
     820                 :            : 
     821                 :     238706 :     rtl::OStringBuffer aBuf;
     822                 :     238706 :     eStyle = GetStyle( eStyle );
     823         [ +  + ]:     238706 :     if ( pParent )
     824                 :            :     {
     825 [ +  + ][ +  - ]:     237524 :         if ( ( pParent->eFlag == FSYS_FLAG_ABSROOT ||
                 [ -  + ]
     826                 :            :                pParent->eFlag == FSYS_FLAG_RELROOT ||
     827                 :            :                pParent->eFlag == FSYS_FLAG_VOLUME ) )
     828                 :            :         {
     829 [ +  - ][ +  - ]:      31562 :             aBuf.append(rtl::OUStringToOString(pParent->GetName( eStyle ), osl_getThreadTextEncoding()));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     830 [ +  - ][ +  - ]:      31562 :             aBuf.append(rtl::OUStringToOString(GetName( eStyle ), osl_getThreadTextEncoding()));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     831                 :            :         }
     832                 :            :         else
     833                 :            :         {
     834 [ +  - ][ +  - ]:     205962 :             aBuf.append(rtl::OUStringToOString(pParent->GetFull( eStyle ), osl_getThreadTextEncoding()));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     835 [ -  + ][ +  - ]:     205962 :             aBuf.append(ACCESSDELIM_C(eStyle));
     836 [ +  - ][ +  - ]:     237524 :             aBuf.append(rtl::OUStringToOString(GetName( eStyle ), osl_getThreadTextEncoding()));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     837                 :            :         }
     838                 :            :     }
     839                 :            :     else
     840                 :            :     {
     841 [ +  - ][ +  - ]:       1182 :         aBuf.append(rtl::OUStringToOString(GetName(eStyle), osl_getThreadTextEncoding()));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     842                 :            :     }
     843                 :            : 
     844                 :            :     //! Hack
     845         [ -  + ]:     238706 :     if ( bWithDelimiter )
     846 [ #  # ][ #  # ]:          0 :         if ( aBuf[aBuf.getLength()-1] != ACCESSDELIM_C(eStyle) )
     847 [ #  # ][ #  # ]:          0 :             aBuf.append(ACCESSDELIM_C(eStyle));
     848                 :            : 
     849                 :     238706 :     rtl::OString aRet = aBuf.makeStringAndClear();
     850                 :            : 
     851                 :            :     // HACK
     852         [ -  + ]:     238706 :     if ( nMaxChars < STRING_MAXLEN )
     853 [ #  # ][ #  # ]:          0 :         aRet = ImplCutPath( aRet, nMaxChars, ACCESSDELIM_C(eStyle) );
     854                 :            : 
     855 [ +  - ][ +  - ]:     238706 :     return rtl::OStringToOUString(aRet, osl_getThreadTextEncoding());
                 [ +  - ]
     856                 :            : }
     857                 :            : 
     858                 :         40 : DirEntry DirEntry::GetPath() const
     859                 :            : {
     860                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
     861                 :            : 
     862         [ +  - ]:         40 :     if ( pParent )
     863                 :         40 :         return DirEntry( *pParent );
     864                 :            : 
     865                 :         40 :     return DirEntry();
     866                 :            : }
     867                 :            : 
     868                 :          0 : String DirEntry::GetExtension( char cSep ) const
     869                 :            : {
     870                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
     871                 :            : 
     872                 :          0 :     const char *p0 = aName.getStr();
     873                 :          0 :     const char *p1 = p0 + aName.getLength() - 1;
     874 [ #  # ][ #  # ]:          0 :     while ( p1 >= p0 && *p1 != cSep )
                 [ #  # ]
     875                 :          0 :     p1--;
     876                 :            : 
     877         [ #  # ]:          0 :     if ( p1 >= p0 )
     878                 :            :     {
     879                 :            :         // found a cSep at position p1
     880                 :            :         return rtl::OStringToOUString(aName.copy(p1 - p0 + 1),
     881 [ #  # ][ #  # ]:          0 :             osl_getThreadTextEncoding());
     882                 :            :     }
     883                 :            : 
     884                 :          0 :     return String();
     885                 :            : }
     886                 :            : 
     887                 :          0 : String DirEntry::GetBase( char cSep ) const
     888                 :            : {
     889                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
     890                 :            : 
     891                 :          0 :     const char *p0 = aName.getStr();
     892                 :          0 :     const char *p1 = p0 + aName.getLength() - 1;
     893 [ #  # ][ #  # ]:          0 :     while ( p1 >= p0 && *p1 != cSep )
                 [ #  # ]
     894                 :          0 :         p1--;
     895                 :            : 
     896         [ #  # ]:          0 :     if ( p1 >= p0 )
     897                 :            :     {
     898                 :            :         // found a cSep at position p1
     899                 :            :         return rtl::OStringToOUString(aName.copy(0, p1 - p0),
     900 [ #  # ][ #  # ]:          0 :             osl_getThreadTextEncoding());
     901                 :            : 
     902                 :            :     }
     903                 :            :     // did not find a cSep
     904         [ #  # ]:          0 :     return rtl::OStringToOUString(aName, osl_getThreadTextEncoding());
     905                 :            : }
     906                 :            : 
     907                 :     278538 : String DirEntry::GetName( FSysPathStyle eStyle ) const
     908                 :            : {
     909                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
     910                 :            : 
     911                 :     278538 :     rtl::OStringBuffer aRet;
     912                 :     278538 :     eStyle = GetStyle( eStyle );
     913                 :            : 
     914   [ -  +  -  +  :     278538 :     switch( eFlag )
                      + ]
     915                 :            :     {
     916                 :            :         case FSYS_FLAG_PARENT:
     917         [ #  # ]:          0 :             aRet.append(ACTPARENT(eStyle));
     918                 :          0 :             break;
     919                 :            : 
     920                 :            :         case FSYS_FLAG_ABSROOT:
     921                 :            :         {
     922         [ +  - ]:      31562 :             aRet.append(aName);
     923 [ -  + ][ +  - ]:      31562 :             aRet.append(ACCESSDELIM_C(eStyle));
     924                 :      31562 :             break;
     925                 :            :         }
     926                 :            : 
     927                 :            :         case FSYS_FLAG_INVALID:
     928                 :            :         case FSYS_FLAG_VOLUME:
     929                 :            :         {
     930         [ #  # ]:          0 :             aRet.append(aName);
     931                 :          0 :             break;
     932                 :            :         }
     933                 :            : 
     934                 :            :         case FSYS_FLAG_RELROOT:
     935         [ +  - ]:        720 :             if ( aName.isEmpty() )
     936                 :            :             {
     937         [ +  - ]:        720 :                 aRet.append(ACTCURRENT(eStyle));
     938                 :        720 :                 break;
     939                 :            :             }
     940                 :            : 
     941                 :            :         default:
     942         [ +  - ]:     246256 :             aRet.append(aName);
     943                 :     246256 :             break;
     944                 :            :     }
     945                 :            : 
     946                 :            :     return rtl::OStringToOUString(aRet.makeStringAndClear(),
     947 [ +  - ][ +  - ]:     278538 :         osl_getThreadTextEncoding());
                 [ +  - ]
     948                 :            : }
     949                 :            : 
     950                 :     112709 : bool DirEntry::IsAbs() const
     951                 :            : {
     952                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
     953                 :            : 
     954                 :            : #ifdef UNX
     955         [ +  + ]:     112709 :     return ( pParent ? pParent->IsAbs() : eFlag == FSYS_FLAG_ABSROOT );
     956                 :            : #else
     957                 :            :     return ( pParent ? pParent->IsAbs() : eFlag == FSYS_FLAG_ABSROOT && !aName.isEmpty() );
     958                 :            : #endif
     959                 :            : }
     960                 :            : 
     961                 :          0 : String DirEntry::CutName( FSysPathStyle eStyle )
     962                 :            : {
     963                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
     964                 :            : 
     965                 :          0 :     eStyle = GetStyle( eStyle );
     966                 :            : 
     967                 :          0 :     String aOldName( GetName( eStyle ) );
     968                 :            : 
     969         [ #  # ]:          0 :     if ( pParent )
     970                 :            :     {
     971                 :          0 :         DirEntry *pOldParent = pParent;
     972         [ #  # ]:          0 :         if ( pOldParent )
     973                 :            :         {
     974                 :          0 :             pParent = pOldParent->pParent;
     975                 :          0 :             eFlag = pOldParent->eFlag;
     976                 :          0 :             aName = pOldParent->aName;
     977                 :          0 :             pOldParent->pParent = NULL;
     978 [ #  # ][ #  # ]:          0 :             delete pOldParent;
     979                 :            :         }
     980                 :            :         else
     981                 :            :         {
     982                 :          0 :             eFlag = FSYS_FLAG_CURRENT;
     983                 :          0 :             aName = rtl::OString();
     984                 :            :         }
     985                 :            :     }
     986                 :            :     else
     987                 :            :     {
     988                 :          0 :         eFlag = FSYS_FLAG_CURRENT;
     989                 :          0 :         aName = rtl::OString();
     990 [ #  # ][ #  # ]:          0 :         delete pParent;
     991                 :          0 :         pParent = NULL;
     992                 :            :     }
     993                 :            : 
     994                 :          0 :     return aOldName;
     995                 :            : }
     996                 :            : 
     997                 :        660 : sal_Bool DirEntry::operator==( const DirEntry& rEntry ) const
     998                 :            : {
     999                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
    1000                 :            : 
    1001                 :            :     // test whether the contents are textual the same
    1002                 :            : 
    1003 [ -  + ][ #  # ]:        660 :     if ( nError && ( nError == rEntry.nError ) )
    1004                 :          0 :         return sal_True;
    1005 [ +  - ][ +  - ]:        660 :     if ( nError || rEntry.nError ||
         [ +  - ][ -  + ]
    1006                 :            :          ( eFlag == FSYS_FLAG_INVALID ) ||
    1007                 :            :          ( rEntry.eFlag == FSYS_FLAG_INVALID ) )
    1008                 :          0 :         return sal_False;
    1009                 :            : 
    1010                 :        660 :     const DirEntry *pThis = (DirEntry *)this;
    1011                 :        660 :     const DirEntry *pWith = (DirEntry *)&rEntry;
    1012 [ +  - ][ +  - ]:        660 :     while( pThis && pWith && (pThis->eFlag == pWith->eFlag) )
         [ +  - ][ +  - ]
    1013                 :            :     {
    1014         [ +  - ]:        660 :         if ( CMP_LOWER(pThis->aName) != CMP_LOWER(pWith->aName) )
    1015                 :        660 :             break;
    1016                 :          0 :         pThis = pThis->pParent;
    1017                 :          0 :         pWith = pWith->pParent;
    1018                 :            :     }
    1019                 :            : 
    1020 [ -  + ][ #  # ]:        660 :     return ( !pThis && !pWith );
    1021                 :            : }
    1022                 :            : 
    1023                 :      11699 : DirEntry& DirEntry::operator=( const DirEntry& rEntry )
    1024                 :            : {
    1025                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
    1026                 :            : 
    1027         [ -  + ]:      11699 :     if ( this == &rEntry )
    1028                 :          0 :         return *this;
    1029         [ -  + ]:      11699 :     if ( rEntry.nError != FSYS_ERR_OK ) {
    1030                 :            :         OSL_FAIL("Zuweisung mit invalidem DirEntry");
    1031                 :          0 :         nError = rEntry.nError;
    1032                 :          0 :         return *this;
    1033                 :            :     }
    1034                 :            : 
    1035                 :            :     // set name and type, but keep refs
    1036                 :      11699 :     aName                       = rEntry.aName;
    1037                 :      11699 :     eFlag                       = rEntry.eFlag;
    1038                 :      11699 :     nError                      = FSYS_ERR_OK;
    1039                 :            : 
    1040                 :      11699 :     DirEntry *pOldParent = pParent;
    1041         [ +  - ]:      11699 :     if ( rEntry.pParent )
    1042         [ +  - ]:      11699 :         pParent = new DirEntry( *rEntry.pParent );
    1043                 :            :     else
    1044                 :          0 :         pParent = NULL;
    1045                 :            : 
    1046         [ +  + ]:      11699 :     if ( pOldParent )
    1047         [ +  - ]:      10878 :         delete pOldParent;
    1048                 :      11699 :     return *this;
    1049                 :            : }
    1050                 :            : 
    1051                 :      10670 : DirEntry DirEntry::operator+( const DirEntry& rEntry ) const
    1052                 :            : {
    1053                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
    1054                 :            : #ifdef DBG_UTIL
    1055                 :            :         static sal_Bool bTested = sal_False;
    1056                 :            :         if ( !bTested )
    1057                 :            :         {
    1058                 :            :                 bTested = sal_True;
    1059                 :            :                 FSysTest();
    1060                 :            :         }
    1061                 :            : #endif
    1062                 :            : 
    1063                 :      10670 :         const DirEntry *pEntryTop = rEntry.ImpGetTopPtr();
    1064                 :      10670 :         const DirEntry *pThisTop = ImpGetTopPtr();
    1065                 :            : 
    1066   [ #  #  #  # ]:      21340 :     if (
         [ +  - ][ +  - ]
         [ -  + ][ -  + ]
           [ -  +  #  #  
                   -  + ]
    1067                 :          0 :         (eFlag == FSYS_FLAG_RELROOT && aName.isEmpty()) ||
    1068                 :            :         (
    1069                 :      10670 :          (!pEntryTop->aName.isEmpty()  ||
    1070 [ #  # ][ #  # ]:          0 :           ((rEntry.Level()>1)?(rEntry[rEntry.Level()-2].aName.equalsIgnoreAsciiCase(RFS_IDENTIFIER)):sal_False))
                 [ #  # ]
    1071                 :            :           &&
    1072                 :            :          (pEntryTop->eFlag == FSYS_FLAG_ABSROOT ||
    1073                 :            :           pEntryTop->eFlag == FSYS_FLAG_RELROOT ||
    1074                 :            :           pEntryTop->eFlag == FSYS_FLAG_VOLUME)
    1075                 :            :         )
    1076                 :            :        )
    1077                 :            :     {
    1078         [ #  # ]:          0 :                 return rEntry;
    1079                 :            :     }
    1080                 :            : 
    1081                 :            :     // something + "." (=> pEntryTop == &rEntry)
    1082 [ -  + ][ #  # ]:      10670 :     if (pEntryTop->eFlag == FSYS_FLAG_RELROOT && pEntryTop->aName.isEmpty())
                 [ -  + ]
    1083                 :            :     {
    1084                 :            :         DBG_ASSERT( pEntryTop == &rEntry, "DirEntry::op+ buggy" );
    1085         [ #  # ]:          0 :         return *this;
    1086                 :            :     }
    1087                 :            : 
    1088                 :            :     // root += ".." (=> impossible)
    1089 [ -  + ][ #  # ]:      10670 :         if ( pEntryTop->eFlag == FSYS_FLAG_PARENT && pThisTop == this &&
                 [ #  # ]
    1090                 :            :                 ( eFlag == FSYS_FLAG_ABSROOT ) )
    1091         [ #  # ]:          0 :                 return DirEntry( FSYS_FLAG_INVALID );
    1092                 :            : 
    1093                 :            :         // something += abs (=> only append device if existant)
    1094         [ -  + ]:      10670 :         if ( pEntryTop->eFlag == FSYS_FLAG_ABSROOT )
    1095                 :            :         {
    1096                 :          0 :                 rtl::OString aDevice;
    1097         [ #  # ]:          0 :                 if ( pThisTop->eFlag == FSYS_FLAG_ABSROOT )
    1098                 :          0 :                     aDevice = pThisTop->aName;
    1099         [ #  # ]:          0 :                 DirEntry aRet = rEntry;
    1100         [ #  # ]:          0 :                 if ( !aDevice.isEmpty() )
    1101                 :          0 :                     aRet.ImpGetTopPtr()->aName = aDevice;
    1102 [ #  # ][ #  # ]:          0 :                 return aRet;
    1103                 :            :         }
    1104                 :            : 
    1105                 :            :         // something += ".." (=> break apart)
    1106 [ +  - ][ -  + ]:      10670 :         if ( eFlag == FSYS_FLAG_NORMAL && pEntryTop->eFlag == FSYS_FLAG_PARENT )
    1107                 :            :         {
    1108         [ #  # ]:          0 :                 String aConcated( GetFull() );
    1109         [ #  # ]:          0 :                 aConcated += ACCESSDELIM_C(FSYS_STYLE_HOST);
    1110 [ #  # ][ #  # ]:          0 :                 aConcated += rEntry.GetFull();
                 [ #  # ]
    1111 [ #  # ][ #  # ]:          0 :                 return DirEntry( aConcated );
    1112                 :            :         }
    1113                 :            : 
    1114                 :            :         // otherwise append consecutively
    1115         [ +  - ]:      10670 :         DirEntry aRet( rEntry );
    1116                 :      10670 :         DirEntry *pTop = aRet.ImpGetTopPtr();
    1117 [ +  - ][ +  - ]:      10670 :         pTop->pParent = new DirEntry( *this );
    1118                 :            : 
    1119 [ +  - ][ +  - ]:      10670 :         return aRet;
    1120                 :            : }
    1121                 :            : 
    1122                 :      10670 : DirEntry &DirEntry::operator+=( const DirEntry& rEntry )
    1123                 :            : {
    1124                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
    1125                 :            : 
    1126         [ +  - ]:      10670 :     return *this = *this + rEntry;
    1127                 :            : }
    1128                 :            : 
    1129                 :         60 : String DirEntry::GetAccessDelimiter( FSysPathStyle eFormatter )
    1130                 :            : {
    1131 [ -  + ][ +  - ]:         60 :         return rtl::OUString( ACCESSDELIM_C( GetStyle( eFormatter ) ) );
    1132                 :            : }
    1133                 :            : 
    1134                 :       1440 : void DirEntry::SetExtension( const String& rExtension, char cSep )
    1135                 :            : {
    1136                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
    1137                 :            : 
    1138                 :            :     // do not set extensions for drives
    1139         [ -  + ]:       1440 :     if(eFlag == FSYS_FLAG_ABSROOT)
    1140                 :            :     {
    1141                 :          0 :         nError = FSYS_ERR_NOTSUPPORTED;
    1142                 :       1440 :         return;
    1143                 :            :     }
    1144                 :            : 
    1145         [ +  - ]:       1440 :     rtl::OStringBuffer aBuf(aName);
    1146                 :            : 
    1147                 :            :     // search cSep within aName
    1148                 :       1440 :     const sal_Char *p0 = aBuf.getStr();
    1149                 :       1440 :     const sal_Char *p1 = p0 + aBuf.getLength() - 1;
    1150 [ +  + ][ +  + ]:       7740 :     while ( p1 >= p0 && *p1 != cSep )
                 [ +  + ]
    1151                 :       6300 :         p1--;
    1152         [ +  + ]:       1440 :     if ( p1 >= p0 )
    1153                 :            :     {
    1154                 :            :         // found a cSep on position p1
    1155                 :            : 
    1156                 :            :         sal_Int32 n = static_cast<sal_Int32>(
    1157                 :        780 :                 p1 - p0 + 1 - ( rExtension.Len() ? 0 : 1 ));
    1158                 :            : 
    1159         [ +  - ]:        780 :         aBuf.remove(n, aBuf.getLength()-n);
    1160                 :            :     }
    1161         [ +  - ]:        660 :     else if ( rExtension.Len() )
    1162                 :            :     {
    1163                 :            :         // no cSep was found
    1164         [ +  - ]:        660 :         aBuf.append(cSep);
    1165                 :            :     }
    1166                 :            : 
    1167                 :            :     aBuf.append(rtl::OUStringToOString(rExtension,
    1168 [ +  - ][ +  - ]:       1440 :         osl_getThreadTextEncoding()));
         [ +  - ][ +  - ]
    1169                 :            : 
    1170                 :       1440 :     aName = aBuf.makeStringAndClear();
    1171                 :            : }
    1172                 :            : 
    1173                 :          0 : void DirEntry::SetName( const String& rName, FSysPathStyle eFormatter )
    1174                 :            : {
    1175                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
    1176                 :            : 
    1177 [ #  # ][ #  # ]:          0 :     if ( eFormatter == FSYS_STYLE_HOST || eFormatter == FSYS_STYLE_DETECT )
    1178                 :          0 :         eFormatter = DEFSTYLE;
    1179         [ #  # ]:          0 :     sal_Char cAccDelim(ACCESSDELIM_C(eFormatter));
    1180                 :            : 
    1181   [ #  #  #  #  :          0 :     if ( (eFlag != FSYS_FLAG_NORMAL) ||
           #  # ][ #  # ]
    1182                 :          0 :          (aName.indexOf(':') != -1) ||
    1183                 :          0 :          (aName.indexOf(cAccDelim) != -1) )
    1184                 :            :     {
    1185                 :          0 :         eFlag = FSYS_FLAG_INVALID;
    1186                 :            :     }
    1187                 :            :     else
    1188                 :            :     {
    1189         [ #  # ]:          0 :         aName = rtl::OUStringToOString(rName, osl_getThreadTextEncoding());
    1190                 :            :     }
    1191                 :          0 : }
    1192                 :            : 
    1193                 :        390 : sal_Bool DirEntry::Find( const String& rPfad, char cDelim )
    1194                 :            : {
    1195                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
    1196                 :            : 
    1197         [ +  + ]:        390 :     if ( ImpGetTopPtr()->eFlag == FSYS_FLAG_ABSROOT )
    1198                 :         61 :             return sal_True;
    1199                 :            : 
    1200                 :        329 :     sal_Bool bWild = aName.indexOf( '*' ) != -1 ||
    1201 [ -  + ][ +  - ]:        329 :                      aName.indexOf( '?' ) != -1;
    1202                 :            : 
    1203         [ +  - ]:        329 :     if ( !cDelim )
    1204                 :        329 :             cDelim = SEARCHDELIM(DEFSTYLE)[0];
    1205                 :            : 
    1206                 :            :     rtl::OString aThis = rtl::OStringBuffer()
    1207         [ +  - ]:        658 :         .append(ACCESSDELIM_C(DEFSTYLE))
    1208                 :            :         .append(rtl::OUStringToOString(GetFull(),
    1209 [ +  - ][ +  - ]:        987 :             osl_getThreadTextEncoding()))
         [ +  - ][ +  - ]
           [ +  -  +  - ]
    1210                 :        329 :         .makeStringAndClear();
    1211                 :        329 :     sal_Int32 nIndex = 0;
    1212         [ +  - ]:       1143 :     do
    1213                 :            :     {
    1214                 :            :         rtl::OStringBuffer aPath(rtl::OUStringToOString(rPfad,
    1215 [ +  - ][ +  - ]:       1143 :             osl_getThreadTextEncoding()).getToken( 0, cDelim, nIndex ));
         [ +  - ][ +  - ]
    1216                 :            : 
    1217         [ +  - ]:       1143 :         if ( aPath.getLength() )
    1218                 :            :         {
    1219         [ +  + ]:       1143 :             if (aPath[aPath.getLength()-1] == ACCESSDELIM_C(DEFSTYLE))
    1220         [ +  - ]:        221 :                 aPath.remove(aPath.getLength()-1, 1);
    1221         [ +  - ]:       1143 :             aPath.append(aThis);
    1222                 :            :             DirEntry aEntry(rtl::OStringToOUString(
    1223 [ +  - ][ +  - ]:       1143 :                 aPath.makeStringAndClear(), osl_getThreadTextEncoding()));
         [ +  - ][ +  - ]
                 [ +  - ]
    1224 [ +  - ][ +  - ]:       2286 :             if ( aEntry.ToAbs() &&
         [ +  + ][ -  + ]
         [ #  # ][ +  + ]
                 [ +  - ]
    1225 [ +  - ][ #  # ]:       1143 :                      ( ( !bWild && aEntry.Exists() ) || ( bWild && aEntry.First() ) ) )
    1226                 :            :             {
    1227         [ +  - ]:        329 :                     (*this) = aEntry;
    1228                 :       1143 :                     return sal_True;
    1229 [ +  - ][ +  + ]:       1143 :             }
    1230         [ +  + ]:       1143 :         }
    1231                 :            :     }
    1232                 :            :     while ( nIndex >= 0 );
    1233                 :        390 :     return sal_False;
    1234                 :            : }
    1235                 :            : 
    1236                 :            : #ifndef UNX
    1237                 :            : DirEntry DirEntry::GetDevice() const
    1238                 :            : {
    1239                 :            :         DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
    1240                 :            : 
    1241                 :            :         const DirEntry *pTop = ImpGetTopPtr();
    1242                 :            : 
    1243                 :            :         if ( ( pTop->eFlag == FSYS_FLAG_ABSROOT || pTop->eFlag == FSYS_FLAG_RELROOT ) &&
    1244                 :            :                  !pTop->aName.isEmpty() )
    1245                 :            :                 return DirEntry( pTop->aName, FSYS_FLAG_VOLUME );
    1246                 :            :         else
    1247                 :            :                 return DirEntry( rtl::OString(), FSYS_FLAG_INVALID );
    1248                 :            : }
    1249                 :            : #endif
    1250                 :            : 
    1251                 :      10543 : String DirEntry::GetSearchDelimiter( FSysPathStyle eFormatter )
    1252                 :            : {
    1253 [ +  - ][ +  - ]:      10543 :     return rtl::OStringToOUString(rtl::OString(SEARCHDELIM(GetStyle(eFormatter))), osl_getThreadTextEncoding());
                 [ +  - ]
    1254                 :            : }
    1255                 :            : 
    1256                 :            : namespace
    1257                 :            : {
    1258                 :            :     struct TempNameBase_Impl : public rtl::Static< DirEntry, TempNameBase_Impl > {};
    1259                 :            : }
    1260                 :            : 
    1261                 :         40 : DirEntry DirEntry::TempName( DirEntryKind eKind ) const
    1262                 :            : {
    1263                 :            :         // use base-temp-dir if necessary
    1264         [ +  - ]:         40 :         const DirEntry &rEntry = TempNameBase_Impl::get();
    1265 [ -  + ][ #  # ]:         40 :         if ( !pParent && FSYS_FLAG_CURRENT != rEntry.eFlag && FSYS_FLAG_ABSROOT != eFlag )
                 [ #  # ]
    1266                 :            :         {
    1267         [ #  # ]:          0 :                 DirEntry aFactory( rEntry );
    1268 [ #  # ][ #  # ]:          0 :                 aFactory += GetName();
         [ #  # ][ #  # ]
                 [ #  # ]
    1269 [ #  # ][ #  # ]:          0 :                 return aFactory.TempName();
    1270                 :            :         }
    1271                 :            : 
    1272                 :         40 :         rtl::OString aDirName;
    1273                 :            :         char *ret_val;
    1274                 :            :         size_t i;
    1275                 :            : 
    1276                 :            :         // determine Directory, Prefix and Extension
    1277                 :            :         char pfx[6];
    1278                 :            :         char ext[5];
    1279                 :            :         const char *dir;
    1280                 :         40 :         const char *pWild = strchr( aName.getStr(), '*' );
    1281         [ +  - ]:         40 :         if ( !pWild )
    1282                 :         40 :             pWild = strchr( aName.getStr(), '?' );
    1283                 :            : 
    1284         [ -  + ]:         40 :         if ( pWild )
    1285                 :            :         {
    1286         [ #  # ]:          0 :             if ( pParent )
    1287 [ #  # ][ #  # ]:          0 :                 aDirName = rtl::OUStringToOString(pParent->GetFull(), osl_getThreadTextEncoding());
         [ #  # ][ #  # ]
                 [ #  # ]
    1288                 :          0 :             strncpy( pfx, aName.getStr(), Min( (int)5, (int)(pWild-aName.getStr()) ) );
    1289                 :          0 :             pfx[ pWild-aName.getStr() ] = 0;
    1290                 :          0 :             const char *pExt = strchr( pWild, '.' );
    1291         [ #  # ]:          0 :             if ( pExt )
    1292                 :            :             {
    1293                 :          0 :                 strncpy( ext, pExt, 4 );
    1294                 :          0 :                 ext[4] = 0;
    1295                 :            :             }
    1296                 :            :             else
    1297                 :          0 :                 strcpy( ext, ".tmp" );
    1298                 :            :         }
    1299                 :            :         else
    1300                 :            :         {
    1301 [ +  - ][ +  - ]:         40 :             aDirName = rtl::OUStringToOString(GetFull(), osl_getThreadTextEncoding());
         [ +  - ][ +  - ]
                 [ +  - ]
    1302                 :         40 :             strcpy( pfx, "lo" );
    1303                 :         40 :             strcpy( ext, ".tmp" );
    1304                 :            :         }
    1305                 :         40 :         dir = aDirName.getStr();
    1306                 :            : 
    1307                 :            :         char sBuf[_MAX_PATH];
    1308 [ -  + ][ #  # ]:         40 :         if ( eFlag == FSYS_FLAG_CURRENT || ( !pParent && pWild ) )
                 [ +  - ]
    1309         [ #  # ]:          0 :             dir = TempDirImpl(sBuf);
    1310                 :            : 
    1311         [ +  - ]:         40 :         DirEntry aRet(FSYS_FLAG_INVALID);
    1312                 :         40 :         i = strlen(dir);
    1313                 :            :         // need to add ?\\? + prefix + number + pid + .ext + '\0'
    1314                 :            : #       define TMPNAME_SIZE  ( 1 + 5 + 5 + 10 + 4 + 1 )
    1315         [ +  - ]:         40 :         ret_val = new char[i + TMPNAME_SIZE ];
    1316         [ +  - ]:         40 :         if (ret_val)
    1317                 :            :         {
    1318                 :         40 :             strcpy(ret_val,dir);
    1319                 :            : 
    1320                 :            :             /* Make sure directory ends with a separator    */
    1321                 :            : #if defined(WNT)
    1322                 :            :             if ( i>0 && ret_val[i-1] != '\\' && ret_val[i-1] != '/' &&
    1323                 :            :                  ret_val[i-1] != ':')
    1324                 :            :                 ret_val[i++] = '\\';
    1325                 :            : #elif defined UNX
    1326 [ +  - ][ +  - ]:         40 :             if (i>0 && ret_val[i-1] != '/')
    1327                 :         40 :                 ret_val[i++] = '/';
    1328                 :            : #else
    1329                 :            : #error unknown operating system
    1330                 :            : #endif
    1331                 :            : 
    1332                 :         40 :             strncpy(ret_val + i, pfx, 5);
    1333                 :         40 :             ret_val[i + 5] = '\0';      /* strncpy doesn't put a 0 if more  */
    1334                 :         40 :             i = strlen(ret_val);        /* than 'n' chars.          */
    1335                 :            : 
    1336                 :            :             /* Prefix can have 5 chars, leaving 3 for numbers. 26 ** 3 == 17576
    1337                 :            :              * Welcome to the 21st century, we can have longer filenames now ;)
    1338                 :            :              * New format: pfx + "5 char milli/micro second res" + "current pid" + ".tmp"
    1339                 :            :              */
    1340                 :            : #if (defined MSC || defined __MINGW32__) && defined WNT
    1341                 :            :             /* Milliseconds !! */
    1342                 :            :             static unsigned long u = GetTickCount();
    1343                 :            :             unsigned long mypid = static_cast<unsigned long>(_getpid());
    1344                 :            : #else
    1345                 :            :             /* Microseconds !! */
    1346 [ +  + ][ +  - ]:         40 :             static unsigned long u = clock();
    1347                 :         40 :             unsigned long mypid = static_cast<unsigned long>(getpid());
    1348                 :            : #endif
    1349         [ +  - ]:         40 :             for ( unsigned long nOld = u; ++u != nOld; ) /* Hae??? */
    1350                 :            :             {
    1351                 :         40 :                 u %= 100000;  /* on *NIX repeats every 100ms, maybe less if CLOCKS_PER_SEC > 10^6 */
    1352                 :         40 :                 snprintf(ret_val+i, TMPNAME_SIZE, "%05lu%lu", u, mypid);
    1353                 :            : 
    1354                 :         40 :                 strcat(ret_val,ext);
    1355                 :            : 
    1356         [ -  + ]:         40 :                 if ( FSYS_KIND_FILE == eKind )
    1357                 :            :                 {
    1358         [ #  # ]:          0 :                     SvFileStream aStream( String( ret_val, osl_getThreadTextEncoding()),
    1359 [ #  # ][ #  # ]:          0 :                                             STREAM_WRITE|STREAM_SHARE_DENYALL );
                 [ #  # ]
    1360         [ #  # ]:          0 :                     if ( aStream.IsOpen() )
    1361                 :            :                     {
    1362         [ #  # ]:          0 :                         aStream.Seek( STREAM_SEEK_TO_END );
    1363         [ #  # ]:          0 :                         if ( 0 == aStream.Tell() )
    1364                 :            :                         {
    1365 [ #  # ][ #  # ]:          0 :                                 aRet = DirEntry( String( ret_val, osl_getThreadTextEncoding()));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1366                 :            :                                 break;
    1367                 :            :                         }
    1368         [ #  # ]:          0 :                         aStream.Close();
    1369 [ #  # ][ #  # ]:          0 :                     }
    1370                 :            :                 }
    1371                 :            :                 else
    1372                 :            :                 {
    1373                 :            :                     // Redirect
    1374 [ +  - ][ +  - ]:         40 :                     String aRetVal(ret_val, osl_getThreadTextEncoding());
    1375         [ +  - ]:         40 :                     String aRedirected (aRetVal);
    1376         [ -  + ]:         40 :                     if ( FSYS_KIND_DIR == eKind )
    1377                 :            :                     {
    1378 [ #  # ][ #  # ]:          0 :                         if (0 == _mkdir(rtl::OUStringToOString(aRedirected, osl_getThreadTextEncoding()).getStr()))
         [ #  # ][ #  # ]
    1379                 :            :                         {
    1380 [ #  # ][ #  # ]:          0 :                             aRet = DirEntry( aRetVal );
                 [ #  # ]
    1381                 :            :                             break;
    1382                 :            :                         }
    1383                 :            :                     }
    1384                 :            :                     else
    1385                 :            :                     {
    1386                 :            : #if defined(UNX)
    1387 [ +  - ][ +  - ]:         40 :                         if (access(rtl::OUStringToOString(aRedirected, osl_getThreadTextEncoding()).getStr(), F_OK))
         [ +  - ][ +  - ]
    1388                 :            :                         {
    1389 [ +  - ][ +  - ]:         40 :                                 aRet = DirEntry( aRetVal );
                 [ +  - ]
    1390                 :            :                                 break;
    1391                 :            :                         }
    1392                 :            : #else
    1393                 :            :                         struct stat aStat;
    1394                 :            :                         if (stat(rtl::OUStringToOString(aRedirected, osl_getThreadTextEncoding()).getStr(), &aStat))
    1395                 :            :                         {
    1396                 :            :                             aRet = DirEntry( aRetVal );
    1397                 :            :                             break;
    1398                 :            :                         }
    1399                 :            : #endif
    1400 [ +  - ][ +  - ]:         40 :                     }
         [ +  - ][ -  + ]
    1401                 :            :                 }
    1402                 :            :             }
    1403                 :            : 
    1404         [ +  - ]:         40 :             delete[] ret_val;
    1405                 :         40 :             ret_val = 0;
    1406                 :            :         }
    1407                 :            : 
    1408 [ +  - ][ +  - ]:         40 :         return aRet;
    1409                 :            : }
    1410                 :            : 
    1411                 :          0 : const DirEntry &DirEntry::operator[]( sal_uInt16 nParentLevel ) const
    1412                 :            : {
    1413                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
    1414                 :            : 
    1415                 :            :     //TPF: maybe to be implemented (FastFSys)
    1416                 :            : 
    1417                 :          0 :     const DirEntry *pRes = this;
    1418 [ #  # ][ #  # ]:          0 :     while ( pRes && nParentLevel-- )
                 [ #  # ]
    1419                 :          0 :         pRes = pRes->pParent;
    1420                 :            : 
    1421                 :          0 :     return *pRes;
    1422                 :            : }
    1423                 :            : 
    1424                 :          0 : sal_Bool DirEntry::MakeDir( sal_Bool bSloppy ) const
    1425                 :            : {
    1426                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
    1427                 :            : 
    1428                 :            :         // fast check if exists
    1429 [ #  # ][ #  # ]:          0 :         if ( FileStat( *this ).IsKind( FSYS_KIND_DIR ) )
    1430                 :          0 :                 return sal_True;
    1431 [ #  # ][ #  # ]:          0 :         if ( bSloppy && pParent )
    1432 [ #  # ][ #  # ]:          0 :                  if ( FileStat( *pParent ).IsKind( FSYS_KIND_DIR ) )
    1433                 :          0 :                           return sal_True;
    1434                 :            : 
    1435         [ #  # ]:          0 :         const DirEntry *pNewDir = bSloppy ? pParent : this;
    1436         [ #  # ]:          0 :         if ( pNewDir )
    1437                 :            :         {
    1438                 :            :                 // Create path to dir
    1439 [ #  # ][ #  # ]:          0 :                 if ( pNewDir->pParent && !pNewDir->pParent->MakeDir(sal_False) )
                 [ #  # ]
    1440                 :          0 :                         return sal_False;
    1441                 :            : 
    1442                 :            :                 // create dir ourselves
    1443 [ #  # ][ #  # ]:          0 :                 if ( pNewDir->eFlag == FSYS_FLAG_ABSROOT ||
    1444                 :            :                          pNewDir->eFlag == FSYS_FLAG_VOLUME )
    1445                 :          0 :                         return sal_True;
    1446                 :            :                 else
    1447                 :            :                 {
    1448                 :            :                         //? nError = ???
    1449 [ #  # ][ #  # ]:          0 :                         if ( FileStat( *pNewDir ).IsKind( FSYS_KIND_DIR ) )
    1450                 :          0 :                                 return sal_True;
    1451                 :            :                         else
    1452                 :            :                         {
    1453                 :            :                                 FSysFailOnErrorImpl();
    1454         [ #  # ]:          0 :                                 String aDirName(pNewDir->GetFull());
    1455 [ #  # ][ #  # ]:          0 :                                 rtl::OString bDirName(rtl::OUStringToOString(aDirName, osl_getThreadTextEncoding()));
                 [ #  # ]
    1456                 :            : 
    1457                 :            : #ifdef WIN32
    1458                 :            :                                 SetLastError(0);
    1459                 :            : #endif
    1460                 :          0 :                                 sal_Bool bResult = (0 == _mkdir(bDirName.getStr()));
    1461         [ #  # ]:          0 :                                 if ( !bResult )
    1462                 :            :                                 {
    1463                 :            : #ifdef WIN32
    1464                 :            :                                     ((DirEntry *)this)->SetError( Sys2SolarError_Impl(  GetLastError() ) );
    1465                 :            : #else
    1466         [ #  # ]:          0 :                                     ((DirEntry *)this)->SetError( Sys2SolarError_Impl(  errno ) );
    1467                 :            : #endif
    1468                 :            :                                 }
    1469                 :            : 
    1470         [ #  # ]:          0 :                                 return bResult;
    1471                 :            :                         }
    1472                 :            :                 }
    1473                 :            :         }
    1474                 :          0 :         return sal_True;
    1475                 :            : }
    1476                 :            : 
    1477                 :        660 : FSysError DirEntry::CopyTo( const DirEntry& rDest, FSysAction nActions ) const
    1478                 :            : {
    1479                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
    1480                 :            : 
    1481         [ -  + ]:        660 :         if ( FSYS_ACTION_COPYFILE != (nActions & FSYS_ACTION_COPYFILE) )
    1482                 :            : #ifdef UNX
    1483                 :            :     {
    1484                 :            :         // create hardlink
    1485                 :            :         HACK(redirection missing)
    1486 [ #  # ][ #  # ]:          0 :         rtl::OString aThis(rtl::OUStringToOString(GetFull(), osl_getThreadTextEncoding()));
         [ #  # ][ #  # ]
                 [ #  # ]
    1487 [ #  # ][ #  # ]:          0 :         rtl::OString aDest(rtl::OUStringToOString(rDest.GetFull(), osl_getThreadTextEncoding()));
         [ #  # ][ #  # ]
                 [ #  # ]
    1488         [ #  # ]:          0 :         if (link(aThis.getStr(), aDest.getStr()) == -1)
    1489         [ #  # ]:          0 :             return Sys2SolarError_Impl(  errno );
    1490                 :            :         else
    1491                 :          0 :             return FSYS_ERR_OK;
    1492                 :            :     }
    1493                 :            : #else
    1494                 :            :         return FSYS_ERR_NOTSUPPORTED;
    1495                 :            : #endif
    1496                 :            : 
    1497         [ +  - ]:        660 :         FileCopier fc(*this, rDest);
    1498 [ +  - ][ +  - ]:        660 :         return fc.Execute(nActions);
    1499                 :            : }
    1500                 :            : 
    1501                 :            : #if defined WNT || defined UNX
    1502                 :          0 : FSysError DirEntry::MoveTo( const DirEntry& rNewName ) const
    1503                 :            : {
    1504                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
    1505                 :            : 
    1506         [ #  # ]:          0 :     DirEntry aDest(rNewName);
    1507         [ #  # ]:          0 :     FileStat aDestStat(rNewName);
    1508 [ #  # ][ #  # ]:          0 :     if ( aDestStat.IsKind(FSYS_KIND_DIR ) )
    1509                 :            :     {
    1510 [ #  # ][ #  # ]:          0 :         aDest += DirEntry(rtl::OStringToOUString(aName, osl_getThreadTextEncoding()));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1511                 :            :     }
    1512 [ #  # ][ #  # ]:          0 :     if ( aDest.Exists() )
    1513                 :            :     {
    1514                 :          0 :         return FSYS_ERR_ALREADYEXISTS;
    1515                 :            :     }
    1516                 :            : 
    1517                 :            :         FSysFailOnErrorImpl();
    1518         [ #  # ]:          0 :         String aFrom( GetFull() );
    1519                 :            : 
    1520         [ #  # ]:          0 :         String aTo( aDest.GetFull() );
    1521                 :            : 
    1522 [ #  # ][ #  # ]:          0 :         rtl::OString bFrom(rtl::OUStringToOString(aFrom, osl_getThreadTextEncoding()));
                 [ #  # ]
    1523 [ #  # ][ #  # ]:          0 :         rtl::OString bTo(rtl::OUStringToOString(aTo, osl_getThreadTextEncoding()));
                 [ #  # ]
    1524                 :            : 
    1525                 :            : #ifdef WNT
    1526                 :            :         // MoveTo nun atomar
    1527                 :            :         SetLastError(0);
    1528                 :            : 
    1529                 :            :         DirEntry aFromDevice(rtl::OStringToOUString(bFrom, osl_getThreadTextEncoding()));
    1530                 :            :         DirEntry aToDevice(rtl::OStringToOUString(bTo,osl_getThreadTextEncoding()));
    1531                 :            :         aFromDevice.ToAbs();
    1532                 :            :         aToDevice.ToAbs();
    1533                 :            :         aFromDevice=aFromDevice.GetDevice();
    1534                 :            :         aToDevice=aToDevice.GetDevice();
    1535                 :            : 
    1536                 :            :         if (aFromDevice==aToDevice)
    1537                 :            :         {
    1538                 :            :             // same device, use intra-device-move with MoveFile
    1539                 :            :             MoveFile( bFrom.getStr(), bTo.getStr() );
    1540                 :            :             // Note: MoveFile is buggy for cross-device operations.
    1541                 :            :             // Return value is TRUE, even if the operation was only partially successful.
    1542                 :            :             // MoveFile has varying behavior between differing NT-versions.
    1543                 :            :             return Sys2SolarError_Impl( GetLastError() );
    1544                 :            :         }
    1545                 :            :         else
    1546                 :            :         {
    1547                 :            :             // Not the same device, use inter-device-move with copy/delete
    1548                 :            :             FSysError nCopyError = CopyTo(rNewName, FSYS_ACTION_COPYFILE);
    1549                 :            : 
    1550                 :            :             DirEntry aKill(rtl::OStringToOUString(bTo, osl_getThreadTextEncoding()));
    1551                 :            :             FileStat aKillStat(String(rtl::OStringToOUString(bTo, osl_getThreadTextEncoding())));
    1552                 :            :             if ( aKillStat.IsKind(FSYS_KIND_DIR ) )
    1553                 :            :             {
    1554                 :            :                 aKill += String(rtl::OStringToOUString(aName, osl_getThreadTextEncoding()));
    1555                 :            :             }
    1556                 :            : 
    1557                 :            :             if (nCopyError==FSYS_ERR_OK)
    1558                 :            :             {
    1559                 :            :                 if (Kill()==FSYS_ERR_OK)
    1560                 :            :                 {
    1561                 :            :                     return FSYS_ERR_OK;
    1562                 :            :                 }
    1563                 :            :                 else
    1564                 :            :                 {
    1565                 :            :                     aKill.Kill();
    1566                 :            :                     return FSYS_ERR_ACCESSDENIED;
    1567                 :            :                 }
    1568                 :            :             }
    1569                 :            :             else
    1570                 :            :             {
    1571                 :            :                 aKill.Kill();
    1572                 :            :                 return nCopyError;
    1573                 :            :             }
    1574                 :            :         }
    1575                 :            : #else
    1576                 :            :         // #68639#
    1577                 :            :         // on some nfs connections rename with from == to
    1578                 :            :         // leads to destruction of file
    1579 [ #  # ][ #  # ]:          0 :         if ( ( aFrom != aTo ) && ( 0 != rename( bFrom.getStr(), bTo.getStr() ) ) )
         [ #  # ][ #  # ]
    1580                 :            : #if !defined(UNX)
    1581                 :            :             return Sys2SolarError_Impl( GetLastError() );
    1582                 :            : #else
    1583                 :            :         {
    1584         [ #  # ]:          0 :                 if( errno == EXDEV )
    1585                 :            :                 // simple rename does not work cross device
    1586                 :            :                 {
    1587         [ #  # ]:          0 :                         FILE *fpIN  = fopen( bFrom.getStr(), "r" );
    1588         [ #  # ]:          0 :                         FILE *fpOUT = fopen( bTo.getStr(), "w" );
    1589 [ #  # ][ #  # ]:          0 :                         if( fpIN && fpOUT )
    1590                 :            :                         {
    1591                 :            :                                 char pBuf[ 16384 ];
    1592                 :          0 :                                 int nBytes, nWritten, nErr = 0;
    1593                 :          0 :                                 errno = 0;
    1594 [ #  # ][ #  # ]:          0 :                                 while( ( nBytes = fread( pBuf, 1, sizeof(pBuf), fpIN ) ) && ! nErr )
         [ #  # ][ #  # ]
    1595                 :            :                                 {
    1596         [ #  # ]:          0 :                                     nWritten = fwrite( pBuf, 1, nBytes, fpOUT );
    1597                 :            :                                     // Error in fwrite ?
    1598         [ #  # ]:          0 :                                     if( nWritten < nBytes )
    1599                 :            :                                     {
    1600                 :          0 :                                         nErr = errno;
    1601                 :          0 :                                         break;
    1602                 :            :                                     }
    1603                 :            :                                 }
    1604         [ #  # ]:          0 :                                 fclose( fpIN );
    1605         [ #  # ]:          0 :                                 fclose( fpOUT );
    1606         [ #  # ]:          0 :                                 if ( nErr )
    1607                 :            :                                 {
    1608                 :          0 :                                     unlink( bTo.getStr() );
    1609         [ #  # ]:          0 :                                     return Sys2SolarError_Impl( nErr );
    1610                 :            :                                 }
    1611                 :            :                                 else
    1612                 :            :                                 {
    1613                 :          0 :                                     unlink( bFrom.getStr() );
    1614                 :          0 :                                 }
    1615                 :            :                         }
    1616                 :            :                         else
    1617                 :            :                         {
    1618         [ #  # ]:          0 :                             if ( fpIN )
    1619         [ #  # ]:          0 :                                 fclose( fpIN );
    1620         [ #  # ]:          0 :                             if ( fpOUT )
    1621         [ #  # ]:          0 :                                 fclose( fpOUT );
    1622         [ #  # ]:          0 :                             return Sys2SolarError_Impl( EXDEV );
    1623                 :            :                         }
    1624                 :            :                 }
    1625                 :            :                 else
    1626                 :            :                 {
    1627         [ #  # ]:          0 :                     return Sys2SolarError_Impl( errno );
    1628                 :            :                 }
    1629                 :            :         }
    1630                 :            : #endif
    1631                 :            : #endif
    1632                 :            : 
    1633                 :            : // For the WNT case we always return already above, so avoid warning
    1634                 :            : // C4702: unreachable code. Possibly also in non-WNT cases we always
    1635                 :            : // return already above, but gcc apparently doesn't mind.
    1636                 :            : #ifndef WNT
    1637 [ #  # ][ #  # ]:          0 :         return ERRCODE_NONE;
         [ #  # ][ #  # ]
    1638                 :            : #endif
    1639                 :            : }
    1640                 :            : 
    1641                 :            : #endif
    1642                 :            : 
    1643                 :        761 : FSysError DirEntry::Kill(  FSysAction nActions ) const
    1644                 :            : {
    1645                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
    1646                 :            : 
    1647                 :        761 :         FSysError eError = FSYS_ERR_OK;
    1648                 :            :         FSysFailOnErrorImpl();
    1649                 :            : 
    1650                 :            :         // Terminate name string with two '0'
    1651         [ +  - ]:        761 :         String aTmpName( GetFull() );
    1652 [ +  - ][ +  - ]:        761 :         rtl::OString bTmpName(rtl::OUStringToOString(aTmpName, osl_getThreadTextEncoding()));
                 [ +  - ]
    1653                 :            : 
    1654         [ +  - ]:        761 :         char *pName = new char[bTmpName.getLength()+2];
    1655                 :        761 :         strcpy( pName, bTmpName.getStr() );
    1656                 :        761 :         pName[bTmpName.getLength()+1] = (char) 0;
    1657                 :            : 
    1658                 :            :         // delete read-only files as well
    1659         [ +  - ]:        761 :         sal_Bool isReadOnly = FileStat::GetReadOnlyFlag(*this);
    1660         [ -  + ]:        761 :         if (isReadOnly)
    1661                 :            :         {
    1662         [ #  # ]:          0 :             FileStat::SetReadOnlyFlag(*this, sal_False);
    1663                 :            :         }
    1664                 :            : 
    1665                 :            :         // directory?
    1666 [ +  - ][ +  - ]:        761 :         if ( FileStat( *this ).IsKind(FSYS_KIND_DIR) )
         [ +  - ][ -  + ]
    1667                 :            :         {
    1668                 :            :                 // Delete recursively?
    1669         [ #  # ]:          0 :                 if ( FSYS_ACTION_RECURSIVE == (nActions & FSYS_ACTION_RECURSIVE) )
    1670                 :            :                 {
    1671         [ #  # ]:          0 :                         Dir aDir( *this, FSYS_KIND_DIR|FSYS_KIND_FILE );
    1672 [ #  # ][ #  # ]:          0 :                         for ( sal_uInt16 n = 0; eError == FSYS_ERR_OK && n < aDir.Count(); ++n )
         [ #  # ][ #  # ]
    1673                 :            :                         {
    1674         [ #  # ]:          0 :                                 const DirEntry &rSubDir = aDir[n];
    1675                 :          0 :                                 DirEntryFlag flag = rSubDir.GetFlag();
    1676 [ #  # ][ #  # ]:          0 :                                 if ( flag != FSYS_FLAG_CURRENT && flag != FSYS_FLAG_PARENT )
    1677         [ #  # ]:          0 :                                         eError = rSubDir.Kill(nActions);
    1678         [ #  # ]:          0 :                         }
    1679                 :            :                 }
    1680                 :            : 
    1681                 :            :                 // remove Dir myself
    1682                 :            : #ifdef WIN32
    1683                 :            :                 SetLastError(0);
    1684                 :            : #endif
    1685 [ #  # ][ #  # ]:          0 :                 if ( eError == FSYS_ERR_OK && 0 != _rmdir( (char*) pName ) )
                 [ #  # ]
    1686                 :            :                 {
    1687                 :            :                         // Change CWD if deletion failed
    1688                 :            : #ifdef WIN32
    1689                 :            :                     eError = Sys2SolarError_Impl( GetLastError() );
    1690                 :            : #else
    1691         [ #  # ]:          0 :                     eError = Sys2SolarError_Impl( errno );
    1692                 :            : #endif
    1693         [ #  # ]:          0 :                         if ( eError )
    1694                 :            :                         {
    1695 [ #  # ][ #  # ]:          0 :                                 GetPath().SetCWD();
                 [ #  # ]
    1696                 :            : #ifdef WIN32
    1697                 :            :                                 SetLastError(0);
    1698                 :            : #endif
    1699         [ #  # ]:          0 :                                 if (_rmdir( (char*) pName) != 0)
    1700                 :            :                                 {
    1701                 :            : #ifdef WIN32
    1702                 :            :                                     eError = Sys2SolarError_Impl( GetLastError() );
    1703                 :            : #else
    1704         [ #  # ]:          0 :                                     eError = Sys2SolarError_Impl( errno );
    1705                 :            : #endif
    1706                 :            :                                 }
    1707                 :            :                                 else
    1708                 :            :                                 {
    1709                 :          0 :                                     eError = FSYS_ERR_OK;
    1710                 :            :                                 }
    1711                 :            :                         }
    1712                 :            :                 }
    1713                 :            :         }
    1714                 :            :         else
    1715                 :            :         {
    1716         [ -  + ]:        761 :                 if ( FSYS_ACTION_USERECYCLEBIN == (nActions & FSYS_ACTION_USERECYCLEBIN) )
    1717                 :            :                 {
    1718                 :            : #if defined(WNT)
    1719                 :            :                         SHFILEOPSTRUCT aOp;
    1720                 :            :                         aOp.hwnd = 0;
    1721                 :            :                         aOp.wFunc = FO_DELETE;
    1722                 :            :                         aOp.pFrom = pName;
    1723                 :            :                         aOp.pTo = 0;
    1724                 :            :                         aOp.fFlags = FOF_ALLOWUNDO|FOF_SILENT|FOF_NOCONFIRMATION;
    1725                 :            :                         aOp.hNameMappings = 0;
    1726                 :            :                         aOp.lpszProgressTitle = 0;
    1727                 :            :                         eError = Sys2SolarError_Impl( SHFileOperation( &aOp ) );
    1728                 :            : #else
    1729                 :          0 :                         eError = ERRCODE_IO_NOTSUPPORTED;
    1730                 :            : #endif
    1731                 :            :                 }
    1732                 :            :                 else
    1733                 :            :                 {
    1734                 :            : #ifdef WIN32
    1735                 :            :                     SetLastError(0);
    1736                 :            : #endif
    1737         [ -  + ]:        761 :                     if ( 0 != _unlink( (char*) pName ) )
    1738                 :            :                     {
    1739                 :            : #ifdef WIN32
    1740                 :            :                         eError = Sys2SolarError_Impl( GetLastError() );
    1741                 :            : #else
    1742         [ #  # ]:          0 :                         eError = Sys2SolarError_Impl( errno );
    1743                 :            : #endif
    1744                 :            :                     }
    1745                 :            :                     else
    1746                 :            :                     {
    1747                 :        761 :                         eError = ERRCODE_NONE;
    1748                 :            :                     }
    1749                 :            :                 }
    1750                 :            :         }
    1751                 :            : 
    1752                 :            :         // restore original read-only flag upon error
    1753 [ -  + ][ #  # ]:        761 :         if ( isReadOnly && (eError!=ERRCODE_NONE) )
    1754                 :            :         {
    1755         [ #  # ]:          0 :             FileStat::SetReadOnlyFlag(*this, isReadOnly);
    1756                 :            :         }
    1757                 :            : 
    1758         [ +  - ]:        761 :         delete[] pName;
    1759         [ +  - ]:        761 :         return eError;
    1760                 :            : }
    1761                 :            : 
    1762                 :            : /** Check if rSubEntry is (in)directly beneath *this */
    1763                 :          0 : sal_Bool DirEntry::Contains( const DirEntry &rSubEntry ) const
    1764                 :            : {
    1765                 :            :     DBG_ASSERT( IsAbs() && rSubEntry.IsAbs(), "must be absolute entries" );
    1766                 :            : 
    1767                 :          0 :         sal_uInt16 nThisLevel = Level();
    1768                 :          0 :     sal_uInt16 nSubLevel = rSubEntry.Level();
    1769         [ #  # ]:          0 :     if ( nThisLevel < nSubLevel )
    1770                 :            :     {
    1771         [ #  # ]:          0 :         for ( ; nThisLevel; --nThisLevel, --nSubLevel )
    1772         [ #  # ]:          0 :             if ( (*this)[nThisLevel-1] != rSubEntry[nSubLevel-1] )
    1773                 :          0 :                 return sal_False;
    1774                 :          0 :         return sal_True;
    1775                 :            :     }
    1776                 :          0 :     return sal_False;
    1777                 :            : }
    1778                 :            : 
    1779                 :          0 : sal_uInt16 DirEntry::Level() const
    1780                 :            : {
    1781                 :            :     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
    1782                 :            : 
    1783                 :          0 :     sal_uInt16 nLevel = 0;
    1784                 :          0 :     const DirEntry *pRes = this;
    1785         [ #  # ]:          0 :     while ( pRes )
    1786                 :            :     {
    1787                 :          0 :         pRes = pRes->pParent;
    1788                 :          0 :         nLevel++;
    1789                 :            :     }
    1790                 :            : 
    1791                 :          0 :     return nLevel;
    1792                 :            : }
    1793                 :            : 
    1794                 :     223622 : sal_Bool DirEntry::IsValid() const
    1795                 :            : {
    1796                 :     223622 :         return (nError == FSYS_ERR_OK);
    1797                 :            : }
    1798                 :            : 
    1799                 :            : #if defined(DBG_UTIL)
    1800                 :            : void FSysTest()
    1801                 :            : {
    1802                 :            : }
    1803                 :            : #endif
    1804                 :            : 
    1805                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10