Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "com/sun/star/io/IOException.hpp"
30 : : #include "com/sun/star/uno/RuntimeException.hpp"
31 : : #include "osl/diagnose.h"
32 : : #include "filstr.hxx"
33 : : #include "shell.hxx"
34 : : #include "prov.hxx"
35 : :
36 : :
37 : : using namespace fileaccess;
38 : : using namespace com::sun::star;
39 : : using namespace com::sun::star::ucb;
40 : :
41 : :
42 : :
43 : : /******************************************************************************/
44 : : /* */
45 : : /* XStream_impl implementation */
46 : : /* */
47 : : /******************************************************************************/
48 : :
49 : :
50 : : uno::Any SAL_CALL
51 : 15339 : XStream_impl::queryInterface(
52 : : const uno::Type& rType )
53 : : throw( uno::RuntimeException)
54 : : {
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 [ + - ]: 15339 : (static_cast< io::XAsyncOutputMonitor* >(this)) );
63 [ + + ][ + - ]: 15339 : return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
64 : : }
65 : :
66 : :
67 : : void SAL_CALL
68 : 199497 : XStream_impl::acquire(
69 : : void )
70 : : throw()
71 : : {
72 : 199497 : OWeakObject::acquire();
73 : 199497 : }
74 : :
75 : :
76 : : void SAL_CALL
77 : 198568 : XStream_impl::release(
78 : : void )
79 : : throw()
80 : : {
81 : 198568 : OWeakObject::release();
82 : 198568 : }
83 : :
84 : :
85 : : //////////////////////////////////////////////////////////////////////////////////////////
86 : : // XTypeProvider
87 : : //////////////////////////////////////////////////////////////////////////////////////////
88 : :
89 : :
90 [ # # ][ # # ]: 0 : XTYPEPROVIDER_IMPL_7( XStream_impl,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
91 : : lang::XTypeProvider,
92 : : io::XStream,
93 : : io::XSeekable,
94 : : io::XInputStream,
95 : : io::XOutputStream,
96 : : io::XTruncate,
97 : : io::XAsyncOutputMonitor )
98 : :
99 : :
100 : :
101 : 10023 : 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 ),
106 : : m_aFile( aUncPath ),
107 : : m_nErrorCode( TASKHANDLER_NO_ERROR ),
108 [ + - ][ + - ]: 10023 : m_nMinorErrorCode( TASKHANDLER_NO_ERROR )
[ + - ][ + - ]
109 : : {
110 : 10023 : sal_uInt32 nFlags = ( osl_File_OpenFlag_Read | osl_File_OpenFlag_Write );
111 [ - + ]: 10023 : if ( !bLock )
112 : 0 : nFlags |= osl_File_OpenFlag_NoLock;
113 : :
114 [ + - ]: 10023 : osl::FileBase::RC err = m_aFile.open( nFlags );
115 [ + + ]: 10023 : if( err != osl::FileBase::E_None )
116 : : {
117 : 321 : m_nIsOpen = false;
118 [ + - ]: 321 : m_aFile.close();
119 : :
120 : 321 : m_nErrorCode = TASKHANDLING_OPEN_FOR_STREAM;
121 : 321 : m_nMinorErrorCode = err;
122 : : }
123 : : else
124 : 9702 : m_nIsOpen = true;
125 : 10023 : }
126 : :
127 : :
128 [ + - ][ + - ]: 9825 : XStream_impl::~XStream_impl()
129 : : {
130 : : try
131 : : {
132 [ + - ]: 9825 : closeStream();
133 : : }
134 [ # # ]: 0 : catch (const io::IOException&)
135 : : {
136 : : OSL_FAIL("unexpected situation");
137 : : }
138 [ # # ]: 0 : catch (const uno::RuntimeException&)
139 : : {
140 : : OSL_FAIL("unexpected situation");
141 : : }
142 [ - + ]: 19650 : }
[ # # # ]
143 : :
144 : :
145 : 10023 : sal_Int32 SAL_CALL XStream_impl::CtorSuccess()
146 : : {
147 : 10023 : return m_nErrorCode;
148 : : }
149 : :
150 : :
151 : :
152 : 321 : sal_Int32 SAL_CALL XStream_impl::getMinorError()
153 : : {
154 : 321 : return m_nMinorErrorCode;
155 : : }
156 : :
157 : :
158 : :
159 : : uno::Reference< io::XInputStream > SAL_CALL
160 : 13357 : XStream_impl::getInputStream( )
161 : : throw( uno::RuntimeException)
162 : : {
163 : : {
164 [ + - ]: 13357 : osl::MutexGuard aGuard( m_aMutex );
165 [ + - ]: 13357 : m_bInputStreamCalled = true;
166 : : }
167 : 13357 : return uno::Reference< io::XInputStream >( this );
168 : : }
169 : :
170 : :
171 : : uno::Reference< io::XOutputStream > SAL_CALL
172 : 13153 : XStream_impl::getOutputStream( )
173 : : throw( uno::RuntimeException )
174 : : {
175 : : {
176 [ + - ]: 13153 : osl::MutexGuard aGuard( m_aMutex );
177 [ + - ]: 13153 : m_bOutputStreamCalled = true;
178 : : }
179 : 13153 : return uno::Reference< io::XOutputStream >( this );
180 : : }
181 : :
182 : :
183 : 282 : void SAL_CALL XStream_impl::truncate(void)
184 : : throw( io::IOException, uno::RuntimeException )
185 : : {
186 [ - + ]: 282 : if (osl::FileBase::E_None != m_aFile.setSize(0))
187 [ # # ]: 0 : throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX ), uno::Reference< uno::XInterface >() );
188 : :
189 [ - + ]: 282 : if (osl::FileBase::E_None != m_aFile.setPos(osl_Pos_Absolut,sal_uInt64(0)))
190 [ # # ]: 0 : throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX ), uno::Reference< uno::XInterface >() );
191 : 282 : }
192 : :
193 : :
194 : :
195 : : //===========================================================================
196 : : // XStream_impl private non interface methods
197 : : //===========================================================================
198 : :
199 : : sal_Int32 SAL_CALL
200 : 195499 : XStream_impl::readBytes(
201 : : uno::Sequence< sal_Int8 >& aData,
202 : : sal_Int32 nBytesToRead )
203 : : throw( io::NotConnectedException,
204 : : io::BufferSizeExceededException,
205 : : io::IOException,
206 : : uno::RuntimeException)
207 : : {
208 [ - + ]: 195499 : if( ! m_nIsOpen )
209 [ # # ]: 0 : throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX ), uno::Reference< uno::XInterface >() );
210 : :
211 : : sal_Int8 * buffer;
212 : : try
213 : : {
214 [ + - ]: 195499 : buffer = new sal_Int8[nBytesToRead];
215 : : }
216 [ # # ]: 0 : catch (const std::bad_alloc&)
217 : : {
218 [ # # # # ]: 0 : if( m_nIsOpen ) m_aFile.close();
219 [ # # ]: 0 : throw io::BufferSizeExceededException( ::rtl::OUString( OSL_LOG_PREFIX ), uno::Reference< uno::XInterface >() );
220 : : }
221 : :
222 : 195499 : sal_uInt64 nrc(0);
223 [ + - ][ - + ]: 195499 : if(m_aFile.read( (void* )buffer,sal_uInt64(nBytesToRead),nrc )
224 : : != osl::FileBase::E_None)
225 : : {
226 [ # # ]: 0 : delete[] buffer;
227 [ # # ]: 0 : throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX ), uno::Reference< uno::XInterface >() );
228 : : }
229 [ + - ][ + - ]: 195499 : aData = uno::Sequence< sal_Int8 > ( buffer, (sal_uInt32)nrc );
[ + - ]
230 [ + - ]: 195499 : delete[] buffer;
231 : 195499 : return ( sal_Int32 ) nrc;
232 : : }
233 : :
234 : :
235 : : sal_Int32 SAL_CALL
236 : 160148 : XStream_impl::readSomeBytes(
237 : : uno::Sequence< sal_Int8 >& aData,
238 : : sal_Int32 nMaxBytesToRead )
239 : : throw( io::NotConnectedException,
240 : : io::BufferSizeExceededException,
241 : : io::IOException,
242 : : uno::RuntimeException)
243 : : {
244 : 160148 : return readBytes( aData,nMaxBytesToRead );
245 : : }
246 : :
247 : :
248 : : void SAL_CALL
249 : 16 : XStream_impl::skipBytes(
250 : : sal_Int32 nBytesToSkip )
251 : : throw( io::NotConnectedException,
252 : : io::BufferSizeExceededException,
253 : : io::IOException,
254 : : uno::RuntimeException )
255 : : {
256 : 16 : m_aFile.setPos( osl_Pos_Current, sal_uInt64( nBytesToSkip ) );
257 : 16 : }
258 : :
259 : :
260 : : sal_Int32 SAL_CALL
261 : 16 : XStream_impl::available(
262 : : void )
263 : : throw( io::NotConnectedException,
264 : : io::IOException,
265 : : uno::RuntimeException)
266 : : {
267 : 16 : return 0;
268 : : }
269 : :
270 : :
271 : : void SAL_CALL
272 : 50468 : XStream_impl::writeBytes( const uno::Sequence< sal_Int8 >& aData )
273 : : throw( io::NotConnectedException,
274 : : io::BufferSizeExceededException,
275 : : io::IOException,
276 : : uno::RuntimeException)
277 : : {
278 : 50468 : sal_uInt32 length = aData.getLength();
279 [ + + ]: 50468 : if(length)
280 : : {
281 : 50400 : sal_uInt64 nWrittenBytes(0);
282 : 50400 : const sal_Int8* p = aData.getConstArray();
283 [ + - ][ - + ]: 50400 : if(osl::FileBase::E_None != m_aFile.write(((void*)(p)),sal_uInt64(length),nWrittenBytes) ||
[ - + ][ + - ]
284 : : nWrittenBytes != length )
285 [ # # ]: 50400 : throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX ), uno::Reference< uno::XInterface >() );
286 : : }
287 : 50468 : }
288 : :
289 : :
290 : : void SAL_CALL
291 : 10950 : XStream_impl::closeStream(
292 : : void )
293 : : throw( io::NotConnectedException,
294 : : io::IOException,
295 : : uno::RuntimeException )
296 : : {
297 [ + + ]: 10950 : if( m_nIsOpen )
298 : : {
299 : 9504 : osl::FileBase::RC err = m_aFile.close();
300 : :
301 [ - + ]: 9504 : if( err != osl::FileBase::E_None ) {
302 [ # # ]: 0 : io::IOException ex;
303 : 0 : ex.Message = rtl::OUString( "could not close file");
304 [ # # ]: 0 : throw ex;
305 : : }
306 : :
307 : 9504 : m_nIsOpen = false;
308 : : }
309 : 10950 : }
310 : :
311 : : void SAL_CALL
312 : 630 : XStream_impl::closeInput(
313 : : void )
314 : : throw( io::NotConnectedException,
315 : : io::IOException,
316 : : uno::RuntimeException )
317 : : {
318 [ + - ]: 630 : osl::MutexGuard aGuard( m_aMutex );
319 : 630 : m_bInputStreamCalled = false;
320 : :
321 [ + + ]: 630 : if( ! m_bOutputStreamCalled )
322 [ + - ][ + - ]: 630 : closeStream();
323 : 630 : }
324 : :
325 : :
326 : : void SAL_CALL
327 : 1125 : XStream_impl::closeOutput(
328 : : void )
329 : : throw( io::NotConnectedException,
330 : : io::IOException,
331 : : uno::RuntimeException )
332 : : {
333 [ + - ]: 1125 : osl::MutexGuard aGuard( m_aMutex );
334 : 1125 : m_bOutputStreamCalled = false;
335 : :
336 [ + + ]: 1125 : if( ! m_bInputStreamCalled )
337 [ + - ][ + - ]: 1125 : closeStream();
338 : 1125 : }
339 : :
340 : :
341 : : void SAL_CALL
342 : 178854 : XStream_impl::seek(
343 : : sal_Int64 location )
344 : : throw( lang::IllegalArgumentException,
345 : : io::IOException,
346 : : uno::RuntimeException )
347 : : {
348 [ - + ]: 178854 : if( location < 0 )
349 [ # # ]: 0 : throw lang::IllegalArgumentException( ::rtl::OUString( OSL_LOG_PREFIX ), uno::Reference< uno::XInterface >(), 0 );
350 [ - + ]: 178854 : if( osl::FileBase::E_None != m_aFile.setPos( osl_Pos_Absolut, sal_uInt64( location ) ) )
351 [ # # ]: 0 : throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX ), uno::Reference< uno::XInterface >() );
352 : 178854 : }
353 : :
354 : :
355 : : sal_Int64 SAL_CALL
356 : 634834 : XStream_impl::getPosition(
357 : : void )
358 : : throw( io::IOException,
359 : : uno::RuntimeException )
360 : : {
361 : : sal_uInt64 uPos;
362 [ + - ][ - + ]: 634834 : if( osl::FileBase::E_None != m_aFile.getPos( uPos ) )
363 [ # # ]: 0 : throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX ), uno::Reference< uno::XInterface >() );
364 : 634834 : return sal_Int64( uPos );
365 : : }
366 : :
367 : : sal_Int64 SAL_CALL
368 : 20210 : XStream_impl::getLength(
369 : : void )
370 : : throw( io::IOException,
371 : : uno::RuntimeException )
372 : : {
373 : : sal_uInt64 uEndPos;
374 [ + - ][ - + ]: 20210 : if ( m_aFile.getSize(uEndPos) != osl::FileBase::E_None )
375 [ # # ]: 0 : throw io::IOException( ::rtl::OUString( OSL_LOG_PREFIX ), uno::Reference< uno::XInterface >() );
376 : : else
377 : 20210 : return sal_Int64( uEndPos );
378 : : }
379 : :
380 : : void SAL_CALL
381 : 10022 : XStream_impl::flush()
382 : : throw( io::NotConnectedException,
383 : : io::BufferSizeExceededException,
384 : : io::IOException,
385 : : uno::RuntimeException )
386 : 10022 : {}
387 : :
388 : 325 : void XStream_impl::waitForCompletion()
389 : : throw (io::IOException, uno::RuntimeException)
390 : : {
391 : : // At least on UNIX, to reliably learn about any errors encountered by
392 : : // asynchronous NFS write operations, without closing the file directly
393 : : // afterwards, there appears to be no cheaper way than to call fsync:
394 [ + - ][ - + ]: 325 : if (m_nIsOpen && m_aFile.sync() != osl::FileBase::E_None) {
[ - + ]
395 : : throw io::IOException(
396 : : rtl::OUString( "could not synchronize file to disc"),
397 [ # # ][ # # ]: 0 : static_cast< OWeakObject * >(this));
398 : : }
399 : 325 : }
400 : :
401 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|