LCOV - code coverage report
Current view: top level - unotools/source/ucbhelper - xtempfile.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 173 227 76.2 %
Date: 2014-11-03 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       17498 : 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       17498 : , mbHasCachedPos( false )
      39             : 
      40             : {
      41       17498 :     mpTempFile = new ::utl::TempFile;
      42       17498 :     mpTempFile->EnableKillingFile ( true );
      43       17498 : }
      44             : 
      45       52485 : OTempFileService::~OTempFileService ()
      46             : {
      47       17495 :     if ( mpTempFile )
      48       16113 :         delete mpTempFile;
      49       34990 : }
      50             : 
      51             : // XInterface
      52             : 
      53      104344 : css::uno::Any SAL_CALL OTempFileService::queryInterface( css::uno::Type const & aType )
      54             : throw ( css::uno::RuntimeException, std::exception )
      55             : {
      56      104344 :     css::uno::Any aResult( OTempFileBase::queryInterface( aType ) );
      57      104344 :     if (!aResult.hasValue())
      58        2598 :         aResult = cppu::PropertySetMixin< css::io::XTempFile >::queryInterface( aType );
      59      104344 :     return aResult;
      60             : };
      61      364476 : void SAL_CALL OTempFileService::acquire(  )
      62             : throw ()
      63             : {
      64      364476 :     OTempFileBase::acquire();
      65      364476 : }
      66      364461 : void SAL_CALL OTempFileService::release(  )
      67             : throw ()
      68             : {
      69      364461 :     OTempFileBase::release();
      70      364461 : }
      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        1542 : void SAL_CALL OTempFileService::setRemoveFile( sal_Bool _removefile )
     114             : throw ( css::uno::RuntimeException, std::exception )
     115             : {
     116        1542 :     ::osl::MutexGuard aGuard( maMutex );
     117             : 
     118        1542 :     if ( !mpTempFile )
     119             :     {
     120             :         // the stream is already disconnected
     121           0 :         throw css::uno::RuntimeException();
     122             :     }
     123             : 
     124        1542 :     mbRemoveFile = _removefile;
     125        1542 :     mpTempFile->EnableKillingFile( mbRemoveFile );
     126        1542 : };
     127        1532 : OUString SAL_CALL OTempFileService::getUri()
     128             : throw ( css::uno::RuntimeException, std::exception )
     129             : {
     130        1532 :     ::osl::MutexGuard aGuard( maMutex );
     131             : 
     132        1532 :     if ( !mpTempFile )
     133             :     {
     134           0 :         throw css::uno::RuntimeException();
     135             :     }
     136             : 
     137        1532 :     return OUString( mpTempFile->GetURL() );
     138             : 
     139             : };
     140           2 : OUString SAL_CALL OTempFileService::getResourceName()
     141             : throw ( css::uno::RuntimeException, std::exception )
     142             : {
     143           2 :     ::osl::MutexGuard aGuard( maMutex );
     144             : 
     145           2 :     if ( !mpTempFile )
     146             :     {
     147           0 :         throw css::uno::RuntimeException();
     148             : }
     149             : 
     150           2 :     return OUString( mpTempFile->GetFileName() );
     151             : };
     152             : 
     153             : // XInputStream
     154             : 
     155      216678 : 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      216678 :     ::osl::MutexGuard aGuard( maMutex );
     159      216678 :     if ( mbInClosed )
     160           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     161             : 
     162      216678 :     checkConnected();
     163      216678 :     if (nBytesToRead < 0)
     164           0 :         throw css::io::BufferSizeExceededException( OUString(), static_cast< css::uno::XWeak * >(this));
     165             : 
     166      216678 :     aData.realloc(nBytesToRead);
     167             : 
     168      216678 :     sal_uInt32 nRead = mpStream->Read(static_cast < void* > ( aData.getArray() ), nBytesToRead);
     169      216678 :     checkError();
     170             : 
     171      216678 :     if (nRead < static_cast < sal_uInt32 > ( nBytesToRead ) )
     172        6844 :         aData.realloc( nRead );
     173             : 
     174      216678 :     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        6844 :         mnCachedPos = mpStream->Tell();
     179        6844 :         mbHasCachedPos = true;
     180             : 
     181        6844 :         mpStream = NULL;
     182        6844 :         if ( mpTempFile )
     183        6844 :             mpTempFile->CloseStream();
     184             :     }
     185             : 
     186      216678 :     return nRead;
     187             : }
     188          92 : 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          92 :     ::osl::MutexGuard aGuard( maMutex );
     192          92 :     if ( mbInClosed )
     193           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     194             : 
     195          92 :     checkConnected();
     196          92 :     checkError();
     197             : 
     198          92 :     if (nMaxBytesToRead < 0)
     199           0 :         throw css::io::BufferSizeExceededException( OUString(), static_cast < css::uno::XWeak * >( this ) );
     200             : 
     201          92 :     if (mpStream->IsEof())
     202             :     {
     203           0 :         aData.realloc(0);
     204           0 :         return 0;
     205             :     }
     206             :     else
     207          92 :         return readBytes(aData, nMaxBytesToRead);
     208             : }
     209         432 : 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         432 :     ::osl::MutexGuard aGuard( maMutex );
     213         432 :     if ( mbInClosed )
     214           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     215             : 
     216         432 :     checkConnected();
     217         432 :     checkError();
     218         432 :     mpStream->SeekRel(nBytesToSkip);
     219         432 :     checkError();
     220         432 : }
     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        1382 : void SAL_CALL OTempFileService::closeInput(  )
     237             : throw ( css::io::NotConnectedException, css::io::IOException, css::uno::RuntimeException, std::exception )
     238             : {
     239        1382 :     ::osl::MutexGuard aGuard( maMutex );
     240        1382 :     if ( mbInClosed )
     241           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak  * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     242             : 
     243        1382 :     mbInClosed = true;
     244             : 
     245        1382 :     if ( mbOutClosed )
     246             :     {
     247             :         // stream will be deleted by TempFile implementation
     248        1372 :         mpStream = NULL;
     249             : 
     250        1372 :         if ( mpTempFile )
     251             :         {
     252        1372 :             delete mpTempFile;
     253        1372 :             mpTempFile = NULL;
     254             :         }
     255        1382 :     }
     256        1382 : }
     257             : 
     258             : // XOutputStream
     259             : 
     260       43234 : 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       43234 :     ::osl::MutexGuard aGuard( maMutex );
     264       43234 :     if ( mbOutClosed )
     265           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     266             : 
     267       43234 :     checkConnected();
     268       43234 :     sal_uInt32 nWritten = mpStream->Write(aData.getConstArray(),aData.getLength());
     269       43234 :     checkError();
     270       43234 :     if  ( nWritten != (sal_uInt32)aData.getLength())
     271           0 :         throw css::io::BufferSizeExceededException( OUString(),static_cast < css::uno::XWeak * > ( this ) );
     272       43234 : }
     273        5046 : void SAL_CALL OTempFileService::flush(  )
     274             : throw ( css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException, std::exception )
     275             : {
     276        5046 :     ::osl::MutexGuard aGuard( maMutex );
     277        5046 :     if ( mbOutClosed )
     278           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     279             : 
     280        5046 :     checkConnected();
     281        5044 :     mpStream->Flush();
     282        5046 :     checkError();
     283        5044 : }
     284        4292 : void SAL_CALL OTempFileService::closeOutput(  )
     285             : throw ( css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException, std::exception )
     286             : {
     287        4292 :     ::osl::MutexGuard aGuard( maMutex );
     288        4292 :     if ( mbOutClosed )
     289           0 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     290             : 
     291        4292 :     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        4292 :     if ( mpStream )
     295             :     {
     296        4280 :         mnCachedPos = mpStream->Tell();
     297        4280 :         mbHasCachedPos = true;
     298             : 
     299        4280 :         mpStream = NULL;
     300        4280 :         if ( mpTempFile )
     301        4280 :             mpTempFile->CloseStream();
     302             :     }
     303             : 
     304        4292 :     if ( mbInClosed )
     305             :     {
     306             :         // stream will be deleted by TempFile implementation
     307          10 :         mpStream = NULL;
     308             : 
     309          10 :         if ( mpTempFile )
     310             :         {
     311          10 :             delete mpTempFile;
     312          10 :             mpTempFile = NULL;
     313             :         }
     314        4292 :     }
     315        4292 : }
     316             : 
     317      426238 : void OTempFileService::checkError () const
     318             : {
     319      426238 :     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      426238 : }
     322      367518 : void OTempFileService::checkConnected ()
     323             : {
     324      367518 :     if (!mpStream && mpTempFile)
     325             :     {
     326       23084 :         mpStream = mpTempFile->GetStream( STREAM_STD_READWRITE );
     327       23084 :         if ( mpStream && mbHasCachedPos )
     328             :         {
     329        7116 :             mpStream->Seek( sal::static_int_cast<sal_Size>(mnCachedPos) );
     330        7116 :             if ( mpStream->SvStream::GetError () == ERRCODE_NONE )
     331             :             {
     332        7114 :                 mbHasCachedPos = false;
     333        7114 :                 mnCachedPos = 0;
     334             :             }
     335             :             else
     336             :             {
     337           2 :                 mpStream = NULL;
     338           2 :                 mpTempFile->CloseStream();
     339             :             }
     340             :         }
     341             :     }
     342             : 
     343      367518 :     if (!mpStream)
     344           2 :         throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) );
     345      367516 : }
     346             : 
     347             : // XSeekable
     348             : 
     349       41450 : void SAL_CALL OTempFileService::seek( sal_Int64 nLocation )
     350             : throw ( css::lang::IllegalArgumentException, css::io::IOException, css::uno::RuntimeException, std::exception )
     351             : {
     352       41450 :     ::osl::MutexGuard aGuard( maMutex );
     353       41450 :     checkConnected();
     354       41450 :     if ( nLocation < 0 || nLocation > getLength() )
     355           0 :         throw css::lang::IllegalArgumentException();
     356             : 
     357       41450 :     mpStream->Seek((sal_uInt32) nLocation );
     358       41450 :     checkError();
     359       41450 : }
     360        2296 : sal_Int64 SAL_CALL OTempFileService::getPosition(  )
     361             : throw ( css::io::IOException, css::uno::RuntimeException, std::exception )
     362             : {
     363        2296 :     ::osl::MutexGuard aGuard( maMutex );
     364        2296 :     checkConnected();
     365             : 
     366        2296 :     sal_uInt32 nPos = mpStream->Tell();
     367        2296 :     checkError();
     368        2296 :     return (sal_Int64)nPos;
     369             : }
     370       58290 : sal_Int64 SAL_CALL OTempFileService::getLength(  )
     371             : throw ( css::io::IOException, css::uno::RuntimeException, std::exception )
     372             : {
     373       58290 :     ::osl::MutexGuard aGuard( maMutex );
     374       58290 :     checkConnected();
     375             : 
     376       58290 :     sal_uInt32 nCurrentPos = mpStream->Tell();
     377       58290 :     checkError();
     378             : 
     379       58290 :     mpStream->Seek(STREAM_SEEK_TO_END);
     380       58290 :     sal_uInt32 nEndPos = mpStream->Tell();
     381       58290 :     mpStream->Seek(nCurrentPos);
     382             : 
     383       58290 :     checkError();
     384             : 
     385       58290 :     return (sal_Int64)nEndPos;
     386             : }
     387             : 
     388             : // XStream
     389             : 
     390       14506 : css::uno::Reference< css::io::XInputStream > SAL_CALL OTempFileService::getInputStream()
     391             : throw ( css::uno::RuntimeException, std::exception )
     392             :     {
     393       14506 :     return css::uno::Reference< css::io::XInputStream >( *this, css::uno::UNO_QUERY );
     394             : }
     395             : 
     396       14926 : css::uno::Reference< css::io::XOutputStream > SAL_CALL OTempFileService::getOutputStream()
     397             : throw ( css::uno::RuntimeException, std::exception )
     398             :     {
     399       14926 :     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           0 : OUString SAL_CALL OTempFileService::getImplementationName()
     418             : throw ( css::uno::RuntimeException, std::exception )
     419             : {
     420           0 :     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           0 : css::uno::Sequence < OUString > SAL_CALL OTempFileService::getSupportedServiceNames()
     430             : throw ( css::uno::RuntimeException, std::exception )
     431             : {
     432           0 :     return getSupportedServiceNames_Static();
     433             : }
     434             : 
     435         312 : OUString OTempFileService::getImplementationName_Static ()
     436             : {
     437         312 :     return OUString ( "com.sun.star.io.comp.TempFile" );
     438             : }
     439         156 : css::uno::Sequence < OUString > OTempFileService::getSupportedServiceNames_Static()
     440             : {
     441         156 :     css::uno::Sequence < OUString > aNames ( 1 );
     442         156 :     aNames[0] = "com.sun.star.io.TempFile";
     443         156 :     return aNames;
     444             : }
     445       17498 : css::uno::Reference < css::uno::XInterface >SAL_CALL XTempFile_createInstance(
     446             :     css::uno::Reference< css::uno::XComponentContext > const & context)
     447             : {
     448       17498 :     return static_cast< ::cppu::OWeakObject * >( new OTempFileService(context) );
     449             : }
     450             : 
     451         156 : css::uno::Reference < css::lang::XSingleComponentFactory > OTempFileService::createServiceFactory_Static()
     452             : {
     453         156 :     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         156 : 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         156 :     void * pRet = 0;
     468             :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMgr(
     469         156 :         reinterpret_cast< css::lang::XMultiServiceFactory * >( pServiceManager ) );
     470         312 :     css::uno::Reference< css::lang::XSingleComponentFactory > xFactory;
     471             : 
     472         156 :     if (OTempFileService::getImplementationName_Static().equalsAscii( pImplName ) )
     473         156 :         xFactory = OTempFileService::createServiceFactory_Static();
     474             : 
     475         156 :     if ( xFactory.is() )
     476             :     {
     477         156 :         xFactory->acquire();
     478         156 :         pRet = xFactory.get();
     479             :     }
     480         312 :     return pRet;
     481             : }
     482             : 
     483             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10