1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "com/sun/star/io/IOException.hpp"
30 #include "com/sun/star/uno/RuntimeException.hpp"
31 #include "osl/diagnose.h"
37 using namespace fileaccess
;
38 using namespace com::sun::star
;
39 using namespace com::sun::star::ucb
;
43 /******************************************************************************/
45 /* XStream_impl implementation */
47 /******************************************************************************/
51 XStream_impl::queryInterface(
52 const uno::Type
& rType
)
53 throw( uno::RuntimeException
)
55 uno::Any aRet
= cppu::queryInterface( rType
,
56 (static_cast< lang::XTypeProvider
* >(this)),
57 (static_cast< io::XStream
* >(this)),
58 (static_cast< io::XInputStream
* >(this)),
59 (static_cast< io::XOutputStream
* >(this)),
60 (static_cast< io::XSeekable
* >(this)),
61 (static_cast< io::XTruncate
* >(this)),
62 (static_cast< io::XAsyncOutputMonitor
* >(this)) );
63 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
68 XStream_impl::acquire(
72 OWeakObject::acquire();
77 XStream_impl::release(
81 OWeakObject::release();
85 //////////////////////////////////////////////////////////////////////////////////////////
87 //////////////////////////////////////////////////////////////////////////////////////////
90 XTYPEPROVIDER_IMPL_7( XStream_impl
,
97 io::XAsyncOutputMonitor
)
101 XStream_impl::XStream_impl( shell
* pMyShell
,const rtl::OUString
& aUncPath
, sal_Bool bLock
)
102 : m_bInputStreamCalled( false ),
103 m_bOutputStreamCalled( false ),
104 m_pMyShell( pMyShell
),
105 m_xProvider( m_pMyShell
->m_pProvider
),
108 m_nErrorCode( TASKHANDLER_NO_ERROR
),
109 m_nMinorErrorCode( TASKHANDLER_NO_ERROR
)
111 sal_uInt32 nFlags
= ( osl_File_OpenFlag_Read
| osl_File_OpenFlag_Write
);
113 nFlags
|= osl_File_OpenFlag_NoLock
;
115 osl::FileBase::RC err
= m_aFile
.open( nFlags
);
116 if( err
!= osl::FileBase::E_None
)
121 m_nErrorCode
= TASKHANDLING_OPEN_FOR_STREAM
;
122 m_nMinorErrorCode
= err
;
129 XStream_impl::~XStream_impl()
135 catch (const io::IOException
&)
137 OSL_FAIL("unexpected situation");
139 catch (const uno::RuntimeException
&)
141 OSL_FAIL("unexpected situation");
146 sal_Int32 SAL_CALL
XStream_impl::CtorSuccess()
153 sal_Int32 SAL_CALL
XStream_impl::getMinorError()
155 return m_nMinorErrorCode
;
160 uno::Reference
< io::XInputStream
> SAL_CALL
161 XStream_impl::getInputStream( )
162 throw( uno::RuntimeException
)
165 osl::MutexGuard
aGuard( m_aMutex
);
166 m_bInputStreamCalled
= true;
168 return uno::Reference
< io::XInputStream
>( this );
172 uno::Reference
< io::XOutputStream
> SAL_CALL
173 XStream_impl::getOutputStream( )
174 throw( uno::RuntimeException
)
177 osl::MutexGuard
aGuard( m_aMutex
);
178 m_bOutputStreamCalled
= true;
180 return uno::Reference
< io::XOutputStream
>( this );
184 void SAL_CALL
XStream_impl::truncate(void)
185 throw( io::IOException
, uno::RuntimeException
)
187 if (osl::FileBase::E_None
!= m_aFile
.setSize(0))
188 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
190 if (osl::FileBase::E_None
!= m_aFile
.setPos(osl_Pos_Absolut
,sal_uInt64(0)))
191 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
196 //===========================================================================
197 // XStream_impl private non interface methods
198 //===========================================================================
201 XStream_impl::readBytes(
202 uno::Sequence
< sal_Int8
>& aData
,
203 sal_Int32 nBytesToRead
)
204 throw( io::NotConnectedException
,
205 io::BufferSizeExceededException
,
207 uno::RuntimeException
)
210 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
215 buffer
= new sal_Int8
[nBytesToRead
];
217 catch (const std::bad_alloc
&)
219 if( m_nIsOpen
) m_aFile
.close();
220 throw io::BufferSizeExceededException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
224 if(m_aFile
.read( (void* )buffer
,sal_uInt64(nBytesToRead
),nrc
)
225 != osl::FileBase::E_None
)
228 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
230 aData
= uno::Sequence
< sal_Int8
> ( buffer
, (sal_uInt32
)nrc
);
232 return ( sal_Int32
) nrc
;
237 XStream_impl::readSomeBytes(
238 uno::Sequence
< sal_Int8
>& aData
,
239 sal_Int32 nMaxBytesToRead
)
240 throw( io::NotConnectedException
,
241 io::BufferSizeExceededException
,
243 uno::RuntimeException
)
245 return readBytes( aData
,nMaxBytesToRead
);
250 XStream_impl::skipBytes(
251 sal_Int32 nBytesToSkip
)
252 throw( io::NotConnectedException
,
253 io::BufferSizeExceededException
,
255 uno::RuntimeException
)
257 m_aFile
.setPos( osl_Pos_Current
, sal_uInt64( nBytesToSkip
) );
262 XStream_impl::available(
264 throw( io::NotConnectedException
,
266 uno::RuntimeException
)
273 XStream_impl::writeBytes( const uno::Sequence
< sal_Int8
>& aData
)
274 throw( io::NotConnectedException
,
275 io::BufferSizeExceededException
,
277 uno::RuntimeException
)
279 sal_uInt32 length
= aData
.getLength();
282 sal_uInt64
nWrittenBytes(0);
283 const sal_Int8
* p
= aData
.getConstArray();
284 if(osl::FileBase::E_None
!= m_aFile
.write(((void*)(p
)),sal_uInt64(length
),nWrittenBytes
) ||
285 nWrittenBytes
!= length
)
286 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
292 XStream_impl::closeStream(
294 throw( io::NotConnectedException
,
296 uno::RuntimeException
)
300 osl::FileBase::RC err
= m_aFile
.close();
302 if( err
!= osl::FileBase::E_None
) {
304 ex
.Message
= rtl::OUString( "could not close file");
313 XStream_impl::closeInput(
315 throw( io::NotConnectedException
,
317 uno::RuntimeException
)
319 osl::MutexGuard
aGuard( m_aMutex
);
320 m_bInputStreamCalled
= false;
322 if( ! m_bOutputStreamCalled
)
328 XStream_impl::closeOutput(
330 throw( io::NotConnectedException
,
332 uno::RuntimeException
)
334 osl::MutexGuard
aGuard( m_aMutex
);
335 m_bOutputStreamCalled
= false;
337 if( ! m_bInputStreamCalled
)
345 throw( lang::IllegalArgumentException
,
347 uno::RuntimeException
)
350 throw lang::IllegalArgumentException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>(), 0 );
351 if( osl::FileBase::E_None
!= m_aFile
.setPos( osl_Pos_Absolut
, sal_uInt64( location
) ) )
352 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
357 XStream_impl::getPosition(
359 throw( io::IOException
,
360 uno::RuntimeException
)
363 if( osl::FileBase::E_None
!= m_aFile
.getPos( uPos
) )
364 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
365 return sal_Int64( uPos
);
369 XStream_impl::getLength(
371 throw( io::IOException
,
372 uno::RuntimeException
)
375 if ( m_aFile
.getSize(uEndPos
) != osl::FileBase::E_None
)
376 throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
378 return sal_Int64( uEndPos
);
382 XStream_impl::flush()
383 throw( io::NotConnectedException
,
384 io::BufferSizeExceededException
,
386 uno::RuntimeException
)
389 void XStream_impl::waitForCompletion()
390 throw (io::IOException
, uno::RuntimeException
)
392 // At least on UNIX, to reliably learn about any errors encountered by
393 // asynchronous NFS write operations, without closing the file directly
394 // afterwards, there appears to be no cheaper way than to call fsync:
395 if (m_nIsOpen
&& m_aFile
.sync() != osl::FileBase::E_None
) {
396 throw io::IOException(
397 rtl::OUString( "could not synchronize file to disc"),
398 static_cast< OWeakObject
* >(this));
402 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */