1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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"
28 OTempFileService::OTempFileService(css::uno::Reference
< css::uno::XComponentContext
> const & context
)
29 : ::cppu::PropertySetMixin
< css::io::XTempFile
>(
31 , static_cast< Implements
>( IMPLEMENTS_PROPERTY_SET
| IMPLEMENTS_FAST_PROPERTY_SET
| IMPLEMENTS_PROPERTY_ACCESS
)
32 , com::sun::star::uno::Sequence
< OUString
>() )
34 , mbRemoveFile( true )
36 , mbOutClosed( false )
38 , mbHasCachedPos( false )
41 mpTempFile
= new ::utl::TempFile
;
42 mpTempFile
->EnableKillingFile ( true );
45 OTempFileService::~OTempFileService ()
53 css::uno::Any SAL_CALL
OTempFileService::queryInterface( css::uno::Type
const & aType
)
54 throw ( css::uno::RuntimeException
, std::exception
)
56 css::uno::Any
aResult( OTempFileBase::queryInterface( aType
) );
57 if (!aResult
.hasValue())
58 aResult
= cppu::PropertySetMixin
< css::io::XTempFile
>::queryInterface( aType
);
61 void SAL_CALL
OTempFileService::acquire( )
64 OTempFileBase::acquire();
66 void SAL_CALL
OTempFileService::release( )
69 OTempFileBase::release();
74 css::uno::Sequence
< css::uno::Type
> SAL_CALL
OTempFileService::getTypes( )
75 throw ( css::uno::RuntimeException
, std::exception
)
77 static ::cppu::OTypeCollection
* pTypeCollection
= NULL
;
78 if ( pTypeCollection
== NULL
)
80 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
82 if ( pTypeCollection
== NULL
)
84 static ::cppu::OTypeCollection
aTypeCollection(
85 cppu::UnoType
<css::beans::XPropertySet
>::get()
86 ,OTempFileBase::getTypes() );
87 pTypeCollection
= &aTypeCollection
;
90 return pTypeCollection
->getTypes();
92 css::uno::Sequence
< sal_Int8
> SAL_CALL
OTempFileService::getImplementationId( )
93 throw ( css::uno::RuntimeException
, std::exception
)
95 return OTempFileBase::getImplementationId();
100 sal_Bool SAL_CALL
OTempFileService::getRemoveFile()
101 throw ( css::uno::RuntimeException
, std::exception
)
103 ::osl::MutexGuard
aGuard( maMutex
);
107 // the stream is already disconnected
108 throw css::uno::RuntimeException();
113 void SAL_CALL
OTempFileService::setRemoveFile( sal_Bool _removefile
)
114 throw ( css::uno::RuntimeException
, std::exception
)
116 ::osl::MutexGuard
aGuard( maMutex
);
120 // the stream is already disconnected
121 throw css::uno::RuntimeException();
124 mbRemoveFile
= _removefile
;
125 mpTempFile
->EnableKillingFile( mbRemoveFile
);
127 OUString SAL_CALL
OTempFileService::getUri()
128 throw ( css::uno::RuntimeException
, std::exception
)
130 ::osl::MutexGuard
aGuard( maMutex
);
134 throw css::uno::RuntimeException();
137 return OUString( mpTempFile
->GetURL() );
140 OUString SAL_CALL
OTempFileService::getResourceName()
141 throw ( css::uno::RuntimeException
, std::exception
)
143 ::osl::MutexGuard
aGuard( maMutex
);
147 throw css::uno::RuntimeException();
150 return OUString( mpTempFile
->GetFileName() );
155 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
)
158 ::osl::MutexGuard
aGuard( maMutex
);
160 throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak
* > ( static_cast < const css::uno::XWeak
* > (this ) ) );
163 if (nBytesToRead
< 0)
164 throw css::io::BufferSizeExceededException( OUString(), static_cast< css::uno::XWeak
* >(this));
166 aData
.realloc(nBytesToRead
);
168 sal_uInt32 nRead
= mpStream
->Read(static_cast < void* > ( aData
.getArray() ), nBytesToRead
);
171 if (nRead
< static_cast < sal_uInt32
> ( nBytesToRead
) )
172 aData
.realloc( nRead
);
174 if ( sal::static_int_cast
<sal_uInt32
>(nBytesToRead
) > nRead
)
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 mnCachedPos
= mpStream
->Tell();
179 mbHasCachedPos
= true;
183 mpTempFile
->CloseStream();
188 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
)
191 ::osl::MutexGuard
aGuard( maMutex
);
193 throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak
* > ( static_cast < const css::uno::XWeak
* > (this ) ) );
198 if (nMaxBytesToRead
< 0)
199 throw css::io::BufferSizeExceededException( OUString(), static_cast < css::uno::XWeak
* >( this ) );
201 if (mpStream
->IsEof())
207 return readBytes(aData
, nMaxBytesToRead
);
209 void SAL_CALL
OTempFileService::skipBytes( sal_Int32 nBytesToSkip
)
210 throw ( css::io::NotConnectedException
, css::io::BufferSizeExceededException
, css::io::IOException
, css::uno::RuntimeException
, std::exception
)
212 ::osl::MutexGuard
aGuard( maMutex
);
214 throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak
* > ( static_cast < const css::uno::XWeak
* > (this ) ) );
218 mpStream
->SeekRel(nBytesToSkip
);
221 sal_Int32 SAL_CALL
OTempFileService::available( )
222 throw ( css::io::NotConnectedException
, css::io::IOException
, css::uno::RuntimeException
, std::exception
)
224 ::osl::MutexGuard
aGuard( maMutex
);
226 throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak
* > ( static_cast < const css::uno::XWeak
* > (this ) ) );
230 sal_uInt32
const nAvailable
=
231 static_cast<sal_uInt32
>(mpStream
->remainingSize());
236 void SAL_CALL
OTempFileService::closeInput( )
237 throw ( css::io::NotConnectedException
, css::io::IOException
, css::uno::RuntimeException
, std::exception
)
239 ::osl::MutexGuard
aGuard( maMutex
);
241 throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak
* > ( static_cast < const css::uno::XWeak
* > (this ) ) );
247 // stream will be deleted by TempFile implementation
260 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
)
263 ::osl::MutexGuard
aGuard( maMutex
);
265 throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak
* > ( static_cast < const css::uno::XWeak
* > (this ) ) );
268 sal_uInt32 nWritten
= mpStream
->Write(aData
.getConstArray(),aData
.getLength());
270 if ( nWritten
!= (sal_uInt32
)aData
.getLength())
271 throw css::io::BufferSizeExceededException( OUString(),static_cast < css::uno::XWeak
* > ( this ) );
273 void SAL_CALL
OTempFileService::flush( )
274 throw ( css::io::NotConnectedException
, css::io::BufferSizeExceededException
, css::io::IOException
, css::uno::RuntimeException
, std::exception
)
276 ::osl::MutexGuard
aGuard( maMutex
);
278 throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak
* > ( static_cast < const css::uno::XWeak
* > (this ) ) );
284 void SAL_CALL
OTempFileService::closeOutput( )
285 throw ( css::io::NotConnectedException
, css::io::BufferSizeExceededException
, css::io::IOException
, css::uno::RuntimeException
, std::exception
)
287 ::osl::MutexGuard
aGuard( maMutex
);
289 throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak
* > ( static_cast < const css::uno::XWeak
* > (this ) ) );
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? )
296 mnCachedPos
= mpStream
->Tell();
297 mbHasCachedPos
= true;
301 mpTempFile
->CloseStream();
306 // stream will be deleted by TempFile implementation
317 void OTempFileService::checkError () const
319 if (!mpStream
|| mpStream
->SvStream::GetError () != ERRCODE_NONE
)
320 throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak
* > ( static_cast < const css::uno::XWeak
* > (this ) ) );
322 void OTempFileService::checkConnected ()
324 if (!mpStream
&& mpTempFile
)
326 mpStream
= mpTempFile
->GetStream( STREAM_STD_READWRITE
);
327 if ( mpStream
&& mbHasCachedPos
)
329 mpStream
->Seek( sal::static_int_cast
<sal_Size
>(mnCachedPos
) );
330 if ( mpStream
->SvStream::GetError () == ERRCODE_NONE
)
332 mbHasCachedPos
= false;
338 mpTempFile
->CloseStream();
344 throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak
* > ( static_cast < const css::uno::XWeak
* > (this ) ) );
349 void SAL_CALL
OTempFileService::seek( sal_Int64 nLocation
)
350 throw ( css::lang::IllegalArgumentException
, css::io::IOException
, css::uno::RuntimeException
, std::exception
)
352 ::osl::MutexGuard
aGuard( maMutex
);
354 if ( nLocation
< 0 || nLocation
> getLength() )
355 throw css::lang::IllegalArgumentException();
357 mpStream
->Seek((sal_uInt32
) nLocation
);
360 sal_Int64 SAL_CALL
OTempFileService::getPosition( )
361 throw ( css::io::IOException
, css::uno::RuntimeException
, std::exception
)
363 ::osl::MutexGuard
aGuard( maMutex
);
366 sal_uInt32 nPos
= mpStream
->Tell();
368 return (sal_Int64
)nPos
;
370 sal_Int64 SAL_CALL
OTempFileService::getLength( )
371 throw ( css::io::IOException
, css::uno::RuntimeException
, std::exception
)
373 ::osl::MutexGuard
aGuard( maMutex
);
376 sal_uInt32 nCurrentPos
= mpStream
->Tell();
379 mpStream
->Seek(STREAM_SEEK_TO_END
);
380 sal_uInt32 nEndPos
= mpStream
->Tell();
381 mpStream
->Seek(nCurrentPos
);
385 return (sal_Int64
)nEndPos
;
390 css::uno::Reference
< css::io::XInputStream
> SAL_CALL
OTempFileService::getInputStream()
391 throw ( css::uno::RuntimeException
, std::exception
)
393 return css::uno::Reference
< css::io::XInputStream
>( *this, css::uno::UNO_QUERY
);
396 css::uno::Reference
< css::io::XOutputStream
> SAL_CALL
OTempFileService::getOutputStream()
397 throw ( css::uno::RuntimeException
, std::exception
)
399 return css::uno::Reference
< css::io::XOutputStream
>( *this, css::uno::UNO_QUERY
);
404 void SAL_CALL
OTempFileService::truncate()
405 throw ( css::io::IOException
, css::uno::RuntimeException
, std::exception
)
407 ::osl::MutexGuard
aGuard( maMutex
);
409 // SetStreamSize() call does not change the position
411 mpStream
->SetStreamSize( 0 );
417 OUString SAL_CALL
OTempFileService::getImplementationName()
418 throw ( css::uno::RuntimeException
, std::exception
)
420 return getImplementationName_Static();
423 sal_Bool SAL_CALL
OTempFileService::supportsService( OUString
const & rServiceName
)
424 throw ( css::uno::RuntimeException
, std::exception
)
426 return cppu::supportsService(this, rServiceName
);
429 css::uno::Sequence
< OUString
> SAL_CALL
OTempFileService::getSupportedServiceNames()
430 throw ( css::uno::RuntimeException
, std::exception
)
432 return getSupportedServiceNames_Static();
435 OUString
OTempFileService::getImplementationName_Static ()
437 return OUString ( "com.sun.star.io.comp.TempFile" );
439 css::uno::Sequence
< OUString
> OTempFileService::getSupportedServiceNames_Static()
441 css::uno::Sequence
< OUString
> aNames ( 1 );
442 aNames
[0] = "com.sun.star.io.TempFile";
445 css::uno::Reference
< css::uno::XInterface
>SAL_CALL
XTempFile_createInstance(
446 css::uno::Reference
< css::uno::XComponentContext
> const & context
)
448 return static_cast< ::cppu::OWeakObject
* >( new OTempFileService(context
) );
451 css::uno::Reference
< css::lang::XSingleComponentFactory
> OTempFileService::createServiceFactory_Static()
453 return ::cppu::createSingleComponentFactory( XTempFile_createInstance
, getImplementationName_Static(), getSupportedServiceNames_Static() );
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)
463 extern "C" SAL_DLLPUBLIC_EXPORT
void * SAL_CALL
utl_component_getFactory(
464 const sal_Char
* pImplName
, void * pServiceManager
,
465 SAL_UNUSED_PARAMETER
void * /*pRegistryKey*/ )
468 css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMgr(
469 static_cast< css::lang::XMultiServiceFactory
* >( pServiceManager
) );
470 css::uno::Reference
< css::lang::XSingleComponentFactory
> xFactory
;
472 if (OTempFileService::getImplementationName_Static().equalsAscii( pImplName
) )
473 xFactory
= OTempFileService::createServiceFactory_Static();
478 pRet
= xFactory
.get();
483 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */