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 "com/sun/star/io/IOException.hpp"
21 #include "com/sun/star/uno/RuntimeException.hpp"
22 #include "osl/diagnose.h"
28 using namespace fileaccess
;
29 using namespace com::sun::star
;
30 using namespace com::sun::star::ucb
;
34 /******************************************************************************/
36 /* XStream_impl implementation */
38 /******************************************************************************/
42 XStream_impl::queryInterface(
43 const uno::Type
& rType
)
44 throw( uno::RuntimeException
)
46 uno::Any aRet
= cppu::queryInterface( rType
,
47 (static_cast< lang::XTypeProvider
* >(this)),
48 (static_cast< io::XStream
* >(this)),
49 (static_cast< io::XInputStream
* >(this)),
50 (static_cast< io::XOutputStream
* >(this)),
51 (static_cast< io::XSeekable
* >(this)),
52 (static_cast< io::XTruncate
* >(this)),
53 (static_cast< io::XAsyncOutputMonitor
* >(this)) );
54 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
59 XStream_impl::acquire(
63 OWeakObject::acquire();
68 XStream_impl::release(
72 OWeakObject::release();
76 //////////////////////////////////////////////////////////////////////////////////////////
78 //////////////////////////////////////////////////////////////////////////////////////////
81 XTYPEPROVIDER_IMPL_7( XStream_impl
,
88 io::XAsyncOutputMonitor
)
92 XStream_impl::XStream_impl( shell
* pMyShell
,const rtl::OUString
& aUncPath
, sal_Bool bLock
)
93 : m_bInputStreamCalled( false ),
94 m_bOutputStreamCalled( false ),
95 m_pMyShell( pMyShell
),
96 m_xProvider( m_pMyShell
->m_pProvider
),
98 m_nErrorCode( TASKHANDLER_NO_ERROR
),
99 m_nMinorErrorCode( TASKHANDLER_NO_ERROR
)
101 sal_uInt32 nFlags
= ( osl_File_OpenFlag_Read
| osl_File_OpenFlag_Write
);
103 nFlags
|= osl_File_OpenFlag_NoLock
;
105 osl::FileBase::RC err
= m_aFile
.open( nFlags
);
106 if( err
!= osl::FileBase::E_None
)
111 m_nErrorCode
= TASKHANDLING_OPEN_FOR_STREAM
;
112 m_nMinorErrorCode
= err
;
119 XStream_impl::~XStream_impl()
125 catch (const io::IOException
&)
127 OSL_FAIL("unexpected situation");
129 catch (const uno::RuntimeException
&)
131 OSL_FAIL("unexpected situation");
136 sal_Int32 SAL_CALL
XStream_impl::CtorSuccess()
143 sal_Int32 SAL_CALL
XStream_impl::getMinorError()
145 return m_nMinorErrorCode
;
150 uno::Reference
< io::XInputStream
> SAL_CALL
151 XStream_impl::getInputStream( )
152 throw( uno::RuntimeException
)
155 osl::MutexGuard
aGuard( m_aMutex
);
156 m_bInputStreamCalled
= true;
158 return uno::Reference
< io::XInputStream
>( this );
162 uno::Reference
< io::XOutputStream
> SAL_CALL
163 XStream_impl::getOutputStream( )
164 throw( uno::RuntimeException
)
167 osl::MutexGuard
aGuard( m_aMutex
);
168 m_bOutputStreamCalled
= true;
170 return uno::Reference
< io::XOutputStream
>( this );
174 void SAL_CALL
XStream_impl::truncate(void)
175 throw( io::IOException
, uno::RuntimeException
)
177 if (osl::FileBase::E_None
!= m_aFile
.setSize(0))
178 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
180 if (osl::FileBase::E_None
!= m_aFile
.setPos(osl_Pos_Absolut
,sal_uInt64(0)))
181 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
186 //===========================================================================
187 // XStream_impl private non interface methods
188 //===========================================================================
191 XStream_impl::readBytes(
192 uno::Sequence
< sal_Int8
>& aData
,
193 sal_Int32 nBytesToRead
)
194 throw( io::NotConnectedException
,
195 io::BufferSizeExceededException
,
197 uno::RuntimeException
)
200 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
205 buffer
= new sal_Int8
[nBytesToRead
];
207 catch (const std::bad_alloc
&)
209 if( m_nIsOpen
) m_aFile
.close();
210 throw io::BufferSizeExceededException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
214 if(m_aFile
.read( (void* )buffer
,sal_uInt64(nBytesToRead
),nrc
)
215 != osl::FileBase::E_None
)
218 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
220 aData
= uno::Sequence
< sal_Int8
> ( buffer
, (sal_uInt32
)nrc
);
222 return ( sal_Int32
) nrc
;
227 XStream_impl::readSomeBytes(
228 uno::Sequence
< sal_Int8
>& aData
,
229 sal_Int32 nMaxBytesToRead
)
230 throw( io::NotConnectedException
,
231 io::BufferSizeExceededException
,
233 uno::RuntimeException
)
235 return readBytes( aData
,nMaxBytesToRead
);
240 XStream_impl::skipBytes(
241 sal_Int32 nBytesToSkip
)
242 throw( io::NotConnectedException
,
243 io::BufferSizeExceededException
,
245 uno::RuntimeException
)
247 m_aFile
.setPos( osl_Pos_Current
, sal_uInt64( nBytesToSkip
) );
252 XStream_impl::available(
254 throw( io::NotConnectedException
,
256 uno::RuntimeException
)
263 XStream_impl::writeBytes( const uno::Sequence
< sal_Int8
>& aData
)
264 throw( io::NotConnectedException
,
265 io::BufferSizeExceededException
,
267 uno::RuntimeException
)
269 sal_uInt32 length
= aData
.getLength();
272 sal_uInt64
nWrittenBytes(0);
273 const sal_Int8
* p
= aData
.getConstArray();
274 if(osl::FileBase::E_None
!= m_aFile
.write(((void*)(p
)),sal_uInt64(length
),nWrittenBytes
) ||
275 nWrittenBytes
!= length
)
276 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
282 XStream_impl::closeStream(
284 throw( io::NotConnectedException
,
286 uno::RuntimeException
)
290 osl::FileBase::RC err
= m_aFile
.close();
292 if( err
!= osl::FileBase::E_None
) {
294 ex
.Message
= rtl::OUString( "could not close file");
303 XStream_impl::closeInput(
305 throw( io::NotConnectedException
,
307 uno::RuntimeException
)
309 osl::MutexGuard
aGuard( m_aMutex
);
310 m_bInputStreamCalled
= false;
312 if( ! m_bOutputStreamCalled
)
318 XStream_impl::closeOutput(
320 throw( io::NotConnectedException
,
322 uno::RuntimeException
)
324 osl::MutexGuard
aGuard( m_aMutex
);
325 m_bOutputStreamCalled
= false;
327 if( ! m_bInputStreamCalled
)
335 throw( lang::IllegalArgumentException
,
337 uno::RuntimeException
)
340 throw lang::IllegalArgumentException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>(), 0 );
341 if( osl::FileBase::E_None
!= m_aFile
.setPos( osl_Pos_Absolut
, sal_uInt64( location
) ) )
342 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
347 XStream_impl::getPosition(
349 throw( io::IOException
,
350 uno::RuntimeException
)
353 if( osl::FileBase::E_None
!= m_aFile
.getPos( uPos
) )
354 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
355 return sal_Int64( uPos
);
359 XStream_impl::getLength(
361 throw( io::IOException
,
362 uno::RuntimeException
)
365 if ( m_aFile
.getSize(uEndPos
) != osl::FileBase::E_None
)
366 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
368 return sal_Int64( uEndPos
);
372 XStream_impl::flush()
373 throw( io::NotConnectedException
,
374 io::BufferSizeExceededException
,
376 uno::RuntimeException
)
379 void XStream_impl::waitForCompletion()
380 throw (io::IOException
, uno::RuntimeException
)
382 // At least on UNIX, to reliably learn about any errors encountered by
383 // asynchronous NFS write operations, without closing the file directly
384 // afterwards, there appears to be no cheaper way than to call fsync:
385 if (m_nIsOpen
&& m_aFile
.sync() != osl::FileBase::E_None
) {
386 throw io::IOException(
387 rtl::OUString( "could not synchronize file to disc"),
388 static_cast< OWeakObject
* >(this));
392 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */