diff options
Diffstat (limited to 'oox/source/helper/binaryoutputstream.cxx')
-rw-r--r-- | oox/source/helper/binaryoutputstream.cxx | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/oox/source/helper/binaryoutputstream.cxx b/oox/source/helper/binaryoutputstream.cxx new file mode 100644 index 000000000..50ce7f11c --- /dev/null +++ b/oox/source/helper/binaryoutputstream.cxx @@ -0,0 +1,184 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <oox/helper/binaryoutputstream.hxx> + +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <osl/diagnose.h> +#include <string.h> + +namespace oox { + +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::uno; + +namespace { + +const sal_Int32 OUTPUTSTREAM_BUFFERSIZE = 0x8000; + +} // namespace + +BinaryXOutputStream::BinaryXOutputStream( const Reference< XOutputStream >& rxOutStrm, bool bAutoClose ) : + BinaryStreamBase( Reference< XSeekable >( rxOutStrm, UNO_QUERY ).is() ), + BinaryXSeekableStream( Reference< XSeekable >( rxOutStrm, UNO_QUERY ) ), + maBuffer( OUTPUTSTREAM_BUFFERSIZE ), + mxOutStrm( rxOutStrm ), + mbAutoClose( bAutoClose && rxOutStrm.is() ) +{ + mbEof = !mxOutStrm.is(); +} + +BinaryXOutputStream::~BinaryXOutputStream() +{ + close(); +} + +void BinaryXOutputStream::close() +{ + OSL_ENSURE( !mbAutoClose || mxOutStrm.is(), "BinaryXOutputStream::close - invalid call" ); + if( mxOutStrm.is() ) try + { + mxOutStrm->flush(); + if ( mbAutoClose ) + mxOutStrm->closeOutput(); + } + catch( Exception& ) + { + OSL_FAIL( "BinaryXOutputStream::close - closing output stream failed" ); + } + mxOutStrm.clear(); + mbAutoClose = false; + BinaryXSeekableStream::close(); +} + +void BinaryXOutputStream::writeData( const StreamDataSequence& rData, size_t /*nAtomSize*/ ) +{ + if( mxOutStrm.is() ) try + { + mxOutStrm->writeBytes( rData ); + } + catch( Exception& ) + { + OSL_FAIL( "BinaryXOutputStream::writeData - stream read error" ); + } +} + +void BinaryXOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize ) +{ + if( !(mxOutStrm.is() && (nBytes > 0)) ) + return; + + sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, (OUTPUTSTREAM_BUFFERSIZE / nAtomSize) * nAtomSize ); + const sal_uInt8* pnMem = static_cast< const sal_uInt8* >( pMem ); + while( nBytes > 0 ) + { + sal_Int32 nWriteSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, nBufferSize ); + maBuffer.realloc( nWriteSize ); + memcpy( maBuffer.getArray(), pnMem, static_cast< size_t >( nWriteSize ) ); + writeData( maBuffer, nAtomSize ); + pnMem += nWriteSize; + nBytes -= nWriteSize; + } +} + +void +BinaryOutputStream::writeCharArrayUC( std::u16string_view rString, rtl_TextEncoding eTextEnc ) +{ + OString sBuf( OUStringToOString( rString, eTextEnc ) ); + sBuf = sBuf.replace( '\0', '?' ); + writeMemory( static_cast< const void* >( sBuf.getStr() ), sBuf.getLength() ); +} + +void +BinaryOutputStream::writeUnicodeArray( const OUString& rString ) +{ + OUString sBuf = rString.replace( '\0', '?' ); +#ifdef OSL_BIGENDIAN + // need a non-const buffer for swapping byte order + sal_Unicode notConst[sBuf.getLength()]; + memcpy( notConst, sBuf.getStr(), sizeof(sal_Unicode)*sBuf.getLength() ); + writeArray( notConst, sBuf.getLength() ); +#else + writeArray( sBuf.getStr(), sBuf.getLength() ); +#endif +} + +void BinaryOutputStream::writeCompressedUnicodeArray( const OUString& rString, bool bCompressed ) +{ + if ( bCompressed ) + // ISO-8859-1 maps all byte values 0xHH to the same Unicode code point U+00HH + writeCharArrayUC( rString, RTL_TEXTENCODING_ISO_8859_1 ); + else + writeUnicodeArray( rString ); +} + +SequenceOutputStream::SequenceOutputStream( StreamDataSequence & rData ) : + BinaryStreamBase( true ), + mpData( &rData ), + mnPos( 0 ) +{ +} + +void SequenceOutputStream::writeData( const StreamDataSequence& rData, size_t nAtomSize ) +{ + if( mpData && rData.hasElements() ) + writeMemory( rData.getConstArray(), rData.getLength(), nAtomSize ); +} + +void SequenceOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes, size_t /*nAtomSize*/ ) +{ + if( mpData && (nBytes > 0) ) + { + if( mpData->getLength() - mnPos < nBytes ) + mpData->realloc( mnPos + nBytes ); + memcpy( mpData->getArray() + mnPos, pMem, static_cast< size_t >( nBytes ) ); + mnPos += nBytes; + } +} + +sal_Int64 SequenceOutputStream::size() const +{ + return mpData ? mpData->getLength() : -1; +} + +sal_Int64 SequenceOutputStream::tell() const +{ + return mpData ? mnPos : -1; +} + +void SequenceOutputStream::seek( sal_Int64 nPos ) +{ + if( mpData ) + { + mnPos = getLimitedValue< sal_Int32, sal_Int64 >( nPos, 0, mpData->getLength() ); + mbEof = mnPos != nPos; + } +} + +void SequenceOutputStream::close() +{ + mpData = nullptr; + mbEof = true; +} + + +} // namespace oox + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |