diff options
Diffstat (limited to 'oox/source/helper')
-rw-r--r-- | oox/source/helper/binaryinputstream.cxx | 182 | ||||
-rw-r--r-- | oox/source/helper/binaryoutputstream.cxx | 76 | ||||
-rw-r--r-- | oox/source/helper/binarystreambase.cxx | 63 | ||||
-rw-r--r-- | oox/source/helper/containerhelper.cxx | 68 | ||||
-rwxr-xr-x | oox/source/helper/graphichelper.cxx | 11 | ||||
-rwxr-xr-x[-rw-r--r--] | oox/source/helper/makefile.mk | 0 | ||||
-rw-r--r-- | oox/source/helper/modelobjecthelper.cxx | 29 | ||||
-rw-r--r-- | oox/source/helper/propertymap.cxx | 4 | ||||
-rw-r--r-- | oox/source/helper/propertyset.cxx | 67 | ||||
-rwxr-xr-x[-rw-r--r--] | oox/source/helper/textinputstream.cxx | 223 | ||||
-rw-r--r-- | oox/source/helper/zipstorage.cxx | 38 |
11 files changed, 472 insertions, 289 deletions
diff --git a/oox/source/helper/binaryinputstream.cxx b/oox/source/helper/binaryinputstream.cxx index 2d547cdbf724..58c7cca37008 100644 --- a/oox/source/helper/binaryinputstream.cxx +++ b/oox/source/helper/binaryinputstream.cxx @@ -27,6 +27,8 @@ #include "oox/helper/binaryinputstream.hxx" +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> #include <string.h> #include <vector> #include <rtl/strbuf.hxx> @@ -80,11 +82,16 @@ OString BinaryInputStream::readCharArray( sal_Int32 nChars, bool bAllowNulChars if( nChars <= 0 ) return OString(); - ::std::vector< sal_Char > aBuffer( static_cast< size_t >( nChars ) ); - size_t nCharsRead = static_cast< size_t >( readMemory( &aBuffer.front(), nChars ) ); + ::std::vector< sal_uInt8 > aBuffer; + sal_Int32 nCharsRead = readArray( aBuffer, nChars ); + if( nCharsRead <= 0 ) + return OString(); + + aBuffer.resize( static_cast< size_t >( nCharsRead ) ); if( !bAllowNulChars ) - ::std::replace( aBuffer.begin(), aBuffer.begin() + nCharsRead, '\0', '?' ); - return OString( &aBuffer.front(), nCharsRead ); + ::std::replace( aBuffer.begin(), aBuffer.end(), '\0', '?' ); + + return OString( reinterpret_cast< sal_Char* >( &aBuffer.front() ), nCharsRead ); } OUString BinaryInputStream::readCharArrayUC( sal_Int32 nChars, rtl_TextEncoding eTextEnc, bool bAllowNulChars ) @@ -94,30 +101,44 @@ OUString BinaryInputStream::readCharArrayUC( sal_Int32 nChars, rtl_TextEncoding OUString BinaryInputStream::readUnicodeArray( sal_Int32 nChars, bool bAllowNulChars ) { - OUStringBuffer aBuffer; - if( nChars > 0 ) - { - aBuffer.ensureCapacity( nChars ); - sal_uInt16 nChar; - for( sal_uInt16 nCharIdx = 0; !mbEof && (nCharIdx < nChars); ++nCharIdx ) - { - readValue( nChar ); - aBuffer.append( static_cast< sal_Unicode >( (!bAllowNulChars && (nChar == 0)) ? '?' : nChar ) ); - } - } - return aBuffer.makeStringAndClear(); + if( nChars <= 0 ) + return OUString(); + + ::std::vector< sal_uInt16 > aBuffer; + sal_Int32 nCharsRead = readArray( aBuffer, nChars ); + if( nCharsRead <= 0 ) + return OUString(); + + aBuffer.resize( static_cast< size_t >( nCharsRead ) ); + if( !bAllowNulChars ) + ::std::replace( aBuffer.begin(), aBuffer.begin() + nCharsRead, '\0', '?' ); + + OUStringBuffer aStringBuffer; + aStringBuffer.ensureCapacity( nCharsRead ); + for( ::std::vector< sal_uInt16 >::iterator aIt = aBuffer.begin(), aEnd = aBuffer.end(); aIt != aEnd; ++aIt ) + aStringBuffer.append( static_cast< sal_Unicode >( *aIt ) ); + return aStringBuffer.makeStringAndClear(); +} + +OUString BinaryInputStream::readCompressedUnicodeArray( sal_Int32 nChars, bool bCompressed, bool bAllowNulChars ) +{ + return bCompressed ? + // ISO-8859-1 maps all byte values 0xHH to the same Unicode code point U+00HH + readCharArrayUC( nChars, RTL_TEXTENCODING_ISO_8859_1, bAllowNulChars ) : + readUnicodeArray( nChars, bAllowNulChars ); } -void BinaryInputStream::copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nBytes ) +void BinaryInputStream::copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nBytes, sal_Int32 nAtomSize ) { if( nBytes > 0 ) { - sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, INPUTSTREAM_BUFFERSIZE ); + // make buffer size a multiple of the passed atom size + sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, (INPUTSTREAM_BUFFERSIZE / nAtomSize) * nAtomSize ); StreamDataSequence aBuffer( nBufferSize ); while( nBytes > 0 ) { sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, nBufferSize ); - sal_Int32 nBytesRead = readData( aBuffer, nReadSize ); + sal_Int32 nBytesRead = readData( aBuffer, nReadSize, nAtomSize ); rOutStrm.writeData( aBuffer ); if( nReadSize == nBytesRead ) nBytes -= nReadSize; @@ -127,34 +148,44 @@ void BinaryInputStream::copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nB } } -void BinaryInputStream::readAtom( void* opMem, sal_uInt8 nSize ) -{ - readMemory( opMem, nSize ); -} - // ============================================================================ BinaryXInputStream::BinaryXInputStream( const Reference< XInputStream >& rxInStrm, bool bAutoClose ) : + BinaryStreamBase( Reference< XSeekable >( rxInStrm, UNO_QUERY ).is() ), BinaryXSeekableStream( Reference< XSeekable >( rxInStrm, UNO_QUERY ) ), maBuffer( INPUTSTREAM_BUFFERSIZE ), mxInStrm( rxInStrm ), - mbAutoClose( bAutoClose ) + mbAutoClose( bAutoClose && rxInStrm.is() ) { mbEof = !mxInStrm.is(); } BinaryXInputStream::~BinaryXInputStream() { - if( mbAutoClose ) - close(); + close(); +} + +void BinaryXInputStream::close() +{ + OSL_ENSURE( !mbAutoClose || mxInStrm.is(), "BinaryXInputStream::close - invalid call" ); + if( mbAutoClose && mxInStrm.is() ) try + { + mxInStrm->closeInput(); + } + catch( Exception& ) + { + OSL_ENSURE( false, "BinaryXInputStream::close - closing input stream failed" ); + } + mxInStrm.clear(); + mbAutoClose = false; + BinaryXSeekableStream::close(); } -sal_Int32 BinaryXInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes ) +sal_Int32 BinaryXInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t /*nAtomSize*/ ) { sal_Int32 nRet = 0; if( !mbEof && (nBytes > 0) ) try { - OSL_ENSURE( mxInStrm.is(), "BinaryXInputStream::readData - invalid call" ); nRet = mxInStrm->readBytes( orData, nBytes ); mbEof = nRet != nBytes; } @@ -165,7 +196,7 @@ sal_Int32 BinaryXInputStream::readData( StreamDataSequence& orData, sal_Int32 nB return nRet; } -sal_Int32 BinaryXInputStream::readMemory( void* opMem, sal_Int32 nBytes ) +sal_Int32 BinaryXInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nRet = 0; if( !mbEof && (nBytes > 0) ) @@ -175,7 +206,7 @@ sal_Int32 BinaryXInputStream::readMemory( void* opMem, sal_Int32 nBytes ) while( !mbEof && (nBytes > 0) ) { sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, nBufferSize ); - sal_Int32 nBytesRead = readData( maBuffer, nReadSize ); + sal_Int32 nBytesRead = readData( maBuffer, nReadSize, nAtomSize ); if( nBytesRead > 0 ) memcpy( opnMem, maBuffer.getConstArray(), static_cast< size_t >( nBytesRead ) ); opnMem += nBytesRead; @@ -186,11 +217,10 @@ sal_Int32 BinaryXInputStream::readMemory( void* opMem, sal_Int32 nBytes ) return nRet; } -void BinaryXInputStream::skip( sal_Int32 nBytes ) +void BinaryXInputStream::skip( sal_Int32 nBytes, size_t /*nAtomSize*/ ) { if( !mbEof ) try { - OSL_ENSURE( mxInStrm.is(), "BinaryXInputStream::skip - invalid call" ); mxInStrm->skipBytes( nBytes ); } catch( Exception& ) @@ -199,60 +229,48 @@ void BinaryXInputStream::skip( sal_Int32 nBytes ) } } -void BinaryXInputStream::close() -{ - if( mxInStrm.is() ) try - { - mxInStrm->closeInput(); - mxInStrm.clear(); - } - catch( Exception& ) - { - OSL_ENSURE( false, "BinaryXInputStream::close - closing input stream failed" ); - } -} - // ============================================================================ SequenceInputStream::SequenceInputStream( const StreamDataSequence& rData ) : + BinaryStreamBase( true ), SequenceSeekableStream( rData ) { } -sal_Int32 SequenceInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes ) +sal_Int32 SequenceInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t /*nAtomSize*/ ) { sal_Int32 nReadBytes = 0; if( !mbEof ) { - nReadBytes = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mrData.getLength() - mnPos ); + nReadBytes = getMaxBytes( nBytes ); orData.realloc( nReadBytes ); if( nReadBytes > 0 ) - memcpy( orData.getArray(), mrData.getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) ); + memcpy( orData.getArray(), mpData->getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) ); mnPos += nReadBytes; mbEof = nReadBytes < nBytes; } return nReadBytes; } -sal_Int32 SequenceInputStream::readMemory( void* opMem, sal_Int32 nBytes ) +sal_Int32 SequenceInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t /*nAtomSize*/ ) { sal_Int32 nReadBytes = 0; if( !mbEof ) { - nReadBytes = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mrData.getLength() - mnPos ); + nReadBytes = getMaxBytes( nBytes ); if( nReadBytes > 0 ) - memcpy( opMem, mrData.getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) ); + memcpy( opMem, mpData->getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) ); mnPos += nReadBytes; mbEof = nReadBytes < nBytes; } return nReadBytes; } -void SequenceInputStream::skip( sal_Int32 nBytes ) +void SequenceInputStream::skip( sal_Int32 nBytes, size_t /*nAtomSize*/ ) { if( !mbEof ) { - sal_Int32 nSkipBytes = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mrData.getLength() - mnPos ); + sal_Int32 nSkipBytes = getMaxBytes( nBytes ); mnPos += nSkipBytes; mbEof = nSkipBytes < nBytes; } @@ -260,73 +278,75 @@ void SequenceInputStream::skip( sal_Int32 nBytes ) // ============================================================================ -RelativeInputStream::RelativeInputStream( BinaryInputStream& rInStrm, sal_Int64 nLength ) : - mrInStrm( rInStrm ), +RelativeInputStream::RelativeInputStream( BinaryInputStream& rInStrm, sal_Int64 nSize ) : + BinaryStreamBase( rInStrm.isSeekable() ), + mpInStrm( &rInStrm ), mnStartPos( rInStrm.tell() ), mnRelPos( 0 ) { sal_Int64 nRemaining = rInStrm.getRemaining(); - mnLength = (nRemaining >= 0) ? ::std::min( nLength, nRemaining ) : nLength; - mbEof = mnLength < 0; + mnSize = (nRemaining >= 0) ? ::std::min( nSize, nRemaining ) : nSize; + mbEof = mbEof || rInStrm.isEof() || (mnSize < 0); } -bool RelativeInputStream::isSeekable() const +sal_Int64 RelativeInputStream::size() const { - return mrInStrm.isSeekable(); -} - -sal_Int64 RelativeInputStream::getLength() const -{ - return mnLength; + return mpInStrm ? mnSize : -1; } sal_Int64 RelativeInputStream::tell() const { - return mnRelPos; + return mpInStrm ? mnRelPos : -1; } void RelativeInputStream::seek( sal_Int64 nPos ) { - if( mrInStrm.isSeekable() && (mnStartPos >= 0) ) + if( mpInStrm && isSeekable() && (mnStartPos >= 0) ) { - mnRelPos = getLimitedValue< sal_Int64, sal_Int64 >( nPos, 0, mnLength ); - mrInStrm.seek( mnStartPos + mnRelPos ); - mbEof = (mnRelPos != nPos) || mrInStrm.isEof(); + mnRelPos = getLimitedValue< sal_Int64, sal_Int64 >( nPos, 0, mnSize ); + mpInStrm->seek( mnStartPos + mnRelPos ); + mbEof = (mnRelPos != nPos) || mpInStrm->isEof(); } } -sal_Int32 RelativeInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes ) +void RelativeInputStream::close() +{ + mpInStrm = 0; + mbEof = true; +} + +sal_Int32 RelativeInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nReadBytes = 0; if( !mbEof ) { - sal_Int32 nRealBytes = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnLength - mnRelPos ); - nReadBytes = mrInStrm.readData( orData, nRealBytes ); + sal_Int32 nMaxBytes = getMaxBytes( nBytes ); + nReadBytes = mpInStrm->readData( orData, nMaxBytes, nAtomSize ); mnRelPos += nReadBytes; - mbEof = (nRealBytes < nBytes) || mrInStrm.isEof(); + mbEof = (nMaxBytes < nBytes) || mpInStrm->isEof(); } return nReadBytes; } -sal_Int32 RelativeInputStream::readMemory( void* opMem, sal_Int32 nBytes ) +sal_Int32 RelativeInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nReadBytes = 0; if( !mbEof ) { - sal_Int32 nRealBytes = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnLength - mnRelPos ); - nReadBytes = mrInStrm.readMemory( opMem, nRealBytes ); + sal_Int32 nMaxBytes = getMaxBytes( nBytes ); + nReadBytes = mpInStrm->readMemory( opMem, nMaxBytes, nAtomSize ); mnRelPos += nReadBytes; - mbEof = (nRealBytes < nBytes) || mrInStrm.isEof(); + mbEof = (nMaxBytes < nBytes) || mpInStrm->isEof(); } return nReadBytes; } -void RelativeInputStream::skip( sal_Int32 nBytes ) +void RelativeInputStream::skip( sal_Int32 nBytes, size_t nAtomSize ) { if( !mbEof ) { - sal_Int32 nSkipBytes = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnLength - mnRelPos ); - mrInStrm.skip( nSkipBytes ); + sal_Int32 nSkipBytes = getMaxBytes( nBytes ); + mpInStrm->skip( nSkipBytes, nAtomSize ); mnRelPos += nSkipBytes; mbEof = nSkipBytes < nBytes; } diff --git a/oox/source/helper/binaryoutputstream.cxx b/oox/source/helper/binaryoutputstream.cxx index f4ea9378aa90..2f894ccf1bf2 100644 --- a/oox/source/helper/binaryoutputstream.cxx +++ b/oox/source/helper/binaryoutputstream.cxx @@ -27,6 +27,8 @@ #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> @@ -45,33 +47,43 @@ const sal_Int32 OUTPUTSTREAM_BUFFERSIZE = 0x8000; // ============================================================================ -void BinaryOutputStream::writeAtom( const void* pMem, sal_uInt8 nSize ) -{ - writeMemory( pMem, nSize ); -} - -// ============================================================================ - 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 ) + mbAutoClose( bAutoClose && rxOutStrm.is() ) { mbEof = !mxOutStrm.is(); } BinaryXOutputStream::~BinaryXOutputStream() { - if( mbAutoClose ) - close(); + 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_ENSURE( false, "BinaryXOutputStream::close - closing output stream failed" ); + } + mxOutStrm.clear(); + mbAutoClose = false; + BinaryXSeekableStream::close(); } -void BinaryXOutputStream::writeData( const StreamDataSequence& rData ) +void BinaryXOutputStream::writeData( const StreamDataSequence& rData, size_t /*nAtomSize*/ ) { - try + if( mxOutStrm.is() ) try { - OSL_ENSURE( mxOutStrm.is(), "BinaryXOutputStream::writeData - invalid call" ); mxOutStrm->writeBytes( rData ); } catch( Exception& ) @@ -80,57 +92,45 @@ void BinaryXOutputStream::writeData( const StreamDataSequence& rData ) } } -void BinaryXOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes ) +void BinaryXOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize ) { - if( nBytes > 0 ) + if( mxOutStrm.is() && (nBytes > 0) ) { - sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, OUTPUTSTREAM_BUFFERSIZE ); + sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, (OUTPUTSTREAM_BUFFERSIZE / nAtomSize) * nAtomSize ); const sal_uInt8* pnMem = reinterpret_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 ); + writeData( maBuffer, nAtomSize ); pnMem += nWriteSize; nBytes -= nWriteSize; } } } -void BinaryXOutputStream::close() -{ - if( mxOutStrm.is() ) try - { - mxOutStrm->flush(); - mxOutStrm->closeOutput(); - } - catch( Exception& ) - { - OSL_ENSURE( false, "BinaryXOutputStream::close - closing output stream failed" ); - } -} - // ============================================================================ SequenceOutputStream::SequenceOutputStream( StreamDataSequence& rData ) : + BinaryStreamBase( true ), SequenceSeekableStream( rData ) { } -void SequenceOutputStream::writeData( const StreamDataSequence& rData ) +void SequenceOutputStream::writeData( const StreamDataSequence& rData, size_t nAtomSize ) { - if( rData.hasElements() ) - writeMemory( rData.getConstArray(), rData.getLength() ); + if( mpData && rData.hasElements() ) + writeMemory( rData.getConstArray(), rData.getLength(), nAtomSize ); } -void SequenceOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes ) +void SequenceOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes, size_t /*nAtomSize*/ ) { - if( nBytes > 0 ) + if( mpData && (nBytes > 0) ) { - if( mrData.getLength() - mnPos < nBytes ) - const_cast< StreamDataSequence& >( mrData ).realloc( mnPos + nBytes ); - memcpy( const_cast< StreamDataSequence& >( mrData ).getArray() + mnPos, pMem, static_cast< size_t >( nBytes ) ); + if( mpData->getLength() - mnPos < nBytes ) + const_cast< StreamDataSequence* >( mpData )->realloc( mnPos + nBytes ); + memcpy( const_cast< StreamDataSequence* >( mpData )->getArray() + mnPos, pMem, static_cast< size_t >( nBytes ) ); mnPos += nBytes; } } diff --git a/oox/source/helper/binarystreambase.cxx b/oox/source/helper/binarystreambase.cxx index d1e11850a68c..f189a37f97f5 100644 --- a/oox/source/helper/binarystreambase.cxx +++ b/oox/source/helper/binarystreambase.cxx @@ -27,6 +27,7 @@ #include "oox/helper/binarystreambase.hxx" +#include <com/sun/star/io/XSeekable.hpp> #include <osl/diagnose.h> namespace oox { @@ -42,30 +43,11 @@ BinaryStreamBase::~BinaryStreamBase() { } -bool BinaryStreamBase::isSeekable() const -{ - return false; -} - -sal_Int64 BinaryStreamBase::getLength() const -{ - return -1; -} - -sal_Int64 BinaryStreamBase::tell() const -{ - return -1; -} - -void BinaryStreamBase::seek( sal_Int64 ) -{ -} - sal_Int64 BinaryStreamBase::getRemaining() const { // do not use isSeekable(), implementations may provide stream position and size even if not seekable sal_Int64 nPos = tell(); - sal_Int64 nLen = getLength(); + sal_Int64 nLen = size(); return ((nPos >= 0) && (nLen >= 0)) ? ::std::max< sal_Int64 >( nLen - nPos, 0 ) : -1; } @@ -73,7 +55,7 @@ void BinaryStreamBase::alignToBlock( sal_Int32 nBlockSize, sal_Int64 nAnchorPos { sal_Int64 nStrmPos = tell(); // nothing to do, if stream is at anchor position - if( isSeekable() && (0 <= nAnchorPos) && (nAnchorPos != nStrmPos) && (nBlockSize > 1) ) + if( mbSeekable && (0 <= nAnchorPos) && (nAnchorPos != nStrmPos) && (nBlockSize > 1) ) { // prevent modulo with negative arguments... sal_Int64 nSkipSize = (nAnchorPos < nStrmPos) ? @@ -86,16 +68,16 @@ void BinaryStreamBase::alignToBlock( sal_Int32 nBlockSize, sal_Int64 nAnchorPos // ============================================================================ BinaryXSeekableStream::BinaryXSeekableStream( const Reference< XSeekable >& rxSeekable ) : + BinaryStreamBase( mxSeekable.is() ), mxSeekable( rxSeekable ) { } -bool BinaryXSeekableStream::isSeekable() const +BinaryXSeekableStream::~BinaryXSeekableStream() { - return mxSeekable.is(); } -sal_Int64 BinaryXSeekableStream::getLength() const +sal_Int64 BinaryXSeekableStream::size() const { if( mxSeekable.is() ) try { @@ -103,7 +85,7 @@ sal_Int64 BinaryXSeekableStream::getLength() const } catch( Exception& ) { - OSL_ENSURE( false, "BinaryXSeekableStream::getLength - exception caught" ); + OSL_ENSURE( false, "BinaryXSeekableStream::size - exception caught" ); } return -1; } @@ -134,27 +116,44 @@ void BinaryXSeekableStream::seek( sal_Int64 nPos ) } } +void BinaryXSeekableStream::close() +{ + mxSeekable.clear(); + mbEof = true; +} + // ============================================================================ -bool SequenceSeekableStream::isSeekable() const +SequenceSeekableStream::SequenceSeekableStream( const StreamDataSequence& rData ) : + BinaryStreamBase( true ), + mpData( &rData ), + mnPos( 0 ) { - return true; } -sal_Int64 SequenceSeekableStream::getLength() const +sal_Int64 SequenceSeekableStream::size() const { - return mrData.getLength(); + return mpData ? mpData->getLength() : -1; } sal_Int64 SequenceSeekableStream::tell() const { - return mnPos; + return mpData ? mnPos : -1; } void SequenceSeekableStream::seek( sal_Int64 nPos ) { - mnPos = getLimitedValue< sal_Int32, sal_Int64 >( nPos, 0, mrData.getLength() ); - mbEof = mnPos != nPos; + if( mpData ) + { + mnPos = getLimitedValue< sal_Int32, sal_Int64 >( nPos, 0, mpData->getLength() ); + mbEof = mnPos != nPos; + } +} + +void SequenceSeekableStream::close() +{ + mpData = 0; + mbEof = true; } // ============================================================================ diff --git a/oox/source/helper/containerhelper.cxx b/oox/source/helper/containerhelper.cxx index e7f322ff10e3..264deb366878 100644 --- a/oox/source/helper/containerhelper.cxx +++ b/oox/source/helper/containerhelper.cxx @@ -30,6 +30,7 @@ #include <com/sun/star/container/XIndexContainer.hpp> #include <com/sun/star/container/XNameContainer.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> #include <rtl/ustrbuf.hxx> #include "oox/helper/helper.hxx" @@ -46,12 +47,66 @@ using ::rtl::OUStringBuffer; // ============================================================================ -Reference< XIndexContainer > ContainerHelper::createIndexContainer( const Reference< XMultiServiceFactory >& rxFactory ) +namespace { + +struct ValueRangeComp +{ + inline bool operator()( const ValueRange& rRange, sal_Int32 nValue ) const { return rRange.mnLast < nValue; } +}; + +} // namespace + +// ---------------------------------------------------------------------------- + +void ValueRangeSet::insert( const ValueRange& rRange ) +{ + // find the first range that contains or follows the starting point of the passed range + ValueRangeVector::iterator aBeg = maRanges.begin(); + ValueRangeVector::iterator aEnd = maRanges.end(); + ValueRangeVector::iterator aIt = ::std::lower_bound( aBeg, aEnd, rRange.mnFirst, ValueRangeComp() ); + // nothing to do if found range contains passed range + if( (aIt != aEnd) && aIt->contains( rRange ) ) return; + // check if previous range can be used to merge with the passed range + if( (aIt != aBeg) && ((aIt - 1)->mnLast + 1 == rRange.mnFirst) ) --aIt; + // check if current range (aIt) can be used to merge with passed range + if( (aIt != aEnd) && aIt->intersects( rRange ) ) + { + // set new start value to existing range + aIt->mnFirst = ::std::min( aIt->mnFirst, rRange.mnFirst ); + // search first range that cannot be merged anymore (aNext) + ValueRangeVector::iterator aNext = aIt + 1; + while( (aNext != aEnd) && aNext->intersects( rRange ) ) ++aNext; + // set new end value to existing range + aIt->mnLast = ::std::max( (aNext - 1)->mnLast, rRange.mnLast ); + // remove ranges covered by new existing range (aIt) + maRanges.erase( aIt + 1, aNext ); + } + else + { + // merging not possible: insert new range + maRanges.insert( aIt, rRange ); + } +} + +ValueRangeVector ValueRangeSet::getIntersection( const ValueRange& rRange ) const +{ + ValueRangeVector aRanges; + // find the range that contains nFirst or the first range that follows nFirst + ValueRangeVector::const_iterator aIt = ::std::lower_bound( maRanges.begin(), maRanges.end(), rRange.mnFirst, ValueRangeComp() ); + for( ValueRangeVector::const_iterator aEnd = maRanges.end(); (aIt != aEnd) && (aIt->mnFirst <= rRange.mnLast); ++aIt ) + aRanges.push_back( ValueRange( ::std::max( aIt->mnFirst, rRange.mnFirst ), ::std::min( aIt->mnLast, rRange.mnLast ) ) ); + return aRanges; +} + +// ============================================================================ + +Reference< XIndexContainer > ContainerHelper::createIndexContainer( const Reference< XComponentContext >& rxContext ) { Reference< XIndexContainer > xContainer; - if( rxFactory.is() ) try + if( rxContext.is() ) try { - xContainer.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.IndexedPropertyValues" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + xContainer.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.IndexedPropertyValues" ) ), UNO_QUERY_THROW ); } catch( Exception& ) { @@ -78,12 +133,13 @@ bool ContainerHelper::insertByIndex( return bRet; } -Reference< XNameContainer > ContainerHelper::createNameContainer( const Reference< XMultiServiceFactory >& rxFactory ) +Reference< XNameContainer > ContainerHelper::createNameContainer( const Reference< XComponentContext >& rxContext ) { Reference< XNameContainer > xContainer; - if( rxFactory.is() ) try + if( rxContext.is() ) try { - xContainer.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.NamedPropertyValues" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + xContainer.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.NamedPropertyValues" ) ), UNO_QUERY_THROW ); } catch( Exception& ) { diff --git a/oox/source/helper/graphichelper.cxx b/oox/source/helper/graphichelper.cxx index 2e5a612699e2..aeed0322b536 100755 --- a/oox/source/helper/graphichelper.cxx +++ b/oox/source/helper/graphichelper.cxx @@ -69,14 +69,13 @@ inline sal_Int32 lclConvertScreenPixelToHmm( double fPixel, double fPixelPerHmm // ============================================================================ GraphicHelper::GraphicHelper( const Reference< XComponentContext >& rxContext, const Reference< XFrame >& rxTargetFrame, const StorageRef& rxStorage ) : - mxCompContext( rxContext ), + mxContext( rxContext ), mxStorage( rxStorage ), maGraphicObjScheme( CREATE_OUSTRING( "vnd.sun.star.GraphicObject:" ) ) { - OSL_ENSURE( mxCompContext.is(), "GraphicHelper::GraphicHelper - missing component context" ); - Reference< XMultiServiceFactory > xFactory( mxCompContext->getServiceManager(), UNO_QUERY_THROW ); + OSL_ENSURE( mxContext.is(), "GraphicHelper::GraphicHelper - missing component context" ); + Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY ); OSL_ENSURE( xFactory.is(), "GraphicHelper::GraphicHelper - missing service factory" ); - if( xFactory.is() ) mxGraphicProvider.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.graphic.GraphicProvider" ) ), UNO_QUERY ); @@ -319,9 +318,9 @@ Reference< XGraphic > GraphicHelper::importEmbeddedGraphic( const OUString& rStr OUString GraphicHelper::createGraphicObject( const Reference< XGraphic >& rxGraphic ) const { OUString aGraphicObjUrl; - if( mxCompContext.is() && rxGraphic.is() ) try + if( mxContext.is() && rxGraphic.is() ) try { - Reference< XGraphicObject > xGraphicObj( GraphicObject::create( mxCompContext ), UNO_SET_THROW ); + Reference< XGraphicObject > xGraphicObj( GraphicObject::create( mxContext ), UNO_SET_THROW ); xGraphicObj->setGraphic( rxGraphic ); maGraphicObjects.push_back( xGraphicObj ); aGraphicObjUrl = maGraphicObjScheme + xGraphicObj->getUniqueID(); diff --git a/oox/source/helper/makefile.mk b/oox/source/helper/makefile.mk index f31736faac8d..f31736faac8d 100644..100755 --- a/oox/source/helper/makefile.mk +++ b/oox/source/helper/makefile.mk diff --git a/oox/source/helper/modelobjecthelper.cxx b/oox/source/helper/modelobjecthelper.cxx index 7fdbe4b38134..d9c5bddff0f2 100644 --- a/oox/source/helper/modelobjecthelper.cxx +++ b/oox/source/helper/modelobjecthelper.cxx @@ -48,12 +48,12 @@ using ::rtl::OUString; // ============================================================================ -ObjectContainer::ObjectContainer( const Reference< XMultiServiceFactory >& rxFactory, const OUString& rServiceName ) : - mxFactory( rxFactory ), +ObjectContainer::ObjectContainer( const Reference< XMultiServiceFactory >& rxModelFactory, const OUString& rServiceName ) : + mxModelFactory( rxModelFactory ), maServiceName( rServiceName ), mnIndex( 0 ) { - OSL_ENSURE( mxFactory.is(), "ObjectContainer::ObjectContainer - missing service factory" ); + OSL_ENSURE( mxModelFactory.is(), "ObjectContainer::ObjectContainer - missing service factory" ); } ObjectContainer::~ObjectContainer() @@ -94,9 +94,10 @@ OUString ObjectContainer::insertObject( const OUString& rObjName, const Any& rOb void ObjectContainer::createContainer() const { - if( !mxContainer.is() && mxFactory.is() ) try + if( !mxContainer.is() && mxModelFactory.is() ) try { - mxContainer.set( mxFactory->createInstance( maServiceName ), UNO_QUERY_THROW ); + mxContainer.set( mxModelFactory->createInstance( maServiceName ), UNO_QUERY_THROW ); + mxModelFactory.clear(); } catch( Exception& ) { @@ -107,13 +108,13 @@ void ObjectContainer::createContainer() const // ============================================================================ ModelObjectHelper::ModelObjectHelper( const Reference< XMultiServiceFactory >& rxModelFactory ) : - maMarkerContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.MarkerTable" ) ), - maDashContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.DashTable" ) ), - maGradientContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.GradientTable" ) ), - maBitmapContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.BitmapTable" ) ), - maDashNameBase( CREATE_OUSTRING( "msLineDash " ) ), - maGradientNameBase( CREATE_OUSTRING( "msFillGradient " ) ), - maBitmapNameBase( CREATE_OUSTRING( "msFillBitmap " ) ) + maMarkerContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.MarkerTable" ) ), + maDashContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.DashTable" ) ), + maGradientContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.GradientTable" ) ), + maBitmapUrlContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.BitmapTable" ) ), + maDashNameBase( CREATE_OUSTRING( "msLineDash " ) ), + maGradientNameBase( CREATE_OUSTRING( "msFillGradient " ) ), + maBitmapUrlNameBase( CREATE_OUSTRING( "msFillBitmap " ) ) { } @@ -140,10 +141,10 @@ OUString ModelObjectHelper::insertFillGradient( const Gradient& rGradient ) return maGradientContainer.insertObject( maGradientNameBase, Any( rGradient ), true ); } -OUString ModelObjectHelper::insertFillBitmap( const OUString& rGraphicUrl ) +OUString ModelObjectHelper::insertFillBitmapUrl( const OUString& rGraphicUrl ) { if( rGraphicUrl.getLength() > 0 ) - return maBitmapContainer.insertObject( maBitmapNameBase, Any( rGraphicUrl ), true ); + return maBitmapUrlContainer.insertObject( maBitmapUrlNameBase, Any( rGraphicUrl ), true ); return OUString(); } diff --git a/oox/source/helper/propertymap.cxx b/oox/source/helper/propertymap.cxx index 0c4e2cb07549..aada69cfb888 100644 --- a/oox/source/helper/propertymap.cxx +++ b/oox/source/helper/propertymap.cxx @@ -161,10 +161,6 @@ PropertyMap::PropertyMap() : { } -PropertyMap::~PropertyMap() -{ -} - /*static*/ const OUString& PropertyMap::getPropertyName( sal_Int32 nPropId ) { OSL_ENSURE( (0 <= nPropId) && (nPropId < PROP_COUNT), "PropertyMap::getPropertyName - invalid property identifier" ); diff --git a/oox/source/helper/propertyset.cxx b/oox/source/helper/propertyset.cxx index 4812fdf35aa5..c21b8959e2bc 100644 --- a/oox/source/helper/propertyset.cxx +++ b/oox/source/helper/propertyset.cxx @@ -48,26 +48,34 @@ void PropertySet::set( const Reference< XPropertySet >& rxPropSet ) { mxPropSet = rxPropSet; mxMultiPropSet.set( mxPropSet, UNO_QUERY ); + if( mxPropSet.is() ) try + { + mxPropSetInfo = mxPropSet->getPropertySetInfo(); + } + catch( Exception& ) + { + } } -// Get properties ------------------------------------------------------------- - -bool PropertySet::getAnyProperty( Any& orValue, sal_Int32 nPropId ) const +bool PropertySet::hasProperty( sal_Int32 nPropId ) const { - return getAnyProperty( orValue, PropertyMap::getPropertyName( nPropId ) ); + if( mxPropSetInfo.is() ) try + { + const OUString& rPropName = PropertyMap::getPropertyName( nPropId ); + return mxPropSetInfo->hasPropertyByName( rPropName ); + } + catch( Exception& ) + { + } + return false; } +// Get properties ------------------------------------------------------------- + Any PropertySet::getAnyProperty( sal_Int32 nPropId ) const { Any aValue; - return getAnyProperty( aValue, nPropId ) ? aValue : Any(); -} - -bool PropertySet::getBoolProperty( sal_Int32 nPropId ) const -{ - Any aAny; - bool bValue = false; - return getAnyProperty( aAny, nPropId ) && (aAny >>= bValue) && bValue; + return implGetPropertyValue( aValue, PropertyMap::getPropertyName( nPropId ) ) ? aValue : Any(); } void PropertySet::getProperties( Sequence< Any >& orValues, const Sequence< OUString >& rPropNames ) const @@ -90,15 +98,15 @@ void PropertySet::getProperties( Sequence< Any >& orValues, const Sequence< OUSt orValues.realloc( nLen ); Any* pValue = orValues.getArray(); for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue ) - getAnyProperty( *pValue, *pPropName ); + implGetPropertyValue( *pValue, *pPropName ); } } // Set properties ------------------------------------------------------------- -void PropertySet::setAnyProperty( sal_Int32 nPropId, const Any& rValue ) +bool PropertySet::setAnyProperty( sal_Int32 nPropId, const Any& rValue ) { - setAnyProperty( PropertyMap::getPropertyName( nPropId ), rValue ); + return implSetPropertyValue( PropertyMap::getPropertyName( nPropId ), rValue ); } void PropertySet::setProperties( const Sequence< OUString >& rPropNames, const Sequence< Any >& rValues ) @@ -122,7 +130,7 @@ void PropertySet::setProperties( const Sequence< OUString >& rPropNames, const S const OUString* pPropNameEnd = pPropName + rPropNames.getLength(); const Any* pValue = rValues.getConstArray(); for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue ) - setAnyProperty( *pPropName, *pValue ); + implSetPropertyValue( *pPropName, *pValue ); } } @@ -139,37 +147,34 @@ void PropertySet::setProperties( const PropertyMap& rPropertyMap ) // private -------------------------------------------------------------------- -bool PropertySet::getAnyProperty( Any& orValue, const OUString& rPropName ) const +bool PropertySet::implGetPropertyValue( Any& orValue, const OUString& rPropName ) const { - bool bHasValue = false; - try + if( mxPropSet.is() ) try { - if( mxPropSet.is() ) - { - orValue = mxPropSet->getPropertyValue( rPropName ); - bHasValue = true; - } + orValue = mxPropSet->getPropertyValue( rPropName ); + return true; } catch( Exception& ) { - OSL_ENSURE( false, OStringBuffer( "PropertySet::getAnyProperty - cannot get property \"" ). + OSL_ENSURE( false, OStringBuffer( "PropertySet::implGetPropertyValue - cannot get property \"" ). append( OUStringToOString( rPropName, RTL_TEXTENCODING_ASCII_US ) ).append( '"' ).getStr() ); } - return bHasValue; + return false; } -void PropertySet::setAnyProperty( const OUString& rPropName, const Any& rValue ) +bool PropertySet::implSetPropertyValue( const OUString& rPropName, const Any& rValue ) { - try + if( mxPropSet.is() ) try { - if( mxPropSet.is() ) - mxPropSet->setPropertyValue( rPropName, rValue ); + mxPropSet->setPropertyValue( rPropName, rValue ); + return true; } catch( Exception& ) { - OSL_ENSURE( false, OStringBuffer( "PropertySet::setAnyProperty - cannot set property \"" ). + OSL_ENSURE( false, OStringBuffer( "PropertySet::implSetPropertyValue - cannot set property \"" ). append( OUStringToOString( rPropName, RTL_TEXTENCODING_ASCII_US ) ).append( '"' ).getStr() ); } + return false; } // ============================================================================ diff --git a/oox/source/helper/textinputstream.cxx b/oox/source/helper/textinputstream.cxx index d590781c6fd3..9087dea7b26f 100644..100755 --- a/oox/source/helper/textinputstream.cxx +++ b/oox/source/helper/textinputstream.cxx @@ -27,102 +27,209 @@ #include "oox/helper/textinputstream.hxx" -#include <rtl/strbuf.hxx> -#include <rtl/ustrbuf.hxx> +#include <com/sun/star/io/XActiveDataSink.hpp> +#include <com/sun/star/io/XTextInputStream.hpp> +#include <cppuhelper/implbase1.hxx> +#include <rtl/tencinfo.h> #include "oox/helper/binaryinputstream.hxx" namespace oox { // ============================================================================ -using ::rtl::OStringBuffer; -using ::rtl::OStringToOUString; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; + using ::rtl::OUString; -using ::rtl::OUStringBuffer; // ============================================================================ namespace { -/** Reads a text line from stream. First, tries to skip the second character of - a two-character line end sequence. Returns the new line-end character. */ -template< typename BufferType, typename CharType, typename StreamDataType > -sal_Unicode lclReadLine( BufferType& orBuffer, BinaryInputStream& rInStrm, sal_Unicode cLastEolChar ) +typedef ::cppu::WeakImplHelper1< XInputStream > UnoBinaryInputStream_BASE; + +/** Implementation of a UNO input stream wrapping a binary input stream. + */ +class UnoBinaryInputStream : public UnoBinaryInputStream_BASE { - // try to skip LF following CR, or CR following LF - if( !rInStrm.isEof() && (cLastEolChar != 0) ) - { - CharType cChar = static_cast< CharType >( rInStrm.readValue< StreamDataType >() ); - // return on EOF after line-end - if( rInStrm.isEof() ) - return 0; - // return on sequence of equal line-end characters - bool bIsEolChar = (cChar == 10) || (cChar == 13); - if( bIsEolChar && (cChar == cLastEolChar) ) - return cChar; - // append the character, if it is not the other line-end charcter - if( !bIsEolChar ) - orBuffer.append( cChar ); - } +public: + explicit UnoBinaryInputStream( BinaryInputStream& rInStrm ); + + virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); + virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); + virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); + virtual sal_Int32 SAL_CALL available() + throw (NotConnectedException, IOException, RuntimeException); + virtual void SAL_CALL closeInput() + throw (NotConnectedException, IOException, RuntimeException); + +private: + void ensureConnected() const throw (NotConnectedException); + +private: + BinaryInputStream* mpInStrm; +}; + +// ---------------------------------------------------------------------------- + +UnoBinaryInputStream::UnoBinaryInputStream( BinaryInputStream& rInStrm ) : + mpInStrm( &rInStrm ) +{ +} - // read chars until EOF or line end character (LF or CR) - while( true ) - { - CharType cChar = static_cast< CharType >( rInStrm.readValue< StreamDataType >() ); - if( rInStrm.isEof() ) - return 0; - if( (cChar == 10) || (cChar == 13) ) - return cChar; - orBuffer.append( cChar ); - } +sal_Int32 SAL_CALL UnoBinaryInputStream::readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + ensureConnected(); + return mpInStrm->readData( rData, nBytesToRead, 1 ); +} + +sal_Int32 SAL_CALL UnoBinaryInputStream::readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + ensureConnected(); + return mpInStrm->readData( rData, nMaxBytesToRead, 1 ); +} + +void SAL_CALL UnoBinaryInputStream::skipBytes( sal_Int32 nBytesToSkip ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + ensureConnected(); + mpInStrm->skip( nBytesToSkip, 1 ); +} + +sal_Int32 SAL_CALL UnoBinaryInputStream::available() throw (NotConnectedException, IOException, RuntimeException) +{ + ensureConnected(); + throw RuntimeException( CREATE_OUSTRING( "Functionality not supported" ), Reference< XInputStream >() ); +} + +void SAL_CALL UnoBinaryInputStream::closeInput() throw (NotConnectedException, IOException, RuntimeException) +{ + ensureConnected(); + mpInStrm->close(); + mpInStrm = 0; +} + +void UnoBinaryInputStream::ensureConnected() const throw (NotConnectedException) +{ + if( !mpInStrm ) + throw NotConnectedException( CREATE_OUSTRING( "Stream closed" ), Reference< XInterface >() ); } } // namespace // ============================================================================ -TextInputStream::TextInputStream( BinaryInputStream& rInStrm, rtl_TextEncoding eTextEnc ) : - mrInStrm( rInStrm ), - meTextEnc( eTextEnc ), - mcLastEolChar( 0 ) +TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc ) +{ + init( rxContext, rxInStrm, eTextEnc ); +} + +TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, BinaryInputStream& rInStrm, rtl_TextEncoding eTextEnc ) +{ + init( rxContext, new UnoBinaryInputStream( rInStrm ), eTextEnc ); +} + +TextInputStream::~TextInputStream() { } bool TextInputStream::isEof() const { - // do not return EOF, if last text line missed line-end character (see below) - return mrInStrm.isEof() && (mcLastEolChar == 0); + if( mxTextStrm.is() ) try + { + return mxTextStrm->isEOF(); + } + catch( Exception& ) + { + } + return true; } OUString TextInputStream::readLine() { - if( mrInStrm.isEof() ) + if( mxTextStrm.is() ) try + { + /* The function createFinalString() adds a character that may have + been buffered in the previous call of readToChar() (see below). */ + return createFinalString( mxTextStrm->readLine() ); + } + catch( Exception& ) { - mcLastEolChar = 0; - return OUString(); + mxTextStrm.clear(); } + return OUString(); +} - OUString aLine; - if( meTextEnc == RTL_TEXTENCODING_UCS2 ) +OUString TextInputStream::readToChar( sal_Unicode cChar, bool bIncludeChar ) +{ + if( mxTextStrm.is() ) try { - // read 16-bit characters for UCS2 encoding - OUStringBuffer aBuffer; - mcLastEolChar = lclReadLine< OUStringBuffer, sal_Unicode, sal_uInt16 >( aBuffer, mrInStrm, mcLastEolChar ); - aLine = aBuffer.makeStringAndClear(); + Sequence< sal_Unicode > aDelimiters( 1 ); + aDelimiters[ 0 ] = cChar; + /* Always get the delimiter character from the UNO text input stream. + In difference to this implementation, it will not return it in the + next call but silently skip it. If caller specifies to exclude the + character in this call, it will be returned in the next call of one + of the own member functions. The function createFinalString() adds + a character that has been buffered in the previous call. */ + OUString aString = createFinalString( mxTextStrm->readString( aDelimiters, sal_False ) ); + // remove last character from string and remember it for next call + if( !bIncludeChar && (aString.getLength() > 0) && (aString[ aString.getLength() - 1 ] == cChar) ) + { + mcPendingChar = cChar; + aString = aString.copy( 0, aString.getLength() - 1 ); + } + return aString; } - else + catch( Exception& ) { - // otherwise, read 8-bit characters and convert according to text encoding - OStringBuffer aBuffer; - mcLastEolChar = lclReadLine< OStringBuffer, sal_Char, sal_uInt8 >( aBuffer, mrInStrm, mcLastEolChar ); - aLine = OStringToOUString( aBuffer.makeStringAndClear(), meTextEnc ); + mxTextStrm.clear(); } + return OUString(); +} - // if last line is not empty but line-end character is missing, do not return EOF - if( mrInStrm.isEof() && (aLine.getLength() > 0) ) - mcLastEolChar = 10; +/*static*/ Reference< XTextInputStream > TextInputStream::createXTextInputStream( + const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc ) +{ + Reference< XTextInputStream > xTextStrm; + const char* pcCharset = rtl_getMimeCharsetFromTextEncoding( eTextEnc ); + OSL_ENSURE( pcCharset, "TextInputStream::createXTextInputStream - unsupported text encoding" ); + if( rxContext.is() && rxInStrm.is() && pcCharset ) try + { + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XActiveDataSink > xDataSink( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextInputStream" ) ), UNO_QUERY_THROW ); + xDataSink->setInputStream( rxInStrm ); + xTextStrm.set( xDataSink, UNO_QUERY_THROW ); + xTextStrm->setEncoding( OUString::createFromAscii( pcCharset ) ); + } + catch( Exception& ) + { + } + return xTextStrm; +} - return aLine; +// private -------------------------------------------------------------------- + +OUString TextInputStream::createFinalString( const OUString& rString ) +{ + if( mcPendingChar == 0 ) + return rString; + + OUString aString = OUString( mcPendingChar ) + rString; + mcPendingChar = 0; + return aString; +} + +void TextInputStream::init( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc ) +{ + mcPendingChar = 0; + mxTextStrm = createXTextInputStream( rxContext, rxInStrm, eTextEnc ); } // ============================================================================ diff --git a/oox/source/helper/zipstorage.cxx b/oox/source/helper/zipstorage.cxx index fecad5ab40e7..c190f39d1e43 100644 --- a/oox/source/helper/zipstorage.cxx +++ b/oox/source/helper/zipstorage.cxx @@ -33,6 +33,7 @@ #include <com/sun/star/io/XInputStream.hpp> #include <com/sun/star/io/XOutputStream.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> #include <comphelper/storagehelper.hxx> #include "oox/helper/helper.hxx" @@ -50,47 +51,46 @@ using ::rtl::OUString; // ============================================================================ -ZipStorage::ZipStorage( - const Reference< XMultiServiceFactory >& rxFactory, - const Reference< XInputStream >& rxInStream ) : +ZipStorage::ZipStorage( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStream ) : StorageBase( rxInStream, false ) { - OSL_ENSURE( rxFactory.is(), "ZipStorage::ZipStorage - missing service factory" ); + OSL_ENSURE( rxContext.is(), "ZipStorage::ZipStorage - missing component context" ); // create base storage object - try + if( rxContext.is() ) try { /* #i105325# ::comphelper::OStorageHelper::GetStorageFromInputStream() cannot be used here as it will open a storage with format type 'PackageFormat' that will not work with OOXML packages. - #161971# The MS-document storages should always be opened in Repair-Mode to - ignore the format errors and get so much info as possible. I hate this - solution, but it seems to be the only consistent way to handle the MS-documents. + #161971# The MS-document storages should always be opened in repair + mode to ignore the format errors and get so much info as possible. + I hate this solution, but it seems to be the only consistent way to + handle the MS documents. TODO: #i105410# switch to 'OFOPXMLFormat' and use its - implementation of relations handling. */ - + implementation of relations handling. + */ + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( - ZIP_STORAGE_FORMAT_STRING, rxInStream, rxFactory, - sal_False /* DEV300_m80: Was sal_True, but DOCX and others did not load */ ); + ZIP_STORAGE_FORMAT_STRING, rxInStream, xFactory, + sal_False ); // DEV300_m80: Was sal_True, but DOCX and others did not load } catch( Exception& ) { } } -ZipStorage::ZipStorage( - const Reference< XMultiServiceFactory >& rxFactory, - const Reference< XStream >& rxStream ) : +ZipStorage::ZipStorage( const Reference< XComponentContext >& rxContext, const Reference< XStream >& rxStream ) : StorageBase( rxStream, false ) { - OSL_ENSURE( rxFactory.is(), "ZipStorage::ZipStorage - missing service factory" ); + OSL_ENSURE( rxContext.is(), "ZipStorage::ZipStorage - missing component context" ); // create base storage object - try + if( rxContext.is() ) try { - using namespace ::com::sun::star::embed::ElementModes; + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + const sal_Int32 nOpenMode = ElementModes::READWRITE | ElementModes::TRUNCATE; mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( - OFOPXML_STORAGE_FORMAT_STRING, rxStream, READWRITE | TRUNCATE, rxFactory, sal_True ); + OFOPXML_STORAGE_FORMAT_STRING, rxStream, nOpenMode, xFactory, sal_True ); } catch( Exception& ) { |