1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: stream.cxx,v $
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"
34 #include <rtl/memory.h>
35 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
37 #include <libgnomevfs/gnome-vfs-ops.h>
41 using namespace com::sun::star::io
;
42 using namespace com::sun::star::uno
;
43 using namespace com::sun::star::ucb
;
46 Stream::Stream( GnomeVFSHandle
*handle
,
47 const GnomeVFSFileInfo
*aInfo
,
49 GnomeVFSOpenMode open_mode
) :
51 m_bInputStreamCalled( sal_False
),
52 m_bOutputStreamCalled( sal_False
),
53 m_pURI( g_strdup( uri
) ),
54 m_nOpenMode( open_mode
)
57 gnome_vfs_file_info_copy (&m_info
, aInfo
);
60 Stream::~Stream( void )
63 gnome_vfs_close (m_handle
);
69 Any
Stream::queryInterface( const Type
&type
)
70 throw( RuntimeException
)
72 Any aRet
= ::cppu::queryInterface
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 // -------------------------------------------------------------------
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 // -------------------------------------------------------------------
111 // -------------------------------------------------------------------
113 sal_Int32 SAL_CALL
Stream::readBytes(
114 Sequence
< sal_Int8
>& aData
, sal_Int32 nBytesToRead
)
115 throw( NotConnectedException
,
116 BufferSizeExceededException
,
120 GnomeVFSResult result
;
131 aData
.realloc( nBytesToRead
);
132 } catch ( const Exception
&e
) {
133 throw BufferSizeExceededException();
136 sal_Int32 nTotalBytesRead
= 0;
138 GnomeVFSFileSize nBytesRead
= 0;
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
)
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
,
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
,
176 GnomeVFSResult result
;
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
,
195 return 0; // cf. filinpstr.cxx
198 void SAL_CALL
Stream::closeInput( void )
199 throw( NotConnectedException
,
203 osl::MutexGuard
aGuard( m_aMutex
);
204 m_bInputStreamCalled
= false;
206 if( ! m_bOutputStreamCalled
)
210 // -------------------------------------------------------------------
212 // -------------------------------------------------------------------
214 void SAL_CALL
Stream::seek( sal_Int64 location
)
215 throw( ::com::sun::star::lang::IllegalArgumentException
,
219 GnomeVFSResult result
;
225 throw ::com::sun::star::lang::IllegalArgumentException();
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()
240 GnomeVFSFileSize nBytesIn
= 0;
245 throwOnError( gnome_vfs_tell( m_handle
, &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
)
257 g_warning ("FIXME: No valid length");
262 // -------------------------------------------------------------------
264 // -------------------------------------------------------------------
266 void SAL_CALL
Stream::truncate( void )
267 throw( com::sun::star::io::IOException
,
268 com::sun::star::uno::RuntimeException
)
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
);
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 // -------------------------------------------------------------------
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();
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
)
309 throwOnError( result
);
310 g_assert( bytesWritten
<= toWrite
);
311 toWrite
-= 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
)
334 // -------------------------------------------------------------------
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
)
344 gnome_vfs_close (m_handle
);
350 void Stream::throwOnError( GnomeVFSResult result
)
351 throw( NotConnectedException
,
352 BufferSizeExceededException
,
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 ) );