Update ooo320-m1
[ooovba.git] / ucb / source / ucp / gvfs / stream.cxx
blobea524a414bc9c098d17fdb220ecd1921ac9557f8
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: stream.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucb.hxx"
33 #include "stream.hxx"
34 #include <rtl/memory.h>
35 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
37 #include <libgnomevfs/gnome-vfs-ops.h>
39 using namespace cppu;
40 using namespace rtl;
41 using namespace com::sun::star::io;
42 using namespace com::sun::star::uno;
43 using namespace com::sun::star::ucb;
44 using namespace gvfs;
46 Stream::Stream( GnomeVFSHandle *handle,
47 const GnomeVFSFileInfo *aInfo,
48 const gchar *uri,
49 GnomeVFSOpenMode open_mode ) :
50 m_eof (sal_False),
51 m_bInputStreamCalled( sal_False ),
52 m_bOutputStreamCalled( sal_False ),
53 m_pURI( g_strdup( uri ) ),
54 m_nOpenMode( open_mode )
56 m_handle = handle;
57 gnome_vfs_file_info_copy (&m_info, aInfo);
60 Stream::~Stream( void )
62 if (m_handle) {
63 gnome_vfs_close (m_handle);
64 m_handle = NULL;
66 g_free( m_pURI );
69 Any Stream::queryInterface( const Type &type )
70 throw( RuntimeException )
72 Any aRet = ::cppu::queryInterface
73 ( type,
74 static_cast< XStream * >( this ),
75 static_cast< XInputStream * >( this ),
76 static_cast< XOutputStream * >( this ),
77 static_cast< XSeekable * >( this ),
78 static_cast< XTruncate * >( this ) );
80 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( type );
83 // -------------------------------------------------------------------
84 // XStream
85 // -------------------------------------------------------------------
87 com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL
88 Stream::getInputStream( )
89 throw( com::sun::star::uno::RuntimeException )
92 osl::MutexGuard aGuard( m_aMutex );
93 m_bInputStreamCalled = true;
95 return Reference< XInputStream >( this );
98 com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL
99 Stream::getOutputStream( )
100 throw( com::sun::star::uno::RuntimeException )
103 osl::MutexGuard aGuard( m_aMutex );
104 m_bOutputStreamCalled = true;
106 return Reference< XOutputStream >( this );
109 // -------------------------------------------------------------------
110 // XInputStream
111 // -------------------------------------------------------------------
113 sal_Int32 SAL_CALL Stream::readBytes(
114 Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
115 throw( NotConnectedException,
116 BufferSizeExceededException,
117 IOException,
118 RuntimeException )
120 GnomeVFSResult result;
122 if( ! m_handle )
123 throw IOException();
125 if( m_eof ) {
126 aData.realloc( 0 );
127 return 0;
130 try {
131 aData.realloc( nBytesToRead );
132 } catch ( const Exception &e ) {
133 throw BufferSizeExceededException();
136 sal_Int32 nTotalBytesRead = 0;
137 do {
138 GnomeVFSFileSize nBytesRead = 0;
139 do {
140 result = gnome_vfs_read( m_handle, aData.getArray() + nTotalBytesRead,
141 nBytesToRead - nTotalBytesRead, &nBytesRead );
142 } while( result == GNOME_VFS_ERROR_INTERRUPTED );
143 nTotalBytesRead += nBytesRead;
144 } while( result == GNOME_VFS_OK && nTotalBytesRead < nBytesToRead );
146 if (result != GNOME_VFS_OK &&
147 result != GNOME_VFS_ERROR_EOF)
148 throwOnError( result );
150 if (result == GNOME_VFS_ERROR_EOF)
151 m_eof = sal_True;
153 aData.realloc( sal::static_int_cast<sal_uInt32>(nTotalBytesRead) );
155 return sal::static_int_cast<sal_Int32>(nTotalBytesRead);
158 sal_Int32 SAL_CALL Stream::readSomeBytes(
159 Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
160 throw( NotConnectedException,
161 BufferSizeExceededException,
162 IOException,
163 RuntimeException )
165 // Again - having 2 methods here just sucks; cf. filinpstr.cxx
166 // This can never be an effective non-blocking API - so why bother ?
167 return readBytes( aData, nMaxBytesToRead );
170 void SAL_CALL Stream::skipBytes( sal_Int32 nBytesToSkip )
171 throw( NotConnectedException,
172 BufferSizeExceededException,
173 IOException,
174 RuntimeException )
176 GnomeVFSResult result;
178 if( ! m_handle )
179 throw IOException();
181 result = gnome_vfs_seek( m_handle, GNOME_VFS_SEEK_CURRENT, nBytesToSkip );
183 if ( result == GNOME_VFS_ERROR_BAD_PARAMETERS ||
184 result == GNOME_VFS_ERROR_NOT_SUPPORTED )
185 g_warning ("FIXME: just read them in ...");
187 throwOnError( result );
190 sal_Int32 SAL_CALL Stream::available( )
191 throw( NotConnectedException,
192 IOException,
193 RuntimeException )
195 return 0; // cf. filinpstr.cxx
198 void SAL_CALL Stream::closeInput( void )
199 throw( NotConnectedException,
200 IOException,
201 RuntimeException )
203 osl::MutexGuard aGuard( m_aMutex );
204 m_bInputStreamCalled = false;
206 if( ! m_bOutputStreamCalled )
207 closeStream();
210 // -------------------------------------------------------------------
211 // XSeekable
212 // -------------------------------------------------------------------
214 void SAL_CALL Stream::seek( sal_Int64 location )
215 throw( ::com::sun::star::lang::IllegalArgumentException,
216 IOException,
217 RuntimeException )
219 GnomeVFSResult result;
221 if( ! m_handle )
222 throw IOException();
224 if ( location < 0 )
225 throw ::com::sun::star::lang::IllegalArgumentException();
227 m_eof = sal_False;
228 result = gnome_vfs_seek( m_handle, GNOME_VFS_SEEK_START, location );
230 if (result == GNOME_VFS_ERROR_EOF)
231 throw ::com::sun::star::lang::IllegalArgumentException();
233 throwOnError( result );
236 sal_Int64 SAL_CALL Stream::getPosition()
237 throw( IOException,
238 RuntimeException )
240 GnomeVFSFileSize nBytesIn = 0;
242 if( ! m_handle )
243 throw IOException();
245 throwOnError( gnome_vfs_tell( m_handle, &nBytesIn ) );
247 return nBytesIn;
250 sal_Int64 SAL_CALL Stream::getLength()
251 throw( IOException, RuntimeException )
253 // FIXME: so this sucks; it may be stale but ...
254 if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE)
255 return m_info.size;
256 else {
257 g_warning ("FIXME: No valid length");
258 return 0;
262 // -------------------------------------------------------------------
263 // XTruncate
264 // -------------------------------------------------------------------
266 void SAL_CALL Stream::truncate( void )
267 throw( com::sun::star::io::IOException,
268 com::sun::star::uno::RuntimeException )
270 if( ! m_handle )
271 throw IOException();
273 GnomeVFSResult result = gnome_vfs_truncate_handle( m_handle, 0 );
275 if ( result == GNOME_VFS_ERROR_NOT_SUPPORTED )
277 result = gnome_vfs_close( m_handle );
278 m_handle = NULL;
279 if ( result == GNOME_VFS_OK )
280 result = gnome_vfs_open( &m_handle, m_pURI, (GnomeVFSOpenMode)( m_nOpenMode | GNOME_VFS_OPEN_LOCKED ) );
283 throwOnError( result );
286 // -------------------------------------------------------------------
287 // XOutputStream
288 // -------------------------------------------------------------------
290 void SAL_CALL Stream::writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
291 throw( com::sun::star::io::NotConnectedException,
292 com::sun::star::io::BufferSizeExceededException,
293 com::sun::star::io::IOException,
294 com::sun::star::uno::RuntimeException)
296 GnomeVFSResult result = GNOME_VFS_OK;
297 GnomeVFSFileSize toWrite = aData.getLength();
298 const sal_Int8 *p = aData.getConstArray();
300 if( ! m_handle )
301 throw IOException();
303 while( toWrite > 0) {
304 GnomeVFSFileSize bytesWritten = 0;
306 result = gnome_vfs_write( m_handle, p, toWrite, &bytesWritten );
307 if( result == GNOME_VFS_ERROR_INTERRUPTED )
308 continue;
309 throwOnError( result );
310 g_assert( bytesWritten <= toWrite );
311 toWrite -= bytesWritten;
312 p += bytesWritten;
316 void SAL_CALL Stream::flush( void )
317 throw( NotConnectedException, BufferSizeExceededException,
318 IOException, RuntimeException )
322 void SAL_CALL Stream::closeOutput( void )
323 throw( com::sun::star::io::NotConnectedException,
324 com::sun::star::io::IOException,
325 com::sun::star::uno::RuntimeException )
327 osl::MutexGuard aGuard( m_aMutex );
328 m_bOutputStreamCalled = false;
330 if( ! m_bInputStreamCalled )
331 closeStream();
334 // -------------------------------------------------------------------
335 // Misc.
336 // -------------------------------------------------------------------
338 void Stream::closeStream( void )
339 throw( ::com::sun::star::io::NotConnectedException,
340 ::com::sun::star::io::IOException,
341 ::com::sun::star::uno::RuntimeException )
343 if (m_handle) {
344 gnome_vfs_close (m_handle);
345 m_handle = NULL;
346 } else
347 throw IOException();
350 void Stream::throwOnError( GnomeVFSResult result )
351 throw( NotConnectedException,
352 BufferSizeExceededException,
353 IOException,
354 RuntimeException )
356 if( result != GNOME_VFS_OK ) {
357 ::rtl::OUString aMsg = ::rtl::OUString::createFromAscii
358 ( gnome_vfs_result_to_string( result ) );
360 g_warning( "Input Stream exceptional result '%s' (%d)",
361 gnome_vfs_result_to_string( result ), result );
363 throw IOException( aMsg, static_cast< cppu::OWeakObject * >( this ) );