Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "com/sun/star/io/IOException.hpp"
21 : #include "com/sun/star/uno/RuntimeException.hpp"
22 : #include "osl/diagnose.h"
23 : #include "filstr.hxx"
24 : #include "shell.hxx"
25 : #include "prov.hxx"
26 : #include <boost/scoped_array.hpp>
27 :
28 : using namespace fileaccess;
29 : using namespace com::sun::star;
30 : using namespace com::sun::star::ucb;
31 :
32 : #if OSL_DEBUG_LEVEL > 0
33 : #define THROW_WHERE SAL_WHERE
34 : #else
35 : #define THROW_WHERE ""
36 : #endif
37 :
38 : /******************************************************************************/
39 : /* */
40 : /* XStream_impl implementation */
41 : /* */
42 : /******************************************************************************/
43 :
44 38500 : 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 ),
49 : m_aFile( aUncPath ),
50 : m_nErrorCode( TASKHANDLER_NO_ERROR ),
51 38500 : m_nMinorErrorCode( TASKHANDLER_NO_ERROR )
52 : {
53 38500 : sal_uInt32 nFlags = ( osl_File_OpenFlag_Read | osl_File_OpenFlag_Write );
54 38500 : if ( !bLock )
55 0 : nFlags |= osl_File_OpenFlag_NoLock;
56 :
57 38500 : osl::FileBase::RC err = m_aFile.open( nFlags );
58 38500 : if( err != osl::FileBase::E_None )
59 : {
60 179 : m_nIsOpen = false;
61 179 : m_aFile.close();
62 :
63 179 : m_nErrorCode = TASKHANDLING_OPEN_FOR_STREAM;
64 179 : m_nMinorErrorCode = err;
65 : }
66 : else
67 38321 : m_nIsOpen = true;
68 38500 : }
69 :
70 :
71 115425 : XStream_impl::~XStream_impl()
72 : {
73 : try
74 : {
75 38475 : closeStream();
76 : }
77 0 : catch (const io::IOException&)
78 : {
79 : OSL_FAIL("unexpected situation");
80 : }
81 0 : catch (const uno::RuntimeException&)
82 : {
83 : OSL_FAIL("unexpected situation");
84 : }
85 76950 : }
86 :
87 :
88 :
89 :
90 :
91 :
92 :
93 :
94 : uno::Reference< io::XInputStream > SAL_CALL
95 55403 : XStream_impl::getInputStream( )
96 : throw( uno::RuntimeException, std::exception)
97 : {
98 : {
99 55403 : osl::MutexGuard aGuard( m_aMutex );
100 55403 : m_bInputStreamCalled = true;
101 : }
102 55403 : return uno::Reference< io::XInputStream >( this );
103 : }
104 :
105 :
106 : uno::Reference< io::XOutputStream > SAL_CALL
107 55832 : XStream_impl::getOutputStream( )
108 : throw( uno::RuntimeException, std::exception )
109 : {
110 : {
111 55832 : osl::MutexGuard aGuard( m_aMutex );
112 55832 : m_bOutputStreamCalled = true;
113 : }
114 55832 : return uno::Reference< io::XOutputStream >( this );
115 : }
116 :
117 :
118 234 : void SAL_CALL XStream_impl::truncate(void)
119 : throw( io::IOException, uno::RuntimeException, std::exception )
120 : {
121 234 : if (osl::FileBase::E_None != m_aFile.setSize(0))
122 0 : throw io::IOException( THROW_WHERE );
123 :
124 234 : if (osl::FileBase::E_None != m_aFile.setPos(osl_Pos_Absolut,sal_uInt64(0)))
125 0 : throw io::IOException( THROW_WHERE );
126 234 : }
127 :
128 :
129 :
130 :
131 : // XStream_impl private non interface methods
132 :
133 :
134 : sal_Int32 SAL_CALL
135 130957 : XStream_impl::readBytes(
136 : uno::Sequence< sal_Int8 >& aData,
137 : sal_Int32 nBytesToRead )
138 : throw( io::NotConnectedException,
139 : io::BufferSizeExceededException,
140 : io::IOException,
141 : uno::RuntimeException, std::exception)
142 : {
143 130957 : if( ! m_nIsOpen )
144 0 : throw io::IOException( THROW_WHERE );
145 :
146 130957 : boost::scoped_array<sal_Int8> buffer;
147 : try
148 : {
149 130957 : buffer.reset(new sal_Int8[nBytesToRead]);
150 : }
151 0 : catch (const std::bad_alloc&)
152 : {
153 0 : if( m_nIsOpen ) m_aFile.close();
154 0 : throw io::BufferSizeExceededException( THROW_WHERE );
155 : }
156 :
157 130957 : sal_uInt64 nrc(0);
158 130957 : if(m_aFile.read( buffer.get(),sal_uInt64(nBytesToRead),nrc )
159 : != osl::FileBase::E_None)
160 : {
161 0 : throw io::IOException( THROW_WHERE );
162 : }
163 130957 : aData = uno::Sequence< sal_Int8 > ( buffer.get(), (sal_uInt32)nrc );
164 130957 : return ( sal_Int32 ) nrc;
165 : }
166 :
167 :
168 : sal_Int32 SAL_CALL
169 0 : XStream_impl::readSomeBytes(
170 : uno::Sequence< sal_Int8 >& aData,
171 : sal_Int32 nMaxBytesToRead )
172 : throw( io::NotConnectedException,
173 : io::BufferSizeExceededException,
174 : io::IOException,
175 : uno::RuntimeException, std::exception)
176 : {
177 0 : return readBytes( aData,nMaxBytesToRead );
178 : }
179 :
180 :
181 : void SAL_CALL
182 0 : XStream_impl::skipBytes(
183 : sal_Int32 nBytesToSkip )
184 : throw( io::NotConnectedException,
185 : io::BufferSizeExceededException,
186 : io::IOException,
187 : uno::RuntimeException, std::exception )
188 : {
189 0 : m_aFile.setPos( osl_Pos_Current, sal_uInt64( nBytesToSkip ) );
190 0 : }
191 :
192 :
193 : sal_Int32 SAL_CALL
194 0 : XStream_impl::available(
195 : void )
196 : throw( io::NotConnectedException,
197 : io::IOException,
198 : uno::RuntimeException, std::exception)
199 : {
200 0 : return 0;
201 : }
202 :
203 :
204 : void SAL_CALL
205 131030 : XStream_impl::writeBytes( const uno::Sequence< sal_Int8 >& aData )
206 : throw( io::NotConnectedException,
207 : io::BufferSizeExceededException,
208 : io::IOException,
209 : uno::RuntimeException, std::exception)
210 : {
211 131030 : sal_uInt32 length = aData.getLength();
212 131030 : if(length)
213 : {
214 130916 : sal_uInt64 nWrittenBytes(0);
215 130916 : const sal_Int8* p = aData.getConstArray();
216 261832 : if(osl::FileBase::E_None != m_aFile.write(((void*)(p)),sal_uInt64(length),nWrittenBytes) ||
217 130916 : nWrittenBytes != length )
218 0 : throw io::IOException( THROW_WHERE );
219 : }
220 131030 : }
221 :
222 :
223 : void SAL_CALL
224 44863 : XStream_impl::closeStream(
225 : void )
226 : throw( io::NotConnectedException,
227 : io::IOException,
228 : uno::RuntimeException )
229 : {
230 44863 : if( m_nIsOpen )
231 : {
232 38296 : osl::FileBase::RC err = m_aFile.close();
233 :
234 38296 : if( err != osl::FileBase::E_None ) {
235 0 : io::IOException ex;
236 0 : ex.Message = "could not close file";
237 0 : throw ex;
238 : }
239 :
240 38296 : m_nIsOpen = false;
241 : }
242 44863 : }
243 :
244 : void SAL_CALL
245 4692 : XStream_impl::closeInput(
246 : void )
247 : throw( io::NotConnectedException,
248 : io::IOException,
249 : uno::RuntimeException, std::exception )
250 : {
251 4692 : osl::MutexGuard aGuard( m_aMutex );
252 4692 : m_bInputStreamCalled = false;
253 :
254 4692 : if( ! m_bOutputStreamCalled )
255 398 : closeStream();
256 4692 : }
257 :
258 :
259 : void SAL_CALL
260 6388 : XStream_impl::closeOutput(
261 : void )
262 : throw( io::NotConnectedException,
263 : io::IOException,
264 : uno::RuntimeException, std::exception )
265 : {
266 6388 : osl::MutexGuard aGuard( m_aMutex );
267 6388 : m_bOutputStreamCalled = false;
268 :
269 6388 : if( ! m_bInputStreamCalled )
270 5990 : closeStream();
271 6388 : }
272 :
273 :
274 : void SAL_CALL
275 109669 : XStream_impl::seek(
276 : sal_Int64 location )
277 : throw( lang::IllegalArgumentException,
278 : io::IOException,
279 : uno::RuntimeException, std::exception )
280 : {
281 109669 : if( location < 0 )
282 0 : throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
283 109669 : if( osl::FileBase::E_None != m_aFile.setPos( osl_Pos_Absolut, sal_uInt64( location ) ) )
284 0 : throw io::IOException( THROW_WHERE );
285 109669 : }
286 :
287 :
288 : sal_Int64 SAL_CALL
289 8474 : XStream_impl::getPosition(
290 : void )
291 : throw( io::IOException,
292 : uno::RuntimeException, std::exception )
293 : {
294 : sal_uInt64 uPos;
295 8474 : if( osl::FileBase::E_None != m_aFile.getPos( uPos ) )
296 0 : throw io::IOException( THROW_WHERE );
297 8474 : return sal_Int64( uPos );
298 : }
299 :
300 : sal_Int64 SAL_CALL
301 96436 : XStream_impl::getLength(
302 : void )
303 : throw( io::IOException,
304 : uno::RuntimeException, std::exception )
305 : {
306 : sal_uInt64 uEndPos;
307 96436 : if ( m_aFile.getSize(uEndPos) != osl::FileBase::E_None )
308 0 : throw io::IOException( THROW_WHERE );
309 : else
310 96436 : return sal_Int64( uEndPos );
311 : }
312 :
313 : void SAL_CALL
314 41632 : XStream_impl::flush()
315 : throw( io::NotConnectedException,
316 : io::BufferSizeExceededException,
317 : io::IOException,
318 : uno::RuntimeException, std::exception )
319 41632 : {}
320 :
321 350 : void XStream_impl::waitForCompletion()
322 : throw (io::IOException, uno::RuntimeException, std::exception)
323 : {
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 350 : if (m_nIsOpen && m_aFile.sync() != osl::FileBase::E_None) {
328 : throw io::IOException(
329 : OUString( "could not synchronize file to disc"),
330 0 : static_cast< OWeakObject * >(this));
331 : }
332 350 : }
333 :
334 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|