Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / unotools / source / ucbhelper / xtempfile.cxx
blob8c1da6c9850456376cb3d0ae608dd2e7ef67c454
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 &)
31 : mpStream( nullptr )
32 , mbRemoveFile( true )
33 , mbInClosed( false )
34 , mbOutClosed( false )
36 mpTempFile.emplace();
37 mpTempFile->EnableKillingFile();
40 OTempFileService::~OTempFileService ()
44 // XTypeProvider
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();
55 // XTempFile
57 sal_Bool SAL_CALL OTempFileService::getRemoveFile()
59 std::unique_lock aGuard( maMutex );
61 if ( !mpTempFile )
63 // the stream is already disconnected
64 throw css::uno::RuntimeException("Not connected to a file.");
67 return mbRemoveFile;
69 void SAL_CALL OTempFileService::setRemoveFile( sal_Bool _removefile )
71 std::unique_lock aGuard( maMutex );
73 if ( !mpTempFile )
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 );
86 if ( !mpTempFile )
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 );
98 if ( !mpTempFile )
100 throw css::uno::RuntimeException("Not connected to a file.");
103 return mpTempFile->GetFileName();
106 // XInputStream
108 sal_Int32 SAL_CALL OTempFileService::readBytes( css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
110 std::unique_lock aGuard( maMutex );
111 if ( mbInClosed )
112 throw css::io::NotConnectedException ( OUString(), getXWeak() );
114 checkConnected();
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);
122 checkError();
124 if (nRead < o3tl::make_unsigned(aData.getLength()))
125 aData.realloc( nRead );
127 return nRead;
129 sal_Int32 SAL_CALL OTempFileService::readSomeBytes( css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
132 std::unique_lock aGuard( maMutex );
133 if ( mbInClosed )
134 throw css::io::NotConnectedException ( OUString(), getXWeak() );
136 checkConnected();
137 checkError();
139 if (nMaxBytesToRead < 0)
140 throw css::io::BufferSizeExceededException( OUString(), getXWeak() );
142 if (mpStream->eof())
144 aData.realloc(0);
145 return 0;
148 return readBytes(aData, nMaxBytesToRead);
150 void SAL_CALL OTempFileService::skipBytes( sal_Int32 nBytesToSkip )
152 std::unique_lock aGuard( maMutex );
153 if ( mbInClosed )
154 throw css::io::NotConnectedException ( OUString(), getXWeak() );
156 checkConnected();
157 checkError();
158 mpStream->SeekRel(nBytesToSkip);
159 checkError();
161 sal_Int32 SAL_CALL OTempFileService::available( )
163 std::unique_lock aGuard( maMutex );
164 if ( mbInClosed )
165 throw css::io::NotConnectedException ( OUString(), getXWeak() );
167 checkConnected();
169 sal_Int64 nAvailable = mpStream->remainingSize();
170 checkError();
172 return std::min<sal_Int64>(SAL_MAX_INT32, nAvailable);
174 void SAL_CALL OTempFileService::closeInput( )
176 std::unique_lock aGuard( maMutex );
177 if ( mbInClosed )
178 throw css::io::NotConnectedException ( OUString(), getXWeak() );
180 mbInClosed = true;
182 if ( mbOutClosed )
184 // stream will be deleted by TempFile implementation
185 mpStream = nullptr;
186 mpTempFile.reset();
190 // XOutputStream
192 void SAL_CALL OTempFileService::writeBytes( const css::uno::Sequence< sal_Int8 >& aData )
194 std::unique_lock aGuard( maMutex );
195 if ( mbOutClosed )
196 throw css::io::NotConnectedException ( OUString(), getXWeak() );
198 checkConnected();
199 sal_uInt32 nWritten = mpStream->WriteBytes(aData.getConstArray(), aData.getLength());
200 checkError();
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 );
207 if ( mbOutClosed )
208 throw css::io::NotConnectedException ( OUString(), getXWeak() );
210 checkConnected();
211 mpStream->Flush();
212 checkError();
214 void SAL_CALL OTempFileService::closeOutput( )
216 std::unique_lock aGuard( maMutex );
217 if ( mbOutClosed )
218 throw css::io::NotConnectedException ( OUString(), getXWeak() );
220 mbOutClosed = true;
221 if (mpStream)
223 // so that if you then open the InputStream, you can read the content
224 mpStream->FlushBuffer();
225 mpStream->Seek(0);
228 if ( mbInClosed )
230 // stream will be deleted by TempFile implementation
231 mpStream = nullptr;
232 mpTempFile.reset();
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);
251 if (!mpStream)
252 throw css::io::NotConnectedException ( OUString(), getXWeak() );
255 // XSeekable
257 void SAL_CALL OTempFileService::seek( sal_Int64 nLocation )
259 std::unique_lock aGuard( maMutex );
260 checkConnected();
261 checkError();
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) );
267 checkError();
269 sal_Int64 SAL_CALL OTempFileService::getPosition( )
271 std::unique_lock aGuard( maMutex );
272 checkConnected();
274 sal_uInt32 nPos = mpStream->Tell();
275 checkError();
276 return static_cast<sal_Int64>(nPos);
278 sal_Int64 SAL_CALL OTempFileService::getLength( )
280 std::unique_lock aGuard( maMutex );
281 checkConnected();
283 checkError();
285 sal_Int64 nEndPos = mpStream->TellEnd();
287 return nEndPos;
290 // XStream
292 css::uno::Reference< css::io::XInputStream > SAL_CALL OTempFileService::getInputStream()
294 return this;
297 css::uno::Reference< css::io::XOutputStream > SAL_CALL OTempFileService::getOutputStream()
299 return this;
302 // XTruncate
304 void SAL_CALL OTempFileService::truncate()
306 std::unique_lock aGuard( maMutex );
307 checkConnected();
308 // SetStreamSize() call does not change the position
309 mpStream->Seek( 0 );
310 mpStream->SetStreamSize( 0 );
311 checkError();
314 #define PROPERTY_HANDLE_URI 1
315 #define PROPERTY_HANDLE_REMOVE_FILE 2
316 #define PROPERTY_HANDLE_RESOURCE_NAME 3
318 // XPropertySet
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(),
328 0 ),
329 css::beans::Property( "ResourceName", PROPERTY_HANDLE_RESOURCE_NAME, cppu::UnoType<OUString>::get(),
330 css::beans::PropertyAttribute::READONLY )
332 true );
333 static css::uno::Reference< css::beans::XPropertySetInfo > xInfo(
334 ::cppu::OPropertySetHelper::createPropertySetInfo( ourPropertyInfo ) );
335 return xInfo;
337 void OTempFileService::setPropertyValue( const ::rtl::OUString& aPropertyName, const ::css::uno::Any& aValue )
339 if ( aPropertyName == "RemoveFile" )
340 setRemoveFile( aValue.get<bool>() );
341 else
343 assert(false);
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());
355 else
357 assert(false);
358 throw css::beans::UnknownPropertyException(aPropertyName);
361 void OTempFileService::addPropertyChangeListener( const ::rtl::OUString& /*aPropertyName*/, const ::css::uno::Reference< ::css::beans::XPropertyChangeListener >& /*xListener*/ )
363 assert(false);
365 void OTempFileService::removePropertyChangeListener( const ::rtl::OUString& /*aPropertyName*/, const ::css::uno::Reference< ::css::beans::XPropertyChangeListener >& /*xListener*/ )
367 assert(false);
369 void OTempFileService::addVetoableChangeListener( const ::rtl::OUString& /*aPropertyName*/, const ::css::uno::Reference< ::css::beans::XVetoableChangeListener >& /*xListener*/ )
371 assert(false);
373 void OTempFileService::removeVetoableChangeListener( const ::rtl::OUString& /*aPropertyName*/, const ::css::uno::Reference< ::css::beans::XVetoableChangeListener >& /*xListener*/ )
375 assert(false);
377 // XFastPropertySet
378 void OTempFileService::setFastPropertyValue( ::sal_Int32 nHandle, const ::css::uno::Any& aValue )
380 switch (nHandle)
382 case PROPERTY_HANDLE_REMOVE_FILE: setRemoveFile( aValue.get<bool>() ); return;
384 assert(false);
385 throw css::beans::UnknownPropertyException(OUString::number(nHandle));
387 ::css::uno::Any OTempFileService::getFastPropertyValue( ::sal_Int32 nHandle )
389 switch (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());
395 assert(false);
396 throw css::beans::UnknownPropertyException(OUString::number(nHandle));
398 // XPropertyAccess
399 ::css::uno::Sequence< ::css::beans::PropertyValue > OTempFileService::getPropertyValues()
401 return {
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 );
413 // XServiceInfo
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: */