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 "XTempFile.hxx"
21 #include <com/sun/star/io/BufferSizeExceededException.hpp>
22 #include <com/sun/star/io/NotConnectedException.hpp>
23 #include <com/sun/star/beans/PropertyAttribute.hpp>
24 #include <cppuhelper/typeprovider.hxx>
25 #include <o3tl/safeint.hxx>
26 #include <unotools/tempfile.hxx>
27 #include <cppuhelper/propshlp.hxx>
28 #include <cppuhelper/supportsservice.hxx>
30 OTempFileService::OTempFileService(css::uno::Reference
< css::uno::XComponentContext
> const &)
32 , mbRemoveFile( true )
34 , mbOutClosed( false )
37 mpTempFile
->EnableKillingFile();
40 OTempFileService::~OTempFileService ()
46 css::uno::Sequence
< css::uno::Type
> SAL_CALL
OTempFileService::getTypes( )
48 static ::cppu::OTypeCollection
ourTypeCollection(
49 cppu::UnoType
<css::beans::XPropertySet
>::get()
50 ,OTempFileBase::getTypes() );
52 return ourTypeCollection
.getTypes();
57 sal_Bool SAL_CALL
OTempFileService::getRemoveFile()
59 std::unique_lock
aGuard( maMutex
);
63 // the stream is already disconnected
64 throw css::uno::RuntimeException("Not connected to a file.");
69 void SAL_CALL
OTempFileService::setRemoveFile( sal_Bool _removefile
)
71 std::unique_lock
aGuard( maMutex
);
75 // the stream is already disconnected
76 throw css::uno::RuntimeException("Not connected to a file.");
79 mbRemoveFile
= _removefile
;
80 mpTempFile
->EnableKillingFile( mbRemoveFile
);
82 OUString SAL_CALL
OTempFileService::getUri()
84 std::unique_lock
aGuard( maMutex
);
88 throw css::uno::RuntimeException("Not connected to a file.");
91 return mpTempFile
->GetURL();
94 OUString SAL_CALL
OTempFileService::getResourceName()
96 std::unique_lock
aGuard( maMutex
);
100 throw css::uno::RuntimeException("Not connected to a file.");
103 return mpTempFile
->GetFileName();
108 sal_Int32 SAL_CALL
OTempFileService::readBytes( css::uno::Sequence
< sal_Int8
>& aData
, sal_Int32 nBytesToRead
)
110 std::unique_lock
aGuard( maMutex
);
112 throw css::io::NotConnectedException ( OUString(), getXWeak() );
115 if (nBytesToRead
< 0)
116 throw css::io::BufferSizeExceededException( OUString(), getXWeak());
118 if (aData
.getLength() < nBytesToRead
)
119 aData
.realloc(nBytesToRead
);
121 sal_uInt32 nRead
= mpStream
->ReadBytes(static_cast<void*>(aData
.getArray()), nBytesToRead
);
124 if (nRead
< o3tl::make_unsigned(aData
.getLength()))
125 aData
.realloc( nRead
);
129 sal_Int32 SAL_CALL
OTempFileService::readSomeBytes( css::uno::Sequence
< sal_Int8
>& aData
, sal_Int32 nMaxBytesToRead
)
132 std::unique_lock
aGuard( maMutex
);
134 throw css::io::NotConnectedException ( OUString(), getXWeak() );
139 if (nMaxBytesToRead
< 0)
140 throw css::io::BufferSizeExceededException( OUString(), getXWeak() );
148 return readBytes(aData
, nMaxBytesToRead
);
150 void SAL_CALL
OTempFileService::skipBytes( sal_Int32 nBytesToSkip
)
152 std::unique_lock
aGuard( maMutex
);
154 throw css::io::NotConnectedException ( OUString(), getXWeak() );
158 mpStream
->SeekRel(nBytesToSkip
);
161 sal_Int32 SAL_CALL
OTempFileService::available( )
163 std::unique_lock
aGuard( maMutex
);
165 throw css::io::NotConnectedException ( OUString(), getXWeak() );
169 sal_Int64 nAvailable
= mpStream
->remainingSize();
172 return std::min
<sal_Int64
>(SAL_MAX_INT32
, nAvailable
);
174 void SAL_CALL
OTempFileService::closeInput( )
176 std::unique_lock
aGuard( maMutex
);
178 throw css::io::NotConnectedException ( OUString(), getXWeak() );
184 // stream will be deleted by TempFile implementation
192 void SAL_CALL
OTempFileService::writeBytes( const css::uno::Sequence
< sal_Int8
>& aData
)
194 std::unique_lock
aGuard( maMutex
);
196 throw css::io::NotConnectedException ( OUString(), getXWeak() );
199 sal_uInt32 nWritten
= mpStream
->WriteBytes(aData
.getConstArray(), aData
.getLength());
201 if ( nWritten
!= static_cast<sal_uInt32
>(aData
.getLength()))
202 throw css::io::BufferSizeExceededException( OUString(), getXWeak() );
204 void SAL_CALL
OTempFileService::flush( )
206 std::unique_lock
aGuard( maMutex
);
208 throw css::io::NotConnectedException ( OUString(), getXWeak() );
214 void SAL_CALL
OTempFileService::closeOutput( )
216 std::unique_lock
aGuard( maMutex
);
218 throw css::io::NotConnectedException ( OUString(), getXWeak() );
223 // so that if you then open the InputStream, you can read the content
224 mpStream
->FlushBuffer();
230 // stream will be deleted by TempFile implementation
236 void OTempFileService::checkError () const
238 if (!mpStream
|| mpStream
->SvStream::GetError () != ERRCODE_NONE
)
239 throw css::io::NotConnectedException ( OUString(), const_cast < OTempFileService
* > (this)->getXWeak() );
241 void OTempFileService::checkConnected ()
243 if (!mpStream
&& mpTempFile
)
245 // Ideally we should open this SHARE_DENYALL, but the JunitTest_unotools_complex test wants to open
246 // this file directly and read from it.
247 mpStream
= mpTempFile
->GetStream(StreamMode::READ
| StreamMode::WRITE
248 | StreamMode::SHARE_DENYWRITE
);
252 throw css::io::NotConnectedException ( OUString(), getXWeak() );
257 void SAL_CALL
OTempFileService::seek( sal_Int64 nLocation
)
259 std::unique_lock
aGuard( maMutex
);
262 sal_Int64 nEndPos
= mpStream
->TellEnd();
263 if ( nLocation
< 0 || nLocation
> nEndPos
)
264 throw css::lang::IllegalArgumentException();
266 mpStream
->Seek(static_cast<sal_uInt32
>(nLocation
) );
269 sal_Int64 SAL_CALL
OTempFileService::getPosition( )
271 std::unique_lock
aGuard( maMutex
);
274 sal_uInt32 nPos
= mpStream
->Tell();
276 return static_cast<sal_Int64
>(nPos
);
278 sal_Int64 SAL_CALL
OTempFileService::getLength( )
280 std::unique_lock
aGuard( maMutex
);
285 sal_Int64 nEndPos
= mpStream
->TellEnd();
292 css::uno::Reference
< css::io::XInputStream
> SAL_CALL
OTempFileService::getInputStream()
297 css::uno::Reference
< css::io::XOutputStream
> SAL_CALL
OTempFileService::getOutputStream()
304 void SAL_CALL
OTempFileService::truncate()
306 std::unique_lock
aGuard( maMutex
);
308 // SetStreamSize() call does not change the position
310 mpStream
->SetStreamSize( 0 );
314 #define PROPERTY_HANDLE_URI 1
315 #define PROPERTY_HANDLE_REMOVE_FILE 2
316 #define PROPERTY_HANDLE_RESOURCE_NAME 3
319 ::css::uno::Reference
< ::css::beans::XPropertySetInfo
> OTempFileService::getPropertySetInfo()
321 // Create a table that map names to index values.
322 // attention: properties need to be sorted by name!
323 static cppu::OPropertyArrayHelper
ourPropertyInfo(
325 css::beans::Property( "Uri", PROPERTY_HANDLE_URI
, cppu::UnoType
<OUString
>::get(),
326 css::beans::PropertyAttribute::READONLY
),
327 css::beans::Property( "RemoveFile", PROPERTY_HANDLE_REMOVE_FILE
, cppu::UnoType
<bool>::get(),
329 css::beans::Property( "ResourceName", PROPERTY_HANDLE_RESOURCE_NAME
, cppu::UnoType
<OUString
>::get(),
330 css::beans::PropertyAttribute::READONLY
)
333 static css::uno::Reference
< css::beans::XPropertySetInfo
> xInfo(
334 ::cppu::OPropertySetHelper::createPropertySetInfo( ourPropertyInfo
) );
337 void OTempFileService::setPropertyValue( const ::rtl::OUString
& aPropertyName
, const ::css::uno::Any
& aValue
)
339 if ( aPropertyName
== "RemoveFile" )
340 setRemoveFile( aValue
.get
<bool>() );
344 throw css::beans::UnknownPropertyException(aPropertyName
);
347 ::css::uno::Any
OTempFileService::getPropertyValue( const ::rtl::OUString
& aPropertyName
)
349 if ( aPropertyName
== "RemoveFile" )
350 return css::uno::Any(getRemoveFile());
351 else if ( aPropertyName
== "ResourceName" )
352 return css::uno::Any(getResourceName());
353 else if ( aPropertyName
== "Uri" )
354 return css::uno::Any(getUri());
358 throw css::beans::UnknownPropertyException(aPropertyName
);
361 void OTempFileService::addPropertyChangeListener( const ::rtl::OUString
& /*aPropertyName*/, const ::css::uno::Reference
< ::css::beans::XPropertyChangeListener
>& /*xListener*/ )
365 void OTempFileService::removePropertyChangeListener( const ::rtl::OUString
& /*aPropertyName*/, const ::css::uno::Reference
< ::css::beans::XPropertyChangeListener
>& /*xListener*/ )
369 void OTempFileService::addVetoableChangeListener( const ::rtl::OUString
& /*aPropertyName*/, const ::css::uno::Reference
< ::css::beans::XVetoableChangeListener
>& /*xListener*/ )
373 void OTempFileService::removeVetoableChangeListener( const ::rtl::OUString
& /*aPropertyName*/, const ::css::uno::Reference
< ::css::beans::XVetoableChangeListener
>& /*xListener*/ )
378 void OTempFileService::setFastPropertyValue( ::sal_Int32 nHandle
, const ::css::uno::Any
& aValue
)
382 case PROPERTY_HANDLE_REMOVE_FILE
: setRemoveFile( aValue
.get
<bool>() ); return;
385 throw css::beans::UnknownPropertyException(OUString::number(nHandle
));
387 ::css::uno::Any
OTempFileService::getFastPropertyValue( ::sal_Int32 nHandle
)
391 case PROPERTY_HANDLE_REMOVE_FILE
: return css::uno::Any(getRemoveFile());
392 case PROPERTY_HANDLE_RESOURCE_NAME
: return css::uno::Any(getResourceName());
393 case PROPERTY_HANDLE_URI
: return css::uno::Any(getUri());
396 throw css::beans::UnknownPropertyException(OUString::number(nHandle
));
399 ::css::uno::Sequence
< ::css::beans::PropertyValue
> OTempFileService::getPropertyValues()
402 css::beans::PropertyValue("Uri", PROPERTY_HANDLE_URI
, css::uno::Any(getUri()), css::beans::PropertyState_DEFAULT_VALUE
),
403 css::beans::PropertyValue("RemoveFile", PROPERTY_HANDLE_REMOVE_FILE
, css::uno::Any(getRemoveFile()), css::beans::PropertyState_DEFAULT_VALUE
),
404 css::beans::PropertyValue("ResourceName", PROPERTY_HANDLE_RESOURCE_NAME
, css::uno::Any(getResourceName()), css::beans::PropertyState_DEFAULT_VALUE
)
407 void OTempFileService::setPropertyValues( const ::css::uno::Sequence
< ::css::beans::PropertyValue
>& aProps
)
409 for ( auto const & rPropVal
: aProps
)
410 setPropertyValue( rPropVal
.Name
, rPropVal
.Value
);
414 sal_Bool
OTempFileService::supportsService(const OUString
& sServiceName
)
416 return cppu::supportsService(this, sServiceName
);
418 OUString
OTempFileService::getImplementationName()
420 return "com.sun.star.io.comp.TempFile";
422 css::uno::Sequence
< OUString
> OTempFileService::getSupportedServiceNames()
424 return { "com.sun.star.io.TempFile" };
427 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
428 unotools_OTempFileService_get_implementation(
429 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
431 return cppu::acquire(new OTempFileService(context
));
435 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */