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"
26 #include <boost/scoped_array.hpp>
28 using namespace fileaccess
;
29 using namespace com::sun::star
;
30 using namespace com::sun::star::ucb
;
32 #if OSL_DEBUG_LEVEL > 0
33 #define THROW_WHERE SAL_WHERE
35 #define THROW_WHERE ""
38 /******************************************************************************/
40 /* XStream_impl implementation */
42 /******************************************************************************/
44 XStream_impl::XStream_impl( shell
* pMyShell
,const OUString
& aUncPath
, bool bLock
)
45 : m_bInputStreamCalled( false ),
46 m_bOutputStreamCalled( false ),
47 m_pMyShell( pMyShell
),
48 m_xProvider( m_pMyShell
->m_pProvider
),
50 m_nErrorCode( TASKHANDLER_NO_ERROR
),
51 m_nMinorErrorCode( TASKHANDLER_NO_ERROR
)
53 sal_uInt32 nFlags
= ( osl_File_OpenFlag_Read
| osl_File_OpenFlag_Write
);
55 nFlags
|= osl_File_OpenFlag_NoLock
;
57 osl::FileBase::RC err
= m_aFile
.open( nFlags
);
58 if( err
!= osl::FileBase::E_None
)
63 m_nErrorCode
= TASKHANDLING_OPEN_FOR_STREAM
;
64 m_nMinorErrorCode
= err
;
71 XStream_impl::~XStream_impl()
77 catch (const io::IOException
&)
79 OSL_FAIL("unexpected situation");
81 catch (const uno::RuntimeException
&)
83 OSL_FAIL("unexpected situation");
94 uno::Reference
< io::XInputStream
> SAL_CALL
95 XStream_impl::getInputStream( )
96 throw( uno::RuntimeException
, std::exception
)
99 osl::MutexGuard
aGuard( m_aMutex
);
100 m_bInputStreamCalled
= true;
102 return uno::Reference
< io::XInputStream
>( this );
106 uno::Reference
< io::XOutputStream
> SAL_CALL
107 XStream_impl::getOutputStream( )
108 throw( uno::RuntimeException
, std::exception
)
111 osl::MutexGuard
aGuard( m_aMutex
);
112 m_bOutputStreamCalled
= true;
114 return uno::Reference
< io::XOutputStream
>( this );
118 void SAL_CALL
XStream_impl::truncate()
119 throw( io::IOException
, uno::RuntimeException
, std::exception
)
121 if (osl::FileBase::E_None
!= m_aFile
.setSize(0))
122 throw io::IOException( THROW_WHERE
);
124 if (osl::FileBase::E_None
!= m_aFile
.setPos(osl_Pos_Absolut
,sal_uInt64(0)))
125 throw io::IOException( THROW_WHERE
);
131 // XStream_impl private non interface methods
135 XStream_impl::readBytes(
136 uno::Sequence
< sal_Int8
>& aData
,
137 sal_Int32 nBytesToRead
)
138 throw( io::NotConnectedException
,
139 io::BufferSizeExceededException
,
141 uno::RuntimeException
, std::exception
)
144 throw io::IOException( THROW_WHERE
);
146 boost::scoped_array
<sal_Int8
> buffer
;
149 buffer
.reset(new sal_Int8
[nBytesToRead
]);
151 catch (const std::bad_alloc
&)
153 if( m_nIsOpen
) m_aFile
.close();
154 throw io::BufferSizeExceededException( THROW_WHERE
);
158 if(m_aFile
.read( buffer
.get(),sal_uInt64(nBytesToRead
),nrc
)
159 != osl::FileBase::E_None
)
161 throw io::IOException( THROW_WHERE
);
163 aData
= uno::Sequence
< sal_Int8
> ( buffer
.get(), (sal_uInt32
)nrc
);
164 return ( sal_Int32
) nrc
;
169 XStream_impl::readSomeBytes(
170 uno::Sequence
< sal_Int8
>& aData
,
171 sal_Int32 nMaxBytesToRead
)
172 throw( io::NotConnectedException
,
173 io::BufferSizeExceededException
,
175 uno::RuntimeException
, std::exception
)
177 return readBytes( aData
,nMaxBytesToRead
);
182 XStream_impl::skipBytes(
183 sal_Int32 nBytesToSkip
)
184 throw( io::NotConnectedException
,
185 io::BufferSizeExceededException
,
187 uno::RuntimeException
, std::exception
)
189 m_aFile
.setPos( osl_Pos_Current
, sal_uInt64( nBytesToSkip
) );
194 XStream_impl::available(
196 throw( io::NotConnectedException
,
198 uno::RuntimeException
, std::exception
)
205 XStream_impl::writeBytes( const uno::Sequence
< sal_Int8
>& aData
)
206 throw( io::NotConnectedException
,
207 io::BufferSizeExceededException
,
209 uno::RuntimeException
, std::exception
)
211 sal_uInt32 length
= aData
.getLength();
214 sal_uInt64
nWrittenBytes(0);
215 const sal_Int8
* p
= aData
.getConstArray();
216 if(osl::FileBase::E_None
!= m_aFile
.write(((void*)(p
)),sal_uInt64(length
),nWrittenBytes
) ||
217 nWrittenBytes
!= length
)
218 throw io::IOException( THROW_WHERE
);
224 XStream_impl::closeStream(
226 throw( io::NotConnectedException
,
228 uno::RuntimeException
)
232 osl::FileBase::RC err
= m_aFile
.close();
234 if( err
!= osl::FileBase::E_None
) {
236 ex
.Message
= "could not close file";
245 XStream_impl::closeInput(
247 throw( io::NotConnectedException
,
249 uno::RuntimeException
, std::exception
)
251 osl::MutexGuard
aGuard( m_aMutex
);
252 m_bInputStreamCalled
= false;
254 if( ! m_bOutputStreamCalled
)
260 XStream_impl::closeOutput(
262 throw( io::NotConnectedException
,
264 uno::RuntimeException
, std::exception
)
266 osl::MutexGuard
aGuard( m_aMutex
);
267 m_bOutputStreamCalled
= false;
269 if( ! m_bInputStreamCalled
)
277 throw( lang::IllegalArgumentException
,
279 uno::RuntimeException
, std::exception
)
282 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
283 if( osl::FileBase::E_None
!= m_aFile
.setPos( osl_Pos_Absolut
, sal_uInt64( location
) ) )
284 throw io::IOException( THROW_WHERE
);
289 XStream_impl::getPosition(
291 throw( io::IOException
,
292 uno::RuntimeException
, std::exception
)
295 if( osl::FileBase::E_None
!= m_aFile
.getPos( uPos
) )
296 throw io::IOException( THROW_WHERE
);
297 return sal_Int64( uPos
);
301 XStream_impl::getLength(
303 throw( io::IOException
,
304 uno::RuntimeException
, std::exception
)
307 if ( m_aFile
.getSize(uEndPos
) != osl::FileBase::E_None
)
308 throw io::IOException( THROW_WHERE
);
310 return sal_Int64( uEndPos
);
314 XStream_impl::flush()
315 throw( io::NotConnectedException
,
316 io::BufferSizeExceededException
,
318 uno::RuntimeException
, std::exception
)
321 void XStream_impl::waitForCompletion()
322 throw (io::IOException
, uno::RuntimeException
, std::exception
)
324 // At least on UNIX, to reliably learn about any errors encountered by
325 // asynchronous NFS write operations, without closing the file directly
326 // afterwards, there appears to be no cheaper way than to call fsync:
327 if (m_nIsOpen
&& m_aFile
.sync() != osl::FileBase::E_None
) {
328 throw io::IOException(
329 OUString( "could not synchronize file to disc"),
330 static_cast< OWeakObject
* >(this));
334 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */