summaryrefslogtreecommitdiff
path: root/oox/source/helper
diff options
context:
space:
mode:
Diffstat (limited to 'oox/source/helper')
-rw-r--r--oox/source/helper/attributelist.cxx311
-rw-r--r--oox/source/helper/binaryinputstream.cxx239
-rw-r--r--oox/source/helper/binaryoutputstream.cxx157
-rw-r--r--oox/source/helper/binarystreambase.cxx144
-rw-r--r--oox/source/helper/containerhelper.cxx224
-rw-r--r--oox/source/helper/graphichelper.cxx120
-rw-r--r--oox/source/helper/makefile.mk61
-rw-r--r--oox/source/helper/modelobjecthelper.cxx91
-rw-r--r--oox/source/helper/olestorage.cxx180
-rw-r--r--oox/source/helper/progressbar.cxx185
-rw-r--r--oox/source/helper/propertymap.cxx234
-rw-r--r--oox/source/helper/propertyset.cxx174
-rw-r--r--oox/source/helper/recordinputstream.cxx71
-rw-r--r--oox/source/helper/storagebase.cxx209
-rw-r--r--oox/source/helper/zipstorage.cxx194
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
+