diff options
Diffstat (limited to 'oox/source/helper')
-rw-r--r-- | oox/source/helper/attributelist.cxx | 311 | ||||
-rw-r--r-- | oox/source/helper/binaryinputstream.cxx | 239 | ||||
-rw-r--r-- | oox/source/helper/binaryoutputstream.cxx | 157 | ||||
-rw-r--r-- | oox/source/helper/binarystreambase.cxx | 144 | ||||
-rw-r--r-- | oox/source/helper/containerhelper.cxx | 224 | ||||
-rw-r--r-- | oox/source/helper/graphichelper.cxx | 120 | ||||
-rw-r--r-- | oox/source/helper/makefile.mk | 61 | ||||
-rw-r--r-- | oox/source/helper/modelobjecthelper.cxx | 91 | ||||
-rw-r--r-- | oox/source/helper/olestorage.cxx | 180 | ||||
-rw-r--r-- | oox/source/helper/progressbar.cxx | 185 | ||||
-rw-r--r-- | oox/source/helper/propertymap.cxx | 234 | ||||
-rw-r--r-- | oox/source/helper/propertyset.cxx | 174 | ||||
-rw-r--r-- | oox/source/helper/recordinputstream.cxx | 71 | ||||
-rw-r--r-- | oox/source/helper/storagebase.cxx | 209 | ||||
-rw-r--r-- | oox/source/helper/zipstorage.cxx | 194 |
15 files changed, 2594 insertions, 0 deletions
diff --git a/oox/source/helper/attributelist.cxx b/oox/source/helper/attributelist.cxx new file mode 100644 index 000000000000..4e121497c452 --- /dev/null +++ b/oox/source/helper/attributelist.cxx @@ -0,0 +1,311 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/helper/attributelist.hxx" +#include <osl/diagnose.h> +#include <rtl/ustrbuf.hxx> + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::util::DateTime; +using ::com::sun::star::xml::sax::XFastAttributeList; + +namespace oox { + +// ============================================================================ + +namespace { + +const sal_Int32 XSTRING_ENCCHAR_LEN = 7; + +bool lclAddHexDigit( sal_Unicode& orcChar, sal_Unicode cDigit, int nBitShift ) +{ + if( ('0' <= cDigit) && (cDigit <= '9') ) { orcChar |= ((cDigit - '0') << nBitShift); return true; } + if( ('a' <= cDigit) && (cDigit <= 'f') ) { orcChar |= ((cDigit - 'a' + 10) << nBitShift); return true; } + if( ('A' <= cDigit) && (cDigit <= 'F') ) { orcChar |= ((cDigit - 'A' + 10) << nBitShift); return true; } + return false; +} + +sal_Unicode lclGetXChar( const sal_Unicode*& rpcStr, const sal_Unicode* pcEnd ) +{ + sal_Unicode cChar = 0; + if( (pcEnd - rpcStr >= XSTRING_ENCCHAR_LEN) && + (rpcStr[ 0 ] == '_') && + (rpcStr[ 1 ] == 'x') && + (rpcStr[ 6 ] == '_') && + lclAddHexDigit( cChar, rpcStr[ 2 ], 12 ) && + lclAddHexDigit( cChar, rpcStr[ 3 ], 8 ) && + lclAddHexDigit( cChar, rpcStr[ 4 ], 4 ) && + lclAddHexDigit( cChar, rpcStr[ 5 ], 0 ) ) + { + rpcStr += XSTRING_ENCCHAR_LEN; + return cChar; + } + return *rpcStr++; +} + +} // namespace + +// ============================================================================ + +AttributeList::AttributeList( const Reference< XFastAttributeList >& rxAttribs ) : + mxAttribs( rxAttribs ) +{ + OSL_ENSURE( mxAttribs.is(), "AttributeList::AttributeList - missing attribute list interface" ); +} + +bool AttributeList::hasAttribute( sal_Int32 nElement ) const +{ + return mxAttribs->hasAttribute( nElement ); +} + +// static string conversion ----------------------------------------------- + +OUString AttributeList::decodeXString( const OUString& rValue ) +{ + // string shorter than one encoded character - no need to decode + if( rValue.getLength() < XSTRING_ENCCHAR_LEN ) + return rValue; + OUStringBuffer aBuffer; + const sal_Unicode* pcStr = rValue.getStr(); + const sal_Unicode* pcEnd = pcStr + rValue.getLength(); + while( pcStr < pcEnd ) + aBuffer.append( lclGetXChar( pcStr, pcEnd ) ); + return aBuffer.makeStringAndClear(); +} + +double AttributeList::decodeDouble( const OUString& rValue ) +{ + return rValue.toDouble(); +} + +sal_Int32 AttributeList::decodeInteger( const OUString& rValue ) +{ + return rValue.toInt32(); +} + +sal_uInt32 AttributeList::decodeUnsigned( const OUString& rValue ) +{ + return getLimitedValue< sal_uInt32, sal_Int64 >( rValue.toInt64(), 0, SAL_MAX_UINT32 ); +} + +sal_Int64 AttributeList::decodeHyper( const OUString& rValue ) +{ + return rValue.toInt64(); +} + +sal_Int32 AttributeList::decodeIntegerHex( const OUString& rValue ) +{ + return rValue.toInt32( 16 ); +} + +sal_uInt32 AttributeList::decodeUnsignedHex( const OUString& rValue ) +{ + return getLimitedValue< sal_uInt32, sal_Int64 >( rValue.toInt64( 16 ), 0, SAL_MAX_UINT32 ); +} + +sal_Int64 AttributeList::decodeHyperHex( const OUString& rValue ) +{ + return rValue.toInt64( 16 ); +} + +// optional return values ----------------------------------------------------- + +OptValue< sal_Int32 > AttributeList::getToken( sal_Int32 nElement ) const +{ + sal_Int32 nToken = mxAttribs->getOptionalValueToken( nElement, XML_TOKEN_INVALID ); + return OptValue< sal_Int32 >( nToken != XML_TOKEN_INVALID, nToken ); +} + +OptValue< OUString > AttributeList::getString( sal_Int32 nElement ) const +{ + return OptValue< OUString >( mxAttribs->hasAttribute( nElement ), mxAttribs->getOptionalValue( nElement ) ); +} + +OptValue< OUString > AttributeList::getXString( sal_Int32 nElement ) const +{ + return OptValue< OUString >( mxAttribs->hasAttribute( nElement ), decodeXString( mxAttribs->getOptionalValue( nElement ) ) ); +} + +OptValue< double > AttributeList::getDouble( sal_Int32 nElement ) const +{ + OUString aValue = mxAttribs->getOptionalValue( nElement ); + bool bValid = aValue.getLength() > 0; + return OptValue< double >( bValid, bValid ? decodeDouble( aValue ) : 0.0 ); +} + +OptValue< sal_Int32 > AttributeList::getInteger( sal_Int32 nElement ) const +{ + OUString aValue = mxAttribs->getOptionalValue( nElement ); + bool bValid = aValue.getLength() > 0; + return OptValue< sal_Int32 >( bValid, bValid ? decodeInteger( aValue ) : 0 ); +} + +OptValue< sal_uInt32 > AttributeList::getUnsigned( sal_Int32 nElement ) const +{ + OUString aValue = mxAttribs->getOptionalValue( nElement ); + bool bValid = aValue.getLength() > 0; + return OptValue< sal_uInt32 >( bValid, decodeUnsigned( aValue ) ); +} + +OptValue< sal_Int64 > AttributeList::getHyper( sal_Int32 nElement ) const +{ + OUString aValue = mxAttribs->getOptionalValue( nElement ); + bool bValid = aValue.getLength() > 0; + return OptValue< sal_Int64 >( bValid, bValid ? decodeHyper( aValue ) : 0 ); +} + +OptValue< sal_Int32 > AttributeList::getIntegerHex( sal_Int32 nElement ) const +{ + OUString aValue = mxAttribs->getOptionalValue( nElement ); + bool bValid = aValue.getLength() > 0; + return OptValue< sal_Int32 >( bValid, bValid ? decodeIntegerHex( aValue ) : 0 ); +} + +OptValue< sal_uInt32 > AttributeList::getUnsignedHex( sal_Int32 nElement ) const +{ + OUString aValue = mxAttribs->getOptionalValue( nElement ); + bool bValid = aValue.getLength() > 0; + return OptValue< sal_uInt32 >( bValid, bValid ? decodeUnsignedHex( aValue ) : 0 ); +} + +OptValue< sal_Int64 > AttributeList::getHyperHex( sal_Int32 nElement ) const +{ + OUString aValue = mxAttribs->getOptionalValue( nElement ); + bool bValid = aValue.getLength() > 0; + return OptValue< sal_Int64 >( bValid, bValid ? decodeHyperHex( aValue ) : 0 ); +} + +OptValue< bool > AttributeList::getBool( sal_Int32 nElement ) const +{ + // boolean attributes may be "t", "f", "true", "false", "on", "off", "1", or "0" + switch( getToken( nElement, -1 ) ) + { + case XML_t: return OptValue< bool >( true, true ); // used in VML + case XML_true: return OptValue< bool >( true, true ); + case XML_on: return OptValue< bool >( true, true ); + case XML_f: return OptValue< bool >( true, false ); // used in VML + case XML_false: return OptValue< bool >( true, false ); + case XML_off: return OptValue< bool >( true, false ); + } + OptValue< sal_Int32 > onValue = getInteger( nElement ); + return OptValue< bool >( onValue.has(), onValue.get() != 0 ); +} + +OptValue< DateTime > AttributeList::getDateTime( sal_Int32 nElement ) const +{ + OUString aValue = mxAttribs->getOptionalValue( nElement ); + DateTime aDateTime; + bool bValid = (aValue.getLength() == 19) && (aValue[ 4 ] == '-') && (aValue[ 7 ] == '-') && + (aValue[ 10 ] == 'T') && (aValue[ 13 ] == ':') && (aValue[ 16 ] == ':'); + if( bValid ) + { + aDateTime.Year = static_cast< sal_uInt16 >( aValue.copy( 0, 4 ).toInt32() ); + aDateTime.Month = static_cast< sal_uInt16 >( aValue.copy( 5, 2 ).toInt32() ); + aDateTime.Day = static_cast< sal_uInt16 >( aValue.copy( 8, 2 ).toInt32() ); + aDateTime.Hours = static_cast< sal_uInt16 >( aValue.copy( 11, 2 ).toInt32() ); + aDateTime.Minutes = static_cast< sal_uInt16 >( aValue.copy( 14, 2 ).toInt32() ); + aDateTime.Seconds = static_cast< sal_uInt16 >( aValue.copy( 17, 2 ).toInt32() ); + } + return OptValue< DateTime >( bValid, aDateTime ); +} + +// defaulted return values ---------------------------------------------------- + +sal_Int32 AttributeList::getToken( sal_Int32 nElement, sal_Int32 nDefault ) const +{ + return mxAttribs->getOptionalValueToken( nElement, nDefault ); +} + +OUString AttributeList::getString( sal_Int32 nElement, const OUString& rDefault ) const +{ + try + { + return mxAttribs->getValue( nElement ); + } + catch( Exception& ) + { + } + return rDefault; +} + +OUString AttributeList::getXString( sal_Int32 nElement, const OUString& rDefault ) const +{ + return getXString( nElement ).get( rDefault ); +} + +double AttributeList::getDouble( sal_Int32 nElement, double fDefault ) const +{ + return getDouble( nElement ).get( fDefault ); +} + +sal_Int32 AttributeList::getInteger( sal_Int32 nElement, sal_Int32 nDefault ) const +{ + return getInteger( nElement ).get( nDefault ); +} + +sal_uInt32 AttributeList::getUnsigned( sal_Int32 nElement, sal_uInt32 nDefault ) const +{ + return getUnsigned( nElement ).get( nDefault ); +} + +sal_Int64 AttributeList::getHyper( sal_Int32 nElement, sal_Int64 nDefault ) const +{ + return getHyper( nElement ).get( nDefault ); +} + +sal_Int32 AttributeList::getIntegerHex( sal_Int32 nElement, sal_Int32 nDefault ) const +{ + return getIntegerHex( nElement ).get( nDefault ); +} + +sal_uInt32 AttributeList::getUnsignedHex( sal_Int32 nElement, sal_uInt32 nDefault ) const +{ + return getUnsignedHex( nElement ).get( nDefault ); +} + +sal_Int64 AttributeList::getHyperHex( sal_Int32 nElement, sal_Int64 nDefault ) const +{ + return getHyperHex( nElement ).get( nDefault ); +} + +bool AttributeList::getBool( sal_Int32 nElement, bool bDefault ) const +{ + return getBool( nElement ).get( bDefault ); +} + +DateTime AttributeList::getDateTime( sal_Int32 nElement, const DateTime& rDefault ) const +{ + return getDateTime( nElement ).get( rDefault ); +} + +// ============================================================================ + +} // namespace oox + diff --git a/oox/source/helper/binaryinputstream.cxx b/oox/source/helper/binaryinputstream.cxx new file mode 100644 index 000000000000..5ba4a8b0b73b --- /dev/null +++ b/oox/source/helper/binaryinputstream.cxx @@ -0,0 +1,239 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/helper/binaryinputstream.hxx" +#include <string.h> +#include <vector> +#include <rtl/strbuf.hxx> +#include <rtl/ustrbuf.hxx> + +using ::rtl::OString; +using ::rtl::OStringBuffer; +using ::rtl::OStringToOUString; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::io::XInputStream; +using ::com::sun::star::io::XSeekable; + +namespace oox { + +const sal_Int32 INPUTSTREAM_BUFFERSIZE = 0x8000; + +// ============================================================================ + +OString BinaryInputStream::readNulCharArray() +{ + OStringBuffer aBuffer; + for( sal_uInt8 nChar = readuInt8(); !mbEof && (nChar > 0); readValue( nChar ) ) + aBuffer.append( static_cast< sal_Char >( nChar ) ); + return aBuffer.makeStringAndClear(); +} + +OUString BinaryInputStream::readNulCharArrayUC( rtl_TextEncoding eTextEnc ) +{ + return OStringToOUString( readNulCharArray(), eTextEnc ); +} + +OUString BinaryInputStream::readNulUnicodeArray() +{ + OUStringBuffer aBuffer; + for( sal_uInt16 nChar = readuInt16(); !mbEof && (nChar > 0); readValue( nChar ) ) + aBuffer.append( static_cast< sal_Unicode >( nChar ) ); + return aBuffer.makeStringAndClear(); +} + +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 ) ); + if( !bAllowNulChars ) + ::std::replace( aBuffer.begin(), aBuffer.begin() + nCharsRead, '\0', '?' ); + return OString( &aBuffer.front(), nCharsRead ); +} + +OUString BinaryInputStream::readCharArrayUC( sal_Int32 nChars, rtl_TextEncoding eTextEnc, bool bAllowNulChars ) +{ + return OStringToOUString( readCharArray( nChars, bAllowNulChars ), eTextEnc ); +} + +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(); +} + +void BinaryInputStream::readAtom( void* opMem, sal_uInt8 nSize ) +{ + readMemory( opMem, nSize ); +} + +// ============================================================================ + +BinaryXInputStream::BinaryXInputStream( const Reference< XInputStream >& rxInStrm, bool bAutoClose ) : + BinaryXSeekableStream( Reference< XSeekable >( rxInStrm, UNO_QUERY ) ), + maBuffer( INPUTSTREAM_BUFFERSIZE ), + mxInStrm( rxInStrm ), + mbAutoClose( bAutoClose ) +{ + mbEof = !mxInStrm.is(); +} + +BinaryXInputStream::~BinaryXInputStream() +{ + if( mbAutoClose ) + close(); +} + +sal_Int32 BinaryXInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes ) +{ + 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; + } + catch( Exception& ) + { + mbEof = true; + } + return nRet; +} + +sal_Int32 BinaryXInputStream::readMemory( void* opMem, sal_Int32 nBytes ) +{ + sal_Int32 nRet = 0; + if( !mbEof && (nBytes > 0) ) + { + sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, INPUTSTREAM_BUFFERSIZE ); + sal_uInt8* opnMem = reinterpret_cast< sal_uInt8* >( opMem ); + while( !mbEof && (nBytes > 0) ) + { + sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, nBufferSize ); + sal_Int32 nBytesRead = readData( maBuffer, nReadSize ); + if( nBytesRead > 0 ) + memcpy( opnMem, maBuffer.getConstArray(), static_cast< size_t >( nBytesRead ) ); + opnMem += nBytesRead; + nBytes -= nBytesRead; + nRet += nBytesRead; + } + } + return nRet; +} + +void BinaryXInputStream::skip( sal_Int32 nBytes ) +{ + if( !mbEof ) try + { + OSL_ENSURE( mxInStrm.is(), "BinaryXInputStream::skip - invalid call" ); + mxInStrm->skipBytes( nBytes ); + } + catch( Exception& ) + { + mbEof = true; + } +} + +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 ) : + SequenceSeekableStream( rData ) +{ +} + +sal_Int32 SequenceInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes ) +{ + sal_Int32 nReadBytes = 0; + if( !mbEof ) + { + nReadBytes = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mrData.getLength() - mnPos ); + orData.realloc( nReadBytes ); + if( nReadBytes > 0 ) + memcpy( orData.getArray(), mrData.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 nReadBytes = 0; + if( !mbEof ) + { + nReadBytes = ::std::min< sal_Int32 >( nBytes, mrData.getLength() - mnPos ); + if( nReadBytes > 0 ) + memcpy( opMem, mrData.getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) ); + mnPos += nReadBytes; + mbEof = nReadBytes < nBytes; + } + return nReadBytes; +} + +void SequenceInputStream::skip( sal_Int32 nBytes ) +{ + if( !mbEof ) + { + sal_Int32 nSkipBytes = ::std::min< sal_Int32 >( nBytes, mrData.getLength() - mnPos ); + mnPos += nSkipBytes; + mbEof = nSkipBytes < nBytes; + } +} + +// ============================================================================ + +} // namespace oox + diff --git a/oox/source/helper/binaryoutputstream.cxx b/oox/source/helper/binaryoutputstream.cxx new file mode 100644 index 000000000000..be6bc6d67577 --- /dev/null +++ b/oox/source/helper/binaryoutputstream.cxx @@ -0,0 +1,157 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/helper/binaryoutputstream.hxx" +#include <osl/diagnose.h> +#include "oox/helper/binaryinputstream.hxx" +#include <string.h> + +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::io::XOutputStream; +using ::com::sun::star::io::XSeekable; + +namespace oox { + +const sal_Int32 OUTPUTSTREAM_BUFFERSIZE = 0x8000; + +// ============================================================================ + +void BinaryOutputStream::copyStream( BinaryInputStream& rInStrm, sal_Int64 nBytes ) +{ + if( nBytes > 0 ) + { + sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, OUTPUTSTREAM_BUFFERSIZE ); + StreamDataSequence aBuffer( nBufferSize ); + while( nBytes > 0 ) + { + sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, nBufferSize ); + sal_Int32 nBytesRead = rInStrm.readData( aBuffer, nReadSize ); + writeData( aBuffer ); + if( nReadSize == nBytesRead ) + nBytes -= nReadSize; + else + nBytes = 0; + } + } +} + +void BinaryOutputStream::writeAtom( const void* pMem, sal_uInt8 nSize ) +{ + writeMemory( pMem, nSize ); +} + +// ============================================================================ + +BinaryXOutputStream::BinaryXOutputStream( const Reference< XOutputStream >& rxOutStrm, bool bAutoClose ) : + BinaryXSeekableStream( Reference< XSeekable >( rxOutStrm, UNO_QUERY ) ), + maBuffer( OUTPUTSTREAM_BUFFERSIZE ), + mxOutStrm( rxOutStrm ), + mbAutoClose( bAutoClose ) +{ + mbEof = !mxOutStrm.is(); +} + +BinaryXOutputStream::~BinaryXOutputStream() +{ + if( mbAutoClose ) + close(); +} + +void BinaryXOutputStream::writeData( const StreamDataSequence& rData ) +{ + try + { + OSL_ENSURE( mxOutStrm.is(), "BinaryXOutputStream::writeData - invalid call" ); + mxOutStrm->writeBytes( rData ); + } + catch( Exception& ) + { + OSL_ENSURE( false, "BinaryXOutputStream::writeData - stream read error" ); + } +} + +void BinaryXOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes ) +{ + if( nBytes > 0 ) + { + sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, OUTPUTSTREAM_BUFFERSIZE ); + 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 ); + 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 ) : + SequenceSeekableStream( rData ) +{ +} + +void SequenceOutputStream::writeData( const StreamDataSequence& rData ) +{ + if( rData.hasElements() ) + writeMemory( rData.getConstArray(), rData.getLength() ); +} + +void SequenceOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes ) +{ + if( 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 ) ); + mnPos += nBytes; + } +} + +// ============================================================================ + +} // namespace oox + diff --git a/oox/source/helper/binarystreambase.cxx b/oox/source/helper/binarystreambase.cxx new file mode 100644 index 000000000000..be6b17d3aab9 --- /dev/null +++ b/oox/source/helper/binarystreambase.cxx @@ -0,0 +1,144 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/helper/binarystreambase.hxx" +#include <osl/diagnose.h> + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::io::XSeekable; + +namespace oox { + +// ============================================================================ + +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 +{ + return isSeekable() ? ::std::max< sal_Int64 >( getLength() - tell(), 0 ) : -1; +} + +// ============================================================================ + +BinaryXSeekableStream::BinaryXSeekableStream( const Reference< XSeekable >& rxSeekable ) : + mxSeekable( rxSeekable ) +{ +} + +bool BinaryXSeekableStream::isSeekable() const +{ + return mxSeekable.is(); +} + +sal_Int64 BinaryXSeekableStream::getLength() const +{ + if( mxSeekable.is() ) try + { + return mxSeekable->getLength(); + } + catch( Exception& ) + { + OSL_ENSURE( false, "BinaryXSeekableStream::getLength - exception caught" ); + } + return -1; +} + +sal_Int64 BinaryXSeekableStream::tell() const +{ + if( mxSeekable.is() ) try + { + return mxSeekable->getPosition(); + } + catch( Exception& ) + { + OSL_ENSURE( false, "BinaryXSeekableStream::tell - exception caught" ); + } + return -1; +} + +void BinaryXSeekableStream::seek( sal_Int64 nPos ) +{ + if( mxSeekable.is() ) try + { + mbEof = false; + mxSeekable->seek( nPos ); + } + catch( Exception& ) + { + mbEof = true; + } +} + +// ============================================================================ + +bool SequenceSeekableStream::isSeekable() const +{ + return true; +} + +sal_Int64 SequenceSeekableStream::getLength() const +{ + return mrData.getLength(); +} + +sal_Int64 SequenceSeekableStream::tell() const +{ + return mnPos; +} + +void SequenceSeekableStream::seek( sal_Int64 nPos ) +{ + mnPos = getLimitedValue< sal_Int32, sal_Int64 >( nPos, 0, mrData.getLength() ); + mbEof = mnPos < nPos; +} + +// ============================================================================ + +} // namespace oox + diff --git a/oox/source/helper/containerhelper.cxx b/oox/source/helper/containerhelper.cxx new file mode 100644 index 000000000000..359bc87e09e9 --- /dev/null +++ b/oox/source/helper/containerhelper.cxx @@ -0,0 +1,224 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/helper/containerhelper.hxx" +#include <rtl/ustrbuf.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include "oox/helper/helper.hxx" + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::lang::XMultiServiceFactory; +using ::com::sun::star::container::XIndexContainer; +using ::com::sun::star::container::XNameAccess; +using ::com::sun::star::container::XNameContainer; + +namespace oox { + +// ============================================================================ + +Reference< XIndexContainer > ContainerHelper::createIndexContainer( const Reference< XMultiServiceFactory >& rxFactory ) +{ + Reference< XIndexContainer > xContainer; + if( rxFactory.is() ) try + { + xContainer.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.IndexedPropertyValues" ) ), UNO_QUERY_THROW ); + } + catch( Exception& ) + { + } + OSL_ENSURE( xContainer.is(), "ContainerHelper::createIndexContainer - cannot create container" ); + return xContainer; +} + +bool ContainerHelper::insertByIndex( + const Reference< XIndexContainer >& rxIndexContainer, + sal_Int32 nIndex, const Any& rObject ) +{ + OSL_ENSURE( rxIndexContainer.is(), "ContainerHelper::insertByIndex - missing XIndexContainer interface" ); + bool bRet = false; + try + { + rxIndexContainer->insertByIndex( nIndex, rObject ); + bRet = true; + } + catch( Exception& ) + { + } + OSL_ENSURE( bRet, "ContainerHelper::insertByIndex - cannot insert object" ); + return bRet; +} + +Reference< XNameContainer > ContainerHelper::createNameContainer( const Reference< XMultiServiceFactory >& rxFactory ) +{ + Reference< XNameContainer > xContainer; + if( rxFactory.is() ) try + { + xContainer.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.NamedPropertyValues" ) ), UNO_QUERY_THROW ); + } + catch( Exception& ) + { + } + OSL_ENSURE( xContainer.is(), "ContainerHelper::createNameContainer - cannot create container" ); + return xContainer; +} + +OUString ContainerHelper::getUnusedName( + const Reference< XNameAccess >& rxNameAccess, const OUString& rSuggestedName, + sal_Unicode cSeparator, sal_Int32 nFirstIndexToAppend ) +{ + OSL_ENSURE( rxNameAccess.is(), "ContainerHelper::getUnusedName - missing XNameAccess interface" ); + + OUString aNewName = rSuggestedName; + sal_Int32 nIndex = nFirstIndexToAppend; + while( rxNameAccess->hasByName( aNewName ) ) + aNewName = OUStringBuffer( rSuggestedName ).append( cSeparator ).append( nIndex++ ).makeStringAndClear(); + return aNewName; +} + +bool ContainerHelper::insertByName( + const Reference< XNameContainer >& rxNameContainer, + const OUString& rName, const Any& rObject, bool bReplaceOldExisting ) +{ + OSL_ENSURE( rxNameContainer.is(), "ContainerHelper::insertByName - missing XNameContainer interface" ); + bool bRet = false; + try + { + if( bReplaceOldExisting && rxNameContainer->hasByName( rName ) ) + rxNameContainer->replaceByName( rName, rObject ); + else + rxNameContainer->insertByName( rName, rObject ); + bRet = true; + } + catch( Exception& ) + { + } + OSL_ENSURE( bRet, "ContainerHelper::insertByName - cannot insert object" ); + return bRet; +} + +OUString ContainerHelper::insertByUnusedName( + const Reference< XNameContainer >& rxNameContainer, + const OUString& rSuggestedName, sal_Unicode cSeparator, + const Any& rObject, bool bRenameOldExisting ) +{ + OSL_ENSURE( rxNameContainer.is(), "ContainerHelper::insertByUnusedName - missing XNameContainer interface" ); + + // find an unused name + Reference< XNameAccess > xNameAccess( rxNameContainer, UNO_QUERY ); + OUString aNewName = getUnusedName( xNameAccess, rSuggestedName, cSeparator ); + + // rename existing object + if( bRenameOldExisting && rxNameContainer->hasByName( rSuggestedName ) ) + { + try + { + Any aOldObject = rxNameContainer->getByName( rSuggestedName ); + rxNameContainer->removeByName( rSuggestedName ); + rxNameContainer->insertByName( aNewName, aOldObject ); + aNewName = rSuggestedName; + } + catch( Exception& ) + { + OSL_ENSURE( false, "ContainerHelper::insertByUnusedName - cannot rename old object" ); + } + } + + // insert the new object and return its resulting name + insertByName( rxNameContainer, aNewName, rObject ); + return aNewName; +} + +// ============================================================================ + +ObjectContainer::ObjectContainer( const Reference< XMultiServiceFactory >& rxFactory, const OUString& rServiceName ) : + mxFactory( rxFactory ), + maServiceName( rServiceName ), + mnIndex( 0 ) +{ + OSL_ENSURE( mxFactory.is(), "ObjectContainer::ObjectContainer - missing service factory" ); +} + +ObjectContainer::~ObjectContainer() +{ +} + +bool ObjectContainer::hasObject( const OUString& rObjName ) const +{ + createContainer(); + return mxContainer.is() && mxContainer->hasByName( rObjName ); +} + +Any ObjectContainer::getObject( const OUString& rObjName ) const +{ + createContainer(); + if( mxContainer.is() ) try + { + return mxContainer->getByName( rObjName ); + } + catch( Exception& ) + { + } + return Any(); +} + +OUString ObjectContainer::insertObject( const OUString& rObjName, const Any& rObj, bool bInsertByUnusedName ) +{ + createContainer(); + if( mxContainer.is() ) + { + if( bInsertByUnusedName ) + return ContainerHelper::insertByUnusedName( mxContainer, rObjName + OUString::valueOf( ++mnIndex ), ' ', rObj ); + if( ContainerHelper::insertByName( mxContainer, rObjName, rObj ) ) + return rObjName; + } + return OUString(); +} + +void ObjectContainer::createContainer() const +{ + if( !mxContainer.is() && mxFactory.is() ) try + { + mxContainer.set( mxFactory->createInstance( maServiceName ), UNO_QUERY_THROW ); + } + catch( Exception& ) + { + } + OSL_ENSURE( mxContainer.is(), "ObjectContainer::createContainer - container not found" ); +} + +// ============================================================================ + +} // namespace oox + diff --git a/oox/source/helper/graphichelper.cxx b/oox/source/helper/graphichelper.cxx new file mode 100644 index 000000000000..3e54cd16c2bc --- /dev/null +++ b/oox/source/helper/graphichelper.cxx @@ -0,0 +1,120 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/helper/graphichelper.hxx" +#include <com/sun/star/graphic/GraphicObject.hpp> +#include <com/sun/star/graphic/XGraphicProvider.hpp> +#include <comphelper/componentcontext.hxx> +#include <comphelper/seqstream.hxx> + +using ::rtl::OUString; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_SET_THROW; +using ::com::sun::star::beans::PropertyValue; +using ::com::sun::star::io::XInputStream; +using ::com::sun::star::lang::XMultiServiceFactory; +using ::com::sun::star::graphic::GraphicObject; +using ::com::sun::star::graphic::XGraphic; +using ::com::sun::star::graphic::XGraphicObject; +using ::com::sun::star::graphic::XGraphicProvider; + +namespace oox { + +// ============================================================================ + +GraphicHelper::GraphicHelper( const Reference< XMultiServiceFactory >& rxFactory ) : + mxGraphicProvider( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.graphic.GraphicProvider" ) ), UNO_QUERY ), + maGraphicObjScheme( CREATE_OUSTRING( "vnd.sun.star.GraphicObject:" ) ) +{ + ::comphelper::ComponentContext aContext( rxFactory ); + mxCompContext = aContext.getUNOContext(); +} + +GraphicHelper::~GraphicHelper() +{ +} + +Reference< XGraphic > GraphicHelper::importGraphic( const Reference< XInputStream >& rxInStrm ) +{ + Reference< XGraphic > xGraphic; + if( rxInStrm.is() && mxGraphicProvider.is() ) try + { + Sequence< PropertyValue > aArgs( 1 ); + aArgs[ 0 ].Name = CREATE_OUSTRING( "InputStream" ); + aArgs[ 0 ].Value <<= rxInStrm; + xGraphic = mxGraphicProvider->queryGraphic( aArgs ); + } + catch( Exception& ) + { + } + return xGraphic; +} + +Reference< XGraphic > GraphicHelper::importGraphic( const StreamDataSequence& rGraphicData ) +{ + Reference< XGraphic > xGraphic; + if( rGraphicData.hasElements() ) + { + Reference< XInputStream > xInStrm( new ::comphelper::SequenceInputStream( rGraphicData ) ); + xGraphic = importGraphic( xInStrm ); + } + return xGraphic; +} + +OUString GraphicHelper::createGraphicObject( const Reference< XGraphic >& rxGraphic ) +{ + OUString aGraphicObjUrl; + if( mxCompContext.is() && rxGraphic.is() ) try + { + Reference< XGraphicObject > xGraphicObj( GraphicObject::create( mxCompContext ), UNO_SET_THROW ); + xGraphicObj->setGraphic( rxGraphic ); + maGraphicObjects.push_back( xGraphicObj ); + aGraphicObjUrl = maGraphicObjScheme + xGraphicObj->getUniqueID(); + } + catch( Exception& ) + { + } + return aGraphicObjUrl; +} + +OUString GraphicHelper::importGraphicObject( const Reference< XInputStream >& rxInStrm ) +{ + return createGraphicObject( importGraphic( rxInStrm ) ); +} + +OUString GraphicHelper::importGraphicObject( const StreamDataSequence& rGraphicData ) +{ + return createGraphicObject( importGraphic( rGraphicData ) ); +} + +// ============================================================================ + +} // namespace oox + diff --git a/oox/source/helper/makefile.mk b/oox/source/helper/makefile.mk new file mode 100644 index 000000000000..4a91a7a47764 --- /dev/null +++ b/oox/source/helper/makefile.mk @@ -0,0 +1,61 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=oox +TARGET=helper +AUTOSEG=true + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/attributelist.obj \ + $(SLO)$/binaryinputstream.obj \ + $(SLO)$/binaryoutputstream.obj \ + $(SLO)$/binarystreambase.obj \ + $(SLO)$/containerhelper.obj \ + $(SLO)$/graphichelper.obj \ + $(SLO)$/modelobjecthelper.obj \ + $(SLO)$/olestorage.obj \ + $(SLO)$/progressbar.obj \ + $(SLO)$/propertymap.obj \ + $(SLO)$/propertyset.obj \ + $(SLO)$/recordinputstream.obj \ + $(SLO)$/storagebase.obj \ + $(SLO)$/zipstorage.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/oox/source/helper/modelobjecthelper.cxx b/oox/source/helper/modelobjecthelper.cxx new file mode 100644 index 000000000000..d1996991090a --- /dev/null +++ b/oox/source/helper/modelobjecthelper.cxx @@ -0,0 +1,91 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/helper/modelobjecthelper.hxx" +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/awt/Gradient.hpp> +#include <com/sun/star/drawing/LineDash.hpp> +#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp> +#include "oox/helper/helper.hxx" + +using ::rtl::OUString; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::lang::XMultiServiceFactory; +using ::com::sun::star::awt::Gradient; +using ::com::sun::star::drawing::LineDash; +using ::com::sun::star::drawing::PolyPolygonBezierCoords; + +namespace oox { + +// ============================================================================ + +ModelObjectHelper::ModelObjectHelper( const Reference< XMultiServiceFactory >& rxFactory ) : + maMarkerContainer( rxFactory, CREATE_OUSTRING( "com.sun.star.drawing.MarkerTable" ) ), + maDashContainer( rxFactory, CREATE_OUSTRING( "com.sun.star.drawing.DashTable" ) ), + maGradientContainer( rxFactory, CREATE_OUSTRING( "com.sun.star.drawing.GradientTable" ) ), + maBitmapContainer( rxFactory, CREATE_OUSTRING( "com.sun.star.drawing.BitmapTable" ) ), + maDashNameBase( CREATE_OUSTRING( "msLineDash " ) ), + maGradientNameBase( CREATE_OUSTRING( "msFillGradient " ) ), + maBitmapNameBase( CREATE_OUSTRING( "msFillBitmap " ) ) +{ +} + +bool ModelObjectHelper::hasLineMarker( const OUString& rMarkerName ) const +{ + return maMarkerContainer.hasObject( rMarkerName ); +} + +bool ModelObjectHelper::insertLineMarker( const OUString& rMarkerName, const PolyPolygonBezierCoords& rMarker ) +{ + OSL_ENSURE( rMarker.Coordinates.hasElements(), "ModelObjectHelper::insertLineMarker - line marker without coordinates" ); + if( rMarker.Coordinates.hasElements() ) + return maMarkerContainer.insertObject( rMarkerName, Any( rMarker ), false ).getLength() > 0; + return false; +} + +OUString ModelObjectHelper::insertLineDash( const LineDash& rDash ) +{ + return maDashContainer.insertObject( maDashNameBase, Any( rDash ), true ); +} + +OUString ModelObjectHelper::insertFillGradient( const Gradient& rGradient ) +{ + return maGradientContainer.insertObject( maGradientNameBase, Any( rGradient ), true ); +} + +OUString ModelObjectHelper::insertFillBitmap( const OUString& rGraphicUrl ) +{ + if( rGraphicUrl.getLength() > 0 ) + return maBitmapContainer.insertObject( maBitmapNameBase, Any( rGraphicUrl ), true ); + return OUString(); +} + +// ============================================================================ + +} // namespace oox + diff --git a/oox/source/helper/olestorage.cxx b/oox/source/helper/olestorage.cxx new file mode 100644 index 000000000000..fe660b27ff2b --- /dev/null +++ b/oox/source/helper/olestorage.cxx @@ -0,0 +1,180 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/helper/olestorage.hxx" +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XStream.hpp> +#include "oox/helper/helper.hxx" + +using ::rtl::OUString; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::container::XNameAccess; +using ::com::sun::star::lang::XMultiServiceFactory; +using ::com::sun::star::beans::PropertyValue; +using ::com::sun::star::embed::XStorage; +using ::com::sun::star::io::XInputStream; +using ::com::sun::star::io::XOutputStream; +using ::com::sun::star::io::XStream; + +namespace oox { + +// ============================================================================ + +OleStorage::OleStorage( + const Reference< XMultiServiceFactory >& rxFactory, + const Reference< XInputStream >& rxInStream, + bool bBaseStreamAccess ) : + StorageBase( rxInStream, bBaseStreamAccess ) +{ + OSL_ENSURE( rxFactory.is(), "OleStorage::OleStorage - missing service factory" ); + // create base storage object + Sequence< Any > aArgs( 2 ); + aArgs[ 0 ] <<= rxInStream; + aArgs[ 1 ] <<= true; // true = do not create a copy of the input stream + mxStorage.set( rxFactory->createInstanceWithArguments( + CREATE_OUSTRING( "com.sun.star.embed.OLESimpleStorage" ), aArgs ), UNO_QUERY ); + mxElements.set( mxStorage, UNO_QUERY ); +} + +OleStorage::OleStorage( + const Reference< XMultiServiceFactory >& rxFactory, + const Reference< XStream >& rxStream, + bool bBaseStreamAccess ) : + StorageBase( rxStream, bBaseStreamAccess ) +{ + OSL_ENSURE( rxFactory.is(), "OleStorage::OleStorage - missing service factory" ); + (void)rxFactory; // prevent compiler warning + OSL_ENSURE( false, "OleStorage::OleStorage - not implemented" ); + mxElements.set( mxStorage, UNO_QUERY ); +} + +OleStorage::OleStorage( const OleStorage& rParentStorage, const Reference< XNameAccess >& rxElementsAccess, const OUString& rElementName ) : + StorageBase( rParentStorage, rElementName ), + mxStorage( rParentStorage.mxStorage ), + mxElements( rxElementsAccess ) +{ + OSL_ENSURE( mxElements.is(), "OleStorage::OleStorage - missing elements access" ); +} + +OleStorage::~OleStorage() +{ +} + +// StorageBase interface ------------------------------------------------------ + +bool OleStorage::implIsStorage() const +{ + if( mxStorage.is() && mxElements.is() ) try + { + /* If this is not a storage, hasElements() throws an exception. But we + do not return the result of hasElements(), because an empty storage + is a valid storage too. */ + mxElements->hasElements(); + return true; + } + catch( Exception& ) + { + } + return false; +} + +Reference< XStorage > OleStorage::implGetXStorage() const +{ + OSL_ENSURE( false, "OleStorage::getXStorage - not implemented" ); + return Reference< XStorage >(); +} + +void OleStorage::implGetElementNames( ::std::vector< OUString >& orElementNames ) const +{ + Sequence< OUString > aNames; + if( mxElements.is() ) try + { + aNames = mxElements->getElementNames(); + if( aNames.getLength() > 0 ) + orElementNames.insert( orElementNames.end(), aNames.getConstArray(), aNames.getConstArray() + aNames.getLength() ); + } + catch( Exception& ) + { + } +} + +StorageRef OleStorage::implOpenSubStorage( const OUString& rElementName, bool bCreate ) +{ + OSL_ENSURE( !bCreate, "OleStorage::implOpenSubStorage - creating substorages not implemented" ); + (void)bCreate; // prevent compiler warning + StorageRef xSubStorage; + if( mxElements.is() ) try + { + Reference< XNameAccess > xSubElements( mxElements->getByName( rElementName ), UNO_QUERY_THROW ); + xSubStorage.reset( new OleStorage( *this, xSubElements, rElementName ) ); + } + catch( Exception& ) + { + } + return xSubStorage; +} + +Reference< XInputStream > OleStorage::implOpenInputStream( const OUString& rElementName ) +{ + Reference< XInputStream > xInStream; + if( mxElements.is() ) try + { + xInStream.set( mxElements->getByName( rElementName ), UNO_QUERY ); + } + catch( Exception& ) + { + } + return xInStream; +} + +Reference< XOutputStream > OleStorage::implOpenOutputStream( const OUString& rElementName ) +{ + Reference< XOutputStream > xOutStream; + if( mxElements.is() && (rElementName.getLength() > 0) ) try + { + (void)rElementName; // prevent compiler warning + OSL_ENSURE( false, "OleStorage::implOpenOutputStream - not implemented" ); + } + catch( Exception& ) + { + } + return xOutStream; +} + +// ============================================================================ + +} // namespace oox + diff --git a/oox/source/helper/progressbar.cxx b/oox/source/helper/progressbar.cxx new file mode 100644 index 000000000000..6934f2dcf8d3 --- /dev/null +++ b/oox/source/helper/progressbar.cxx @@ -0,0 +1,185 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/helper/progressbar.hxx" +#include <com/sun/star/task/XStatusIndicator.hpp> +#include "oox/helper/helper.hxx" + +using ::rtl::OUString; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::task::XStatusIndicator; + +namespace oox { + +// ============================================================================ + +namespace { + +const sal_Int32 PROGRESS_RANGE = 1000000; + +} // namespace + +// ============================================================================ + +IProgressBar::~IProgressBar() +{ +} + +// ---------------------------------------------------------------------------- + +ISegmentProgressBar::~ISegmentProgressBar() +{ +} + +// ============================================================================ +// ============================================================================ + +ProgressBar::ProgressBar( const Reference< XStatusIndicator >& rxIndicator, const OUString& rText ) : + mxIndicator( rxIndicator ), + mfPosition( 0 ) +{ + if( mxIndicator.is() ) + mxIndicator->start( rText, PROGRESS_RANGE ); +} + +ProgressBar::~ProgressBar() +{ + if( mxIndicator.is() ) + mxIndicator->end(); +} + +double ProgressBar::getPosition() const +{ + return mfPosition; +} + +void ProgressBar::setPosition( double fPosition ) +{ + OSL_ENSURE( (mfPosition <= fPosition) && (fPosition <= 1.0), "ProgressBar::setPosition - invalid position" ); + mfPosition = getLimitedValue< double >( fPosition, mfPosition, 1.0 ); + if( mxIndicator.is() ) + mxIndicator->setValue( static_cast< sal_Int32 >( mfPosition * PROGRESS_RANGE ) ); +} + +// ============================================================================ + +namespace prv { + +class SubSegment : public ISegmentProgressBar +{ +public: + explicit SubSegment( IProgressBar& rParentProgress, double fStartPos, double fLength ); + + virtual double getPosition() const; + virtual void setPosition( double fPosition ); + + virtual double getFreeLength() const; + virtual ISegmentProgressBarRef createSegment( double fLength ); + +private: + IProgressBar& mrParentProgress; + double mfStartPos; + double mfLength; + double mfPosition; + double mfFreeStart; +}; + +// ---------------------------------------------------------------------------- + +SubSegment::SubSegment( IProgressBar& rParentProgress, double fStartPos, double fLength ) : + mrParentProgress( rParentProgress ), + mfStartPos( fStartPos ), + mfLength( fLength ), + mfPosition( 0.0 ), + mfFreeStart( 0.0 ) +{ +} + +double SubSegment::getPosition() const +{ + return mfPosition; +} + +void SubSegment::setPosition( double fPosition ) +{ + OSL_ENSURE( (mfPosition <= fPosition) && (fPosition <= 1.0), "SubSegment::setPosition - invalid position" ); + mfPosition = getLimitedValue< double >( fPosition, mfPosition, 1.0 ); + mrParentProgress.setPosition( mfStartPos + mfPosition * mfLength ); +} + +double SubSegment::getFreeLength() const +{ + return 1.0 - mfFreeStart; +} + +ISegmentProgressBarRef SubSegment::createSegment( double fLength ) +{ + OSL_ENSURE( (0.0 < fLength) && (fLength <= getFreeLength()), "SubSegment::createSegment - invalid length" ); + fLength = getLimitedValue< double >( fLength, 0.0, getFreeLength() ); + ISegmentProgressBarRef xSegment( new prv::SubSegment( *this, mfFreeStart, fLength ) ); + mfFreeStart += fLength; + return xSegment; +} + +} // namespace prv + +// ============================================================================ + +SegmentProgressBar::SegmentProgressBar( const Reference< XStatusIndicator >& rxIndicator, const OUString& rText ) : + maProgress( rxIndicator, rText ), + mfFreeStart( 0.0 ) +{ +} + +double SegmentProgressBar::getPosition() const +{ + return maProgress.getPosition(); +} + +void SegmentProgressBar::setPosition( double fPosition ) +{ + maProgress.setPosition( fPosition ); +} + +double SegmentProgressBar::getFreeLength() const +{ + return 1.0 - mfFreeStart; +} + +ISegmentProgressBarRef SegmentProgressBar::createSegment( double fLength ) +{ + OSL_ENSURE( (0.0 < fLength) && (fLength <= getFreeLength()), "SegmentProgressBar::createSegment - invalid length" ); + fLength = getLimitedValue< double >( fLength, 0.0, getFreeLength() ); + ISegmentProgressBarRef xSegment( new prv::SubSegment( maProgress, mfFreeStart, fLength ) ); + mfFreeStart += fLength; + return xSegment; +} + +// ============================================================================ + +} // namespace oox + diff --git a/oox/source/helper/propertymap.cxx b/oox/source/helper/propertymap.cxx new file mode 100644 index 000000000000..9ff791fd21f3 --- /dev/null +++ b/oox/source/helper/propertymap.cxx @@ -0,0 +1,234 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/helper/propertymap.hxx" +#include <osl/mutex.hxx> +#include <cppuhelper/implbase2.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include "properties.hxx" +#include "oox/token/propertylist.hxx" + +using ::rtl::OUString; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::RuntimeException; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::lang::IllegalArgumentException; +using ::com::sun::star::lang::WrappedTargetException; +using ::com::sun::star::beans::Property; +using ::com::sun::star::beans::PropertyValue; +using ::com::sun::star::beans::PropertyVetoException; +using ::com::sun::star::beans::UnknownPropertyException; +using ::com::sun::star::beans::XPropertyChangeListener; +using ::com::sun::star::beans::XPropertySet; +using ::com::sun::star::beans::XPropertySetInfo; +using ::com::sun::star::beans::XVetoableChangeListener; + +namespace oox { + +// ============================================================================ + +namespace { + +/** Thread-save singleton of a vector of all supported property names. */ +struct StaticPropertyList : public ::rtl::Static< PropertyList, StaticPropertyList > {}; + +// ---------------------------------------------------------------------------- + +typedef ::cppu::WeakImplHelper2< XPropertySet, XPropertySetInfo > GenericPropertySetImplBase; + +/** This class implements a generic XPropertySet. + + Properties of all names and types can be set and later retrieved. + TODO: move this to comphelper or better find an existing implementation + */ +class GenericPropertySet : public GenericPropertySetImplBase, private ::osl::Mutex +{ +public: + explicit GenericPropertySet(); + explicit GenericPropertySet( const PropertyMap& rPropMap ); + + // XPropertySet + virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo() throw (RuntimeException); + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException); + virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException); + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException); + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException); + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException); + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException); + + // XPropertySetInfo + virtual Sequence< Property > SAL_CALL getProperties() throw (RuntimeException); + virtual Property SAL_CALL getPropertyByName( const OUString& aName ) throw (UnknownPropertyException, RuntimeException); + virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) throw (RuntimeException); + +private: + typedef ::std::map< OUString, Any > PropertyNameMap; + PropertyNameMap maPropMap; +}; + +// ---------------------------------------------------------------------------- + +GenericPropertySet::GenericPropertySet() +{ +} + +GenericPropertySet::GenericPropertySet( const PropertyMap& rPropMap ) +{ + const PropertyList& rPropNames = StaticPropertyList::get(); + for( PropertyMap::const_iterator aIt = rPropMap.begin(), aEnd = rPropMap.end(); aIt != aEnd; ++aIt ) + maPropMap[ rPropNames[ aIt->first ] ] = aIt->second; +} + +Reference< XPropertySetInfo > SAL_CALL GenericPropertySet::getPropertySetInfo() throw (RuntimeException) +{ + return this; +} + +void SAL_CALL GenericPropertySet::setPropertyValue( const OUString& rPropertyName, const Any& rValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + ::osl::MutexGuard aGuard( *this ); + maPropMap[ rPropertyName ] = rValue; +} + +Any SAL_CALL GenericPropertySet::getPropertyValue( const OUString& rPropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + PropertyNameMap::iterator aIt = maPropMap.find( rPropertyName ); + if( aIt == maPropMap.end() ) + throw UnknownPropertyException(); + return aIt->second; +} + +// listeners are not supported by this implementation +void SAL_CALL GenericPropertySet::addPropertyChangeListener( const OUString& , const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {} +void SAL_CALL GenericPropertySet::removePropertyChangeListener( const OUString& , const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {} +void SAL_CALL GenericPropertySet::addVetoableChangeListener( const OUString& , const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {} +void SAL_CALL GenericPropertySet::removeVetoableChangeListener( const OUString& , const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {} + +// XPropertySetInfo +Sequence< Property > SAL_CALL GenericPropertySet::getProperties() throw (RuntimeException) +{ + Sequence< Property > aSeq( static_cast< sal_Int32 >( maPropMap.size() ) ); + Property* pProperty = aSeq.getArray(); + for( PropertyNameMap::iterator aIt = maPropMap.begin(), aEnd = maPropMap.end(); aIt != aEnd; ++aIt, ++pProperty ) + { + pProperty->Name = aIt->first; + pProperty->Handle = 0; + pProperty->Type = aIt->second.getValueType(); + pProperty->Attributes = 0; + } + return aSeq; +} + +Property SAL_CALL GenericPropertySet::getPropertyByName( const OUString& rPropertyName ) throw (UnknownPropertyException, RuntimeException) +{ + PropertyNameMap::iterator aIt = maPropMap.find( rPropertyName ); + if( aIt == maPropMap.end() ) + throw UnknownPropertyException(); + Property aProperty; + aProperty.Name = aIt->first; + aProperty.Handle = 0; + aProperty.Type = aIt->second.getValueType(); + aProperty.Attributes = 0; + return aProperty; +} + +sal_Bool SAL_CALL GenericPropertySet::hasPropertyByName( const OUString& rPropertyName ) throw (RuntimeException) +{ + return maPropMap.find( rPropertyName ) != maPropMap.end(); +} + +} // namespace + +// ============================================================================ + +PropertyMap::PropertyMap() : + mpPropNames( &StaticPropertyList::get() ) +{ +} + +PropertyMap::~PropertyMap() +{ +} + +/*static*/ const OUString& PropertyMap::getPropertyName( sal_Int32 nPropId ) +{ + OSL_ENSURE( (0 <= nPropId) && (nPropId < PROP_COUNT), "PropertyMap::getPropertyName - invalid property identifier" ); + return StaticPropertyList::get()[ nPropId ]; +} + +const Any* PropertyMap::getProperty( sal_Int32 nPropId ) const +{ + const_iterator aIt = find( nPropId ); + return (aIt == end()) ? 0 : &aIt->second; +} + +Sequence< PropertyValue > PropertyMap::makePropertyValueSequence() const +{ + Sequence< PropertyValue > aSeq( static_cast< sal_Int32 >( size() ) ); + if( !empty() ) + { + PropertyValue* pValues = aSeq.getArray(); + for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt, ++pValues ) + { + OSL_ENSURE( (0 <= aIt->first) && (aIt->first < PROP_COUNT), "PropertyMap::makePropertyValueSequence - invalid property identifier" ); + pValues->Name = (*mpPropNames)[ aIt->first ]; + pValues->Value = aIt->second; + pValues->State = ::com::sun::star::beans::PropertyState_DIRECT_VALUE; + } + } + return aSeq; +} + +void PropertyMap::fillSequences( Sequence< OUString >& rNames, Sequence< Any >& rValues ) const +{ + rNames.realloc( static_cast< sal_Int32 >( size() ) ); + rValues.realloc( static_cast< sal_Int32 >( size() ) ); + if( !empty() ) + { + OUString* pNames = rNames.getArray(); + Any* pValues = rValues.getArray(); + for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt, ++pNames, ++pValues ) + { + OSL_ENSURE( (0 <= aIt->first) && (aIt->first < PROP_COUNT), "PropertyMap::fillSequences - invalid property identifier" ); + *pNames = (*mpPropNames)[ aIt->first ]; + *pValues = aIt->second; + } + } +} + +Reference< XPropertySet > PropertyMap::makePropertySet() const +{ + return new GenericPropertySet( *this ); +} + +// ============================================================================ + +} // namespace oox + diff --git a/oox/source/helper/propertyset.cxx b/oox/source/helper/propertyset.cxx new file mode 100644 index 000000000000..5477224b9461 --- /dev/null +++ b/oox/source/helper/propertyset.cxx @@ -0,0 +1,174 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/helper/propertyset.hxx" +#include <rtl/strbuf.hxx> +#include <osl/diagnose.h> +#include "oox/helper/propertymap.hxx" + +using ::rtl::OUString; +using ::rtl::OStringBuffer; +using ::rtl::OUStringToOString; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::beans::XPropertySet; + +namespace oox { + +// ============================================================================ + +void PropertySet::set( const Reference< XPropertySet >& rxPropSet ) +{ + mxPropSet = rxPropSet; + mxMultiPropSet.set( mxPropSet, UNO_QUERY ); +} + +// Get properties ------------------------------------------------------------- + +bool PropertySet::getAnyProperty( Any& orValue, sal_Int32 nPropId ) const +{ + return getAnyProperty( orValue, PropertyMap::getPropertyName( nPropId ) ); +} + +bool PropertySet::getBoolProperty( sal_Int32 nPropId ) const +{ + Any aAny; + bool bValue = false; + return getAnyProperty( aAny, nPropId ) && (aAny >>= bValue) && bValue; +} + +void PropertySet::getProperties( Sequence< Any >& orValues, const Sequence< OUString >& rPropNames ) const +{ + if( mxMultiPropSet.is() ) // first try the XMultiPropertySet + { + try + { + orValues = mxMultiPropSet->getPropertyValues( rPropNames ); + } + catch( Exception& ) + { + OSL_ENSURE( false, "PropertySet::getProperties - cannot get all property values" ); + } + } + else if( mxPropSet.is() ) + { + sal_Int32 nLen = rPropNames.getLength(); + const OUString* pPropName = rPropNames.getConstArray(); + const OUString* pPropNameEnd = pPropName + nLen; + orValues.realloc( nLen ); + Any* pValue = orValues.getArray(); + for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue ) + getAnyProperty( *pValue, *pPropName ); + } +} + +// Set properties ------------------------------------------------------------- + +void PropertySet::setAnyProperty( sal_Int32 nPropId, const Any& rValue ) +{ + setAnyProperty( PropertyMap::getPropertyName( nPropId ), rValue ); +} + +void PropertySet::setProperties( const Sequence< OUString >& rPropNames, const Sequence< Any >& rValues ) +{ + OSL_ENSURE( rPropNames.getLength() == rValues.getLength(), + "PropertySet::setProperties - length of sequences different" ); + + if( mxMultiPropSet.is() ) // first try the XMultiPropertySet + { + try + { + mxMultiPropSet->setPropertyValues( rPropNames, rValues ); + } + catch( Exception& ) + { + OSL_ENSURE( false, "PropertySet::setProperties - cannot set all property values" ); + } + } + else if( mxPropSet.is() ) + { + const OUString* pPropName = rPropNames.getConstArray(); + const OUString* pPropNameEnd = pPropName + rPropNames.getLength(); + const Any* pValue = rValues.getConstArray(); + for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue ) + setAnyProperty( *pPropName, *pValue ); + } +} + +void PropertySet::setProperties( const PropertyMap& rPropertyMap ) +{ + if( !rPropertyMap.empty() ) + { + Sequence< OUString > aPropNames; + Sequence< Any > aValues; + rPropertyMap.fillSequences( aPropNames, aValues ); + setProperties( aPropNames, aValues ); + } +} + +// private -------------------------------------------------------------------- + +bool PropertySet::getAnyProperty( Any& orValue, const OUString& rPropName ) const +{ + bool bHasValue = false; + try + { + if( mxPropSet.is() ) + { + orValue = mxPropSet->getPropertyValue( rPropName ); + bHasValue = true; + } + } + catch( Exception& ) + { + OSL_ENSURE( false, OStringBuffer( "PropertySet::getAnyProperty - cannot get property \"" ). + append( OUStringToOString( rPropName, RTL_TEXTENCODING_ASCII_US ) ).append( '"' ).getStr() ); + } + return bHasValue; +} + +void PropertySet::setAnyProperty( const OUString& rPropName, const Any& rValue ) +{ + try + { + if( mxPropSet.is() ) + mxPropSet->setPropertyValue( rPropName, rValue ); + } + catch( Exception& ) + { + OSL_ENSURE( false, OStringBuffer( "PropertySet::setAnyProperty - cannot set property \"" ). + append( OUStringToOString( rPropName, RTL_TEXTENCODING_ASCII_US ) ).append( '"' ).getStr() ); + } +} + +// ============================================================================ + +} // namespace oox + diff --git a/oox/source/helper/recordinputstream.cxx b/oox/source/helper/recordinputstream.cxx new file mode 100644 index 000000000000..617e7f95876e --- /dev/null +++ b/oox/source/helper/recordinputstream.cxx @@ -0,0 +1,71 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/helper/recordinputstream.hxx" +#include <vector> +#include <string.h> + +using ::rtl::OUString; + +namespace oox { + +// ============================================================================ + +RecordInputStream::RecordInputStream( const StreamDataSequence& rData ) : + SequenceInputStream( rData ) +{ +} + +OUString RecordInputStream::readString( bool b32BitLen ) +{ + OUString aString; + if( !isEof() ) + { + sal_Int32 nCharCount = b32BitLen ? readValue< sal_Int32 >() : readValue< sal_Int16 >(); + // string length -1 is often used to indicate a missing string + OSL_ENSURE( !isEof() && (nCharCount >= -1), "RecordInputStream::readString - invalid string length" ); + if( !isEof() && (nCharCount > 0) ) + { + ::std::vector< sal_Unicode > aBuffer; + aBuffer.reserve( getLimitedValue< size_t, sal_Int32 >( nCharCount + 1, 0, 0xFFFF ) ); + for( sal_Int32 nCharIdx = 0; !isEof() && (nCharIdx < nCharCount); ++nCharIdx ) + { + sal_uInt16 nChar; + readValue( nChar ); + aBuffer.push_back( static_cast< sal_Unicode >( nChar ) ); + } + aBuffer.push_back( 0 ); + aString = OUString( &aBuffer.front() ); + } + } + return aString; +} + +// ============================================================================ + +} // namespace oox + diff --git a/oox/source/helper/storagebase.cxx b/oox/source/helper/storagebase.cxx new file mode 100644 index 000000000000..6f174a74593c --- /dev/null +++ b/oox/source/helper/storagebase.cxx @@ -0,0 +1,209 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/helper/storagebase.hxx" +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/embed/XTransactedObject.hpp> +#include <rtl/ustrbuf.hxx> + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::embed::XStorage; +using ::com::sun::star::embed::XTransactedObject; +using ::com::sun::star::io::XInputStream; +using ::com::sun::star::io::XOutputStream; +using ::com::sun::star::io::XStream; + +namespace oox { + +// ============================================================================ + +namespace { + +void lclSplitFirstElement( OUString& orElement, OUString& orRemainder, const OUString& rFullName ) +{ + sal_Int32 nSlashPos = rFullName.indexOf( '/' ); + if( (0 <= nSlashPos) && (nSlashPos < rFullName.getLength()) ) + { + orElement = rFullName.copy( 0, nSlashPos ); + orRemainder = rFullName.copy( nSlashPos + 1 ); + } + else + { + orElement = rFullName; + } +} + +} // namespace + +// ---------------------------------------------------------------------------- + +StorageBase::StorageBase( const Reference< XInputStream >& rxInStream, bool bBaseStreamAccess ) : + mxInStream( rxInStream ), + mpParentStorage( 0 ), + mbBaseStreamAccess( bBaseStreamAccess ) +{ + OSL_ENSURE( mxInStream.is(), "StorageBase::StorageBase - missing base input stream" ); +} + +StorageBase::StorageBase( const Reference< XStream >& rxOutStream, bool bBaseStreamAccess ) : + mxOutStream( rxOutStream ), + mpParentStorage( 0 ), + mbBaseStreamAccess( bBaseStreamAccess ) +{ + OSL_ENSURE( mxOutStream.is(), "StorageBase::StorageBase - missing base output stream" ); +} + +StorageBase::StorageBase( const StorageBase& rParentStorage, const OUString& rStorageName ) : + maStorageName( rStorageName ), + mpParentStorage( &rParentStorage ), + mbBaseStreamAccess( false ) +{ +} + +StorageBase::~StorageBase() +{ +} + +bool StorageBase::isStorage() const +{ + return implIsStorage(); +} + +Reference< XStorage > StorageBase::getXStorage() const +{ + return implGetXStorage(); +} + +const OUString& StorageBase::getName() const +{ + return maStorageName; +} + +OUString StorageBase::getPath() const +{ + OUStringBuffer aBuffer; + if( mpParentStorage ) + aBuffer.append( mpParentStorage->getPath() ); + if( aBuffer.getLength() > 0 ) + aBuffer.append( sal_Unicode( '/' ) ); + aBuffer.append( maStorageName ); + return aBuffer.makeStringAndClear(); +} + +void StorageBase::getElementNames( ::std::vector< OUString >& orElementNames ) const +{ + orElementNames.clear(); + implGetElementNames( orElementNames ); +} + +StorageRef StorageBase::openSubStorage( const OUString& rStorageName, bool bCreate ) +{ + StorageRef xSubStorage; + OUString aElement, aRemainder; + lclSplitFirstElement( aElement, aRemainder, rStorageName ); + if( aElement.getLength() > 0 ) + xSubStorage = getSubStorage( aElement, bCreate ); + if( xSubStorage.get() && (aRemainder.getLength() > 0) ) + xSubStorage = xSubStorage->openSubStorage( aRemainder, bCreate ); + return xSubStorage; +} + +Reference< XInputStream > StorageBase::openInputStream( const OUString& rStreamName ) +{ + Reference< XInputStream > xInStream; + OUString aElement, aRemainder; + lclSplitFirstElement( aElement, aRemainder, rStreamName ); + if( aElement.getLength() > 0 ) + { + if( aRemainder.getLength() > 0 ) + { + StorageRef xSubStorage = getSubStorage( aElement, false ); + if( xSubStorage.get() ) + xInStream = xSubStorage->openInputStream( aRemainder ); + } + else + { + xInStream = implOpenInputStream( aElement ); + } + } + else if( mbBaseStreamAccess ) + { + xInStream = mxInStream; + } + return xInStream; +} + +Reference< XOutputStream > StorageBase::openOutputStream( const OUString& rStreamName ) +{ + Reference< XOutputStream > xOutStream; + OUString aElement, aRemainder; + lclSplitFirstElement( aElement, aRemainder, rStreamName ); + if( aElement.getLength() > 0 ) + { + if( aRemainder.getLength() > 0 ) + { + StorageRef xSubStorage = getSubStorage( aElement, true ); + if( xSubStorage.get() ) + xOutStream = xSubStorage->openOutputStream( aRemainder ); + } + else + { + xOutStream = implOpenOutputStream( aElement ); + } + } + else if( mbBaseStreamAccess ) + { + xOutStream = mxOutStream->getOutputStream(); + } + return xOutStream; +} + +StorageRef StorageBase::getSubStorage( const OUString& rElementName, bool bCreate ) +{ + SubStorageMap::iterator aIt = maSubStorages.find( rElementName ); + return (aIt == maSubStorages.end()) ? + (maSubStorages[ rElementName ] = implOpenSubStorage( rElementName, bCreate )) : aIt->second; +} + +void StorageBase::commit() +{ + for( SubStorageMap::iterator aIt = maSubStorages.begin(); aIt != maSubStorages.end(); aIt ++ ) + aIt->second->commit(); + + Reference< XTransactedObject > xTransactedObj( getXStorage(), UNO_QUERY ); + + if( xTransactedObj.is() ) + xTransactedObj->commit(); +} + +// ============================================================================ + +} // namespace oox + diff --git a/oox/source/helper/zipstorage.cxx b/oox/source/helper/zipstorage.cxx new file mode 100644 index 000000000000..c90b2071b133 --- /dev/null +++ b/oox/source/helper/zipstorage.cxx @@ -0,0 +1,194 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/helper/zipstorage.hxx" +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <comphelper/storagehelper.hxx> +#include "oox/helper/helper.hxx" + +using ::rtl::OUString; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::lang::XMultiServiceFactory; +using ::com::sun::star::embed::XStorage; +using ::com::sun::star::io::XInputStream; +using ::com::sun::star::io::XOutputStream; +using ::com::sun::star::io::XStream; + +namespace oox { + +// ============================================================================ + +ZipStorage::ZipStorage( + const Reference< XMultiServiceFactory >& rxFactory, + const Reference< XInputStream >& rxInStream ) : + StorageBase( rxInStream, false ) +{ + OSL_ENSURE( rxFactory.is(), "ZipStorage::ZipStorage - missing service factory" ); + // create base storage object + try + { + /* #i105325# ::comphelper::OStorageHelper::GetStorageFromInputStream() + cannot be used here as it will open a storage with format type + 'PackageFormat' that will not work with OOXML packages. + TODO: #i105410# switch to 'OFOPXMLFormat' and use its + implementation of relations handling. */ + mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( + ZIP_STORAGE_FORMAT_STRING, rxInStream, rxFactory ); + } + catch( Exception& ) + { + } +} + +ZipStorage::ZipStorage( + const Reference< XMultiServiceFactory >& rxFactory, + const Reference< XStream >& rxStream ) : + StorageBase( rxStream, false ) +{ + OSL_ENSURE( rxFactory.is(), "ZipStorage::ZipStorage - missing service factory" ); + // create base storage object + try + { + using namespace ::com::sun::star::embed::ElementModes; + mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( + OFOPXML_STORAGE_FORMAT_STRING, rxStream, READWRITE | TRUNCATE, rxFactory ); + } + catch( Exception& ) + { + OSL_ENSURE( false, "ZipStorage::ZipStorage - cannot open output storage" ); + } +} + +ZipStorage::ZipStorage( const ZipStorage& rParentStorage, const Reference< XStorage >& rxStorage, const OUString& rElementName ) : + StorageBase( rParentStorage, rElementName ), + mxStorage( rxStorage ) +{ + OSL_ENSURE( mxStorage.is(), "ZipStorage::ZipStorage - missing storage" ); +} + +ZipStorage::~ZipStorage() +{ +} + +bool ZipStorage::implIsStorage() const +{ + return mxStorage.is(); +} + +Reference< XStorage > ZipStorage::implGetXStorage() const +{ + return mxStorage; +} + +void ZipStorage::implGetElementNames( ::std::vector< OUString >& orElementNames ) const +{ + Sequence< OUString > aNames; + if( mxStorage.is() ) try + { + aNames = mxStorage->getElementNames(); + if( aNames.getLength() > 0 ) + orElementNames.insert( orElementNames.end(), aNames.getConstArray(), aNames.getConstArray() + aNames.getLength() ); + } + catch( Exception& ) + { + } +} + +StorageRef ZipStorage::implOpenSubStorage( const OUString& rElementName, bool bCreate ) +{ + Reference< XStorage > xSubXStorage; + bool bMissing = false; + if( mxStorage.is() ) try + { + // XStorage::isStorageElement may throw various exceptions... + if( mxStorage->isStorageElement( rElementName ) ) + xSubXStorage = mxStorage->openStorageElement( + rElementName, ::com::sun::star::embed::ElementModes::READ ); + } + catch( ::com::sun::star::container::NoSuchElementException& ) + { + bMissing = true; + } + catch( Exception& ) + { + } + + if( bMissing && bCreate ) + try + { + xSubXStorage = mxStorage->openStorageElement( + rElementName, ::com::sun::star::embed::ElementModes::READWRITE ); + } + catch( Exception& ) + { + } + + StorageRef xSubStorage; + if( xSubXStorage.is() ) + xSubStorage.reset( new ZipStorage( *this, xSubXStorage, rElementName ) ); + return xSubStorage; +} + +Reference< XInputStream > ZipStorage::implOpenInputStream( const OUString& rElementName ) +{ + Reference< XInputStream > xInStream; + if( mxStorage.is() ) try + { + xInStream.set( mxStorage->openStreamElement( rElementName, ::com::sun::star::embed::ElementModes::READ ), UNO_QUERY ); + } + catch( Exception& ) + { + } + return xInStream; +} + +Reference< XOutputStream > ZipStorage::implOpenOutputStream( const OUString& rElementName ) +{ + Reference< XOutputStream > xOutStream; + if( mxStorage.is() ) try + { + xOutStream.set( mxStorage->openStreamElement( rElementName, ::com::sun::star::embed::ElementModes::READWRITE ), UNO_QUERY ); + } + catch( Exception& ) + { + } + return xOutStream; +} + +// ============================================================================ + +} // namespace oox + |