LCOV - code coverage report
Current view: top level - unotools/source/ucbhelper - xtempfile.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 177 227 78.0 %
Date: 2015-06-13 12:38:46 Functions: 30 36 83.3 %
Legend: Lines: hit not hit

          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 <cppuhelper/factory.hxx>
      21             : #include <cppuhelper/supportsservice.hxx>
      22             : #include <cppuhelper/typeprovider.hxx>
      23             : #include <osl/file.hxx>
      24             : #include <unotools/configmgr.hxx>
      25             : #include <unotools/tempfile.hxx>
      26             : #include "XTempFile.hxx"
      27             : 
      28        9979 : OTempFileService::OTempFileService(css::uno::Reference< css::uno::XComponentContext > const & context)
      29             : : ::cppu::PropertySetMixin< css::io::XTempFile >(
      30             :     context
      31             :     , static_cast< Implements >( IMPLEMENTS_PROPERTY_SET | IMPLEMENTS_FAST_PROPERTY_SET | IMPLEMENTS_PROPERTY_ACCESS )
      32             :     , com::sun::star::uno::Sequence< OUString >() )
      33             : , mpStream( NULL )
      34             : , mbRemoveFile( true )
      35             : , mbInClosed( false )
      36             : , mbOutClosed( false )
      37             : , mnCachedPos( 0 )
      38        9979 : , mbHasCachedPos( false )
      39             : 
      40             : {
      41        9979 :     mpTempFile = new ::utl::TempFile;
      42        9979 :     mpTempFile->EnableKillingFile ( true );
      43        9979 : }
      44             : 
      45       29901 : OTempFileService::~OTempFileService ()
      46             : {
      47        9967 :     if ( mpTempFile )
      48        9240 :         delete mpTempFile;
      49       19934 : }
      50             : 
      51             : // XInterface
      52             : 
      53       58745 : css::uno::Any SAL_CALL OTempFileService::queryInterface( css::uno::Type const & aType )
      54             : throw ( css::uno::RuntimeException, std::exception )
      55             : {
      56       58745 :     css::uno::Any aResult( OTempFileBase::queryInterface( aType ) );
      57       58745 :     if (!aResult.hasValue())
      58        1426 :         aResult = cppu::PropertySetMixin< css::io::XTempFile >::queryInterface( aType );
      59       58745 :     return aResult;
      60             : };
      61      210426 : void SAL_CALL OTempFileService::acquire(  )
      62             : throw ()
      63             : {
      64      210426 :     OTempFileBase::acquire();
      65      210426 : }
      66      210366 : void SAL_CALL OTempFileService::release(  )
      67             : throw ()
      68             : {
      69      210366 :     OTempFileBase::release();
      70      210366 : }
      71             : 
      72             : //  XTypeProvider
      73             : 
      74           0 : css::uno::Sequence< css::uno::Type > SAL_CALL OTempFileService::getTypes(  )
      75             : throw ( css::uno::RuntimeException, std::exception )
      76             : {
      77             :     static ::cppu::OTypeCollection* pTypeCollection = NULL;
      78           0 :     if ( pTypeCollection == NULL )
      79             :     {
      80           0 :         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
      81             : 
      82           0 :         if ( pTypeCollection == NULL )
      83             :         {
      84             :             static ::cppu::OTypeCollection aTypeCollection(
      85           0 :                 cppu::UnoType<css::beans::XPropertySet>::get()
      86           0 :                 ,OTempFileBase::getTypes() );
      87           0 :             pTypeCollection = &aTypeCollection;
      88           0 :         }
      89             :     }
      90           0 :     return pTypeCollection->getTypes();
      91             : };
      92           0 : css::uno::Sequence< sal_Int8 > SAL_CALL OTempFileService::getImplementationId(  )
      93             : throw ( css::uno::RuntimeException, std::exception )
      94             : {
      95           0 :     return OTempFileBase::getImplementationId();
      96             : }
      97             : 
      98             : //  XTempFile
      99             : 
     100           0 : sal_Bool SAL_CALL OTempFileService::getRemoveFile()
     101             : throw ( css::uno::RuntimeException, std::exception )
     102             : {
     103           0 :     ::osl::MutexGuard aGuard( maMutex );
     104             : 
     105           0 :     if ( !mpTempFile )
     106             :     {
     107             :         // the stream is already disconnected
     108           0 :         throw css::uno::RuntimeException();
     109             :         }
     110             : 
     111           0 :     return mbRemoveFile;
     112             : };
     113         858 : void SAL_CALL OTempFileService::setRemoveFile( sal_Bool _removefile )
     114             : throw ( css::uno::RuntimeException, std::exception )
     115             : {
     116         858 :     ::osl::MutexGuard aGuard( maMutex );
     117             : 
     118         858 :     if ( !mpTempFile )
     119             :     {
     120             :         // the stream is already disconnected
     121           0 :         throw css::uno::RuntimeException();
     122             :     }
     123             : 
     124         858 :     mbRemoveFile = _removefile;
     125         858 :     mpTempFile->EnableKillingFile( mbRemoveFile );
     126         858 : };
     127         853 : OUString SAL_CALL OTempFileService::getUri()
     128             : throw ( css::uno::RuntimeException, std::exception )
     129             : {
     130         853 :     ::osl::MutexGuard aGuard( maMutex );
     131             : 
     132         853 :     if ( !mpTempFile )
     133             :     {
     134           0 :         throw css::uno::RuntimeException();
     135             :     }
     136             : 
     137         853 :     return OUString( mpTempFile->GetURL() );
     138             : 
     139             : };
     140           1 : OUString SAL_CALL OTempFileService::getResourceName()
     141             : throw ( css::uno::RuntimeException, std::exception )
     142             : {
     143           1 :     ::osl::MutexGuard aGuard( maMutex );
     144             : 
     145           1 :     if ( !mpTempFile )
     146             :     {
     147           0 :         throw css::uno::RuntimeException();
     148             : }
     149             : 
     150           1 :     return OUString( mpTempFile->GetFileName() );
     151             : };
     152             : 
     153             : // XInputStream
     154             : 
     155      115610 : sal_Int32 SAL_CALL OTempFileService::readBytes( css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
     156             : throw (css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException, std::exception )
     157             : {
     158      115610 :     ::osl::MutexGuard aGuard( maMutex );
     159      115610 :     if ( mbInClosed )
     160           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     161             : 
     162      115610 :     checkConnected();
     163      115610 :     if (nBytesToRead < 0)
     164           0 :         throw css::io::BufferSizeExceededException( OUString(), static_cast< css::uno::XWeak * >(this));
     165             : 
     166      115610 :     aData.realloc(nBytesToRead);
     167             : 
     168      115610 :     sal_uInt32 nRead = mpStream->Read(static_cast < void* > ( aData.getArray() ), nBytesToRead);
     169      115610 :     checkError();
     170             : 
     171      115610 :     if (nRead < static_cast < sal_uInt32 > ( nBytesToRead ) )
     172        4306 :         aData.realloc( nRead );
     173             : 
     174      115610 :     if ( sal::static_int_cast<sal_uInt32>(nBytesToRead) > nRead )
     175             :     {
     176             :         // usually that means that the stream was read till the end
     177             :         // TODO/LATER: it is better to get rid of this optimization by avoiding using of multiple temporary files ( there should be only one temporary file? )
     178        4306 :         mnCachedPos = mpStream->Tell();
     179        4306 :         mbHasCachedPos = true;
     180             : 
     181        4306 :         mpStream = NULL;
     182        4306 :         if ( mpTempFile )
     183        4306 :             mpTempFile->CloseStream();
     184             :     }
     185             : 
     186      115610 :     return nRead;
     187             : }
     188          89 : sal_Int32 SAL_CALL OTempFileService::readSomeBytes( css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
     189             : throw ( css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException, std::exception )
     190             : {
     191          89 :     ::osl::MutexGuard aGuard( maMutex );
     192          89 :     if ( mbInClosed )
     193           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     194             : 
     195          89 :     checkConnected();
     196          89 :     checkError();
     197             : 
     198          89 :     if (nMaxBytesToRead < 0)
     199           0 :         throw css::io::BufferSizeExceededException( OUString(), static_cast < css::uno::XWeak * >( this ) );
     200             : 
     201          89 :     if (mpStream->IsEof())
     202             :     {
     203           0 :         aData.realloc(0);
     204           0 :         return 0;
     205             :     }
     206             :     else
     207          89 :         return readBytes(aData, nMaxBytesToRead);
     208             : }
     209         216 : void SAL_CALL OTempFileService::skipBytes( sal_Int32 nBytesToSkip )
     210             : throw ( css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException, std::exception )
     211             : {
     212         216 :     ::osl::MutexGuard aGuard( maMutex );
     213         216 :     if ( mbInClosed )
     214           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     215             : 
     216         216 :     checkConnected();
     217         216 :     checkError();
     218         216 :     mpStream->SeekRel(nBytesToSkip);
     219         216 :     checkError();
     220         216 : }
     221           0 : sal_Int32 SAL_CALL OTempFileService::available(  )
     222             : throw ( css::io::NotConnectedException, css::io::IOException, css::uno::RuntimeException, std::exception )
     223             : {
     224           0 :     ::osl::MutexGuard aGuard( maMutex );
     225           0 :     if ( mbInClosed )
     226           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     227             : 
     228           0 :     checkConnected();
     229             : 
     230             :     sal_uInt32 const nAvailable =
     231           0 :         static_cast<sal_uInt32>(mpStream->remainingSize());
     232           0 :     checkError();
     233             : 
     234           0 :     return nAvailable;
     235             : }
     236         727 : void SAL_CALL OTempFileService::closeInput(  )
     237             : throw ( css::io::NotConnectedException, css::io::IOException, css::uno::RuntimeException, std::exception )
     238             : {
     239         727 :     ::osl::MutexGuard aGuard( maMutex );
     240         727 :     if ( mbInClosed )
     241           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak  * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     242             : 
     243         727 :     mbInClosed = true;
     244             : 
     245         727 :     if ( mbOutClosed )
     246             :     {
     247             :         // stream will be deleted by TempFile implementation
     248         722 :         mpStream = NULL;
     249             : 
     250         722 :         if ( mpTempFile )
     251             :         {
     252         722 :             delete mpTempFile;
     253         722 :             mpTempFile = NULL;
     254             :         }
     255         727 :     }
     256         727 : }
     257             : 
     258             : // XOutputStream
     259             : 
     260       25222 : void SAL_CALL OTempFileService::writeBytes( const css::uno::Sequence< sal_Int8 >& aData )
     261             : throw ( css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException, std::exception )
     262             : {
     263       25222 :     ::osl::MutexGuard aGuard( maMutex );
     264       25222 :     if ( mbOutClosed )
     265           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     266             : 
     267       25222 :     checkConnected();
     268       25222 :     sal_uInt32 nWritten = mpStream->Write(aData.getConstArray(),aData.getLength());
     269       25222 :     checkError();
     270       25222 :     if  ( nWritten != (sal_uInt32)aData.getLength())
     271           0 :         throw css::io::BufferSizeExceededException( OUString(),static_cast < css::uno::XWeak * > ( this ) );
     272       25222 : }
     273        2729 : void SAL_CALL OTempFileService::flush(  )
     274             : throw ( css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException, std::exception )
     275             : {
     276        2729 :     ::osl::MutexGuard aGuard( maMutex );
     277        2729 :     if ( mbOutClosed )
     278           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     279             : 
     280        2729 :     checkConnected();
     281        2728 :     mpStream->Flush();
     282        2729 :     checkError();
     283        2728 : }
     284        2284 : void SAL_CALL OTempFileService::closeOutput(  )
     285             : throw ( css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException, std::exception )
     286             : {
     287        2284 :     ::osl::MutexGuard aGuard( maMutex );
     288        2284 :     if ( mbOutClosed )
     289           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     290             : 
     291        2284 :     mbOutClosed = true;
     292             : 
     293             :     // TODO/LATER: it is better to get rid of this optimization by avoiding using of multiple temporary files ( there should be only one temporary file? )
     294        2284 :     if ( mpStream )
     295             :     {
     296        2278 :         mnCachedPos = mpStream->Tell();
     297        2278 :         mbHasCachedPos = true;
     298             : 
     299        2278 :         mpStream = NULL;
     300        2278 :         if ( mpTempFile )
     301        2278 :             mpTempFile->CloseStream();
     302             :     }
     303             : 
     304        2284 :     if ( mbInClosed )
     305             :     {
     306             :         // stream will be deleted by TempFile implementation
     307           5 :         mpStream = NULL;
     308             : 
     309           5 :         if ( mpTempFile )
     310             :         {
     311           5 :             delete mpTempFile;
     312           5 :             mpTempFile = NULL;
     313             :         }
     314        2284 :     }
     315        2284 : }
     316             : 
     317      241862 : void OTempFileService::checkError () const
     318             : {
     319      241862 :     if (!mpStream || mpStream->SvStream::GetError () != ERRCODE_NONE )
     320           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     321      241862 : }
     322      206175 : void OTempFileService::checkConnected ()
     323             : {
     324      206175 :     if (!mpStream && mpTempFile)
     325             :     {
     326       13470 :         mpStream = mpTempFile->GetStream( STREAM_STD_READWRITE );
     327       13470 :         if ( mpStream && mbHasCachedPos )
     328             :         {
     329        4343 :             mpStream->Seek( sal::static_int_cast<sal_Size>(mnCachedPos) );
     330        4343 :             if ( mpStream->SvStream::GetError () == ERRCODE_NONE )
     331             :             {
     332        4342 :                 mbHasCachedPos = false;
     333        4342 :                 mnCachedPos = 0;
     334             :             }
     335             :             else
     336             :             {
     337           1 :                 mpStream = NULL;
     338           1 :                 mpTempFile->CloseStream();
     339             :             }
     340             :         }
     341             :     }
     342             : 
     343      206175 :     if (!mpStream)
     344           1 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     345      206174 : }
     346             : 
     347             : // XSeekable
     348             : 
     349       25194 : void SAL_CALL OTempFileService::seek( sal_Int64 nLocation )
     350             : throw ( css::lang::IllegalArgumentException, css::io::IOException, css::uno::RuntimeException, std::exception )
     351             : {
     352       25194 :     ::osl::MutexGuard aGuard( maMutex );
     353       25194 :     checkConnected();
     354       25194 :     if ( nLocation < 0 || nLocation > getLength() )
     355           0 :         throw css::lang::IllegalArgumentException();
     356             : 
     357       25194 :     mpStream->Seek((sal_uInt32) nLocation );
     358       25194 :     checkError();
     359       25194 : }
     360        1643 : sal_Int64 SAL_CALL OTempFileService::getPosition(  )
     361             : throw ( css::io::IOException, css::uno::RuntimeException, std::exception )
     362             : {
     363        1643 :     ::osl::MutexGuard aGuard( maMutex );
     364        1643 :     checkConnected();
     365             : 
     366        1643 :     sal_uInt32 nPos = mpStream->Tell();
     367        1643 :     checkError();
     368        1643 :     return (sal_Int64)nPos;
     369             : }
     370       35472 : sal_Int64 SAL_CALL OTempFileService::getLength(  )
     371             : throw ( css::io::IOException, css::uno::RuntimeException, std::exception )
     372             : {
     373       35472 :     ::osl::MutexGuard aGuard( maMutex );
     374       35472 :     checkConnected();
     375             : 
     376       35472 :     sal_uInt32 nCurrentPos = mpStream->Tell();
     377       35472 :     checkError();
     378             : 
     379       35472 :     mpStream->Seek(STREAM_SEEK_TO_END);
     380       35472 :     sal_uInt32 nEndPos = mpStream->Tell();
     381       35472 :     mpStream->Seek(nCurrentPos);
     382             : 
     383       35472 :     checkError();
     384             : 
     385       35472 :     return (sal_Int64)nEndPos;
     386             : }
     387             : 
     388             : // XStream
     389             : 
     390        7959 : css::uno::Reference< css::io::XInputStream > SAL_CALL OTempFileService::getInputStream()
     391             : throw ( css::uno::RuntimeException, std::exception )
     392             :     {
     393        7959 :     return css::uno::Reference< css::io::XInputStream >( *this, css::uno::UNO_QUERY );
     394             : }
     395             : 
     396        8183 : css::uno::Reference< css::io::XOutputStream > SAL_CALL OTempFileService::getOutputStream()
     397             : throw ( css::uno::RuntimeException, std::exception )
     398             :     {
     399        8183 :     return css::uno::Reference< css::io::XOutputStream >( *this, css::uno::UNO_QUERY );
     400             :     }
     401             : 
     402             : // XTruncate
     403             : 
     404           0 : void SAL_CALL OTempFileService::truncate()
     405             : throw ( css::io::IOException, css::uno::RuntimeException, std::exception )
     406             : {
     407           0 :     ::osl::MutexGuard aGuard( maMutex );
     408           0 :     checkConnected();
     409             :     // SetStreamSize() call does not change the position
     410           0 :     mpStream->Seek( 0 );
     411           0 :     mpStream->SetStreamSize( 0 );
     412           0 :     checkError();
     413           0 : }
     414             : 
     415             : // XServiceInfo
     416             : 
     417           1 : OUString SAL_CALL OTempFileService::getImplementationName()
     418             : throw ( css::uno::RuntimeException, std::exception )
     419             : {
     420           1 :     return getImplementationName_Static();
     421             : }
     422             : 
     423           0 : sal_Bool SAL_CALL OTempFileService::supportsService( OUString const & rServiceName )
     424             : throw ( css::uno::RuntimeException, std::exception )
     425             : {
     426           0 :     return cppu::supportsService(this, rServiceName);
     427             : }
     428             : 
     429           1 : css::uno::Sequence < OUString > SAL_CALL OTempFileService::getSupportedServiceNames()
     430             : throw ( css::uno::RuntimeException, std::exception )
     431             : {
     432           1 :     return getSupportedServiceNames_Static();
     433             : }
     434             : 
     435         211 : OUString OTempFileService::getImplementationName_Static ()
     436             : {
     437         211 :     return OUString ( "com.sun.star.io.comp.TempFile" );
     438             : }
     439         106 : css::uno::Sequence < OUString > OTempFileService::getSupportedServiceNames_Static()
     440             : {
     441         106 :     css::uno::Sequence < OUString > aNames ( 1 );
     442         106 :     aNames[0] = "com.sun.star.io.TempFile";
     443         106 :     return aNames;
     444             : }
     445        9979 : css::uno::Reference < css::uno::XInterface >SAL_CALL XTempFile_createInstance(
     446             :     css::uno::Reference< css::uno::XComponentContext > const & context)
     447             : {
     448        9979 :     return static_cast< ::cppu::OWeakObject * >( new OTempFileService(context) );
     449             : }
     450             : 
     451         105 : css::uno::Reference < css::lang::XSingleComponentFactory > OTempFileService::createServiceFactory_Static()
     452             : {
     453         105 :     return ::cppu::createSingleComponentFactory( XTempFile_createInstance, getImplementationName_Static(), getSupportedServiceNames_Static() );
     454             : }
     455             : 
     456             : /**
     457             :  * This function is called to get service factories for an implementation.
     458             :  * @param pImplName name of implementation
     459             :  * @param pServiceManager generic uno interface providing a service manager to instantiate components
     460             :  * @param pRegistryKey registry data key to read and write component persistent data
     461             :  * @return a component factory (generic uno interface)
     462             :  */
     463         105 : extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL utl_component_getFactory(
     464             :     const sal_Char * pImplName, void * pServiceManager,
     465             :     SAL_UNUSED_PARAMETER void * /*pRegistryKey*/ )
     466             : {
     467         105 :     void * pRet = 0;
     468             :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMgr(
     469         105 :         static_cast< css::lang::XMultiServiceFactory * >( pServiceManager ) );
     470         210 :     css::uno::Reference< css::lang::XSingleComponentFactory > xFactory;
     471             : 
     472         105 :     if (OTempFileService::getImplementationName_Static().equalsAscii( pImplName ) )
     473         105 :         xFactory = OTempFileService::createServiceFactory_Static();
     474             : 
     475         105 :     if ( xFactory.is() )
     476             :     {
     477         105 :         xFactory->acquire();
     478         105 :         pRet = xFactory.get();
     479             :     }
     480         210 :     return pRet;
     481             : }
     482             : 
     483             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11