LCOV - code coverage report
Current view: top level - tools/source/stream - strmunx.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 156 239 65.3 %
Date: 2012-08-25 Functions: 21 25 84.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 120 332 36.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                 :            : #include <stdio.h>
      21                 :            : #include <string.h>
      22                 :            : #include <sys/stat.h>
      23                 :            : #include <fcntl.h>
      24                 :            : #include <errno.h>
      25                 :            : #include <unistd.h>
      26                 :            : #include <limits.h>
      27                 :            : 
      28                 :            : #include <tools/debug.hxx>
      29                 :            : #include <tools/fsys.hxx>
      30                 :            : #include <tools/stream.hxx>
      31                 :            : #include <vector>
      32                 :            : 
      33                 :            : #include <osl/mutex.hxx>
      34                 :            : #include <osl/thread.h> // osl_getThreadTextEncoding
      35                 :            : 
      36                 :            : // class FileBase
      37                 :            : #include <osl/file.hxx>
      38                 :            : #include <osl/detail/file.h>
      39                 :            : #include <rtl/instance.hxx>
      40                 :            : #include <rtl/strbuf.hxx>
      41                 :            : 
      42                 :            : using namespace osl;
      43                 :            : 
      44                 :            : // InternalLock ----------------------------------------------------------------
      45                 :            : 
      46                 :            : namespace { struct LockMutex : public rtl::Static< osl::Mutex, LockMutex > {}; }
      47                 :            : 
      48                 :            : class InternalStreamLock
      49                 :            : {
      50                 :            :     sal_Size           m_nStartPos;
      51                 :            :     sal_Size           m_nEndPos;
      52                 :            :     SvFileStream*      m_pStream;
      53                 :            :     osl::DirectoryItem m_aItem;
      54                 :            : 
      55                 :            :     InternalStreamLock( sal_Size, sal_Size, SvFileStream* );
      56                 :            :     ~InternalStreamLock();
      57                 :            : public:
      58                 :            :     static sal_Bool LockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* );
      59                 :            :     static void UnlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* );
      60                 :            : };
      61                 :            : 
      62                 :            : typedef ::std::vector< InternalStreamLock* > InternalStreamLockList;
      63                 :            : 
      64                 :            : namespace { struct LockList : public rtl::Static< InternalStreamLockList, LockList > {}; }
      65                 :            : 
      66                 :          0 : InternalStreamLock::InternalStreamLock(
      67                 :            :     sal_Size nStart,
      68                 :            :     sal_Size nEnd,
      69                 :            :     SvFileStream* pStream ) :
      70                 :            :         m_nStartPos( nStart ),
      71                 :            :         m_nEndPos( nEnd ),
      72                 :          0 :         m_pStream( pStream )
      73                 :            : {
      74 [ #  # ][ #  # ]:          0 :     osl::DirectoryItem::get( m_pStream->GetFileName(), m_aItem );
      75 [ #  # ][ #  # ]:          0 :     LockList::get().push_back( this );
      76                 :            : #if OSL_DEBUG_LEVEL > 1
      77                 :            :     rtl::OString aFileName(rtl::OUStringToOString(m_pStream->GetFileName(),
      78                 :            :                                                   osl_getThreadTextEncoding()));
      79                 :            :     fprintf( stderr, "locked %s", aFileName.getStr() );
      80                 :            :     if( m_nStartPos || m_nEndPos )
      81                 :            :         fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos );
      82                 :            :     fprintf( stderr, "\n" );
      83                 :            : #endif
      84                 :          0 : }
      85                 :            : 
      86                 :          0 : InternalStreamLock::~InternalStreamLock()
      87                 :            : {
      88 [ #  # ][ #  # ]:          0 :     for ( InternalStreamLockList::iterator it = LockList::get().begin();
                 [ #  # ]
      89         [ #  # ]:          0 :           it != LockList::get().end();
      90                 :            :           ++it
      91                 :            :     ) {
      92         [ #  # ]:          0 :         if ( this == *it ) {
      93 [ #  # ][ #  # ]:          0 :             LockList::get().erase( it );
      94                 :          0 :             break;
      95                 :            :         }
      96                 :            :     }
      97                 :            : #if OSL_DEBUG_LEVEL > 1
      98                 :            :     rtl::OString aFileName(rtl::OUStringToOString(m_pStream->GetFileName(),
      99                 :            :                                                   osl_getThreadTextEncoding()));
     100                 :            :     fprintf( stderr, "unlocked %s", aFileName.getStr() );
     101                 :            :     if( m_nStartPos || m_nEndPos )
     102                 :            :         fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos );
     103                 :            :     fprintf( stderr, "\n" );
     104                 :            : #endif
     105                 :          0 : }
     106                 :            : 
     107                 :       1626 : sal_Bool InternalStreamLock::LockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
     108                 :            : {
     109 [ +  - ][ +  - ]:       1626 :     osl::MutexGuard aGuard( LockMutex::get() );
     110                 :       1626 :     osl::DirectoryItem aItem;
     111 [ +  - ][ +  - ]:       1626 :     if (osl::DirectoryItem::get( pStream->GetFileName(), aItem) != osl::FileBase::E_None )
                 [ +  - ]
     112                 :            :     {
     113                 :            :         SAL_INFO("tools", "Failed to lookup stream for locking");
     114                 :       1626 :         return sal_True;
     115                 :            :     }
     116                 :            : 
     117                 :          0 :     osl::FileStatus aStatus( osl_FileStatus_Mask_Type );
     118 [ #  # ][ #  # ]:          0 :     if ( aItem.getFileStatus( aStatus ) != osl::FileBase::E_None )
     119                 :            :     {
     120                 :            :         SAL_INFO("tools", "Failed to stat stream for locking");
     121                 :          0 :         return sal_True;
     122                 :            :     }
     123 [ #  # ][ #  # ]:          0 :     if( aStatus.getFileType() == osl::FileStatus::Directory )
     124                 :          0 :         return sal_True;
     125                 :            : 
     126                 :          0 :     InternalStreamLock* pLock = NULL;
     127         [ #  # ]:          0 :     InternalStreamLockList &rLockList = LockList::get();
     128         [ #  # ]:          0 :     for( size_t i = 0; i < rLockList.size(); ++i )
     129                 :            :     {
     130                 :          0 :         pLock = rLockList[ i ];
     131 [ #  # ][ #  # ]:          0 :         if( aItem.isIdenticalTo( pLock->m_aItem ) )
     132                 :            :         {
     133                 :          0 :             sal_Bool bDenyByOptions = sal_False;
     134                 :          0 :             StreamMode nLockMode = pLock->m_pStream->GetStreamMode();
     135                 :          0 :             StreamMode nNewMode = pStream->GetStreamMode();
     136                 :            : 
     137         [ #  # ]:          0 :             if( nLockMode & STREAM_SHARE_DENYALL )
     138                 :          0 :                 bDenyByOptions = sal_True;
     139 [ #  # ][ #  # ]:          0 :             else if( ( nLockMode & STREAM_SHARE_DENYWRITE ) &&
     140                 :            :                      ( nNewMode & STREAM_WRITE ) )
     141                 :          0 :                 bDenyByOptions = sal_True;
     142 [ #  # ][ #  # ]:          0 :             else if( ( nLockMode & STREAM_SHARE_DENYREAD ) &&
     143                 :            :                      ( nNewMode & STREAM_READ ) )
     144                 :          0 :                 bDenyByOptions = sal_True;
     145                 :            : 
     146         [ #  # ]:          0 :             if( bDenyByOptions )
     147                 :            :             {
     148 [ #  # ][ #  # ]:          0 :                 if( pLock->m_nStartPos == 0 && pLock->m_nEndPos == 0 ) // whole file is already locked
     149                 :          0 :                     return sal_False;
     150 [ #  # ][ #  # ]:          0 :                 if( nStart == 0 && nEnd == 0) // cannot lock whole file
     151                 :          0 :                     return sal_False;
     152                 :            : 
     153 [ #  # ][ #  # ]:          0 :                 if( ( nStart < pLock->m_nStartPos && nEnd > pLock->m_nStartPos ) ||
         [ #  # ][ #  # ]
     154                 :            :                     ( nStart < pLock->m_nEndPos && nEnd > pLock->m_nEndPos ) )
     155                 :          0 :                     return sal_False;
     156                 :            :             }
     157                 :            :         }
     158                 :            :     }
     159                 :            :     // hint: new InternalStreamLock() adds the entry to the global list
     160 [ #  # ][ #  # ]:          0 :     pLock  = new InternalStreamLock( nStart, nEnd, pStream );
     161 [ +  - ][ +  - ]:       1626 :     return sal_True;
     162                 :            : }
     163                 :            : 
     164                 :      14687 : void InternalStreamLock::UnlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
     165                 :            : {
     166 [ +  - ][ +  - ]:      14687 :     osl::MutexGuard aGuard( LockMutex::get() );
     167                 :      14687 :     InternalStreamLock* pLock = NULL;
     168         [ +  - ]:      14687 :     InternalStreamLockList &rLockList = LockList::get();
     169 [ +  - ][ +  - ]:      14687 :     if( nStart == 0 && nEnd == 0 )
     170                 :            :     {
     171                 :            :         // nStart & nEnd = 0, so delete all locks
     172         [ -  + ]:      14687 :         for( size_t i = 0; i < rLockList.size(); ++i )
     173                 :            :         {
     174         [ #  # ]:          0 :             if( ( pLock = rLockList[ i ] )->m_pStream == pStream )
     175                 :            :             {
     176                 :            :                 // hint: delete will remove pLock from the global list
     177 [ #  # ][ #  # ]:          0 :                 delete pLock;
     178                 :          0 :                 i--;
     179                 :            :             }
     180                 :            :         }
     181                 :            :         return;
     182                 :            :     }
     183         [ #  # ]:          0 :     for( size_t i = 0; i < rLockList.size(); ++i )
     184                 :            :     {
     185 [ #  # ][ #  # ]:          0 :         if (  ( pLock = rLockList[ i ] )->m_pStream == pStream
         [ #  # ][ #  # ]
     186                 :            :            && nStart == pLock->m_nStartPos
     187                 :            :            && nEnd == pLock->m_nEndPos
     188                 :            :         ) {
     189                 :            :             // hint: delete will remove pLock from the global list
     190 [ #  # ][ #  # ]:          0 :             delete pLock;
     191                 :            :             return;
     192                 :            :         }
     193 [ +  - ][ -  + ]:      14687 :     }
     194                 :            : }
     195                 :            : 
     196                 :            : // StreamData ------------------------------------------------------------------
     197                 :            : 
     198                 :            : class StreamData
     199                 :            : {
     200                 :            : public:
     201                 :            :     oslFileHandle rHandle;
     202                 :            : 
     203                 :       8801 :     StreamData() : rHandle( 0 ) { }
     204                 :            : };
     205                 :            : 
     206                 :          0 : static sal_uInt32 GetSvError( int nErrno )
     207                 :            : {
     208                 :            :     static struct { int nErr; sal_uInt32 sv; } errArr[] =
     209                 :            :     {
     210                 :            :         { 0,            SVSTREAM_OK },
     211                 :            :         { EACCES,       SVSTREAM_ACCESS_DENIED },
     212                 :            :         { EBADF,        SVSTREAM_INVALID_HANDLE },
     213                 :            : #if defined(RS6000) || defined(NETBSD) || \
     214                 :            :     defined(FREEBSD) || defined(MACOSX) || defined(OPENBSD) || \
     215                 :            :     defined(__FreeBSD_kernel__) || defined (AIX) || defined(DRAGONFLY) || \
     216                 :            :     defined(IOS)
     217                 :            :         { EDEADLK,      SVSTREAM_LOCKING_VIOLATION },
     218                 :            : #else
     219                 :            :         { EDEADLOCK,    SVSTREAM_LOCKING_VIOLATION },
     220                 :            : #endif
     221                 :            :         { EINVAL,       SVSTREAM_INVALID_PARAMETER },
     222                 :            :         { EMFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     223                 :            :         { ENFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     224                 :            :         { ENOENT,       SVSTREAM_FILE_NOT_FOUND },
     225                 :            :         { EPERM,        SVSTREAM_ACCESS_DENIED },
     226                 :            :         { EROFS,        SVSTREAM_ACCESS_DENIED },
     227                 :            :         { EAGAIN,       SVSTREAM_LOCKING_VIOLATION },
     228                 :            :         { EISDIR,       SVSTREAM_PATH_NOT_FOUND },
     229                 :            :         { ELOOP,        SVSTREAM_PATH_NOT_FOUND },
     230                 :            : #if !defined(RS6000) && !defined(NETBSD) && !defined (FREEBSD) && \
     231                 :            :     !defined(MACOSX) && !defined(OPENBSD) && !defined(__FreeBSD_kernel__) && \
     232                 :            :     !defined(DRAGONFLY)
     233                 :            :         { EMULTIHOP,    SVSTREAM_PATH_NOT_FOUND },
     234                 :            :         { ENOLINK,      SVSTREAM_PATH_NOT_FOUND },
     235                 :            : #endif
     236                 :            :         { ENOTDIR,      SVSTREAM_PATH_NOT_FOUND },
     237                 :            :         { ETXTBSY,      SVSTREAM_ACCESS_DENIED  },
     238                 :            :         { EEXIST,       SVSTREAM_CANNOT_MAKE    },
     239                 :            :         { ENOSPC,       SVSTREAM_DISK_FULL      },
     240                 :            :         { (int)0xFFFF,  SVSTREAM_GENERALERROR }
     241                 :            :     };
     242                 :            : 
     243                 :          0 :     sal_uInt32 nRetVal = SVSTREAM_GENERALERROR; // default error
     244                 :          0 :     int i=0;
     245         [ #  # ]:          0 :     do
     246                 :            :     {
     247         [ #  # ]:          0 :         if ( errArr[i].nErr == nErrno )
     248                 :            :         {
     249                 :          0 :             nRetVal = errArr[i].sv;
     250                 :          0 :             break;
     251                 :            :         }
     252                 :          0 :         ++i;
     253                 :            :     }
     254                 :            :     while( errArr[i].nErr != 0xFFFF );
     255                 :          0 :     return nRetVal;
     256                 :            : }
     257                 :            : 
     258                 :        443 : static sal_uInt32 GetSvError( oslFileError nErrno )
     259                 :            : {
     260                 :            :     static struct { oslFileError nErr; sal_uInt32 sv; } errArr[] =
     261                 :            :     {
     262                 :            :         { osl_File_E_None,        SVSTREAM_OK },
     263                 :            :         { osl_File_E_ACCES,       SVSTREAM_ACCESS_DENIED },
     264                 :            :         { osl_File_E_BADF,        SVSTREAM_INVALID_HANDLE },
     265                 :            :         { osl_File_E_DEADLK,      SVSTREAM_LOCKING_VIOLATION },
     266                 :            :         { osl_File_E_INVAL,       SVSTREAM_INVALID_PARAMETER },
     267                 :            :         { osl_File_E_MFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     268                 :            :         { osl_File_E_NFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     269                 :            :         { osl_File_E_NOENT,       SVSTREAM_FILE_NOT_FOUND },
     270                 :            :         { osl_File_E_PERM,        SVSTREAM_ACCESS_DENIED },
     271                 :            :         { osl_File_E_ROFS,        SVSTREAM_ACCESS_DENIED },
     272                 :            :         { osl_File_E_AGAIN,       SVSTREAM_LOCKING_VIOLATION },
     273                 :            :         { osl_File_E_ISDIR,       SVSTREAM_PATH_NOT_FOUND },
     274                 :            :         { osl_File_E_LOOP,        SVSTREAM_PATH_NOT_FOUND },
     275                 :            :         { osl_File_E_MULTIHOP,    SVSTREAM_PATH_NOT_FOUND },
     276                 :            :         { osl_File_E_NOLINK,      SVSTREAM_PATH_NOT_FOUND },
     277                 :            :         { osl_File_E_NOTDIR,      SVSTREAM_PATH_NOT_FOUND },
     278                 :            :         { osl_File_E_EXIST,       SVSTREAM_CANNOT_MAKE    },
     279                 :            :         { osl_File_E_NOSPC,       SVSTREAM_DISK_FULL      },
     280                 :            :         { (oslFileError)0xFFFF,   SVSTREAM_GENERALERROR }
     281                 :            :     };
     282                 :            : 
     283                 :        443 :     sal_uInt32 nRetVal = SVSTREAM_GENERALERROR; // default error
     284                 :        443 :     int i=0;
     285         [ +  - ]:       3086 :     do
     286                 :            :     {
     287         [ +  + ]:       3529 :         if ( errArr[i].nErr == nErrno )
     288                 :            :         {
     289                 :        443 :             nRetVal = errArr[i].sv;
     290                 :        443 :             break;
     291                 :            :         }
     292                 :       3086 :         ++i;
     293                 :            :     }
     294                 :            :     while( errArr[i].nErr != (oslFileError)0xFFFF );
     295                 :        443 :     return nRetVal;
     296                 :            : }
     297                 :            : 
     298         [ +  - ]:       8228 : SvFileStream::SvFileStream( const String& rFileName, StreamMode nOpenMode )
     299                 :            : {
     300                 :       8228 :     bIsOpen             = sal_False;
     301                 :       8228 :     nLockCounter        = 0;
     302                 :       8228 :     bIsWritable         = sal_False;
     303         [ +  - ]:       8228 :     pInstanceData       = new StreamData;
     304                 :            : 
     305         [ +  - ]:       8228 :     SetBufferSize( 1024 );
     306                 :            :     // convert URL to SystemPath, if necessary
     307                 :       8228 :     ::rtl::OUString aSystemFileName;
     308 [ +  - ][ +  + ]:       8228 :     if( FileBase::getSystemPathFromFileURL( rFileName , aSystemFileName )
                 [ +  - ]
     309                 :            :         != FileBase::E_None )
     310                 :            :     {
     311         [ +  - ]:       2147 :         aSystemFileName = rFileName;
     312                 :            :     }
     313 [ +  - ][ +  - ]:       8228 :     Open( aSystemFileName, nOpenMode );
                 [ +  - ]
     314                 :       8228 : }
     315                 :            : 
     316         [ +  - ]:        573 : SvFileStream::SvFileStream()
     317                 :            : {
     318                 :        573 :     bIsOpen             = sal_False;
     319                 :        573 :     nLockCounter        = 0;
     320                 :        573 :     bIsWritable         = sal_False;
     321         [ +  - ]:        573 :     pInstanceData       = new StreamData;
     322         [ +  - ]:        573 :     SetBufferSize( 1024 );
     323                 :        573 : }
     324                 :            : 
     325         [ +  - ]:       7820 : SvFileStream::~SvFileStream()
     326                 :            : {
     327         [ +  - ]:       7820 :     Close();
     328                 :            : 
     329         [ +  - ]:       7820 :     InternalStreamLock::UnlockFile( 0, 0, this );
     330                 :            : 
     331         [ +  - ]:       7820 :     if (pInstanceData)
     332                 :       7820 :         delete pInstanceData;
     333         [ -  + ]:      11318 : }
     334                 :            : 
     335                 :       2640 : sal_uInt32 SvFileStream::GetFileHandle() const
     336                 :            : {
     337                 :            :     sal_IntPtr handle;
     338 [ +  - ][ +  - ]:       2640 :     if (osl_getFileOSHandle(pInstanceData->rHandle, &handle) == osl_File_E_None)
     339                 :       2640 :         return (sal_uInt32) handle;
     340                 :            :     else
     341                 :       2640 :         return (sal_uInt32) -1;
     342                 :            : }
     343                 :            : 
     344                 :          0 : sal_uInt16 SvFileStream::IsA() const
     345                 :            : {
     346                 :          0 :     return ID_FILESTREAM;
     347                 :            : }
     348                 :            : 
     349                 :     474656 : sal_Size SvFileStream::GetData( void* pData, sal_Size nSize )
     350                 :            : {
     351                 :            : #ifdef DBG_UTIL
     352                 :            :     rtl::OStringBuffer aTraceStr(
     353                 :            :         RTL_CONSTASCII_STRINGPARAM("SvFileStream::GetData(): "));
     354                 :            :     aTraceStr.append(static_cast<sal_Int64>(nSize));
     355                 :            :     aTraceStr.append(RTL_CONSTASCII_STRINGPARAM(" Bytes from "));
     356                 :            :     aTraceStr.append(rtl::OUStringToOString(aFilename,
     357                 :            :         osl_getThreadTextEncoding()));
     358                 :            :     OSL_TRACE("%s", aTraceStr.getStr());
     359                 :            : #endif
     360                 :            : 
     361                 :     474656 :     sal_uInt64 nRead = 0;
     362         [ +  - ]:     474656 :     if ( IsOpen() )
     363                 :            :     {
     364         [ +  - ]:     474656 :         oslFileError rc = osl_readFile(pInstanceData->rHandle,pData,(sal_uInt64)nSize,&nRead);
     365         [ -  + ]:     474656 :         if ( rc != osl_File_E_None )
     366                 :            :         {
     367         [ #  # ]:          0 :             SetError( ::GetSvError( rc ));
     368                 :          0 :             return -1;
     369                 :            :         }
     370                 :            :     }
     371                 :     474656 :     return (sal_Size)nRead;
     372                 :            : }
     373                 :            : 
     374                 :      36820 : sal_Size SvFileStream::PutData( const void* pData, sal_Size nSize )
     375                 :            : {
     376                 :            : #ifdef DBG_UTIL
     377                 :            :     rtl::OStringBuffer aTraceStr(
     378                 :            :         RTL_CONSTASCII_STRINGPARAM("SvFileStream::PutData(): "));
     379                 :            :     aTraceStr.append(static_cast<sal_Int64>(nSize));
     380                 :            :     aTraceStr.append(RTL_CONSTASCII_STRINGPARAM(" Bytes to "));
     381                 :            :     aTraceStr.append(rtl::OUStringToOString(aFilename,
     382                 :            :         osl_getThreadTextEncoding()));
     383                 :            :     OSL_TRACE("%s", aTraceStr.getStr());
     384                 :            : #endif
     385                 :            : 
     386                 :      36820 :     sal_uInt64 nWrite = 0;
     387         [ +  - ]:      36820 :     if ( IsOpen() )
     388                 :            :     {
     389         [ +  - ]:      36820 :         oslFileError rc = osl_writeFile(pInstanceData->rHandle,pData,(sal_uInt64)nSize,&nWrite);
     390         [ -  + ]:      36820 :         if ( rc != osl_File_E_None )
     391                 :            :         {
     392         [ #  # ]:          0 :             SetError( ::GetSvError( rc ) );
     393                 :          0 :             return -1;
     394                 :            :         }
     395         [ -  + ]:      36820 :         else if( !nWrite )
     396         [ #  # ]:          0 :             SetError( SVSTREAM_DISK_FULL );
     397                 :            :     }
     398                 :      36820 :     return (sal_Size)nWrite;
     399                 :            : }
     400                 :            : 
     401                 :     582338 : sal_Size SvFileStream::SeekPos( sal_Size nPos )
     402                 :            : {
     403         [ +  - ]:     582338 :     if ( IsOpen() )
     404                 :            :     {
     405                 :            :         oslFileError rc;
     406                 :            :         sal_uInt64 nNewPos;
     407         [ +  + ]:     582338 :         if ( nPos != STREAM_SEEK_TO_END )
     408         [ +  - ]:     578604 :             rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_Absolut, nPos );
     409                 :            :         else
     410         [ +  - ]:       3734 :             rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_End, 0 );
     411                 :            : 
     412         [ -  + ]:     582338 :         if ( rc != osl_File_E_None )
     413                 :            :         {
     414         [ #  # ]:          0 :             SetError( SVSTREAM_SEEK_ERROR );
     415                 :          0 :             return 0L;
     416                 :            :         }
     417         [ +  - ]:     582338 :         rc = osl_getFilePos( pInstanceData->rHandle, &nNewPos );
     418                 :     582338 :         return (sal_Size) nNewPos;
     419                 :            :     }
     420                 :          0 :     SetError( SVSTREAM_GENERALERROR );
     421                 :     582338 :     return 0L;
     422                 :            : }
     423                 :            : 
     424                 :       2432 : void SvFileStream::FlushData()
     425                 :            : {
     426                 :            :     // does not exist locally
     427                 :       2432 : }
     428                 :            : 
     429                 :       7848 : sal_Bool SvFileStream::LockRange( sal_Size nByteOffset, sal_Size nBytes )
     430                 :            : {
     431                 :       7848 :     int nLockMode = 0;
     432                 :            : 
     433         [ -  + ]:       7848 :     if ( ! IsOpen() )
     434                 :          0 :         return sal_False;
     435                 :            : 
     436         [ +  + ]:       7848 :     if ( eStreamMode & STREAM_SHARE_DENYALL )
     437                 :            :         {
     438         [ +  - ]:        221 :         if (bIsWritable)
     439                 :        221 :             nLockMode = F_WRLCK;
     440                 :            :         else
     441                 :          0 :             nLockMode = F_RDLCK;
     442                 :            :         }
     443                 :            : 
     444         [ -  + ]:       7848 :     if ( eStreamMode & STREAM_SHARE_DENYREAD )
     445                 :            :         {
     446         [ #  # ]:          0 :         if (bIsWritable)
     447                 :          0 :             nLockMode = F_WRLCK;
     448                 :            :         else
     449                 :            :         {
     450                 :          0 :             SetError(SVSTREAM_LOCKING_VIOLATION);
     451                 :          0 :             return sal_False;
     452                 :            :         }
     453                 :            :         }
     454                 :            : 
     455         [ +  + ]:       7848 :     if ( eStreamMode & STREAM_SHARE_DENYWRITE )
     456                 :            :         {
     457         [ +  + ]:       4444 :         if (bIsWritable)
     458                 :       1405 :             nLockMode = F_WRLCK;
     459                 :            :         else
     460                 :       3039 :             nLockMode = F_RDLCK;
     461                 :            :         }
     462                 :            : 
     463         [ +  + ]:       7848 :     if (!nLockMode)
     464                 :       6222 :         return sal_True;
     465                 :            : 
     466         [ -  + ]:       1626 :     if( ! InternalStreamLock::LockFile( nByteOffset, nByteOffset+nBytes, this ) )
     467                 :            :     {
     468                 :            : #if OSL_DEBUG_LEVEL > 1
     469                 :            :         fprintf( stderr, "InternalLock on %s [ %ld ... %ld ] failed\n",
     470                 :            :                  rtl::OUStringToOString(aFilename, osl_getThreadTextEncoding()).getStr(), nByteOffset, nByteOffset+nBytes );
     471                 :            : #endif
     472                 :          0 :         return sal_False;
     473                 :            :     }
     474                 :            : 
     475                 :       7848 :     return sal_True;
     476                 :            : }
     477                 :            : 
     478                 :      17431 : sal_Bool SvFileStream::UnlockRange( sal_Size nByteOffset, sal_Size nBytes )
     479                 :            : {
     480         [ +  + ]:      17431 :     if ( ! IsOpen() )
     481                 :      10564 :         return sal_False;
     482                 :            : 
     483                 :       6867 :     InternalStreamLock::UnlockFile( nByteOffset, nByteOffset+nBytes, this );
     484                 :            : 
     485                 :      17431 :     return sal_True;
     486                 :            : }
     487                 :            : 
     488                 :       7848 : sal_Bool SvFileStream::LockFile()
     489                 :            : {
     490                 :       7848 :   return LockRange( 0UL, 0UL );
     491                 :            : }
     492                 :            : 
     493                 :      17431 : sal_Bool SvFileStream::UnlockFile()
     494                 :            : {
     495                 :      17431 :     return UnlockRange( 0UL, 0UL );
     496                 :            : }
     497                 :            : 
     498                 :       8291 : void SvFileStream::Open( const String& rFilename, StreamMode nOpenMode )
     499                 :            : {
     500                 :            :     sal_uInt32 uFlags;
     501                 :            :     oslFileHandle nHandleTmp;
     502                 :            : 
     503         [ +  - ]:       8291 :     Close();
     504                 :       8291 :     errno = 0;
     505                 :       8291 :     eStreamMode = nOpenMode;
     506                 :       8291 :     eStreamMode &= ~STREAM_TRUNC; // don't truncat on reopen
     507                 :            : 
     508                 :            : //    !!! NoOp: use ToAbs()
     509                 :            : //    !!! DirEntry aDirEntry( rFilename );
     510                 :            : //    !!! aFilename = aDirEntry.GetFull();
     511         [ +  - ]:       8291 :     aFilename = rFilename;
     512 [ +  - ][ +  - ]:       8291 :     rtl::OString aLocalFilename(rtl::OUStringToOString(aFilename, osl_getThreadTextEncoding()));
                 [ +  - ]
     513                 :            : 
     514                 :            : #ifdef DBG_UTIL
     515                 :            :     rtl::OStringBuffer aTraceStr(RTL_CONSTASCII_STRINGPARAM(
     516                 :            :         "SvFileStream::Open(): "));
     517                 :            :     aTraceStr.append(aLocalFilename);
     518                 :            :     OSL_TRACE( "%s", aTraceStr.getStr() );
     519                 :            : #endif
     520                 :            : 
     521                 :       8291 :     rtl::OUString aFileURL;
     522                 :       8291 :     osl::DirectoryItem aItem;
     523                 :       8291 :     osl::FileStatus aStatus( osl_FileStatus_Mask_Type | osl_FileStatus_Mask_LinkTargetURL );
     524                 :            : 
     525                 :            :     // FIXME: we really need to switch to a pure URL model ...
     526 [ +  - ][ +  + ]:       8291 :     if ( osl::File::getFileURLFromSystemPath( aFilename, aFileURL ) != osl::FileBase::E_None )
                 [ +  - ]
     527         [ +  - ]:          5 :         aFileURL = aFilename;
     528         [ +  - ]:       8291 :     bool bStatValid = ( osl::DirectoryItem::get( aFileURL, aItem) == osl::FileBase::E_None &&
     529 [ +  + ][ +  - ]:       8291 :                         aItem.getFileStatus( aStatus ) == osl::FileBase::E_None );
                 [ +  - ]
     530                 :            : 
     531                 :            :     // SvFileStream can't open a directory
     532 [ +  + ][ +  - ]:       8291 :     if( bStatValid && aStatus.getFileType() == osl::FileStatus::Directory )
         [ -  + ][ -  + ]
     533                 :            :     {
     534         [ #  # ]:          0 :         SetError( ::GetSvError( EISDIR ) );
     535                 :       8291 :         return;
     536                 :            :     }
     537                 :            : 
     538         [ +  + ]:       8291 :     if ( !( nOpenMode & STREAM_WRITE ) )
     539                 :       6384 :         uFlags = osl_File_OpenFlag_Read;
     540         [ +  + ]:       1907 :     else if ( !( nOpenMode & STREAM_READ ) )
     541                 :       1505 :         uFlags = osl_File_OpenFlag_Write;
     542                 :            :     else
     543                 :        402 :         uFlags = osl_File_OpenFlag_Read | osl_File_OpenFlag_Write;
     544                 :            : 
     545                 :            :     // Fix (MDA, 18.01.95): Don't open with O_CREAT upon RD_ONLY
     546                 :            :     // Important for Read-Only-Filesystems (e.g,  CDROM)
     547 [ +  + ][ +  + ]:       8291 :     if ( (!( nOpenMode & STREAM_NOCREATE )) && ( uFlags != osl_File_OpenFlag_Read ) )
     548                 :       1907 :         uFlags |= osl_File_OpenFlag_Create;
     549         [ +  + ]:       8291 :     if ( nOpenMode & STREAM_TRUNC )
     550                 :       1601 :         uFlags |= osl_File_OpenFlag_Trunc;
     551                 :            : 
     552                 :       8291 :     uFlags |= osl_File_OpenFlag_NoExcl | osl_File_OpenFlag_NoLock;
     553                 :            : 
     554         [ +  + ]:       8291 :     if ( nOpenMode & STREAM_WRITE)
     555                 :            :     {
     556         [ -  + ]:       1907 :         if ( nOpenMode & STREAM_COPY_ON_SYMLINK )
     557                 :            :         {
     558 [ #  # ][ #  # ]:          0 :             if ( bStatValid && aStatus.getFileType() == osl::FileStatus::Link &&
           [ #  #  #  # ]
                 [ #  # ]
     559 [ #  # ][ #  # ]:          0 :                  aStatus.getLinkTargetURL().getLength() > 0 )
                 [ #  # ]
     560                 :            :             {
     561                 :            :                 // delete the symbolic link, and replace it with the contents of the link
     562 [ #  # ][ #  # ]:          0 :                 if (osl::File::remove( aFileURL ) == osl::FileBase::E_None )
     563                 :            :                 {
     564 [ #  # ][ #  # ]:          0 :                     File::copy( aStatus.getLinkTargetURL(), aFileURL );
     565                 :            : #if OSL_DEBUG_LEVEL > 0
     566                 :            :                     fprintf( stderr,
     567                 :            :                              "Removing link and replacing with file contents (%s) -> (%s).\n",
     568                 :            :                              rtl::OUStringToOString( aStatus.getLinkTargetURL(),
     569                 :            :                                                      RTL_TEXTENCODING_UTF8).getStr(),
     570                 :            :                              rtl::OUStringToOString( aFileURL,
     571                 :            :                                                      RTL_TEXTENCODING_UTF8).getStr() );
     572                 :            : #endif
     573                 :            :                 }
     574                 :            :             }
     575                 :            :         }
     576                 :            :     }
     577                 :            : 
     578         [ +  - ]:       8291 :     oslFileError rc = osl_openFile( aFileURL.pData, &nHandleTmp, uFlags );
     579         [ +  + ]:       8291 :     if ( rc != osl_File_E_None )
     580                 :            :     {
     581         [ -  + ]:        443 :         if ( uFlags & osl_File_OpenFlag_Write )
     582                 :            :         {
     583                 :            :             // Change to read-only
     584                 :          0 :             uFlags &= ~osl_File_OpenFlag_Write;
     585         [ #  # ]:          0 :             rc = osl_openFile( aFileURL.pData, &nHandleTmp, uFlags );
     586                 :            :         }
     587                 :            :     }
     588         [ +  + ]:       8291 :     if ( rc == osl_File_E_None )
     589                 :            :     {
     590                 :       7848 :         pInstanceData->rHandle = nHandleTmp;
     591                 :       7848 :         bIsOpen = sal_True;
     592         [ +  + ]:       7848 :         if ( uFlags & osl_File_OpenFlag_Write )
     593                 :       1907 :             bIsWritable = sal_True;
     594                 :            : 
     595 [ +  - ][ -  + ]:       7848 :         if ( !LockFile() ) // whole file
     596                 :            :         {
     597         [ #  # ]:          0 :             rc = osl_closeFile( nHandleTmp );
     598                 :          0 :             bIsOpen = sal_False;
     599                 :          0 :             bIsWritable = sal_False;
     600                 :          0 :             pInstanceData->rHandle = 0;
     601                 :            :         }
     602                 :            :     }
     603                 :            :     else
     604 [ +  - ][ -  + ]:       8291 :         SetError( ::GetSvError( rc ) );
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
     605                 :            : }
     606                 :            : 
     607                 :      17431 : void SvFileStream::Close()
     608                 :            : {
     609                 :      17431 :     UnlockFile();
     610                 :            : 
     611         [ +  + ]:      17431 :     if ( IsOpen() )
     612                 :            :     {
     613                 :            : #ifdef DBG_UTIL
     614                 :            :         rtl::OStringBuffer aTraceStr(
     615                 :            :             RTL_CONSTASCII_STRINGPARAM("SvFileStream::Close(): "));
     616                 :            :         aTraceStr.append(rtl::OUStringToOString(aFilename,
     617                 :            :             osl_getThreadTextEncoding()));
     618                 :            :         OSL_TRACE("%s", aTraceStr.getStr());
     619                 :            : #endif
     620                 :            : 
     621                 :       6867 :         Flush();
     622                 :       6867 :         osl_closeFile( pInstanceData->rHandle );
     623                 :       6867 :         pInstanceData->rHandle = 0;
     624                 :            :     }
     625                 :            : 
     626                 :      17431 :     bIsOpen     = sal_False;
     627                 :      17431 :     bIsWritable = sal_False;
     628                 :      17431 :     SvStream::ClearBuffer();
     629                 :      17431 :     SvStream::ClearError();
     630                 :      17431 : }
     631                 :            : 
     632                 :            : /// set filepointer to beginning of file
     633                 :        135 : void SvFileStream::ResetError()
     634                 :            : {
     635                 :        135 :     SvStream::ClearError();
     636                 :        135 : }
     637                 :            : 
     638                 :        160 : void SvFileStream::SetSize (sal_Size nSize)
     639                 :            : {
     640         [ +  - ]:        160 :     if (IsOpen())
     641                 :            :     {
     642                 :        160 :         oslFileError rc = osl_setFileSize( pInstanceData->rHandle, nSize );
     643         [ -  + ]:        160 :         if (rc != osl_File_E_None )
     644                 :            :         {
     645                 :          0 :             SetError ( ::GetSvError( rc ));
     646                 :            :         }
     647                 :            :     }
     648                 :        160 : }
     649                 :            : 
     650                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10