update credits
[LibreOffice.git] / ucb / source / ucp / gvfs / gvfs_stream.cxx
blob080d484dfb47265331c6abfa5544269640af3e6f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "gvfs_stream.hxx"
21 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
23 #include <libgnomevfs/gnome-vfs-ops.h>
25 using namespace cppu;
26 using namespace com::sun::star::io;
27 using namespace com::sun::star::uno;
28 using namespace com::sun::star::ucb;
29 using namespace gvfs;
32 Stream::Stream( GnomeVFSHandle *handle,
33 const GnomeVFSFileInfo *aInfo ) :
34 m_eof (sal_False),
35 m_bInputStreamCalled( sal_False ),
36 m_bOutputStreamCalled( sal_False )
38 m_handle = handle;
39 gnome_vfs_file_info_copy (&m_info, aInfo);
42 Stream::~Stream( void )
44 if (m_handle) {
45 gnome_vfs_close (m_handle);
46 m_handle = NULL;
50 Any Stream::queryInterface( const Type &type )
51 throw( RuntimeException )
53 Any aRet = ::cppu::queryInterface
54 ( type,
55 static_cast< XStream * >( this ),
56 static_cast< XInputStream * >( this ),
57 static_cast< XOutputStream * >( this ),
58 static_cast< XSeekable * >( this ),
59 static_cast< XTruncate * >( this ) );
61 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( type );
64 // -------------------------------------------------------------------
65 // XStream
66 // -------------------------------------------------------------------
68 com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL
69 Stream::getInputStream( )
70 throw( com::sun::star::uno::RuntimeException )
73 osl::MutexGuard aGuard( m_aMutex );
74 m_bInputStreamCalled = true;
76 return Reference< XInputStream >( this );
79 com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL
80 Stream::getOutputStream( )
81 throw( com::sun::star::uno::RuntimeException )
84 osl::MutexGuard aGuard( m_aMutex );
85 m_bOutputStreamCalled = true;
87 return Reference< XOutputStream >( this );
90 // -------------------------------------------------------------------
91 // XInputStream
92 // -------------------------------------------------------------------
94 sal_Int32 SAL_CALL Stream::readBytes(
95 Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
96 throw( NotConnectedException,
97 BufferSizeExceededException,
98 IOException,
99 RuntimeException )
101 GnomeVFSResult result;
102 GnomeVFSFileSize nBytesRead = 0;
104 if( ! m_handle )
105 throw IOException();
107 if( m_eof ) {
108 aData.realloc( 0 );
109 return 0;
112 try {
113 aData.realloc( nBytesToRead );
114 } catch ( const Exception &e ) {
115 throw BufferSizeExceededException();
118 do {
119 result = gnome_vfs_read( m_handle, aData.getArray(),
120 nBytesToRead, &nBytesRead );
121 } while( result == GNOME_VFS_ERROR_INTERRUPTED );
123 if (result != GNOME_VFS_OK &&
124 result != GNOME_VFS_ERROR_EOF)
125 throwOnError( result );
127 if (result == GNOME_VFS_ERROR_EOF)
128 m_eof = sal_True;
130 aData.realloc( sal::static_int_cast<sal_uInt32>(nBytesRead) );
132 return sal::static_int_cast<sal_Int32>(nBytesRead);
135 sal_Int32 SAL_CALL Stream::readSomeBytes(
136 Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
137 throw( NotConnectedException,
138 BufferSizeExceededException,
139 IOException,
140 RuntimeException )
142 // Again - having 2 methods here just sucks; cf. filinpstr.cxx
143 // This can never be an effective non-blocking API - so why bother ?
144 return readBytes( aData, nMaxBytesToRead );
147 void SAL_CALL Stream::skipBytes( sal_Int32 nBytesToSkip )
148 throw( NotConnectedException,
149 BufferSizeExceededException,
150 IOException,
151 RuntimeException )
153 GnomeVFSResult result;
155 if( ! m_handle )
156 throw IOException();
158 result = gnome_vfs_seek( m_handle, GNOME_VFS_SEEK_CURRENT, nBytesToSkip );
160 if ( result == GNOME_VFS_ERROR_BAD_PARAMETERS ||
161 result == GNOME_VFS_ERROR_NOT_SUPPORTED )
162 g_warning ("FIXME: just read them in ...");
164 throwOnError( result );
167 sal_Int32 SAL_CALL Stream::available( )
168 throw( NotConnectedException,
169 IOException,
170 RuntimeException )
172 return 0; // cf. filinpstr.cxx
175 void SAL_CALL Stream::closeInput( void )
176 throw( NotConnectedException,
177 IOException,
178 RuntimeException )
180 osl::MutexGuard aGuard( m_aMutex );
181 m_bInputStreamCalled = false;
183 if( ! m_bOutputStreamCalled )
184 closeStream();
187 // -------------------------------------------------------------------
188 // XSeekable
189 // -------------------------------------------------------------------
191 void SAL_CALL Stream::seek( sal_Int64 location )
192 throw( ::com::sun::star::lang::IllegalArgumentException,
193 IOException,
194 RuntimeException )
196 GnomeVFSResult result;
198 if( ! m_handle )
199 throw IOException();
201 if ( location < 0 )
202 throw ::com::sun::star::lang::IllegalArgumentException();
204 m_eof = sal_False;
205 result = gnome_vfs_seek( m_handle, GNOME_VFS_SEEK_START, location );
207 if (result == GNOME_VFS_ERROR_EOF)
208 throw ::com::sun::star::lang::IllegalArgumentException();
210 throwOnError( result );
213 sal_Int64 SAL_CALL Stream::getPosition()
214 throw( IOException,
215 RuntimeException )
217 GnomeVFSFileSize nBytesIn = 0;
219 if( ! m_handle )
220 throw IOException();
222 throwOnError( gnome_vfs_tell( m_handle, &nBytesIn ) );
224 return nBytesIn;
227 sal_Int64 SAL_CALL Stream::getLength()
228 throw( IOException, RuntimeException )
230 // FIXME: so this sucks; it may be stale but ...
231 if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE)
232 return m_info.size;
233 else {
234 g_warning ("FIXME: No valid length");
235 return 0;
239 // -------------------------------------------------------------------
240 // XTruncate
241 // -------------------------------------------------------------------
243 void SAL_CALL Stream::truncate( void )
244 throw( com::sun::star::io::IOException,
245 com::sun::star::uno::RuntimeException )
247 if( ! m_handle )
248 throw IOException();
250 throwOnError( gnome_vfs_truncate_handle( m_handle, 0 ) );
253 // -------------------------------------------------------------------
254 // XOutputStream
255 // -------------------------------------------------------------------
257 void SAL_CALL Stream::writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
258 throw( com::sun::star::io::NotConnectedException,
259 com::sun::star::io::BufferSizeExceededException,
260 com::sun::star::io::IOException,
261 com::sun::star::uno::RuntimeException)
263 GnomeVFSResult result = GNOME_VFS_OK;
264 GnomeVFSFileSize toWrite = aData.getLength();
265 const sal_Int8 *p = aData.getConstArray();
267 if( ! m_handle )
268 throw IOException();
270 while( toWrite > 0) {
271 GnomeVFSFileSize bytesWritten = 0;
273 result = gnome_vfs_write( m_handle, p, toWrite, &bytesWritten );
274 if( result == GNOME_VFS_ERROR_INTERRUPTED )
275 continue;
276 throwOnError( result );
277 g_assert( bytesWritten <= toWrite );
278 toWrite -= bytesWritten;
279 p += bytesWritten;
283 void SAL_CALL Stream::flush( void )
284 throw( NotConnectedException, BufferSizeExceededException,
285 IOException, RuntimeException )
289 void SAL_CALL Stream::closeOutput( void )
290 throw( com::sun::star::io::NotConnectedException,
291 com::sun::star::io::IOException,
292 com::sun::star::uno::RuntimeException )
294 osl::MutexGuard aGuard( m_aMutex );
295 m_bOutputStreamCalled = false;
297 if( ! m_bInputStreamCalled )
298 closeStream();
301 // -------------------------------------------------------------------
302 // Misc.
303 // -------------------------------------------------------------------
305 void Stream::closeStream( void )
306 throw( ::com::sun::star::io::NotConnectedException,
307 ::com::sun::star::io::IOException,
308 ::com::sun::star::uno::RuntimeException )
310 if (m_handle) {
311 gnome_vfs_close (m_handle);
312 m_handle = NULL;
313 } else
314 throw IOException();
317 void Stream::throwOnError( GnomeVFSResult result )
318 throw( NotConnectedException,
319 BufferSizeExceededException,
320 IOException,
321 RuntimeException )
323 if( result != GNOME_VFS_OK ) {
324 OUString aMsg = OUString::createFromAscii
325 ( gnome_vfs_result_to_string( result ) );
327 g_warning( "Input Stream exceptional result '%s' (%d)",
328 gnome_vfs_result_to_string( result ), result );
330 throw IOException( aMsg, static_cast< cppu::OWeakObject * >( this ) );
334 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */