--- ucb/source/ucp/gvfs/stream.hxx 2003-04-24 16:24:35.000000000 +0100 +++ ucb/source/ucp/gvfs/stream.hxx 2003-04-24 16:24:35.000000000 +0100 @@ -0,0 +1,156 @@ +#ifndef _GVFSSTREAM_HXX_ +#define _GVFSSTREAM_HXX_ + +#ifndef _SAL_TYPES_H_ +#include +#endif +#ifndef _RTL_USTRING_HXX_ +#include +#endif +#ifndef _CPPUHELPER_WEAK_HXX_ +#include +#endif + +#ifndef _COM_SUN_STAR_IO_XSTREAM_HPP_ +#include +#endif +#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_ +#include +#endif +#ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_ +#include +#endif +#ifndef _COM_SUN_STAR_IO_XTRUNCATE_HPP_ +#include +#endif +#ifndef _COM_SUN_STAR_IO_XSEEKABLE_HPP_ +#include +#endif + +#include + +namespace gvfs +{ + +class Stream : public ::com::sun::star::io::XStream, + public ::com::sun::star::io::XInputStream, + public ::com::sun::star::io::XOutputStream, + public ::com::sun::star::io::XTruncate, + public ::com::sun::star::io::XSeekable, + public ::cppu::OWeakObject +{ +private: + GnomeVFSHandle *m_handle; + GnomeVFSFileInfo m_info; + osl::Mutex m_aMutex; + sal_Bool m_eof; + sal_Bool m_bInputStreamCalled; + sal_Bool m_bOutputStreamCalled; + + void throwOnError( GnomeVFSResult result ) + throw( ::com::sun::star::io::NotConnectedException, + ::com::sun::star::io::BufferSizeExceededException, + ::com::sun::star::io::IOException, + ::com::sun::star::uno::RuntimeException ); + + void closeStream( void ) + throw( ::com::sun::star::io::NotConnectedException, + ::com::sun::star::io::IOException, + ::com::sun::star::uno::RuntimeException ); + +public: + Stream ( GnomeVFSHandle *handle, + const GnomeVFSFileInfo *aInfo ); + virtual ~Stream(); + + // XInterface + virtual com::sun::star::uno::Any SAL_CALL queryInterface(const ::com::sun::star::uno::Type & type ) + throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL acquire( void ) + throw () + { OWeakObject::acquire(); } + virtual void SAL_CALL release( void ) + throw() + { OWeakObject::release(); } + + // XStream + virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL getInputStream( ) + throw( com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL getOutputStream( ) + throw( com::sun::star::uno::RuntimeException ); + + // XInputStream + virtual sal_Int32 SAL_CALL readBytes( + ::com::sun::star::uno::Sequence< sal_Int8 > & aData, + sal_Int32 nBytesToRead ) + throw( ::com::sun::star::io::NotConnectedException, + ::com::sun::star::io::BufferSizeExceededException, + ::com::sun::star::io::IOException, + ::com::sun::star::uno::RuntimeException ); + + virtual sal_Int32 SAL_CALL readSomeBytes( + ::com::sun::star::uno::Sequence< sal_Int8 > & aData, + sal_Int32 nMaxBytesToRead ) + throw( ::com::sun::star::io::NotConnectedException, + ::com::sun::star::io::BufferSizeExceededException, + ::com::sun::star::io::IOException, + ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) + throw( ::com::sun::star::io::NotConnectedException, + ::com::sun::star::io::BufferSizeExceededException, + ::com::sun::star::io::IOException, + ::com::sun::star::uno::RuntimeException ); + + virtual sal_Int32 SAL_CALL available( void ) + throw( ::com::sun::star::io::NotConnectedException, + ::com::sun::star::io::IOException, + ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL closeInput( void ) + throw( ::com::sun::star::io::NotConnectedException, + ::com::sun::star::io::IOException, + ::com::sun::star::uno::RuntimeException ); + + // XSeekable + virtual void SAL_CALL seek( sal_Int64 location ) + throw( ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::io::IOException, + ::com::sun::star::uno::RuntimeException ); + + virtual sal_Int64 SAL_CALL getPosition() + throw( ::com::sun::star::io::IOException, + ::com::sun::star::uno::RuntimeException ); + + virtual sal_Int64 SAL_CALL getLength() + throw( ::com::sun::star::io::IOException, + ::com::sun::star::uno::RuntimeException ); + + // XOutputStream + virtual void SAL_CALL writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL flush( void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + + virtual void SAL_CALL closeOutput( void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + // XTruncate + virtual void SAL_CALL truncate( void ) + throw( com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); +}; + +}; // namespace gvfs +#endif // _GVFSSTREAM_HXX_ --- ucb/source/ucp/gvfs/stream.cxx 2003-04-24 16:24:35.000000000 +0100 +++ ucb/source/ucp/gvfs/stream.cxx 2003-04-24 16:24:35.000000000 +0100 @@ -0,0 +1,319 @@ +#include "stream.hxx" + +#ifndef _RTL_MEMORY_H_ +#include +#endif +#ifndef _COM_SUN_STAR_UCB_INTERACTIVEAUGMENTEDIOEXCEPTION_HPP_ +#include +#endif + +#include + +using namespace cppu; +using namespace rtl; +using namespace com::sun::star::io; +using namespace com::sun::star::uno; +using namespace com::sun::star::ucb; +using namespace gvfs; + +Stream::Stream( GnomeVFSHandle *handle, + const GnomeVFSFileInfo *aInfo ) : + m_eof (sal_False), + m_bInputStreamCalled( sal_False ), + m_bOutputStreamCalled( sal_False ) +{ + m_handle = handle; + gnome_vfs_file_info_copy (&m_info, aInfo); +} + +Stream::~Stream( void ) +{ + if (m_handle) { + gnome_vfs_close (m_handle); + m_handle = NULL; + } +} + +Any Stream::queryInterface( const Type &type ) + throw( RuntimeException ) +{ + Any aRet = ::cppu::queryInterface + ( type, + static_cast< XStream * >( this ), + static_cast< XInputStream * >( this ), + static_cast< XOutputStream * >( this ), + static_cast< XSeekable * >( this ), + static_cast< XTruncate * >( this ) ); + + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( type ); +} + +// ------------------------------------------------------------------- +// XStream +// ------------------------------------------------------------------- + +com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL +Stream::getInputStream( ) + throw( com::sun::star::uno::RuntimeException ) +{ + { + osl::MutexGuard aGuard( m_aMutex ); + m_bInputStreamCalled = true; + } + return Reference< XInputStream >( this ); +} + +com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL +Stream::getOutputStream( ) + throw( com::sun::star::uno::RuntimeException ) +{ + { + osl::MutexGuard aGuard( m_aMutex ); + m_bOutputStreamCalled = true; + } + return Reference< XOutputStream >( this ); +} + +// ------------------------------------------------------------------- +// XInputStream +// ------------------------------------------------------------------- + +sal_Int32 SAL_CALL Stream::readBytes( + Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException ) +{ + GnomeVFSResult result; + GnomeVFSFileSize nBytesRead = 0; + + if( ! m_handle ) + throw IOException(); + + if( m_eof ) { + aData.realloc( 0 ); + return 0; + } + + try { + aData.realloc( nBytesToRead ); + } catch ( const Exception &e ) { + throw BufferSizeExceededException(); + } + + do { + result = gnome_vfs_read( m_handle, aData.getArray(), + nBytesToRead, &nBytesRead ); + } while( result == GNOME_VFS_ERROR_INTERRUPTED ); + + if (result != GNOME_VFS_OK && + result != GNOME_VFS_ERROR_EOF) + throwOnError( result ); + + if (result == GNOME_VFS_ERROR_EOF) + m_eof = sal_True; + + aData.realloc( nBytesRead ); + + return nBytesRead; +} + +sal_Int32 SAL_CALL Stream::readSomeBytes( + Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException ) +{ + // Again - having 2 methods here just sucks; cf. filinpstr.cxx + // This can never be an effective non-blocking API - so why bother ? + return readSomeBytes( aData, nMaxBytesToRead ); +} + +void SAL_CALL Stream::skipBytes( sal_Int32 nBytesToSkip ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException ) +{ + GnomeVFSResult result; + + if( ! m_handle ) + throw IOException(); + + result = gnome_vfs_seek( m_handle, GNOME_VFS_SEEK_CURRENT, nBytesToSkip ); + + if ( result == GNOME_VFS_ERROR_BAD_PARAMETERS || + result == GNOME_VFS_ERROR_NOT_SUPPORTED ) + g_warning ("FIXME: just read them in ..."); + + throwOnError( result ); +} + +sal_Int32 SAL_CALL Stream::available( ) + throw( NotConnectedException, + IOException, + RuntimeException ) +{ + return 0; // cf. filinpstr.cxx +} + +void SAL_CALL Stream::closeInput( void ) + throw( NotConnectedException, + IOException, + RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + m_bInputStreamCalled = false; + + if( ! m_bOutputStreamCalled ) + closeStream(); +} + +// ------------------------------------------------------------------- +// XSeekable +// ------------------------------------------------------------------- + +void SAL_CALL Stream::seek( sal_Int64 location ) + throw( ::com::sun::star::lang::IllegalArgumentException, + IOException, + RuntimeException ) +{ + GnomeVFSResult result; + + if( ! m_handle ) + throw IOException(); + + if ( location < 0 ) + throw ::com::sun::star::lang::IllegalArgumentException(); + + m_eof = sal_False; + result = gnome_vfs_seek( m_handle, GNOME_VFS_SEEK_START, location ); + + if (result == GNOME_VFS_ERROR_EOF) + throw ::com::sun::star::lang::IllegalArgumentException(); + + throwOnError( result ); +} + +sal_Int64 SAL_CALL Stream::getPosition() + throw( IOException, + RuntimeException ) +{ + GnomeVFSFileSize nBytesIn = 0; + + if( ! m_handle ) + throw IOException(); + + throwOnError( gnome_vfs_tell( m_handle, &nBytesIn ) ); + + return nBytesIn; +} + +sal_Int64 SAL_CALL Stream::getLength() + throw( IOException, RuntimeException ) +{ + // FIXME: so this sucks; it may be stale but ... + if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) + return m_info.size; + else { + g_warning ("FIXME: No valid length"); + return 0; + } +} + +// ------------------------------------------------------------------- +// XTruncate +// ------------------------------------------------------------------- + +void SAL_CALL Stream::truncate( void ) + throw( com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ) +{ + if( ! m_handle ) + throw IOException(); + + throwOnError( gnome_vfs_truncate_handle( m_handle, 0 ) ); +} + +// ------------------------------------------------------------------- +// XOutputStream +// ------------------------------------------------------------------- + +void SAL_CALL Stream::writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException) +{ + GnomeVFSResult result = GNOME_VFS_OK; + GnomeVFSFileSize toWrite = aData.getLength(); + const sal_Int8 *p = aData.getConstArray(); + + if( ! m_handle ) + throw IOException(); + + while( toWrite > 0) { + GnomeVFSFileSize bytesWritten = 0; + + result = gnome_vfs_write( m_handle, p, toWrite, &bytesWritten ); + if( result == GNOME_VFS_ERROR_INTERRUPTED ) + continue; + throwOnError( result ); + g_assert( bytesWritten <= toWrite ); + toWrite -= bytesWritten; + p += bytesWritten; + } +} + +void SAL_CALL Stream::flush( void ) + throw( NotConnectedException, BufferSizeExceededException, + IOException, RuntimeException ) +{ +} + +void SAL_CALL Stream::closeOutput( void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + m_bOutputStreamCalled = false; + + if( ! m_bInputStreamCalled ) + closeStream(); +} + +// ------------------------------------------------------------------- +// Misc. +// ------------------------------------------------------------------- + +void Stream::closeStream( void ) + throw( ::com::sun::star::io::NotConnectedException, + ::com::sun::star::io::IOException, + ::com::sun::star::uno::RuntimeException ) +{ + if (m_handle) { + gnome_vfs_close (m_handle); + m_handle = NULL; + } else + throw IOException(); +} + +void Stream::throwOnError( GnomeVFSResult result ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException ) +{ + if( result != GNOME_VFS_OK ) { + ::rtl::OUString aMsg = ::rtl::OUString::createFromAscii + ( gnome_vfs_result_to_string( result ) ); + + g_warning( "Input Stream exceptional result '%s' (%d)", + gnome_vfs_result_to_string( result ), result ); + + throw IOException( aMsg, static_cast< cppu::OWeakObject * >( this ) ); + } +}