LCOV - code coverage report
Current view: top level - unotools/source/ucbhelper - xtempfile.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 173 232 74.6 %
Date: 2014-04-11 Functions: 28 36 77.8 %
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        6785 : 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        6785 : , mbHasCachedPos( false )
      39             : 
      40             : {
      41        6785 :     mpTempFile = new ::utl::TempFile;
      42        6785 :     mpTempFile->EnableKillingFile ( true );
      43        6785 : }
      44             : 
      45       20265 : OTempFileService::~OTempFileService ()
      46             : {
      47        6755 :     if ( mpTempFile )
      48        6093 :         delete mpTempFile;
      49       13510 : }
      50             : 
      51             : // XInterface
      52             : 
      53       40933 : css::uno::Any SAL_CALL OTempFileService::queryInterface( css::uno::Type const & aType )
      54             : throw ( css::uno::RuntimeException, std::exception )
      55             : {
      56       40933 :     css::uno::Any aResult( OTempFileBase::queryInterface( aType ) );
      57       40933 :     if (!aResult.hasValue())
      58         978 :         aResult = cppu::PropertySetMixin< css::io::XTempFile >::queryInterface( aType );
      59       40933 :     return aResult;
      60             : };
      61      141518 : void SAL_CALL OTempFileService::acquire(  )
      62             : throw ()
      63             : {
      64      141518 :     OTempFileBase::acquire();
      65      141518 : }
      66      141368 : void SAL_CALL OTempFileService::release(  )
      67             : throw ()
      68             : {
      69      141368 :     OTempFileBase::release();
      70      141368 : }
      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 :                 ::getCppuType( ( const css::uno::Reference< css::beans::XPropertySet >*)NULL )
      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         455 : void SAL_CALL OTempFileService::setRemoveFile( sal_Bool _removefile )
     114             : throw ( css::uno::RuntimeException, std::exception )
     115             : {
     116         455 :     ::osl::MutexGuard aGuard( maMutex );
     117             : 
     118         455 :     if ( !mpTempFile )
     119             :     {
     120             :         // the stream is already disconnected
     121           0 :         throw css::uno::RuntimeException();
     122             :     }
     123             : 
     124         455 :     mbRemoveFile = _removefile;
     125         455 :     mpTempFile->EnableKillingFile( mbRemoveFile );
     126         455 : };
     127         450 : OUString SAL_CALL OTempFileService::getUri()
     128             : throw ( css::uno::RuntimeException, std::exception )
     129             : {
     130         450 :     ::osl::MutexGuard aGuard( maMutex );
     131             : 
     132         450 :     if ( !mpTempFile )
     133             :     {
     134           0 :         throw css::uno::RuntimeException();
     135             :     }
     136             : 
     137         450 :     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      103146 : 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      103146 :     ::osl::MutexGuard aGuard( maMutex );
     159      103146 :     if ( mbInClosed )
     160           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     161             : 
     162      103146 :     checkConnected();
     163      103146 :     if (nBytesToRead < 0)
     164           0 :         throw css::io::BufferSizeExceededException( OUString(), static_cast< css::uno::XWeak * >(this));
     165             : 
     166      103146 :     aData.realloc(nBytesToRead);
     167             : 
     168      103146 :     sal_uInt32 nRead = mpStream->Read(static_cast < void* > ( aData.getArray() ), nBytesToRead);
     169      103146 :     checkError();
     170             : 
     171      103146 :     if (nRead < static_cast < sal_uInt32 > ( nBytesToRead ) )
     172        2645 :         aData.realloc( nRead );
     173             : 
     174      103146 :     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        2645 :         mnCachedPos = mpStream->Tell();
     179        2645 :         mbHasCachedPos = true;
     180             : 
     181        2645 :         mpStream = NULL;
     182        2645 :         if ( mpTempFile )
     183        2645 :             mpTempFile->CloseStream();
     184             :     }
     185             : 
     186      103146 :     return nRead;
     187             : }
     188          30 : 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          30 :     ::osl::MutexGuard aGuard( maMutex );
     192          30 :     if ( mbInClosed )
     193           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     194             : 
     195          30 :     checkConnected();
     196          30 :     checkError();
     197             : 
     198          30 :     if (nMaxBytesToRead < 0)
     199           0 :         throw css::io::BufferSizeExceededException( OUString(), static_cast < css::uno::XWeak * >( this ) );
     200             : 
     201          30 :     if (mpStream->IsEof())
     202             :     {
     203           0 :         aData.realloc(0);
     204           0 :         return 0;
     205             :     }
     206             :     else
     207          30 :         return readBytes(aData, nMaxBytesToRead);
     208             : }
     209         215 : 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         215 :     ::osl::MutexGuard aGuard( maMutex );
     213         215 :     if ( mbInClosed )
     214           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     215             : 
     216         215 :     checkConnected();
     217         215 :     checkError();
     218         215 :     mpStream->SeekRel(nBytesToSkip);
     219         215 :     checkError();
     220         215 : }
     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           0 :     sal_uInt32 nPos = mpStream->Tell();
     231           0 :     checkError();
     232             : 
     233           0 :     mpStream->Seek(STREAM_SEEK_TO_END);
     234           0 :     checkError();
     235             : 
     236           0 :     sal_Int32 nAvailable = (sal_Int32)mpStream->Tell() - nPos;
     237           0 :     mpStream->Seek(nPos);
     238           0 :     checkError();
     239             : 
     240           0 :     return nAvailable;
     241             : }
     242         662 : void SAL_CALL OTempFileService::closeInput(  )
     243             : throw ( css::io::NotConnectedException, css::io::IOException, css::uno::RuntimeException, std::exception )
     244             : {
     245         662 :     ::osl::MutexGuard aGuard( maMutex );
     246         662 :     if ( mbInClosed )
     247           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak  * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     248             : 
     249         662 :     mbInClosed = true;
     250             : 
     251         662 :     if ( mbOutClosed )
     252             :     {
     253             :         // stream will be deleted by TempFile implementation
     254         657 :         mpStream = NULL;
     255             : 
     256         657 :         if ( mpTempFile )
     257             :         {
     258         657 :             delete mpTempFile;
     259         657 :             mpTempFile = NULL;
     260             :         }
     261         662 :     }
     262         662 : }
     263             : 
     264             : // XOutputStream
     265             : 
     266       18429 : void SAL_CALL OTempFileService::writeBytes( const css::uno::Sequence< sal_Int8 >& aData )
     267             : throw ( css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException, std::exception )
     268             : {
     269       18429 :     ::osl::MutexGuard aGuard( maMutex );
     270       18429 :     if ( mbOutClosed )
     271           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     272             : 
     273       18429 :     checkConnected();
     274       18429 :     sal_uInt32 nWritten = mpStream->Write(aData.getConstArray(),aData.getLength());
     275       18429 :     checkError();
     276       18429 :     if  ( nWritten != (sal_uInt32)aData.getLength())
     277           0 :         throw css::io::BufferSizeExceededException( OUString(),static_cast < css::uno::XWeak * > ( this ) );
     278       18429 : }
     279        1990 : void SAL_CALL OTempFileService::flush(  )
     280             : throw ( css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException, std::exception )
     281             : {
     282        1990 :     ::osl::MutexGuard aGuard( maMutex );
     283        1990 :     if ( mbOutClosed )
     284           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     285             : 
     286        1990 :     checkConnected();
     287        1989 :     mpStream->Flush();
     288        1990 :     checkError();
     289        1989 : }
     290        2072 : void SAL_CALL OTempFileService::closeOutput(  )
     291             : throw ( css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException, std::exception )
     292             : {
     293        2072 :     ::osl::MutexGuard aGuard( maMutex );
     294        2072 :     if ( mbOutClosed )
     295           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     296             : 
     297        2072 :     mbOutClosed = true;
     298             : 
     299             :     // 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? )
     300        2072 :     if ( mpStream )
     301             :     {
     302        2066 :         mnCachedPos = mpStream->Tell();
     303        2066 :         mbHasCachedPos = true;
     304             : 
     305        2066 :         mpStream = NULL;
     306        2066 :         if ( mpTempFile )
     307        2066 :             mpTempFile->CloseStream();
     308             :     }
     309             : 
     310        2072 :     if ( mbInClosed )
     311             :     {
     312             :         // stream will be deleted by TempFile implementation
     313           5 :         mpStream = NULL;
     314             : 
     315           5 :         if ( mpTempFile )
     316             :         {
     317           5 :             delete mpTempFile;
     318           5 :             mpTempFile = NULL;
     319             :         }
     320        2072 :     }
     321        2072 : }
     322             : 
     323      187360 : void OTempFileService::checkError () const
     324             : {
     325      187360 :     if (!mpStream || mpStream->SvStream::GetError () != ERRCODE_NONE )
     326           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     327      187360 : }
     328      164137 : void OTempFileService::checkConnected ()
     329             : {
     330      164137 :     if (!mpStream && mpTempFile)
     331             :     {
     332        9243 :         mpStream = mpTempFile->GetStream( STREAM_STD_READWRITE );
     333        9243 :         if ( mpStream && mbHasCachedPos )
     334             :         {
     335        2907 :             mpStream->Seek( sal::static_int_cast<sal_Size>(mnCachedPos) );
     336        2907 :             if ( mpStream->SvStream::GetError () == ERRCODE_NONE )
     337             :             {
     338        2906 :                 mbHasCachedPos = false;
     339        2906 :                 mnCachedPos = 0;
     340             :             }
     341             :             else
     342             :             {
     343           1 :                 mpStream = NULL;
     344           1 :                 mpTempFile->CloseStream();
     345             :             }
     346             :         }
     347             :     }
     348             : 
     349      164137 :     if (!mpStream)
     350           1 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     351      164136 : }
     352             : 
     353             : // XSeekable
     354             : 
     355       16451 : void SAL_CALL OTempFileService::seek( sal_Int64 nLocation )
     356             : throw ( css::lang::IllegalArgumentException, css::io::IOException, css::uno::RuntimeException, std::exception )
     357             : {
     358       16451 :     ::osl::MutexGuard aGuard( maMutex );
     359       16451 :     checkConnected();
     360       16451 :     if ( nLocation < 0 || nLocation > getLength() )
     361           0 :         throw css::lang::IllegalArgumentException();
     362             : 
     363       16451 :     mpStream->Seek((sal_uInt32) nLocation );
     364       16451 :     checkError();
     365       16451 : }
     366         867 : sal_Int64 SAL_CALL OTempFileService::getPosition(  )
     367             : throw ( css::io::IOException, css::uno::RuntimeException, std::exception )
     368             : {
     369         867 :     ::osl::MutexGuard aGuard( maMutex );
     370         867 :     checkConnected();
     371             : 
     372         867 :     sal_uInt32 nPos = mpStream->Tell();
     373         867 :     checkError();
     374         867 :     return (sal_Int64)nPos;
     375             : }
     376       23009 : sal_Int64 SAL_CALL OTempFileService::getLength(  )
     377             : throw ( css::io::IOException, css::uno::RuntimeException, std::exception )
     378             : {
     379       23009 :     ::osl::MutexGuard aGuard( maMutex );
     380       23009 :     checkConnected();
     381             : 
     382       23009 :     sal_uInt32 nCurrentPos = mpStream->Tell();
     383       23009 :     checkError();
     384             : 
     385       23009 :     mpStream->Seek(STREAM_SEEK_TO_END);
     386       23009 :     sal_uInt32 nEndPos = mpStream->Tell();
     387       23009 :     mpStream->Seek(nCurrentPos);
     388             : 
     389       23009 :     checkError();
     390             : 
     391       23009 :     return (sal_Int64)nEndPos;
     392             : }
     393             : 
     394             : // XStream
     395             : 
     396        5933 : css::uno::Reference< css::io::XInputStream > SAL_CALL OTempFileService::getInputStream()
     397             : throw ( css::uno::RuntimeException, std::exception )
     398             :     {
     399        5933 :     return css::uno::Reference< css::io::XInputStream >( *this, css::uno::UNO_QUERY );
     400             : }
     401             : 
     402        6116 : css::uno::Reference< css::io::XOutputStream > SAL_CALL OTempFileService::getOutputStream()
     403             : throw ( css::uno::RuntimeException, std::exception )
     404             :     {
     405        6116 :     return css::uno::Reference< css::io::XOutputStream >( *this, css::uno::UNO_QUERY );
     406             :     }
     407             : 
     408             : // XTruncate
     409             : 
     410           0 : void SAL_CALL OTempFileService::truncate()
     411             : throw ( css::io::IOException, css::uno::RuntimeException, std::exception )
     412             : {
     413           0 :     ::osl::MutexGuard aGuard( maMutex );
     414           0 :     checkConnected();
     415             :     // SetStreamSize() call does not change the position
     416           0 :     mpStream->Seek( 0 );
     417           0 :     mpStream->SetStreamSize( 0 );
     418           0 :     checkError();
     419           0 : }
     420             : 
     421             : // XServiceInfo
     422             : 
     423           0 : OUString SAL_CALL OTempFileService::getImplementationName()
     424             : throw ( css::uno::RuntimeException, std::exception )
     425             : {
     426           0 :     return getImplementationName_Static();
     427             : }
     428             : 
     429           0 : sal_Bool SAL_CALL OTempFileService::supportsService( OUString const & rServiceName )
     430             : throw ( css::uno::RuntimeException, std::exception )
     431             : {
     432           0 :     return cppu::supportsService(this, rServiceName);
     433             : }
     434             : 
     435           0 : css::uno::Sequence < OUString > SAL_CALL OTempFileService::getSupportedServiceNames()
     436             : throw ( css::uno::RuntimeException, std::exception )
     437             : {
     438           0 :     return getSupportedServiceNames_Static();
     439             : }
     440             : 
     441         128 : OUString OTempFileService::getImplementationName_Static ()
     442             : {
     443         128 :     return OUString ( "com.sun.star.io.comp.TempFile" );
     444             : }
     445          64 : css::uno::Sequence < OUString > OTempFileService::getSupportedServiceNames_Static()
     446             : {
     447          64 :     css::uno::Sequence < OUString > aNames ( 1 );
     448          64 :     aNames[0] = "com.sun.star.io.TempFile";
     449          64 :     return aNames;
     450             : }
     451        6785 : css::uno::Reference < css::uno::XInterface >SAL_CALL XTempFile_createInstance(
     452             :     css::uno::Reference< css::uno::XComponentContext > const & context)
     453             :     SAL_THROW( ( css::uno::Exception ) )
     454             : {
     455        6785 :     return static_cast< ::cppu::OWeakObject * >( new OTempFileService(context) );
     456             : }
     457             : 
     458          64 : css::uno::Reference < css::lang::XSingleComponentFactory > OTempFileService::createServiceFactory_Static()
     459             : {
     460          64 :     return ::cppu::createSingleComponentFactory( XTempFile_createInstance, getImplementationName_Static(), getSupportedServiceNames_Static() );
     461             : }
     462             : 
     463             : /**
     464             :  * This function is called to get service factories for an implementation.
     465             :  * @param pImplName name of implementation
     466             :  * @param pServiceManager generic uno interface providing a service manager to instantiate components
     467             :  * @param pRegistryKey registry data key to read and write component persistent data
     468             :  * @return a component factory (generic uno interface)
     469             :  */
     470          64 : extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL utl_component_getFactory(
     471             :     const sal_Char * pImplName, void * pServiceManager,
     472             :     SAL_UNUSED_PARAMETER void * /*pRegistryKey*/ )
     473             : {
     474          64 :     void * pRet = 0;
     475             :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMgr(
     476          64 :         reinterpret_cast< css::lang::XMultiServiceFactory * >( pServiceManager ) );
     477         128 :     css::uno::Reference< css::lang::XSingleComponentFactory > xFactory;
     478             : 
     479          64 :     if (OTempFileService::getImplementationName_Static().equalsAscii( pImplName ) )
     480          64 :         xFactory = OTempFileService::createServiceFactory_Static();
     481             : 
     482          64 :     if ( xFactory.is() )
     483             :     {
     484          64 :         xFactory->acquire();
     485          64 :         pRet = xFactory.get();
     486             :     }
     487         128 :     return pRet;
     488             : }
     489             : 
     490             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10