diff options
Diffstat (limited to 'ucb/source/ucp/gvfs/gvfs_stream.cxx')
-rw-r--r-- | ucb/source/ucp/gvfs/gvfs_stream.cxx | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/ucb/source/ucp/gvfs/gvfs_stream.cxx b/ucb/source/ucp/gvfs/gvfs_stream.cxx new file mode 100644 index 000000000000..ab0c6ed90fc0 --- /dev/null +++ b/ucb/source/ucp/gvfs/gvfs_stream.cxx @@ -0,0 +1,343 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_ucb.hxx" +#include "gvfs_stream.hxx" +#include <rtl/memory.h> +#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp> + +#include <libgnomevfs/gnome-vfs-ops.h> + +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( sal::static_int_cast<sal_uInt32>(nBytesRead) ); + + return sal::static_int_cast<sal_Int32>(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 readBytes( 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 ) ); + } +} |