diff options
author | Daniel Rentz [dr] <daniel.rentz@oracle.com> | 2011-02-07 17:18:11 +0100 |
---|---|---|
committer | Daniel Rentz [dr] <daniel.rentz@oracle.com> | 2011-02-07 17:18:11 +0100 |
commit | 7a5084f1acacb0858588d4d0c82651e47ca9914f (patch) | |
tree | a92a5c9040270413f47cbf9eacc2605896c7ebb9 /oox/source | |
parent | 09f7fc99c442d71852396d97ee1079f0d03901a0 (diff) |
dr78: rework of stream handling, improve handling of very large streams (prevent loading entire stream into array or string, esp. dumper and VML import), full support of XComponentContext
Diffstat (limited to 'oox/source')
51 files changed, 1187 insertions, 1025 deletions
diff --git a/oox/source/core/binaryfilterbase.cxx b/oox/source/core/binaryfilterbase.cxx index 9bebedb9c96b..edff8a788808 100644 --- a/oox/source/core/binaryfilterbase.cxx +++ b/oox/source/core/binaryfilterbase.cxx @@ -55,12 +55,12 @@ BinaryFilterBase::~BinaryFilterBase() StorageRef BinaryFilterBase::implCreateStorage( const Reference< XInputStream >& rxInStream ) const { - return StorageRef( new ::oox::ole::OleStorage( getServiceFactory(), rxInStream, true ) ); + return StorageRef( new ::oox::ole::OleStorage( getComponentContext(), rxInStream, true ) ); } StorageRef BinaryFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) const { - return StorageRef( new ::oox::ole::OleStorage( getServiceFactory(), rxOutStream, true ) ); + return StorageRef( new ::oox::ole::OleStorage( getComponentContext(), rxOutStream, true ) ); } // ============================================================================ diff --git a/oox/source/core/contexthandler.cxx b/oox/source/core/contexthandler.cxx index 8bf2c4eadfeb..1ff793cd0c84 100644 --- a/oox/source/core/contexthandler.cxx +++ b/oox/source/core/contexthandler.cxx @@ -42,7 +42,7 @@ using ::rtl::OUString; // ============================================================================ ContextHandler::ContextHandler( ContextHandler& rParent ) : - ContextHandlerImplBase(), + ContextHandler_BASE(), mxBaseData( rParent.mxBaseData ) { } diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx index cdab111e9898..f836720a48a2 100644 --- a/oox/source/core/filterdetect.cxx +++ b/oox/source/core/filterdetect.cxx @@ -269,9 +269,9 @@ const sal_uInt32 ENCRYPT_HASH_SHA1 = 0x00008004; // ---------------------------------------------------------------------------- -bool lclIsZipPackage( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm ) +bool lclIsZipPackage( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm ) { - ZipStorage aZipStorage( rxFactory, rxInStrm ); + ZipStorage aZipStorage( rxContext, rxInStrm ); return aZipStorage.isStorage(); } @@ -499,109 +499,106 @@ PasswordVerifier::PasswordVerifier( const PackageEncryptionInfo& rEncryptInfo ) Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescriptor& rMediaDesc ) const { - Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY ); - if( xFactory.is() ) + // try the plain input stream + Reference< XInputStream > xInStrm( rMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY ); + if( !xInStrm.is() || lclIsZipPackage( mxContext, xInStrm ) ) + return xInStrm; + + // check if a temporary file is passed in the 'ComponentData' property + Reference< XStream > xDecrypted( rMediaDesc.getComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ) ), UNO_QUERY ); + if( xDecrypted.is() ) { - // try the plain input stream - Reference< XInputStream > xInStrm( rMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY ); - if( !xInStrm.is() || lclIsZipPackage( xFactory, xInStrm ) ) - return xInStrm; - - // check if a temporary file is passed in the 'ComponentData' property - Reference< XStream > xDecrypted( rMediaDesc.getComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ) ), UNO_QUERY ); - if( xDecrypted.is() ) - { - Reference< XInputStream > xDecrInStrm = xDecrypted->getInputStream(); - if( lclIsZipPackage( xFactory, xDecrInStrm ) ) - return xDecrInStrm; - } + Reference< XInputStream > xDecrInStrm = xDecrypted->getInputStream(); + if( lclIsZipPackage( mxContext, xDecrInStrm ) ) + return xDecrInStrm; + } - // try to decrypt an encrypted OLE package - ::oox::ole::OleStorage aOleStorage( xFactory, xInStrm, false ); - if( aOleStorage.isStorage() ) try + // try to decrypt an encrypted OLE package + ::oox::ole::OleStorage aOleStorage( mxContext, xInStrm, false ); + if( aOleStorage.isStorage() ) try + { + // open the required input streams in the encrypted package + Reference< XInputStream > xEncryptionInfo( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptionInfo" ) ), UNO_SET_THROW ); + Reference< XInputStream > xEncryptedPackage( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptedPackage" ) ), UNO_SET_THROW ); + + // read the encryption info stream + PackageEncryptionInfo aEncryptInfo; + BinaryXInputStream aInfoStrm( xEncryptionInfo, true ); + bool bValidInfo = lclReadEncryptionInfo( aEncryptInfo, aInfoStrm ); + + // check flags and agorithm IDs, requiered are AES128 and SHA-1 + bool bImplemented = bValidInfo && + getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_CRYPTOAPI ) && + getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_AES ) && + // algorithm ID 0 defaults to AES128 too, if ENCRYPTINFO_AES flag is set + ((aEncryptInfo.mnAlgorithmId == 0) || (aEncryptInfo.mnAlgorithmId == ENCRYPT_ALGO_AES128)) && + // hash algorithm ID 0 defaults to SHA-1 too + ((aEncryptInfo.mnAlgorithmIdHash == 0) || (aEncryptInfo.mnAlgorithmIdHash == ENCRYPT_HASH_SHA1)) && + (aEncryptInfo.mnVerifierHashSize == 20); + + if( bImplemented ) { - // open the required input streams in the encrypted package - Reference< XInputStream > xEncryptionInfo( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptionInfo" ) ), UNO_SET_THROW ); - Reference< XInputStream > xEncryptedPackage( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptedPackage" ) ), UNO_SET_THROW ); - - // read the encryption info stream - PackageEncryptionInfo aEncryptInfo; - BinaryXInputStream aInfoStrm( xEncryptionInfo, true ); - bool bValidInfo = lclReadEncryptionInfo( aEncryptInfo, aInfoStrm ); - - // check flags and agorithm IDs, requiered are AES128 and SHA-1 - bool bImplemented = bValidInfo && - getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_CRYPTOAPI ) && - getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_AES ) && - // algorithm ID 0 defaults to AES128 too, if ENCRYPTINFO_AES flag is set - ((aEncryptInfo.mnAlgorithmId == 0) || (aEncryptInfo.mnAlgorithmId == ENCRYPT_ALGO_AES128)) && - // hash algorithm ID 0 defaults to SHA-1 too - ((aEncryptInfo.mnAlgorithmIdHash == 0) || (aEncryptInfo.mnAlgorithmIdHash == ENCRYPT_HASH_SHA1)) && - (aEncryptInfo.mnVerifierHashSize == 20); - - if( bImplemented ) + /* "VelvetSweatshop" is the built-in default encryption + password used by MS Excel for the "workbook protection" + feature with password. Try this first before prompting the + user for a password. */ + ::std::vector< OUString > aDefaultPasswords; + aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) ); + + /* Use the comphelper password helper to request a password. + This helper returns either with the correct password + (according to the verifier), or with an empty string if + user has cancelled the password input dialog. */ + PasswordVerifier aVerifier( aEncryptInfo ); + Sequence< NamedValue > aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( + aVerifier, rMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords ); + + if( aEncryptionData.getLength() == 0 ) { - /* "VelvetSweatshop" is the built-in default encryption - password used by MS Excel for the "workbook protection" - feature with password. Try this first before prompting the - user for a password. */ - ::std::vector< OUString > aDefaultPasswords; - aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) ); - - /* Use the comphelper password helper to request a password. - This helper returns either with the correct password - (according to the verifier), or with an empty string if - user has cancelled the password input dialog. */ - PasswordVerifier aVerifier( aEncryptInfo ); - Sequence< NamedValue > aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( - aVerifier, rMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords ); - - if( aEncryptionData.getLength() == 0 ) - { - rMediaDesc[ MediaDescriptor::PROP_ABORTED() ] <<= true; - } - else + rMediaDesc[ MediaDescriptor::PROP_ABORTED() ] <<= true; + } + else + { + // create temporary file for unencrypted package + Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XStream > xTempFile( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); + Reference< XOutputStream > xDecryptedPackage( xTempFile->getOutputStream(), UNO_SET_THROW ); + BinaryXOutputStream aDecryptedPackage( xDecryptedPackage, true ); + BinaryXInputStream aEncryptedPackage( xEncryptedPackage, true ); + + EVP_CIPHER_CTX aes_ctx; + EVP_CIPHER_CTX_init( &aes_ctx ); + EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, aVerifier.getKey(), 0 ); + EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 ); + + sal_uInt8 pnInBuffer[ 1024 ]; + sal_uInt8 pnOutBuffer[ 1024 ]; + sal_Int32 nInLen; + int nOutLen; + aEncryptedPackage.skip( 8 ); // decrypted size + while( (nInLen = aEncryptedPackage.readMemory( pnInBuffer, sizeof( pnInBuffer ) )) > 0 ) { - // create temporary file for unencrypted package - Reference< XStream > xTempFile( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); - Reference< XOutputStream > xDecryptedPackage( xTempFile->getOutputStream(), UNO_SET_THROW ); - BinaryXOutputStream aDecryptedPackage( xDecryptedPackage, true ); - BinaryXInputStream aEncryptedPackage( xEncryptedPackage, true ); - - EVP_CIPHER_CTX aes_ctx; - EVP_CIPHER_CTX_init( &aes_ctx ); - EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, aVerifier.getKey(), 0 ); - EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 ); - - sal_uInt8 pnInBuffer[ 1024 ]; - sal_uInt8 pnOutBuffer[ 1024 ]; - sal_Int32 nInLen; - int nOutLen; - aEncryptedPackage.skip( 8 ); // decrypted size - while( (nInLen = aEncryptedPackage.readMemory( pnInBuffer, sizeof( pnInBuffer ) )) > 0 ) - { - EVP_DecryptUpdate( &aes_ctx, pnOutBuffer, &nOutLen, pnInBuffer, nInLen ); - aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen ); - } - EVP_DecryptFinal_ex( &aes_ctx, pnOutBuffer, &nOutLen ); + EVP_DecryptUpdate( &aes_ctx, pnOutBuffer, &nOutLen, pnInBuffer, nInLen ); aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen ); + } + EVP_DecryptFinal_ex( &aes_ctx, pnOutBuffer, &nOutLen ); + aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen ); - EVP_CIPHER_CTX_cleanup( &aes_ctx ); - xDecryptedPackage->flush(); - aDecryptedPackage.seekToStart(); + EVP_CIPHER_CTX_cleanup( &aes_ctx ); + xDecryptedPackage->flush(); + aDecryptedPackage.seekToStart(); - // store temp file in media descriptor to keep it alive - rMediaDesc.setComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ), Any( xTempFile ) ); + // store temp file in media descriptor to keep it alive + rMediaDesc.setComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ), Any( xTempFile ) ); - Reference< XInputStream > xDecrInStrm = xTempFile->getInputStream(); - if( lclIsZipPackage( xFactory, xDecrInStrm ) ) - return xDecrInStrm; - } + Reference< XInputStream > xDecrInStrm = xTempFile->getInputStream(); + if( lclIsZipPackage( mxContext, xDecrInStrm ) ) + return xDecrInStrm; } } - catch( Exception& ) - { - } + } + catch( Exception& ) + { } return Reference< XInputStream >(); @@ -633,7 +630,6 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq { OUString aFilterName; MediaDescriptor aMediaDesc( rMediaDescSeq ); - Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); /* Check that the user has not choosen to abort detection, e.g. by hitting 'Cancel' in the password input dialog. This may happen because this @@ -650,7 +646,7 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq Reference< XInputStream > xInStrm( extractUnencryptedPackage( aMediaDesc ), UNO_SET_THROW ); // stream must be a ZIP package - ZipStorage aZipStorage( xFactory, xInStrm ); + ZipStorage aZipStorage( mxContext, xInStrm ); if( aZipStorage.isStorage() ) { // create the fast parser, register the XML namespaces, set document handler diff --git a/oox/source/core/fragmenthandler.cxx b/oox/source/core/fragmenthandler.cxx index a1c42e56c155..14abe0d537fc 100644 --- a/oox/source/core/fragmenthandler.cxx +++ b/oox/source/core/fragmenthandler.cxx @@ -52,12 +52,12 @@ FragmentBaseData::FragmentBaseData( XmlFilterBase& rFilter, const OUString& rFra // ============================================================================ FragmentHandler::FragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath ) : - FragmentHandlerImplBase( FragmentBaseDataRef( new FragmentBaseData( rFilter, rFragmentPath, rFilter.importRelations( rFragmentPath ) ) ) ) + FragmentHandler_BASE( FragmentBaseDataRef( new FragmentBaseData( rFilter, rFragmentPath, rFilter.importRelations( rFragmentPath ) ) ) ) { } FragmentHandler::FragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath, RelationsRef xRelations ) : - FragmentHandlerImplBase( FragmentBaseDataRef( new FragmentBaseData( rFilter, rFragmentPath, xRelations ) ) ) + FragmentHandler_BASE( FragmentBaseDataRef( new FragmentBaseData( rFilter, rFragmentPath, xRelations ) ) ) { } diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx index fe13d9322346..a77789edbeb8 100644 --- a/oox/source/core/xmlfilterbase.cxx +++ b/oox/source/core/xmlfilterbase.cxx @@ -496,12 +496,12 @@ Reference< XInputStream > XmlFilterBase::implGetInputStream( MediaDescriptor& rM StorageRef XmlFilterBase::implCreateStorage( const Reference< XInputStream >& rxInStream ) const { - return StorageRef( new ZipStorage( getServiceFactory(), rxInStream ) ); + return StorageRef( new ZipStorage( getComponentContext(), rxInStream ) ); } StorageRef XmlFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) const { - return StorageRef( new ZipStorage( getServiceFactory(), rxOutStream ) ); + return StorageRef( new ZipStorage( getComponentContext(), rxOutStream ) ); } // ============================================================================ diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx index 279c9d3c0487..54e1fad7febc 100644 --- a/oox/source/dump/biffdumper.cxx +++ b/oox/source/dump/biffdumper.cxx @@ -166,7 +166,7 @@ void BiffCtlsStreamObject::implDump() { IndentGuard aIndGuard( mxOut ); mxStrm->seek( mnStartPos ); - RelativeInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, mnLength ) ); + BinaryInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, mnLength ) ); FormControlStreamObject( *this, xRelStrm ).dump(); } writeEmptyItem( "CTLS-END" ); @@ -356,7 +356,7 @@ bool BiffObjectBase::implStartRecord( BinaryInputStream&, sal_Int64& ornRecPos, break; } - ornRecSize = mxBiffStrm->getLength(); + ornRecSize = mxBiffStrm->size(); return bValid; } @@ -810,7 +810,7 @@ void FormulaObject::implDump() if( mnSize == 0 ) return; sal_Int64 nStartPos = mxStrm->tell(); - sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->getLength() ); + sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->size() ); bool bValid = mxTokens.get(); mxStack.reset( new FormulaStack ); @@ -1603,7 +1603,7 @@ void WorkbookStreamObject::implDumpRecordBody() { BiffInputStream& rStrm = getBiffStream(); sal_uInt16 nRecId = rStrm.getRecId(); - sal_Int64 nRecSize = rStrm.getLength(); + sal_Int64 nRecSize = rStrm.size(); BiffType eBiff = getBiff(); switch( nRecId ) @@ -4524,7 +4524,7 @@ RootStorageObject::RootStorageObject( const DumperBase& rParent ) addPreferredStream( "Workbook" ); } -void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) +void RootStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) { if( (rStrgPath.getLength() == 0) && (rStrmName.equalsAscii( "Book" ) || rStrmName.equalsAscii( "Workbook" )) ) WorkbookStreamObject( *this, rxStrm, rSysFileName ).dump(); @@ -4562,13 +4562,13 @@ Dumper::Dumper( const FilterBase& rFilter ) DumperBase::construct( xCfg ); } -Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName ) +Dumper::Dumper( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName ) { - if( rxFactory.is() && rxInStrm.is() ) + if( rxContext.is() && rxInStrm.is() ) { - StorageRef xStrg( new ::oox::ole::OleStorage( rxFactory, rxInStrm, true ) ); + StorageRef xStrg( new ::oox::ole::OleStorage( rxContext, rxInStrm, true ) ); MediaDescriptor aMediaDesc; - ConfigRef xCfg( new Config( DUMP_BIFF_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) ); + ConfigRef xCfg( new Config( DUMP_BIFF_CONFIG_ENVVAR, rxContext, xStrg, rSysFileName, aMediaDesc ) ); DumperBase::construct( xCfg ); } } diff --git a/oox/source/dump/dumperbase.cxx b/oox/source/dump/dumperbase.cxx index f7c6c6102b1d..eeca65e88cc5 100644 --- a/oox/source/dump/dumperbase.cxx +++ b/oox/source/dump/dumperbase.cxx @@ -29,14 +29,13 @@ #include <algorithm> #include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/io/XActiveDataSink.hpp> #include <com/sun/star/io/XActiveDataSource.hpp> -#include <com/sun/star/io/XTextInputStream.hpp> #include <com/sun/star/io/XTextOutputStream.hpp> #include <com/sun/star/ucb/XSimpleFileAccess.hpp> #include <comphelper/docpasswordhelper.hxx> #include <osl/file.hxx> #include <rtl/math.hxx> +#include <rtl/tencinfo.h> #include "oox/core/filterbase.hxx" #include "oox/helper/binaryoutputstream.hxx" #include "oox/helper/textinputstream.hxx" @@ -112,20 +111,14 @@ OUString InputOutputHelper::getFileNameExtension( const OUString& rFileUrl ) // input streams -------------------------------------------------------------- -Reference< XInputStream > InputOutputHelper::getXInputStream( BinaryInputStream& rStrm ) -{ - if( BinaryXInputStream* pXStrm = dynamic_cast< BinaryXInputStream* >( &rStrm ) ) - return pXStrm->getXInputStream(); - return 0; -} - Reference< XInputStream > InputOutputHelper::openInputStream( - const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName ) + const Reference< XComponentContext >& rxContext, const OUString& rFileName ) { Reference< XInputStream > xInStrm; - if( rxFactory.is() ) try + if( rxContext.is() ) try { - Reference< XSimpleFileAccess > xFileAccess( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XSimpleFileAccess > xFileAccess( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW ); xInStrm = xFileAccess->openFileRead( rFileName ); } catch( Exception& ) @@ -134,38 +127,16 @@ Reference< XInputStream > InputOutputHelper::openInputStream( return xInStrm; } -Reference< XTextInputStream > InputOutputHelper::openTextInputStream( - const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rEncoding ) -{ - Reference< XTextInputStream > xTextInStrm; - if( rxFactory.is() && rxInStrm.is() ) try - { - Reference< XActiveDataSink > xDataSink( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextInputStream" ) ), UNO_QUERY_THROW ); - xDataSink->setInputStream( rxInStrm ); - xTextInStrm.set( xDataSink, UNO_QUERY_THROW ); - xTextInStrm->setEncoding( rEncoding ); - } - catch( Exception& ) - { - } - return xTextInStrm; -} - -Reference< XTextInputStream > InputOutputHelper::openTextInputStream( - const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName, const OUString& rEncoding ) -{ - return openTextInputStream( rxFactory, openInputStream( rxFactory, rFileName ), rEncoding ); -} - // output streams ------------------------------------------------------------- Reference< XOutputStream > InputOutputHelper::openOutputStream( - const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName ) + const Reference< XComponentContext >& rxContext, const OUString& rFileName ) { Reference< XOutputStream > xOutStrm; - if( rxFactory.is() ) try + if( rxContext.is() ) try { - Reference< XSimpleFileAccess > xFileAccess( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XSimpleFileAccess > xFileAccess( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW ); xOutStrm = xFileAccess->openFileWrite( rFileName ); } catch( Exception& ) @@ -175,15 +146,17 @@ Reference< XOutputStream > InputOutputHelper::openOutputStream( } Reference< XTextOutputStream > InputOutputHelper::openTextOutputStream( - const Reference< XMultiServiceFactory >& rxFactory, const Reference< XOutputStream >& rxOutStrm, const OUString& rEncoding ) + const Reference< XComponentContext >& rxContext, const Reference< XOutputStream >& rxOutStrm, rtl_TextEncoding eTextEnc ) { Reference< XTextOutputStream > xTextOutStrm; - if( rxFactory.is() && rxOutStrm.is() ) try + const char* pcCharset = rtl_getMimeCharsetFromTextEncoding( eTextEnc ); + if( rxContext.is() && rxOutStrm.is() && pcCharset ) try { - Reference< XActiveDataSource > xDataSource( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextOutputStream" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XActiveDataSource > xDataSource( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextOutputStream" ) ), UNO_QUERY_THROW ); xDataSource->setOutputStream( rxOutStrm ); xTextOutStrm.set( xDataSource, UNO_QUERY_THROW ); - xTextOutStrm->setEncoding( rEncoding ); + xTextOutStrm->setEncoding( OUString::createFromAscii( pcCharset ) ); } catch( Exception& ) { @@ -192,9 +165,9 @@ Reference< XTextOutputStream > InputOutputHelper::openTextOutputStream( } Reference< XTextOutputStream > InputOutputHelper::openTextOutputStream( - const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName, const OUString& rEncoding ) + const Reference< XComponentContext >& rxContext, const OUString& rFileName, rtl_TextEncoding eTextEnc ) { - return openTextOutputStream( rxFactory, openOutputStream( rxFactory, rFileName ), rEncoding ); + return openTextOutputStream( rxContext, openOutputStream( rxContext, rFileName ), eTextEnc ); } // ============================================================================ @@ -1531,9 +1504,9 @@ NameListRef NameListWrapper::getNameList( const Config& rCfg ) const // ============================================================================ SharedConfigData::SharedConfigData( const OUString& rFileName, - const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, + const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) : - mxFactory( rxFactory ), + mxContext( rxContext ), mxRootStrg( rxRootStrg ), maSysFileName( rSysFileName ), mrMediaDesc( rMediaDesc ), @@ -1600,7 +1573,7 @@ Sequence< NamedValue > SharedConfigData::requestEncryptionData( ::comphelper::ID bool SharedConfigData::implIsValid() const { - return mbLoaded && mxFactory.is() && mxRootStrg.get() && (maSysFileName.getLength() > 0); + return mbLoaded && mxContext.is() && mxRootStrg.get() && (maSysFileName.getLength() > 0); } void SharedConfigData::implProcessConfigItemStr( @@ -1629,9 +1602,8 @@ bool SharedConfigData::readConfigFile( const OUString& rFileUrl ) bool bLoaded = maConfigFiles.count( rFileUrl ) > 0; if( !bLoaded ) { - Reference< XInputStream > xInStrm = InputOutputHelper::openInputStream( mxFactory, rFileUrl ); - BinaryXInputStream aInStrm( xInStrm, true ); - TextInputStream aTxtStrm( aInStrm, RTL_TEXTENCODING_UTF8 ); + Reference< XInputStream > xInStrm = InputOutputHelper::openInputStream( mxContext, rFileUrl ); + TextInputStream aTxtStrm( mxContext, xInStrm, RTL_TEXTENCODING_UTF8 ); if( !aTxtStrm.isEof() ) { maConfigFiles.insert( rFileUrl ); @@ -1698,9 +1670,9 @@ Config::Config( const sal_Char* pcEnvVar, const FilterBase& rFilter ) construct( pcEnvVar, rFilter ); } -Config::Config( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) +Config::Config( const sal_Char* pcEnvVar, const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) { - construct( pcEnvVar, rxFactory, rxRootStrg, rSysFileName, rMediaDesc ); + construct( pcEnvVar, rxContext, rxRootStrg, rSysFileName, rMediaDesc ); } Config::~Config() @@ -1715,14 +1687,14 @@ void Config::construct( const Config& rParent ) void Config::construct( const sal_Char* pcEnvVar, const FilterBase& rFilter ) { if( rFilter.getFileUrl().getLength() > 0 ) - construct( pcEnvVar, rFilter.getServiceFactory(), rFilter.getStorage(), rFilter.getFileUrl(), rFilter.getMediaDescriptor() ); + construct( pcEnvVar, rFilter.getComponentContext(), rFilter.getStorage(), rFilter.getFileUrl(), rFilter.getMediaDescriptor() ); } -void Config::construct( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) +void Config::construct( const sal_Char* pcEnvVar, const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) { if( pcEnvVar && rxRootStrg.get() && (rSysFileName.getLength() > 0) ) if( const sal_Char* pcFileName = ::getenv( pcEnvVar ) ) - mxCfgData.reset( new SharedConfigData( OUString::createFromAscii( pcFileName ), rxFactory, rxRootStrg, rSysFileName, rMediaDesc ) ); + mxCfgData.reset( new SharedConfigData( OUString::createFromAscii( pcFileName ), rxContext, rxRootStrg, rSysFileName, rMediaDesc ) ); } void Config::setStringOption( const String& rKey, const String& rData ) @@ -1795,14 +1767,16 @@ NameListRef Config::implGetNameList( const OUString& rListName ) const // ============================================================================ // ============================================================================ -Output::Output( const Reference< XTextOutputStream >& rxStrm ) -{ - construct( rxStrm ); -} - -Output::Output( const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName ) +Output::Output( const Reference< XComponentContext >& rxContext, const OUString& rFileName ) : + mxStrm( InputOutputHelper::openTextOutputStream( rxContext, rFileName, RTL_TEXTENCODING_UTF8 ) ), + mnCol( 0 ), + mnItemLevel( 0 ), + mnMultiLevel( 0 ), + mnItemIdx( 0 ), + mnLastItem( 0 ) { - construct( InputOutputHelper::openTextOutputStream( rxFactory, rFileName, CREATE_OUSTRING( "UTF-8" ) ) ); + if( mxStrm.is() ) + mxStrm->writeString( OUString( OOX_DUMP_BOM ) ); } // ---------------------------------------------------------------------------- @@ -2084,19 +2058,6 @@ void Output::writeRangeList( const RangeList& rRanges ) // ---------------------------------------------------------------------------- -void Output::construct( const Reference< XTextOutputStream >& rxStrm ) -{ - mxStrm = rxStrm; - mnCol = mnItemLevel = mnMultiLevel = 0; - mnItemIdx = 0; - mnLastItem = 0; - if( mxStrm.is() ) - { - writeChar( OOX_DUMP_BOM ); - newLine(); - } -} - bool Output::implIsValid() const { return mxStrm.is(); @@ -2240,7 +2201,8 @@ void StorageObjectBase::implDump() if( bIsRoot ) try { aSysOutPath += OOX_DUMP_DUMPEXT; - Reference< XSimpleFileAccess > xFileAccess( getFactory()->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( getContext()->getServiceManager(), UNO_QUERY_THROW ); + Reference< XSimpleFileAccess > xFileAccess( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW ); xFileAccess->kill( aSysOutPath ); } catch( Exception& ) @@ -2259,7 +2221,7 @@ void StorageObjectBase::implDump() } } -void StorageObjectBase::implDumpStream( const BinaryInputStreamRef&, const OUString&, const OUString&, const OUString& ) +void StorageObjectBase::implDumpStream( const Reference< XInputStream >&, const OUString&, const OUString&, const OUString& ) { } @@ -2305,12 +2267,12 @@ void StorageObjectBase::extractStream( StorageBase& rStrg, const OUString& rStrg BinaryXInputStream aInStrm( rStrg.openInputStream( rStrmName ), true ); if( !aInStrm.isEof() ) { - BinaryXOutputStream aOutStrm( InputOutputHelper::openOutputStream( getFactory(), rSysFileName ), true ); + BinaryXOutputStream aOutStrm( InputOutputHelper::openOutputStream( getContext(), rSysFileName ), true ); if( !aOutStrm.isEof() ) aInStrm.copyToStream( aOutStrm ); } - BinaryXInputStreamRef xDumpStrm( new BinaryXInputStream( InputOutputHelper::openInputStream( getFactory(), rSysFileName ), true ) ); - if( !xDumpStrm->isEof() ) + Reference< XInputStream > xDumpStrm = InputOutputHelper::openInputStream( getContext(), rSysFileName ); + if( xDumpStrm.is() ) implDumpStream( xDumpStrm, rStrgPath, rStrmName, rSysFileName ); } @@ -2366,13 +2328,10 @@ void OutputObjectBase::construct( const ObjectBase& rParent, const OUString& rSy { ObjectBase::construct( rParent ); if( ObjectBase::implIsValid() ) - mxOut.reset( new Output( getFactory(), rSysFileName + OOX_DUMP_DUMPEXT ) ); -} - -void OutputObjectBase::construct( const ObjectBase& rParent, const OutputRef& rxOut ) -{ - ObjectBase::construct( rParent ); - mxOut = rxOut; + { + maSysFileName = rSysFileName; + mxOut.reset( new Output( getContext(), rSysFileName + OOX_DUMP_DUMPEXT ) ); + } } void OutputObjectBase::construct( const OutputObjectBase& rParent ) @@ -2551,12 +2510,6 @@ void InputObjectBase::construct( const ObjectBase& rParent, const BinaryInputStr mxStrm = rxStrm; } -void InputObjectBase::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OutputRef& rxOut ) -{ - OutputObjectBase::construct( rParent, rxOut ); - mxStrm = rxStrm; -} - void InputObjectBase::construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm ) { OutputObjectBase::construct( rParent ); @@ -2575,7 +2528,7 @@ bool InputObjectBase::implIsValid() const void InputObjectBase::skipBlock( sal_Int64 nBytes, bool bShowSize ) { - sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->getLength() ); + sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->size() ); if( mxStrm->tell() < nEndPos ) { if( bShowSize ) @@ -2595,8 +2548,8 @@ void InputObjectBase::dumpRawBinary( sal_Int64 nBytes, bool bShowOffset, bool bS sal_Int64 nMaxShowSize = cfg().getIntOption< sal_Int64 >( bStream ? "max-binary-stream-size" : "max-binary-data-size", SAL_MAX_INT64 ); - bool bSeekable = mxStrm->getLength() >= 0; - sal_Int64 nEndPos = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->getLength() ) : 0; + bool bSeekable = mxStrm->size() >= 0; + sal_Int64 nEndPos = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->size() ) : 0; sal_Int64 nDumpEnd = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nMaxShowSize, nEndPos ) : nMaxShowSize; sal_Int64 nPos = bSeekable ? mxStrm->tell() : 0; bool bLoop = true; @@ -2671,12 +2624,12 @@ void InputObjectBase::dumpRemainingTo( sal_Int64 nPos ) void InputObjectBase::dumpRemainingStream() { - dumpRemainingTo( mxStrm->getLength() ); + dumpRemainingTo( mxStrm->size() ); } void InputObjectBase::dumpArray( const String& rName, sal_Int32 nBytes, sal_Unicode cSep ) { - sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->getLength() - mxStrm->tell(), 0, nBytes ); + sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->size() - mxStrm->tell(), 0, nBytes ); if( nDumpSize > OOX_DUMP_MAXARRAY ) { dumpBinary( rName, nBytes, false ); @@ -2712,7 +2665,7 @@ sal_Unicode InputObjectBase::dumpUnicode( const String& rName ) OUString InputObjectBase::dumpCharArray( const String& rName, sal_Int32 nLen, rtl_TextEncoding eTextEnc, bool bHideTrailingNul ) { - sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->getLength() - mxStrm->tell(), 0, nLen ); + sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->size() - mxStrm->tell(), 0, nLen ); OUString aString; if( nDumpSize > 0 ) { @@ -2892,7 +2845,7 @@ BinaryStreamObject::BinaryStreamObject( const OutputObjectBase& rParent, const B void BinaryStreamObject::dumpBinaryStream( bool bShowOffset ) { mxStrm->seekToStart(); - dumpRawBinary( mxStrm->getLength(), bShowOffset, true ); + dumpRawBinary( mxStrm->size(), bShowOffset, true ); mxOut->emptyLine(); } @@ -2902,42 +2855,70 @@ void BinaryStreamObject::implDump() } // ============================================================================ +// ============================================================================ -TextStreamObject::TextStreamObject( const ObjectBase& rParent, +void TextStreamObjectBase::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc, const OUString& rSysFileName ) { InputObjectBase::construct( rParent, rxStrm, rSysFileName ); - if( rxStrm.get() ) - mxTextStrm.reset( new TextInputStream( *rxStrm, eTextEnc ) ); + constructTextStrmObj( eTextEnc ); } -TextStreamObject::TextStreamObject( const OutputObjectBase& rParent, +void TextStreamObjectBase::construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc ) { InputObjectBase::construct( rParent, rxStrm ); - if( rxStrm.get() ) - mxTextStrm.reset( new TextInputStream( *rxStrm, eTextEnc ) ); + constructTextStrmObj( eTextEnc ); +} + +void TextStreamObjectBase::construct( const InputObjectBase& rParent, rtl_TextEncoding eTextEnc ) +{ + InputObjectBase::construct( rParent ); + constructTextStrmObj( eTextEnc ); } -bool TextStreamObject::implIsValid() const +bool TextStreamObjectBase::implIsValid() const { return InputObjectBase::implIsValid() && mxTextStrm.get(); } -void TextStreamObject::implDump() +void TextStreamObjectBase::implDump() +{ + implDumpText( *mxTextStrm ); +} + +void TextStreamObjectBase::constructTextStrmObj( rtl_TextEncoding eTextEnc ) +{ + if( mxStrm.get() ) + mxTextStrm.reset( new TextInputStream( getContext(), *mxStrm, eTextEnc ) ); +} + +// ============================================================================ + +TextLineStreamObject::TextLineStreamObject( const ObjectBase& rParent, + const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc, const OUString& rSysFileName ) +{ + TextStreamObjectBase::construct( rParent, rxStrm, eTextEnc, rSysFileName ); +} + +TextLineStreamObject::TextLineStreamObject( const OutputObjectBase& rParent, + const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc ) +{ + TextStreamObjectBase::construct( rParent, rxStrm, eTextEnc ); +} + +void TextLineStreamObject::implDumpText( TextInputStream& rTextStrm ) { - OUString aLine; sal_uInt32 nLine = 0; - while( !mxTextStrm->isEof() ) + while( !rTextStrm.isEof() ) { - aLine = mxTextStrm->readLine(); - if( !mxTextStrm->isEof() ) + OUString aLine = rTextStrm.readLine(); + if( !rTextStrm.isEof() || (aLine.getLength() > 0) ) implDumpLine( aLine, ++nLine ); } - mxOut->emptyLine(); } -void TextStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 nLine ) +void TextLineStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 nLine ) { TableGuard aTabGuard( mxOut, 8 ); mxOut->writeDec( nLine, 6 ); @@ -2948,110 +2929,93 @@ void TextStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 nLine ) // ============================================================================ -XmlStreamObject::XmlStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName ) : - TextStreamObject( rParent, rxStrm, RTL_TEXTENCODING_UTF8, rSysFileName ) +XmlStreamObject::XmlStreamObject( const ObjectBase& rParent, + const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName ) { + TextStreamObjectBase::construct( rParent, rxStrm, RTL_TEXTENCODING_UTF8, rSysFileName ); } -void XmlStreamObject::implDump() +XmlStreamObject::XmlStreamObject( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm ) { - maIncompleteLine = OUString(); - TextStreamObject::implDump(); - if( maIncompleteLine.getLength() > 0 ) - { - mxOut->resetIndent(); - mxOut->writeString( maIncompleteLine ); - mxOut->emptyLine(); - writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM ); - } + TextStreamObjectBase::construct( rParent, rxStrm, RTL_TEXTENCODING_UTF8 ); } -void XmlStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 ) +void XmlStreamObject::implDumpText( TextInputStream& rTextStrm ) { - // build input line from cached incomplete element and new text data - OUStringBuffer aLine; - if( maIncompleteLine.getLength() > 0 ) - aLine.append( maIncompleteLine ).append( sal_Unicode( ' ' ) ); - aLine.append( rLine ); - maIncompleteLine = OUString(); + /* Buffers a start element and the following element text. Needed to dump + matching start/end elements and the element text on the same line. */ + OUStringBuffer aOldStartElem; + // special handling for VML + bool bIsVml = InputOutputHelper::getFileNameExtension( maSysFileName ).equalsIgnoreAsciiCaseAscii( "vml" ); - if( aLine.getLength() == 0 ) + while( !rTextStrm.isEof() ) { - mxOut->newLine(); - return; - } + // get the next element and the following element text from text stream + OUString aElem = rTextStrm.readToChar( '>', true ).trim(); + OUString aText = rTextStrm.readToChar( '<', false ); - const sal_Unicode* pcPos = aLine.getStr(); - const sal_Unicode* pcEnd = pcPos + aLine.getLength(); - while( pcPos < pcEnd ) - { - OUStringBuffer aOutLine; - bool bIsStartElement = false; - bool bIsComplElement = false; - bool bIsEndElement = false; - - /* check for start element at beginning of the line - pcEnd and thus (pcPos+1) - are dereferenceable, because OUStringBuffer::getStr is null-terminated. */ - if( (*pcPos == '<') && (pcPos[ 1 ] != '/') ) + // remove multiple whitespace from element + sal_Int32 nPos = 0; + while( nPos < aElem.getLength() ) { - const sal_Unicode* pcElementEnd = ::std::find( pcPos, pcEnd, '>' ); - if( pcElementEnd == pcEnd ) - { - // incomplete start element - maIncompleteLine = OUString( pcPos, static_cast< sal_Int32 >( pcEnd - pcPos ) ); - pcPos = pcEnd; - } - else - { - bIsComplElement = (pcPos[ 1 ] == '?') || (pcPos[ 1 ] == '!') || (pcElementEnd[ -1 ] == '/'); - bIsStartElement = !bIsComplElement; - ++pcElementEnd; - aOutLine.append( pcPos, static_cast< sal_Int32 >( pcElementEnd - pcPos ) ); - pcPos = pcElementEnd; - } + while( (nPos < aElem.getLength()) && (aElem[ nPos ] >= 32) ) ++nPos; + if( nPos < aElem.getLength() ) + aElem = OUStringBuffer( aElem.copy( 0, nPos ) ).append( sal_Unicode( ' ' ) ).append( aElem.copy( nPos ).trim() ).makeStringAndClear(); + ++nPos; } - // check for following element text - if( !bIsComplElement && (pcPos < pcEnd) ) + sal_Int32 nElemLen = aElem.getLength(); + if( (nElemLen >= 2) && (aElem[ 0 ] == '<') && (aElem[ nElemLen - 1 ] == '>') ) { - const sal_Unicode* pcElementStart = ::std::find( pcPos, pcEnd, '<' ); - // append text between elements - if( pcPos < pcElementStart ) + // determine type of the element + bool bSimpleElem = (aElem[ 1 ] == '!') || (aElem[ 1 ] == '?') || (aElem[ nElemLen - 2 ] == '/') || + (bIsVml && (nElemLen == 4) && (aElem[ 1 ] == 'b') && (aElem[ 2 ] == 'r')); + bool bStartElem = !bSimpleElem && (aElem[ 1 ] != '/'); + bool bEndElem = !bSimpleElem && !bStartElem; + + /* Start element or simple element: flush old start element and + its text from previous iteration, and start a new indentation + level for the new element. Trim whitespace and line breaks from + the text of the old start element. */ + if( (bSimpleElem || bStartElem) && (aOldStartElem.getLength() > 0) ) { - OUString aText( pcPos, static_cast< sal_Int32 >( pcElementStart - pcPos ) ); - if( aText.trim().getLength() > 0 ) - aOutLine.append( aText ); - pcPos = pcElementStart; + mxOut->writeString( aOldStartElem.makeStringAndClear().trim() ); + mxOut->newLine(); + mxOut->incIndent(); } - } - // check for stand-alone or following end element - if( !bIsComplElement && (pcPos < pcEnd) && (pcPos[ 1 ] == '/') ) - { - const sal_Unicode* pcElementEnd = ::std::find( pcPos, pcEnd, '>' ); - if( pcElementEnd == pcEnd ) + /* Start element: remember it and its text, to be able to print the + matching end element on the same line in the next iteration. */ + if( bStartElem ) { - // incomplete end element - aOutLine.append( pcPos, static_cast< sal_Int32 >( pcEnd - pcPos ) ); - maIncompleteLine = aOutLine.makeStringAndClear(); - pcPos = pcEnd; + aOldStartElem.append( aElem ).append( aText ); } else { - bIsEndElement = true; - ++pcElementEnd; - aOutLine.append( pcPos, static_cast< sal_Int32 >( pcElementEnd - pcPos ) ); - pcPos = pcElementEnd; - } - } + /* End element: if a start element has been remembered in the + previous iteration, write it out here untrimmed, to show + all whitespace in the element text, and without trailing + line break. Code below will add the end element right after + it. Otherwise, return to previous indentation level. */ + if( bEndElem ) + { + if( aOldStartElem.getLength() == 0 ) + mxOut->decIndent(); + else + mxOut->writeString( aOldStartElem.makeStringAndClear() ); + } - // flush output line - if( maIncompleteLine.getLength() == 0 ) - { - if( !bIsStartElement && bIsEndElement ) mxOut->decIndent(); - mxOut->writeString( aOutLine.makeStringAndClear() ); - mxOut->newLine(); - if( bIsStartElement && !bIsEndElement ) mxOut->incIndent(); + /* Write the element. Write following element text in a new + line, but only, if it does not contain of white space + entirely. */ + mxOut->writeString( aElem ); + mxOut->newLine(); + if( aText.trim().getLength() > 0 ) + { + mxOut->writeString( aText ); + mxOut->newLine(); + } + } } } } @@ -3167,7 +3131,7 @@ bool SequenceRecordObjectBase::implStartRecord( BinaryInputStream& rBaseStrm, sa { ornRecPos = rBaseStrm.tell(); // do not try to overread seekable streams, may cause assertions - bValid = ornRecPos < rBaseStrm.getLength(); + bValid = ornRecPos < rBaseStrm.size(); } // read the record header diff --git a/oox/source/dump/oledumper.cxx b/oox/source/dump/oledumper.cxx index bd2a0e05ecce..e0135af1604f 100644 --- a/oox/source/dump/oledumper.cxx +++ b/oox/source/dump/oledumper.cxx @@ -469,9 +469,9 @@ void OlePropertyStreamObject::dumpCodePageProperty( sal_uInt32 nStartPos ) if( nType == OLEPROP_TYPE_INT16 ) { sal_uInt16 nCodePage = dumpDec< sal_uInt16 >( "codepage", "CODEPAGES" ); - rtl_TextEncoding nNewTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage ); - if( nNewTextEnc != RTL_TEXTENCODING_DONTKNOW ) - meTextEnc = nNewTextEnc; + rtl_TextEncoding eNewTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage ); + if( eNewTextEnc != RTL_TEXTENCODING_DONTKNOW ) + meTextEnc = eNewTextEnc; mbIsUnicode = nCodePage == CODEPAGE_UNICODE; } else @@ -586,15 +586,8 @@ OUString OlePropertyStreamObject::dumpString8( const String& rName ) OUString OlePropertyStreamObject::dumpCharArray8( const String& rName, sal_Int32 nLen ) { - OUString aData; - size_t nNewLen = getLimitedValue< size_t, sal_Int32 >( nLen, 0, 1024 ); - if( nNewLen > 0 ) - { - ::std::vector< sal_Char > aBuffer( nNewLen + 1 ); - mxStrm->readMemory( &aBuffer.front(), nNewLen ); - aBuffer[ nNewLen ] = 0; - aData = OStringToOUString( OString( &aBuffer.front() ), meTextEnc ); - } + sal_Int32 nNewLen = getLimitedValue< sal_Int32, sal_Int32 >( nLen, 0, 1024 ); + OUString aData = mxStrm->readCharArrayUC( nNewLen, meTextEnc ); writeStringItem( rName, aData ); return aData; } @@ -607,13 +600,8 @@ OUString OlePropertyStreamObject::dumpString16( const String& rName ) OUString OlePropertyStreamObject::dumpCharArray16( const String& rName, sal_Int32 nLen ) { - size_t nNewLen = getLimitedValue< size_t, sal_Int32 >( nLen, 0, 1024 ); - ::std::vector< sal_Unicode > aBuffer; - aBuffer.reserve( nNewLen + 1 ); - for( size_t nIdx = 0; nIdx < nNewLen; ++nIdx ) - aBuffer.push_back( static_cast< sal_Unicode >( mxStrm->readuInt16() ) ); - aBuffer.push_back( 0 ); - OUString aData( &aBuffer.front() ); + sal_Int32 nNewLen = getLimitedValue< sal_Int32, sal_Int32 >( nLen, 0, 1024 ); + OUString aData = mxStrm->readUnicodeArray( nNewLen ); writeStringItem( rName, aData ); if( nNewLen & 1 ) dumpUnused( 2 ); // always padding to 32bit return aData; @@ -687,7 +675,7 @@ void OleStorageObject::construct( const ObjectBase& rParent ) StorageObjectBase::construct( rParent ); } -void OleStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& /*rStrgPath*/, const OUString& rStrmName, const OUString& rSysFileName ) +void OleStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& /*rStrgPath*/, const OUString& rStrmName, const OUString& rSysFileName ) { if( rStrmName.equalsAscii( "\001CompObj" ) ) OleCompObjObject( *this, rxStrm, rSysFileName ).dump(); @@ -1926,7 +1914,7 @@ void VbaFStreamObject::dumpSiteData() sal_uInt32 nSiteCount = dumpDec< sal_uInt32 >( "site-count" ); sal_uInt32 nSiteLength = dumpDec< sal_uInt32 >( "site-data-size" ); sal_Int64 nEndPos = mxStrm->tell() + nSiteLength; - if( ensureValid( nEndPos <= mxStrm->getLength() ) ) + if( ensureValid( nEndPos <= mxStrm->size() ) ) { mxOut->resetItemIndex(); sal_uInt32 nSiteIdx = 0; @@ -1984,7 +1972,7 @@ void VbaOStreamObject::implDump() writeDecItem( "control-id", aIt->mnId ); writeInfoItem( "prog-id", aIt->maProgId ); IndentGuard aIndGuard( mxOut ); - RelativeInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, aIt->mnLength ) ); + BinaryInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, aIt->mnLength ) ); FormControlStreamObject( *this, xRelStrm, &aIt->maProgId ).dump(); } } @@ -2068,7 +2056,7 @@ VbaContainerStorageObject::VbaContainerStorageObject( const ObjectBase& rParent, addPreferredStream( "f" ); } -void VbaContainerStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) +void VbaContainerStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) { if( rStrmName.equalsAscii( "f" ) ) VbaFStreamObject( *this, rxStrm, rSysFileName, maFormData ).dump(); @@ -2280,7 +2268,7 @@ void VbaModuleStreamObject::implDump() writeEmptyItem( "source-code" ); IndentGuard aIndGuard( mxOut ); BinaryInputStreamRef xVbaStrm( new ::oox::ole::VbaInputStream( *mxStrm ) ); - TextStreamObject( *this, xVbaStrm, mrVbaData.meTextEnc ).dump(); + TextLineStreamObject( *this, xVbaStrm, mrVbaData.meTextEnc ).dump(); } // ============================================================================ @@ -2292,7 +2280,7 @@ VbaStorageObject::VbaStorageObject( const ObjectBase& rParent, const StorageRef& addPreferredStream( "dir" ); } -void VbaStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) +void VbaStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) { if( (rStrgPath.getLength() == 0) && rStrmName.equalsAscii( "dir" ) ) VbaDirStreamObject( *this, rxStrm, rSysFileName, mrVbaData ).dump(); @@ -2310,10 +2298,10 @@ VbaFormStorageObject::VbaFormStorageObject( const ObjectBase& rParent, const Sto { } -void VbaFormStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) +void VbaFormStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) { if( rStrmName.equalsAscii( "\003VBFrame" ) ) - TextStreamObject( *this, rxStrm, mrVbaData.meTextEnc, rSysFileName ).dump(); + TextLineStreamObject( *this, rxStrm, mrVbaData.meTextEnc, rSysFileName ).dump(); else VbaContainerStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName ); } @@ -2326,10 +2314,10 @@ VbaProjectStorageObject::VbaProjectStorageObject( const ObjectBase& rParent, con addPreferredStorage( "VBA" ); } -void VbaProjectStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) +void VbaProjectStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) { if( (rStrgPath.getLength() == 0) && rStrmName.equalsAscii( "PROJECT" ) ) - TextStreamObject( *this, rxStrm, maVbaData.meTextEnc, rSysFileName ).dump(); + TextLineStreamObject( *this, rxStrm, maVbaData.meTextEnc, rSysFileName ).dump(); else OleStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName ); } diff --git a/oox/source/dump/pptxdumper.cxx b/oox/source/dump/pptxdumper.cxx index 39e0ccc2be55..c98ffac7e38d 100644 --- a/oox/source/dump/pptxdumper.cxx +++ b/oox/source/dump/pptxdumper.cxx @@ -56,14 +56,13 @@ RootStorageObject::RootStorageObject( const DumperBase& rParent ) StorageObjectBase::construct( rParent ); } -void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) +void RootStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) { OUString aExt = InputOutputHelper::getFileNameExtension( rStrmName ); - Reference< XInputStream > xInStrm = InputOutputHelper::getXInputStream( *rxStrm ); if( aExt.equalsIgnoreAsciiCaseAscii( "pptx" ) || aExt.equalsIgnoreAsciiCaseAscii( "potx" ) ) { - Dumper( getFactory(), xInStrm, rSysFileName ).dump(); + Dumper( getContext(), rxStrm, rSysFileName ).dump(); } else if( aExt.equalsIgnoreAsciiCaseAscii( "xlsb" ) || @@ -72,7 +71,7 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons aExt.equalsIgnoreAsciiCaseAscii( "xltm" ) || aExt.equalsIgnoreAsciiCaseAscii( "xltx" ) ) { - ::oox::dump::xlsb::Dumper( getFactory(), xInStrm, rSysFileName ).dump(); + ::oox::dump::xlsb::Dumper( getContext(), rxStrm, rSysFileName ).dump(); } else if( aExt.equalsIgnoreAsciiCaseAscii( "xla" ) || @@ -82,7 +81,7 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons aExt.equalsIgnoreAsciiCaseAscii( "xlt" ) || aExt.equalsIgnoreAsciiCaseAscii( "xlw" ) ) { - ::oox::dump::biff::Dumper( getFactory(), xInStrm, rSysFileName ).dump(); + ::oox::dump::biff::Dumper( getContext(), rxStrm, rSysFileName ).dump(); } else if( aExt.equalsIgnoreAsciiCaseAscii( "xml" ) || @@ -95,17 +94,17 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons { if( rStrgPath.equalsAscii( "ppt" ) && rStrmName.equalsAscii( "vbaProject.bin" ) ) { - StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) ); + StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, false ) ); VbaProjectStorageObject( *this, xStrg, rSysFileName ).dump(); } else if( rStrgPath.equalsAscii( "ppt/embeddings" ) ) { - StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) ); + StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, false ) ); OleStorageObject( *this, xStrg, rSysFileName ).dump(); } else if( rStrgPath.equalsAscii( "ppt/activeX" ) ) { - StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, true ) ); + StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, true ) ); ActiveXStorageObject( *this, xStrg, rSysFileName ).dump(); } else @@ -125,13 +124,13 @@ Dumper::Dumper( const FilterBase& rFilter ) DumperBase::construct( xCfg ); } -Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName ) +Dumper::Dumper( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName ) { - if( rxFactory.is() && rxInStrm.is() ) + if( rxContext.is() && rxInStrm.is() ) { - StorageRef xStrg( new ZipStorage( rxFactory, rxInStrm ) ); + StorageRef xStrg( new ZipStorage( rxContext, rxInStrm ) ); MediaDescriptor aMediaDesc; - ConfigRef xCfg( new Config( DUMP_PPTX_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) ); + ConfigRef xCfg( new Config( DUMP_PPTX_CONFIG_ENVVAR, rxContext, xStrg, rSysFileName, aMediaDesc ) ); DumperBase::construct( xCfg ); } } diff --git a/oox/source/dump/xlsbdumper.cxx b/oox/source/dump/xlsbdumper.cxx index 3dc2974420a6..a5ffab059b52 100644 --- a/oox/source/dump/xlsbdumper.cxx +++ b/oox/source/dump/xlsbdumper.cxx @@ -368,7 +368,7 @@ void FormulaObject::implDump() if( mnSize < 0 ) return; sal_Int64 nStartPos = mxStrm->tell(); - sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->getLength() ); + sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->size() ); bool bValid = mxTokens.get(); mxStack.reset( new FormulaStack ); @@ -889,8 +889,8 @@ bool FormulaObject::dumpAttrToken() void FormulaObject::dumpAddTokenData() { mxOut->resetItemIndex(); - sal_Int32 nAddDataSize = (mxStrm->getLength() - mxStrm->tell() >= 4) ? dumpDec< sal_Int32 >( "add-data-size" ) : 0; - sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nAddDataSize, mxStrm->getLength() ); + sal_Int32 nAddDataSize = (mxStrm->size() - mxStrm->tell() >= 4) ? dumpDec< sal_Int32 >( "add-data-size" ) : 0; + sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nAddDataSize, mxStrm->size() ); for( AddDataTypeVec::const_iterator aIt = maAddData.begin(), aEnd = maAddData.end(); (aIt != aEnd) && !mxStrm->isEof() && (mxStrm->tell() < nEndPos); ++aIt ) { AddDataType eType = *aIt; @@ -2231,10 +2231,9 @@ RootStorageObject::RootStorageObject( const DumperBase& rParent ) StorageObjectBase::construct( rParent ); } -void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) +void RootStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) { OUString aExt = InputOutputHelper::getFileNameExtension( rStrmName ); - Reference< XInputStream > xInStrm = InputOutputHelper::getXInputStream( *rxStrm ); if( aExt.equalsIgnoreAsciiCaseAscii( "xlsb" ) || aExt.equalsIgnoreAsciiCaseAscii( "xlsm" ) || @@ -2242,7 +2241,7 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons aExt.equalsIgnoreAsciiCaseAscii( "xltm" ) || aExt.equalsIgnoreAsciiCaseAscii( "xltx" ) ) { - Dumper( getFactory(), xInStrm, rSysFileName ).dump(); + Dumper( getContext(), rxStrm, rSysFileName ).dump(); } else if( aExt.equalsIgnoreAsciiCaseAscii( "xla" ) || @@ -2252,13 +2251,13 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons aExt.equalsIgnoreAsciiCaseAscii( "xlt" ) || aExt.equalsIgnoreAsciiCaseAscii( "xlw" ) ) { - ::oox::dump::biff::Dumper( getFactory(), xInStrm, rSysFileName ).dump(); + ::oox::dump::biff::Dumper( getContext(), rxStrm, rSysFileName ).dump(); } else if( aExt.equalsIgnoreAsciiCaseAscii( "pptx" ) || aExt.equalsIgnoreAsciiCaseAscii( "potx" ) ) { - ::oox::dump::pptx::Dumper( getFactory(), xInStrm, rSysFileName ).dump(); + ::oox::dump::pptx::Dumper( getContext(), rxStrm, rSysFileName ).dump(); } else if( aExt.equalsIgnoreAsciiCaseAscii( "xml" ) || @@ -2271,12 +2270,12 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons { if( rStrgPath.equalsAscii( "xl" ) && rStrmName.equalsAscii( "vbaProject.bin" ) ) { - StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) ); + StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, false ) ); VbaProjectStorageObject( *this, xStrg, rSysFileName ).dump(); } else if( rStrgPath.equalsAscii( "xl/embeddings" ) ) { - StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) ); + StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, false ) ); OleStorageObject( *this, xStrg, rSysFileName ).dump(); } else if( @@ -2295,7 +2294,7 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons } else if( rStrgPath.equalsAscii( "xl/activeX" ) ) { - StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, true ) ); + StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, true ) ); ActiveXStorageObject( *this, xStrg, rSysFileName ).dump(); } else @@ -2315,13 +2314,13 @@ Dumper::Dumper( const FilterBase& rFilter ) DumperBase::construct( xCfg ); } -Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName ) +Dumper::Dumper( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName ) { - if( rxFactory.is() && rxInStrm.is() ) + if( rxContext.is() && rxInStrm.is() ) { - StorageRef xStrg( new ZipStorage( rxFactory, rxInStrm ) ); + StorageRef xStrg( new ZipStorage( getContext(), rxInStrm ) ); MediaDescriptor aMediaDesc; - ConfigRef xCfg( new Config( DUMP_XLSB_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) ); + ConfigRef xCfg( new Config( DUMP_XLSB_CONFIG_ENVVAR, rxContext, xStrg, rSysFileName, aMediaDesc ) ); DumperBase::construct( xCfg ); } } diff --git a/oox/source/helper/binaryinputstream.cxx b/oox/source/helper/binaryinputstream.cxx index 2d547cdbf724..e61000675006 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,14 +148,10 @@ 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 ), @@ -145,16 +162,29 @@ BinaryXInputStream::BinaryXInputStream( const Reference< XInputStream >& rxInStr BinaryXInputStream::~BinaryXInputStream() { - if( mbAutoClose ) - close(); + close(); +} + +void BinaryXInputStream::close() +{ + OSL_ENSURE( 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(); + 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 +195,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 +205,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 +216,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 +228,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 +277,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..1ae7b15d7595 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,14 +47,8 @@ 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 ), @@ -63,15 +59,30 @@ BinaryXOutputStream::BinaryXOutputStream( const Reference< XOutputStream >& rxOu BinaryXOutputStream::~BinaryXOutputStream() { - if( mbAutoClose ) - close(); + close(); +} + +void BinaryXOutputStream::close() +{ + OSL_ENSURE( 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(); + 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 +91,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..4fb0d93d6224 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,13 @@ using ::rtl::OUStringBuffer; // ============================================================================ -Reference< XIndexContainer > ContainerHelper::createIndexContainer( const Reference< XMultiServiceFactory >& rxFactory ) +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 +80,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/modelobjecthelper.cxx b/oox/source/helper/modelobjecthelper.cxx index f9d8af74bcb8..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& ) { diff --git a/oox/source/helper/propertyset.cxx b/oox/source/helper/propertyset.cxx index 769bd9974fb9..c21b8959e2bc 100644 --- a/oox/source/helper/propertyset.cxx +++ b/oox/source/helper/propertyset.cxx @@ -48,6 +48,26 @@ void PropertySet::set( const Reference< XPropertySet >& rxPropSet ) { mxPropSet = rxPropSet; mxMultiPropSet.set( mxPropSet, UNO_QUERY ); + if( mxPropSet.is() ) try + { + mxPropSetInfo = mxPropSet->getPropertySetInfo(); + } + catch( Exception& ) + { + } +} + +bool PropertySet::hasProperty( sal_Int32 nPropId ) const +{ + if( mxPropSetInfo.is() ) try + { + const OUString& rPropName = PropertyMap::getPropertyName( nPropId ); + return mxPropSetInfo->hasPropertyByName( rPropName ); + } + catch( Exception& ) + { + } + return false; } // Get properties ------------------------------------------------------------- diff --git a/oox/source/helper/textinputstream.cxx b/oox/source/helper/textinputstream.cxx index d590781c6fd3..9087dea7b26f 100644 --- 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 8145e7c4e5ce..fc976d8d7537 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,14 +51,12 @@ 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 @@ -69,26 +68,26 @@ ZipStorage::ZipStorage( TODO: #i105410# switch to 'OFOPXMLFormat' and use its implementation of relations handling. */ + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( - ZIP_STORAGE_FORMAT_STRING, rxInStream, rxFactory, sal_True ); + ZIP_STORAGE_FORMAT_STRING, rxInStream, xFactory, sal_True ); } 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& ) { diff --git a/oox/source/ole/axbinaryreader.cxx b/oox/source/ole/axbinaryreader.cxx index 493d6b68c6ff..58610e419f32 100644 --- a/oox/source/ole/axbinaryreader.cxx +++ b/oox/source/ole/axbinaryreader.cxx @@ -48,14 +48,22 @@ const sal_uInt32 AX_STRING_COMPRESSED = 0x80000000; // ============================================================================ AxAlignedInputStream::AxAlignedInputStream( BinaryInputStream& rInStrm ) : - mrInStrm( rInStrm ), - mnStrmPos( 0 ) + BinaryStreamBase( false ), + mpInStrm( &rInStrm ), + mnStrmPos( 0 ), + mnStrmSize( rInStrm.getRemaining() ) { + mbEof = mbEof || rInStrm.isEof(); +} + +sal_Int64 AxAlignedInputStream::size() const +{ + return mpInStrm ? mnStrmSize : -1; } sal_Int64 AxAlignedInputStream::tell() const { - return mnStrmPos; + return mpInStrm ? mnStrmPos : -1; } void AxAlignedInputStream::seek( sal_Int64 nPos ) @@ -65,24 +73,44 @@ void AxAlignedInputStream::seek( sal_Int64 nPos ) skip( static_cast< sal_Int32 >( nPos - mnStrmPos ) ); } -sal_Int32 AxAlignedInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes ) +void AxAlignedInputStream::close() +{ + mpInStrm = 0; + mbEof = true; +} + +sal_Int32 AxAlignedInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize ) { - sal_Int32 nReadSize = mrInStrm.readData( orData, nBytes ); - mnStrmPos += nReadSize; + sal_Int32 nReadSize = 0; + if( !mbEof ) + { + nReadSize = mpInStrm->readData( orData, nBytes, nAtomSize ); + mnStrmPos += nReadSize; + mbEof = mpInStrm->isEof(); + } return nReadSize; } -sal_Int32 AxAlignedInputStream::readMemory( void* opMem, sal_Int32 nBytes ) +sal_Int32 AxAlignedInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize ) { - sal_Int32 nReadSize = mrInStrm.readMemory( opMem, nBytes ); - mnStrmPos += nReadSize; + sal_Int32 nReadSize = 0; + if( !mbEof ) + { + nReadSize = mpInStrm->readMemory( opMem, nBytes, nAtomSize ); + mnStrmPos += nReadSize; + mbEof = mpInStrm->isEof(); + } return nReadSize; } -void AxAlignedInputStream::skip( sal_Int32 nBytes ) +void AxAlignedInputStream::skip( sal_Int32 nBytes, size_t nAtomSize ) { - mrInStrm.skip( nBytes ); - mnStrmPos += nBytes; + if( !mbEof ) + { + mpInStrm->skip( nBytes, nAtomSize ); + mnStrmPos += nBytes; + mbEof = mpInStrm->isEof(); + } } void AxAlignedInputStream::align( size_t nSize ) @@ -174,10 +202,7 @@ bool lclReadString( AxAlignedInputStream& rInStrm, OUString& rValue, sal_uInt32 OSL_ENSURE( bValidChars, "lclReadString - string too long" ); sal_Int64 nEndPos = rInStrm.tell() + nChars * (bCompressed ? 1 : 2); nChars = ::std::min< sal_Int32 >( nChars, 65536 ); - rValue = bCompressed ? - // ISO-8859-1 maps all byte values xx to the same Unicode code point U+00xx - rInStrm.readCharArrayUC( nChars, RTL_TEXTENCODING_ISO_8859_1 ) : - rInStrm.readUnicodeArray( nChars ); + rValue = rInStrm.readCompressedUnicodeArray( nChars, bCompressed ); rInStrm.seek( nEndPos ); return bValidChars; } diff --git a/oox/source/ole/axcontrol.cxx b/oox/source/ole/axcontrol.cxx index 86cc55df3127..40dfdf1ca84e 100644 --- a/oox/source/ole/axcontrol.cxx +++ b/oox/source/ole/axcontrol.cxx @@ -226,11 +226,11 @@ void lclPrepareConverter( PropertySet& rConverter, const Reference< XModel >& rx { if( !rConverter.is() ) try { - Reference< XMultiServiceFactory > xFactory( rxDocModel, UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xModelFactory( rxDocModel, UNO_QUERY_THROW ); OUString aServiceName = bRange ? CREATE_OUSTRING( "com.sun.star.table.CellRangeAddressConversion" ) : CREATE_OUSTRING( "com.sun.star.table.CellAddressConversion" ); - rConverter.set( xFactory->createInstance( aServiceName ) ); + rConverter.set( xModelFactory->createInstance( aServiceName ) ); } catch( Exception& ) { @@ -344,8 +344,8 @@ void ControlConverter::bindToSources( const Reference< XControlModel >& rxCtrlMo aArgs[ 0 ] <<= aValue; // create the CellValueBinding instance and set at the control model - Reference< XMultiServiceFactory > xFactory( mxDocModel, UNO_QUERY_THROW ); - Reference< XValueBinding > xBinding( xFactory->createInstanceWithArguments( + Reference< XMultiServiceFactory > xModelFactory( mxDocModel, UNO_QUERY_THROW ); + Reference< XValueBinding > xBinding( xModelFactory->createInstanceWithArguments( CREATE_OUSTRING( "com.sun.star.table.CellValueBinding" ), aArgs ), UNO_QUERY_THROW ); xBindable->setValueBinding( xBinding ); } @@ -376,8 +376,8 @@ void ControlConverter::bindToSources( const Reference< XControlModel >& rxCtrlMo aArgs[ 0 ] <<= aValue; // create the EntrySource instance and set at the control model - Reference< XMultiServiceFactory > xFactory( mxDocModel, UNO_QUERY_THROW ); - Reference< XListEntrySource > xEntrySource( xFactory->createInstanceWithArguments( + Reference< XMultiServiceFactory > xModelFactory( mxDocModel, UNO_QUERY_THROW ); + Reference< XListEntrySource > xEntrySource( xModelFactory->createInstanceWithArguments( CREATE_OUSTRING( "com.sun.star.table.CellRangeListSource" ), aArgs ), UNO_QUERY_THROW ); xEntrySink->setListEntrySource( xEntrySource ); } diff --git a/oox/source/ole/axcontrolfragment.cxx b/oox/source/ole/axcontrolfragment.cxx index f45e8e2590c9..a81ae99f0c11 100644 --- a/oox/source/ole/axcontrolfragment.cxx +++ b/oox/source/ole/axcontrolfragment.cxx @@ -140,7 +140,7 @@ ContextHandlerRef AxControlFragment::onCreateContext( sal_Int32 nElement, const Reference< XInputStream > xStrgStrm = getFilter().openInputStream( aFragmentPath ); if( xStrgStrm.is() ) { - OleStorage aStorage( getFilter().getServiceFactory(), xStrgStrm, false ); + OleStorage aStorage( getFilter().getComponentContext(), xStrgStrm, false ); BinaryXInputStream aInStrm( aStorage.openInputStream( CREATE_OUSTRING( "f" ) ), true ); if( !aInStrm.isEof() ) if( AxContainerModelBase* pModel = dynamic_cast< AxContainerModelBase* >( mrControl.createModelFromGuid( aClassId ) ) ) diff --git a/oox/source/ole/oleobjecthelper.cxx b/oox/source/ole/oleobjecthelper.cxx index 396cd6b53874..5a38d9316a36 100644 --- a/oox/source/ole/oleobjecthelper.cxx +++ b/oox/source/ole/oleobjecthelper.cxx @@ -44,6 +44,7 @@ namespace ole { using namespace ::com::sun::star::awt; using namespace ::com::sun::star::container; +using namespace ::com::sun::star::embed; using namespace ::com::sun::star::io; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::uno; @@ -61,12 +62,17 @@ OleObjectInfo::OleObjectInfo() : // ============================================================================ -OleObjectHelper::OleObjectHelper( const Reference< XMultiServiceFactory >& rxFactory ) : +OleObjectHelper::OleObjectHelper( const Reference< XMultiServiceFactory >& rxModelFactory ) : maEmbeddedObjScheme( CREATE_OUSTRING( "vnd.sun.star.EmbeddedObject:" ) ), mnObjectId( 100 ) { - if( rxFactory.is() ) - mxResolver.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.ImportEmbeddedObjectResolver" ) ), UNO_QUERY ); + if( rxModelFactory.is() ) try + { + mxResolver.set( rxModelFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.ImportEmbeddedObjectResolver" ) ), UNO_QUERY ); + } + catch( Exception& ) + { + } } OleObjectHelper::~OleObjectHelper() @@ -122,11 +128,7 @@ bool OleObjectHelper::importOleObject( PropertyMap& rPropMap, const OleObjectInf if( bRet ) { - // aspect mode - using namespace ::com::sun::star::embed::Aspects; - sal_Int64 nAspect = rOleObject.mbShowAsIcon ? MSOLE_ICON : MSOLE_CONTENT; - rPropMap[ PROP_Aspect ] <<= nAspect; - // visual area + rPropMap[ PROP_Aspect ] <<= (rOleObject.mbShowAsIcon ? Aspects::MSOLE_ICON : Aspects::MSOLE_CONTENT); rPropMap[ PROP_VisualArea ] <<= Rectangle( 0, 0, rObjSize.Width, rObjSize.Height ); } return bRet; diff --git a/oox/source/ole/olestorage.cxx b/oox/source/ole/olestorage.cxx index cf55d6463778..2db4aed76834 100644 --- a/oox/source/ole/olestorage.cxx +++ b/oox/source/ole/olestorage.cxx @@ -35,6 +35,7 @@ #include <com/sun/star/io/XSeekable.hpp> #include <com/sun/star/io/XStream.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> #include <cppuhelper/implbase2.hxx> #include "oox/helper/binaryinputstream.hxx" #include "oox/helper/binaryoutputstream.hxx" @@ -68,7 +69,7 @@ class OleOutputStream : public OleOutputStreamBase { public: explicit OleOutputStream( - const Reference< XMultiServiceFactory >& rxFactory, + const Reference< XComponentContext >& rxContext, const Reference< XNameContainer >& rxStorage, const OUString& rElementName ); virtual ~OleOutputStream(); @@ -95,14 +96,15 @@ private: // ---------------------------------------------------------------------------- -OleOutputStream::OleOutputStream( const Reference< XMultiServiceFactory >& rxFactory, +OleOutputStream::OleOutputStream( const Reference< XComponentContext >& rxContext, const Reference< XNameContainer >& rxStorage, const OUString& rElementName ) : mxStorage( rxStorage ), maElementName( rElementName ) { try { - mxTempFile.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + mxTempFile.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); mxOutStrm = mxTempFile->getOutputStream(); mxSeekable.set( mxOutStrm, UNO_QUERY ); } @@ -179,49 +181,40 @@ void OleOutputStream::ensureConnected() const throw( NotConnectedException ) // ============================================================================ -OleStorage::OleStorage( - const Reference< XMultiServiceFactory >& rxFactory, - const Reference< XInputStream >& rxInStream, - bool bBaseStreamAccess ) : +OleStorage::OleStorage( const Reference< XComponentContext >& rxContext, + const Reference< XInputStream >& rxInStream, bool bBaseStreamAccess ) : StorageBase( rxInStream, bBaseStreamAccess ), - mxFactory( rxFactory ), + mxContext( rxContext ), mpParentStorage( 0 ) { - OSL_ENSURE( mxFactory.is(), "OleStorage::OleStorage - missing service factory" ); + OSL_ENSURE( mxContext.is(), "OleStorage::OleStorage - missing component context" ); initStorage( rxInStream ); } -OleStorage::OleStorage( - const Reference< XMultiServiceFactory >& rxFactory, - const Reference< XStream >& rxOutStream, - bool bBaseStreamAccess ) : +OleStorage::OleStorage( const Reference< XComponentContext >& rxContext, + const Reference< XStream >& rxOutStream, bool bBaseStreamAccess ) : StorageBase( rxOutStream, bBaseStreamAccess ), - mxFactory( rxFactory ), + mxContext( rxContext ), mpParentStorage( 0 ) { - OSL_ENSURE( mxFactory.is(), "OleStorage::OleStorage - missing service factory" ); + OSL_ENSURE( mxContext.is(), "OleStorage::OleStorage - missing component context" ); initStorage( rxOutStream ); } -OleStorage::OleStorage( - const OleStorage& rParentStorage, - const Reference< XNameContainer >& rxStorage, - const OUString& rElementName, - bool bReadOnly ) : +OleStorage::OleStorage( const OleStorage& rParentStorage, + const Reference< XNameContainer >& rxStorage, const OUString& rElementName, bool bReadOnly ) : StorageBase( rParentStorage, rElementName, bReadOnly ), - mxFactory( rParentStorage.mxFactory ), + mxContext( rParentStorage.mxContext ), mxStorage( rxStorage ), mpParentStorage( &rParentStorage ) { OSL_ENSURE( mxStorage.is(), "OleStorage::OleStorage - missing substorage elements" ); } -OleStorage::OleStorage( - const OleStorage& rParentStorage, - const Reference< XStream >& rxOutStream, - const OUString& rElementName ) : +OleStorage::OleStorage( const OleStorage& rParentStorage, + const Reference< XStream >& rxOutStream, const OUString& rElementName ) : StorageBase( rParentStorage, rElementName, false ), - mxFactory( rParentStorage.mxFactory ), + mxContext( rParentStorage.mxContext ), mpParentStorage( &rParentStorage ) { initStorage( rxOutStream ); @@ -239,7 +232,8 @@ void OleStorage::initStorage( const Reference< XInputStream >& rxInStream ) Reference< XInputStream > xInStrm = rxInStream; if( !Reference< XSeekable >( xInStrm, UNO_QUERY ).is() ) try { - Reference< XStream > xTempFile( mxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XStream > xTempFile( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); { Reference< XOutputStream > xOutStrm( xTempFile->getOutputStream(), UNO_SET_THROW ); /* Pass false to both binary stream objects to keep the UNO @@ -259,10 +253,11 @@ void OleStorage::initStorage( const Reference< XInputStream >& rxInStream ) // create base storage object if( xInStrm.is() ) try { + Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); Sequence< Any > aArgs( 2 ); aArgs[ 0 ] <<= xInStrm; aArgs[ 1 ] <<= true; // true = do not create a copy of the input stream - mxStorage.set( mxFactory->createInstanceWithArguments( + mxStorage.set( xFactory->createInstanceWithArguments( CREATE_OUSTRING( "com.sun.star.embed.OLESimpleStorage" ), aArgs ), UNO_QUERY_THROW ); } catch( Exception& ) @@ -275,10 +270,11 @@ void OleStorage::initStorage( const Reference< XStream >& rxOutStream ) // create base storage object if( rxOutStream.is() ) try { + Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); Sequence< Any > aArgs( 2 ); aArgs[ 0 ] <<= rxOutStream; aArgs[ 1 ] <<= true; // true = do not create a copy of the stream - mxStorage.set( mxFactory->createInstanceWithArguments( + mxStorage.set( xFactory->createInstanceWithArguments( CREATE_OUSTRING( "com.sun.star.embed.OLESimpleStorage" ), aArgs ), UNO_QUERY_THROW ); } catch( Exception& ) @@ -347,7 +343,8 @@ StorageRef OleStorage::implOpenSubStorage( const OUString& rElementName, bool bC if( !isReadOnly() && (bCreateMissing || xSubStorage.get()) ) try { // create new storage based on a temp file - Reference< XStream > xTempFile( mxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XStream > xTempFile( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); StorageRef xTempStorage( new OleStorage( *this, xTempFile, rElementName ) ); // copy existing substorage into temp storage if( xSubStorage.get() ) @@ -379,7 +376,7 @@ Reference< XOutputStream > OleStorage::implOpenOutputStream( const OUString& rEl { Reference< XOutputStream > xOutStream; if( mxStorage.is() && (rElementName.getLength() > 0) ) - xOutStream.set( new OleOutputStream( mxFactory, mxStorage, rElementName ) ); + xOutStream.set( new OleOutputStream( mxContext, mxStorage, rElementName ) ); return xOutStream; } diff --git a/oox/source/ole/vbacontrol.cxx b/oox/source/ole/vbacontrol.cxx index 39deb77576d9..45a2b9c70ee3 100644 --- a/oox/source/ole/vbacontrol.cxx +++ b/oox/source/ole/vbacontrol.cxx @@ -756,11 +756,11 @@ bool lclEatKeyword( OUString& rCodeLine, const OUString& rKeyword ) VbaUserForm::VbaUserForm( const Reference< XComponentContext >& rxContext, const Reference< XModel >& rxDocModel, const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr ) : - mxCompContext( rxContext ), + mxContext( rxContext ), mxDocModel( rxDocModel ), maConverter( rxDocModel, rGraphicHelper, bDefaultColorBgr ) { - OSL_ENSURE( mxCompContext.is(), "VbaUserForm::VbaUserForm - missing component context" ); + OSL_ENSURE( mxContext.is(), "VbaUserForm::VbaUserForm - missing component context" ); OSL_ENSURE( mxDocModel.is(), "VbaUserForm::VbaUserForm - missing document model" ); } @@ -768,7 +768,7 @@ void VbaUserForm::importForm( const Reference< XNameContainer >& rxDialogLib, StorageBase& rVbaFormStrg, const OUString& rModuleName, rtl_TextEncoding eTextEnc ) { OSL_ENSURE( rxDialogLib.is(), "VbaUserForm::importForm - missing dialog library" ); - if( !mxCompContext.is() || !mxDocModel.is() || !rxDialogLib.is() ) + if( !mxContext.is() || !mxDocModel.is() || !rxDialogLib.is() ) return; // check that the '03VBFrame' stream exists, this is required for forms @@ -778,7 +778,7 @@ void VbaUserForm::importForm( const Reference< XNameContainer >& rxDialogLib, return; // scan for the line 'Begin {GUID} <FormName>' - TextInputStream aFrameTextStrm( aInStrm, eTextEnc ); + TextInputStream aFrameTextStrm( mxContext, aInStrm, eTextEnc ); const OUString aBegin = CREATE_OUSTRING( "Begin" ); OUString aLine; bool bBeginFound = false; @@ -826,7 +826,7 @@ void VbaUserForm::importForm( const Reference< XNameContainer >& rxDialogLib, { // create the dialog model OUString aServiceName = mxCtrlModel->getServiceName(); - Reference< XMultiServiceFactory > xFactory( mxCompContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); Reference< XControlModel > xDialogModel( xFactory->createInstance( aServiceName ), UNO_QUERY_THROW ); Reference< XNameContainer > xDialogNC( xDialogModel, UNO_QUERY_THROW ); @@ -834,7 +834,7 @@ void VbaUserForm::importForm( const Reference< XNameContainer >& rxDialogLib, if( convertProperties( xDialogModel, maConverter, 0 ) ) { // export the dialog to XML and insert it into the dialog library - Reference< XInputStreamProvider > xDialogSource( ::xmlscript::exportDialogModel( xDialogNC, mxCompContext ), UNO_SET_THROW ); + Reference< XInputStreamProvider > xDialogSource( ::xmlscript::exportDialogModel( xDialogNC, mxContext ), UNO_SET_THROW ); OSL_ENSURE( !rxDialogLib->hasByName( aFormName ), "VbaUserForm::importForm - multiple dialogs with equal name" ); ContainerHelper::insertByName( rxDialogLib, aFormName, Any( xDialogSource ) ); } diff --git a/oox/source/ole/vbainputstream.cxx b/oox/source/ole/vbainputstream.cxx index e56e8b5fbc89..7e2c88dc480f 100644 --- a/oox/source/ole/vbainputstream.cxx +++ b/oox/source/ole/vbainputstream.cxx @@ -47,17 +47,38 @@ const sal_uInt16 VBACHUNK_LENMASK = 0x0FFF; // ============================================================================ VbaInputStream::VbaInputStream( BinaryInputStream& rInStrm ) : - mrInStrm( rInStrm ), + BinaryStreamBase( false ), + mpInStrm( &rInStrm ), mnChunkPos( 0 ) { maChunk.reserve( 4096 ); - sal_uInt8 nSig = mrInStrm.readuInt8(); + sal_uInt8 nSig = rInStrm.readuInt8(); OSL_ENSURE( nSig == VBASTREAM_SIGNATURE, "VbaInputStream::VbaInputStream - wrong signature" ); - mbEof = nSig != VBASTREAM_SIGNATURE; + mbEof = mbEof || rInStrm.isEof() || (nSig != VBASTREAM_SIGNATURE); } -sal_Int32 VbaInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes ) +sal_Int64 VbaInputStream::size() const +{ + return -1; +} + +sal_Int64 VbaInputStream::tell() const +{ + return -1; +} + +void VbaInputStream::seek( sal_Int64 ) +{ +} + +void VbaInputStream::close() +{ + mpInStrm = 0; + mbEof = true; +} + +sal_Int32 VbaInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nRet = 0; if( !mbEof ) @@ -65,7 +86,7 @@ sal_Int32 VbaInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes orData.realloc( ::std::max< sal_Int32 >( nBytes, 0 ) ); if( nBytes > 0 ) { - nRet = readMemory( orData.getArray(), nBytes ); + nRet = readMemory( orData.getArray(), nBytes, nAtomSize ); if( nRet < nBytes ) orData.realloc( nRet ); } @@ -73,7 +94,7 @@ sal_Int32 VbaInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes return nRet; } -sal_Int32 VbaInputStream::readMemory( void* opMem, sal_Int32 nBytes ) +sal_Int32 VbaInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t /*nAtomSize*/ ) { sal_Int32 nRet = 0; sal_uInt8* opnMem = reinterpret_cast< sal_uInt8* >( opMem ); @@ -90,7 +111,7 @@ sal_Int32 VbaInputStream::readMemory( void* opMem, sal_Int32 nBytes ) return nRet; } -void VbaInputStream::skip( sal_Int32 nBytes ) +void VbaInputStream::skip( sal_Int32 nBytes, size_t /*nAtomSize*/ ) { while( (nBytes > 0) && updateChunk() ) { @@ -108,8 +129,8 @@ bool VbaInputStream::updateChunk() if( mbEof || (mnChunkPos < maChunk.size()) ) return !mbEof; // try to read next chunk header, this may trigger EOF - sal_uInt16 nHeader = mrInStrm.readuInt16(); - mbEof = mrInStrm.isEof(); + sal_uInt16 nHeader = mpInStrm->readuInt16(); + mbEof = mpInStrm->isEof(); if( mbEof ) return false; // check header signature @@ -126,15 +147,15 @@ bool VbaInputStream::updateChunk() maChunk.clear(); sal_uInt8 nBitCount = 4; sal_uInt16 nChunkPos = 0; - while( !mbEof && !mrInStrm.isEof() && (nChunkPos < nChunkLen) ) + while( !mbEof && !mpInStrm->isEof() && (nChunkPos < nChunkLen) ) { - sal_uInt8 nTokenFlags = mrInStrm.readuInt8(); + sal_uInt8 nTokenFlags = mpInStrm->readuInt8(); ++nChunkPos; - for( int nBit = 0; !mbEof && !mrInStrm.isEof() && (nBit < 8) && (nChunkPos < nChunkLen); ++nBit, nTokenFlags >>= 1 ) + for( int nBit = 0; !mbEof && !mpInStrm->isEof() && (nBit < 8) && (nChunkPos < nChunkLen); ++nBit, nTokenFlags >>= 1 ) { if( nTokenFlags & 1 ) { - sal_uInt16 nCopyToken = mrInStrm.readuInt16(); + sal_uInt16 nCopyToken = mpInStrm->readuInt16(); nChunkPos = nChunkPos + 2; // update bit count used for offset/length in the token while( static_cast< size_t >( 1 << nBitCount ) < maChunk.size() ) ++nBitCount; @@ -164,7 +185,7 @@ bool VbaInputStream::updateChunk() else { maChunk.resize( maChunk.size() + 1 ); - mrInStrm >> maChunk.back(); + *mpInStrm >> maChunk.back(); ++nChunkPos; } } @@ -173,7 +194,7 @@ bool VbaInputStream::updateChunk() else { maChunk.resize( nChunkLen ); - mrInStrm.readMemory( &maChunk.front(), nChunkLen ); + mpInStrm->readMemory( &maChunk.front(), nChunkLen ); } mnChunkPos = 0; diff --git a/oox/source/ole/vbamodule.cxx b/oox/source/ole/vbamodule.cxx index 2da92b935004..628c2abb8441 100644 --- a/oox/source/ole/vbamodule.cxx +++ b/oox/source/ole/vbamodule.cxx @@ -54,7 +54,9 @@ using ::rtl::OUStringBuffer; // ============================================================================ -VbaModule::VbaModule( const Reference< XModel >& rxDocModel, const OUString& rName, rtl_TextEncoding eTextEnc, bool bExecutable ) : +VbaModule::VbaModule( const Reference< XComponentContext >& rxContext, const Reference< XModel >& rxDocModel, + const OUString& rName, rtl_TextEncoding eTextEnc, bool bExecutable ) : + mxContext( rxContext ), mxDocModel( rxDocModel ), maName( rName ), meTextEnc( eTextEnc ), @@ -161,7 +163,7 @@ OUString VbaModule::readSourceCode( StorageBase& rVbaStrg ) const // decompression starts at current stream position of aInStrm VbaInputStream aVbaStrm( aInStrm ); // load the source code line-by-line, with some more processing - TextInputStream aVbaTextStrm( aVbaStrm, meTextEnc ); + TextInputStream aVbaTextStrm( mxContext, aVbaStrm, meTextEnc ); while( !aVbaTextStrm.isEof() ) { OUString aCodeLine = aVbaTextStrm.readLine(); diff --git a/oox/source/ole/vbaproject.cxx b/oox/source/ole/vbaproject.cxx index 35e6b7911012..57979f6c72d4 100644 --- a/oox/source/ole/vbaproject.cxx +++ b/oox/source/ole/vbaproject.cxx @@ -155,11 +155,11 @@ void VbaMacroAttacherBase::resolveAndAttachMacro( const Reference< XVBAMacroReso VbaProject::VbaProject( const Reference< XComponentContext >& rxContext, const Reference< XModel >& rxDocModel, const OUString& rConfigCompName ) : VbaFilterConfig( rxContext, rConfigCompName ), - mxCompContext( rxContext ), + mxContext( rxContext ), mxDocModel( rxDocModel ), maPrjName( CREATE_OUSTRING( "Standard" ) ) { - OSL_ENSURE( mxCompContext.is(), "VbaProject::VbaProject - missing component context" ); + OSL_ENSURE( mxContext.is(), "VbaProject::VbaProject - missing component context" ); OSL_ENSURE( mxDocModel.is(), "VbaProject::VbaProject - missing document model" ); mxBasicLib = openLibrary( PROP_BasicLibraries, false ); mxDialogLib = openLibrary( PROP_DialogLibraries, false ); @@ -332,7 +332,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap OSL_ENSURE( aName.getLength() > 0, "VbaProject::importVba - invalid module name" ); OSL_ENSURE( !aModules.has( aName ), "VbaProject::importVba - multiple modules with the same name" ); VbaModuleMap::mapped_type& rxModule = aModules[ aName ]; - rxModule.reset( new VbaModule( mxDocModel, aName, eTextEnc, bExecutable ) ); + rxModule.reset( new VbaModule( mxContext, mxDocModel, aName, eTextEnc, bExecutable ) ); // read all remaining records until the MODULEEND record rxModule->importDirRecords( aDirStrm ); OSL_ENSURE( !aModulesByStrm.has( rxModule->getStreamName() ), "VbaProject::importVba - multiple modules with the same stream name" ); @@ -369,7 +369,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap // do not exit if this stream does not exist, but proceed to load the modules below if( !aPrjStrm.isEof() ) { - TextInputStream aPrjTextStrm( aPrjStrm, eTextEnc ); + TextInputStream aPrjTextStrm( mxContext, aPrjStrm, eTextEnc ); OUString aKey, aValue; bool bExitLoop = false; while( !bExitLoop && !aPrjTextStrm.isEof() ) @@ -413,7 +413,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap { OSL_ENSURE( !aModules.has( aIt->first ) && !aDummyModules.has( aIt->first ), "VbaProject::importVba - multiple modules with the same name" ); VbaModuleMap::mapped_type& rxModule = aDummyModules[ aIt->first ]; - rxModule.reset( new VbaModule( mxDocModel, aIt->first, eTextEnc, bExecutable ) ); + rxModule.reset( new VbaModule( mxContext, mxDocModel, aIt->first, eTextEnc, bExecutable ) ); rxModule->setType( aIt->second ); } @@ -489,7 +489,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap // create and import the form Reference< XNameContainer > xDialogLib( createDialogLibrary(), UNO_SET_THROW ); - VbaUserForm aForm( mxCompContext, mxDocModel, rGraphicHelper, bDefaultColorBgr ); + VbaUserForm aForm( mxContext, mxDocModel, rGraphicHelper, bDefaultColorBgr ); aForm.importForm( xDialogLib, *xSubStrg, aModuleName, eTextEnc ); } catch( Exception& ) @@ -506,14 +506,14 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap void VbaProject::attachMacros() { - if( !maMacroAttachers.empty() && mxCompContext.is() ) try + if( !maMacroAttachers.empty() && mxContext.is() ) try { - Reference< XMultiComponentFactory > xFactory( mxCompContext->getServiceManager(), UNO_SET_THROW ); + Reference< XMultiComponentFactory > xFactory( mxContext->getServiceManager(), UNO_SET_THROW ); Sequence< Any > aArgs( 2 ); aArgs[ 0 ] <<= mxDocModel; aArgs[ 1 ] <<= maPrjName; Reference< XVBAMacroResolver > xResolver( xFactory->createInstanceWithArgumentsAndContext( - CREATE_OUSTRING( "com.sun.star.script.vba.VBAMacroResolver" ), aArgs, mxCompContext ), UNO_QUERY_THROW ); + CREATE_OUSTRING( "com.sun.star.script.vba.VBAMacroResolver" ), aArgs, mxContext ), UNO_QUERY_THROW ); maMacroAttachers.forEachMem( &VbaMacroAttacherBase::resolveAndAttachMacro, ::boost::cref( xResolver ) ); } catch( Exception& ) @@ -523,15 +523,14 @@ void VbaProject::attachMacros() void VbaProject::copyStorage( StorageBase& rVbaPrjStrg ) { - if( mxCompContext.is() ) try + if( mxContext.is() ) try { - Reference< XMultiServiceFactory > xFactory( mxCompContext->getServiceManager(), UNO_QUERY_THROW ); Reference< XStorageBasedDocument > xStorageBasedDoc( mxDocModel, UNO_QUERY_THROW ); Reference< XStorage > xDocStorage( xStorageBasedDoc->getDocumentStorage(), UNO_QUERY_THROW ); { - using namespace ::com::sun::star::embed::ElementModes; - Reference< XStream > xDocStream( xDocStorage->openStreamElement( CREATE_OUSTRING( "_MS_VBA_Macros" ), SEEKABLE | WRITE | TRUNCATE ), UNO_SET_THROW ); - OleStorage aDestStorage( xFactory, xDocStream, false ); + const sal_Int32 nOpenMode = ElementModes::SEEKABLE | ElementModes::WRITE | ElementModes::TRUNCATE; + Reference< XStream > xDocStream( xDocStorage->openStreamElement( CREATE_OUSTRING( "_MS_VBA_Macros" ), nOpenMode ), UNO_SET_THROW ); + OleStorage aDestStorage( mxContext, xDocStream, false ); rVbaPrjStrg.copyStorageToStorage( aDestStorage ); aDestStorage.commit(); } diff --git a/oox/source/vml/vmldrawing.cxx b/oox/source/vml/vmldrawing.cxx index ccf0fe567235..44eb8106ee8e 100644 --- a/oox/source/vml/vmldrawing.cxx +++ b/oox/source/vml/vmldrawing.cxx @@ -214,8 +214,8 @@ Reference< XShape > Drawing::createAndInsertXShape( const OUString& rService, Reference< XShape > xShape; if( (rService.getLength() > 0) && rxShapes.is() ) try { - Reference< XMultiServiceFactory > xFactory( mrFilter.getModelFactory(), UNO_SET_THROW ); - xShape.set( xFactory->createInstance( rService ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xModelFactory( mrFilter.getModelFactory(), UNO_SET_THROW ); + xShape.set( xModelFactory->createInstance( rService ), UNO_QUERY_THROW ); // insert shape into passed shape collection (maybe drawpage or group shape) rxShapes->add( xShape ); xShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) ); diff --git a/oox/source/vml/vmldrawingfragment.cxx b/oox/source/vml/vmldrawingfragment.cxx index dc5c82515691..591e85482448 100644 --- a/oox/source/vml/vmldrawingfragment.cxx +++ b/oox/source/vml/vmldrawingfragment.cxx @@ -27,6 +27,7 @@ #include "oox/vml/vmldrawingfragment.hxx" +#include "oox/core/xmlfilterbase.hxx" #include "oox/vml/vmldrawing.hxx" #include "oox/vml/vmlinputstream.hxx" #include "oox/vml/vmlshapecontext.hxx" @@ -53,7 +54,7 @@ DrawingFragment::DrawingFragment( XmlFilterBase& rFilter, const OUString& rFragm Reference< XInputStream > DrawingFragment::openFragmentStream() const { // #i104719# create an input stream that preprocesses the VML data - return new InputStream( FragmentHandler2::openFragmentStream() ); + return new InputStream( getFilter().getComponentContext(), FragmentHandler2::openFragmentStream() ); } ContextHandlerRef DrawingFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) diff --git a/oox/source/vml/vmlinputstream.cxx b/oox/source/vml/vmlinputstream.cxx index fb2443aba4c4..ef2f408d79b0 100644 --- a/oox/source/vml/vmlinputstream.cxx +++ b/oox/source/vml/vmlinputstream.cxx @@ -27,10 +27,12 @@ #include "oox/vml/vmlinputstream.hxx" +#include <com/sun/star/io/XTextInputStream.hpp> #include <map> -#include <rtl/strbuf.hxx> +#include <string.h> #include <rtl/strbuf.hxx> #include "oox/helper/helper.hxx" +#include "oox/helper/textinputstream.hxx" namespace oox { namespace vml { @@ -55,7 +57,7 @@ inline const sal_Char* lclFindCharacter( const sal_Char* pcBeg, const sal_Char* inline bool lclIsWhiteSpace( sal_Char cChar ) { - return (cChar == ' ') || (cChar == '\t') || (cChar == '\n') || (cChar == '\r'); + return cChar < 32; } const sal_Char* lclFindWhiteSpace( const sal_Char* pcBeg, const sal_Char* pcEnd ) @@ -151,14 +153,78 @@ void lclProcessAttribs( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sal lclAppendToBuffer( rBuffer, pcBeg, pcEnd ); } -void lclProcessContents( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sal_Char* pcEnd ) +void lclProcessElement( OStringBuffer& rBuffer, const OString& rElement ) +{ + // check that passed string starts and ends with the brackets of an XML element + sal_Int32 nElementLen = rElement.getLength(); + if( nElementLen == 0 ) + return; + + const sal_Char* pcOpen = rElement.getStr(); + const sal_Char* pcClose = pcOpen + nElementLen - 1; + + // no complete element found + if( (pcOpen >= pcClose) || (*pcOpen != '<') || (*pcClose != '>') ) + { + // just append all passed characters + rBuffer.append( rElement ); + } + + // skip parser instructions: '<![...]>' + else if( (nElementLen >= 5) && (pcOpen[ 1 ] == '!') && (pcOpen[ 2 ] == '[') && (pcClose[ -1 ] == ']') ) + { + // do nothing + } + + // replace '<br>' element with newline + else if( (nElementLen >= 4) && (pcOpen[ 1 ] == 'b') && (pcOpen[ 2 ] == 'r') && (lclFindNonWhiteSpace( pcOpen + 3, pcClose ) == pcClose) ) + { + rBuffer.append( '\n' ); + } + + // check start elements and simple elements for repeated attributes + else if( pcOpen[ 1 ] != '/' ) + { + // find positions of text content inside brackets, exclude '/' in '<simpleelement/>' + const sal_Char* pcContentBeg = pcOpen + 1; + bool bIsEmptyElement = pcClose[ -1 ] == '/'; + const sal_Char* pcContentEnd = bIsEmptyElement ? (pcClose - 1) : pcClose; + // append opening bracket and element name to buffer + const sal_Char* pcWhiteSpace = lclFindWhiteSpace( pcContentBeg, pcContentEnd ); + lclAppendToBuffer( rBuffer, pcOpen, pcWhiteSpace ); + // find begin of attributes, and process all attributes + const sal_Char* pcAttribBeg = lclFindNonWhiteSpace( pcWhiteSpace, pcContentEnd ); + if( pcAttribBeg < pcContentEnd ) + lclProcessAttribs( rBuffer, pcAttribBeg, pcContentEnd ); + // close the element + if( bIsEmptyElement ) + rBuffer.append( '/' ); + rBuffer.append( '>' ); + } + + // append end elements without further processing + else + { + rBuffer.append( rElement ); + } +} + +bool lclProcessCharacters( OStringBuffer& rBuffer, const OString& rChars ) { /* MSO has a very weird way to store and handle whitespaces. The stream may contain lots of spaces, tabs, and newlines which have to be handled as single space character. This will be done in this function. If the element text contains a literal line break, it will be stored as - <br> tag (without matching closing </br> element). + <br> tag (without matching </br> element). This input stream wrapper + will replace this element with a literal LF character (see below). + + A single space character for its own is stored as is. Example: The + element + <font> </font> + represents a single space character. The XML parser will ignore this + space character completely without issuing a 'characters' event. The + VML import filter implementation has to react on this case manually. A single space character following another character is stored literally and must not be stipped away here. Example: The element @@ -167,20 +233,23 @@ void lclProcessContents( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sa Consecutive space characters, or a leading single space character, are stored in a <span> element. If there are N space characters (N > 1), - then the <span> element contains exactly (N-1) NBSP characters - (non-breaking space), followed by a regular space character. Example: + then the <span> element contains exactly (N-1) NBSP (non-breaking + space) characters, followed by a regular space character. Examples: The element <font><span style='mso-spacerun:yes'>\xA0\xA0\xA0 </span></font> represents 4 consecutive space characters. Has to be handled by the - implementation. - - A single space character for its own is stored in an empty element. - Example: The element - <font></font> - represents a single space character. Has to be handled by the - implementation. + implementation. The element + <font><span style='mso-spacerun:yes'> abc</span></font> + represents a space characters followed by the letters a, b, c. These + strings have to be handled by the VML import filter implementation. */ + // passed string ends with the leading opening bracket of an XML element + const sal_Char* pcBeg = rChars.getStr(); + const sal_Char* pcEnd = pcBeg + rChars.getLength(); + bool bHasBracket = (pcBeg < pcEnd) && (pcEnd[ -1 ] == '<'); + if( bHasBracket ) --pcEnd; + // skip leading whitespace const sal_Char* pcContentsBeg = lclFindNonWhiteSpace( pcBeg, pcEnd ); while( pcContentsBeg < pcEnd ) @@ -191,132 +260,139 @@ void lclProcessContents( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sa rBuffer.append( ' ' ); pcContentsBeg = lclFindNonWhiteSpace( pcWhitespaceBeg, pcEnd ); } + + return bHasBracket; } } // namespace // ============================================================================ -StreamDataContainer::StreamDataContainer( const Reference< XInputStream >& rxInStrm ) +InputStream::InputStream( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm ) : + // use single-byte ISO-8859-1 encoding which maps all byte characters to the first 256 Unicode characters + mxTextStrm( TextInputStream::createXTextInputStream( rxContext, rxInStrm, RTL_TEXTENCODING_ISO_8859_1 ) ), + maOpeningBracket( 1 ), + maClosingBracket( 1 ), + maOpeningCData( CREATE_OSTRING( "<![CDATA[" ) ), + maClosingCData( CREATE_OSTRING( "]]>" ) ), + mnBufferPos( 0 ) { - if( rxInStrm.is() ) try + maOpeningBracket[ 0 ] = '<'; + maClosingBracket[ 0 ] = '>'; +} + +InputStream::~InputStream() +{ +} + +sal_Int32 SAL_CALL InputStream::readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + if( nBytesToRead < 0 ) + throw IOException(); + + rData.realloc( nBytesToRead ); + sal_Int8* pcDest = rData.getArray(); + sal_Int32 nRet = 0; + while( (nBytesToRead > 0) && !mxTextStrm->isEOF() ) { - // read all bytes we can read - rxInStrm->readBytes( maDataSeq, SAL_MAX_INT32 ); + updateBuffer(); + sal_Int32 nReadSize = ::std::min( nBytesToRead, maBuffer.getLength() - mnBufferPos ); + if( nReadSize > 0 ) + { + memcpy( pcDest + nRet, maBuffer.getStr() + mnBufferPos, static_cast< size_t >( nReadSize ) ); + mnBufferPos += nReadSize; + nBytesToRead -= nReadSize; + nRet += nReadSize; + } } - catch( Exception& ) + if( nRet < rData.getLength() ) + rData.realloc( nRet ); + return nRet; +} + +sal_Int32 SAL_CALL InputStream::readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + return readBytes( rData, nMaxBytesToRead ); +} + +void SAL_CALL InputStream::skipBytes( sal_Int32 nBytesToSkip ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + if( nBytesToSkip < 0 ) + throw IOException(); + + while( (nBytesToSkip > 0) && !mxTextStrm->isEOF() ) { + updateBuffer(); + sal_Int32 nSkipSize = ::std::min( nBytesToSkip, maBuffer.getLength() - mnBufferPos ); + mnBufferPos += nSkipSize; + nBytesToSkip -= nSkipSize; } +} - if( maDataSeq.hasElements() ) - { - const OString aCDataOpen = CREATE_OSTRING( "<![CDATA[" ); - const OString aCDataClose = CREATE_OSTRING( "]]>" ); +sal_Int32 SAL_CALL InputStream::available() throw (NotConnectedException, IOException, RuntimeException) +{ + updateBuffer(); + return maBuffer.getLength() - mnBufferPos; +} - OStringBuffer aBuffer; - aBuffer.ensureCapacity( maDataSeq.getLength() + 256 ); - const sal_Char* pcCurr = reinterpret_cast< const sal_Char* >( maDataSeq.getConstArray() ); - const sal_Char* pcEnd = pcCurr + maDataSeq.getLength(); - while( pcCurr < pcEnd ) - { - // look for the next opening angle bracket - const sal_Char* pcOpen = lclFindCharacter( pcCurr, pcEnd, '<' ); +void SAL_CALL InputStream::closeInput() throw (NotConnectedException, IOException, RuntimeException) +{ + mxTextStrm->closeInput(); +} - // copy all characters from current position to opening bracket - lclProcessContents( aBuffer, pcCurr, pcOpen ); +// private -------------------------------------------------------------------- - // nothing to do if no opening bracket has been found - if( pcOpen < pcEnd ) - { - // string length from opening bracket to end - sal_Int32 nLengthToEnd = static_cast< sal_Int32 >( pcEnd - pcOpen ); +void InputStream::updateBuffer() throw (IOException, RuntimeException) +{ + while( (mnBufferPos >= maBuffer.getLength()) && !mxTextStrm->isEOF() ) + { + // collect new contents in a string buffer + OStringBuffer aBuffer; - // check for CDATA part, starting with '<![CDATA[' - if( rtl_str_compare_WithLength( pcOpen, nLengthToEnd, aCDataOpen.getStr(), aCDataOpen.getLength() ) == 0 ) - { - // search the position after the end tag ']]>' - sal_Int32 nClosePos = rtl_str_indexOfStr_WithLength( pcOpen, nLengthToEnd, aCDataClose.getStr(), aCDataClose.getLength() ); - pcCurr = (nClosePos < 0) ? pcEnd : (pcOpen + nClosePos + aCDataClose.getLength()); - // copy the entire CDATA part - lclAppendToBuffer( aBuffer, pcOpen, pcCurr ); - } + // read and process characters until the opening bracket of the next XML element + OString aChars = readToElementBegin(); + bool bHasOpeningBracket = lclProcessCharacters( aBuffer, aChars ); - // no CDATA part - process the element starting at pcOpen - else - { - // look for the next closing angle bracket - const sal_Char* pcClose = lclFindCharacter( pcOpen + 1, pcEnd, '>' ); - // complete element found? - if( pcClose < pcEnd ) - { - // continue after closing bracket - pcCurr = pcClose + 1; - // length of entire element with angle brackets - sal_Int32 nElementLen = static_cast< sal_Int32 >( pcCurr - pcOpen ); - - // skip parser instructions: '<![...]>' - if( (nElementLen >= 5) && (pcOpen[ 1 ] == '!') && (pcOpen[ 2 ] == '[') && (pcClose[ -1 ] == ']') ) - { - // do nothing - } - - // replace '<br>' element with newline - else if( (nElementLen >= 4) && (pcOpen[ 1 ] == 'b') && (pcOpen[ 2 ] == 'r') && (lclFindNonWhiteSpace( pcOpen + 3, pcClose ) == pcClose) ) - { - aBuffer.append( '\n' ); - } - - // check start elements and empty elements for repeated attributes - else if( pcOpen[ 1 ] != '/' ) - { - // find positions of text content inside brackets, exclude '/' in '<emptyelement/>' - const sal_Char* pcContentBeg = pcOpen + 1; - bool bIsEmptyElement = pcClose[ -1 ] == '/'; - const sal_Char* pcContentEnd = bIsEmptyElement ? (pcClose - 1) : pcClose; - // append element name to buffer - const sal_Char* pcWhiteSpace = lclFindWhiteSpace( pcContentBeg, pcContentEnd ); - lclAppendToBuffer( aBuffer, pcOpen, pcWhiteSpace ); - // find begin of attributes, and process all attributes - const sal_Char* pcAttribBeg = lclFindNonWhiteSpace( pcWhiteSpace, pcContentEnd ); - if( pcAttribBeg < pcContentEnd ) - lclProcessAttribs( aBuffer, pcAttribBeg, pcContentEnd ); - // close the element - if( bIsEmptyElement ) - aBuffer.append( '/' ); - aBuffer.append( '>' ); - } - - // append end elements without further processing - else - { - lclAppendToBuffer( aBuffer, pcOpen, pcCurr ); - } - } - else - { - // no complete element found, copy all from opening bracket to end - lclAppendToBuffer( aBuffer, pcOpen, pcEnd ); - pcCurr = pcEnd; - } - } + // read and process characters until (and including) closing bracket (an XML element) + OSL_ENSURE( bHasOpeningBracket || mxTextStrm->isEOF(), "InputStream::updateBuffer - missing opening bracket of XML element" ); + if( bHasOpeningBracket && !mxTextStrm->isEOF() ) + { + // read the element text (add the leading opening bracket manually) + OString aElement = OString( '<' ) + readToElementEnd(); + // check for CDATA part, starting with '<![CDATA[' + if( aElement.match( maOpeningCData ) ) + { + // search the end tag ']]>' + while( ((aElement.getLength() < maClosingCData.getLength()) || !aElement.match( maClosingCData, aElement.getLength() - maClosingCData.getLength() )) && !mxTextStrm->isEOF() ) + aElement += readToElementEnd(); + // copy the entire CDATA part + aBuffer.append( aElement ); + } + else + { + // no CDATA part - process the contents of the element + lclProcessElement( aBuffer, aElement ); } } - // set the final data sequence - maDataSeq = ::comphelper::ByteSequence( reinterpret_cast< const sal_Int8* >( aBuffer.getStr() ), aBuffer.getLength() ); + maBuffer = aBuffer.makeStringAndClear(); + mnBufferPos = 0; } } -// ============================================================================ - -InputStream::InputStream( const Reference< XInputStream >& rxInStrm ) : - StreamDataContainer( rxInStrm ), - ::comphelper::SequenceInputStream( maDataSeq ) +OString InputStream::readToElementBegin() throw (IOException, RuntimeException) { + return OUStringToOString( mxTextStrm->readString( maOpeningBracket, sal_False ), RTL_TEXTENCODING_ISO_8859_1 ); } -InputStream::~InputStream() +OString InputStream::readToElementEnd() throw (IOException, RuntimeException) { + OString aText = OUStringToOString( mxTextStrm->readString( maClosingBracket, sal_False ), RTL_TEXTENCODING_ISO_8859_1 ); + OSL_ENSURE( (aText.getLength() > 0) && (aText[ aText.getLength() - 1 ] == '>'), "InputStream::readToElementEnd - missing closing bracket of XML element" ); + return aText; } // ============================================================================ diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx index d266e054691f..5e1a9a8d3e1d 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -274,9 +274,10 @@ Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxS xShape = implConvertAndInsert( rxShapes, aShapeRect ); if( xShape.is() ) { - // set shape name (imported or generated) + // set imported or generated shape name (not supported by form controls) PropertySet aShapeProp( xShape ); - aShapeProp.setProperty( PROP_Name, getShapeName() ); + if( aShapeProp.hasProperty( PROP_Name ) ) + aShapeProp.setProperty( PROP_Name, getShapeName() ); /* Notify the drawing that a new shape has been inserted. For convenience, pass the rectangle that contains position and diff --git a/oox/source/vml/vmltextboxcontext.cxx b/oox/source/vml/vmltextboxcontext.cxx index 4b57656b4f78..6feae68127e7 100755 --- a/oox/source/vml/vmltextboxcontext.cxx +++ b/oox/source/vml/vmltextboxcontext.cxx @@ -75,6 +75,8 @@ TextPortionContext::TextPortionContext( ContextHandler2Helper& rParent, OSL_ENSURE( !maFont.mobStrikeout, "TextPortionContext::TextPortionContext - nested <s> elements" ); maFont.mobStrikeout = true; break; + case XML_span: + break; default: OSL_ENSURE( false, "TextPortionContext::TextPortionContext - unknown element" ); } @@ -92,7 +94,7 @@ void TextPortionContext::onCharacters( const OUString& rChars ) { case XML_span: // replace all NBSP characters with SP - mrTextBox.appendPortion( maFont, rChars.replace( 160, ' ' ) ); + mrTextBox.appendPortion( maFont, rChars.replace( 0xA0, ' ' ) ); break; default: mrTextBox.appendPortion( maFont, rChars ); @@ -101,19 +103,23 @@ void TextPortionContext::onCharacters( const OUString& rChars ) void TextPortionContext::onEndElement() { - /* An empty child element without own child elements represents a single - space character, for example: + /* A child element without own child elements may contain a single space + character, for example: - <font> - <i>abc</i> - <font></font> - <b>def</b> - </font> + <div> + <font><i>abc</i></font> + <font> </font> + <font><b>def</b></font> + </div> represents the italic text 'abc', an unformatted space character, and - the bold text 'def'. + the bold text 'def'. Unfortunately, the XML parser skips the space + character without issuing a 'characters' event. The class member + 'mnInitialPortions' contains the number of text portions existing when + this context has been constructed. If no text has been added in the + meantime, the space character has to be added manually. */ - if( (mnInitialPortions > 0) && (mrTextBox.getPortionCount() == mnInitialPortions) ) + if( mrTextBox.getPortionCount() == mnInitialPortions ) mrTextBox.appendPortion( maFont, OUString( sal_Unicode( ' ' ) ) ); } @@ -143,4 +149,3 @@ ContextHandlerRef TextBoxContext::onCreateContext( sal_Int32 nElement, const Att } // namespace vml } // namespace oox - diff --git a/oox/source/xls/addressconverter.cxx b/oox/source/xls/addressconverter.cxx index 6d53be0c155b..ca216bb8a84f 100644 --- a/oox/source/xls/addressconverter.cxx +++ b/oox/source/xls/addressconverter.cxx @@ -98,12 +98,12 @@ const sal_Unicode BIFF_DCON_ENCODED = '\x01'; /// First character of an en const sal_Unicode BIFF_DCON_INTERN = '\x02'; /// First character of an encoded sheet name from DCON* records. -inline sal_uInt16 lclGetBiffAddressSize( bool bCol16Bit, bool bRow32Bit ) +inline sal_uInt8 lclGetBiffAddressSize( bool bCol16Bit, bool bRow32Bit ) { return (bCol16Bit ? 2 : 1) + (bRow32Bit ? 4 : 2); } -inline sal_uInt16 lclGetBiffRangeSize( bool bCol16Bit, bool bRow32Bit ) +inline sal_uInt8 lclGetBiffRangeSize( bool bCol16Bit, bool bRow32Bit ) { return 2 * lclGetBiffAddressSize( bCol16Bit, bRow32Bit ); } diff --git a/oox/source/xls/biffdetector.cxx b/oox/source/xls/biffdetector.cxx index 038d7d732425..9c8267f8d84d 100644 --- a/oox/source/xls/biffdetector.cxx +++ b/oox/source/xls/biffdetector.cxx @@ -82,14 +82,14 @@ BiffDetector::~BiffDetector() /*static*/ BiffType BiffDetector::detectStreamBiffVersion( BinaryInputStream& rInStream ) { BiffType eBiff = BIFF_UNKNOWN; - if( !rInStream.isEof() && rInStream.isSeekable() && (rInStream.getLength() > 4) ) + if( !rInStream.isEof() && rInStream.isSeekable() && (rInStream.size() > 4) ) { sal_Int64 nOldPos = rInStream.tell(); rInStream.seekToStart(); sal_uInt16 nBofId, nBofSize; rInStream >> nBofId >> nBofSize; - if( (4 <= nBofSize) && (nBofSize <= 16) && (rInStream.tell() + nBofSize <= rInStream.getLength()) ) + if( (4 <= nBofSize) && (nBofSize <= 16) && (rInStream.tell() + nBofSize <= rInStream.size()) ) { switch( nBofId ) { @@ -207,9 +207,8 @@ OUString SAL_CALL BiffDetector::detect( Sequence< PropertyValue >& rDescriptor ) MediaDescriptor aDescriptor( rDescriptor ); aDescriptor.addInputStream(); - Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); Reference< XInputStream > xInStrm( aDescriptor[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY_THROW ); - StorageRef xStorage( new ::oox::ole::OleStorage( xFactory, xInStrm, true ) ); + StorageRef xStorage( new ::oox::ole::OleStorage( mxContext, xInStrm, true ) ); OUString aWorkbookName; switch( detectStorageBiffVersion( aWorkbookName, xStorage ) ) diff --git a/oox/source/xls/biffhelper.cxx b/oox/source/xls/biffhelper.cxx index 55839043865e..b4a3a982b50c 100644 --- a/oox/source/xls/biffhelper.cxx +++ b/oox/source/xls/biffhelper.cxx @@ -269,7 +269,7 @@ void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm, // BIFF12 import -------------------------------------------------------------- -/*static*/ OUString BiffHelper::readString( SequenceInputStream& rStrm, bool b32BitLen ) +/*static*/ OUString BiffHelper::readString( SequenceInputStream& rStrm, bool b32BitLen, bool bAllowNulChars ) { OUString aString; if( !rStrm.isEof() ) @@ -279,16 +279,9 @@ void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm, OSL_ENSURE( !rStrm.isEof() && (nCharCount >= -1), "BiffHelper::readString - invalid string length" ); if( !rStrm.isEof() && (nCharCount > 0) ) { - ::std::vector< sal_Unicode > aBuffer; - aBuffer.reserve( getLimitedValue< size_t, sal_Int32 >( nCharCount + 1, 0, 0xFFFF ) ); - for( sal_Int32 nCharIdx = 0; !rStrm.isEof() && (nCharIdx < nCharCount); ++nCharIdx ) - { - sal_uInt16 nChar; - rStrm.readValue( nChar ); - aBuffer.push_back( static_cast< sal_Unicode >( nChar ) ); - } - aBuffer.push_back( 0 ); - aString = OUString( &aBuffer.front() ); + // SequenceInputStream always supports getRemaining() + nCharCount = ::std::min( nCharCount, static_cast< sal_Int32 >( rStrm.getRemaining() / 2 ) ); + aString = rStrm.readUnicodeArray( nCharCount, bAllowNulChars ); } } return aString; diff --git a/oox/source/xls/biffinputstream.cxx b/oox/source/xls/biffinputstream.cxx index 6dfa8f755c25..b11137aab6b9 100644 --- a/oox/source/xls/biffinputstream.cxx +++ b/oox/source/xls/biffinputstream.cxx @@ -87,7 +87,7 @@ void BiffInputRecordBuffer::enableDecoder( bool bEnable ) bool BiffInputRecordBuffer::startRecord( sal_Int64 nHeaderPos ) { - mbValidHeader = (0 <= nHeaderPos) && (nHeaderPos + 4 <= mrInStrm.getLength()); + mbValidHeader = (0 <= nHeaderPos) && (nHeaderPos + 4 <= mrInStrm.size()); if( mbValidHeader ) { mnHeaderPos = nHeaderPos; @@ -95,7 +95,7 @@ bool BiffInputRecordBuffer::startRecord( sal_Int64 nHeaderPos ) mrInStrm >> mnRecId >> mnRecSize; mnBodyPos = mrInStrm.tell(); mnNextHeaderPos = mnBodyPos + mnRecSize; - mbValidHeader = !mrInStrm.isEof() && (mnNextHeaderPos <= mrInStrm.getLength()); + mbValidHeader = !mrInStrm.isEof() && (mnNextHeaderPos <= mrInStrm.size()); } if( !mbValidHeader ) { @@ -116,7 +116,7 @@ bool BiffInputRecordBuffer::startNextRecord() sal_uInt16 BiffInputRecordBuffer::getNextRecId() { sal_uInt16 nRecId = BIFF_ID_UNKNOWN; - if( mbValidHeader && (mnNextHeaderPos + 4 <= mrInStrm.getLength()) ) + if( mbValidHeader && (mnNextHeaderPos + 4 <= mrInStrm.size()) ) { mrInStrm.seek( mnNextHeaderPos ); mrInStrm >> nRecId; @@ -169,6 +169,7 @@ void BiffInputRecordBuffer::updateDecoded() // ============================================================================ BiffInputStream::BiffInputStream( BinaryInputStream& rInStream, bool bContLookup ) : + BinaryStreamBase( true ), maRecBuffer( rInStream ), mnRecHandle( -1 ), mnRecId( BIFF_ID_UNKNOWN ), @@ -257,9 +258,11 @@ sal_uInt16 BiffInputStream::getNextRecId() // BinaryStreamBase interface (seeking) --------------------------------------- -bool BiffInputStream::isSeekable() const +sal_Int64 BiffInputStream::size() const { - return true; + if( !mbHasComplRec ) + const_cast< BiffInputStream* >( this )->calcRecordLength(); + return mnComplRecSize; } sal_Int64 BiffInputStream::tell() const @@ -267,13 +270,6 @@ sal_Int64 BiffInputStream::tell() const return mbEof ? -1 : (mnCurrRecSize - maRecBuffer.getRecLeft()); } -sal_Int64 BiffInputStream::getLength() const -{ - if( !mbHasComplRec ) - const_cast< BiffInputStream* >( this )->calcRecordLength(); - return mnComplRecSize; -} - void BiffInputStream::seek( sal_Int64 nRecPos ) { if( isInRecord() ) @@ -285,35 +281,35 @@ void BiffInputStream::seek( sal_Int64 nRecPos ) } } +void BiffInputStream::close() +{ +} + sal_Int64 BiffInputStream::tellBase() const { return maRecBuffer.getBaseStream().tell(); } -sal_Int64 BiffInputStream::getBaseLength() const +sal_Int64 BiffInputStream::sizeBase() const { - return maRecBuffer.getBaseStream().getLength(); + return maRecBuffer.getBaseStream().size(); } // BinaryInputStream interface (stream read access) --------------------------- -sal_Int32 BiffInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes ) +sal_Int32 BiffInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nRet = 0; if( !mbEof ) { orData.realloc( ::std::max< sal_Int32 >( nBytes, 0 ) ); if( nBytes > 0 ) - { - nRet = readMemory( orData.getArray(), nBytes ); - if( nRet < nBytes ) - orData.realloc( nRet ); - } + nRet = readMemory( orData.getArray(), nBytes, nAtomSize ); } return nRet; } -sal_Int32 BiffInputStream::readMemory( void* opMem, sal_Int32 nBytes ) +sal_Int32 BiffInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nRet = 0; if( !mbEof && opMem && (nBytes > 0) ) @@ -323,7 +319,7 @@ sal_Int32 BiffInputStream::readMemory( void* opMem, sal_Int32 nBytes ) while( !mbEof && (nBytesLeft > 0) ) { - sal_uInt16 nReadSize = getMaxRawReadSize( nBytesLeft ); + sal_uInt16 nReadSize = getMaxRawReadSize( nBytesLeft, nAtomSize ); // check nReadSize, stream may already be located at end of a raw record if( nReadSize > 0 ) { @@ -340,12 +336,12 @@ sal_Int32 BiffInputStream::readMemory( void* opMem, sal_Int32 nBytes ) return nRet; } -void BiffInputStream::skip( sal_Int32 nBytes ) +void BiffInputStream::skip( sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nBytesLeft = nBytes; while( !mbEof && (nBytesLeft > 0) ) { - sal_uInt16 nSkipSize = getMaxRawReadSize( nBytesLeft ); + sal_uInt16 nSkipSize = getMaxRawReadSize( nBytesLeft, nAtomSize ); // check nSkipSize, stream may already be located at end of a raw record if( nSkipSize > 0 ) { @@ -383,28 +379,22 @@ OUString BiffInputStream::readUniStringChars( sal_uInt16 nChars, bool b16BitChar OUStringBuffer aBuffer; aBuffer.ensureCapacity( nChars ); - /* This function has to react on CONTINUE records to read the repeated - flags field, so readUnicodeArray() cannot be used here. */ - sal_uInt16 nCharsLeft = nChars; + /* This function has to react on CONTINUE records which repeat the flags + field in their first byte and may change the 8bit/16bit character mode, + thus a plain call to readCompressedUnicodeArray() cannot be used here. */ + sal_Int32 nCharsLeft = nChars; while( !mbEof && (nCharsLeft > 0) ) { - sal_uInt16 nPortionCount = 0; - if( b16BitChars ) - { - nPortionCount = ::std::min< sal_uInt16 >( nCharsLeft, maRecBuffer.getRecLeft() / 2 ); - OSL_ENSURE( (nPortionCount <= nCharsLeft) || ((maRecBuffer.getRecLeft() & 1) == 0), - "BiffInputStream::readUniStringChars - missing a byte" ); - } - else - { - nPortionCount = getMaxRawReadSize( nCharsLeft ); - } - - // read the character array - appendUnicodeArray( aBuffer, nPortionCount, b16BitChars, bAllowNulChars ); - - // prepare for next CONTINUE record - nCharsLeft = nCharsLeft - nPortionCount; + /* Read the character array from the remaining part of the current raw + record. First, calculate the maximum number of characters that can + be read without triggering to start a following CONTINUE record. */ + sal_Int32 nRawChars = b16BitChars ? (getMaxRawReadSize( nCharsLeft * 2, 2 ) / 2) : getMaxRawReadSize( nCharsLeft, 1 ); + aBuffer.append( readCompressedUnicodeArray( nRawChars, !b16BitChars, bAllowNulChars ) ); + + /* Prepare for next CONTINUE record. Calling jumpToNextStringContinue() + reads the leading byte in the following CONTINUE record and updates + the b16BitChars flag. */ + nCharsLeft -= nRawChars; if( nCharsLeft > 0 ) jumpToNextStringContinue( b16BitChars ); } @@ -429,25 +419,15 @@ OUString BiffInputStream::readUniString( bool bAllowNulChars ) void BiffInputStream::skipUniStringChars( sal_uInt16 nChars, bool b16BitChars ) { - sal_uInt16 nCharsLeft = nChars; + sal_Int32 nCharsLeft = nChars; while( !mbEof && (nCharsLeft > 0) ) { - sal_uInt16 nPortionCount; - if( b16BitChars ) - { - nPortionCount = ::std::min< sal_uInt16 >( nCharsLeft, maRecBuffer.getRecLeft() / 2 ); - OSL_ENSURE( (nPortionCount <= nCharsLeft) || ((maRecBuffer.getRecLeft() & 1) == 0), - "BiffInputStream::skipUniStringChars - missing a byte" ); - skip( 2 * nPortionCount ); - } - else - { - nPortionCount = getMaxRawReadSize( nCharsLeft ); - skip( nPortionCount ); - } + // skip the character array + sal_Int32 nSkipSize = b16BitChars ? getMaxRawReadSize( 2 * nCharsLeft, 2 ) : getMaxRawReadSize( nCharsLeft, 1 ); + skip( nSkipSize ); // prepare for next CONTINUE record - nCharsLeft = nCharsLeft - nPortionCount; + nCharsLeft -= (b16BitChars ? (nSkipSize / 2) : nSkipSize); if( nCharsLeft > 0 ) jumpToNextStringContinue( b16BitChars ); } @@ -469,13 +449,6 @@ void BiffInputStream::skipUniString() // private -------------------------------------------------------------------- -void BiffInputStream::readAtom( void* opMem, sal_uInt8 nSize ) -{ - // byte swapping is done in calling BinaryInputStream::readValue() template function - if( ensureRawReadSize( nSize ) ) - maRecBuffer.read( opMem, nSize ); -} - void BiffInputStream::setupRecord() { // initialize class members @@ -529,7 +502,7 @@ bool BiffInputStream::jumpToNextContinue() bool BiffInputStream::jumpToNextStringContinue( bool& rb16BitChars ) { - OSL_ENSURE( maRecBuffer.getRecLeft() == 0, "BiffInputStream::jumpToNextStringContinue - unexpected garbage" ); + OSL_ENSURE( maRecBuffer.getRecLeft() == 0, "BiffInputStream::jumpToNextStringContinue - alignment error" ); if( mbCont && (getRemaining() > 0) ) { @@ -561,31 +534,17 @@ void BiffInputStream::calcRecordLength() seek( nCurrPos ); // restore position, seek() resets old mbValid state } -bool BiffInputStream::ensureRawReadSize( sal_uInt16 nBytes ) -{ - if( !mbEof && (nBytes > 0) ) - { - while( !mbEof && (maRecBuffer.getRecLeft() == 0) ) jumpToNextContinue(); - mbEof = mbEof || (nBytes > maRecBuffer.getRecLeft()); - OSL_ENSURE( !mbEof, "BiffInputStream::ensureRawReadSize - record overread" ); - } - return !mbEof; -} - -sal_uInt16 BiffInputStream::getMaxRawReadSize( sal_Int32 nBytes ) const -{ - return getLimitedValue< sal_uInt16, sal_Int32 >( nBytes, 0, maRecBuffer.getRecLeft() ); -} - -void BiffInputStream::appendUnicodeArray( OUStringBuffer& orBuffer, sal_uInt16 nChars, bool b16BitChars, bool bAllowNulChars ) +sal_uInt16 BiffInputStream::getMaxRawReadSize( sal_Int32 nBytes, size_t nAtomSize ) const { - orBuffer.ensureCapacity( orBuffer.getLength() + nChars ); - sal_uInt16 nChar; - for( sal_uInt16 nCharIdx = 0; !mbEof && (nCharIdx < nChars); ++nCharIdx ) + sal_uInt16 nMaxSize = getLimitedValue< sal_uInt16, sal_Int32 >( nBytes, 0, maRecBuffer.getRecLeft() ); + if( (0 < nMaxSize) && (nMaxSize < nBytes) && (nAtomSize > 1) ) { - if( b16BitChars ) readValue( nChar ); else nChar = readuInt8(); - orBuffer.append( static_cast< sal_Unicode >( (!bAllowNulChars && (nChar == 0)) ? '?' : nChar ) ); + // check that remaining data in record buffer is a multiple of the passed atom size + sal_uInt16 nPadding = static_cast< sal_uInt16 >( nMaxSize % nAtomSize ); + OSL_ENSURE( nPadding == 0, "BiffInputStream::getMaxRawReadSize - alignment error" ); + nMaxSize = nMaxSize - nPadding; } + return nMaxSize; } void BiffInputStream::readUniStringHeader( bool& orb16BitChars, sal_Int32& ornAddSize ) diff --git a/oox/source/xls/biffoutputstream.cxx b/oox/source/xls/biffoutputstream.cxx index ba59f50bea4d..14608414c91d 100644 --- a/oox/source/xls/biffoutputstream.cxx +++ b/oox/source/xls/biffoutputstream.cxx @@ -85,6 +85,7 @@ void BiffOutputRecordBuffer::fill( sal_uInt8 nValue, sal_uInt16 nBytes ) // ============================================================================ BiffOutputStream::BiffOutputStream( BinaryOutputStream& rOutStream, sal_uInt16 nMaxRecSize ) : + BinaryStreamBase( true ), maRecBuffer( rOutStream, nMaxRecSize ), mnPortionSize( 0 ), mnPortionPos( 0 ) @@ -96,19 +97,19 @@ BiffOutputStream::BiffOutputStream( BinaryOutputStream& rOutStream, sal_uInt16 n void BiffOutputStream::startRecord( sal_uInt16 nRecId ) { maRecBuffer.startRecord( nRecId ); - setPortionSize( 0 ); + setPortionSize( 1 ); } void BiffOutputStream::endRecord() { - setPortionSize( 0 ); + setPortionSize( 1 ); maRecBuffer.endRecord(); } -void BiffOutputStream::setPortionSize( sal_uInt16 nSize ) +void BiffOutputStream::setPortionSize( sal_uInt8 nSize ) { OSL_ENSURE( mnPortionPos == 0, "BiffOutputStream::setPortionSize - block operation inside portion" ); - mnPortionSize = nSize; + mnPortionSize = ::std::max< sal_uInt8 >( nSize, 1 ); mnPortionPos = 0; } @@ -119,20 +120,20 @@ sal_Int64 BiffOutputStream::tellBase() const return maRecBuffer.getBaseStream().tell(); } -sal_Int64 BiffOutputStream::getBaseLength() const +sal_Int64 BiffOutputStream::sizeBase() const { - return maRecBuffer.getBaseStream().getLength(); + return maRecBuffer.getBaseStream().size(); } // BinaryOutputStream interface (stream write access) ------------------------- -void BiffOutputStream::writeData( const StreamDataSequence& rData ) +void BiffOutputStream::writeData( const StreamDataSequence& rData, size_t nAtomSize ) { if( rData.hasElements() ) - writeMemory( rData.getConstArray(), rData.getLength() ); + writeMemory( rData.getConstArray(), rData.getLength(), nAtomSize ); } -void BiffOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes ) +void BiffOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize ) { if( pMem && (nBytes > 0) ) { @@ -140,7 +141,7 @@ void BiffOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes ) sal_Int32 nBytesLeft = nBytes; while( nBytesLeft > 0 ) { - sal_uInt16 nBlockSize = prepareRawBlock( nBytesLeft ); + sal_uInt16 nBlockSize = prepareWriteBlock( nBytesLeft, nAtomSize ); maRecBuffer.write( pnBuffer, nBlockSize ); pnBuffer += nBlockSize; nBytesLeft -= nBlockSize; @@ -148,59 +149,60 @@ void BiffOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes ) } } -void BiffOutputStream::fill( sal_uInt8 nValue, sal_Int32 nBytes ) +void BiffOutputStream::fill( sal_uInt8 nValue, sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nBytesLeft = nBytes; while( nBytesLeft > 0 ) { - sal_uInt16 nBlockSize = prepareRawBlock( nBytesLeft ); + sal_uInt16 nBlockSize = prepareWriteBlock( nBytesLeft, nAtomSize ); maRecBuffer.fill( nValue, nBlockSize ); nBytesLeft -= nBlockSize; } } -void BiffOutputStream::writeBlock( const void* pMem, sal_uInt16 nBytes ) -{ - ensureRawBlock( nBytes ); - maRecBuffer.write( pMem, nBytes ); -} - // private -------------------------------------------------------------------- -void BiffOutputStream::writeAtom( const void* pMem, sal_uInt8 nSize ) -{ - // byte swapping is done in calling BinaryOutputStream::writeValue() template function - writeBlock( pMem, nSize ); -} - -void BiffOutputStream::ensureRawBlock( sal_uInt16 nSize ) +sal_uInt16 BiffOutputStream::prepareWriteBlock( sal_Int32 nTotalSize, size_t nAtomSize ) { - if( (maRecBuffer.getRecLeft() < nSize) || - ((mnPortionSize > 0) && (mnPortionPos == 0) && (maRecBuffer.getRecLeft() < mnPortionSize)) ) + sal_uInt16 nRecLeft = maRecBuffer.getRecLeft(); + if( mnPortionSize <= 1 ) { - maRecBuffer.endRecord(); - maRecBuffer.startRecord( BIFF_ID_CONT ); + // no portions: restrict remaining record size to entire atoms + nRecLeft = static_cast< sal_uInt16 >( (nRecLeft / nAtomSize) * nAtomSize ); } - if( mnPortionSize > 0 ) + else { - OSL_ENSURE( mnPortionPos + nSize <= mnPortionSize, "BiffOutputStream::ensureRawBlock - portion overflow" ); - mnPortionPos = (mnPortionPos + nSize) % mnPortionSize; // prevent compiler warning, do not use operator+=, operator%= + sal_Int32 nPortionLeft = mnPortionSize - mnPortionPos; + if( nTotalSize <= nPortionLeft ) + { + // block fits into the current portion + OSL_ENSURE( nPortionLeft <= nRecLeft, "BiffOutputStream::prepareWriteBlock - portion exceeds record" ); + mnPortionPos = static_cast< sal_uInt8 >( (mnPortionPos + nTotalSize) % mnPortionSize ); + } + else + { + // restrict remaining record size to entire portions + OSL_ENSURE( mnPortionPos == 0, "BiffOutputStream::prepareWriteBlock - writing over multiple portions starts inside portion" ); + mnPortionPos = 0; + // check that atom size matches portion size + OSL_ENSURE( mnPortionSize % nAtomSize == 0, "BiffOutputStream::prepareWriteBlock - atom size does not match portion size" ); + sal_uInt8 nPortionSize = static_cast< sal_uInt8 >( (mnPortionSize / nAtomSize) * nAtomSize ); + // restrict remaining record size to entire portions + nRecLeft = (nRecLeft / nPortionSize) * nPortionSize; + } } -} -sal_uInt16 BiffOutputStream::prepareRawBlock( sal_Int32 nTotalSize ) -{ - sal_uInt16 nRecLeft = maRecBuffer.getRecLeft(); - if( mnPortionSize > 0 ) - { - OSL_ENSURE( mnPortionPos == 0, "BiffOutputStream::prepareRawBlock - block operation inside portion" ); - OSL_ENSURE( nTotalSize % mnPortionSize == 0, "BiffOutputStream::prepareRawBlock - portion size does not match block size" ); - nRecLeft = (nRecLeft / mnPortionSize) * mnPortionSize; - } - sal_uInt16 nSize = getLimitedValue< sal_uInt16, sal_Int32 >( nTotalSize, 0, nRecLeft ); - ensureRawBlock( nSize ); - return nSize; + // current record has space for some data: return size of available space + if( nRecLeft > 0 ) + return getLimitedValue< sal_uInt16, sal_Int32 >( nTotalSize, 0, nRecLeft ); + + // finish current record and start a new CONTINUE record + maRecBuffer.endRecord(); + maRecBuffer.startRecord( BIFF_ID_CONT ); + mnPortionPos = 0; + return prepareWriteBlock( nTotalSize, nAtomSize ); } + // ============================================================================ } // namespace xls diff --git a/oox/source/xls/drawingmanager.cxx b/oox/source/xls/drawingmanager.cxx index 3ee5c45a80b6..efba6824c8ac 100755 --- a/oox/source/xls/drawingmanager.cxx +++ b/oox/source/xls/drawingmanager.cxx @@ -1374,8 +1374,7 @@ Reference< XShape > BiffDrawingBase::createAndInsertXShape( const OUString& rSer Reference< XShape > xShape; if( (rService.getLength() > 0) && rxShapes.is() ) try { - Reference< XMultiServiceFactory > xFactory( getDocumentFactory(), UNO_SET_THROW ); - xShape.set( xFactory->createInstance( rService ), UNO_QUERY_THROW ); + xShape.set( getBaseFilter().getModelFactory()->createInstance( rService ), UNO_QUERY_THROW ); // insert shape into passed shape collection (maybe drawpage or group shape) rxShapes->add( xShape ); xShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) ); diff --git a/oox/source/xls/excelchartconverter.cxx b/oox/source/xls/excelchartconverter.cxx index 53c0a3b83bf2..702a12fbde50 100644 --- a/oox/source/xls/excelchartconverter.cxx +++ b/oox/source/xls/excelchartconverter.cxx @@ -30,6 +30,7 @@ #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/chart2/data/XDataProvider.hpp> #include <com/sun/star/chart2/data/XDataReceiver.hpp> +#include "oox/core/filterbase.hxx" #include "oox/drawingml/chart/datasourcemodel.hxx" #include "oox/helper/containerhelper.hxx" #include "oox/xls/formulaparser.hxx" @@ -64,8 +65,7 @@ void ExcelChartConverter::createDataProvider( const Reference< XChartDocument >& try { Reference< XDataReceiver > xDataRec( rxChartDoc, UNO_QUERY_THROW ); - Reference< XMultiServiceFactory > xFactory( getDocument(), UNO_QUERY_THROW ); - Reference< XDataProvider > xDataProv( xFactory->createInstance( + Reference< XDataProvider > xDataProv( getBaseFilter().getModelFactory()->createInstance( CREATE_OUSTRING( "com.sun.star.chart2.data.DataProvider" ) ), UNO_QUERY_THROW ); xDataRec->attachDataProvider( xDataProv ); } diff --git a/oox/source/xls/formulabase.cxx b/oox/source/xls/formulabase.cxx index f097dec831d8..58049f4851d7 100755 --- a/oox/source/xls/formulabase.cxx +++ b/oox/source/xls/formulabase.cxx @@ -1025,7 +1025,7 @@ struct OpCodeProviderImpl : public ApiOpCodes explicit OpCodeProviderImpl( const FunctionInfoVector& rFuncInfos, - const Reference< XMultiServiceFactory >& rxFactory ); + const Reference< XMultiServiceFactory >& rxModelFactory ); private: typedef ::std::map< OUString, ApiToken > ApiTokenMap; @@ -1047,11 +1047,11 @@ private: // ---------------------------------------------------------------------------- OpCodeProviderImpl::OpCodeProviderImpl( const FunctionInfoVector& rFuncInfos, - const Reference< XMultiServiceFactory >& rxFactory ) + const Reference< XMultiServiceFactory >& rxModelFactory ) { - if( rxFactory.is() ) try + if( rxModelFactory.is() ) try { - Reference< XFormulaOpCodeMapper > xMapper( rxFactory->createInstance( + Reference< XFormulaOpCodeMapper > xMapper( rxModelFactory->createInstance( CREATE_OUSTRING( "com.sun.star.sheet.FormulaOpCodeMapper" ) ), UNO_QUERY_THROW ); // op-codes provided as attributes @@ -1297,10 +1297,10 @@ bool OpCodeProviderImpl::initFuncOpCodes( const ApiTokenMap& rIntFuncTokenMap, c // ---------------------------------------------------------------------------- -OpCodeProvider::OpCodeProvider( const Reference< XMultiServiceFactory >& rxFactory, +OpCodeProvider::OpCodeProvider( const Reference< XMultiServiceFactory >& rxModelFactory, FilterType eFilter, BiffType eBiff, bool bImportFilter ) : FunctionProvider( eFilter, eBiff, bImportFilter ), - mxOpCodeImpl( new OpCodeProviderImpl( getFuncs(), rxFactory ) ) + mxOpCodeImpl( new OpCodeProviderImpl( getFuncs(), rxModelFactory ) ) { } @@ -1335,12 +1335,12 @@ Sequence< FormulaOpCodeMapEntry > OpCodeProvider::getOoxParserMap() const // API formula parser wrapper ================================================= ApiParserWrapper::ApiParserWrapper( - const Reference< XMultiServiceFactory >& rxFactory, const OpCodeProvider& rOpCodeProv ) : + const Reference< XMultiServiceFactory >& rxModelFactory, const OpCodeProvider& rOpCodeProv ) : OpCodeProvider( rOpCodeProv ) { - if( rxFactory.is() ) try + if( rxModelFactory.is() ) try { - mxParser.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.sheet.FormulaParser" ) ), UNO_QUERY_THROW ); + mxParser.set( rxModelFactory->createInstance( CREATE_OUSTRING( "com.sun.star.sheet.FormulaParser" ) ), UNO_QUERY_THROW ); } catch( Exception& ) { @@ -1483,7 +1483,7 @@ TokenToRangeListState lclProcessClose( sal_Int32& ornParenLevel ) // ---------------------------------------------------------------------------- FormulaProcessorBase::FormulaProcessorBase( const WorkbookHelper& rHelper ) : - OpCodeProvider( rHelper.getDocumentFactory(), rHelper.getFilterType(), rHelper.getBiff(), rHelper.getBaseFilter().isImportFilter() ), + OpCodeProvider( rHelper.getBaseFilter().getModelFactory(), rHelper.getFilterType(), rHelper.getBiff(), rHelper.getBaseFilter().isImportFilter() ), ApiOpCodes( getOpCodes() ), WorkbookHelper( rHelper ) { diff --git a/oox/source/xls/formulaparser.cxx b/oox/source/xls/formulaparser.cxx index 26bf66986638..d7eb91a9c05c 100644 --- a/oox/source/xls/formulaparser.cxx +++ b/oox/source/xls/formulaparser.cxx @@ -1313,7 +1313,7 @@ private: OoxFormulaParserImpl::OoxFormulaParserImpl( const FormulaParser& rParent ) : FormulaParserImpl( rParent ), - maApiParser( rParent.getDocumentFactory(), rParent ), + maApiParser( rParent.getBaseFilter().getModelFactory(), rParent ), mnAddDataPos( 0 ), mbNeedExtRefs( true ) { diff --git a/oox/source/xls/numberformatsbuffer.cxx b/oox/source/xls/numberformatsbuffer.cxx index c77381b2a1c8..782c138d43e2 100644 --- a/oox/source/xls/numberformatsbuffer.cxx +++ b/oox/source/xls/numberformatsbuffer.cxx @@ -1950,7 +1950,7 @@ NumberFormatsBuffer::NumberFormatsBuffer( const WorkbookHelper& rHelper ) : // get the current locale try { - Reference< XMultiServiceFactory > xConfigProv( getGlobalFactory()->createInstance( + Reference< XMultiServiceFactory > xConfigProv( getBaseFilter().getServiceFactory()->createInstance( CREATE_OUSTRING( "com.sun.star.configuration.ConfigurationProvider" ) ), UNO_QUERY_THROW ); // try user-defined locale setting diff --git a/oox/source/xls/ooxformulaparser.cxx b/oox/source/xls/ooxformulaparser.cxx index efa69abcb750..a8860a8f2131 100644 --- a/oox/source/xls/ooxformulaparser.cxx +++ b/oox/source/xls/ooxformulaparser.cxx @@ -47,7 +47,7 @@ using ::rtl::OUString; class OOXMLFormulaParserImpl : private FormulaFinalizer { public: - explicit OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxFactory ); + explicit OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxModelFactory ); Sequence< FormulaToken > parseFormula( const OUString& rFormula, const CellAddress& rReferencePos ); @@ -60,9 +60,9 @@ private: // ---------------------------------------------------------------------------- -OOXMLFormulaParserImpl::OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxFactory ) : - FormulaFinalizer( OpCodeProvider( rxFactory, FILTER_OOXML, BIFF_UNKNOWN, true ) ), - maApiParser( rxFactory, *this ) +OOXMLFormulaParserImpl::OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxModelFactory ) : + FormulaFinalizer( OpCodeProvider( rxModelFactory, FILTER_OOXML, BIFF_UNKNOWN, true ) ), + maApiParser( rxModelFactory, *this ) { } @@ -115,7 +115,7 @@ const FunctionInfo* OOXMLFormulaParserImpl::resolveBadFuncName( const OUString& class OOXMLFormulaPrinterImpl : public OpCodeProvider { public: - explicit OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxFactory ); + explicit OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxModelFactory ); private: ApiParserWrapper maApiParser; @@ -123,9 +123,9 @@ private: // ---------------------------------------------------------------------------- -OOXMLFormulaPrinterImpl::OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxFactory ) : - OpCodeProvider( rxFactory, FILTER_OOXML, BIFF_UNKNOWN, false ), - maApiParser( rxFactory, *this ) +OOXMLFormulaPrinterImpl::OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxModelFactory ) : + OpCodeProvider( rxModelFactory, FILTER_OOXML, BIFF_UNKNOWN, false ), + maApiParser( rxModelFactory, *this ) { } @@ -202,8 +202,8 @@ Sequence< FormulaToken > SAL_CALL OOXMLFormulaParser::parseFormula( { if( !mxParserImpl ) { - Reference< XMultiServiceFactory > xFactory( mxComponent, UNO_QUERY_THROW ); - mxParserImpl.reset( new OOXMLFormulaParserImpl( xFactory ) ); + Reference< XMultiServiceFactory > xModelFactory( mxComponent, UNO_QUERY_THROW ); + mxParserImpl.reset( new OOXMLFormulaParserImpl( xModelFactory ) ); } return mxParserImpl->parseFormula( rFormula, rReferencePos ); } diff --git a/oox/source/xls/pagesettings.cxx b/oox/source/xls/pagesettings.cxx index 188bf78544ec..5c1770bd6463 100644 --- a/oox/source/xls/pagesettings.cxx +++ b/oox/source/xls/pagesettings.cxx @@ -903,8 +903,7 @@ Reference< XTextContent > HeaderFooterParser::createField( const OUString& rServ Reference< XTextContent > xContent; try { - Reference< XMultiServiceFactory > xFactory( getDocument(), UNO_QUERY_THROW ); - xContent.set( xFactory->createInstance( rServiceName ), UNO_QUERY_THROW ); + xContent.set( getBaseFilter().getModelFactory()->createInstance( rServiceName ), UNO_QUERY_THROW ); } catch( Exception& ) { diff --git a/oox/source/xls/pivotcachebuffer.cxx b/oox/source/xls/pivotcachebuffer.cxx index e8ca3539e167..5e5e5efef546 100644 --- a/oox/source/xls/pivotcachebuffer.cxx +++ b/oox/source/xls/pivotcachebuffer.cxx @@ -737,7 +737,7 @@ void PivotCacheField::importPCDFRangePr( BiffInputStream& rStrm ) void PivotCacheField::importPCDFDiscretePr( BiffInputStream& rStrm ) { - sal_Int32 nCount = static_cast< sal_Int32 >( rStrm.getLength() / 2 ); + sal_Int32 nCount = static_cast< sal_Int32 >( rStrm.size() / 2 ); for( sal_Int32 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex ) maDiscreteItems.push_back( rStrm.readuInt16() ); } diff --git a/oox/source/xls/viewsettings.cxx b/oox/source/xls/viewsettings.cxx index c9658dd41cf9..e23273b42b82 100644 --- a/oox/source/xls/viewsettings.cxx +++ b/oox/source/xls/viewsettings.cxx @@ -734,7 +734,7 @@ void ViewSettings::finalizeImport() sal_Int16 nShowMode = getWorkbookSettings().getApiShowObjectMode(); // view settings for all sheets - Reference< XNameContainer > xSheetsNC = ContainerHelper::createNameContainer( getGlobalFactory() ); + Reference< XNameContainer > xSheetsNC = ContainerHelper::createNameContainer( getBaseFilter().getComponentContext() ); if( !xSheetsNC.is() ) return; for( SheetPropertiesMap::const_iterator aIt = maSheetProps.begin(), aEnd = maSheetProps.end(); aIt != aEnd; ++aIt ) ContainerHelper::insertByName( xSheetsNC, rWorksheets.getCalcSheetName( aIt->first ), aIt->second ); @@ -746,7 +746,7 @@ void ViewSettings::finalizeImport() if( !rxActiveSheetView ) rxActiveSheetView.reset( new SheetViewModel ); - Reference< XIndexContainer > xContainer = ContainerHelper::createIndexContainer( getGlobalFactory() ); + Reference< XIndexContainer > xContainer = ContainerHelper::createIndexContainer( getBaseFilter().getComponentContext() ); if( xContainer.is() ) try { PropertyMap aPropMap; diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx index 69daca13812e..843bfd69fdfe 100644 --- a/oox/source/xls/workbookfragment.cxx +++ b/oox/source/xls/workbookfragment.cxx @@ -289,7 +289,7 @@ void WorkbookFragment::finalizeImport() { Reference< XInputStream > xInStrm = getBaseFilter().openInputStream( aVbaFragmentPath ); if( xInStrm.is() ) - setVbaProjectStorage( StorageRef( new ::oox::ole::OleStorage( getGlobalFactory(), xInStrm, false ) ) ); + setVbaProjectStorage( StorageRef( new ::oox::ole::OleStorage( getBaseFilter().getComponentContext(), xInStrm, false ) ) ); } // final conversions, e.g. calculation settings and view settings diff --git a/oox/source/xls/workbookhelper.cxx b/oox/source/xls/workbookhelper.cxx index 8cd2748101d7..6adb7957d4b8 100644 --- a/oox/source/xls/workbookhelper.cxx +++ b/oox/source/xls/workbookhelper.cxx @@ -595,11 +595,6 @@ FilterBase& WorkbookHelper::getBaseFilter() const return mrBookData.getBaseFilter(); } -Reference< XMultiServiceFactory > WorkbookHelper::getGlobalFactory() const -{ - return mrBookData.getBaseFilter().getServiceFactory(); -} - FilterType WorkbookHelper::getFilterType() const { return mrBookData.getFilterType(); @@ -666,11 +661,6 @@ Reference< XSpreadsheetDocument > WorkbookHelper::getDocument() const return mrBookData.getDocument(); } -Reference< XMultiServiceFactory > WorkbookHelper::getDocumentFactory() const -{ - return mrBookData.getBaseFilter().getModelFactory(); -} - Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( sal_Int16 nSheet ) const { Reference< XSpreadsheet > xSheet; diff --git a/oox/source/xls/workbooksettings.cxx b/oox/source/xls/workbooksettings.cxx index 6889d42ed2f6..264555971ba0 100644 --- a/oox/source/xls/workbooksettings.cxx +++ b/oox/source/xls/workbooksettings.cxx @@ -299,7 +299,7 @@ void WorkbookSettings::finalizeImport() { getBaseFilter().getMediaDescriptor()[ CREATE_OUSTRING( "ReadOnly" ) ] <<= true; - Reference< XPropertySet > xDocumentSettings( getDocumentFactory()->createInstance( + Reference< XPropertySet > xDocumentSettings( getBaseFilter().getModelFactory()->createInstance( CREATE_OUSTRING( "com.sun.star.document.Settings" ) ), UNO_QUERY_THROW ); PropertySet aSettingsProp( xDocumentSettings ); if( maFileSharing.mbRecommendReadOnly ) diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx index 124fdacd4431..00f65f90294f 100644 --- a/oox/source/xls/worksheethelper.cxx +++ b/oox/source/xls/worksheethelper.cxx @@ -681,7 +681,7 @@ Reference< XSheetCellRanges > WorksheetData::getCellRangeList( const ApiCellRang Reference< XSheetCellRanges > xRanges; if( mxSheet.is() && !rRanges.empty() ) try { - xRanges.set( getDocumentFactory()->createInstance( maSheetCellRanges ), UNO_QUERY_THROW ); + xRanges.set( getBaseFilter().getModelFactory()->createInstance( maSheetCellRanges ), UNO_QUERY_THROW ); Reference< XSheetCellRangeContainer > xRangeCont( xRanges, UNO_QUERY_THROW ); xRangeCont->addRangeAddresses( ContainerHelper::vectorToSequence( rRanges ), sal_False ); } @@ -1359,7 +1359,7 @@ void WorksheetData::insertHyperlink( const CellAddress& rAddress, const OUString if( xText.is() ) { // create a URL field object and set its properties - Reference< XTextContent > xUrlField( getDocumentFactory()->createInstance( maUrlTextField ), UNO_QUERY ); + Reference< XTextContent > xUrlField( getBaseFilter().getModelFactory()->createInstance( maUrlTextField ), UNO_QUERY ); OSL_ENSURE( xUrlField.is(), "WorksheetData::insertHyperlink - cannot create text field" ); if( xUrlField.is() ) { |