Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / ucb / source / ucp / gvfs / gvfs_stream.cxx
blob462fde93d9acbaa8a2804a0e601f59adb0629ec3
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;
31 using ::rtl::OUString;
33 Stream::Stream( GnomeVFSHandle *handle,
34 const GnomeVFSFileInfo *aInfo ) :
35 m_eof (sal_False),
36 m_bInputStreamCalled( sal_False ),
37 m_bOutputStreamCalled( sal_False )
39 m_handle = handle;
40 gnome_vfs_file_info_copy (&m_info, aInfo);
43 Stream::~Stream( void )
45 if (m_handle) {
46 gnome_vfs_close (m_handle);
47 m_handle = NULL;
51 Any Stream::queryInterface( const Type &type )
52 throw( RuntimeException )
54 Any aRet = ::cppu::queryInterface
55 ( type,
56 static_cast< XStream * >( this ),
57 static_cast< XInputStream * >( this ),
58 static_cast< XOutputStream * >( this ),
59 static_cast< XSeekable * >( this ),
60 static_cast< XTruncate * >( this ) );
62 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( type );
65 // -------------------------------------------------------------------
66 // XStream
67 // -------------------------------------------------------------------
69 com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL
70 Stream::getInputStream( )
71 throw( com::sun::star::uno::RuntimeException )
74 osl::MutexGuard aGuard( m_aMutex );
75 m_bInputStreamCalled = true;
77 return Reference< XInputStream >( this );
80 com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL
81 Stream::getOutputStream( )
82 throw( com::sun::star::uno::RuntimeException )
85 osl::MutexGuard aGuard( m_aMutex );
86 m_bOutputStreamCalled = true;
88 return Reference< XOutputStream >( this );
91 // -------------------------------------------------------------------
92 // XInputStream
93 // -------------------------------------------------------------------
95 sal_Int32 SAL_CALL Stream::readBytes(
96 Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
97 throw( NotConnectedException,
98 BufferSizeExceededException,
99 IOException,
100 RuntimeException )
102 GnomeVFSResult result;
103 GnomeVFSFileSize nBytesRead = 0;
105 if( ! m_handle )
106 throw IOException();
108 if( m_eof ) {
109 aData.realloc( 0 );
110 return 0;
113 try {
114 aData.realloc( nBytesToRead );
115 } catch ( const Exception &e ) {
116 throw BufferSizeExceededException();
119 do {
120 result = gnome_vfs_read( m_handle, aData.getArray(),
121 nBytesToRead, &nBytesRead );
122 } while( result == GNOME_VFS_ERROR_INTERRUPTED );
124 if (result != GNOME_VFS_OK &&
125 result != GNOME_VFS_ERROR_EOF)
126 throwOnError( result );
128 if (result == GNOME_VFS_ERROR_EOF)
129 m_eof = sal_True;
131 aData.realloc( sal::static_int_cast<sal_uInt32>(nBytesRead) );
133 return sal::static_int_cast<sal_Int32>(nBytesRead);
136 sal_Int32 SAL_CALL Stream::readSomeBytes(
137 Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
138 throw( NotConnectedException,
139 BufferSizeExceededException,
140 IOException,
141 RuntimeException )
143 // Again - having 2 methods here just sucks; cf. filinpstr.cxx
144 // This can never be an effective non-blocking API - so why bother ?
145 return readBytes( aData, nMaxBytesToRead );
148 void SAL_CALL Stream::skipBytes( sal_Int32 nBytesToSkip )
149 throw( NotConnectedException,
150 BufferSizeExceededException,
151 IOException,
152 RuntimeException )
154 GnomeVFSResult result;
156 if( ! m_handle )
157 throw IOException();
159 result = gnome_vfs_seek( m_handle, GNOME_VFS_SEEK_CURRENT, nBytesToSkip );
161 if ( result == GNOME_VFS_ERROR_BAD_PARAMETERS ||
162 result == GNOME_VFS_ERROR_NOT_SUPPORTED )
163 g_warning ("FIXME: just read them in ...");
165 throwOnError( result );
168 sal_Int32 SAL_CALL Stream::available( )
169 throw( NotConnectedException,
170 IOException,
171 RuntimeException )
173 return 0; // cf. filinpstr.cxx
176 void SAL_CALL Stream::closeInput( void )
177 throw( NotConnectedException,
178 IOException,
179 RuntimeException )
181 osl::MutexGuard aGuard( m_aMutex );
182 m_bInputStreamCalled = false;
184 if( ! m_bOutputStreamCalled )
185 closeStream();
188 // -------------------------------------------------------------------
189 // XSeekable
190 // -------------------------------------------------------------------
192 void SAL_CALL Stream::seek( sal_Int64 location )
193 throw( ::com::sun::star::lang::IllegalArgumentException,
194 IOException,
195 RuntimeException )
197 GnomeVFSResult result;
199 if( ! m_handle )
200 throw IOException();
202 if ( location < 0 )
203 throw ::com::sun::star::lang::IllegalArgumentException();
205 m_eof = sal_False;
206 result = gnome_vfs_seek( m_handle, GNOME_VFS_SEEK_START, location );
208 if (result == GNOME_VFS_ERROR_EOF)
209 throw ::com::sun::star::lang::IllegalArgumentException();
211 throwOnError( result );
214 sal_Int64 SAL_CALL Stream::getPosition()
215 throw( IOException,
216 RuntimeException )
218 GnomeVFSFileSize nBytesIn = 0;
220 if( ! m_handle )
221 throw IOException();
223 throwOnError( gnome_vfs_tell( m_handle, &nBytesIn ) );
225 return nBytesIn;
228 sal_Int64 SAL_CALL Stream::getLength()
229 throw( IOException, RuntimeException )
231 // FIXME: so this sucks; it may be stale but ...
232 if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE)
233 return m_info.size;
234 else {
235 g_warning ("FIXME: No valid length");
236 return 0;
240 // -------------------------------------------------------------------
241 // XTruncate
242 // -------------------------------------------------------------------
244 void SAL_CALL Stream::truncate( void )
245 throw( com::sun::star::io::IOException,
246 com::sun::star::uno::RuntimeException )
248 if( ! m_handle )
249 throw IOException();
251 throwOnError( gnome_vfs_truncate_handle( m_handle, 0 ) );
254 // -------------------------------------------------------------------
255 // XOutputStream
256 // -------------------------------------------------------------------
258 void SAL_CALL Stream::writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
259 throw( com::sun::star::io::NotConnectedException,
260 com::sun::star::io::BufferSizeExceededException,
261 com::sun::star::io::IOException,
262 com::sun::star::uno::RuntimeException)
264 GnomeVFSResult result = GNOME_VFS_OK;
265 GnomeVFSFileSize toWrite = aData.getLength();
266 const sal_Int8 *p = aData.getConstArray();
268 if( ! m_handle )
269 throw IOException();
271 while( toWrite > 0) {
272 GnomeVFSFileSize bytesWritten = 0;
274 result = gnome_vfs_write( m_handle, p, toWrite, &bytesWritten );
275 if( result == GNOME_VFS_ERROR_INTERRUPTED )
276 continue;
277 throwOnError( result );
278 g_assert( bytesWritten <= toWrite );
279 toWrite -= bytesWritten;
280 p += bytesWritten;
284 void SAL_CALL Stream::flush( void )
285 throw( NotConnectedException, BufferSizeExceededException,
286 IOException, RuntimeException )
290 void SAL_CALL Stream::closeOutput( void )
291 throw( com::sun::star::io::NotConnectedException,
292 com::sun::star::io::IOException,
293 com::sun::star::uno::RuntimeException )
295 osl::MutexGuard aGuard( m_aMutex );
296 m_bOutputStreamCalled = false;
298 if( ! m_bInputStreamCalled )
299 closeStream();
302 // -------------------------------------------------------------------
303 // Misc.
304 // -------------------------------------------------------------------
306 void Stream::closeStream( void )
307 throw( ::com::sun::star::io::NotConnectedException,
308 ::com::sun::star::io::IOException,
309 ::com::sun::star::uno::RuntimeException )
311 if (m_handle) {
312 gnome_vfs_close (m_handle);
313 m_handle = NULL;
314 } else
315 throw IOException();
318 void Stream::throwOnError( GnomeVFSResult result )
319 throw( NotConnectedException,
320 BufferSizeExceededException,
321 IOException,
322 RuntimeException )
324 if( result != GNOME_VFS_OK ) {
325 ::rtl::OUString aMsg = ::rtl::OUString::createFromAscii
326 ( gnome_vfs_result_to_string( result ) );
328 g_warning( "Input Stream exceptional result '%s' (%d)",
329 gnome_vfs_result_to_string( result ), result );
331 throw IOException( aMsg, static_cast< cppu::OWeakObject * >( this ) );
335 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */