1*dde7d3faSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*dde7d3faSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*dde7d3faSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*dde7d3faSAndrew Rist * distributed with this work for additional information 6*dde7d3faSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*dde7d3faSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*dde7d3faSAndrew Rist * "License"); you may not use this file except in compliance 9*dde7d3faSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*dde7d3faSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*dde7d3faSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*dde7d3faSAndrew Rist * software distributed under the License is distributed on an 15*dde7d3faSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*dde7d3faSAndrew Rist * KIND, either express or implied. See the License for the 17*dde7d3faSAndrew Rist * specific language governing permissions and limitations 18*dde7d3faSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*dde7d3faSAndrew Rist *************************************************************/ 21*dde7d3faSAndrew Rist 22*dde7d3faSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_comphelper.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "comphelper_module.hxx" 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include <com/sun/star/io/XStream.hpp> 30cdf0e10cSrcweir #include <com/sun/star/io/XSeekableInputStream.hpp> 31cdf0e10cSrcweir #include <com/sun/star/io/XTruncate.hpp> 32cdf0e10cSrcweir #include <com/sun/star/uno/XComponentContext.hpp> 33cdf0e10cSrcweir #include <cppuhelper/implbase4.hxx> 34cdf0e10cSrcweir 35cdf0e10cSrcweir #include <string.h> 36cdf0e10cSrcweir #include <vector> 37cdf0e10cSrcweir 38cdf0e10cSrcweir using ::rtl::OUString; 39cdf0e10cSrcweir using ::cppu::OWeakObject; 40cdf0e10cSrcweir using ::cppu::WeakImplHelper4; 41cdf0e10cSrcweir using namespace ::com::sun::star::io; 42cdf0e10cSrcweir using namespace ::com::sun::star::uno; 43cdf0e10cSrcweir using namespace ::com::sun::star::lang; 44cdf0e10cSrcweir using namespace ::osl; 45cdf0e10cSrcweir 46cdf0e10cSrcweir namespace comphelper 47cdf0e10cSrcweir { 48cdf0e10cSrcweir 49cdf0e10cSrcweir class UNOMemoryStream : public WeakImplHelper4 < XStream, XSeekableInputStream, XOutputStream, XTruncate > 50cdf0e10cSrcweir { 51cdf0e10cSrcweir public: 52cdf0e10cSrcweir UNOMemoryStream(); 53cdf0e10cSrcweir virtual ~UNOMemoryStream(); 54cdf0e10cSrcweir 55cdf0e10cSrcweir // XStream 56cdf0e10cSrcweir virtual Reference< XInputStream > SAL_CALL getInputStream( ) throw (RuntimeException); 57cdf0e10cSrcweir virtual Reference< XOutputStream > SAL_CALL getOutputStream( ) throw (RuntimeException); 58cdf0e10cSrcweir 59cdf0e10cSrcweir // XInputStream 60cdf0e10cSrcweir virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); 61cdf0e10cSrcweir virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); 62cdf0e10cSrcweir virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); 63cdf0e10cSrcweir virtual sal_Int32 SAL_CALL available() throw (NotConnectedException, IOException, RuntimeException); 64cdf0e10cSrcweir virtual void SAL_CALL closeInput() throw (NotConnectedException, IOException, RuntimeException); 65cdf0e10cSrcweir 66cdf0e10cSrcweir // XSeekable 67cdf0e10cSrcweir virtual void SAL_CALL seek( sal_Int64 location ) throw (IllegalArgumentException, IOException, RuntimeException); 68cdf0e10cSrcweir virtual sal_Int64 SAL_CALL getPosition() throw (IOException, RuntimeException); 69cdf0e10cSrcweir virtual sal_Int64 SAL_CALL getLength() throw (IOException, RuntimeException); 70cdf0e10cSrcweir 71cdf0e10cSrcweir // XOutputStream 72cdf0e10cSrcweir virtual void SAL_CALL writeBytes( const Sequence< sal_Int8 >& aData ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); 73cdf0e10cSrcweir virtual void SAL_CALL flush() throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); 74cdf0e10cSrcweir virtual void SAL_CALL closeOutput() throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); 75cdf0e10cSrcweir 76cdf0e10cSrcweir // XTruncate 77cdf0e10cSrcweir virtual void SAL_CALL truncate() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); 78cdf0e10cSrcweir 79cdf0e10cSrcweir // XServiceInfo - static versions (used for component registration) 80cdf0e10cSrcweir static ::rtl::OUString SAL_CALL getImplementationName_static(); 81cdf0e10cSrcweir static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(); 82cdf0e10cSrcweir static Reference< XInterface > SAL_CALL Create( const Reference< ::com::sun::star::uno::XComponentContext >& ); 83cdf0e10cSrcweir 84cdf0e10cSrcweir private: 85cdf0e10cSrcweir std::vector< sal_Int8 > maData; 86cdf0e10cSrcweir sal_Int32 mnCursor; 87cdf0e10cSrcweir }; 88cdf0e10cSrcweir 89cdf0e10cSrcweir UNOMemoryStream::UNOMemoryStream() 90cdf0e10cSrcweir : mnCursor(0) 91cdf0e10cSrcweir { 92cdf0e10cSrcweir } 93cdf0e10cSrcweir 94cdf0e10cSrcweir UNOMemoryStream::~UNOMemoryStream() 95cdf0e10cSrcweir { 96cdf0e10cSrcweir } 97cdf0e10cSrcweir 98cdf0e10cSrcweir // XStream 99cdf0e10cSrcweir Reference< XInputStream > SAL_CALL UNOMemoryStream::getInputStream( ) throw (RuntimeException) 100cdf0e10cSrcweir { 101cdf0e10cSrcweir return this; 102cdf0e10cSrcweir } 103cdf0e10cSrcweir 104cdf0e10cSrcweir Reference< XOutputStream > SAL_CALL UNOMemoryStream::getOutputStream( ) throw (RuntimeException) 105cdf0e10cSrcweir { 106cdf0e10cSrcweir return this; 107cdf0e10cSrcweir } 108cdf0e10cSrcweir 109cdf0e10cSrcweir // XInputStream 110cdf0e10cSrcweir sal_Int32 SAL_CALL UNOMemoryStream::readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) 111cdf0e10cSrcweir { 112cdf0e10cSrcweir if( nBytesToRead < 0 ) 113cdf0e10cSrcweir throw IOException(); 114cdf0e10cSrcweir 115cdf0e10cSrcweir nBytesToRead = std::min( nBytesToRead, available() ); 116cdf0e10cSrcweir aData.realloc( nBytesToRead ); 117cdf0e10cSrcweir 118cdf0e10cSrcweir if( nBytesToRead ) 119cdf0e10cSrcweir { 120cdf0e10cSrcweir sal_Int8* pData = static_cast<sal_Int8*>(&(*maData.begin())); 121cdf0e10cSrcweir sal_Int8* pCursor = &((pData)[mnCursor]); 122cdf0e10cSrcweir memcpy( (void*)aData.getArray(), (void*)pCursor, nBytesToRead ); 123cdf0e10cSrcweir 124cdf0e10cSrcweir mnCursor += nBytesToRead; 125cdf0e10cSrcweir } 126cdf0e10cSrcweir 127cdf0e10cSrcweir return nBytesToRead; 128cdf0e10cSrcweir } 129cdf0e10cSrcweir 130cdf0e10cSrcweir sal_Int32 SAL_CALL UNOMemoryStream::readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) 131cdf0e10cSrcweir { 132cdf0e10cSrcweir return readBytes( aData, nMaxBytesToRead ); 133cdf0e10cSrcweir } 134cdf0e10cSrcweir 135cdf0e10cSrcweir void SAL_CALL UNOMemoryStream::skipBytes( sal_Int32 nBytesToSkip ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) 136cdf0e10cSrcweir { 137cdf0e10cSrcweir if( nBytesToSkip < 0 ) 138cdf0e10cSrcweir throw IOException(); 139cdf0e10cSrcweir 140cdf0e10cSrcweir mnCursor += std::min( nBytesToSkip, available() ); 141cdf0e10cSrcweir } 142cdf0e10cSrcweir 143cdf0e10cSrcweir sal_Int32 SAL_CALL UNOMemoryStream::available() throw (NotConnectedException, IOException, RuntimeException) 144cdf0e10cSrcweir { 145cdf0e10cSrcweir return static_cast< sal_Int32 >( maData.size() ) - mnCursor; 146cdf0e10cSrcweir } 147cdf0e10cSrcweir 148cdf0e10cSrcweir void SAL_CALL UNOMemoryStream::closeInput() throw (NotConnectedException, IOException, RuntimeException) 149cdf0e10cSrcweir { 150cdf0e10cSrcweir mnCursor = 0; 151cdf0e10cSrcweir } 152cdf0e10cSrcweir 153cdf0e10cSrcweir // XSeekable 154cdf0e10cSrcweir void SAL_CALL UNOMemoryStream::seek( sal_Int64 location ) throw (IllegalArgumentException, IOException, RuntimeException) 155cdf0e10cSrcweir { 156cdf0e10cSrcweir if( (location < 0) || (location > SAL_MAX_INT32) ) 157cdf0e10cSrcweir throw IllegalArgumentException( OUString(RTL_CONSTASCII_USTRINGPARAM("this implementation does not support more than 2GB!")), Reference< XInterface >(static_cast<OWeakObject*>(this)), 0 ); 158cdf0e10cSrcweir 159cdf0e10cSrcweir // seek operation should be able to resize the stream 160cdf0e10cSrcweir if ( location > static_cast< sal_Int64 >( maData.size() ) ) 161cdf0e10cSrcweir maData.resize( static_cast< sal_Int32 >( location ) ); 162cdf0e10cSrcweir 163cdf0e10cSrcweir if ( location > static_cast< sal_Int64 >( maData.size() ) ) 164cdf0e10cSrcweir maData.resize( static_cast< sal_Int32 >( location ) ); 165cdf0e10cSrcweir 166cdf0e10cSrcweir mnCursor = static_cast< sal_Int32 >( location ); 167cdf0e10cSrcweir } 168cdf0e10cSrcweir 169cdf0e10cSrcweir sal_Int64 SAL_CALL UNOMemoryStream::getPosition() throw (IOException, RuntimeException) 170cdf0e10cSrcweir { 171cdf0e10cSrcweir return static_cast< sal_Int64 >( mnCursor ); 172cdf0e10cSrcweir } 173cdf0e10cSrcweir 174cdf0e10cSrcweir sal_Int64 SAL_CALL UNOMemoryStream::getLength() throw (IOException, RuntimeException) 175cdf0e10cSrcweir { 176cdf0e10cSrcweir return static_cast< sal_Int64 >( maData.size() ); 177cdf0e10cSrcweir } 178cdf0e10cSrcweir 179cdf0e10cSrcweir // XOutputStream 180cdf0e10cSrcweir void SAL_CALL UNOMemoryStream::writeBytes( const Sequence< sal_Int8 >& aData ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) 181cdf0e10cSrcweir { 182cdf0e10cSrcweir const sal_Int32 nBytesToWrite( aData.getLength() ); 183cdf0e10cSrcweir if( nBytesToWrite ) 184cdf0e10cSrcweir { 185cdf0e10cSrcweir sal_Int64 nNewSize = static_cast< sal_Int64 >( mnCursor + nBytesToWrite ); 186cdf0e10cSrcweir if( nNewSize > SAL_MAX_INT32 ) 187cdf0e10cSrcweir { 188cdf0e10cSrcweir OSL_ASSERT(false); 189cdf0e10cSrcweir throw IOException( OUString(RTL_CONSTASCII_USTRINGPARAM("this implementation does not support more than 2GB!")), Reference< XInterface >(static_cast<OWeakObject*>(this)) ); 190cdf0e10cSrcweir } 191cdf0e10cSrcweir 192cdf0e10cSrcweir if( static_cast< sal_Int32 >( nNewSize ) > static_cast< sal_Int32 >( maData.size() ) ) 193cdf0e10cSrcweir maData.resize( static_cast< sal_Int32 >( nNewSize ) ); 194cdf0e10cSrcweir 195cdf0e10cSrcweir sal_Int8* pData = static_cast<sal_Int8*>(&(*maData.begin())); 196cdf0e10cSrcweir sal_Int8* pCursor = &(pData[mnCursor]); 197cdf0e10cSrcweir memcpy( (void*)pCursor, (void*)aData.getConstArray(), nBytesToWrite ); 198cdf0e10cSrcweir 199cdf0e10cSrcweir mnCursor += nBytesToWrite; 200cdf0e10cSrcweir } 201cdf0e10cSrcweir } 202cdf0e10cSrcweir 203cdf0e10cSrcweir void SAL_CALL UNOMemoryStream::flush() throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) 204cdf0e10cSrcweir { 205cdf0e10cSrcweir } 206cdf0e10cSrcweir 207cdf0e10cSrcweir void SAL_CALL UNOMemoryStream::closeOutput() throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) 208cdf0e10cSrcweir { 209cdf0e10cSrcweir mnCursor = 0; 210cdf0e10cSrcweir } 211cdf0e10cSrcweir 212cdf0e10cSrcweir //XTruncate 213cdf0e10cSrcweir void SAL_CALL UNOMemoryStream::truncate() throw (IOException, RuntimeException) 214cdf0e10cSrcweir { 215cdf0e10cSrcweir maData.resize( 0 ); 216cdf0e10cSrcweir mnCursor = 0; 217cdf0e10cSrcweir } 218cdf0e10cSrcweir 219cdf0e10cSrcweir ::rtl::OUString SAL_CALL UNOMemoryStream::getImplementationName_static() 220cdf0e10cSrcweir { 221cdf0e10cSrcweir static const OUString sImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.MemoryStream" ) ); 222cdf0e10cSrcweir return sImplName; 223cdf0e10cSrcweir } 224cdf0e10cSrcweir 225cdf0e10cSrcweir Sequence< ::rtl::OUString > SAL_CALL UNOMemoryStream::getSupportedServiceNames_static() 226cdf0e10cSrcweir { 227cdf0e10cSrcweir Sequence< OUString > aSeq(1); 228cdf0e10cSrcweir aSeq[0] = getImplementationName_static(); 229cdf0e10cSrcweir return aSeq; 230cdf0e10cSrcweir } 231cdf0e10cSrcweir 232cdf0e10cSrcweir Reference< XInterface > SAL_CALL UNOMemoryStream::Create( 233cdf0e10cSrcweir const Reference< XComponentContext >& ) 234cdf0e10cSrcweir { 235cdf0e10cSrcweir return static_cast<OWeakObject*>(new UNOMemoryStream()); 236cdf0e10cSrcweir } 237cdf0e10cSrcweir 238cdf0e10cSrcweir } // namespace comphelper 239cdf0e10cSrcweir 240cdf0e10cSrcweir void createRegistryInfo_UNOMemoryStream() 241cdf0e10cSrcweir { 242cdf0e10cSrcweir static ::comphelper::module::OAutoRegistration< ::comphelper::UNOMemoryStream > aAutoRegistration; 243cdf0e10cSrcweir } 244