summaryrefslogtreecommitdiff
path: root/package
diff options
context:
space:
mode:
Diffstat (limited to 'package')
-rw-r--r--package/dtd/Manifest.dtd58
-rw-r--r--package/inc/ByteChucker.hxx67
-rw-r--r--package/inc/ByteGrabber.hxx77
-rw-r--r--package/inc/CRC32.hxx56
-rw-r--r--package/inc/Deflater.hxx66
-rw-r--r--package/inc/EncryptedDataHeader.hxx51
-rw-r--r--package/inc/EncryptionData.hxx43
-rw-r--r--package/inc/HashMaps.hxx63
-rw-r--r--package/inc/Inflater.hxx57
-rw-r--r--package/inc/PackageConstants.hxx52
-rw-r--r--package/inc/ZipEntry.hxx46
-rw-r--r--package/inc/ZipEnumeration.hxx43
-rw-r--r--package/inc/ZipFile.hxx198
-rw-r--r--package/inc/ZipOutputStream.hxx103
-rw-r--r--package/inc/ZipPackage.hxx189
-rw-r--r--package/inc/ZipPackageBuffer.hxx84
-rw-r--r--package/inc/ZipPackageFolder.hxx144
-rw-r--r--package/inc/makefile.mk47
-rw-r--r--package/inc/mutexholder.hxx131
-rw-r--r--package/inc/pch/precompiled_package.cxx29
-rw-r--r--package/inc/pch/precompiled_package.hxx32
-rw-r--r--package/inc/zipfileaccess.hxx109
-rw-r--r--package/prj/build.lst9
-rw-r--r--package/prj/d.lst5
-rw-r--r--package/qa/ofopxmlstorages/StorageTest.java7
-rw-r--r--package/qa/ofopxmlstorages/StorageUnitTest.java158
-rw-r--r--package/qa/ofopxmlstorages/Test01.java200
-rw-r--r--package/qa/ofopxmlstorages/Test02.java164
-rw-r--r--package/qa/ofopxmlstorages/Test03.java233
-rw-r--r--package/qa/ofopxmlstorages/Test04.java308
-rw-r--r--package/qa/ofopxmlstorages/Test05.java314
-rw-r--r--package/qa/ofopxmlstorages/Test06.java277
-rw-r--r--package/qa/ofopxmlstorages/Test07.java258
-rw-r--r--package/qa/ofopxmlstorages/Test08.java261
-rw-r--r--package/qa/ofopxmlstorages/TestHelper.java1098
-rw-r--r--package/qa/ofopxmlstorages/makefile.mk91
-rw-r--r--package/qa/storages/BorderedStream.java195
-rw-r--r--package/qa/storages/RegressionTest_114358.java190
-rw-r--r--package/qa/storages/RegressionTest_125919.java134
-rw-r--r--package/qa/storages/RegressionTest_i26398.java146
-rw-r--r--package/qa/storages/RegressionTest_i27773.java299
-rw-r--r--package/qa/storages/RegressionTest_i29169.java369
-rw-r--r--package/qa/storages/RegressionTest_i29321.java170
-rw-r--r--package/qa/storages/RegressionTest_i30400.java435
-rw-r--r--package/qa/storages/RegressionTest_i30677.java263
-rw-r--r--package/qa/storages/RegressionTest_i35095.java166
-rw-r--r--package/qa/storages/RegressionTest_i46848.java191
-rw-r--r--package/qa/storages/RegressionTest_i49755.java272
-rw-r--r--package/qa/storages/RegressionTest_i55821.java111
-rw-r--r--package/qa/storages/RegressionTest_i59886.java243
-rw-r--r--package/qa/storages/RegressionTest_i61909.java167
-rw-r--r--package/qa/storages/RegressionTest_i84234.java134
-rw-r--r--package/qa/storages/StorageTest.java7
-rw-r--r--package/qa/storages/StorageUnitTest.java326
-rw-r--r--package/qa/storages/Test01.java177
-rw-r--r--package/qa/storages/Test02.java163
-rw-r--r--package/qa/storages/Test03.java231
-rw-r--r--package/qa/storages/Test04.java307
-rw-r--r--package/qa/storages/Test05.java299
-rw-r--r--package/qa/storages/Test06.java279
-rw-r--r--package/qa/storages/Test07.java162
-rw-r--r--package/qa/storages/Test08.java230
-rw-r--r--package/qa/storages/Test09.java138
-rw-r--r--package/qa/storages/Test10.java232
-rw-r--r--package/qa/storages/Test11.java218
-rw-r--r--package/qa/storages/Test12.java240
-rw-r--r--package/qa/storages/Test13.java215
-rw-r--r--package/qa/storages/Test14.java188
-rw-r--r--package/qa/storages/Test15.java268
-rw-r--r--package/qa/storages/Test16.java159
-rw-r--r--package/qa/storages/Test17.java142
-rw-r--r--package/qa/storages/Test18.java172
-rw-r--r--package/qa/storages/TestHelper.java1661
-rw-r--r--package/qa/storages/makefile.mk116
-rw-r--r--package/source/manifest/Base64Codec.cxx204
-rw-r--r--package/source/manifest/Base64Codec.hxx45
-rw-r--r--package/source/manifest/ManifestDefines.hxx67
-rw-r--r--package/source/manifest/ManifestExport.cxx323
-rw-r--r--package/source/manifest/ManifestExport.hxx46
-rw-r--r--package/source/manifest/ManifestImport.cxx332
-rw-r--r--package/source/manifest/ManifestImport.hxx131
-rw-r--r--package/source/manifest/ManifestReader.cxx150
-rw-r--r--package/source/manifest/ManifestReader.hxx73
-rw-r--r--package/source/manifest/ManifestWriter.cxx135
-rw-r--r--package/source/manifest/ManifestWriter.hxx74
-rw-r--r--package/source/manifest/UnoRegister.cxx154
-rw-r--r--package/source/manifest/makefile.mk55
-rw-r--r--package/source/xstor/disposelistener.cxx57
-rw-r--r--package/source/xstor/disposelistener.hxx51
-rw-r--r--package/source/xstor/makefile.mk75
-rw-r--r--package/source/xstor/ocompinstream.cxx759
-rw-r--r--package/source/xstor/ocompinstream.hxx128
-rw-r--r--package/source/xstor/ohierarchyholder.cxx356
-rw-r--r--package/source/xstor/ohierarchyholder.hxx139
-rw-r--r--package/source/xstor/oseekinstream.cxx180
-rw-r--r--package/source/xstor/oseekinstream.hxx68
-rw-r--r--package/source/xstor/owriteablestream.cxx3613
-rw-r--r--package/source/xstor/owriteablestream.hxx411
-rw-r--r--package/source/xstor/register.cxx101
-rw-r--r--package/source/xstor/selfterminatefilestream.cxx153
-rw-r--r--package/source/xstor/selfterminatefilestream.hxx76
-rw-r--r--package/source/xstor/switchpersistencestream.cxx488
-rw-r--r--package/source/xstor/switchpersistencestream.hxx120
-rw-r--r--package/source/xstor/xfactory.cxx324
-rw-r--r--package/source/xstor/xfactory.hxx74
-rw-r--r--package/source/xstor/xstor.dxp3
-rw-r--r--package/source/xstor/xstorage.cxx6175
-rw-r--r--package/source/xstor/xstorage.hxx807
-rw-r--r--package/source/zipapi/ByteChucker.cxx112
-rw-r--r--package/source/zipapi/ByteGrabber.cxx191
-rw-r--r--package/source/zipapi/CRC32.cxx96
-rw-r--r--package/source/zipapi/Deflater.cxx212
-rw-r--r--package/source/zipapi/EntryInputStream.cxx201
-rw-r--r--package/source/zipapi/EntryInputStream.hxx86
-rw-r--r--package/source/zipapi/Inflater.cxx162
-rw-r--r--package/source/zipapi/MemoryByteGrabber.hxx177
-rw-r--r--package/source/zipapi/XFileStream.cxx227
-rw-r--r--package/source/zipapi/XFileStream.hxx96
-rw-r--r--package/source/zipapi/XMemoryStream.cxx52
-rw-r--r--package/source/zipapi/XMemoryStream.hxx42
-rw-r--r--package/source/zipapi/XUnbufferedStream.cxx360
-rw-r--r--package/source/zipapi/XUnbufferedStream.hxx108
-rw-r--r--package/source/zipapi/ZipEnumeration.cxx53
-rw-r--r--package/source/zipapi/ZipFile.cxx1061
-rw-r--r--package/source/zipapi/ZipOutputStream.cxx429
-rw-r--r--package/source/zipapi/makefile.mk59
-rw-r--r--package/source/zippackage/ContentInfo.hxx69
-rw-r--r--package/source/zippackage/ZipPackage.cxx1719
-rw-r--r--package/source/zippackage/ZipPackageBuffer.cxx136
-rw-r--r--package/source/zippackage/ZipPackageEntry.cxx136
-rw-r--r--package/source/zippackage/ZipPackageEntry.hxx105
-rw-r--r--package/source/zippackage/ZipPackageFolder.cxx811
-rw-r--r--package/source/zippackage/ZipPackageFolderEnumeration.cxx79
-rw-r--r--package/source/zippackage/ZipPackageFolderEnumeration.hxx68
-rw-r--r--package/source/zippackage/ZipPackageSink.cxx48
-rw-r--r--package/source/zippackage/ZipPackageSink.hxx48
-rw-r--r--package/source/zippackage/ZipPackageStream.cxx797
-rw-r--r--package/source/zippackage/ZipPackageStream.hxx201
-rw-r--r--package/source/zippackage/makefile.mk63
-rw-r--r--package/source/zippackage/wrapstreamforshare.cxx180
-rw-r--r--package/source/zippackage/wrapstreamforshare.hxx73
-rw-r--r--package/source/zippackage/zipfileaccess.cxx492
-rw-r--r--package/util/exports.dxp3
-rw-r--r--package/util/makefile.mk77
144 files changed, 39319 insertions, 0 deletions
diff --git a/package/dtd/Manifest.dtd b/package/dtd/Manifest.dtd
new file mode 100644
index 000000000000..d5f9184bf07e
--- /dev/null
+++ b/package/dtd/Manifest.dtd
@@ -0,0 +1,58 @@
+<!--
+
+ 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.
+
+-->
+<!ELEMENT manifest:manifest (manifest:file-entry+)>
+<!ATTLIST manifest:manifest xmlns:manifest CDATA #FIXED "http://openoffice.org/2001/manifest">
+
+<!ELEMENT manifest:file-entry (manifest:encryption-data?)>
+<!-- manifest:size is usually only specified for encrypted entries -->
+<!ATTLIST manifest:file-entry
+ manifest:full-path CDATA #REQUIRED
+ manifest:size CDATA #IMPLIED
+ manifest:media-type CDATA #REQUIRED
+>
+
+<!ELEMENT manifest:encryption-data (manifest:algorithm,manifest:key-derivation)>
+<!ATTLIST manifest:encryption-data
+ manifest:checksum-type CDATA #REQUIRED
+ manifest:checksum CDATA #REQUIRED >
+<!-- algorithm-name specifies the name of the algorithm used to encrypt
+ the stream, for example Blowfish
+ manifest:initialisation-vector is stored encoded in Base64 -->
+<!ELEMENT manifest:algorithm EMPTY>
+<!ATTLIST manifest:algorithm
+ manifest:algorithm-name CDATA #REQUIRED
+ manifest:initialisation-vector CDATA #REQUIRED>
+
+<!ELEMENT manifest:key-derivation EMPTY>
+<!-- manifest:key-derivation-name specifies the name of the algorithm used to derive
+ the key, for example PBKDF2 (see rfc 2898 )
+ manifest:salt is stored encoded in Base64 -->
+<!ATTLIST manifest:key-derivation
+ manifest:key-derivation-name CDATA #REQUIRED
+ manifest:salt CDATA #REQUIRED
+ manifest:iteration-count CDATA #REQUIRED>
+
diff --git a/package/inc/ByteChucker.hxx b/package/inc/ByteChucker.hxx
new file mode 100644
index 000000000000..d0a07cdfadaf
--- /dev/null
+++ b/package/inc/ByteChucker.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _BYTE_CHUCKER_HXX_
+#define _BYTE_CHUCKER_HXX_
+
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/io/BufferSizeExceededException.hpp>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/io/NotConnectedException.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+namespace com { namespace sun { namespace star {
+ namespace io { class XSeekable; class XOutputStream; }
+} } }
+class ByteChucker
+{
+protected:
+ com::sun::star::uno::Reference < com::sun::star::io::XOutputStream > xStream;
+ com::sun::star::uno::Reference < com::sun::star::io::XSeekable > xSeek;
+ com::sun::star::uno::Sequence < sal_Int8 > a1Sequence, a2Sequence, a4Sequence;
+ sal_Int8 * const p1Sequence, * const p2Sequence, * const p4Sequence;
+
+public:
+ ByteChucker (com::sun::star::uno::Reference<com::sun::star::io::XOutputStream> xOstream);
+ ~ByteChucker();
+
+ void WriteBytes( const ::com::sun::star::uno::Sequence< sal_Int8 >& aData )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ sal_Int64 GetPosition()
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ ByteChucker& operator << (sal_Int8 nInt8);
+ ByteChucker& operator << (sal_Int16 nInt16);
+ ByteChucker& operator << (sal_Int32 nInt32);
+ ByteChucker& operator << (sal_uInt8 nuInt8);
+ ByteChucker& operator << (sal_uInt16 nuInt16);
+ ByteChucker& operator << (sal_uInt32 nuInt32);
+};
+
+#endif
diff --git a/package/inc/ByteGrabber.hxx b/package/inc/ByteGrabber.hxx
new file mode 100644
index 000000000000..8ef127900655
--- /dev/null
+++ b/package/inc/ByteGrabber.hxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _BYTE_GRABBER_HXX_
+#define _BYTE_GRABBER_HXX_
+
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/io/BufferSizeExceededException.hpp>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/io/NotConnectedException.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+#include <osl/mutex.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace io { class XSeekable; class XInputStream; }
+} } }
+class ByteGrabber
+{
+protected:
+ ::osl::Mutex m_aMutex;
+
+ com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xStream;
+ com::sun::star::uno::Reference < com::sun::star::io::XSeekable > xSeek;
+ com::sun::star::uno::Sequence < sal_Int8 > aSequence;
+ const sal_Int8 *pSequence;
+
+public:
+ ByteGrabber (com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xIstream);
+ ~ByteGrabber();
+
+ void setInputStream (com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewStream);
+ // XInputStream
+ sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ // XSeekable
+ sal_Int64 SAL_CALL seek( sal_Int64 location )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ sal_Int64 SAL_CALL getPosition( )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ sal_Int64 SAL_CALL getLength( )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ ByteGrabber& operator >> (sal_Int8& rInt8);
+ ByteGrabber& operator >> (sal_Int16& rInt16);
+ ByteGrabber& operator >> (sal_Int32& rInt32);
+ ByteGrabber& operator >> (sal_uInt8& ruInt8);
+ ByteGrabber& operator >> (sal_uInt16& ruInt16);
+ ByteGrabber& operator >> (sal_uInt32& ruInt32);
+};
+
+#endif
diff --git a/package/inc/CRC32.hxx b/package/inc/CRC32.hxx
new file mode 100644
index 000000000000..b8de389c8721
--- /dev/null
+++ b/package/inc/CRC32.hxx
@@ -0,0 +1,56 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _CRC32_HXX
+#define _CRC32_HXX
+
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/uno/RuntimeException.hpp>
+
+namespace com { namespace sun { namespace star {
+ namespace io { class XInputStream; }
+} } }
+class CRC32
+{
+protected:
+ sal_uInt32 nCRC;
+public:
+ CRC32();
+ ~CRC32();
+
+ sal_Int32 SAL_CALL updateStream (::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > & xStream)
+ throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL updateSegment(const ::com::sun::star::uno::Sequence< sal_Int8 > &b, sal_Int32 off, sal_Int32 len)
+ throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL update(const ::com::sun::star::uno::Sequence< sal_Int8 > &b)
+ throw(::com::sun::star::uno::RuntimeException);
+ sal_Int32 SAL_CALL getValue()
+ throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL reset()
+ throw(::com::sun::star::uno::RuntimeException);
+};
+
+#endif
diff --git a/package/inc/Deflater.hxx b/package/inc/Deflater.hxx
new file mode 100644
index 000000000000..f39b8e2b9547
--- /dev/null
+++ b/package/inc/Deflater.hxx
@@ -0,0 +1,66 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _DEFLATER_HXX_
+#define _DEFLATER_HXX_
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+extern "C"
+{
+ typedef struct z_stream_s z_stream;
+}
+
+class Deflater
+{
+protected:
+ com::sun::star::uno::Sequence< sal_Int8 > sInBuffer;
+ sal_Bool bFinish;
+ sal_Bool bFinished;
+ sal_Bool bSetParams;
+ sal_Int32 nLevel, nStrategy;
+ sal_Int32 nOffset, nLength;
+ z_stream* pStream;
+
+ void init (sal_Int32 nLevel, sal_Int32 nStrategy, sal_Bool bNowrap);
+ sal_Int32 doDeflateBytes (com::sun::star::uno::Sequence < sal_Int8 > &rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength);
+
+public:
+ ~Deflater();
+ Deflater(sal_Int32 nSetLevel, sal_Bool bNowrap);
+ void SAL_CALL setInputSegment( const ::com::sun::star::uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength );
+ void SAL_CALL setLevel( sal_Int32 nNewLevel );
+ sal_Bool SAL_CALL needsInput( );
+ void SAL_CALL finish( );
+ sal_Bool SAL_CALL finished( );
+ sal_Int32 SAL_CALL doDeflateSegment( ::com::sun::star::uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength );
+ sal_Int32 SAL_CALL getTotalIn( );
+ sal_Int32 SAL_CALL getTotalOut( );
+ void SAL_CALL reset( );
+ void SAL_CALL end( );
+};
+
+#endif
diff --git a/package/inc/EncryptedDataHeader.hxx b/package/inc/EncryptedDataHeader.hxx
new file mode 100644
index 000000000000..a166397cce34
--- /dev/null
+++ b/package/inc/EncryptedDataHeader.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _ENCRYPTED_DATA_HEADER_HXX_
+#define _ENCRYPTED_DATA_HEADER_HXX_
+
+#include <sal/types.h>
+
+/* The structure of this header is as follows:
+
+ Header signature 4 bytes
+ Version number 2 bytes
+ Iteraction count 4 bytes
+ Size 4 bytes
+ Salt length 2 bytes
+ IV length 2 bytes
+ Digest length 2 bytes
+ MediaType length 2 bytes
+ Salt content X bytes
+ IV content X bytes
+ digest content X bytes
+ MediaType X bytes
+
+*/
+const sal_uInt32 n_ConstHeader = 0x0502474dL; // "MG\002\005"
+const sal_Int32 n_ConstHeaderSize = 22; // + salt length + iv length + digest length + mediatype length
+const sal_Int16 n_ConstCurrentVersion = 1;
+#endif
diff --git a/package/inc/EncryptionData.hxx b/package/inc/EncryptionData.hxx
new file mode 100644
index 000000000000..66d74f739b9c
--- /dev/null
+++ b/package/inc/EncryptionData.hxx
@@ -0,0 +1,43 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _ENCRYPTION_DATA_HXX_
+#define _ENCRYPTION_DATA_HXX_
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <cppuhelper/weak.hxx>
+
+class EncryptionData : public cppu::OWeakObject
+{
+public:
+ // On export aKey holds the derived key
+ // On import aKey holds the hash of the user enterred key
+ com::sun::star::uno::Sequence < sal_Int8 > aKey;
+ com::sun::star::uno::Sequence < sal_uInt8 > aSalt, aInitVector, aDigest;
+ sal_Int32 nIterationCount;
+ EncryptionData(): nIterationCount ( 0 ){}
+};
+#endif
diff --git a/package/inc/HashMaps.hxx b/package/inc/HashMaps.hxx
new file mode 100644
index 000000000000..b10f42aa7020
--- /dev/null
+++ b/package/inc/HashMaps.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _HASHMAPS_HXX
+#define _HASHMAPS_HXX
+
+#include <ZipEntry.hxx>
+#include <vos/ref.hxx>
+#include <hash_map>
+
+struct eqFunc
+{
+ sal_Bool operator()( const rtl::OUString &r1,
+ const rtl::OUString &r2) const
+ {
+ return r1 == r2;
+ }
+};
+
+class ZipPackageFolder;
+namespace com { namespace sun { namespace star { namespace packages {
+class ContentInfo;
+} } } }
+
+typedef std::hash_map < rtl::OUString,
+ ZipPackageFolder *,
+ ::rtl::OUStringHash,
+ eqFunc > FolderHash;
+
+typedef std::hash_map < rtl::OUString,
+ vos::ORef < com::sun::star::packages::ContentInfo >,
+ ::rtl::OUStringHash,
+ eqFunc > ContentHash;
+
+typedef std::hash_map < rtl::OUString,
+ ZipEntry,
+ rtl::OUStringHash,
+ eqFunc > EntryHash;
+
+#endif
diff --git a/package/inc/Inflater.hxx b/package/inc/Inflater.hxx
new file mode 100644
index 000000000000..26c903ae5c47
--- /dev/null
+++ b/package/inc/Inflater.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _INFLATER_HXX_
+#define _INFLATER_HXX_
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+extern "C"
+{
+ typedef struct z_stream_s z_stream;
+}
+class Inflater
+{
+protected:
+ sal_Bool bFinish, bFinished, bSetParams, bNeedDict;
+ sal_Int32 nOffset, nLength, nLastInflateError;
+ z_stream* pStream;
+ com::sun::star::uno::Sequence < sal_Int8 > sInBuffer;
+ sal_Int32 doInflateBytes (com::sun::star::uno::Sequence < sal_Int8 > &rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength);
+
+public:
+ Inflater(sal_Bool bNoWrap = sal_False);
+ ~Inflater();
+ void SAL_CALL setInput( const ::com::sun::star::uno::Sequence< sal_Int8 >& rBuffer );
+ sal_Bool SAL_CALL needsDictionary( );
+ sal_Bool SAL_CALL finished( );
+ sal_Int32 SAL_CALL doInflateSegment( ::com::sun::star::uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength );
+ void SAL_CALL end( );
+
+ sal_Int32 getLastInflateError() { return nLastInflateError; }
+};
+
+#endif
diff --git a/package/inc/PackageConstants.hxx b/package/inc/PackageConstants.hxx
new file mode 100644
index 000000000000..a23a22fcb888
--- /dev/null
+++ b/package/inc/PackageConstants.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _PACKAGE_CONSTANTS_HXX_
+#define _PACKAGE_CONSTANTS_HXX_
+
+#include <sal/types.h>
+
+const sal_Int32 n_ConstBufferSize = 32768;
+const sal_Int32 n_ConstMaxMemoryStreamSize = 20480;
+const sal_Int32 n_ConstDigestLength = 1024;
+
+// the constants related to the manifest.xml entries
+#define PKG_MNFST_MEDIATYPE 0
+#define PKG_MNFST_VERSION 1
+#define PKG_MNFST_FULLPATH 2
+
+#define PKG_MNFST_INIVECTOR 3
+#define PKG_MNFST_SALT 4
+#define PKG_MNFST_ITERATION 5
+#define PKG_MNFST_UCOMPSIZE 6
+#define PKG_MNFST_DIGEST 7
+
+#define PKG_SIZE_NOENCR_MNFST 3
+#define PKG_SIZE_ENCR_MNFST 8
+
+
+#endif
+
diff --git a/package/inc/ZipEntry.hxx b/package/inc/ZipEntry.hxx
new file mode 100644
index 000000000000..4f47f25a1329
--- /dev/null
+++ b/package/inc/ZipEntry.hxx
@@ -0,0 +1,46 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _ZIP_ENTRY_HXX_
+#define _ZIP_ENTRY_HXX_
+
+#include <rtl/ustring.hxx>
+
+struct ZipEntry
+{
+ sal_Int16 nVersion;
+ sal_Int16 nFlag;
+ sal_Int16 nMethod;
+ sal_Int32 nTime;
+ sal_Int32 nCrc;
+ sal_Int32 nCompressedSize;
+ sal_Int32 nSize;
+ sal_Int32 nOffset;
+ sal_Int16 nPathLen;
+ sal_Int16 nExtraLen;
+ ::rtl::OUString sPath;
+};
+#endif
diff --git a/package/inc/ZipEnumeration.hxx b/package/inc/ZipEnumeration.hxx
new file mode 100644
index 000000000000..967007ade78d
--- /dev/null
+++ b/package/inc/ZipEnumeration.hxx
@@ -0,0 +1,43 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _ZIP_ENUMERATION_HXX
+#define _ZIP_ENUMERATION_HXX
+
+#include <HashMaps.hxx>
+
+class ZipEnumeration
+{
+protected:
+ EntryHash &rEntryHash;
+ EntryHash::const_iterator aIterator;
+public:
+ sal_Bool SAL_CALL hasMoreElements();
+ const ZipEntry * SAL_CALL nextElement();
+ ZipEnumeration( EntryHash &rNewEntryHash );
+ ~ZipEnumeration();
+};
+#endif
diff --git a/package/inc/ZipFile.hxx b/package/inc/ZipFile.hxx
new file mode 100644
index 000000000000..be8158c0ba4e
--- /dev/null
+++ b/package/inc/ZipFile.hxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _ZIP_FILE_HXX
+#define _ZIP_FILE_HXX
+
+#include <com/sun/star/packages/zip/ZipException.hpp>
+#include <com/sun/star/packages/zip/ZipIOException.hpp>
+#include <com/sun/star/packages/NoEncryptionException.hpp>
+#include <com/sun/star/packages/WrongPasswordException.hpp>
+#include <ByteGrabber.hxx>
+#include <HashMaps.hxx>
+#ifndef _INFLATER_HXX
+#include <Inflater.hxx>
+#endif
+
+#include <mutexholder.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace lang { class XMultiServiceFactory; }
+ namespace ucb { class XProgressHandler; }
+} } }
+namespace vos
+{
+ template < class T > class ORef;
+}
+/*
+ * We impose arbitrary but reasonable limit on ZIP files.
+ */
+
+#define ZIP_MAXNAMELEN 512
+#define ZIP_MAXEXTRA 256
+#define ZIP_MAXENTRIES (0x10000 - 2)
+
+typedef void* rtlCipher;
+class ZipEnumeration;
+class EncryptionData;
+
+class ZipFile
+{
+protected:
+ ::osl::Mutex m_aMutex;
+
+ ::rtl::OUString sComment; /* zip file comment */
+ EntryHash aEntries;
+ ByteGrabber aGrabber;
+ Inflater aInflater;
+ com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xStream;
+ com::sun::star::uno::Reference < com::sun::star::io::XSeekable > xSeek;
+ const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > xFactory;
+ ::com::sun::star::uno::Reference < ::com::sun::star::ucb::XProgressHandler > xProgressHandler;
+
+ sal_Bool bRecoveryMode;
+
+ com::sun::star::uno::Reference < com::sun::star::io::XInputStream > createMemoryStream(
+ ZipEntry & rEntry,
+ const vos::ORef < EncryptionData > &rData,
+ sal_Bool bRawStream,
+ sal_Bool bDecrypt );
+
+ com::sun::star::uno::Reference < com::sun::star::io::XInputStream > createFileStream(
+ ZipEntry & rEntry,
+ const vos::ORef < EncryptionData > &rData,
+ sal_Bool bRawStream,
+ sal_Bool bDecrypt );
+
+ // aMediaType parameter is used only for raw stream header creation
+ com::sun::star::uno::Reference < com::sun::star::io::XInputStream > createUnbufferedStream(
+ SotMutexHolderRef aMutexHolder,
+ ZipEntry & rEntry,
+ const vos::ORef < EncryptionData > &rData,
+ sal_Int8 nStreamMode,
+ sal_Bool bDecrypt,
+ ::rtl::OUString aMediaType = ::rtl::OUString() );
+
+ sal_Bool hasValidPassword ( ZipEntry & rEntry, const vos::ORef < EncryptionData > &rData );
+
+ sal_Bool checkSizeAndCRC( const ZipEntry& aEntry );
+
+ sal_Int32 getCRC( sal_Int32 nOffset, sal_Int32 nSize );
+
+ void getSizeAndCRC( sal_Int32 nOffset, sal_Int32 nCompressedSize, sal_Int32 *nSize, sal_Int32 *nCRC );
+
+public:
+
+ ZipFile( com::sun::star::uno::Reference < com::sun::star::io::XInputStream > &xInput,
+ const com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > &xNewFactory,
+ sal_Bool bInitialise
+ )
+ throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
+
+ ZipFile( com::sun::star::uno::Reference < com::sun::star::io::XInputStream > &xInput,
+ const com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > &xNewFactory,
+ sal_Bool bInitialise,
+ sal_Bool bForceRecover,
+ ::com::sun::star::uno::Reference < ::com::sun::star::ucb::XProgressHandler > xProgress
+ )
+ throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
+
+ ~ZipFile();
+
+ EntryHash& GetEntryHash() { return aEntries; }
+
+ void setInputStream ( com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewStream );
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getRawData(
+ ZipEntry& rEntry,
+ const vos::ORef < EncryptionData > &rData,
+ sal_Bool bDecrypt,
+ SotMutexHolderRef aMutexHolder )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::packages::zip::ZipException, ::com::sun::star::uno::RuntimeException);
+
+ static sal_Bool StaticGetCipher ( const vos::ORef < EncryptionData > & xEncryptionData, rtlCipher &rCipher, sal_Bool bDecode );
+
+ static void StaticFillHeader ( const vos::ORef < EncryptionData > & rData,
+ sal_Int32 nSize,
+ const ::rtl::OUString& aMediaType,
+ sal_Int8 * & pHeader );
+
+ static sal_Bool StaticFillData ( vos::ORef < EncryptionData > & rData,
+ sal_Int32 &rSize,
+ ::rtl::OUString& aMediaType,
+ ::com::sun::star::uno::Reference < com::sun::star::io::XInputStream > &rStream );
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > StaticGetDataFromRawStream(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xStream,
+ const vos::ORef < EncryptionData > &rData )
+ throw ( ::com::sun::star::packages::WrongPasswordException,
+ ::com::sun::star::packages::zip::ZipIOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ static sal_Bool StaticHasValidPassword ( const ::com::sun::star::uno::Sequence< sal_Int8 > &aReadBuffer,
+ const vos::ORef < EncryptionData > &rData );
+
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream(
+ ZipEntry& rEntry,
+ const vos::ORef < EncryptionData > &rData,
+ sal_Bool bDecrypt,
+ SotMutexHolderRef aMutexHolder )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::packages::zip::ZipException, ::com::sun::star::uno::RuntimeException);
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getDataStream(
+ ZipEntry& rEntry,
+ const vos::ORef < EncryptionData > &rData,
+ sal_Bool bDecrypt,
+ SotMutexHolderRef aMutexHolder )
+ throw ( ::com::sun::star::packages::WrongPasswordException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::packages::zip::ZipException,
+ ::com::sun::star::uno::RuntimeException );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getWrappedRawStream(
+ ZipEntry& rEntry,
+ const vos::ORef < EncryptionData > &rData,
+ const ::rtl::OUString& aMediaType,
+ SotMutexHolderRef aMutexHolder )
+ throw ( ::com::sun::star::packages::NoEncryptionException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::packages::zip::ZipException,
+ ::com::sun::star::uno::RuntimeException );
+
+ ZipEnumeration * SAL_CALL entries( );
+protected:
+ sal_Bool readLOC ( ZipEntry &rEntry)
+ throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
+ sal_Int32 readCEN()
+ throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
+ sal_Int32 findEND()
+ throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
+ sal_Int32 recover()
+ throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
+
+};
+
+#endif
diff --git a/package/inc/ZipOutputStream.hxx b/package/inc/ZipOutputStream.hxx
new file mode 100644
index 000000000000..345fe332b8cc
--- /dev/null
+++ b/package/inc/ZipOutputStream.hxx
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _ZIP_OUTPUT_STREAM_HXX
+#define _ZIP_OUTPUT_STREAM_HXX
+
+#include <ByteChucker.hxx>
+#ifndef _DEFLATER_HXX
+#include <Deflater.hxx>
+#endif
+#include <CRC32.hxx>
+#include <rtl/cipher.h>
+#ifndef RTL_DIGEST_H_
+#include <rtl/digest.h>
+#endif
+
+#include <vector>
+
+struct ZipEntry;
+class EncryptionData;
+namespace vos
+{
+ template < class T > class ORef;
+}
+class ZipOutputStream
+{
+protected:
+ com::sun::star::uno::Reference < com::sun::star::io::XOutputStream > xStream;
+ ::std::vector < ZipEntry * > aZipList;
+ com::sun::star::uno::Sequence < sal_Int8 > aBuffer, aEncryptionBuffer;
+ ::rtl::OUString sComment;
+ Deflater aDeflater;
+ rtlCipher aCipher;
+ rtlDigest aDigest;
+ CRC32 aCRC;
+ ByteChucker aChucker;
+ ZipEntry *pCurrentEntry;
+ sal_Int16 nMethod, nLevel, mnDigested;
+ sal_Bool bFinished, bEncryptCurrentEntry;
+ EncryptionData *pCurrentEncryptData;
+
+public:
+ ZipOutputStream( com::sun::star::uno::Reference < com::sun::star::io::XOutputStream > &xOStream );
+ ~ZipOutputStream();
+
+ // rawWrite to support a direct write to the output stream
+ void SAL_CALL rawWrite( ::com::sun::star::uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ void SAL_CALL rawCloseEntry( )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // XZipOutputStream interfaces
+ void SAL_CALL setMethod( sal_Int32 nNewMethod )
+ throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setLevel( sal_Int32 nNewLevel )
+ throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL putNextEntry( ZipEntry& rEntry,
+ vos::ORef < EncryptionData > &rData,
+ sal_Bool bEncrypt = sal_False )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ void SAL_CALL closeEntry( )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ void SAL_CALL write( const ::com::sun::star::uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ void SAL_CALL finish( )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ static sal_uInt32 getCurrentDosTime ( );
+protected:
+ void doDeflate();
+ void writeEND(sal_uInt32 nOffset, sal_uInt32 nLength)
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ void writeCEN( const ZipEntry &rEntry )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ void writeEXT( const ZipEntry &rEntry )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ sal_Int32 writeLOC( const ZipEntry &rEntry )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+};
+
+#endif
diff --git a/package/inc/ZipPackage.hxx b/package/inc/ZipPackage.hxx
new file mode 100644
index 000000000000..e3b8d44be183
--- /dev/null
+++ b/package/inc/ZipPackage.hxx
@@ -0,0 +1,189 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _ZIP_PACKAGE_HXX
+#define _ZIP_PACKAGE_HXX
+
+#include <cppuhelper/implbase7.hxx>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#ifndef _COM_SUN_STAR_LANG_XPSERVICEINFO_HPP_
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#endif
+#include <HashMaps.hxx>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <osl/file.h>
+#include <mutexholder.hxx>
+
+class ZipOutputStream;
+class ZipPackageFolder;
+class ZipFile;
+class ByteGrabber;
+namespace com { namespace sun { namespace star {
+ namespace container { class XNameContainer; }
+ namespace io { class XStream; class XOutputStream; class XInputStream; class XSeekable; class XActiveDataStreamer; }
+ namespace lang { class XMultiServiceFactory; }
+ namespace task { class XInteractionHandler; }
+} } }
+enum SegmentEnum
+{
+ e_Aborted = -1000,
+ e_Retry,
+ e_Finished,
+ e_Success = 0
+};
+
+enum InitialisationMode
+{
+ e_IMode_None,
+ e_IMode_URL,
+ e_IMode_XInputStream,
+ e_IMode_XStream
+};
+
+class ZipPackage : public cppu::WeakImplHelper7
+ <
+ com::sun::star::lang::XInitialization,
+ com::sun::star::lang::XSingleServiceFactory,
+ com::sun::star::lang::XUnoTunnel,
+ com::sun::star::lang::XServiceInfo,
+ com::sun::star::container::XHierarchicalNameAccess,
+ com::sun::star::util::XChangesBatch,
+ com::sun::star::beans::XPropertySet
+ >
+{
+protected:
+ SotMutexHolderRef m_aMutexHolder;
+
+ ::com::sun::star::uno::Sequence < sal_Int8 > m_aEncryptionKey;
+ FolderHash m_aRecent;
+ ::rtl::OUString m_aURL;
+ sal_Bool m_bHasEncryptedEntries;
+ sal_Bool m_bHasNonEncryptedEntries;
+ sal_Bool m_bInconsistent;
+ sal_Bool m_bUseManifest;
+ sal_Bool m_bForceRecovery;
+
+ sal_Bool m_bMediaTypeFallbackUsed;
+ sal_Int32 m_nFormat;
+ sal_Bool m_bAllowRemoveOnInsert;
+
+ InitialisationMode m_eMode;
+
+ ::com::sun::star::uno::Reference < com::sun::star::container::XNameContainer > m_xRootFolder;
+ ::com::sun::star::uno::Reference < com::sun::star::io::XStream > m_xStream;
+ ::com::sun::star::uno::Reference < com::sun::star::io::XInputStream > m_xContentStream;
+ ::com::sun::star::uno::Reference < com::sun::star::io::XSeekable > m_xContentSeek;
+ const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > m_xFactory;
+
+ ZipPackageFolder *m_pRootFolder;
+ ZipFile *m_pZipFile;
+
+ void parseManifest();
+ void parseContentType();
+ void getZipFileContents();
+
+ void WriteMimetypeMagicFile( ZipOutputStream& aZipOut );
+ void WriteManifest( ZipOutputStream& aZipOut, const ::std::vector< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > >& aManList );
+ void WriteContentTypes( ZipOutputStream& aZipOut, const ::std::vector< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > >& aManList );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > writeTempFile();
+ ::com::sun::star::uno::Reference < ::com::sun::star::io::XActiveDataStreamer > openOriginalForOutput();
+ void DisconnectFromTargetAndThrowException_Impl(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xTempStream );
+
+public:
+ ZipPackage (const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > &xNewFactory);
+ virtual ~ZipPackage( void );
+ ZipFile& getZipFile() { return *m_pZipFile;}
+ const com::sun::star::uno::Sequence < sal_Int8 > & getEncryptionKey ( ) {return m_aEncryptionKey;}
+ sal_Int32 getFormat() const { return m_nFormat; }
+
+ SotMutexHolderRef GetSharedMutexRef() { return m_aMutexHolder; }
+
+ void ConnectTo( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInStream );
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ // XHierarchicalNameAccess
+ virtual ::com::sun::star::uno::Any SAL_CALL getByHierarchicalName( const ::rtl::OUString& aName )
+ throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasByHierarchicalName( const ::rtl::OUString& aName )
+ throw(::com::sun::star::uno::RuntimeException);
+ // XSingleServiceFactory
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstance( )
+ throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithArguments( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ // XChangesBatch
+ virtual void SAL_CALL commitChanges( )
+ throw(::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasPendingChanges( )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::util::ElementChange > SAL_CALL getPendingChanges( )
+ throw(::com::sun::star::uno::RuntimeException);
+ // XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
+ throw(::com::sun::star::uno::RuntimeException);
+ com::sun::star::uno::Sequence < sal_Int8 > getUnoTunnelImplementationId( void )
+ throw(::com::sun::star::uno::RuntimeException);
+ // XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // Uno componentiseralation
+ static ::rtl::OUString static_getImplementationName();
+ static ::com::sun::star::uno::Sequence < ::rtl::OUString > static_getSupportedServiceNames();
+ static ::com::sun::star::uno::Reference < com::sun::star::lang::XSingleServiceFactory > createServiceFactory( com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > const & rServiceFactory );
+ sal_Bool SAL_CALL static_supportsService(rtl::OUString const & rServiceName);
+};
+#endif
diff --git a/package/inc/ZipPackageBuffer.hxx b/package/inc/ZipPackageBuffer.hxx
new file mode 100644
index 000000000000..54876d97bde1
--- /dev/null
+++ b/package/inc/ZipPackageBuffer.hxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _ZIP_PACKAGE_BUFFER_HXX
+#define _ZIP_PACKAGE_BUFFER_HXX
+
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#ifndef _CPPUHELPER_IMPLBASE3_HXX
+#include <cppuhelper/implbase3.hxx>
+#endif
+
+class ZipPackage;
+
+class ZipPackageBuffer : public ::cppu::WeakImplHelper3
+<
+ com::sun::star::io::XInputStream,
+ com::sun::star::io::XOutputStream,
+ com::sun::star::io::XSeekable
+>
+{
+protected:
+ com::sun::star::uno::Sequence < sal_Int8 > m_aBuffer;
+ sal_Int64 m_nBufferSize, m_nEnd, m_nCurrent;
+ sal_Bool m_bMustInitBuffer;
+public:
+ ZipPackageBuffer(sal_Int64 nNewBufferSize);
+ virtual ~ZipPackageBuffer(void);
+
+ inline void realloc ( sal_Int32 nSize ) { m_aBuffer.realloc ( nSize ); }
+ inline const sal_Int8 * getConstArray () const { return m_aBuffer.getConstArray(); }
+ inline const com::sun::star::uno::Sequence < sal_Int8> getSequence () const { return m_aBuffer; }
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL available( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeInput( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ // XOutputStream
+ virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< sal_Int8 >& aData )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL flush( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeOutput( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ // XSeekable
+ virtual void SAL_CALL seek( sal_Int64 location )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getPosition( )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getLength( )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+};
+#endif
diff --git a/package/inc/ZipPackageFolder.hxx b/package/inc/ZipPackageFolder.hxx
new file mode 100644
index 000000000000..89414f18ce65
--- /dev/null
+++ b/package/inc/ZipPackageFolder.hxx
@@ -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.
+ *
+ ************************************************************************/
+#ifndef _ZIP_PACKAGE_FOLDER_HXX
+#define _ZIP_PACKAGE_FOLDER_HXX
+
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/beans/StringPair.hpp>
+#include <HashMaps.hxx>
+#include <ZipPackageEntry.hxx>
+#include <cppuhelper/implbase2.hxx>
+
+namespace com { namespace sun { namespace star {
+namespace beans
+{
+ struct PropertyValue;
+}
+} } }
+class ZipFile;
+class ZipPackage;
+class ZipOutputStream;
+struct ZipEntry;
+typedef void* rtlRandomPool;
+
+class ZipPackageFolder : public cppu::ImplInheritanceHelper2
+<
+ ZipPackageEntry,
+ ::com::sun::star::container::XNameContainer,
+ ::com::sun::star::container::XEnumerationAccess
+>
+{
+ static com::sun::star::uno::Sequence < sal_Int8 > aImplementationId;
+
+protected:
+ ContentHash maContents;
+ const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > m_xFactory;
+ sal_Int32 m_nFormat;
+ ::rtl::OUString m_sVersion;
+
+public:
+
+ ZipPackageFolder( const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory >& xFactory,
+ sal_Int32 nFormat,
+ sal_Bool bAllowRemoveOnInsert );
+ virtual ~ZipPackageFolder();
+
+ ::rtl::OUString& GetVersion() { return m_sVersion; }
+ void SetVersion( const ::rtl::OUString& aVersion ) { m_sVersion = aVersion; }
+
+ sal_Bool LookForUnexpectedODF12Streams( const ::rtl::OUString& aPath );
+
+ void setChildStreamsTypeByExtension( const ::com::sun::star::beans::StringPair& aPair );
+
+ void doInsertByName ( ZipPackageEntry *pEntry, sal_Bool bSetParent )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ com::sun::star::packages::ContentInfo & doGetByName( const ::rtl::OUString& aName )
+ throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ static void copyZipEntry( ZipEntry &rDest, const ZipEntry &rSource);
+ static ::com::sun::star::uno::Sequence < sal_Int8 > static_getImplementationId()
+ {
+ return aImplementationId;
+ }
+
+ void setPackageFormat_Impl( sal_Int32 nFormat ) { m_nFormat = nFormat; }
+ void setRemoveOnInsertMode_Impl( sal_Bool bRemove ) { this->mbAllowRemoveOnInsert = bRemove; }
+
+ // Recursive functions
+ void saveContents(rtl::OUString &rPath, std::vector < com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > > &rManList, ZipOutputStream & rZipOut, com::sun::star::uno::Sequence < sal_Int8 > &rEncryptionKey, rtlRandomPool & rRandomPool)
+ throw(::com::sun::star::uno::RuntimeException);
+ void releaseUpwardRef();
+
+ // XNameContainer
+ virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeByName( const ::rtl::OUString& Name )
+ throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XEnumerationAccess
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createEnumeration( )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XElementAccess
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType( )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements( )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XNameAccess
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
+ throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XNameReplace
+ virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XPropertySet
+ virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw (::com::sun::star::uno::RuntimeException);
+};
+#endif
diff --git a/package/inc/makefile.mk b/package/inc/makefile.mk
new file mode 100644
index 000000000000..19d89678b0ae
--- /dev/null
+++ b/package/inc/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# 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=package
+TARGET=inc
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.IF "$(ENABLE_PCH)"!=""
+ALLTAR : \
+ $(SLO)$/precompiled.pch \
+ $(SLO)$/precompiled_ex.pch
+
+.ENDIF # "$(ENABLE_PCH)"!=""
+
diff --git a/package/inc/mutexholder.hxx b/package/inc/mutexholder.hxx
new file mode 100644
index 000000000000..97b410ad549b
--- /dev/null
+++ b/package/inc/mutexholder.hxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __MUTEXHOLDER_HXX_
+#define __MUTEXHOLDER_HXX_
+
+#include <osl/mutex.hxx>
+
+class SotMutexHolder
+{
+ ::osl::Mutex m_aMutex;
+ sal_Int32 m_nRefCount;
+
+ public:
+ SotMutexHolder() : m_nRefCount( 0 ) {}
+
+ void AddRef()
+ {
+ m_nRefCount++;
+ }
+
+ void ReleaseRef()
+ {
+ if ( !--m_nRefCount )
+ delete this;
+ }
+
+ ::osl::Mutex& GetMutex() { return m_aMutex; }
+};
+
+class SotMutexHolderRef
+{
+ SotMutexHolder* m_pHolder;
+
+public:
+ SotMutexHolderRef()
+ : m_pHolder( NULL )
+ {}
+
+ SotMutexHolderRef( SotMutexHolder* pHolder )
+ : m_pHolder( pHolder )
+ {
+ if ( m_pHolder )
+ m_pHolder->AddRef();
+ }
+
+ SotMutexHolderRef( const SotMutexHolderRef& rRef )
+ : m_pHolder( rRef.m_pHolder )
+ {
+ if ( m_pHolder )
+ m_pHolder->AddRef();
+ }
+
+ ~SotMutexHolderRef()
+ {
+ if ( m_pHolder )
+ m_pHolder->ReleaseRef();
+ }
+
+ SotMutexHolderRef& operator =( const SotMutexHolderRef& rRef )
+ {
+ if ( m_pHolder )
+ m_pHolder->ReleaseRef();
+
+ m_pHolder = rRef.m_pHolder;
+
+ if ( m_pHolder )
+ m_pHolder->AddRef();
+
+ return *this;
+ }
+
+ SotMutexHolderRef& operator =( SotMutexHolder* pHolder )
+ {
+ if ( m_pHolder )
+ m_pHolder->ReleaseRef();
+
+ m_pHolder = pHolder;
+
+ if ( m_pHolder )
+ m_pHolder->AddRef();
+ return *this;
+ }
+
+ SotMutexHolder* operator ->() const
+ {
+ return m_pHolder;
+ }
+
+ SotMutexHolder& operator *() const
+ {
+ return *m_pHolder;
+ }
+
+ operator SotMutexHolder*() const
+ {
+ return m_pHolder;
+ }
+
+ sal_Bool Is() const
+ {
+ return m_pHolder != NULL;
+ }
+};
+
+#endif
+
diff --git a/package/inc/pch/precompiled_package.cxx b/package/inc/pch/precompiled_package.cxx
new file mode 100644
index 000000000000..da7eca4d4557
--- /dev/null
+++ b/package/inc/pch/precompiled_package.cxx
@@ -0,0 +1,29 @@
+/*************************************************************************
+ *
+ * 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 "precompiled_package.hxx"
+
diff --git a/package/inc/pch/precompiled_package.hxx b/package/inc/pch/precompiled_package.hxx
new file mode 100644
index 000000000000..3fc91f789528
--- /dev/null
+++ b/package/inc/pch/precompiled_package.hxx
@@ -0,0 +1,32 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): Generated on 2006-09-01 17:49:53.889391
+
+#ifdef PRECOMPILED_HEADERS
+#endif
+
diff --git a/package/inc/zipfileaccess.hxx b/package/inc/zipfileaccess.hxx
new file mode 100644
index 000000000000..61297aed6da6
--- /dev/null
+++ b/package/inc/zipfileaccess.hxx
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _ZIPFILEACCESS_HXX_
+#define _ZIPFILEACCESS_HXX_
+
+#include <com/sun/star/packages/zip/XZipFileAccess.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+
+#include <cppuhelper/interfacecontainer.h>
+#include <cppuhelper/implbase5.hxx>
+
+#include <mutexholder.hxx>
+
+#include <ZipFile.hxx>
+#include <HashMaps.hxx>
+
+class OZipFileAccess : public ::cppu::WeakImplHelper5<
+ ::com::sun::star::packages::zip::XZipFileAccess,
+ ::com::sun::star::container::XNameAccess,
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::lang::XComponent,
+ ::com::sun::star::lang::XServiceInfo >
+{
+ SotMutexHolderRef m_aMutexHolder;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > m_xContentStream;
+ ZipFile* m_pZipFile;
+
+ ::cppu::OInterfaceContainerHelper* m_pListenersContainer;
+
+ sal_Bool m_bDisposed;
+
+public:
+ OZipFileAccess( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory );
+
+ virtual ~OZipFileAccess();
+
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > GetPatternsFromString_Impl( const ::rtl::OUString& aString );
+
+ sal_Bool StringGoodForPattern_Impl( const ::rtl::OUString& aString,
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPattern );
+
+
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL impl_staticGetSupportedServiceNames();
+
+ static ::rtl::OUString SAL_CALL impl_staticGetImplementationName();
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL impl_staticCreateSelfInstance(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager );
+
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XNameAccess
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XZipFileAccess
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getStreamByPattern( const ::rtl::OUString& aPattern ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // XComponent
+ virtual void SAL_CALL dispose( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException);
+
+};
+
+#endif
+
diff --git a/package/prj/build.lst b/package/prj/build.lst
new file mode 100644
index 000000000000..0b508271765c
--- /dev/null
+++ b/package/prj/build.lst
@@ -0,0 +1,9 @@
+pk package : cppu cppuhelper comphelper ucbhelper sal ZLIB:zlib NULL
+pk package usr1 - all pk_mkout NULL
+pk package\inc nmake - all pk_inc NULL
+pk package\source\zipapi nmake - all pk_zipapi pk_inc NULL
+pk package\source\zippackage nmake - all pk_zippackage pk_inc NULL
+pk package\source\manifest nmake - all pk_manifest pk_inc NULL
+pk package\source\xstor nmake - all pk_xstor pk_manifest pk_inc NULL
+pk package\util nmake - all pk_util pk_zipapi pk_zippackage pk_manifest pk_xstor NULL
+
diff --git a/package/prj/d.lst b/package/prj/d.lst
new file mode 100644
index 000000000000..23966d0cfeae
--- /dev/null
+++ b/package/prj/d.lst
@@ -0,0 +1,5 @@
+..\%__SRC%\misc\*.map %_DEST%\bin%_EXT%\*.map
+..\%__SRC%\bin\*.dll %_DEST%\bin%_EXT%\*.dll
+..\%__SRC%\lib\lib*.so %_DEST%\lib%_EXT%\lib*.so
+..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*.dylib
+..\dtd\*.dtd %_DEST%\bin%_EXT%\*.*
diff --git a/package/qa/ofopxmlstorages/StorageTest.java b/package/qa/ofopxmlstorages/StorageTest.java
new file mode 100644
index 000000000000..5f3b2ff2a799
--- /dev/null
+++ b/package/qa/ofopxmlstorages/StorageTest.java
@@ -0,0 +1,7 @@
+package complex.ofopxmlstorages;
+
+public interface StorageTest
+{
+ boolean test();
+}
+
diff --git a/package/qa/ofopxmlstorages/StorageUnitTest.java b/package/qa/ofopxmlstorages/StorageUnitTest.java
new file mode 100644
index 000000000000..65294d46bbb9
--- /dev/null
+++ b/package/qa/ofopxmlstorages/StorageUnitTest.java
@@ -0,0 +1,158 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+package complex.ofopxmlstorages;
+
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.connection.XConnector;
+import com.sun.star.connection.XConnection;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.uno.XNamingService;
+import com.sun.star.uno.XComponentContext;
+
+import com.sun.star.container.*;
+import com.sun.star.beans.*;
+import com.sun.star.lang.*;
+
+import complexlib.ComplexTestCase;
+
+import complex.ofopxmlstorages.*;
+
+import util.utils;
+import java.util.*;
+import java.io.*;
+
+/* This unit test for storage objects is designed to
+ * test most important statements from storage service
+ * specification.
+ *
+ * Regression tests are added to extend the tested
+ * functionalities.
+ */
+public class StorageUnitTest extends ComplexTestCase
+{
+ private XMultiServiceFactory m_xMSF = null;
+ private XSingleServiceFactory m_xStorageFactory = null;
+
+ public String[] getTestMethodNames()
+ {
+ return new String[] {
+ "ExecuteTest01",
+ "ExecuteTest02",
+ "ExecuteTest03",
+ "ExecuteTest04",
+ "ExecuteTest05",
+ "ExecuteTest06",
+ "ExecuteTest07",
+ "ExecuteTest08"
+ };
+ }
+
+ public String getTestObjectName()
+ {
+ return "StorageUnitTest";
+ }
+
+ public void before()
+ {
+ m_xMSF = (XMultiServiceFactory)param.getMSF();
+ if ( m_xMSF == null )
+ {
+ failed( "Can't create service factory!" );
+ return;
+ }
+
+ try {
+ Object oStorageFactory = m_xMSF.createInstance( "com.sun.star.embed.StorageFactory" );
+ m_xStorageFactory = (XSingleServiceFactory)UnoRuntime.queryInterface( XSingleServiceFactory.class,
+ oStorageFactory );
+ }
+ catch( Exception e )
+ {
+ failed( "Can't create storage factory!" );
+ return;
+ }
+
+ if ( m_xStorageFactory == null )
+ {
+ failed( "Can't create service factory!" );
+ return;
+ }
+ }
+
+ public void ExecuteTest01()
+ {
+ StorageTest aTest = new Test01( m_xMSF, m_xStorageFactory, log );
+ assure( "Test01 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest02()
+ {
+ StorageTest aTest = new Test02( m_xMSF, m_xStorageFactory, log );
+ assure( "Test02 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest03()
+ {
+ StorageTest aTest = new Test03( m_xMSF, m_xStorageFactory, log );
+ assure( "Test03 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest04()
+ {
+ StorageTest aTest = new Test04( m_xMSF, m_xStorageFactory, log );
+ assure( "Test04 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest05()
+ {
+ StorageTest aTest = new Test05( m_xMSF, m_xStorageFactory, log );
+ assure( "Test05 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest06()
+ {
+ StorageTest aTest = new Test06( m_xMSF, m_xStorageFactory, log );
+ assure( "Test06 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest07()
+ {
+ StorageTest aTest = new Test07( m_xMSF, m_xStorageFactory, log );
+ assure( "Test07 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest08()
+ {
+ StorageTest aTest = new Test08( m_xMSF, m_xStorageFactory, log );
+ assure( "Test08 failed!", aTest.test() );
+ }
+}
+
diff --git a/package/qa/ofopxmlstorages/Test01.java b/package/qa/ofopxmlstorages/Test01.java
new file mode 100644
index 000000000000..abb73c3fc48b
--- /dev/null
+++ b/package/qa/ofopxmlstorages/Test01.java
@@ -0,0 +1,200 @@
+package complex.ofopxmlstorages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.embed.*;
+import com.sun.star.beans.StringPair;
+
+import share.LogWriter;
+import complex.ofopxmlstorages.TestHelper;
+import complex.ofopxmlstorages.StorageTest;
+
+public class Test01 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test01( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test01: " );
+ }
+
+ public boolean test()
+ {
+ StringPair[][] aRelations1 =
+ { { new StringPair( "Id", "Num1" ) },
+ { new StringPair( "Target", "TargetURLValue1" ), new StringPair( "Id", "Num6" ) },
+ { new StringPair( "Target", "" ), new StringPair( "Id", "Num7" ) },
+ { new StringPair( "Id", "Num2" ), new StringPair( "TargetMode", "Internal1" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value 1" ) },
+ { new StringPair( "Id", "Num3" ), new StringPair( "TargetMode", "Internal1" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value 1" ) },
+ { new StringPair( "Id", "Num4" ), new StringPair( "TargetMode", "Internal1" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value 1" ) },
+ { new StringPair( "Id", "Num5" ), new StringPair( "TargetMode", "" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value1" ) }
+ };
+
+ StringPair[][] aRelations2 =
+ { { new StringPair( "Id", "Num1" ) },
+ { new StringPair( "Target", "TargetURLValue2" ), new StringPair( "Id", "Num6" ) },
+ { new StringPair( "Target", "" ), new StringPair( "Id", "Num7" ) },
+ { new StringPair( "Id", "Num2" ), new StringPair( "TargetMode", "Internal2" ), new StringPair( "Type", "unknown2" ), new StringPair( "Target", "URL value 2" ) },
+ { new StringPair( "Id", "Num3" ), new StringPair( "TargetMode", "Internal2" ), new StringPair( "Type", "unknown2" ), new StringPair( "Target", "URL value 2" ) },
+ { new StringPair( "Id", "Num4" ), new StringPair( "TargetMode", "Internal2" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) },
+ { new StringPair( "Id", "Num5" ), new StringPair( "TargetMode", "" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) }
+ };
+
+ try
+ {
+ String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
+ if ( sTempFileURL == null || sTempFileURL == "" )
+ {
+ m_aTestHelper.Error( "No valid temporary file was created!" );
+ return false;
+ }
+
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ XStorage xTempStorage = m_aTestHelper.createTempStorage( m_xMSF, m_xStorageFactory );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage,
+ "SubStream1",
+ "MediaType1",
+ true,
+ pBytes1,
+ aRelations1 ) )
+ return false;
+
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage,
+ "SubStream2",
+ "MediaType2",
+ false,
+ pBytes2,
+ aRelations2 ) )
+ return false;
+
+ // set Relations for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ true,
+ ElementModes.WRITE,
+ aRelations1 ) )
+ return false;
+
+ // set Relations for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ false,
+ ElementModes.WRITE,
+ aRelations1 ) )
+ return false;
+
+ // create temporary storage based on a previously created temporary file
+ XStorage xTempFileStorage = m_aTestHelper.createStorageFromURL( m_xStorageFactory,
+ sTempFileURL,
+ ElementModes.WRITE );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ // copy xTempStorage to xTempFileStorage
+ // xTempFileStorage will be automatically commited
+ if ( !m_aTestHelper.copyStorage( xTempStorage, xTempFileStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) || !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+ // ================================================
+ // now check all the written and copied information
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ XStorage xResultStorage = m_aTestHelper.createStorageFromURL( m_xStorageFactory,
+ sTempFileURL,
+ ElementModes.WRITE );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage,
+ true,
+ ElementModes.WRITE,
+ aRelations1 ) )
+ return false;
+
+ // open existing substorage
+ XStorage xResultSubStorage = m_aTestHelper.openSubStorage( xResultStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xResultSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultSubStorage,
+ false,
+ ElementModes.READ,
+ aRelations1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage,
+ "SubStream1",
+ "MediaType1",
+ pBytes1,
+ aRelations1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage,
+ "SubStream2",
+ "MediaType2",
+ pBytes2,
+ aRelations2 ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/ofopxmlstorages/Test02.java b/package/qa/ofopxmlstorages/Test02.java
new file mode 100644
index 000000000000..4ba7892b8295
--- /dev/null
+++ b/package/qa/ofopxmlstorages/Test02.java
@@ -0,0 +1,164 @@
+package complex.ofopxmlstorages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+import com.sun.star.beans.StringPair;
+
+import share.LogWriter;
+import complex.ofopxmlstorages.TestHelper;
+import complex.ofopxmlstorages.StorageTest;
+
+public class Test02 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test02( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test02: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ StringPair[][] aRelations =
+ { { new StringPair( "Id", "Num1" ) },
+ { new StringPair( "Target", "TargetURLValue" ), new StringPair( "Id", "Num6" ) },
+ { new StringPair( "Target", "" ), new StringPair( "Id", "Num7" ) },
+ { new StringPair( "Id", "Num2" ), new StringPair( "TargetMode", "Internal" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) },
+ { new StringPair( "Id", "Num3" ), new StringPair( "TargetMode", "Internal" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) },
+ { new StringPair( "Id", "Num4" ), new StringPair( "TargetMode", "Internal" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) },
+ { new StringPair( "Id", "Num5" ), new StringPair( "TargetMode", "" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) }
+ };
+
+
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ XStorage xTempStorage = m_aTestHelper.createStorageFromStream( m_xStorageFactory,
+ xTempFileStream,
+ ElementModes.WRITE );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage,
+ "SubStream1",
+ "MediaType1",
+ true,
+ pBytes1,
+ aRelations ) )
+ return false;
+
+ // set Relations for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ true,
+ ElementModes.WRITE,
+ aRelations ) )
+ return false;
+
+ // set Relations for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ false,
+ ElementModes.WRITE,
+ aRelations ) )
+ return false;
+
+ // commit substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+
+ // ================================================
+ // now check all the written information
+ // ================================================
+
+ // close the output part of the temporary stream
+ // the output part must present since we already wrote to the stream
+ if ( !m_aTestHelper.closeOutput( xTempFileStream ) )
+ return false;
+
+ XInputStream xTempInStream = m_aTestHelper.getInputStream( xTempFileStream );
+ if ( xTempInStream == null )
+ return false;
+
+
+ // open input stream
+ XStorage xResultStorage = m_aTestHelper.createStorageFromInputStream( m_xStorageFactory, xTempInStream );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open storage based on input stream!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage, true, ElementModes.READ, aRelations ) )
+ return false;
+
+ // open existing substorage
+ XStorage xResultSubStorage = m_aTestHelper.openSubStorage( xResultStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xResultSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultSubStorage,
+ false,
+ ElementModes.READ,
+ aRelations ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream1", "MediaType1", pBytes1, aRelations ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/ofopxmlstorages/Test03.java b/package/qa/ofopxmlstorages/Test03.java
new file mode 100644
index 000000000000..e3424c9106f2
--- /dev/null
+++ b/package/qa/ofopxmlstorages/Test03.java
@@ -0,0 +1,233 @@
+package complex.ofopxmlstorages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.embed.*;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.beans.StringPair;
+
+import share.LogWriter;
+import complex.ofopxmlstorages.TestHelper;
+import complex.ofopxmlstorages.StorageTest;
+
+public class Test03 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test03( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test03: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ StringPair[][] aRelations =
+ { { new StringPair( "Id", "Num1" ) },
+ { new StringPair( "Target", "TargetURLValue" ), new StringPair( "Id", "Num6" ) },
+ { new StringPair( "Target", "" ), new StringPair( "Id", "Num7" ) },
+ { new StringPair( "Id", "Num2" ), new StringPair( "TargetMode", "Internal" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) },
+ { new StringPair( "Id", "Num3" ), new StringPair( "TargetMode", "Internal" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) },
+ { new StringPair( "Id", "Num4" ), new StringPair( "TargetMode", "Internal" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) },
+ { new StringPair( "Id", "Num5" ), new StringPair( "TargetMode", "" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) }
+ };
+
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ XStorage xTempStorage = m_aTestHelper.createTempStorage( m_xMSF, m_xStorageFactory );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempStorage,
+ "SubStream1",
+ "MediaType1",
+ true,
+ pBytes1,
+ aRelations ) )
+ return false;
+
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage,
+ "SubStream2",
+ "MediaType2",
+ false,
+ pBytes2,
+ aRelations ) )
+ return false;
+
+ // set Relations for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ false,
+ ElementModes.WRITE,
+ aRelations ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // ================================================
+ // check storage hyerarchy tree
+ // ================================================
+
+ // check that isStorageElement() and isStreamElement reacts to nonexisting object correctly
+ try {
+ xTempStorage.isStorageElement( "does not exist" );
+ m_aTestHelper.Error( "Nonexisting element doesn't detected by isStorageElement() call!" );
+ return false;
+ }
+ catch( com.sun.star.container.NoSuchElementException ne )
+ {
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Wrong exception is thrown by isStorageElement() call: " + e );
+ return false;
+ }
+
+ try {
+ xTempStorage.isStreamElement( "does not exist" );
+ m_aTestHelper.Error( "Nonexisting element doesn't detected by isStreamElement() call!" );
+ return false;
+ }
+ catch( com.sun.star.container.NoSuchElementException ne )
+ {
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Wrong exception is thrown by isStreamElement() call: " + e );
+ return false;
+ }
+
+ XNameAccess xRootNameAccess = (XNameAccess) UnoRuntime.queryInterface( XNameAccess.class, xTempStorage );
+ if ( xRootNameAccess == null )
+ {
+ m_aTestHelper.Error( "Root storage doesn't support XNameAccess!" );
+ return false;
+ }
+
+ try {
+ if ( !xTempStorage.isStorageElement( "SubStorage1" ) || xTempStorage.isStreamElement( "SubStorage1" ) )
+ {
+ m_aTestHelper.Error( "Child 'SubStorage1' can not be detected as storage!" );
+ return false;
+ }
+
+ if ( xTempStorage.isStorageElement( "SubStream1" ) || !xTempStorage.isStreamElement( "SubStream1" ) )
+ {
+ m_aTestHelper.Error( "Child 'SubStream1' can not be detected as stream!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Child's type can not be detected, exception: " + e );
+ return false;
+ }
+
+
+ // check that root storage contents are represented correctly
+ String sRootCont[] = xRootNameAccess.getElementNames();
+
+ if ( sRootCont.length != 2 )
+ {
+ m_aTestHelper.Error( "Root storage contains wrong amount of children!" );
+ return false;
+ }
+
+ if ( !( sRootCont[0].equals( "SubStorage1" ) && sRootCont[1].equals( "SubStream1" )
+ || sRootCont[0].equals( "SubStream1" ) && sRootCont[1].equals( "SubStorage1" ) )
+ || !( xRootNameAccess.hasByName( "SubStream1" ) && xRootNameAccess.hasByName( "SubStorage1" ) ) )
+ {
+ m_aTestHelper.Error( "Root storage contains wrong list of children!" );
+ return false;
+ }
+
+ // get storage through XNameAccess
+ XStorage xResultSubStorage = getStorageFromNameAccess( xRootNameAccess, "SubStorage1" );
+ if ( xResultSubStorage == null )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultSubStorage,
+ false,
+ ElementModes.READ,
+ aRelations ) )
+ return false;
+
+ XNameAccess xChildAccess = (XNameAccess) UnoRuntime.queryInterface( XNameAccess.class, xResultSubStorage );
+ if ( xChildAccess == null )
+ {
+ m_aTestHelper.Error( "Child storage doesn't support XNameAccess!" );
+ return false;
+ }
+
+ if ( !xChildAccess.hasByName( "SubStream2" )
+ || !xResultSubStorage.isStreamElement( "SubStream2" )
+ || xResultSubStorage.isStorageElement( "SubStream2" ) )
+ {
+ m_aTestHelper.Error( "'SubStream2' can not be detected as child stream element of 'SubStorage1'!" );
+ return false;
+ }
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+ public XStorage getStorageFromNameAccess( XNameAccess xAccess, String sName )
+ {
+ try
+ {
+ Object oStorage = xAccess.getByName( sName );
+ XStorage xResult = (XStorage) UnoRuntime.queryInterface( XStorage.class, oStorage );
+
+ if ( xResult != null )
+ return xResult;
+ else
+ m_aTestHelper.Error( "Can't retrieve substorage '" + sName + "' through XNameAccess!" );
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Can't retrieve substorage '" + sName + "' through XNameAccess, exception: " + e );
+ }
+
+ return null;
+ }
+
+}
+
diff --git a/package/qa/ofopxmlstorages/Test04.java b/package/qa/ofopxmlstorages/Test04.java
new file mode 100644
index 000000000000..8b99c15bd77c
--- /dev/null
+++ b/package/qa/ofopxmlstorages/Test04.java
@@ -0,0 +1,308 @@
+package complex.ofopxmlstorages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+import com.sun.star.lang.DisposedException;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.container.XNameAccess;
+
+import com.sun.star.embed.*;
+import com.sun.star.beans.StringPair;
+
+import share.LogWriter;
+import complex.ofopxmlstorages.TestHelper;
+import complex.ofopxmlstorages.StorageTest;
+
+public class Test04 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test04( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test04: " );
+ }
+
+ public boolean test()
+ {
+ StringPair[][] aRelations1 =
+ { { new StringPair( "Id", "Num1" ) },
+ { new StringPair( "Target", "TargetURLValue1" ), new StringPair( "Id", "Num6" ) },
+ { new StringPair( "Target", "" ), new StringPair( "Id", "Num7" ) },
+ { new StringPair( "Id", "Num2" ), new StringPair( "TargetMode", "Internal1" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value 1" ) },
+ { new StringPair( "Id", "Num3" ), new StringPair( "TargetMode", "Internal1" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value 1" ) },
+ { new StringPair( "Id", "Num4" ), new StringPair( "TargetMode", "Internal1" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value 1" ) },
+ { new StringPair( "Id", "Num5" ), new StringPair( "TargetMode", "" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value1" ) }
+ };
+
+ StringPair[][] aRelations2 =
+ { { new StringPair( "Id", "Num1" ) },
+ { new StringPair( "Target", "TargetURLValue2" ), new StringPair( "Id", "Num6" ) },
+ { new StringPair( "Target", "" ), new StringPair( "Id", "Num7" ) },
+ { new StringPair( "Id", "Num2" ), new StringPair( "TargetMode", "Internal2" ), new StringPair( "Type", "unknown2" ), new StringPair( "Target", "URL value 2" ) },
+ { new StringPair( "Id", "Num3" ), new StringPair( "TargetMode", "Internal2" ), new StringPair( "Type", "unknown2" ), new StringPair( "Target", "URL value 2" ) },
+ { new StringPair( "Id", "Num4" ), new StringPair( "TargetMode", "Internal2" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) },
+ { new StringPair( "Id", "Num5" ), new StringPair( "TargetMode", "" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) }
+ };
+
+ try
+ {
+ String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
+ if ( sTempFileURL == null || sTempFileURL == "" )
+ {
+ m_aTestHelper.Error( "No valid temporary file was created!" );
+ return false;
+ }
+
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ XStorage xTempStorage = m_aTestHelper.createTempStorage( m_xMSF, m_xStorageFactory );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open substorages and create streams there
+
+ // first substorage of the root storage
+ XStorage xTempSubStorage1 = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage1 == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage1,
+ "SubStream1",
+ "MediaType1",
+ true,
+ pBytes1,
+ aRelations1 ) )
+ return false;
+
+ // second substorage of the root storage
+ XStorage xTempSubStorage2 = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage2",
+ ElementModes.WRITE );
+ if ( xTempSubStorage2 == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage2,
+ "SubStream2",
+ "MediaType2",
+ false,
+ pBytes2,
+ aRelations2 ) )
+ return false;
+
+ // set Relations for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ true,
+ ElementModes.WRITE,
+ aRelations2 ) )
+ return false;
+
+ // set Relations for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage1,
+ false,
+ ElementModes.WRITE,
+ aRelations2 ) )
+ return false;
+
+ // set Relations for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage2,
+ false,
+ ElementModes.WRITE,
+ aRelations2 ) )
+ return false;
+
+ // create temporary storage based on a previously created temporary file
+ XStorage xTempFileStorage = m_aTestHelper.createStorageFromURL( m_xStorageFactory,
+ sTempFileURL,
+ ElementModes.WRITE );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.copyElementTo( xTempStorage, "SubStorage1", xTempFileStorage ) )
+ return false;
+
+ // if storage is not commited before disposing all the changes will be lost
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage2 ) )
+ return false;
+
+ // a storage must be disposed before moving/removing otherwise the access will be denied
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage2 ) )
+ return false;
+
+ if ( !m_aTestHelper.moveElementTo( xTempStorage, "SubStorage2", xTempFileStorage ) )
+ return false;
+
+ // SubStorage2 must be removed and disposed now
+ try
+ {
+ xTempSubStorage2.isStreamElement( "SubStream2" );
+ m_aTestHelper.Error( "SubStorage2 must be disposed already!" );
+ return false;
+ }
+ catch( com.sun.star.lang.DisposedException de )
+ {
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Wrong exception in case of disposed storage, exception: " + e );
+ return false;
+ }
+
+ if ( !m_aTestHelper.copyElementTo( xTempSubStorage1, "SubStream1", xTempFileStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.renameElement( xTempFileStorage, "SubStream1", "SubStream1_copy" ) )
+ return false;
+
+ if ( !m_aTestHelper.moveElementTo( xTempSubStorage1, "SubStream1", xTempFileStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xTempFileStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) || !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+ // ================================================
+ // now check all the written and copied information
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ XStorage xResStorage = m_aTestHelper.createStorageFromURL( m_xStorageFactory,
+ sTempFileURL,
+ ElementModes.WRITE );
+
+ if ( xResStorage == null )
+ {
+ m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
+ return false;
+ }
+
+ // open and check SubStorage1
+ XStorage xResSubStorage1 = m_aTestHelper.openSubStorage( xResStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xResSubStorage1 == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResSubStorage1,
+ false,
+ ElementModes.READ,
+ aRelations2 ) )
+ return false;
+
+
+ // open and check SubStorage2
+ XStorage xResSubStorage2 = m_aTestHelper.openSubStorage( xResStorage,
+ "SubStorage2",
+ ElementModes.READ );
+ if ( xResSubStorage2 == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResSubStorage2,
+ false,
+ ElementModes.READ,
+ aRelations2 ) )
+ return false;
+
+
+ // check all the result streams
+
+ if ( !m_aTestHelper.checkStream( xResStorage, "SubStream1", "MediaType1", pBytes1, aRelations1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResStorage, "SubStream1_copy", "MediaType1", pBytes1, aRelations1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResSubStorage1, "SubStream1", "MediaType1", pBytes1, aRelations1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResSubStorage2, "SubStream2", "MediaType2", pBytes2, aRelations2 ) )
+ return false;
+
+ // the storage must be disposed before removing
+ if ( !m_aTestHelper.disposeStorage( xResSubStorage2 ) )
+ return false;
+
+ // remove element and check that it was removed completelly
+ if ( !m_aTestHelper.removeElement( xResStorage, "SubStorage2" ) )
+ return false;
+
+ try
+ {
+ XNameAccess xResAccess = (XNameAccess) UnoRuntime.queryInterface( XNameAccess.class, xResStorage );
+ if ( xResAccess.hasByName( "SubStorage2" ) )
+ m_aTestHelper.Error( "SubStorage2 must be removed already!" );
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Can't get access to root storage, exception: " + e );
+ return false;
+ }
+
+ try
+ {
+ xResSubStorage2.isStreamElement( "SubStream2" );
+
+ m_aTestHelper.Error( "SubStorage2 must be disposed already!" );
+ return false;
+ }
+ catch( com.sun.star.lang.DisposedException de )
+ {
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Wrong exception in case of disposed storage, exception: " + e );
+ return false;
+ }
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/ofopxmlstorages/Test05.java b/package/qa/ofopxmlstorages/Test05.java
new file mode 100644
index 000000000000..36439ca6ebcd
--- /dev/null
+++ b/package/qa/ofopxmlstorages/Test05.java
@@ -0,0 +1,314 @@
+package complex.ofopxmlstorages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+
+import com.sun.star.embed.*;
+import com.sun.star.beans.StringPair;
+
+import share.LogWriter;
+import complex.ofopxmlstorages.TestHelper;
+import complex.ofopxmlstorages.StorageTest;
+
+public class Test05 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test05( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test05: " );
+ }
+
+ public boolean test()
+ {
+ StringPair[][] aRelations1 =
+ { { new StringPair( "Id", "Num1" ) },
+ { new StringPair( "Target", "TargetURLValue1" ), new StringPair( "Id", "Num6" ) },
+ { new StringPair( "Target", "" ), new StringPair( "Id", "Num7" ) },
+ { new StringPair( "Id", "Num2" ), new StringPair( "TargetMode", "Internal1" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value 1" ) },
+ { new StringPair( "Id", "Num3" ), new StringPair( "TargetMode", "Internal1" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value 1" ) },
+ { new StringPair( "Id", "Num4" ), new StringPair( "TargetMode", "Internal1" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value 1" ) },
+ { new StringPair( "Id", "Num5" ), new StringPair( "TargetMode", "" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value1" ) }
+ };
+
+ StringPair[][] aRelations2 =
+ { { new StringPair( "Id", "Num1" ) },
+ { new StringPair( "Target", "TargetURLValue2" ), new StringPair( "Id", "Num6" ) },
+ { new StringPair( "Target", "" ), new StringPair( "Id", "Num7" ) },
+ { new StringPair( "Id", "Num2" ), new StringPair( "TargetMode", "Internal2" ), new StringPair( "Type", "unknown2" ), new StringPair( "Target", "URL value 2" ) },
+ { new StringPair( "Id", "Num3" ), new StringPair( "TargetMode", "Internal2" ), new StringPair( "Type", "unknown2" ), new StringPair( "Target", "URL value 2" ) },
+ { new StringPair( "Id", "Num4" ), new StringPair( "TargetMode", "Internal2" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) },
+ { new StringPair( "Id", "Num5" ), new StringPair( "TargetMode", "" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) }
+ };
+
+ try
+ {
+ String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
+ if ( sTempFileURL == null || sTempFileURL == "" )
+ {
+ m_aTestHelper.Error( "No valid temporary file was created!" );
+ return false;
+ }
+
+ // create temporary storage based on a previously created temporary file
+ XStorage xTempFileStorage = m_aTestHelper.createStorageFromURL( m_xStorageFactory,
+ sTempFileURL,
+ ElementModes.WRITE );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempFileStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xSubSubStorage = m_aTestHelper.openSubStorage( xTempSubStorage,
+ "SubSubStorage1",
+ ElementModes.WRITE );
+ if ( xSubSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xSubSubStorage,
+ "SubStream1",
+ "MediaType1",
+ true,
+ pBytes1,
+ aRelations1 ) )
+ return false;
+
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xSubSubStorage,
+ "SubStream2",
+ "MediaType2",
+ false,
+ pBytes2,
+ aRelations2 ) )
+ return false;
+
+ // set Relations for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempFileStorage,
+ true,
+ ElementModes.WRITE,
+ aRelations2 ) )
+ return false;
+
+ // set Relations for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ false,
+ ElementModes.WRITE,
+ aRelations2 ) )
+ return false;
+
+ // set Relations for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xSubSubStorage,
+ false,
+ ElementModes.WRITE,
+ aRelations2 ) )
+ return false;
+
+
+ // commit all the storages
+ if ( !m_aTestHelper.commitStorage( xSubSubStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xTempFileStorage ) )
+ return false;
+
+ // try to open an opened substorage, open call must fail
+ if ( !m_aTestHelper.cantOpenStorage( xTempFileStorage, "SubStorage1" ) )
+ return false;
+
+
+ // reopen created streams
+ XStream xSubStream1 = m_aTestHelper.OpenStream( xSubSubStorage,
+ "SubStream1",
+ ElementModes.WRITE | ElementModes.NOCREATE );
+ XStream xSubStream2 = m_aTestHelper.OpenStream( xSubSubStorage,
+ "SubStream2",
+ ElementModes.READ | ElementModes.NOCREATE );
+ if ( xSubStream1 == null || xSubStream2 == null )
+ return false;
+
+ // it should be possible to have more then one copy of stream for reading
+ XStream xSubStream2clone = m_aTestHelper.OpenStream( xSubSubStorage,
+ "SubStream2",
+ ElementModes.READ | ElementModes.NOCREATE );
+ if ( xSubStream2 == null )
+ return false;
+
+
+ // so now the first stream can not be open neither for reading nor for writing
+ if ( !m_aTestHelper.cantOpenStream( xSubSubStorage, "SubStream1", ElementModes.WRITE )
+ || !m_aTestHelper.cantOpenStream( xSubSubStorage, "SubStream1", ElementModes.READ ) )
+ return false;
+
+ // the second stream can not be open for writing
+ if ( !m_aTestHelper.cantOpenStream( xSubSubStorage, "SubStream2", ElementModes.WRITE ) )
+ return false;
+
+
+ // dispose xTestSubStorage, all the subtree must be disposed
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // check that subtree was disposed correctly
+ try
+ {
+ xSubSubStorage.isStreamElement( "SubStream1" );
+ m_aTestHelper.Error( "Substorage was not disposed!" );
+ return false;
+ }
+ catch ( com.sun.star.lang.DisposedException de )
+ {}
+ catch ( Exception e )
+ {
+ m_aTestHelper.Error( "Wrong exception is thrown by disposed storage: " + e );
+ return false;
+ }
+
+ try
+ {
+ xSubStream1.getInputStream();
+ m_aTestHelper.Error( "Writeable substream was not disposed!" );
+ return false;
+ }
+ catch ( com.sun.star.lang.DisposedException de )
+ {}
+ catch ( Exception e )
+ {
+ m_aTestHelper.Error( "Wrong exception is thrown by disposed stream: " + e );
+ return false;
+ }
+
+ try
+ {
+ xSubStream2.getInputStream();
+ m_aTestHelper.Error( "Readonly substream was not disposed!" );
+ return false;
+ }
+ catch ( com.sun.star.lang.DisposedException de )
+ {}
+ catch ( Exception e )
+ {
+ m_aTestHelper.Error( "Wrong exception is thrown by disposed stream: " + e );
+ return false;
+ }
+
+
+ // dispose root storage
+ if ( !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+
+ // ================================================
+ // now check all the written and copied information
+ // ================================================
+
+ XStorage xResultStorage = m_aTestHelper.createStorageFromURL( m_xStorageFactory,
+ sTempFileURL,
+ ElementModes.READ );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage,
+ true,
+ ElementModes.READ,
+ aRelations2 ) )
+ return false;
+
+ // open existing substorage
+ XStorage xResSubStorage = m_aTestHelper.openSubStorage( xResultStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xResSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage 'SubSubStorage'!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResSubStorage,
+ false,
+ ElementModes.READ,
+ aRelations2 ) )
+ return false;
+
+ // open existing substorage
+ XStorage xResSubSubStorage = m_aTestHelper.openSubStorage( xResSubStorage,
+ "SubSubStorage1",
+ ElementModes.READ );
+ if ( xResSubSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage 'SubSubStorage'!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResSubSubStorage,
+ false,
+ ElementModes.READ,
+ aRelations2 ) )
+ return false;
+
+ // check substreams
+ if ( !m_aTestHelper.checkStream( xResSubSubStorage,
+ "SubStream1",
+ "MediaType1",
+ pBytes1,
+ aRelations1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResSubSubStorage,
+ "SubStream2",
+ "MediaType2",
+ pBytes2,
+ aRelations2 ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/ofopxmlstorages/Test06.java b/package/qa/ofopxmlstorages/Test06.java
new file mode 100644
index 000000000000..61969db88e12
--- /dev/null
+++ b/package/qa/ofopxmlstorages/Test06.java
@@ -0,0 +1,277 @@
+package complex.ofopxmlstorages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.container.NoSuchElementException;
+import com.sun.star.container.ElementExistException;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.ofopxmlstorages.TestHelper;
+import complex.ofopxmlstorages.StorageTest;
+
+public class Test06 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test06( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test06: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ XStorage xTempStorage = m_aTestHelper.createTempStorage( m_xMSF, m_xStorageFactory );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ try
+ {
+ xTempStorage.copyToStorage( null );
+ m_aTestHelper.Error( "The method must throw an exception because of illegal parameter!" );
+ return false;
+ }
+ catch( com.sun.star.lang.IllegalArgumentException iae )
+ {}
+ catch( com.sun.star.uno.Exception ue )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion because of illegal parameter : " + e );
+ return false;
+ }
+
+ // open new substorages
+ XStorage xTempSubStorage1 = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ XStorage xTempSubStorage2 = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage2",
+ ElementModes.WRITE );
+ if ( xTempSubStorage1 == null || xTempSubStorage2 == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // in case stream is open for reading it must exist
+ try
+ {
+ xTempSubStorage1.openStreamElement( "NonExistingStream", ElementModes.READ );
+ m_aTestHelper.Error( "The method must throw an exception in case of try to open nonexistent stream for reading!" );
+ return false;
+ }
+ catch( com.sun.star.uno.Exception ue )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case of try to open nonexistent stream for reading : " + e );
+ return false;
+ }
+
+ // in case a storage is open for reading it must exist
+ try
+ {
+ xTempSubStorage1.openStreamElement( "NonExistingStorage", ElementModes.READ );
+ m_aTestHelper.Error( "The method must throw an exception in case of try to open nonexistent storage for reading!" );
+ return false;
+ }
+ catch( com.sun.star.uno.Exception ue )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case of try to open nonexistent storage for reading : " + e );
+ return false;
+ }
+
+ // in case of removing nonexistent element an exception must be thrown
+ try
+ {
+ xTempSubStorage1.removeElement( "NonExistingElement" );
+ m_aTestHelper.Error( "An exception must be thrown in case of removing nonexistent element!" );
+ return false;
+ }
+ catch( com.sun.star.container.NoSuchElementException ne )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case of try to remove nonexistent element : " + e );
+ return false;
+ }
+
+ // in case of renaming of nonexistent element an exception must be thrown
+ try
+ {
+ xTempSubStorage1.renameElement( "NonExistingElement", "NewName" );
+ m_aTestHelper.Error( "An exception must be thrown in case of renaming nonexistent element!" );
+ return false;
+ }
+ catch( com.sun.star.container.NoSuchElementException ne )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case of try to rename nonexistent element : " + e );
+ return false;
+ }
+
+ // in case of renaming to a name of existent element an exception must be thrown
+ try
+ {
+ xTempStorage.renameElement( "SubStorage1", "SubStorage2" );
+ m_aTestHelper.Error( "An exception must be thrown in case of renaming to the name of existent element!" );
+ return false;
+ }
+ catch( com.sun.star.container.ElementExistException ee )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case of try to rename to the name of existent element : " + e );
+ return false;
+ }
+
+ // in case of copying target storage must be provided
+ try
+ {
+ xTempStorage.copyElementTo( "SubStorage1", null, "SubStorage1" );
+ m_aTestHelper.Error( "An exception must be thrown in case empty reference is provided as target for copying!" );
+ return false;
+ }
+ catch( com.sun.star.lang.IllegalArgumentException iae )
+ {}
+ catch( com.sun.star.uno.Exception ue )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case empty reference is provieded as target for copying : " + e );
+ return false;
+ }
+
+ // in case of moving target storage must be provided
+ try
+ {
+ xTempStorage.moveElementTo( "SubStorage1", null, "SubStorage1" );
+ m_aTestHelper.Error( "An exception must be thrown in case empty reference is provided as target for moving!" );
+ return false;
+ }
+ catch( com.sun.star.lang.IllegalArgumentException iae )
+ {}
+ catch( com.sun.star.uno.Exception ue )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case empty reference is provieded as target for moving : " + e );
+ return false;
+ }
+
+
+ // prepare target for further testings
+
+ // create new temporary storage based on arbitrary medium
+ XStorage xTargetStorage = m_aTestHelper.createTempStorage( m_xMSF, m_xStorageFactory );
+ if ( xTargetStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTargetSubStorage = m_aTestHelper.openSubStorage( xTargetStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTargetSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // in case of copying of nonexistent element an exception must be thrown
+ try
+ {
+ xTempStorage.copyElementTo( "Nonexistent element", xTargetStorage, "Target" );
+ m_aTestHelper.Error( "An exception must be thrown in case of copying of nonexisting element!" );
+ return false;
+ }
+ catch( com.sun.star.container.NoSuchElementException ne )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case of copying of nonexistent element: " + e );
+ return false;
+ }
+
+ // in case of moving of nonexistent element an exception must be thrown
+ try
+ {
+ xTempStorage.moveElementTo( "Nonexistent element", xTargetStorage, "Target" );
+ m_aTestHelper.Error( "An exception must be thrown in case of moving of nonexisting element!" );
+ return false;
+ }
+ catch( com.sun.star.container.NoSuchElementException ne )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case of moving of nonexistent element: " + e );
+ return false;
+ }
+
+ // in case target for copying already exists an exception must be thrown
+ try
+ {
+ xTempStorage.copyElementTo( "SubStorage1", xTargetStorage, "SubStorage1" );
+ m_aTestHelper.Error( "An exception must be thrown in case target for copying already exists!" );
+ return false;
+ }
+ catch( com.sun.star.container.ElementExistException ee )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case target for copying already exists: " + e );
+ return false;
+ }
+
+ // in case target for moving already exists an exception must be thrown
+ try
+ {
+ xTempStorage.moveElementTo( "SubStorage1", xTargetStorage, "SubStorage1" );
+ m_aTestHelper.Error( "An exception must be thrown in case target for moving already exists!" );
+ return false;
+ }
+ catch( com.sun.star.container.ElementExistException ee )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case target for moving already exists: " + e );
+ return false;
+ }
+
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/ofopxmlstorages/Test07.java b/package/qa/ofopxmlstorages/Test07.java
new file mode 100644
index 000000000000..bcd85d5d01c0
--- /dev/null
+++ b/package/qa/ofopxmlstorages/Test07.java
@@ -0,0 +1,258 @@
+package complex.ofopxmlstorages;
+
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.container.XNameAccess;
+import com.sun.star.io.XStream;
+
+import com.sun.star.embed.*;
+import com.sun.star.beans.StringPair;
+
+import share.LogWriter;
+import complex.ofopxmlstorages.TestHelper;
+import complex.ofopxmlstorages.StorageTest;
+
+public class Test07 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test07( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test07: " );
+ }
+
+ public boolean test()
+ {
+ StringPair[][] aRelations1 =
+ { { new StringPair( "Id", "Num1" ) },
+ { new StringPair( "Target", "TargetURLValue1" ), new StringPair( "Id", "Num6" ) },
+ { new StringPair( "Target", "" ), new StringPair( "Id", "Num7" ) },
+ { new StringPair( "Id", "Num2" ), new StringPair( "TargetMode", "Internal1" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value 1" ) },
+ { new StringPair( "Id", "Num3" ), new StringPair( "TargetMode", "Internal1" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value 1" ) },
+ { new StringPair( "Id", "Num4" ), new StringPair( "TargetMode", "Internal1" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value 1" ) },
+ { new StringPair( "Id", "Num5" ), new StringPair( "TargetMode", "" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value1" ) }
+ };
+
+ StringPair[][] aRelations2 =
+ { { new StringPair( "Id", "Num1" ) },
+ { new StringPair( "Target", "TargetURLValue2" ), new StringPair( "Id", "Num6" ) },
+ { new StringPair( "Target", "" ), new StringPair( "Id", "Num7" ) },
+ { new StringPair( "Id", "Num2" ), new StringPair( "TargetMode", "Internal2" ), new StringPair( "Type", "unknown2" ), new StringPair( "Target", "URL value 2" ) },
+ { new StringPair( "Id", "Num3" ), new StringPair( "TargetMode", "Internal2" ), new StringPair( "Type", "unknown2" ), new StringPair( "Target", "URL value 2" ) },
+ { new StringPair( "Id", "Num4" ), new StringPair( "TargetMode", "Internal2" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) },
+ { new StringPair( "Id", "Num5" ), new StringPair( "TargetMode", "" ), new StringPair( "Type", "unknown" ), new StringPair( "Target", "URL value" ) }
+ };
+
+ try
+ {
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ XStorage xTempStorage = m_aTestHelper.createTempStorage( m_xMSF, m_xStorageFactory );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempStorage,
+ "SubStream1",
+ "MediaType1",
+ true,
+ pBytes1,
+ aRelations1 ) )
+ return false;
+
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage,
+ "SubStream2",
+ "MediaType2",
+ true,
+ pBytes2,
+ aRelations2 ) )
+ return false;
+
+ // set Relations for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ true,
+ ElementModes.WRITE,
+ aRelations2 ) )
+ return false;
+
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ false,
+ ElementModes.WRITE,
+ aRelations2 ) )
+ return false;
+
+ // ==============================
+ // check cloning at current state
+ // ==============================
+
+ // the new storage still was not commited so the clone must be empty
+ XStorage xClonedSubStorage = m_aTestHelper.cloneSubStorage( m_xMSF, m_xStorageFactory, xTempStorage, "SubStorage1" );
+
+ if ( xClonedSubStorage == null )
+ {
+ m_aTestHelper.Error( "The result of clone is empty!" );
+ return false;
+ }
+
+ XNameAccess xClonedNameAccess = (XNameAccess) UnoRuntime.queryInterface( XNameAccess.class, xClonedSubStorage );
+ if ( xClonedNameAccess == null )
+ {
+ m_aTestHelper.Error( "XNameAccess is not implemented by the clone!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xClonedSubStorage,
+ true,
+ ElementModes.WRITE,
+ new StringPair[0][0] ) )
+ return false;
+
+ if ( xClonedNameAccess.hasElements() )
+ {
+ m_aTestHelper.Error( "The new substorage still was not commited so it must be empty!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.disposeStorage( xClonedSubStorage ) )
+ return false;
+
+ xClonedSubStorage = null;
+ xClonedNameAccess = null;
+
+ // the new stream was opened, written and closed, that means flashed
+ // so the clone must contain all the information
+ XStream xClonedSubStream = m_aTestHelper.cloneSubStream( xTempStorage, "SubStream1" );
+ if ( !m_aTestHelper.InternalCheckStream( xClonedSubStream,
+ "SubStream1",
+ "MediaType1",
+ pBytes1,
+ aRelations1 ) )
+ return false;
+
+ if ( !m_aTestHelper.disposeStream( xClonedSubStream, "SubStream1" ) )
+ return false;
+
+ // ==============================
+ // commit substorage and check cloning
+ // ==============================
+
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ xClonedSubStorage = m_aTestHelper.cloneSubStorage( m_xMSF, m_xStorageFactory, xTempStorage, "SubStorage1" );
+ if ( xClonedSubStorage == null )
+ {
+ m_aTestHelper.Error( "The result of clone is empty!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xClonedSubStorage,
+ true,
+ ElementModes.WRITE,
+ aRelations2 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xClonedSubStorage,
+ "SubStream2",
+ "MediaType2",
+ pBytes2,
+ aRelations2 ) )
+ return false;
+
+ XStorage xCloneOfRoot = m_aTestHelper.cloneStorage( m_xMSF, m_xStorageFactory, xTempStorage );
+ if ( xCloneOfRoot == null )
+ {
+ m_aTestHelper.Error( "The result of root clone is empty!" );
+ return false;
+ }
+
+ XNameAccess xCloneOfRootNA = (XNameAccess) UnoRuntime.queryInterface( XNameAccess.class, xCloneOfRoot );
+ if ( xCloneOfRootNA == null )
+ {
+ m_aTestHelper.Error( "XNameAccess is not implemented by the root clone!" );
+ return false;
+ }
+
+ if ( xCloneOfRootNA.hasElements() )
+ {
+ m_aTestHelper.Error( "The root storage still was not commited so it's clone must be empty!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.disposeStorage( xCloneOfRoot ) )
+ return false;
+
+ xCloneOfRoot = null;
+
+ // ==============================
+ // commit root storage and check cloning
+ // ==============================
+
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ xCloneOfRoot = m_aTestHelper.cloneStorage( m_xMSF, m_xStorageFactory, xTempStorage );
+ if ( xCloneOfRoot == null )
+ {
+ m_aTestHelper.Error( "The result of root clone is empty!" );
+ return false;
+ }
+
+ XStorage xSubStorageOfClone = xCloneOfRoot.openStorageElement( "SubStorage1", ElementModes.READ );
+ if ( xSubStorageOfClone == null )
+ {
+ m_aTestHelper.Error( "The result of root clone is wrong!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xSubStorageOfClone,
+ false,
+ ElementModes.READ,
+ aRelations2 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xSubStorageOfClone,
+ "SubStream2",
+ "MediaType2",
+ pBytes2,
+ aRelations2 ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/ofopxmlstorages/Test08.java b/package/qa/ofopxmlstorages/Test08.java
new file mode 100644
index 000000000000..eaed60d4d8e3
--- /dev/null
+++ b/package/qa/ofopxmlstorages/Test08.java
@@ -0,0 +1,261 @@
+package complex.ofopxmlstorages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+import com.sun.star.beans.StringPair;
+
+import share.LogWriter;
+import complex.ofopxmlstorages.TestHelper;
+import complex.ofopxmlstorages.StorageTest;
+
+public class Test08 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test08( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test08: " );
+ }
+
+ public boolean test()
+ {
+ StringPair[][] aRelations1 =
+ { { new StringPair( "Id", "Num1" ) },
+ { new StringPair( "Target", "TargetURLValue1" ), new StringPair( "Id", "Num6" ) },
+ { new StringPair( "Target", "" ), new StringPair( "Id", "Num7" ) },
+ { new StringPair( "Id", "Num2" ), new StringPair( "TargetMode", "Internal1" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value 1" ) },
+ { new StringPair( "Id", "Num3" ), new StringPair( "TargetMode", "Internal1" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value 1" ) },
+ { new StringPair( "Id", "Num4" ), new StringPair( "TargetMode", "Internal1" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value 1" ) },
+ { new StringPair( "Id", "Num5" ), new StringPair( "TargetMode", "" ), new StringPair( "Type", "unknown1" ), new StringPair( "Target", "URL value1" ) }
+ };
+
+ try
+ {
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ XStorage xTempStorage = m_aTestHelper.createStorageFromStream( m_xStorageFactory,
+ xTempFileStream,
+ ElementModes.WRITE );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage,
+ "SubStream1",
+ "MediaType1",
+ true,
+ pBytes1,
+ aRelations1 ) )
+ return false;
+
+ // set Relations for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ true,
+ ElementModes.WRITE,
+ aRelations1 ) )
+ return false;
+
+ // set Relations for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ false,
+ ElementModes.WRITE,
+ aRelations1 ) )
+ return false;
+
+ // commit substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // ================================================
+ // check substorage
+ // ================================================
+
+ if ( !checkSubStorages( xTempStorage, pBytes1, aRelations1 ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // now check all the written information with readwrite access
+ // ================================================
+
+ XStorage xResWriteStorage = m_aTestHelper.createStorageFromStream( m_xStorageFactory,
+ xTempFileStream,
+ ElementModes.WRITE );
+ if ( xResWriteStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open storage based on input stream!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResWriteStorage,
+ true,
+ ElementModes.WRITE,
+ aRelations1 ) )
+ return false;
+
+ if( !checkSubStorages( xResWriteStorage, pBytes1, aRelations1 ) )
+ return false;
+
+ // try to open for writing after opening for reading
+ XStorage xResWSubStorage = m_aTestHelper.openSubStorage( xResWriteStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xResWSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open substorage for writing after it was opened for reading!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResWSubStorage,
+ false,
+ ElementModes.WRITE,
+ aRelations1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResWSubStorage,
+ "SubStream1",
+ "MediaType1",
+ pBytes1,
+ aRelations1 ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xResWriteStorage ) )
+ return false;
+
+
+ // ================================================
+ // now check all the written information with readonly access
+ // ================================================
+
+ // close the output part of the temporary stream
+ // the output part must present since we already wrote to the stream
+ if ( !m_aTestHelper.closeOutput( xTempFileStream ) )
+ return false;
+
+ XInputStream xTempInStream = m_aTestHelper.getInputStream( xTempFileStream );
+ if ( xTempInStream == null )
+ return false;
+
+ // open input stream
+ // since no mode is provided the result storage must be opened readonly
+ XStorage xResultStorage = m_aTestHelper.createStorageFromInputStream( m_xStorageFactory,
+ xTempInStream );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open storage based on input stream!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage,
+ true,
+ ElementModes.READ,
+ aRelations1 ) )
+ return false;
+
+ if( !checkSubStorages( xResultStorage, pBytes1, aRelations1 ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+ private boolean checkSubStorages( XStorage xStorage, byte[] pBytes1, StringPair[][] aRelations )
+ {
+ XStorage xReadSubStorage1 = m_aTestHelper.openSubStorage( xStorage,
+ "SubStorage1",
+ ElementModes.READ );
+
+ XStorage xReadSubStorage2 = m_aTestHelper.openSubStorage( xStorage,
+ "SubStorage1",
+ ElementModes.READ );
+
+ if ( xReadSubStorage1 == null || xReadSubStorage2 == null )
+ {
+ m_aTestHelper.Error( "Can't open substorage for reading!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xReadSubStorage1,
+ false,
+ ElementModes.READ,
+ aRelations ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xReadSubStorage2,
+ false,
+ ElementModes.READ,
+ aRelations ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xReadSubStorage1,
+ "SubStream1",
+ "MediaType1",
+ pBytes1,
+ aRelations ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xReadSubStorage2,
+ "SubStream1",
+ "MediaType1",
+ pBytes1,
+ aRelations ) )
+ return false;
+
+ if ( !m_aTestHelper.disposeStorage( xReadSubStorage1 ) )
+ return false;
+
+ if ( !m_aTestHelper.disposeStorage( xReadSubStorage2 ) )
+ return false;
+
+ return true;
+ }
+}
+
diff --git a/package/qa/ofopxmlstorages/TestHelper.java b/package/qa/ofopxmlstorages/TestHelper.java
new file mode 100644
index 000000000000..6b153fd2b960
--- /dev/null
+++ b/package/qa/ofopxmlstorages/TestHelper.java
@@ -0,0 +1,1098 @@
+package complex.ofopxmlstorages;
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.uno.AnyConverter;
+
+import com.sun.star.lang.*;
+import com.sun.star.embed.*;
+import com.sun.star.packages.*;
+import com.sun.star.io.*;
+import com.sun.star.beans.*;
+
+import share.LogWriter;
+
+public class TestHelper {
+
+ LogWriter m_aLogWriter;
+ String m_sTestPrefix;
+
+ public TestHelper( LogWriter aLogWriter, String sTestPrefix )
+ {
+ m_aLogWriter = aLogWriter;
+ m_sTestPrefix = sTestPrefix;
+ }
+
+ public boolean WriteBytesToStream( XStream xStream,
+ String sStreamName,
+ String sMediaType,
+ boolean bCompressed,
+ byte[] pBytes,
+ StringPair[][] aRelations )
+ {
+ // get output stream of substream
+ XOutputStream xOutput = xStream.getOutputStream();
+ if ( xOutput == null )
+ {
+ Error( "Can't get XOutputStream implementation from substream '" + sStreamName + "'!" );
+ return false;
+ }
+
+ // get XTrucate implementation from output stream
+ XTruncate xTruncate = (XTruncate) UnoRuntime.queryInterface( XTruncate.class, xOutput );
+ if ( xTruncate == null )
+ {
+ Error( "Can't get XTruncate implementation from substream '" + sStreamName + "'!" );
+ return false;
+ }
+
+ // write requested byte sequence
+ try
+ {
+ xTruncate.truncate();
+ xOutput.writeBytes( pBytes );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't write to stream '" + sStreamName + "', exception: " + e );
+ return false;
+ }
+
+ // get access to the XPropertySet interface
+ XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStream );
+ if ( xPropSet == null )
+ {
+ Error( "Can't get XPropertySet implementation from substream '" + sStreamName + "'!" );
+ return false;
+ }
+
+ // set properties to the stream
+ try
+ {
+ xPropSet.setPropertyValue( "MediaType", sMediaType );
+ xPropSet.setPropertyValue( "Compressed", new Boolean( bCompressed ) );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't set properties to substream '" + sStreamName + "', exception: " + e );
+ return false;
+ }
+
+ // check size property of the stream
+ try
+ {
+ int nSize = AnyConverter.toInt( xPropSet.getPropertyValue( "Size" ) );
+ if ( nSize != pBytes.length )
+ {
+ Error( "The 'Size' property of substream '" + sStreamName + "' contains wrong value!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't get 'Size' property from substream '" + sStreamName + "', exception: " + e );
+ return false;
+ }
+
+ // get access to the relationship information
+ XRelationshipAccess xRelAccess = (XRelationshipAccess) UnoRuntime.queryInterface( XRelationshipAccess.class, xStream );
+ if ( xRelAccess == null )
+ {
+ Error( "Can't get XRelationshipAccess implementation from substream '" + sStreamName + "'!" );
+ return false;
+ }
+
+ // set the relationship information
+ try
+ {
+ xRelAccess.insertRelationships( aRelations, false );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't set relationships to substream '" + sStreamName + "', exception: " + e );
+ return false;
+ }
+
+ // free the stream resources, garbage collector may remove the object too late
+ if ( !disposeStream( xStream, sStreamName ) )
+ return false;
+
+ return true;
+ }
+
+ public boolean WriteBytesToSubstream( XStorage xStorage,
+ String sStreamName,
+ String sMediaType,
+ boolean bCompressed,
+ byte[] pBytes,
+ StringPair[][] aRelations )
+ {
+ // open substream element
+ XStream xSubStream = null;
+ try
+ {
+ Object oSubStream = xStorage.openStreamElement( sStreamName, ElementModes.WRITE );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ {
+ Error( "Can't create substream '" + sStreamName + "'!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't create substream '" + sStreamName + "', exception : " + e + "!" );
+ return false;
+ }
+
+ return WriteBytesToStream( xSubStream, sStreamName, sMediaType, bCompressed, pBytes, aRelations );
+ }
+
+ public boolean setStorageTypeAndCheckProps( XStorage xStorage,
+ boolean bIsRoot,
+ int nMode,
+ StringPair[][] aRelations )
+ {
+ boolean bOk = false;
+
+ // get access to the XPropertySet interface
+ XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStorage );
+ if ( xPropSet != null )
+ {
+ try
+ {
+ // get "IsRoot" and "OpenMode" properties and control there values
+ boolean bPropIsRoot = AnyConverter.toBoolean( xPropSet.getPropertyValue( "IsRoot" ) );
+ int nPropMode = AnyConverter.toInt( xPropSet.getPropertyValue( "OpenMode" ) );
+
+ bOk = true;
+ if ( bPropIsRoot != bIsRoot )
+ {
+ Error( "'IsRoot' property contains wrong value!" );
+ bOk = false;
+ }
+
+ if ( ( bIsRoot
+ && ( nPropMode | ElementModes.READ ) != ( nMode | ElementModes.READ ) )
+ || ( !bIsRoot && ( nPropMode & nMode ) != nMode ) )
+ {
+ Error( "'OpenMode' property contains wrong value, expected " + nMode + ", in reality " + nPropMode + "!" );
+ bOk = false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't control properties of substorage, exception: " + e );
+ }
+ }
+ else
+ {
+ Error( "Can't get XPropertySet implementation from storage!" );
+ }
+
+ // get access to the relationship information
+ XRelationshipAccess xRelAccess = (XRelationshipAccess) UnoRuntime.queryInterface( XRelationshipAccess.class, xStorage );
+
+ if ( xRelAccess == null )
+ {
+ Error( "Can't get XRelationshipAccess implementation from the storage!" );
+ return false;
+ }
+
+ // set the relationship information
+ try
+ {
+ xRelAccess.insertRelationships( aRelations, false );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't set relationships to the storage, exception: " + e );
+ return false;
+ }
+
+
+ return bOk;
+ }
+
+ public boolean checkRelations( StringPair[][] aStorRels, StringPair[][] aTestRels )
+ {
+ // Message( "StorageRels:" );
+ // PrintRelations( aStorRels );
+ // Message( "TestRels:" );
+ // PrintRelations( aTestRels );
+
+ if ( aStorRels.length != aTestRels.length )
+ {
+ Error( "The provided relations sequence has different size than the storage's one!" );
+ return false;
+ }
+
+ for ( int nStorInd = 0; nStorInd < aStorRels.length; nStorInd++ )
+ {
+ int nStorIDInd = -1;
+ for ( int nStorTagInd = 0; nStorTagInd < aStorRels[nStorInd].length; nStorTagInd++ )
+ {
+ if ( aStorRels[nStorInd][nStorTagInd].First.equals( "Id" ) )
+ {
+ nStorIDInd = nStorTagInd;
+ break;
+ }
+ }
+
+ if ( nStorIDInd == -1 )
+ {
+ Error( "One of the storage relations entries has no ID!" );
+ return false;
+ }
+
+ for ( int nInd = 0; nInd < aTestRels.length; nInd++ )
+ {
+ int nIDInd = -1;
+ for ( int nTagInd = 0; nTagInd < aTestRels[nInd].length; nTagInd++ )
+ {
+ if ( aTestRels[nInd][nTagInd].First.equals( "Id" ) )
+ {
+ nIDInd = nTagInd;
+ break;
+ }
+ }
+
+ if ( nIDInd == -1 )
+ {
+ Error( "One of the test hardcoded entries has no ID, num = " + nInd + ", length = " + aTestRels[nInd].length + ", global length = " + aTestRels.length + "!" );
+ return false;
+ }
+
+ if ( aStorRels[nStorInd][nStorIDInd].Second.equals( aTestRels[nInd][nIDInd].Second ) )
+ {
+ boolean[] pRelCheckMark = new boolean[ aTestRels[nInd].length ];
+ for ( int nCheckInd = 0; nCheckInd < pRelCheckMark.length; nCheckInd++ )
+ {
+ pRelCheckMark[nCheckInd] = false;
+ }
+
+ for ( int nStorTagInd = 0; nStorTagInd < aStorRels[nStorInd].length; nStorTagInd++ )
+ {
+ boolean bFound = false;
+ for ( int nTagInd = 0; nTagInd < aTestRels[nInd].length; nTagInd++ )
+ {
+ if ( aTestRels[nInd][nTagInd].First.equals( aStorRels[nStorInd][nStorTagInd].First ) )
+ {
+ if ( !aTestRels[nInd][nTagInd].Second.equals( aStorRels[nStorInd][nStorTagInd].Second ) )
+ {
+ Error( "Test rel. num. " + nInd + " has different tag \"" + aTestRels[nInd][nTagInd].First + "\" value!" );
+ return false;
+ }
+
+ bFound = true;
+ pRelCheckMark[nTagInd] = true;
+ break;
+ }
+ }
+
+ if ( !bFound )
+ {
+ Error( "Stor rel. num. " + nStorInd + " has unexpected tag \"" + aStorRels[nStorInd][nStorTagInd].First + "\", ID = \"" + aStorRels[nStorInd][nStorIDInd].Second + "\"!" );
+ return false;
+ }
+ }
+
+ for ( int nCheckInd = 0; nCheckInd < pRelCheckMark.length; nCheckInd++ )
+ {
+ if ( !pRelCheckMark[nCheckInd] && !aTestRels[nInd][nCheckInd].Second.equals( "" ) )
+ {
+ Error( "Test rel. num. " + nInd + " has unexpected tag \"" + aTestRels[nInd][nCheckInd].First + "\" with nonempty value!" );
+ return false;
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ public boolean checkStorageProperties( XStorage xStorage,
+ boolean bIsRoot,
+ int nMode,
+ StringPair[][] aRelations )
+ {
+ boolean bOk = false;
+
+ // get access to the XPropertySet interface
+ XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStorage );
+ if ( xPropSet != null )
+ {
+ try
+ {
+ // get "IsRoot" and "OpenMode" properties and control there values
+ boolean bPropIsRoot = AnyConverter.toBoolean( xPropSet.getPropertyValue( "IsRoot" ) );
+ int nPropMode = AnyConverter.toInt( xPropSet.getPropertyValue( "OpenMode" ) );
+
+ bOk = true;
+ if ( bPropIsRoot != bIsRoot )
+ {
+ Error( "'IsRoot' property contains wrong value!" );
+ bOk = false;
+ }
+
+ if ( ( bIsRoot
+ && ( nPropMode | ElementModes.READ ) != ( nMode | ElementModes.READ ) )
+ || ( !bIsRoot && ( nPropMode & nMode ) != nMode ) )
+ {
+ Error( "'OpenMode' property contains wrong value, expected " + nMode + ", in reality " + nPropMode + "!" );
+ bOk = false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't get properties of substorage, exception: " + e );
+ }
+ }
+ else
+ {
+ Error( "Can't get XPropertySet implementation from storage!" );
+ }
+
+ // get access to the relationship information
+ XRelationshipAccess xRelAccess = (XRelationshipAccess) UnoRuntime.queryInterface( XRelationshipAccess.class, xStorage );
+
+ if ( xRelAccess == null )
+ {
+ Error( "Can't get XRelationshipAccess implementation from the checked storage!" );
+ return false;
+ }
+
+ // get the relationship information
+ StringPair[][] aStorRels;
+ try
+ {
+ aStorRels = xRelAccess.getAllRelationships();
+ }
+ catch( Exception e )
+ {
+ Error( "Can't get relationships of the checked storage, exception: " + e );
+ return false;
+ }
+
+ if ( !checkRelations( aStorRels, aRelations ) )
+ {
+ Error( "StorageRelationsChecking has failed!" );
+ return false;
+ }
+
+ return bOk;
+ }
+
+ public boolean InternalCheckStream( XStream xStream,
+ String sName,
+ String sMediaType,
+ byte[] pBytes,
+ StringPair[][] aRelations )
+ {
+ // get input stream of substream
+ XInputStream xInput = xStream.getInputStream();
+ if ( xInput == null )
+ {
+ Error( "Can't get XInputStream implementation from substream '" + sName + "'!" );
+ return false;
+ }
+
+ byte pContents[][] = new byte[1][]; // ???
+
+ // read contents
+ try
+ {
+ xInput.readBytes( pContents, pBytes.length + 1 );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't read from stream '" + sName + "', exception: " + e );
+ return false;
+ }
+
+ // check size of stream data
+ if ( pContents.length == 0 )
+ {
+ Error( "SubStream '" + sName + "' reading produced disaster!" );
+ return false;
+ }
+
+ if ( pBytes.length != pContents[0].length )
+ {
+ Error( "SubStream '" + sName + "' contains wrong amount of data! (" + pContents[0].length + "/" + pBytes.length + ")" );
+ return false;
+ }
+
+ // check stream data
+ for ( int ind = 0; ind < pBytes.length; ind++ )
+ {
+ if ( pBytes[ind] != pContents[0][ind] )
+ {
+ Error( "SubStream '" + sName + "' contains wrong data! ( byte num. "
+ + ind + " should be" + pBytes[ind] + " but it is " + pContents[0][ind] + ")" );
+ return false;
+ }
+ }
+
+ // check properties
+ boolean bOk = false;
+
+ // get access to the XPropertySet interface
+ XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStream );
+ if ( xPropSet != null )
+ {
+ try
+ {
+ // get "MediaType" and "Size" properties and control there values
+ String sPropMediaType = AnyConverter.toString( xPropSet.getPropertyValue( "MediaType" ) );
+ int nPropSize = AnyConverter.toInt( xPropSet.getPropertyValue( "Size" ) );
+
+ bOk = true;
+ if ( !sPropMediaType.equals( sMediaType ) )
+ {
+ Error( "'MediaType' property contains wrong value for stream '" + sName + "',\nexpected: '"
+ + sMediaType + "', set: '" + sPropMediaType + "'!" );
+ bOk = false;
+ }
+
+ if ( nPropSize != pBytes.length )
+ {
+ Error( "'Size' property contains wrong value for stream'" + sName + "'!" );
+ bOk = false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't get properties of substream '" + sName + "', exception: " + e );
+ }
+ }
+ else
+ {
+ Error( "Can't get XPropertySet implementation from stream '" + sName + "'!" );
+ }
+
+
+ // get access to the relationship information
+ XRelationshipAccess xRelAccess = (XRelationshipAccess) UnoRuntime.queryInterface( XRelationshipAccess.class, xStream );
+
+ if ( xRelAccess == null )
+ {
+ Error( "Can't get XRelationshipAccess implementation from the stream\"" + sName + "\"!" );
+ return false;
+ }
+
+ // get the relationship information
+ StringPair[][] aStorRels;
+ try
+ {
+ aStorRels = xRelAccess.getAllRelationships();
+ }
+ catch( Exception e )
+ {
+ Error( "Can't get relationships of the substream '" + sName + "', exception: " + e );
+ return false;
+ }
+
+ if ( !checkRelations( aStorRels, aRelations ) )
+ {
+ Error( "Stream '" + sName + "' RelationsChecking has failed!" );
+ return false;
+ }
+
+ return bOk;
+ }
+
+ public boolean checkStream( XStorage xParentStorage,
+ String sName,
+ String sMediaType,
+ byte[] pBytes,
+ StringPair[][] aRelations )
+ {
+ // open substream element first
+ XStream xSubStream = null;
+ try
+ {
+ Object oSubStream = xParentStorage.openStreamElement( sName, ElementModes.READ );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ {
+ Error( "Can't open substream '" + sName + "'!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't open substream '" + sName + "', exception : " + e + "!" );
+ return false;
+ }
+
+ boolean bResult = InternalCheckStream( xSubStream, sName, sMediaType, pBytes, aRelations );
+
+ // free the stream resources, garbage collector may remove the object too late
+ if ( !disposeStream( xSubStream, sName ) )
+ return false;
+
+ return bResult;
+ }
+
+ public boolean copyStorage( XStorage xSourceStorage, XStorage xDestStorage )
+ {
+ // copy xSourceStorage to xDestStorage
+ try
+ {
+ xSourceStorage.copyToStorage( xDestStorage );
+ }
+ catch( Exception e )
+ {
+ Error( "Storage copying failed, exception: " + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean commitStorage( XStorage xStorage )
+ {
+ // XTransactedObject must be supported by storages
+ XTransactedObject xTransact = (XTransactedObject) UnoRuntime.queryInterface( XTransactedObject.class, xStorage );
+ if ( xTransact == null )
+ {
+ Error( "Storage doesn't implement transacted access!" );
+ return false;
+ }
+
+ try
+ {
+ xTransact.commit();
+ }
+ catch( Exception e )
+ {
+ Error( "Storage commit failed, exception:" + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean disposeStream( XStream xStream, String sStreamName )
+ {
+ XComponent xComponent = (XComponent) UnoRuntime.queryInterface( XComponent.class, xStream );
+ if ( xComponent == null )
+ {
+ Error( "Can't get XComponent implementation from substream '" + sStreamName + "'!" );
+ return false;
+ }
+
+ try
+ {
+ xComponent.dispose();
+ }
+ catch( Exception e )
+ {
+ Error( "Substream '" + sStreamName + "' disposing throws exception: " + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean disposeStorage( XStorage xStorage )
+ {
+ // dispose the storage
+ XComponent xComponent = (XComponent) UnoRuntime.queryInterface( XComponent.class, xStorage );
+ if ( xComponent == null )
+ {
+ Error( "Can't retrieve XComponent implementation from storage!" );
+ return false;
+ }
+
+ try
+ {
+ xComponent.dispose();
+ }
+ catch( Exception e )
+ {
+ Error( "Storage disposing failed!" );
+ return false;
+ }
+
+ return true;
+ }
+
+ public XInputStream getInputStream( XStream xStream )
+ {
+ XInputStream xInTemp = null;
+ try
+ {
+ xInTemp = xStream.getInputStream();
+ if ( xInTemp == null )
+ Error( "Can't get the input part of a stream!" );
+ }
+ catch ( Exception e )
+ {
+ Error( "Can't get the input part of a stream, exception :" + e );
+ }
+
+ return xInTemp;
+ }
+
+ public boolean closeOutput( XStream xStream )
+ {
+ XOutputStream xOutTemp = null;
+ try
+ {
+ xOutTemp = xStream.getOutputStream();
+ if ( xOutTemp == null )
+ {
+ Error( "Can't get the output part of a stream!" );
+ return false;
+ }
+ }
+ catch ( Exception e )
+ {
+ Error( "Can't get the output part of a stream, exception :" + e );
+ return false;
+ }
+
+ try
+ {
+ xOutTemp.closeOutput();
+ }
+ catch ( Exception e )
+ {
+ Error( "Can't close output part of a stream, exception :" + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public XStorage openSubStorage( XStorage xStorage, String sName, int nMode )
+ {
+ // open existing substorage
+ try
+ {
+ Object oSubStorage = xStorage.openStorageElement( sName, nMode );
+ XStorage xSubStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oSubStorage );
+ return xSubStorage;
+ }
+ catch( Exception e )
+ {
+ Error( "Can't open substorage '" + sName + "', exception: " + e );
+ }
+
+ return null;
+ }
+
+ public XStream CreateTempFileStream( XMultiServiceFactory xMSF )
+ {
+ // try to get temporary file representation
+ XStream xTempFileStream = null;
+ try
+ {
+ Object oTempFile = xMSF.createInstance( "com.sun.star.io.TempFile" );
+ xTempFileStream = (XStream)UnoRuntime.queryInterface( XStream.class, oTempFile );
+ }
+ catch( Exception e )
+ {}
+
+ if ( xTempFileStream == null )
+ Error( "Can't create temporary file!" );
+
+ return xTempFileStream;
+ }
+
+ public String CreateTempFile( XMultiServiceFactory xMSF )
+ {
+ String sResult = null;
+
+ // try to get temporary file representation
+ XPropertySet xTempFileProps = null;
+ try
+ {
+ Object oTempFile = xMSF.createInstance( "com.sun.star.io.TempFile" );
+ xTempFileProps = (XPropertySet)UnoRuntime.queryInterface( XPropertySet.class, oTempFile );
+ }
+ catch( Exception e )
+ {}
+
+ if ( xTempFileProps != null )
+ {
+ try
+ {
+ xTempFileProps.setPropertyValue( "RemoveFile", new Boolean( false ) );
+ sResult = AnyConverter.toString( xTempFileProps.getPropertyValue( "Uri" ) );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't control TempFile properties, exception: " + e );
+ }
+ }
+ else
+ {
+ Error( "Can't create temporary file representation!" );
+ }
+
+ // close temporary file explicitly
+ try
+ {
+ XStream xStream = (XStream)UnoRuntime.queryInterface( XStream.class, xTempFileProps );
+ if ( xStream != null )
+ {
+ XOutputStream xOut = xStream.getOutputStream();
+ if ( xOut != null )
+ xOut.closeOutput();
+
+ XInputStream xIn = xStream.getInputStream();
+ if ( xIn != null )
+ xIn.closeInput();
+ }
+ else
+ Error( "Can't close TempFile!" );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't close TempFile, exception: " + e );
+ }
+
+ return sResult;
+ }
+
+ public boolean copyElementTo( XStorage xSource, String sName, XStorage xDest )
+ {
+ // copy element with name sName from xSource to xDest
+ try
+ {
+ xSource.copyElementTo( sName, xDest, sName );
+ }
+ catch( Exception e )
+ {
+ Error( "Element copying failed, exception: " + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean copyElementTo( XStorage xSource, String sName, XStorage xDest, String sTargetName )
+ {
+ // copy element with name sName from xSource to xDest
+ try
+ {
+ xSource.copyElementTo( sName, xDest, sTargetName );
+ }
+ catch( Exception e )
+ {
+ Error( "Element copying failed, exception: " + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean moveElementTo( XStorage xSource, String sName, XStorage xDest )
+ {
+ // move element with name sName from xSource to xDest
+ try
+ {
+ xSource.moveElementTo( sName, xDest, sName );
+ }
+ catch( Exception e )
+ {
+ Error( "Element moving failed, exception: " + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean renameElement( XStorage xStorage, String sOldName, String sNewName )
+ {
+ // rename element with name sOldName to sNewName
+ try
+ {
+ xStorage.renameElement( sOldName, sNewName );
+ }
+ catch( Exception e )
+ {
+ Error( "Element renaming failed, exception: " + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean removeElement( XStorage xStorage, String sName )
+ {
+ // remove element with name sName
+ try
+ {
+ xStorage.removeElement( sName );
+ }
+ catch( Exception e )
+ {
+ Error( "Element removing failed, exception: " + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public XStream OpenStream( XStorage xStorage,
+ String sStreamName,
+ int nMode )
+ {
+ // open substream element
+ XStream xSubStream = null;
+ try
+ {
+ Object oSubStream = xStorage.openStreamElement( sStreamName, nMode );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ Error( "Can't create substream '" + sStreamName + "'!" );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't create substream '" + sStreamName + "', exception : " + e + "!" );
+ }
+
+ return xSubStream;
+ }
+
+ public boolean cantOpenStorage( XStorage xStorage, String sName )
+ {
+ // try to open an opened substorage, open call must fail
+ try
+ {
+ Object oDummyStorage = xStorage.openStorageElement( sName, ElementModes.READ );
+ Error( "The trying to reopen opened substorage '" + sName + "' must fail!" );
+ }
+ catch( Exception e )
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean cantOpenStream( XStorage xStorage, String sName, int nMode )
+ {
+ // try to open the substream with specified mode must fail
+ try
+ {
+ Object oDummyStream = xStorage.openStreamElement( sName, nMode );
+ Error( "The trying to open substoream '" + sName + "' must fail!" );
+ }
+ catch( Exception e )
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public XStorage createStorageFromURL(
+ XSingleServiceFactory xFactory,
+ String aURL,
+ int nMode )
+ {
+ XStorage xResult = null;
+
+ try
+ {
+ PropertyValue[] aAddArgs = new PropertyValue[1];
+ aAddArgs[0] = new PropertyValue();
+ aAddArgs[0].Name = "StorageFormat";
+ aAddArgs[0].Value = "OFOPXMLFormat";
+
+ Object pArgs[] = new Object[3];
+ pArgs[0] = (Object) aURL;
+ pArgs[1] = new Integer( nMode );
+ pArgs[2] = (Object) aAddArgs;
+
+ Object oTempStorage = xFactory.createInstanceWithArguments( pArgs );
+ xResult = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't create storage from URL, exception: " + e );
+ return null;
+ }
+
+ if ( xResult == null )
+ Error( "Can't create storage from URL!" );
+
+ return xResult;
+ }
+
+ public XStorage createStorageFromStream(
+ XSingleServiceFactory xFactory,
+ XStream xStream,
+ int nMode )
+ {
+ XStorage xResult = null;
+
+ try
+ {
+ PropertyValue[] aAddArgs = new PropertyValue[1];
+ aAddArgs[0] = new PropertyValue();
+ aAddArgs[0].Name = "StorageFormat";
+ aAddArgs[0].Value = "OFOPXMLFormat";
+
+ Object pArgs[] = new Object[3];
+ pArgs[0] = (Object) xStream;
+ pArgs[1] = new Integer( nMode );
+ pArgs[2] = (Object) aAddArgs;
+
+ Object oTempStorage = xFactory.createInstanceWithArguments( pArgs );
+ xResult = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't create storage from stream, exception: " + e );
+ return null;
+ }
+
+ if ( xResult == null )
+ Error( "Can't create storage from stream!" );
+
+ return xResult;
+ }
+
+ public XStorage createStorageFromInputStream(
+ XSingleServiceFactory xFactory,
+ XInputStream xInStream )
+ {
+ XStorage xResult = null;
+
+ try
+ {
+ PropertyValue[] aAddArgs = new PropertyValue[1];
+ aAddArgs[0] = new PropertyValue();
+ aAddArgs[0].Name = "StorageFormat";
+ aAddArgs[0].Value = "OFOPXMLFormat";
+
+ Object pArgs[] = new Object[3];
+ pArgs[0] = (Object) xInStream;
+ pArgs[1] = new Integer( ElementModes.READ );
+ pArgs[2] = (Object) aAddArgs;
+
+ Object oTempStorage = xFactory.createInstanceWithArguments( pArgs );
+ xResult = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't create storage from input stream, exception: " + e );
+ return null;
+ }
+
+ if ( xResult == null )
+ Error( "Can't create storage from input stream!" );
+
+ return xResult;
+ }
+
+ public XStorage createTempStorage( XMultiServiceFactory xMSF, XSingleServiceFactory xFactory )
+ {
+ // create a temporary storage
+ XStorage xResult = null;
+ XStream xStream = CreateTempFileStream( xMSF );
+ if ( xStream == null )
+ {
+ Error( "Can't create temp file stream!" );
+ return null;
+ }
+
+ try
+ {
+ xResult = createStorageFromStream( xFactory, xStream, ElementModes.WRITE );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't create temp storage, exception: " + e );
+ }
+
+ return xResult;
+ }
+
+ public XStorage cloneStorage( XMultiServiceFactory xMSF, XSingleServiceFactory xFactory, XStorage xStorage )
+ {
+ // create a copy of a last commited version of specified storage
+ XStorage xResult = null;
+ try
+ {
+ xResult = createTempStorage( xMSF, xFactory );
+ if ( xResult != null )
+ xStorage.copyLastCommitTo( xResult );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't clone storage, exception: " + e );
+ return null;
+ }
+
+ return xResult;
+ }
+
+ public XStorage cloneSubStorage( XMultiServiceFactory xMSF, XSingleServiceFactory xFactory, XStorage xStorage, String sName )
+ {
+ // create a copy of a last commited version of specified substorage
+ XStorage xResult = null;
+ try
+ {
+ xResult = createTempStorage( xMSF, xFactory );
+ if ( xResult != null )
+ xStorage.copyStorageElementLastCommitTo( sName, xResult );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't clone substorage '" + sName + "', exception: " + e );
+ return null;
+ }
+
+ return xResult;
+ }
+
+ public XStream cloneSubStream( XStorage xStorage, String sName )
+ {
+ // clone existing substream
+ try
+ {
+ XStream xStream = xStorage.cloneStreamElement( sName );
+ return xStream;
+ }
+ catch( Exception e )
+ {
+ Error( "Can't clone substream '" + sName + "', exception: " + e );
+ }
+
+ return null;
+ }
+
+ public void Error( String sError )
+ {
+ m_aLogWriter.println( m_sTestPrefix + "Error: " + sError );
+ }
+
+ public void Message( String sMessage )
+ {
+ m_aLogWriter.println( m_sTestPrefix + sMessage );
+ }
+
+ public void PrintRelations( StringPair[][] aRels )
+ {
+ m_aLogWriter.println( "========" );
+ for ( int nInd1 = 0; nInd1 < aRels.length; nInd1++ )
+ {
+ for ( int nInd2 = 0; nInd2 < aRels[nInd1].length; nInd2++ )
+ {
+ m_aLogWriter.println( "\"" + aRels[nInd1][nInd2].First + "\" = \"" + aRels[nInd1][nInd2].Second + "\", " );
+ }
+ m_aLogWriter.println( "========" );
+ }
+ }
+}
+
diff --git a/package/qa/ofopxmlstorages/makefile.mk b/package/qa/ofopxmlstorages/makefile.mk
new file mode 100644
index 000000000000..c829458d3c24
--- /dev/null
+++ b/package/qa/ofopxmlstorages/makefile.mk
@@ -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.
+#
+#*************************************************************************
+
+PRJ = ..$/..
+TARGET = StorageUnitTest
+PRJNAME = package
+PACKAGE = complex$/ofopxmlstorages
+
+# --- Settings -----------------------------------------------------
+.INCLUDE: settings.mk
+
+
+#----- compile .java files -----------------------------------------
+
+JARFILES = ridl.jar unoil.jar jurt.jar juh.jar java_uno.jar OOoRunner.jar
+
+JAVAFILES =\
+ StorageUnitTest.java\
+ StorageTest.java\
+ TestHelper.java\
+ Test01.java\
+ Test02.java\
+ Test03.java\
+ Test04.java\
+ Test05.java\
+ Test06.java\
+ Test07.java\
+ Test08.java
+
+JAVACLASSFILES = $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class)
+
+#----- make a jar from compiled files ------------------------------
+
+MAXLINELENGTH = 100000
+
+JARCLASSDIRS = $(PACKAGE)
+JARTARGET = $(TARGET).jar
+JARCOMPRESS = TRUE
+
+# --- Parameters for the test --------------------------------------
+
+# start an office if the parameter is set for the makefile
+.IF "$(OFFICE)" == ""
+CT_APPEXECCOMMAND =
+.ELSE
+CT_APPEXECCOMMAND = -AppExecutionCommand "$(OFFICE)$/soffice -accept=socket,host=localhost,port=8100;urp;"
+.ENDIF
+
+# test base is java complex
+CT_TESTBASE = -TestBase java_complex
+
+# test looks something like the.full.package.TestName
+CT_TEST = -o $(PACKAGE:s\$/\.\).$(JAVAFILES:b)
+
+# start the runner application
+CT_APP = org.openoffice.Runner
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE: target.mk
+
+RUN: run
+
+run:
+ java -cp $(CLASSPATH) $(CT_APP) $(CT_TESTBASE) $(CT_APPEXECCOMMAND) $(CT_TEST)
+
+
diff --git a/package/qa/storages/BorderedStream.java b/package/qa/storages/BorderedStream.java
new file mode 100644
index 000000000000..7972b7a3ef0a
--- /dev/null
+++ b/package/qa/storages/BorderedStream.java
@@ -0,0 +1,195 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+import com.sun.star.io.XOutputStream;
+import com.sun.star.io.XTruncate;
+import com.sun.star.io.XSeekable;
+
+
+public class BorderedStream
+ implements XStream, XInputStream, XOutputStream, XTruncate, XSeekable
+{
+ int m_nMaxSize;
+ int m_nCurSize;
+ int m_nCurPos;
+ byte m_pBytes[];
+
+ public BorderedStream( int nMaxSize )
+ {
+ m_nMaxSize = nMaxSize;
+ m_nCurSize = 0;
+ m_nCurPos = 0;
+ m_pBytes = new byte[m_nMaxSize];
+ }
+
+ //==============
+ // XStream
+ //==============
+
+ // ----------------------------------------------------------
+ public synchronized XInputStream getInputStream()
+ throws com.sun.star.uno.RuntimeException
+ {
+ return (XInputStream)UnoRuntime.queryInterface( XInputStream.class, this );
+ }
+
+ // ----------------------------------------------------------
+ public synchronized XOutputStream getOutputStream()
+ throws com.sun.star.uno.RuntimeException
+ {
+ return (XOutputStream)UnoRuntime.queryInterface( XOutputStream.class, this );
+ }
+
+ //==============
+ // XInputStream
+ //==============
+
+ // ----------------------------------------------------------
+ public synchronized int readBytes( byte[][] aData, int nBytesToRead )
+ throws com.sun.star.io.NotConnectedException, com.sun.star.io.BufferSizeExceededException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
+ {
+ int nRead = 0;
+ if ( m_pBytes != null && nBytesToRead > 0 )
+ {
+ int nAvailable = m_nCurSize - m_nCurPos;
+ if ( nBytesToRead > nAvailable )
+ nBytesToRead = nAvailable;
+
+ aData[0] = new byte[nBytesToRead];
+ for ( int nInd = 0; nInd < nBytesToRead; nInd++ )
+ aData[0][nInd] = m_pBytes[m_nCurPos+nInd];
+
+ nRead = nBytesToRead;
+ m_nCurPos += nRead;
+ }
+ else
+ {
+ aData[0] = new byte[0];
+ }
+
+ return nRead;
+ }
+
+ // ----------------------------------------------------------
+ public synchronized int readSomeBytes( byte[][] aData, int nMaxBytesToRead )
+ throws com.sun.star.io.NotConnectedException, com.sun.star.io.BufferSizeExceededException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
+ {
+ return readBytes( aData, nMaxBytesToRead );
+ }
+
+ // ----------------------------------------------------------
+ public synchronized void skipBytes( int nBytesToSkip )
+ throws com.sun.star.io.NotConnectedException, com.sun.star.io.BufferSizeExceededException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
+ {
+ if ( nBytesToSkip < 0 )
+ throw new com.sun.star.io.IOException(); // illegal argument
+
+ if ( m_nCurSize - m_nCurPos > nBytesToSkip )
+ m_nCurPos += nBytesToSkip;
+ else
+ m_nCurPos = m_nCurSize;
+ }
+
+ // ----------------------------------------------------------
+ public synchronized int available()
+ throws com.sun.star.io.NotConnectedException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
+ {
+ return 0;
+ }
+
+ // ----------------------------------------------------------
+ public synchronized void closeInput()
+ throws com.sun.star.io.NotConnectedException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
+ {
+ // no need to do anything
+ }
+
+
+ //==============
+ // XOutputStream
+ //==============
+
+ // ----------------------------------------------------------
+ public synchronized void writeBytes( byte[] aData )
+ throws com.sun.star.io.NotConnectedException, com.sun.star.io.BufferSizeExceededException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
+ {
+ if ( m_pBytes != null && aData.length > 0 )
+ {
+ if ( aData.length > m_nMaxSize - m_nCurPos )
+ throw new com.sun.star.io.IOException();
+
+ for ( int nInd = 0; nInd < aData.length; nInd++ )
+ m_pBytes[m_nCurPos+nInd] = aData[nInd];
+
+ m_nCurPos += aData.length;
+ if ( m_nCurPos > m_nCurSize )
+ m_nCurSize = m_nCurPos;
+ }
+ }
+
+ // ----------------------------------------------------------
+ public synchronized void flush()
+ throws com.sun.star.io.NotConnectedException, com.sun.star.io.BufferSizeExceededException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
+ {
+ // nothing to do
+ }
+
+ // ----------------------------------------------------------
+ public synchronized void closeOutput()
+ throws com.sun.star.io.NotConnectedException, com.sun.star.io.BufferSizeExceededException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
+ {
+ // nothing to do
+ }
+
+
+ //==============
+ // XTruncate
+ //==============
+
+ // ----------------------------------------------------------
+ public synchronized void truncate()
+ throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
+ {
+ m_nCurSize = 0;
+ m_nCurPos = 0;
+ }
+
+
+ //==============
+ // XSeekable
+ //==============
+
+ // ----------------------------------------------------------
+ public synchronized void seek( long location )
+ throws com.sun.star.lang.IllegalArgumentException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
+ {
+ if ( location > (long)m_nCurSize )
+ throw new com.sun.star.lang.IllegalArgumentException();
+
+ m_nCurPos = (int)location;
+ }
+
+ // ----------------------------------------------------------
+ public synchronized long getPosition()
+ throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
+ {
+ return (long)m_nCurPos;
+ }
+
+ // ----------------------------------------------------------
+ public synchronized long getLength()
+ throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
+ {
+ return (long)m_nCurSize;
+ }
+};
+
diff --git a/package/qa/storages/RegressionTest_114358.java b/package/qa/storages/RegressionTest_114358.java
new file mode 100644
index 000000000000..51d3ecb4a8b4
--- /dev/null
+++ b/package/qa/storages/RegressionTest_114358.java
@@ -0,0 +1,190 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class RegressionTest_114358 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public RegressionTest_114358( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "RegressionTest_114358: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType2",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType3",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // commit substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // dispose the temporary storage
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // create a new storage based on the stream and change the substream
+ // as described in the bug description
+ // ================================================
+
+ byte pBytes2[] = { 2, 2 };
+
+ oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open the substorage
+ xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open the substream, set new "MediaType" and "Compressed" properties to it, truncate and write new contents
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream1", "MediaType4", true, pBytes2 ) )
+ return false;
+
+ // commit substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // dispose the temporary storage
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // create a new readonly storage based on the stream and check the contents
+ // ================================================
+
+ pArgs[1] = new Integer( ElementModes.READ );
+ oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open the substorage
+ xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempStorage, "MediaType2", true, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubStorage, "MediaType3", false, ElementModes.READ ) )
+ return false;
+
+ // the MediaType and the contents must be up to date
+ if ( !m_aTestHelper.checkStream( xTempSubStorage, "SubStream1", "MediaType4", true, pBytes2 ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/RegressionTest_125919.java b/package/qa/storages/RegressionTest_125919.java
new file mode 100644
index 000000000000..0a13fc63758c
--- /dev/null
+++ b/package/qa/storages/RegressionTest_125919.java
@@ -0,0 +1,134 @@
+package complex.storages;
+
+import java.lang.Integer;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+import complex.storages.BorderedStream;
+
+public class RegressionTest_125919 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ int nMinTestLen = 0;
+ int nMaxTestLen = 60000;
+
+ public RegressionTest_125919( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "RegressionTest_125919: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ byte[] pBytes0 = new byte[0];
+ byte[] pBytes18 = new byte[18000];
+ byte[] pBytes36 = new byte[36000];
+
+ for ( int nInitInd = 0; nInitInd < 36000; nInitInd++ )
+ {
+ pBytes36[nInitInd] = ( new Integer( nInitInd >> ( ( nInitInd % 2 ) * 8 ) ) ).byteValue();
+ if ( nInitInd < 18000 )
+ pBytes18[nInitInd] = ( new Integer( 256 - pBytes36[nInitInd] ) ).byteValue();
+ }
+
+ System.out.println( "This test can take up to some hours. The file size currently is about 50000." );
+ System.out.println( "Progress: " );
+ for ( int nAvailableBytes = nMinTestLen; nAvailableBytes < nMaxTestLen; nAvailableBytes++ )
+ {
+ Object oBStream = new BorderedStream( nAvailableBytes );
+ XStream xBorderedStream = (XStream)UnoRuntime.queryInterface( XStream.class, oBStream );
+ if ( xBorderedStream == null )
+ {
+ m_aTestHelper.Error( "Can't create bordered stream!" );
+ return false;
+ }
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xBorderedStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ XTransactedObject xTransact = (XTransactedObject) UnoRuntime.queryInterface( XTransactedObject.class, xTempStorage );
+ if ( xTransact == null )
+ {
+ m_aTestHelper.Error( "This test is designed for storages in transacted mode!" );
+ return false;
+ }
+
+
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempStorage, "SubStream" + 0, "MediaType1", true, pBytes0 ) )
+ return false;
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempStorage, "SubStream" + 18, "MediaType2", true, pBytes18 ) )
+ return false;
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempStorage, "SubStream" + 36, "MediaType3", true, pBytes36 ) )
+ return false;
+
+ if ( nAvailableBytes > 0 && nAvailableBytes % 100 == 0 )
+ System.out.println( " " + nAvailableBytes );
+
+ if ( nAvailableBytes > 0 && nAvailableBytes % 2 == 1 )
+ System.out.print( "#" );
+
+ try
+ {
+ xTransact.commit();
+
+ System.out.println( "" );
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // SUCCESS
+ return true;
+ }
+ catch( UseBackupException aExc )
+ {
+ // when there is not enough place in the target location and the target file is empty
+ // the direct writing will fail and must throw this exception with empty URL
+ if ( aExc.TemporaryFileURL.length() != 0 )
+ return false;
+ }
+ catch( Exception e )
+ {
+ System.out.println( "" );
+ m_aTestHelper.Error( "Unexpected exception: " + e + "\nnAvailableBytes = " + nAvailableBytes );
+ return false;
+ }
+ }
+
+ return false;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/RegressionTest_i26398.java b/package/qa/storages/RegressionTest_i26398.java
new file mode 100644
index 000000000000..9116a7d9bafa
--- /dev/null
+++ b/package/qa/storages/RegressionTest_i26398.java
@@ -0,0 +1,146 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class RegressionTest_i26398 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public RegressionTest_i26398( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "RegressionTest_i26398: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType2",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType3",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+
+ // ================================================
+ // commit the substorage, dispose it, reopen readonly
+ // and dispose the reopened substorage
+ // ================================================
+
+ // commit substorage
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // dispose substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // open a new substorage
+ xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // dispose substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // ================================================
+ // reopen the substorage in readwrite mode and check contents
+ // ================================================
+
+ // open a new substorage
+ xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubStorage, "MediaType3", false, ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempStorage, "MediaType2", true, ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xTempSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // the root storage is based on the temporary stream so it can be left undisposed, since it does not lock
+ // any resource, later the garbage collector will release the object and it must die by refcount
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/RegressionTest_i27773.java b/package/qa/storages/RegressionTest_i27773.java
new file mode 100644
index 000000000000..4e627a816167
--- /dev/null
+++ b/package/qa/storages/RegressionTest_i27773.java
@@ -0,0 +1,299 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.uno.AnyConverter;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+///////////////////////////////////
+// Tests also fix for i51352
+///////////////////////////////////
+
+public class RegressionTest_i27773 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public RegressionTest_i27773( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "RegressionTest_i27773: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ if ( true )
+ {
+ // for debugging proposes
+
+ XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xTempFileStream );
+ if ( xPropSet != null )
+ {
+ try
+ {
+ String sTempURL = AnyConverter.toString( xPropSet.getPropertyValue( "Uri" ) );
+ // m_aTestHelper.Message( "URL: " + sTempURL );
+ xPropSet.setPropertyValue( "RemoveFile", new Boolean( false ) );
+ }
+ catch ( Exception e )
+ {
+ }
+ }
+ }
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open an empty substorage
+ XStorage xEmptySubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "EmptySubStorage1",
+ ElementModes.WRITE );
+ if ( xEmptySubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open an empty substorage
+ XStorage xEmptySubSubStorage = m_aTestHelper.openSubStorage( xTempSubStorage,
+ "EmptySubSubStorage1",
+ ElementModes.WRITE );
+ if ( xEmptySubSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType2",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xEmptySubStorage,
+ "MediaType3",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType4",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xEmptySubSubStorage,
+ "MediaType5",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+
+ // make a copy of substorage
+
+ if ( !m_aTestHelper.copyElementTo( xTempStorage, "SubStorage1", xTempStorage, "SubStorage1_copy" ) )
+ return false;
+
+ if ( !m_aTestHelper.copyElementTo( xTempStorage, "EmptySubStorage1", xTempStorage, "EmptySubStorage1_copy" ) )
+ return false;
+
+ // ================================================
+ // copy all the changed and noncommited substorages
+ // and dispose them
+ // ================================================
+
+ if ( !m_aTestHelper.commitStorage( xEmptySubSubStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xEmptySubStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose substorages
+
+ if ( !m_aTestHelper.disposeStorage( xEmptySubSubStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.disposeStorage( xEmptySubStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // reopen the storage in readonly mode an check contents
+ // ================================================
+
+ pArgs[1] = new Integer( ElementModes.READ );
+
+ oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open original substorage
+ xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open copy of the original substorage
+ XStorage xTempSubStorage_copy = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1_copy",
+ ElementModes.READ );
+ if ( xTempSubStorage_copy == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open empty substorage
+ xEmptySubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "EmptySubStorage1",
+ ElementModes.READ );
+ if ( xEmptySubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open copy of empty substorage
+ XStorage xEmptySubStorage_copy = m_aTestHelper.openSubStorage( xTempStorage,
+ "EmptySubStorage1_copy",
+ ElementModes.READ );
+ if ( xEmptySubStorage_copy == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open an empty substorage of the substorage
+ xEmptySubSubStorage = m_aTestHelper.openSubStorage( xTempSubStorage,
+ "EmptySubSubStorage1",
+ ElementModes.READ );
+ if ( xEmptySubSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open an empty substorage of the substorage copy
+ XStorage xEmptySubSubStorage_inCopy = m_aTestHelper.openSubStorage( xTempSubStorage_copy,
+ "EmptySubSubStorage1",
+ ElementModes.READ );
+ if ( xEmptySubSubStorage_inCopy == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+
+ // check contents
+
+ if ( !m_aTestHelper.checkStorageProperties( xEmptySubSubStorage, "MediaType5", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xEmptySubSubStorage_inCopy, "MediaType5", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubStorage, "MediaType4", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubStorage_copy, "MediaType4", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xEmptySubStorage, "MediaType3", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xEmptySubStorage_copy, "MediaType3", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempStorage, "MediaType2", true, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xTempSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xTempSubStorage_copy, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // the root storage is based on the temporary stream so it can be left undisposed, since it does not lock
+ // any resource, later the garbage collector will release the object and it must die by refcount
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/RegressionTest_i29169.java b/package/qa/storages/RegressionTest_i29169.java
new file mode 100644
index 000000000000..580ee510caf8
--- /dev/null
+++ b/package/qa/storages/RegressionTest_i29169.java
@@ -0,0 +1,369 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class RegressionTest_i29169 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public RegressionTest_i29169( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "RegressionTest_i29169: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // open a new substorage in the existing substorage
+ XStorage xTempSubSubStorage = m_aTestHelper.openSubStorage( xTempSubStorage,
+ "SubSubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubSubStorage, "SubSubStream1", "MediaType2", true, pBytes1 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubSubStorage,
+ "MediaType3",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType4",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType5",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // ================================================
+ // commit the storages, and check the renaming in all stages
+ // ================================================
+
+ // rename the storage before it is commited
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubSubStorage1", "SubSubStorage2" ) )
+ return false;
+
+ // rename the stream
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubStream1", "SubStream2" ) )
+ return false;
+
+ // commit lowlevel substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubSubStorage ) )
+ return false;
+
+ // rename the storage after it is commited
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubSubStorage2", "SubSubStorage3" ) )
+ return false;
+
+ // rename the stream one more time
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubStream2", "SubStream3" ) )
+ return false;
+
+ // commit substorage
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // rename the storage after it`s parent is commited
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubSubStorage3", "SubSubStorage4" ) )
+ return false;
+
+ // rename the stream after it`s parent is commited
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubStream3", "SubStream4" ) )
+ return false;
+
+ // commit substorage to let the renaming take place
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // rename the storage after the package is commited
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubSubStorage4", "SubSubStorage5" ) )
+ return false;
+
+ // rename the stream after it`s parent is commited
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubStream4", "SubStream5" ) )
+ return false;
+
+ // commit substorage to let the renaming take place
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // dispose the storages
+ // ================================================
+
+ // dispose lowerest substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubSubStorage ) )
+ return false;
+
+ // dispose substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // dispose the temporary storage
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // create a new storage based on the stream and check the substreams and substorages
+ // ================================================
+
+ oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open the substorage
+ xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open the lowlevel substorage
+ xTempSubSubStorage = m_aTestHelper.openSubStorage( xTempSubStorage,
+ "SubSubStorage5",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // check the storages and streams
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubSubStorage, "MediaType3", false, ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubStorage, "MediaType4", false, ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempStorage, "MediaType5", true, ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xTempSubStorage, "SubStream5", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xTempSubSubStorage, "SubSubStream1", "MediaType2", true, pBytes1 ) )
+ return false;
+
+ // ================================================
+ // rename the reopened storages and streams
+ // ================================================
+
+ // rename the storage before it is commited
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubSubStorage5", "SubSubStorage6" ) )
+ return false;
+
+ // rename the stream
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubStream5", "SubStream6" ) )
+ return false;
+
+ // commit lowlevel substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubSubStorage ) )
+ return false;
+
+ // rename the storage after it is commited
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubSubStorage6", "SubSubStorage7" ) )
+ return false;
+
+ // rename the stream one more time
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubStream6", "SubStream7" ) )
+ return false;
+
+ // commit substorage
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // rename the storage after it`s parent is commited
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubSubStorage7", "SubSubStorage8" ) )
+ return false;
+
+ // rename the stream after it`s parent is commited
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubStream7", "SubStream8" ) )
+ return false;
+
+ // commit substorage to let the renaming take place
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // rename the storage after the package is commited
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubSubStorage8", "SubSubStorage9" ) )
+ return false;
+
+ // rename the stream after it`s parent is commited
+ if ( !m_aTestHelper.renameElement( xTempSubStorage, "SubStream8", "SubStream9" ) )
+ return false;
+
+ // commit substorage to let the renaming take place
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // dispose the storages
+ // ================================================
+
+ // dispose lowerest substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubSubStorage ) )
+ return false;
+
+ // dispose substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // dispose the temporary storage
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+
+ // ================================================
+ // create a new readonly storage based on the stream and check the contents
+ // ================================================
+
+ pArgs[1] = new Integer( ElementModes.READ );
+ oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open the substorage
+ xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open the lowlevel substorage
+ xTempSubSubStorage = m_aTestHelper.openSubStorage( xTempSubStorage,
+ "SubSubStorage9",
+ ElementModes.READ );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // check the storages and streams
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubSubStorage, "MediaType3", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubStorage, "MediaType4", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempStorage, "MediaType5", true, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xTempSubStorage, "SubStream9", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xTempSubSubStorage, "SubSubStream1", "MediaType2", true, pBytes1 ) )
+ return false;
+
+ // the storage is based on the temporary stream so it can be left undisposed, since it does not lock
+ // any resource, later the garbage collector will release the object and it must die by refcount
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/RegressionTest_i29321.java b/package/qa/storages/RegressionTest_i29321.java
new file mode 100644
index 000000000000..740f48ce59a3
--- /dev/null
+++ b/package/qa/storages/RegressionTest_i29321.java
@@ -0,0 +1,170 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class RegressionTest_i29321 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public RegressionTest_i29321( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "RegressionTest_i29321: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubSubStorage = m_aTestHelper.openSubStorage( xTempSubStorage,
+ "SubSubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempStorage, "Stream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream1", "MediaType2", true, pBytes1 ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubSubStorage, "SubSubStream1", "MediaType3", true, pBytes1 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType4",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType5",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubSubStorage,
+ "MediaType6",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // ================================================
+ // commit the storages twice to test the bug scenario
+ // ================================================
+
+ // commit lowlevel substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubSubStorage ) )
+ return false;
+
+ // commit substorage
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit substorage to let the renaming take place
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // commit lowlevel substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubSubStorage ) )
+ return false;
+
+ // commit substorage
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit substorage to let the renaming take place
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // check the storages and streams without closing
+ // ================================================
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubSubStorage, "MediaType6", false, ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubStorage, "MediaType5", false, ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempStorage, "MediaType4", true, ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xTempSubSubStorage, "SubSubStream1", "MediaType3", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xTempSubStorage, "SubStream1", "MediaType2", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xTempStorage, "Stream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // the root storage is based on the temporary stream so it can be left undisposed, since it does not lock
+ // any resource, later the garbage collector will release the object and it must die by refcount
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/RegressionTest_i30400.java b/package/qa/storages/RegressionTest_i30400.java
new file mode 100644
index 000000000000..5f82a7beb39e
--- /dev/null
+++ b/package/qa/storages/RegressionTest_i30400.java
@@ -0,0 +1,435 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class RegressionTest_i30400 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public RegressionTest_i30400( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "RegressionTest_i30400: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ // ================================================
+ // create a temporary stream and a storage based on it
+ // fill the storage with the data that will be used for testing
+ // ================================================
+
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+ String pPass1 = "1, 2, 3, 4, 5";
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempStorage, "Stream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempStorage, "EncrStream1", "MediaType2", true, pBytes1, pPass1 ) )
+ return false;
+
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream1", "MediaType3", true, pBytes1 ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempSubStorage, "SubEncrStream1", "MediaType4", true, pBytes1, pPass1 ) )
+ return false;
+
+ // open a new substorage in the existing substorage
+ XStorage xTempSubSubStorage = m_aTestHelper.openSubStorage( xTempSubStorage,
+ "SubSubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubSubStorage, "SubSubStream1", "MediaType5", true, pBytes1 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubSubStorage,
+ "MediaType6",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType7",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType8",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // ================================================
+ // check the copying with renaming
+ // ================================================
+
+ if ( !TestCopyWithRenaming( xTempStorage, xTempSubStorage, xTempSubSubStorage ) )
+ return false;
+
+ // ================================================
+ // commit the storages
+ // ================================================
+
+ // commit lowlevel substorage
+ if ( !m_aTestHelper.commitStorage( xTempSubSubStorage ) )
+ return false;
+
+ // commit substorage
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // dispose the storages
+ // ================================================
+
+ // dispose lowerest substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubSubStorage ) )
+ return false;
+
+ // dispose substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // dispose the temporary storage
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // reopen the target storage readonly, and check the copying with renaming
+ // ================================================
+
+ pArgs[1] = new Integer( ElementModes.READ );
+ oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open the substorages
+
+ xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open the lowlevel substorages
+
+ xTempSubSubStorage = m_aTestHelper.openSubStorage( xTempSubStorage,
+ "SubSubStorage1",
+ ElementModes.READ );
+ if ( xTempSubSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // test the copying with renaming
+ if ( !TestCopyWithRenaming( xTempStorage, xTempSubStorage, xTempSubSubStorage ) )
+ return false;
+
+
+ // the storage is based on the temporary stream so it can be left undisposed, since it does not lock
+ // any resource, later the garbage collector will release the object and it must die by refcount
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+
+ public boolean TestCopyWithRenaming( XStorage xTempStorage, XStorage xTempSubStorage, XStorage xTempSubSubStorage )
+ throws com.sun.star.uno.Exception
+ {
+ // ================================================
+ // create a second temporary stream and copy all the staff there
+ // with renaming, check the success
+ // ================================================
+
+ XStream xTempFileStream2 = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream2 == null )
+ return false;
+
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream2;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+ String pPass1 = "1, 2, 3, 4, 5";
+
+ Object oTempStorage2 = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage2 = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage2 );
+ if ( xTempStorage2 == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage2 = m_aTestHelper.openSubStorage( xTempStorage2,
+ "SubStorage1_target",
+ ElementModes.WRITE );
+ if ( xTempSubStorage2 == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open a new substorage in the existing substorage
+ XStorage xTempSubSubStorage2 = m_aTestHelper.openSubStorage( xTempSubStorage2,
+ "SubSubStorage1_target",
+ ElementModes.WRITE );
+ if ( xTempSubSubStorage2 == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // make a copy with renaming on lowerest level
+ if ( !m_aTestHelper.copyElementTo( xTempSubSubStorage, "SubSubStream1", xTempSubSubStorage2, "SubSubStream1_renamed" ) )
+ return false;
+
+ // make a copy with renaming on the next level
+
+ if ( !m_aTestHelper.copyElementTo( xTempSubStorage, "SubStream1", xTempSubStorage2, "SubStream1_renamed" ) )
+ return false;
+
+ if ( !m_aTestHelper.copyElementTo( xTempSubStorage, "SubEncrStream1", xTempSubStorage2, "SubEncrStream1_renamed" ) )
+ return false;
+
+ if ( !m_aTestHelper.copyElementTo( xTempSubStorage, "SubSubStorage1", xTempSubStorage2, "SubSubStorage1_renamed" ) )
+ return false;
+
+ // make a copy with renaming of subelements of the root storage
+
+ if ( !m_aTestHelper.copyElementTo( xTempStorage, "Stream1", xTempStorage2, "Stream1_renamed" ) )
+ return false;
+
+ if ( !m_aTestHelper.copyElementTo( xTempStorage, "EncrStream1", xTempStorage2, "EncrStream1_renamed" ) )
+ return false;
+
+ if ( !m_aTestHelper.copyElementTo( xTempStorage, "SubStorage1", xTempStorage2, "SubStorage1_renamed" ) )
+ return false;
+
+ // ================================================
+ // commit the storages, and check the renaming in all stages
+ // ================================================
+
+ // commit substorage to let the renaming take place
+ if ( !m_aTestHelper.commitStorage( xTempSubSubStorage2 ) )
+ return false;
+
+ // commit substorage to let the renaming take place
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage2 ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage2 ) )
+ return false;
+
+ // ================================================
+ // dispose the storages
+ // ================================================
+
+ // dispose lowerest substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubSubStorage2 ) )
+ return false;
+
+ // dispose substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage2 ) )
+ return false;
+
+ // dispose the temporary storage
+ if ( !m_aTestHelper.disposeStorage( xTempStorage2 ) )
+ return false;
+
+ // ================================================
+ // reopen the target storage readonly, and check the contents
+ // ================================================
+
+ pArgs[1] = new Integer( ElementModes.READ );
+ oTempStorage2 = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ xTempStorage2 = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage2 );
+ if ( xTempStorage2 == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open the substorages
+
+ XStorage xTempSubStorage2_target = m_aTestHelper.openSubStorage( xTempStorage2,
+ "SubStorage1_target",
+ ElementModes.READ );
+ if ( xTempSubStorage2_target == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ XStorage xTempSubStorage2_renamed = m_aTestHelper.openSubStorage( xTempStorage2,
+ "SubStorage1_renamed",
+ ElementModes.READ );
+ if ( xTempSubStorage2_renamed == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open the lowlevel substorages
+
+ XStorage xTempSubSubStorage2_inRenamed = m_aTestHelper.openSubStorage( xTempSubStorage2_renamed,
+ "SubSubStorage1",
+ ElementModes.READ );
+ if ( xTempSubSubStorage2_inRenamed == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ XStorage xTempSubSubStorage2_renamed = m_aTestHelper.openSubStorage( xTempSubStorage2_target,
+ "SubSubStorage1_renamed",
+ ElementModes.READ );
+ if ( xTempSubSubStorage2_renamed == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ XStorage xTempSubSubStorage2_target = m_aTestHelper.openSubStorage( xTempSubStorage2_target,
+ "SubSubStorage1_target",
+ ElementModes.READ );
+ if ( xTempSubSubStorage2_target == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // check the storages
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubSubStorage2_inRenamed, "MediaType6", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubSubStorage2_renamed, "MediaType6", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubStorage2_renamed, "MediaType7", false, ElementModes.READ ) )
+ return false;
+
+
+ // check the streams
+
+
+ // sub sub level
+
+ if ( !m_aTestHelper.checkStream( xTempSubSubStorage2_inRenamed, "SubSubStream1", "MediaType5", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xTempSubSubStorage2_renamed, "SubSubStream1", "MediaType5", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xTempSubSubStorage2_target, "SubSubStream1_renamed", "MediaType5", true, pBytes1 ) )
+ return false;
+
+ // sub level
+
+ if ( !m_aTestHelper.checkStream( xTempSubStorage2_renamed, "SubStream1", "MediaType3", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( xTempSubStorage2_renamed, "SubEncrStream1", "MediaType4", pBytes1, pPass1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xTempSubStorage2_target, "SubStream1_renamed", "MediaType3", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( xTempSubStorage2_target, "SubEncrStream1_renamed", "MediaType4", pBytes1, pPass1 ) )
+ return false;
+
+ // root storage level
+
+ if ( !m_aTestHelper.checkStream( xTempStorage2, "Stream1_renamed", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( xTempStorage2, "EncrStream1_renamed", "MediaType2", pBytes1, pPass1 ) )
+ return false;
+
+ // the storage is based on the temporary stream so it can be left undisposed, since it does not lock
+ // any resource, later the garbage collector will release the object and it must die by refcount
+
+ return true;
+ }
+}
+
diff --git a/package/qa/storages/RegressionTest_i30677.java b/package/qa/storages/RegressionTest_i30677.java
new file mode 100644
index 000000000000..740c9e319313
--- /dev/null
+++ b/package/qa/storages/RegressionTest_i30677.java
@@ -0,0 +1,263 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class RegressionTest_i30677 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public RegressionTest_i30677( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "RegressionTest_i30677: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open a new subsubstorage
+ XStorage xTempSubSubStorage = m_aTestHelper.openSubStorage( xTempSubStorage,
+ "SubSubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubSubStorage, "SubSubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType2",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType3",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubSubStorage,
+ "MediaType4",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // ================================================
+ // commit the storages
+ // ================================================
+
+ // commit lowlevel substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubSubStorage ) )
+ return false;
+
+ // commit substorage
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit substorage to let the renaming take place
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // dispose the storages
+ // ================================================
+
+ // dispose lowerest substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubSubStorage ) )
+ return false;
+
+ // dispose substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // dispose the temporary storage
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // reopen the storage and rewrite the stream
+ // ================================================
+
+ oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open the substorages
+
+ xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open the lowlevel substorages
+
+ xTempSubSubStorage = m_aTestHelper.openSubStorage( xTempSubStorage,
+ "SubSubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubSubStorage, "SubSubStream1", "MediaType1", true, pBytes2 ) )
+ return false;
+
+ // ================================================
+ // commit the storages
+ // ================================================
+
+ // commit lowlevel substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubSubStorage ) )
+ return false;
+
+ // commit substorage
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit substorage to let the renaming take place
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // dispose the storages
+ // ================================================
+
+ // dispose lowerest substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubSubStorage ) )
+ return false;
+
+ // dispose substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // dispose the temporary storage
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // reopen the storages and check the contents
+ // ================================================
+
+ pArgs[1] = new Integer( ElementModes.READ );
+ oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open the substorages
+
+ xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open the lowlevel substorages
+
+ xTempSubSubStorage = m_aTestHelper.openSubStorage( xTempSubStorage,
+ "SubSubStorage1",
+ ElementModes.READ );
+ if ( xTempSubSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubSubStorage, "MediaType4", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubStorage, "MediaType3", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempStorage, "MediaType2", true, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xTempSubSubStorage, "SubSubStream1", "MediaType1", true, pBytes2 ) )
+ return false;
+
+ // the root storage is based on the temporary stream so it can be left undisposed, since it does not lock
+ // any resource, later the garbage collector will release the object and it must die by refcount
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/RegressionTest_i35095.java b/package/qa/storages/RegressionTest_i35095.java
new file mode 100644
index 000000000000..d98ec800a5a6
--- /dev/null
+++ b/package/qa/storages/RegressionTest_i35095.java
@@ -0,0 +1,166 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class RegressionTest_i35095 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public RegressionTest_i35095( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "RegressionTest_i35095: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ byte pBytes[] = new byte[36000];
+ for ( int nInd = 0; nInd < 36000; nInd++ )
+ pBytes[nInd] = (byte)( nInd % 128 );
+
+ String sPass = "12345";
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempStorage, "SubStream1", "MediaType1", true, pBytes, sPass ) )
+ return false;
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempSubStorage, "SubStream2", "MediaType2", false, pBytes, sPass ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType3",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType4",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // commit substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // now check all the written information
+ // and the raw stream contents
+ // ================================================
+
+ // close the output part of the temporary stream
+ // the output part must present since we already wrote to the stream
+ if ( !m_aTestHelper.closeOutput( xTempFileStream ) )
+ return false;
+
+ XInputStream xTempInStream = m_aTestHelper.getInputStream( xTempFileStream );
+ if ( xTempInStream == null )
+ return false;
+
+ // open input stream
+ // since no mode is provided the result storage must be opened readonly
+ Object pOneArg[] = new Object[1];
+ pOneArg[0] = (Object) xTempInStream;
+
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pOneArg );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open storage based on input stream!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage, "MediaType3", true, ElementModes.READ ) )
+ return false;
+
+ // open existing substorage
+ XStorage xResultSubStorage = m_aTestHelper.openSubStorage( xResultStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xResultSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultSubStorage, "MediaType4", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.compareRawMethodsOnEncrStream( xResultStorage, "SubStream1" ) )
+ return false;
+
+ if ( !m_aTestHelper.compareRawMethodsOnEncrStream( xResultSubStorage, "SubStream2" ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/storages/RegressionTest_i46848.java b/package/qa/storages/RegressionTest_i46848.java
new file mode 100644
index 000000000000..438626e9a7ba
--- /dev/null
+++ b/package/qa/storages/RegressionTest_i46848.java
@@ -0,0 +1,191 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class RegressionTest_i46848 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public RegressionTest_i46848( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "RegressionTest_i46848: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType2",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType3",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // commit substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // dispose the temporary storage
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // create a new storage based on the stream and change the mediatype of the substorage
+ // as described in the bug description
+ // ================================================
+
+ oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open the substorage
+ xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "ChangedMediaType3",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // commit substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // dispose the temporary storage
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // create a new readonly storage based on the stream and check the contents
+ // ================================================
+
+ pArgs[1] = new Integer( ElementModes.READ );
+ oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open the substorage
+ xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempStorage, "MediaType2", true, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempSubStorage, "ChangedMediaType3", false, ElementModes.READ ) )
+ return false;
+
+ // the MediaType and the contents must be up to date
+ if ( !m_aTestHelper.checkStream( xTempSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/RegressionTest_i49755.java b/package/qa/storages/RegressionTest_i49755.java
new file mode 100644
index 000000000000..7d3ee6c01cac
--- /dev/null
+++ b/package/qa/storages/RegressionTest_i49755.java
@@ -0,0 +1,272 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class RegressionTest_i49755 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public RegressionTest_i49755( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "RegressionTest_i49755: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType1",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+
+ byte pBytes[] = new byte[36000];
+ for ( int nInd = 0; nInd < 36000; nInd++ )
+ pBytes[nInd] = (byte)( nInd % 128 );
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType2",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // open a new substorage
+ XStorage xTempSubSubStorage = m_aTestHelper.openSubStorage( xTempSubStorage,
+ "SubStorage2",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubSubStorage,
+ "MediaType3",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubSubStorage, "SubStream1", "MediaType4", true, pBytes ) )
+ return false;
+
+ // open a new substorage
+ XStorage xTempSubStorage1 = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage3",
+ ElementModes.WRITE );
+ if ( xTempSubStorage1 == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage1,
+ "MediaType5",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage1, "SubStream2", "MediaType4", false, pBytes ) )
+ return false;
+
+
+ // commit substorages first
+ if ( !m_aTestHelper.commitStorage( xTempSubSubStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage1 ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // now change the contents of the second substorage
+ // without changing of the contents of the first substorage
+ // ================================================
+
+ Object oStep2TempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xStep2TempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oStep2TempStorage );
+ if ( xStep2TempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ XStorage xStep2TempSubStorage1 = m_aTestHelper.openSubStorage( xStep2TempStorage,
+ "SubStorage3",
+ ElementModes.WRITE );
+ if ( xStep2TempSubStorage1 == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xStep2TempSubStorage1, "SubStream2", "MediaType4", false, pBytes ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xStep2TempSubStorage1 ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xStep2TempStorage ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xStep2TempStorage ) )
+ return false;
+
+
+ // ================================================
+ // now check all the written information
+ // and the raw stream contents
+ // ================================================
+
+ // close the output part of the temporary stream
+ // the output part must present since we already wrote to the stream
+ if ( !m_aTestHelper.closeOutput( xTempFileStream ) )
+ return false;
+
+ XInputStream xTempInStream = m_aTestHelper.getInputStream( xTempFileStream );
+ if ( xTempInStream == null )
+ return false;
+
+ // open input stream
+ // since no mode is provided the result storage must be opened readonly
+ Object pOneArg[] = new Object[1];
+ pOneArg[0] = (Object) xTempInStream;
+
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pOneArg );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open storage based on input stream!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage, "MediaType1", true, ElementModes.READ ) )
+ return false;
+
+ // open existing substorage
+ XStorage xResultSubStorage = m_aTestHelper.openSubStorage( xResultStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xResultSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultSubStorage, "MediaType2", false, ElementModes.READ ) )
+ return false;
+
+ // open existing substorage
+ XStorage xResultSubSubStorage = m_aTestHelper.openSubStorage( xResultSubStorage,
+ "SubStorage2",
+ ElementModes.READ );
+ if ( xResultSubSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultSubSubStorage, "MediaType3", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubSubStorage, "SubStream1", "MediaType4", true, pBytes ) )
+ return false;
+
+
+
+ XStorage xResultSubStorage1 = m_aTestHelper.openSubStorage( xResultStorage,
+ "SubStorage3",
+ ElementModes.READ );
+ if ( xResultSubStorage1 == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultSubStorage1, "MediaType5", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage1, "SubStream2", "MediaType4", false, pBytes ) )
+ return false;
+
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/storages/RegressionTest_i55821.java b/package/qa/storages/RegressionTest_i55821.java
new file mode 100644
index 000000000000..0803816427d6
--- /dev/null
+++ b/package/qa/storages/RegressionTest_i55821.java
@@ -0,0 +1,111 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class RegressionTest_i55821 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public RegressionTest_i55821( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "RegressionTest_i55821: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ // ================================================
+ // create a temporary stream and a storage based on it
+ // fill the storage with the data that will be used for testing
+ // ================================================
+
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ String sPass = "12345";
+ byte pBytes[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ // the stream will not be encrypted
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempStorage, "SubStream1", "MediaType1", false, pBytes, sPass ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempStorage, "SubStream2", "MediaType2", false, pBytes, sPass ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // reopen the target storage readonly, and check contents
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ pArgs[1] = new Integer( ElementModes.READ );
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkEncrStream( xResultStorage, "SubStream1", "MediaType1", pBytes, sPass ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( xResultStorage, "SubStream2", "MediaType2", pBytes, sPass ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/RegressionTest_i59886.java b/package/qa/storages/RegressionTest_i59886.java
new file mode 100644
index 000000000000..471149823c33
--- /dev/null
+++ b/package/qa/storages/RegressionTest_i59886.java
@@ -0,0 +1,243 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class RegressionTest_i59886 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public RegressionTest_i59886( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "RegressionTest_i59886: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ byte pBytes[] = new byte[36000];
+ for ( int nInd = 0; nInd < 36000; nInd++ )
+ pBytes[nInd] = (byte)( nInd % 128 );
+
+ String sPass = "12345";
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempStorage, "SubStream1", "MediaType1", true, pBytes, sPass ) )
+ return false;
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempSubStorage, "SubStream2", "MediaType2", false, pBytes, sPass ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType3",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType4",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // commit substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // now reopen the storage, set the common storage key
+ // and copy the storage
+ // ================================================
+
+ Object oStep2TempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xStep2TempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oStep2TempStorage );
+ if ( xStep2TempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+
+ XStorage xStep2TempSubStorage = m_aTestHelper.openSubStorage( xStep2TempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xStep2TempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // set the common storage password
+ XEncryptionProtectedSource xEncr = (XEncryptionProtectedSource) UnoRuntime.queryInterface( XEncryptionProtectedSource.class, xStep2TempStorage );
+ if ( xEncr == null )
+ {
+ m_aTestHelper.Error( "The storage does not support encryption access!" );
+ return false;
+ }
+ try
+ {
+ xEncr.setEncryptionPassword( sPass );
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Can not set the common storage password!" );
+ return false;
+ }
+
+ // open the stream for writing and read them so that the cache is created, but do not change
+ byte pDummyData[][] = new byte[1][3];
+ XStream xTempStream1 = m_aTestHelper.OpenStream( xStep2TempStorage, "SubStream1", ElementModes.WRITE );
+ XStream xTempStream2 = m_aTestHelper.OpenStream( xStep2TempSubStorage, "SubStream2", ElementModes.WRITE );
+ if ( xTempStream1 == null || xTempStream2 == null )
+ return false;
+
+ XInputStream xTempInStream1 = xTempStream1.getInputStream();
+ XInputStream xTempInStream2 = xTempStream2.getInputStream();
+ if ( xTempInStream1 == null || xTempInStream2 == null )
+ {
+ m_aTestHelper.Error( "No input stream is available!" );
+ return false;
+ }
+
+ xTempInStream1.readBytes( pDummyData, 3 );
+ xTempInStream2.readBytes( pDummyData, 3 );
+
+
+ // create temporary storage, it will be checked later
+ Object oTargetStorage = m_xStorageFactory.createInstance();
+ XStorage xTargetStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTargetStorage );
+ if ( xTargetStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // copy the current storage to the target
+ try
+ {
+ xStep2TempStorage.copyToStorage( xTargetStorage );
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Can not copy the storage with common storage password!" );
+ return false;
+ }
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xStep2TempStorage ) )
+ return false;
+
+ // ================================================
+ // now check all the information in the copy
+ // ================================================
+
+ if ( !m_aTestHelper.checkStorageProperties( xTargetStorage, "MediaType3", true, ElementModes.WRITE ) )
+ return false;
+
+ // open existing substorage
+ XStorage xTargetSubStorage = m_aTestHelper.openSubStorage( xTargetStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTargetSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xTargetSubStorage, "MediaType4", false, ElementModes.WRITE ) )
+ return false;
+
+ // set the common storage password
+ XEncryptionProtectedSource xTargetEncr = (XEncryptionProtectedSource) UnoRuntime.queryInterface( XEncryptionProtectedSource.class, xTargetStorage );
+ if ( xTargetEncr == null )
+ {
+ m_aTestHelper.Error( "The storage does not support encryption access!" );
+ return false;
+ }
+ try
+ {
+ xTargetEncr.setEncryptionPassword( sPass );
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Can not set the common storage password!" );
+ return false;
+ }
+
+ // check the streams
+ if ( !m_aTestHelper.checkStream( xTargetStorage, "SubStream1", "MediaType1", true, pBytes ) )
+ return false;
+ if ( !m_aTestHelper.checkStream( xTargetSubStorage, "SubStream2", "MediaType2", true, pBytes ) )
+ return false;
+
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTargetStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/RegressionTest_i61909.java b/package/qa/storages/RegressionTest_i61909.java
new file mode 100644
index 000000000000..5f5c1572d79d
--- /dev/null
+++ b/package/qa/storages/RegressionTest_i61909.java
@@ -0,0 +1,167 @@
+package complex.storages;
+
+import java.net.URI;
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipEntry;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class RegressionTest_i61909 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public RegressionTest_i61909( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "RegressionTest_i61909: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
+ if ( sTempFileURL == null || sTempFileURL == "" )
+ {
+ m_aTestHelper.Error( "No valid temporary file was created!" );
+ return false;
+ }
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) sTempFileURL;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ byte pBytes[] = new byte[36000];
+ for ( int nInd = 0; nInd < 36000; nInd++ )
+ pBytes[nInd] = (byte)( nInd % 128 );
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempStorage, "SubStream1", "MediaType1", true, pBytes ) )
+ return false;
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream2", "MediaType2", true, pBytes ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType3",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType4",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // commit substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // now reopen the storage, and insert a new stream
+ // ================================================
+
+ Object oStep2TempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xStep2TempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oStep2TempStorage );
+ if ( xStep2TempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xStep2TempStorage, "SubStream3", "MediaType5", true, pBytes ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xStep2TempStorage ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xStep2TempStorage ) )
+ return false;
+
+ // ================================================
+ // now access the stream using ZipInputStream
+ // ================================================
+
+ URI aUri = new URI( sTempFileURL );
+ File aFile = new File( aUri );
+ FileInputStream aFileStream = new FileInputStream( aFile );
+ ZipInputStream aZipStream = new ZipInputStream( aFileStream );
+
+ ZipEntry aEntry;
+ int nNumber = 0;
+ m_aTestHelper.Message( "Available entries:" );
+ while ( ( aEntry = aZipStream.getNextEntry() ) != null )
+ {
+ nNumber++;
+ m_aTestHelper.Message( aEntry.getName() );
+ }
+
+ if ( nNumber != 6 )
+ {
+ m_aTestHelper.Error( "Wrong number of entries: " + nNumber + ", Expected: 6" );
+ return false;
+ }
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/RegressionTest_i84234.java b/package/qa/storages/RegressionTest_i84234.java
new file mode 100644
index 000000000000..16150690d882
--- /dev/null
+++ b/package/qa/storages/RegressionTest_i84234.java
@@ -0,0 +1,134 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class RegressionTest_i84234 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public RegressionTest_i84234( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "RegressionTest_i84234: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempStorage, "SubStream1", "text/xml", false, pBytes1 ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream2", "text/xml", false, pBytes1 ) )
+ return false;
+
+
+ // ================================================
+ // commit the storages and dispose them
+ // ================================================
+
+ // commit substorage
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // dispose substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // commit storage
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose storage
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // reopen the storages in readwrite mode and check Compressed flag
+ // ================================================
+
+ oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStream( xTempStorage, "SubStream1", "text/xml", false, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xTempSubStorage, "SubStream2", "text/xml", false, pBytes1 ) )
+ return false;
+
+ // the root storage is based on the temporary stream so it can be left undisposed, since it does not lock
+ // any resource, later the garbage collector will release the object and it must die by refcount
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/StorageTest.java b/package/qa/storages/StorageTest.java
new file mode 100644
index 000000000000..4691564c23a0
--- /dev/null
+++ b/package/qa/storages/StorageTest.java
@@ -0,0 +1,7 @@
+package complex.storages;
+
+public interface StorageTest
+{
+ boolean test();
+}
+
diff --git a/package/qa/storages/StorageUnitTest.java b/package/qa/storages/StorageUnitTest.java
new file mode 100644
index 000000000000..e5010d86c735
--- /dev/null
+++ b/package/qa/storages/StorageUnitTest.java
@@ -0,0 +1,326 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+package complex.storages;
+
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.connection.XConnector;
+import com.sun.star.connection.XConnection;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.uno.XNamingService;
+import com.sun.star.uno.XComponentContext;
+
+import com.sun.star.container.*;
+import com.sun.star.beans.*;
+import com.sun.star.lang.*;
+
+import complexlib.ComplexTestCase;
+
+import complex.storages.*;
+
+import util.utils;
+import java.util.*;
+import java.io.*;
+
+/* This unit test for storage objects is designed to
+ * test most important statements from storage service
+ * specification.
+ *
+ * Regression tests are added to extend the tested
+ * functionalities.
+ */
+public class StorageUnitTest extends ComplexTestCase
+{
+ private XMultiServiceFactory m_xMSF = null;
+ private XSingleServiceFactory m_xStorageFactory = null;
+
+ public String[] getTestMethodNames()
+ {
+ return new String[] {
+ "ExecuteTest01",
+ "ExecuteTest02",
+ "ExecuteTest03",
+ "ExecuteTest04",
+ "ExecuteTest05",
+ "ExecuteTest06",
+ "ExecuteTest07",
+ "ExecuteTest08",
+ "ExecuteTest09",
+ "ExecuteTest10",
+ "ExecuteTest11",
+ "ExecuteTest12",
+ "ExecuteTest13",
+ "ExecuteTest14",
+ "ExecuteTest15",
+ "ExecuteTest16",
+ "ExecuteTest17",
+ "ExecuteTest18",
+ "ExecuteRegressionTest_114358",
+ "ExecuteRegressionTest_i29169",
+ "ExecuteRegressionTest_i30400",
+ "ExecuteRegressionTest_i29321",
+ "ExecuteRegressionTest_i30677",
+ "ExecuteRegressionTest_i27773",
+ "ExecuteRegressionTest_i46848",
+ "ExecuteRegressionTest_i55821",
+ "ExecuteRegressionTest_i35095",
+ "ExecuteRegressionTest_i49755",
+ "ExecuteRegressionTest_i59886",
+ "ExecuteRegressionTest_i61909",
+ "ExecuteRegressionTest_i84234",
+ "ExecuteRegressionTest_125919"
+ };
+ }
+
+ public String getTestObjectName()
+ {
+ return "StorageUnitTest";
+ }
+
+ public void before()
+ {
+ m_xMSF = (XMultiServiceFactory)param.getMSF();
+ if ( m_xMSF == null )
+ {
+ failed( "Can't create service factory!" );
+ return;
+ }
+
+ try {
+ Object oStorageFactory = m_xMSF.createInstance( "com.sun.star.embed.StorageFactory" );
+ m_xStorageFactory = (XSingleServiceFactory)UnoRuntime.queryInterface( XSingleServiceFactory.class,
+ oStorageFactory );
+ }
+ catch( Exception e )
+ {
+ failed( "Can't create storage factory!" );
+ return;
+ }
+
+ if ( m_xStorageFactory == null )
+ {
+ failed( "Can't create service factory!" );
+ return;
+ }
+ }
+
+ public void ExecuteTest01()
+ {
+ StorageTest aTest = new Test01( m_xMSF, m_xStorageFactory, log );
+ assure( "Test01 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest02()
+ {
+ StorageTest aTest = new Test02( m_xMSF, m_xStorageFactory, log );
+ assure( "Test02 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest03()
+ {
+ StorageTest aTest = new Test03( m_xMSF, m_xStorageFactory, log );
+ assure( "Test03 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest04()
+ {
+ StorageTest aTest = new Test04( m_xMSF, m_xStorageFactory, log );
+ assure( "Test04 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest05()
+ {
+ StorageTest aTest = new Test05( m_xMSF, m_xStorageFactory, log );
+ assure( "Test05 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest06()
+ {
+ StorageTest aTest = new Test06( m_xMSF, m_xStorageFactory, log );
+ assure( "Test06 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest07()
+ {
+ StorageTest aTest = new Test07( m_xMSF, m_xStorageFactory, log );
+ assure( "Test07 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest08()
+ {
+ StorageTest aTest = new Test08( m_xMSF, m_xStorageFactory, log );
+ assure( "Test08 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest09()
+ {
+ StorageTest aTest = new Test09( m_xMSF, m_xStorageFactory, log );
+ assure( "Test09 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest10()
+ {
+ StorageTest aTest = new Test10( m_xMSF, m_xStorageFactory, log );
+ assure( "Test10 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest11()
+ {
+ StorageTest aTest = new Test11( m_xMSF, m_xStorageFactory, log );
+ assure( "Test11 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest12()
+ {
+ StorageTest aTest = new Test12( m_xMSF, m_xStorageFactory, log );
+ assure( "Test12 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest13()
+ {
+ StorageTest aTest = new Test13( m_xMSF, m_xStorageFactory, log );
+ assure( "Test13 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest14()
+ {
+ StorageTest aTest = new Test14( m_xMSF, m_xStorageFactory, log );
+ assure( "Test14 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest15()
+ {
+ StorageTest aTest = new Test15( m_xMSF, m_xStorageFactory, log );
+ assure( "Test15 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest16()
+ {
+ StorageTest aTest = new Test16( m_xMSF, m_xStorageFactory, log );
+ assure( "Test16 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest17()
+ {
+ StorageTest aTest = new Test17( m_xMSF, m_xStorageFactory, log );
+ assure( "Test17 failed!", aTest.test() );
+ }
+
+ public void ExecuteTest18()
+ {
+ StorageTest aTest = new Test18( m_xMSF, m_xStorageFactory, log );
+ assure( "Test18 failed!", aTest.test() );
+ }
+
+ public void ExecuteRegressionTest_114358()
+ {
+ StorageTest aTest = new RegressionTest_114358( m_xMSF, m_xStorageFactory, log );
+ assure( "RegressionTest_114358 failed!", aTest.test() );
+ }
+
+ public void ExecuteRegressionTest_i29169()
+ {
+ StorageTest aTest = new RegressionTest_i29169( m_xMSF, m_xStorageFactory, log );
+ assure( "RegressionTest_i29169 failed!", aTest.test() );
+ }
+
+ public void ExecuteRegressionTest_i30400()
+ {
+ StorageTest aTest = new RegressionTest_i30400( m_xMSF, m_xStorageFactory, log );
+ assure( "RegressionTest_i30400 failed!", aTest.test() );
+ }
+
+ public void ExecuteRegressionTest_i29321()
+ {
+ StorageTest aTest = new RegressionTest_i29321( m_xMSF, m_xStorageFactory, log );
+ assure( "RegressionTest_i29321 failed!", aTest.test() );
+ }
+
+ public void ExecuteRegressionTest_i30677()
+ {
+ StorageTest aTest = new RegressionTest_i30677( m_xMSF, m_xStorageFactory, log );
+ assure( "RegressionTest_i30677 failed!", aTest.test() );
+ }
+
+ public void ExecuteRegressionTest_i27773()
+ {
+ StorageTest aTest = new RegressionTest_i27773( m_xMSF, m_xStorageFactory, log );
+ assure( "RegressionTest_i27773 failed!", aTest.test() );
+ }
+
+ public void ExecuteRegressionTest_i46848()
+ {
+ StorageTest aTest = new RegressionTest_i46848( m_xMSF, m_xStorageFactory, log );
+ assure( "RegressionTest_i46848 failed!", aTest.test() );
+ }
+
+ public void ExecuteRegressionTest_i55821()
+ {
+ StorageTest aTest = new RegressionTest_i55821( m_xMSF, m_xStorageFactory, log );
+ assure( "RegressionTest_i55821 failed!", aTest.test() );
+ }
+
+ public void ExecuteRegressionTest_i35095()
+ {
+ StorageTest aTest = new RegressionTest_i35095( m_xMSF, m_xStorageFactory, log );
+ assure( "RegressionTest_i35095 failed!", aTest.test() );
+ }
+
+ public void ExecuteRegressionTest_i49755()
+ {
+ StorageTest aTest = new RegressionTest_i49755( m_xMSF, m_xStorageFactory, log );
+ assure( "RegressionTest_i49755 failed!", aTest.test() );
+ }
+
+ public void ExecuteRegressionTest_i59886()
+ {
+ StorageTest aTest = new RegressionTest_i59886( m_xMSF, m_xStorageFactory, log );
+ assure( "RegressionTest_i59886 failed!", aTest.test() );
+ }
+
+ public void ExecuteRegressionTest_i61909()
+ {
+ StorageTest aTest = new RegressionTest_i61909( m_xMSF, m_xStorageFactory, log );
+ assure( "RegressionTest_i61909 failed!", aTest.test() );
+ }
+
+ public void ExecuteRegressionTest_i84234()
+ {
+ StorageTest aTest = new RegressionTest_i84234( m_xMSF, m_xStorageFactory, log );
+ assure( "RegressionTest_i84234 failed!", aTest.test() );
+ }
+
+ public void ExecuteRegressionTest_125919()
+ {
+ StorageTest aTest = new RegressionTest_125919( m_xMSF, m_xStorageFactory, log );
+ assure( "RegressionTest_125919 failed!", aTest.test() );
+ }
+}
+
diff --git a/package/qa/storages/Test01.java b/package/qa/storages/Test01.java
new file mode 100644
index 000000000000..a793a2fd5809
--- /dev/null
+++ b/package/qa/storages/Test01.java
@@ -0,0 +1,177 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test01 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test01( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test01: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
+ if ( sTempFileURL == null || sTempFileURL == "" )
+ {
+ m_aTestHelper.Error( "No valid temporary file was created!" );
+ return false;
+ }
+
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ Object oTempStorage = m_xStorageFactory.createInstance();
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBigBytes[] = new byte[33000];
+ for ( int nInd = 0; nInd < 33000; nInd++ )
+ pBigBytes[nInd] = (byte)( nInd % 128 );
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "BigSubStream1", "MediaType1", true, pBigBytes ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "BigSubStream2", "MediaType2", false, pBigBytes ) )
+ return false;
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream2", "MediaType2", false, pBytes2 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType3",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType4",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // create temporary storage based on a previously created temporary file
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) sTempFileURL;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ // copy xTempStorage to xTempFileStorage
+ // xTempFileStorage will be automatically commited
+ if ( !m_aTestHelper.copyStorage( xTempStorage, xTempFileStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) || !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+ // ================================================
+ // now check all the written and copied information
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ pArgs[1] = new Integer( ElementModes.WRITE );
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage, "MediaType3", true, ElementModes.WRITE ) )
+ return false;
+
+ // open existing substorage
+ XStorage xResultSubStorage = m_aTestHelper.openSubStorage( xResultStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xResultSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultSubStorage, "MediaType4", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "BigSubStream1", "MediaType1", true, pBigBytes ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "BigSubStream2", "MediaType2", false, pBigBytes ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream2", "MediaType2", false, pBytes2 ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/storages/Test02.java b/package/qa/storages/Test02.java
new file mode 100644
index 000000000000..668efbe6a509
--- /dev/null
+++ b/package/qa/storages/Test02.java
@@ -0,0 +1,163 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test02 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test02( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test02: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBigBytes[] = new byte[33000];
+ for ( int nInd = 0; nInd < 33000; nInd++ )
+ pBigBytes[nInd] = (byte)( nInd % 128 );
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "BigSubStream1", "MediaType1", true, pBigBytes ) )
+ return false;
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType2",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType3",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // commit substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+
+ // ================================================
+ // now check all the written information
+ // ================================================
+
+ // close the output part of the temporary stream
+ // the output part must present since we already wrote to the stream
+ if ( !m_aTestHelper.closeOutput( xTempFileStream ) )
+ return false;
+
+ XInputStream xTempInStream = m_aTestHelper.getInputStream( xTempFileStream );
+ if ( xTempInStream == null )
+ return false;
+
+
+ // open input stream
+ // since no mode is provided the result storage must be opened readonly
+ Object pOneArg[] = new Object[1];
+ pOneArg[0] = (Object) xTempInStream;
+
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pOneArg );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open storage based on input stream!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage, "MediaType2", true, ElementModes.READ ) )
+ return false;
+
+ // open existing substorage
+ XStorage xResultSubStorage = m_aTestHelper.openSubStorage( xResultStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xResultSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultSubStorage, "MediaType3", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "BigSubStream1", "MediaType1", true, pBigBytes ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/storages/Test03.java b/package/qa/storages/Test03.java
new file mode 100644
index 000000000000..353cd4df8d14
--- /dev/null
+++ b/package/qa/storages/Test03.java
@@ -0,0 +1,231 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.embed.*;
+import com.sun.star.container.XNameAccess;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test03 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test03( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test03: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ Object oTempStorage = m_xStorageFactory.createInstance();
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBigBytes[] = new byte[33000];
+ for ( int nInd = 0; nInd < 33000; nInd++ )
+ pBigBytes[nInd] = (byte)( nInd % 128 );
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempStorage, "BigSubStream1", "MediaType1", true, pBigBytes ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "BigSubStream2", "MediaType2", false, pBigBytes ) )
+ return false;
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream2", "MediaType2", false, pBytes2 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType3",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // ================================================
+ // check storage hyerarchy tree
+ // ================================================
+
+ // check that isStorageElement() and isStreamElement reacts to nonexisting object correctly
+ try {
+ xTempStorage.isStorageElement( "does not exist" );
+ m_aTestHelper.Error( "Nonexisting element doesn't detected by isStorageElement() call!" );
+ return false;
+ }
+ catch( com.sun.star.container.NoSuchElementException ne )
+ {
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Wrong exception is thrown by isStorageElement() call: " + e );
+ return false;
+ }
+
+ try {
+ xTempStorage.isStreamElement( "does not exist" );
+ m_aTestHelper.Error( "Nonexisting element doesn't detected by isStreamElement() call!" );
+ return false;
+ }
+ catch( com.sun.star.container.NoSuchElementException ne )
+ {
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Wrong exception is thrown by isStreamElement() call: " + e );
+ return false;
+ }
+
+ XNameAccess xRootNameAccess = (XNameAccess) UnoRuntime.queryInterface( XNameAccess.class, xTempStorage );
+ if ( xRootNameAccess == null )
+ {
+ m_aTestHelper.Error( "Root storage doesn't support XNameAccess!" );
+ return false;
+ }
+
+ try {
+ if ( !xTempStorage.isStorageElement( "SubStorage1" ) || xTempStorage.isStreamElement( "SubStorage1" ) )
+ {
+ m_aTestHelper.Error( "Child 'SubStorage1' can not be detected as storage!" );
+ return false;
+ }
+
+ if ( xTempStorage.isStorageElement( "SubStream1" ) || !xTempStorage.isStreamElement( "SubStream1" ) )
+ {
+ m_aTestHelper.Error( "Child 'SubStream1' can not be detected as stream!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Child's type can not be detected, exception: " + e );
+ return false;
+ }
+
+
+ // check that root storage contents are represented correctly
+ String sRootCont[] = xRootNameAccess.getElementNames();
+
+ if ( sRootCont.length != 3 )
+ {
+ m_aTestHelper.Error( "Root storage contains wrong amount of children!" );
+ return false;
+ }
+
+ int nFlag = 0;
+ for ( int nInd = 0; nInd < sRootCont.length; nInd++ )
+ {
+ if ( sRootCont[nInd].equals( "SubStorage1" ) )
+ nFlag |= 1;
+ else if ( sRootCont[nInd].equals( "SubStream1" ) )
+ nFlag |= 2;
+ else if ( sRootCont[nInd].equals( "BigSubStream1" ) )
+ nFlag |= 4;
+ }
+
+ if ( nFlag != 7 || !( xRootNameAccess.hasByName( "BigSubStream1" ) && xRootNameAccess.hasByName( "SubStream1" ) && xRootNameAccess.hasByName( "SubStorage1" ) ) )
+ {
+ m_aTestHelper.Error( "Root storage contains wrong list of children!" );
+ return false;
+ }
+
+ // get storage through XNameAccess
+ XStorage xResultSubStorage = getStorageFromNameAccess( xRootNameAccess, "SubStorage1" );
+ if ( xResultSubStorage == null )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultSubStorage, "MediaType3", false, ElementModes.READ ) )
+ return false;
+
+ XNameAccess xChildAccess = (XNameAccess) UnoRuntime.queryInterface( XNameAccess.class, xResultSubStorage );
+ if ( xChildAccess == null )
+ {
+ m_aTestHelper.Error( "Child storage doesn't support XNameAccess!" );
+ return false;
+ }
+
+ if ( !( xChildAccess.hasByName( "SubStream2" ) && xChildAccess.hasByName( "BigSubStream2" ) )
+ || !xResultSubStorage.isStreamElement( "SubStream2" )
+ || !xResultSubStorage.isStreamElement( "BigSubStream2" ) )
+ {
+ m_aTestHelper.Error( "'SubStream2' can not be detected as child stream element of 'SubStorage1'!" );
+ return false;
+ }
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+ public XStorage getStorageFromNameAccess( XNameAccess xAccess, String sName )
+ {
+ try
+ {
+ Object oStorage = xAccess.getByName( sName );
+ XStorage xResult = (XStorage) UnoRuntime.queryInterface( XStorage.class, oStorage );
+
+ if ( xResult != null )
+ return xResult;
+ else
+ m_aTestHelper.Error( "Can't retrieve substorage '" + sName + "' through XNameAccess!" );
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Can't retrieve substorage '" + sName + "' through XNameAccess, exception: " + e );
+ }
+
+ return null;
+ }
+
+}
+
diff --git a/package/qa/storages/Test04.java b/package/qa/storages/Test04.java
new file mode 100644
index 000000000000..81f770f8ff9a
--- /dev/null
+++ b/package/qa/storages/Test04.java
@@ -0,0 +1,307 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+import com.sun.star.lang.DisposedException;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.container.XNameAccess;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test04 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test04( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test04: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
+ if ( sTempFileURL == null || sTempFileURL == "" )
+ {
+ m_aTestHelper.Error( "No valid temporary file was created!" );
+ return false;
+ }
+
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ Object oTempStorage = m_xStorageFactory.createInstance();
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open substorages and create streams there
+
+ // first substorage of the root storage
+ XStorage xTempSubStorage1 = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage1 == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBigBytes[] = new byte[33000];
+ for ( int nInd = 0; nInd < 33000; nInd++ )
+ pBigBytes[nInd] = (byte)( nInd % 128 );
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage1, "BigSubStream1", "MediaType1", true, pBigBytes ) )
+ return false;
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage1, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // second substorage of the root storage
+ XStorage xTempSubStorage2 = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage2",
+ ElementModes.WRITE );
+ if ( xTempSubStorage2 == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage2, "BigSubStream2", "MediaType2", false, pBigBytes ) )
+ return false;
+
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage2, "SubStream2", "MediaType2", false, pBytes2 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType3",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage1,
+ "MediaType4",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage2,
+ "MediaType5",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // create temporary storage based on a previously created temporary file
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) sTempFileURL;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.copyElementTo( xTempStorage, "SubStorage1", xTempFileStorage ) )
+ return false;
+
+ // if storage is not commited before disposing all the changes will be lost
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage2 ) )
+ return false;
+
+ // a storage must be disposed before moving/removing otherwise the access will be denied
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage2 ) )
+ return false;
+
+ if ( !m_aTestHelper.moveElementTo( xTempStorage, "SubStorage2", xTempFileStorage ) )
+ return false;
+
+ // SubStorage2 must be removed and disposed now
+ try
+ {
+ xTempSubStorage2.isStreamElement( "SubStream2" );
+ m_aTestHelper.Error( "SubStorage2 must be disposed already!" );
+ return false;
+ }
+ catch( com.sun.star.lang.DisposedException de )
+ {
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Wrong exception in case of disposed storage, exception: " + e );
+ return false;
+ }
+
+ if ( !m_aTestHelper.copyElementTo( xTempSubStorage1, "SubStream1", xTempFileStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.renameElement( xTempFileStorage, "SubStream1", "SubStream1_copy" ) )
+ return false;
+
+ if ( !m_aTestHelper.moveElementTo( xTempSubStorage1, "SubStream1", xTempFileStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.copyElementTo( xTempSubStorage1, "BigSubStream1", xTempFileStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.renameElement( xTempFileStorage, "BigSubStream1", "BigSubStream1_copy" ) )
+ return false;
+
+ if ( !m_aTestHelper.moveElementTo( xTempSubStorage1, "BigSubStream1", xTempFileStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xTempFileStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) || !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+ // ================================================
+ // now check all the written and copied information
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ pArgs[1] = new Integer( ElementModes.WRITE );
+ Object oResStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xResStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResStorage );
+ if ( xResStorage == null )
+ {
+ m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
+ return false;
+ }
+
+ // open and check SubStorage1
+ XStorage xResSubStorage1 = m_aTestHelper.openSubStorage( xResStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xResSubStorage1 == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResSubStorage1, "MediaType4", false, ElementModes.READ ) )
+ return false;
+
+
+ // open and check SubStorage2
+ XStorage xResSubStorage2 = m_aTestHelper.openSubStorage( xResStorage,
+ "SubStorage2",
+ ElementModes.READ );
+ if ( xResSubStorage2 == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResSubStorage2, "MediaType5", false, ElementModes.READ ) )
+ return false;
+
+
+ // check all the result streams
+
+ if ( !m_aTestHelper.checkStream( xResStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResStorage, "BigSubStream1", "MediaType1", true, pBigBytes ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResStorage, "SubStream1_copy", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResStorage, "BigSubStream1_copy", "MediaType1", true, pBigBytes ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResSubStorage1, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResSubStorage1, "BigSubStream1", "MediaType1", true, pBigBytes ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResSubStorage2, "SubStream2", "MediaType2", false, pBytes2 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResSubStorage2, "BigSubStream2", "MediaType2", false, pBigBytes ) )
+ return false;
+
+ // the storage must be disposed before removing
+ if ( !m_aTestHelper.disposeStorage( xResSubStorage2 ) )
+ return false;
+
+ // remove element and check that it was removed completelly
+ if ( !m_aTestHelper.removeElement( xResStorage, "SubStorage2" ) )
+ return false;
+
+ try
+ {
+ XNameAccess xResAccess = (XNameAccess) UnoRuntime.queryInterface( XNameAccess.class, xResStorage );
+ if ( xResAccess.hasByName( "SubStorage2" ) )
+ m_aTestHelper.Error( "SubStorage2 must be removed already!" );
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Can't get access to root storage, exception: " + e );
+ return false;
+ }
+
+ try
+ {
+ xResSubStorage2.isStreamElement( "SubStream2" );
+
+ m_aTestHelper.Error( "SubStorage2 must be disposed already!" );
+ return false;
+ }
+ catch( com.sun.star.lang.DisposedException de )
+ {
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Wrong exception in case of disposed storage, exception: " + e );
+ return false;
+ }
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/storages/Test05.java b/package/qa/storages/Test05.java
new file mode 100644
index 000000000000..adf943c6ef12
--- /dev/null
+++ b/package/qa/storages/Test05.java
@@ -0,0 +1,299 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test05 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test05( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test05: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
+ if ( sTempFileURL == null || sTempFileURL == "" )
+ {
+ m_aTestHelper.Error( "No valid temporary file was created!" );
+ return false;
+ }
+
+ // create temporary storage based on a previously created temporary file
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) sTempFileURL;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempFileStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xSubSubStorage = m_aTestHelper.openSubStorage( xTempSubStorage,
+ "SubSubStorage1",
+ ElementModes.WRITE );
+ if ( xSubSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBigBytes[] = new byte[33000];
+ for ( int nInd = 0; nInd < 33000; nInd++ )
+ pBigBytes[nInd] = (byte)( nInd % 128 );
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xSubSubStorage, "BigSubStream1", "MediaType1", true, pBigBytes ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xSubSubStorage, "BigSubStream2", "MediaType2", false, pBigBytes ) )
+ return false;
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xSubSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xSubSubStorage, "SubStream2", "MediaType2", false, pBytes2 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempFileStorage,
+ "MediaType3",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType4",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xSubSubStorage,
+ "MediaType5",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+
+ // commit all the storages
+ if ( !m_aTestHelper.commitStorage( xSubSubStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.commitStorage( xTempFileStorage ) )
+ return false;
+
+ // try to open an opened substorage, open call must fail
+ if ( !m_aTestHelper.cantOpenStorage( xTempFileStorage, "SubStorage1" ) )
+ return false;
+
+
+ // reopen created streams
+ XStream xSubStream1 = m_aTestHelper.OpenStream( xSubSubStorage,
+ "SubStream1",
+ ElementModes.WRITE | ElementModes.NOCREATE );
+ XStream xBigSubStream1 = m_aTestHelper.OpenStream( xSubSubStorage,
+ "BigSubStream1",
+ ElementModes.WRITE | ElementModes.NOCREATE );
+ XStream xSubStream2 = m_aTestHelper.OpenStream( xSubSubStorage,
+ "SubStream2",
+ ElementModes.READ | ElementModes.NOCREATE );
+ XStream xBigSubStream2 = m_aTestHelper.OpenStream( xSubSubStorage,
+ "BigSubStream2",
+ ElementModes.READ | ElementModes.NOCREATE );
+
+ if ( xSubStream1 == null || xBigSubStream1 == null || xSubStream2 == null || xBigSubStream2 == null )
+ return false;
+
+ // it should be possible to have more then one copy of stream for reading
+ XStream xSubStream2clone = m_aTestHelper.OpenStream( xSubSubStorage,
+ "SubStream2",
+ ElementModes.READ | ElementModes.NOCREATE );
+ XStream xBigSubStream2clone = m_aTestHelper.OpenStream( xSubSubStorage,
+ "BigSubStream2",
+ ElementModes.READ | ElementModes.NOCREATE );
+ if ( xSubStream2clone == null || xBigSubStream2clone == null )
+ return false;
+
+
+ // so now the first streams can not be open neither for reading nor for writing
+ if ( !m_aTestHelper.cantOpenStream( xSubSubStorage, "SubStream1", ElementModes.WRITE )
+ || !m_aTestHelper.cantOpenStream( xSubSubStorage, "SubStream1", ElementModes.READ )
+ || !m_aTestHelper.cantOpenStream( xSubSubStorage, "BigSubStream1", ElementModes.WRITE )
+ || !m_aTestHelper.cantOpenStream( xSubSubStorage, "BigSubStream1", ElementModes.READ ) )
+ return false;
+
+ // the second streams can not be open for writing
+ if ( !m_aTestHelper.cantOpenStream( xSubSubStorage, "SubStream2", ElementModes.WRITE )
+ || !m_aTestHelper.cantOpenStream( xSubSubStorage, "BigSubStream2", ElementModes.WRITE ) )
+ return false;
+
+
+ // dispose xTestSubStorage, all the subtree must be disposed
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // check that subtree was disposed correctly
+ try
+ {
+ xSubSubStorage.isStreamElement( "SubStream1" );
+ m_aTestHelper.Error( "Substorage was not disposed!" );
+ return false;
+ }
+ catch ( com.sun.star.lang.DisposedException de )
+ {}
+ catch ( Exception e )
+ {
+ m_aTestHelper.Error( "Wrong exception is thrown by disposed storage: " + e );
+ return false;
+ }
+
+ try
+ {
+ xSubStream1.getInputStream();
+ m_aTestHelper.Error( "Writeable substream was not disposed!" );
+ return false;
+ }
+ catch ( com.sun.star.lang.DisposedException de )
+ {}
+ catch ( Exception e )
+ {
+ m_aTestHelper.Error( "Wrong exception is thrown by disposed stream: " + e );
+ return false;
+ }
+
+ try
+ {
+ xSubStream2.getInputStream();
+ m_aTestHelper.Error( "Readonly substream was not disposed!" );
+ return false;
+ }
+ catch ( com.sun.star.lang.DisposedException de )
+ {}
+ catch ( Exception e )
+ {
+ m_aTestHelper.Error( "Wrong exception is thrown by disposed stream: " + e );
+ return false;
+ }
+
+
+ // dispose root storage
+ if ( !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+
+ // ================================================
+ // now check all the written and copied information
+ // ================================================
+
+ pArgs[1] = new Integer( ElementModes.READ );
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage, "MediaType3", true, ElementModes.READ ) )
+ return false;
+
+ // open existing substorage
+ XStorage xResSubStorage = m_aTestHelper.openSubStorage( xResultStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xResSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage 'SubSubStorage'!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResSubStorage, "MediaType4", false, ElementModes.READ ) )
+ return false;
+
+ // open existing substorage
+ XStorage xResSubSubStorage = m_aTestHelper.openSubStorage( xResSubStorage,
+ "SubSubStorage1",
+ ElementModes.READ );
+ if ( xResSubSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage 'SubSubStorage'!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResSubSubStorage, "MediaType5", false, ElementModes.READ ) )
+ return false;
+
+ // check substreams
+ if ( !m_aTestHelper.checkStream( xResSubSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResSubSubStorage, "BigSubStream1", "MediaType1", true, pBigBytes ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResSubSubStorage, "SubStream2", "MediaType2", false, pBytes2 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResSubSubStorage, "BigSubStream2", "MediaType2", false, pBigBytes ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/storages/Test06.java b/package/qa/storages/Test06.java
new file mode 100644
index 000000000000..ef42c66335a5
--- /dev/null
+++ b/package/qa/storages/Test06.java
@@ -0,0 +1,279 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.container.NoSuchElementException;
+import com.sun.star.container.ElementExistException;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test06 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test06( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test06: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ Object oTempStorage = m_xStorageFactory.createInstance();
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ try
+ {
+ xTempStorage.copyToStorage( null );
+ m_aTestHelper.Error( "The method must throw an exception because of illegal parameter!" );
+ return false;
+ }
+ catch( com.sun.star.lang.IllegalArgumentException iae )
+ {}
+ catch( com.sun.star.uno.Exception ue )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion because of illegal parameter : " + e );
+ return false;
+ }
+
+ // open new substorages
+ XStorage xTempSubStorage1 = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ XStorage xTempSubStorage2 = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage2",
+ ElementModes.WRITE );
+ if ( xTempSubStorage1 == null || xTempSubStorage2 == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // in case stream is open for reading it must exist
+ try
+ {
+ xTempSubStorage1.openStreamElement( "NonExistingStream", ElementModes.READ );
+ m_aTestHelper.Error( "The method must throw an exception in case of try to open nonexistent stream for reading!" );
+ return false;
+ }
+ catch( com.sun.star.uno.Exception ue )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case of try to open nonexistent stream for reading : " + e );
+ return false;
+ }
+
+ // in case a storage is open for reading it must exist
+ try
+ {
+ xTempSubStorage1.openStreamElement( "NonExistingStorage", ElementModes.READ );
+ m_aTestHelper.Error( "The method must throw an exception in case of try to open nonexistent storage for reading!" );
+ return false;
+ }
+ catch( com.sun.star.uno.Exception ue )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case of try to open nonexistent storage for reading : " + e );
+ return false;
+ }
+
+ // in case of removing nonexistent element an exception must be thrown
+ try
+ {
+ xTempSubStorage1.removeElement( "NonExistingElement" );
+ m_aTestHelper.Error( "An exception must be thrown in case of removing nonexistent element!" );
+ return false;
+ }
+ catch( com.sun.star.container.NoSuchElementException ne )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case of try to remove nonexistent element : " + e );
+ return false;
+ }
+
+ // in case of renaming of nonexistent element an exception must be thrown
+ try
+ {
+ xTempSubStorage1.renameElement( "NonExistingElement", "NewName" );
+ m_aTestHelper.Error( "An exception must be thrown in case of renaming nonexistent element!" );
+ return false;
+ }
+ catch( com.sun.star.container.NoSuchElementException ne )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case of try to rename nonexistent element : " + e );
+ return false;
+ }
+
+ // in case of renaming to a name of existent element an exception must be thrown
+ try
+ {
+ xTempStorage.renameElement( "SubStorage1", "SubStorage2" );
+ m_aTestHelper.Error( "An exception must be thrown in case of renaming to the name of existent element!" );
+ return false;
+ }
+ catch( com.sun.star.container.ElementExistException ee )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case of try to rename to the name of existent element : " + e );
+ return false;
+ }
+
+ // in case of copying target storage must be provided
+ try
+ {
+ xTempStorage.copyElementTo( "SubStorage1", null, "SubStorage1" );
+ m_aTestHelper.Error( "An exception must be thrown in case empty reference is provided as target for copying!" );
+ return false;
+ }
+ catch( com.sun.star.lang.IllegalArgumentException iae )
+ {}
+ catch( com.sun.star.uno.Exception ue )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case empty reference is provieded as target for copying : " + e );
+ return false;
+ }
+
+ // in case of moving target storage must be provided
+ try
+ {
+ xTempStorage.moveElementTo( "SubStorage1", null, "SubStorage1" );
+ m_aTestHelper.Error( "An exception must be thrown in case empty reference is provided as target for moving!" );
+ return false;
+ }
+ catch( com.sun.star.lang.IllegalArgumentException iae )
+ {}
+ catch( com.sun.star.uno.Exception ue )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case empty reference is provieded as target for moving : " + e );
+ return false;
+ }
+
+
+ // prepare target for further testings
+
+ // create new temporary storage based on arbitrary medium
+ Object oTargetStorage = m_xStorageFactory.createInstance();
+ XStorage xTargetStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTargetStorage );
+ if ( xTargetStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTargetSubStorage = m_aTestHelper.openSubStorage( xTargetStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTargetSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // in case of copying of nonexistent element an exception must be thrown
+ try
+ {
+ xTempStorage.copyElementTo( "Nonexistent element", xTargetStorage, "Target" );
+ m_aTestHelper.Error( "An exception must be thrown in case of copying of nonexisting element!" );
+ return false;
+ }
+ catch( com.sun.star.container.NoSuchElementException ne )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case of copying of nonexistent element: " + e );
+ return false;
+ }
+
+ // in case of moving of nonexistent element an exception must be thrown
+ try
+ {
+ xTempStorage.moveElementTo( "Nonexistent element", xTargetStorage, "Target" );
+ m_aTestHelper.Error( "An exception must be thrown in case of moving of nonexisting element!" );
+ return false;
+ }
+ catch( com.sun.star.container.NoSuchElementException ne )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case of moving of nonexistent element: " + e );
+ return false;
+ }
+
+ // in case target for copying already exists an exception must be thrown
+ try
+ {
+ xTempStorage.copyElementTo( "SubStorage1", xTargetStorage, "SubStorage1" );
+ m_aTestHelper.Error( "An exception must be thrown in case target for copying already exists!" );
+ return false;
+ }
+ catch( com.sun.star.container.ElementExistException ee )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case target for copying already exists: " + e );
+ return false;
+ }
+
+ // in case target for moving already exists an exception must be thrown
+ try
+ {
+ xTempStorage.moveElementTo( "SubStorage1", xTargetStorage, "SubStorage1" );
+ m_aTestHelper.Error( "An exception must be thrown in case target for moving already exists!" );
+ return false;
+ }
+ catch( com.sun.star.container.ElementExistException ee )
+ {}
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Unexpected excepion in case target for moving already exists: " + e );
+ return false;
+ }
+
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/storages/Test07.java b/package/qa/storages/Test07.java
new file mode 100644
index 000000000000..970c6f13ec09
--- /dev/null
+++ b/package/qa/storages/Test07.java
@@ -0,0 +1,162 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test07 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test07( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test07: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
+ if ( sTempFileURL == null || sTempFileURL == "" )
+ {
+ m_aTestHelper.Error( "No valid temporary file was created!" );
+ return false;
+ }
+
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ Object oTempStorage = m_xStorageFactory.createInstance();
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ byte pBigBytes[] = new byte[33000];
+ for ( int nInd = 0; nInd < 33000; nInd++ )
+ pBigBytes[nInd] = (byte)( nInd % 128 );
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+ String sPass1 = "12345";
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempStorage, "BigSubStream1", "MediaType1", true, pBigBytes, sPass1 ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempStorage, "SubStream1", "MediaType1", true, pBytes1, sPass1 ) )
+ return false;
+
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+ String sPass2 = "54321";
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempStorage, "BigSubStream2", "MediaType2", false, pBigBytes, sPass2 ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempStorage, "SubStream2", "MediaType2", false, pBytes2, sPass2 ) )
+ return false;
+
+ // create temporary storage based on a previously created temporary file
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) sTempFileURL;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ // copy xTempStorage to xTempFileStorage
+ // xTempFileStorage will be automatically commited
+ if ( !m_aTestHelper.copyStorage( xTempStorage, xTempFileStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) || !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+ // ================================================
+ // now check all the written and copied information
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ pArgs[1] = new Integer( ElementModes.WRITE );
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
+ return false;
+ }
+
+ Object o2CopyStorage = m_xStorageFactory.createInstance();
+ XStorage x2CopyStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, o2CopyStorage );
+ if ( x2CopyStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.copyStorage( xResultStorage, x2CopyStorage ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( xResultStorage, "SubStream1", "MediaType1", pBytes1, sPass1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( xResultStorage, "BigSubStream1", "MediaType1", pBigBytes, sPass1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( xResultStorage, "SubStream2", "MediaType2", pBytes2, sPass2 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( xResultStorage, "BigSubStream2", "MediaType2", pBigBytes, sPass2 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( x2CopyStorage, "SubStream1", "MediaType1", pBytes1, sPass1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( x2CopyStorage, "BigSubStream1", "MediaType1", pBigBytes, sPass1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( x2CopyStorage, "SubStream2", "MediaType2", pBytes2, sPass2 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( x2CopyStorage, "BigSubStream2", "MediaType2", pBigBytes, sPass2 ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/storages/Test08.java b/package/qa/storages/Test08.java
new file mode 100644
index 000000000000..5e024db588c8
--- /dev/null
+++ b/package/qa/storages/Test08.java
@@ -0,0 +1,230 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test08 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test08( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test08: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ Object oTempStorage = m_xStorageFactory.createInstance();
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // set the global password for the root storage
+ XEncryptionProtectedSource xTempStorageEncryption =
+ (XEncryptionProtectedSource) UnoRuntime.queryInterface( XEncryptionProtectedSource.class, xTempStorage );
+
+ if ( xTempStorageEncryption == null )
+ {
+ m_aTestHelper.Message( "Optional interface XEncryptionProtectedSource is not implemented, feature can not be tested!" );
+ return true;
+ }
+
+ String sPass1 = "123";
+ String sPass2 = "321";
+
+ try {
+ xTempStorageEncryption.setEncryptionPassword( sPass1 );
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Can't set a common encryption key for the storage, exception:" + e );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBigBytes[] = new byte[33000];
+ for ( int nInd = 0; nInd < 33000; nInd++ )
+ pBigBytes[nInd] = (byte)( nInd % 128 );
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ // the stream will be encrypted with common password
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+ if ( !m_aTestHelper.WBToSubstrOfEncr( xTempSubStorage, "SubStream1", "MediaType1", true, pBytes1, true ) )
+ return false;
+ if ( !m_aTestHelper.WBToSubstrOfEncr( xTempSubStorage, "BigSubStream1", "MediaType1", true, pBigBytes, true ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ // the stream will not be encrypted
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+ if ( !m_aTestHelper.WBToSubstrOfEncr( xTempSubStorage, "SubStream2", "MediaType2", false, pBytes2, false ) )
+ return false;
+ if ( !m_aTestHelper.WBToSubstrOfEncr( xTempSubStorage, "BigSubStream2", "MediaType2", false, pBigBytes, false ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ // the stream will be compressed with own password
+ byte pBytes3[] = { 3, 3, 3, 3, 3 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ // the stream will not be encrypted
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempSubStorage, "SubStream3", "MediaType3", false, pBytes3, sPass2 ) )
+ return false;
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempSubStorage, "BigSubStream3", "MediaType3", false, pBigBytes, sPass2 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType4",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType5",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // create temporary file
+ String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
+ if ( sTempFileURL == null || sTempFileURL == "" )
+ {
+ m_aTestHelper.Error( "No valid temporary file was created!" );
+ return false;
+ }
+
+ // create temporary storage based on a previously created temporary file
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) sTempFileURL;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ // copy xTempStorage to xTempFileStorage
+ // xTempFileStorage will be automatically commited
+ if ( !m_aTestHelper.copyStorage( xTempStorage, xTempFileStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) || !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+ // ================================================
+ // now check all the written and copied information
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ pArgs[1] = new Integer( ElementModes.READ );
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage, "MediaType4", true, ElementModes.READ ) )
+ return false;
+
+ // open existing substorage
+ XStorage xResultSubStorage = m_aTestHelper.openSubStorage( xResultStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xResultSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultSubStorage, "MediaType5", false, ElementModes.READ ) )
+ return false;
+
+ // set the global password for the root storage
+ XEncryptionProtectedSource xResultStorageEncryption =
+ (XEncryptionProtectedSource) UnoRuntime.queryInterface( XEncryptionProtectedSource.class, xResultStorage );
+
+ if ( xResultStorageEncryption == null )
+ {
+ m_aTestHelper.Error( "XEncryptionProtectedSource was successfully used already, so it must be supported!" );
+ return false;
+ }
+
+ try {
+ xResultStorageEncryption.setEncryptionPassword( sPass2 );
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Can't set a common encryption key for the storage, exception:" + e );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkEncrStream( xResultSubStorage, "SubStream1", "MediaType1", pBytes1, sPass1 ) )
+ return false;
+ if ( !m_aTestHelper.checkEncrStream( xResultSubStorage, "BigSubStream1", "MediaType1", pBigBytes, sPass1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream2", "MediaType2", false, pBytes2 ) )
+ return false;
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "BigSubStream2", "MediaType2", false, pBigBytes ) )
+ return false;
+
+ // the common root storage password should allow to open this stream
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream3", "MediaType3", true, pBytes3 ) )
+ return false;
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "BigSubStream3", "MediaType3", true, pBigBytes ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/Test09.java b/package/qa/storages/Test09.java
new file mode 100644
index 000000000000..2ce2dfb1e484
--- /dev/null
+++ b/package/qa/storages/Test09.java
@@ -0,0 +1,138 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test09 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test09( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test09: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ Object oTempStorage = m_xStorageFactory.createInstance();
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ String sPass1 = "123";
+ String sPass2 = "321";
+ byte pBytes[] = { 1, 1, 1, 1, 1 };
+ byte pBigBytes[] = new byte[33000];
+ for ( int nInd = 0; nInd < 33000; nInd++ )
+ pBigBytes[nInd] = (byte)( nInd % 128 );
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ // the stream will not be encrypted
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempStorage, "SubStream1", "MediaType1", false, pBytes, sPass1 ) )
+ return false;
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempStorage, "BigSubStream1", "MediaType1", false, pBigBytes, sPass1 ) )
+ return false;
+
+ // create temporary file
+ String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
+ if ( sTempFileURL == null || sTempFileURL == "" )
+ {
+ m_aTestHelper.Error( "No valid temporary file was created!" );
+ return false;
+ }
+
+ // create temporary storage based on a previously created temporary file
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) sTempFileURL;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ // copy xTempStorage to xTempFileStorage
+ // xTempFileStorage will be automatically commited
+ if ( !m_aTestHelper.copyStorage( xTempStorage, xTempFileStorage ) )
+ return false;
+
+ // change password of the substream of new storage based on file
+ int nResult = m_aTestHelper.ChangeStreamPass( xTempFileStorage, "SubStream1", sPass1, sPass2 );
+ if ( nResult == 0 )
+ return false; // test failed
+ else if ( nResult == -1 )
+ return true; // tested optional feature is not supported
+
+ // change password of the substream of new storage based on file
+ nResult = m_aTestHelper.ChangeStreamPass( xTempFileStorage, "BigSubStream1", sPass1, sPass2 );
+ if ( nResult == 0 )
+ return false; // test failed
+ else if ( nResult == -1 )
+ return true; // tested optional feature is not supported
+
+ if ( !m_aTestHelper.commitStorage( xTempFileStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) || !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+ // ================================================
+ // now check all the written and copied information
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ pArgs[1] = new Integer( ElementModes.READ );
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkEncrStream( xResultStorage, "SubStream1", "MediaType1", pBytes, sPass2 ) )
+ return false;
+ if ( !m_aTestHelper.checkEncrStream( xResultStorage, "BigSubStream1", "MediaType1", pBigBytes, sPass2 ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/Test10.java b/package/qa/storages/Test10.java
new file mode 100644
index 000000000000..162daa5abe29
--- /dev/null
+++ b/package/qa/storages/Test10.java
@@ -0,0 +1,232 @@
+package complex.storages;
+
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.container.XNameAccess;
+import com.sun.star.io.XStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test10 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test10( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test10: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ Object oTempStorage = m_xStorageFactory.createInstance();
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ byte pBigBytes[] = new byte[33000];
+ for ( int nInd = 0; nInd < 33000; nInd++ )
+ pBigBytes[nInd] = (byte)( nInd % 128 );
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempStorage, "BigSubStream1", "MediaType1", true, pBigBytes ) )
+ return false;
+
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream2", "MediaType2", true, pBytes2 ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "BigSubStream2", "MediaType2", true, pBigBytes ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType3",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType4",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // ==============================
+ // check cloning at current state
+ // ==============================
+
+ // the new storage still was not commited so the clone must be empty
+ XStorage xClonedSubStorage = m_aTestHelper.cloneSubStorage( m_xStorageFactory, xTempStorage, "SubStorage1" );
+
+ if ( xClonedSubStorage == null )
+ {
+ m_aTestHelper.Error( "The result of clone is empty!" );
+ return false;
+ }
+
+ XNameAccess xClonedNameAccess = (XNameAccess) UnoRuntime.queryInterface( XNameAccess.class, xClonedSubStorage );
+ if ( xClonedNameAccess == null )
+ {
+ m_aTestHelper.Error( "XNameAccess is not implemented by the clone!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xClonedSubStorage, "", true, ElementModes.WRITE ) )
+ return false;
+
+ if ( xClonedNameAccess.hasElements() )
+ {
+ m_aTestHelper.Error( "The new substorage still was not commited so it must be empty!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.disposeStorage( xClonedSubStorage ) )
+ return false;
+
+ xClonedSubStorage = null;
+ xClonedNameAccess = null;
+
+ // the new stream was opened, written and closed, that means flashed
+ // so the clone must contain all the information
+ XStream xClonedSubStream = m_aTestHelper.cloneSubStream( xTempStorage, "SubStream1" );
+ if ( !m_aTestHelper.InternalCheckStream( xClonedSubStream, "SubStream1", "MediaType1", true, pBytes1, true ) )
+ return false;
+
+ XStream xClonedBigSubStream = m_aTestHelper.cloneSubStream( xTempStorage, "BigSubStream1" );
+ if ( !m_aTestHelper.InternalCheckStream( xClonedBigSubStream, "BigSubStream1", "MediaType1", true, pBigBytes, true ) )
+ return false;
+
+ if ( !m_aTestHelper.disposeStream( xClonedSubStream, "SubStream1" ) )
+ return false;
+
+ if ( !m_aTestHelper.disposeStream( xClonedBigSubStream, "BigSubStream1" ) )
+ return false;
+
+ // ==============================
+ // commit substorage and check cloning
+ // ==============================
+
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ xClonedSubStorage = m_aTestHelper.cloneSubStorage( m_xStorageFactory, xTempStorage, "SubStorage1" );
+ if ( xClonedSubStorage == null )
+ {
+ m_aTestHelper.Error( "The result of clone is empty!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xClonedSubStorage, "MediaType4", true, ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xClonedSubStorage, "SubStream2", "MediaType2", true, pBytes2 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xClonedSubStorage, "BigSubStream2", "MediaType2", true, pBigBytes ) )
+ return false;
+
+ XStorage xCloneOfRoot = m_aTestHelper.cloneStorage( m_xStorageFactory, xTempStorage );
+ if ( xCloneOfRoot == null )
+ {
+ m_aTestHelper.Error( "The result of root clone is empty!" );
+ return false;
+ }
+
+ XNameAccess xCloneOfRootNA = (XNameAccess) UnoRuntime.queryInterface( XNameAccess.class, xCloneOfRoot );
+ if ( xCloneOfRootNA == null )
+ {
+ m_aTestHelper.Error( "XNameAccess is not implemented by the root clone!" );
+ return false;
+ }
+
+ if ( xCloneOfRootNA.hasElements() )
+ {
+ m_aTestHelper.Error( "The root storage still was not commited so it's clone must be empty!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.disposeStorage( xCloneOfRoot ) )
+ return false;
+
+ xCloneOfRoot = null;
+
+ // ==============================
+ // commit root storage and check cloning
+ // ==============================
+
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ xCloneOfRoot = m_aTestHelper.cloneStorage( m_xStorageFactory, xTempStorage );
+ if ( xCloneOfRoot == null )
+ {
+ m_aTestHelper.Error( "The result of root clone is empty!" );
+ return false;
+ }
+
+ XStorage xSubStorageOfClone = xCloneOfRoot.openStorageElement( "SubStorage1", ElementModes.READ );
+ if ( xSubStorageOfClone == null )
+ {
+ m_aTestHelper.Error( "The result of root clone is wrong!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xSubStorageOfClone, "MediaType4", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xSubStorageOfClone, "SubStream2", "MediaType2", true, pBytes2 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xSubStorageOfClone, "BigSubStream2", "MediaType2", true, pBigBytes ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/Test11.java b/package/qa/storages/Test11.java
new file mode 100644
index 000000000000..198fa41fe588
--- /dev/null
+++ b/package/qa/storages/Test11.java
@@ -0,0 +1,218 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.container.XNameAccess;
+import com.sun.star.io.XStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test11 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test11( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test11: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ Object oTempStorage = m_xStorageFactory.createInstance();
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ byte pBigBytes[] = new byte[33000];
+ for ( int nInd = 0; nInd < 33000; nInd++ )
+ pBigBytes[nInd] = (byte)( nInd % 128 );
+
+ String sPass1 = "111111111";
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempStorage, "SubStream1", "MediaType1", true, pBytes1, sPass1 ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempStorage, "BigSubStream1", "MediaType1", true, pBigBytes, sPass1 ) )
+ return false;
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ String sPass2 = "2222222222";
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempSubStorage, "SubStream2", "MediaType2", true, pBytes2, sPass2 ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempSubStorage, "BigSubStream2", "MediaType2", true, pBigBytes, sPass2 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType3",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType4",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // ==============================
+ // check cloning at current state
+ // ==============================
+
+ // the new storage still was not commited so the clone must be empty
+ XStorage xClonedSubStorage = m_aTestHelper.cloneSubStorage( m_xStorageFactory, xTempStorage, "SubStorage1" );
+
+ if ( xClonedSubStorage == null )
+ {
+ m_aTestHelper.Error( "The result of clone is empty!" );
+ return false;
+ }
+
+ XNameAccess xClonedNameAccess = (XNameAccess) UnoRuntime.queryInterface( XNameAccess.class, xClonedSubStorage );
+ if ( xClonedNameAccess == null )
+ {
+ m_aTestHelper.Error( "XNameAccess is not implemented by the clone!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xClonedSubStorage, "", true, ElementModes.WRITE ) )
+ return false;
+
+ if ( xClonedNameAccess.hasElements() )
+ {
+ m_aTestHelper.Error( "The new substorage still was not commited so it must be empty!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.disposeStorage( xClonedSubStorage ) )
+ return false;
+
+ xClonedSubStorage = null;
+ xClonedNameAccess = null;
+
+ // the new stream was opened, written and closed, that means flashed
+ // so the clone must contain all the information
+ XStream xClonedSubStream = m_aTestHelper.cloneEncrSubStream( xTempStorage, "SubStream1", sPass1 );
+ if ( !m_aTestHelper.InternalCheckStream( xClonedSubStream, "SubStream1", "MediaType1", true, pBytes1, true ) )
+ return false;
+
+ XStream xClonedBigSubStream = m_aTestHelper.cloneEncrSubStream( xTempStorage, "BigSubStream1", sPass1 );
+ if ( !m_aTestHelper.InternalCheckStream( xClonedBigSubStream, "BigSubStream1", "MediaType1", true, pBigBytes, true ) )
+ return false;
+
+ if ( !m_aTestHelper.disposeStream( xClonedSubStream, "SubStream1" ) )
+ return false;
+
+ if ( !m_aTestHelper.disposeStream( xClonedBigSubStream, "BigSubStream1" ) )
+ return false;
+
+ // ==============================
+ // commit substorage and check cloning
+ // ==============================
+
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ xClonedSubStorage = m_aTestHelper.cloneSubStorage( m_xStorageFactory, xTempStorage, "SubStorage1" );
+ if ( xClonedSubStorage == null )
+ {
+ m_aTestHelper.Error( "The result of clone is empty!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xClonedSubStorage, "MediaType4", true, ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( xClonedSubStorage, "SubStream2", "MediaType2", pBytes2, sPass2 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( xClonedSubStorage, "BigSubStream2", "MediaType2", pBigBytes, sPass2 ) )
+ return false;
+
+ // ==============================
+ // commit the root storage and check cloning
+ // ==============================
+
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ XStorage xCloneOfRoot = m_aTestHelper.cloneStorage( m_xStorageFactory, xTempStorage );
+ if ( xCloneOfRoot == null )
+ {
+ m_aTestHelper.Error( "The result of root clone is empty!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xCloneOfRoot, "MediaType3", true, ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( xCloneOfRoot, "SubStream1", "MediaType1", pBytes1, sPass1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( xCloneOfRoot, "BigSubStream1", "MediaType1", pBigBytes, sPass1 ) )
+ return false;
+
+ XStorage xSubStorageOfClone = xCloneOfRoot.openStorageElement( "SubStorage1", ElementModes.READ );
+ if ( xSubStorageOfClone == null )
+ {
+ m_aTestHelper.Error( "The result of root clone is wrong!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xSubStorageOfClone, "MediaType4", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( xSubStorageOfClone, "SubStream2", "MediaType2", pBytes2, sPass2 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStream( xSubStorageOfClone, "BigSubStream2", "MediaType2", pBigBytes, sPass2 ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+}
+
diff --git a/package/qa/storages/Test12.java b/package/qa/storages/Test12.java
new file mode 100644
index 000000000000..05928cf76b0d
--- /dev/null
+++ b/package/qa/storages/Test12.java
@@ -0,0 +1,240 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test12 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test12( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test12: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBigBytes[] = new byte[33000];
+ for ( int nInd = 0; nInd < 33000; nInd++ )
+ pBigBytes[nInd] = (byte)( nInd % 128 );
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "BigSubStream1", "MediaType1", true, pBigBytes ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType2",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType3",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // commit substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose substorage
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+
+ // ================================================
+ // check substorage
+ // ================================================
+
+ if ( !checkSubStorages( xTempStorage, pBytes1, pBigBytes ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+ // ================================================
+ // now check all the written information with readwrite access
+ // ================================================
+
+ Object oResWriteStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xResWriteStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResWriteStorage );
+ if ( xResWriteStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open storage based on input stream!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResWriteStorage, "MediaType2", true, ElementModes.WRITE ) )
+ return false;
+
+ if( !checkSubStorages( xResWriteStorage, pBytes1, pBigBytes ) )
+ return false;
+
+ // try to open for writing after opening for reading
+ XStorage xResWSubStorage = m_aTestHelper.openSubStorage( xResWriteStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xResWSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open substorage for writing after it was opened for reading!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResWSubStorage, "MediaType3", false, ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResWSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResWSubStorage, "BigSubStream1", "MediaType1", true, pBigBytes ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xResWriteStorage ) )
+ return false;
+
+
+ // ================================================
+ // now check all the written information with readonly access
+ // ================================================
+
+ // close the output part of the temporary stream
+ // the output part must present since we already wrote to the stream
+ if ( !m_aTestHelper.closeOutput( xTempFileStream ) )
+ return false;
+
+ XInputStream xTempInStream = m_aTestHelper.getInputStream( xTempFileStream );
+ if ( xTempInStream == null )
+ return false;
+
+ // open input stream
+ // since no mode is provided the result storage must be opened readonly
+ Object pOneArg[] = new Object[1];
+ pOneArg[0] = (Object) xTempInStream;
+
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pOneArg );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open storage based on input stream!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage, "MediaType2", true, ElementModes.READ ) )
+ return false;
+
+ if( !checkSubStorages( xResultStorage, pBytes1, pBigBytes ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+ private boolean checkSubStorages( XStorage xStorage, byte[] pBytes1, byte[] pBigBytes )
+ {
+ XStorage xReadSubStorage1 = m_aTestHelper.openSubStorage( xStorage,
+ "SubStorage1",
+ ElementModes.READ );
+
+ XStorage xReadSubStorage2 = m_aTestHelper.openSubStorage( xStorage,
+ "SubStorage1",
+ ElementModes.READ );
+
+ if ( xReadSubStorage1 == null || xReadSubStorage2 == null )
+ {
+ m_aTestHelper.Error( "Can't open substorage for reading!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xReadSubStorage1, "MediaType3", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStorageProperties( xReadSubStorage2, "MediaType3", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xReadSubStorage1, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xReadSubStorage1, "BigSubStream1", "MediaType1", true, pBigBytes ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xReadSubStorage2, "SubStream1", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xReadSubStorage2, "BigSubStream1", "MediaType1", true, pBigBytes ) )
+ return false;
+
+ if ( !m_aTestHelper.disposeStorage( xReadSubStorage1 ) )
+ return false;
+
+ if ( !m_aTestHelper.disposeStorage( xReadSubStorage2 ) )
+ return false;
+
+ return true;
+ }
+}
+
diff --git a/package/qa/storages/Test13.java b/package/qa/storages/Test13.java
new file mode 100644
index 000000000000..e8b05264f44d
--- /dev/null
+++ b/package/qa/storages/Test13.java
@@ -0,0 +1,215 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test13 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test13( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test13: " );
+ }
+
+ public boolean test()
+ {
+ String aStreamPrefix = "";
+ for ( int nInd = 0; nInd < 4; ++nInd, aStreamPrefix += "SubStorage" + nInd )
+ if ( !testForPath( aStreamPrefix ) )
+ return false;
+
+ return true;
+ }
+
+ public boolean testForPath( String aStreamPrefix )
+ {
+ try
+ {
+ String aSubStream1Path = aStreamPrefix + "SubStream1";
+ String aSubStream2Path = aStreamPrefix + "SubStream2";
+ String aSubStream3Path = aStreamPrefix + "SubStream3";
+ String aBigSubStream1Path = aStreamPrefix + "BigSubStream1";
+ String aBigSubStream2Path = aStreamPrefix + "BigSubStream2";
+ String aBigSubStream3Path = aStreamPrefix + "BigSubStream3";
+
+ String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
+ if ( sTempFileURL == null || sTempFileURL == "" )
+ {
+ m_aTestHelper.Error( "No valid temporary file was created!" );
+ return false;
+ }
+
+ // create temporary storage based on a previously created temporary file
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) sTempFileURL;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ byte pBigBytes[] = new byte[33000];
+ for ( int nInd = 0; nInd < 33000; nInd++ )
+ pBigBytes[nInd] = (byte)( nInd % 128 );
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and commit
+ if ( !m_aTestHelper.WriteBytesToStreamH( xTempFileStorage, aSubStream1Path, "MediaType1", true, pBytes1, true ) )
+ return false;
+ if ( !m_aTestHelper.WriteBytesToStreamH( xTempFileStorage, aBigSubStream1Path, "MediaType1", true, pBigBytes, true ) )
+ return false;
+
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+
+ // open a new substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and commit
+ if ( !m_aTestHelper.WriteBytesToStreamH( xTempFileStorage, aSubStream2Path, "MediaType2", false, pBytes2, true ) )
+ return false;
+ if ( !m_aTestHelper.WriteBytesToStreamH( xTempFileStorage, aBigSubStream2Path, "MediaType2", false, pBigBytes, true ) )
+ return false;
+
+ // open a new substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and don't commit
+ if ( !m_aTestHelper.WriteBytesToStreamH( xTempFileStorage, aSubStream3Path, "MediaType2", false, pBytes2, false ) )
+ return false;
+ if ( !m_aTestHelper.WriteBytesToStreamH( xTempFileStorage, aBigSubStream3Path, "MediaType2", false, pBigBytes, false ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempFileStorage,
+ "MediaType3",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempFileStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+ // ================================================
+ // now reopen the storage,
+ // check all the written and copied information
+ // and change it
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempFileStorage, "MediaType3", true, ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStreamH( xTempFileStorage, aSubStream1Path, "MediaType1", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStreamH( xTempFileStorage, aBigSubStream1Path, "MediaType1", true, pBigBytes ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStreamH( xTempFileStorage, aSubStream2Path, "MediaType2", false, pBytes2 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStreamH( xTempFileStorage, aBigSubStream2Path, "MediaType2", false, pBigBytes ) )
+ return false;
+
+ if ( !m_aTestHelper.cantOpenStreamH( xTempFileStorage, aSubStream3Path, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.cantOpenStreamH( xTempFileStorage, aBigSubStream3Path, ElementModes.READ ) )
+ return false;
+
+ // open existing substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and commit
+ if ( !m_aTestHelper.WriteBytesToStreamH( xTempFileStorage, aSubStream1Path, "MediaType3", true, pBytes2, true ) )
+ return false;
+ if ( !m_aTestHelper.WriteBytesToStreamH( xTempFileStorage, aBigSubStream1Path, "MediaType3", true, pBigBytes, true ) )
+ return false;
+
+
+ // open existing substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and don't commit
+ if ( !m_aTestHelper.WriteBytesToStreamH( xTempFileStorage, aSubStream2Path, "MediaType3", true, pBytes1, false ) )
+ return false;
+ if ( !m_aTestHelper.WriteBytesToStreamH( xTempFileStorage, aBigSubStream2Path, "MediaType3", true, pBigBytes, false ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempFileStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+ // ================================================
+ // now reopen the storage,
+ // check all the written information
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ pArgs[1] = new Integer( ElementModes.READ );
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage, "MediaType3", true, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStreamH( xResultStorage, aSubStream1Path, "MediaType3", true, pBytes2 ) )
+ return false;
+ if ( !m_aTestHelper.checkStreamH( xResultStorage, aBigSubStream1Path, "MediaType3", true, pBigBytes ) )
+ return false;
+
+ // the following stream was not commited last time, so the last change must be lost
+ if ( !m_aTestHelper.checkStreamH( xResultStorage, aBigSubStream2Path, "MediaType2", false, pBigBytes ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/storages/Test14.java b/package/qa/storages/Test14.java
new file mode 100644
index 000000000000..1f35758af05a
--- /dev/null
+++ b/package/qa/storages/Test14.java
@@ -0,0 +1,188 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test14 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test14( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test14: " );
+ }
+
+ public boolean test()
+ {
+ String aStreamPrefix = "";
+ for ( int nInd = 0; nInd < 4; ++nInd, aStreamPrefix += "SubStorage" + nInd )
+ if ( !testForPath( aStreamPrefix ) )
+ return false;
+
+ return true;
+ }
+
+ public boolean testForPath( String aStreamPrefix )
+ {
+ try
+ {
+ String aSubStream1Path = aStreamPrefix + "SubStream1";
+ String aSubStream2Path = aStreamPrefix + "SubStream2";
+ String aSubStream3Path = aStreamPrefix + "SubStream3";
+
+ String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
+ if ( sTempFileURL == null || sTempFileURL == "" )
+ {
+ m_aTestHelper.Error( "No valid temporary file was created!" );
+ return false;
+ }
+
+ // create temporary storage based on a previously created temporary file
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) sTempFileURL;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+ String sPass1 = "12345";
+
+ // open a new substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and commit
+ if ( !m_aTestHelper.WriteBytesToEncrStreamH( xTempFileStorage, aSubStream1Path, "MediaType1", true, pBytes1, sPass1, true ) )
+ return false;
+
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+ String sPass2 = "54321";
+
+ // open a new substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and commit
+ if ( !m_aTestHelper.WriteBytesToEncrStreamH( xTempFileStorage, aSubStream2Path, "MediaType2", false, pBytes2, sPass2, true ) )
+ return false;
+
+ // open a new substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and don't commit
+ if ( !m_aTestHelper.WriteBytesToEncrStreamH( xTempFileStorage, aSubStream3Path, "MediaType2", false, pBytes2, sPass2, false ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempFileStorage,
+ "MediaType3",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempFileStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+ // ================================================
+ // now reopen the storage,
+ // check all the written and copied information
+ // and change it
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempFileStorage, "MediaType3", true, ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStreamH( xTempFileStorage, aSubStream1Path, "MediaType1", pBytes1, sPass1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStreamH( xTempFileStorage, aSubStream2Path, "MediaType2", pBytes2, sPass2 ) )
+ return false;
+
+ if ( !m_aTestHelper.cantOpenEncrStreamH( xTempFileStorage, aSubStream3Path, ElementModes.READ, sPass2 ) )
+ return false;
+
+ // open existing substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and commit
+ if ( !m_aTestHelper.WriteBytesToEncrStreamH( xTempFileStorage, aSubStream1Path, "MediaType3", true, pBytes2, sPass1, true ) )
+ return false;
+
+ // open existing substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and don't commit
+ if ( !m_aTestHelper.WriteBytesToEncrStreamH( xTempFileStorage, aSubStream2Path, "MediaType3", true, pBytes1, sPass2, false ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempFileStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+ // ================================================
+ // now reopen the storage,
+ // check all the written information
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ pArgs[1] = new Integer( ElementModes.READ );
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage, "MediaType3", true, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStreamH( xResultStorage, aSubStream1Path, "MediaType3", pBytes2, sPass1 ) )
+ return false;
+
+ // the following stream was not commited last time, so the last change must be lost
+ if ( !m_aTestHelper.checkEncrStreamH( xResultStorage, aSubStream2Path, "MediaType2", pBytes2, sPass2 ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/storages/Test15.java b/package/qa/storages/Test15.java
new file mode 100644
index 000000000000..b58453f9a195
--- /dev/null
+++ b/package/qa/storages/Test15.java
@@ -0,0 +1,268 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test15 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test15( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test15: " );
+ }
+
+ public boolean test()
+ {
+ String aStreamPrefix = "";
+ for ( int nInd = 0; nInd < 4; ++nInd, aStreamPrefix += "SubStorage" + nInd )
+ if ( !testForPath( aStreamPrefix ) )
+ return false;
+
+ return true;
+ }
+
+ public boolean testForPath( String aStreamPrefix )
+ {
+ try
+ {
+ String aSubStream1Path = aStreamPrefix + "SubStream1";
+ String aSubStream2Path = aStreamPrefix + "SubStream2";
+ String aSubStream3Path = aStreamPrefix + "SubStream3";
+ String aSubStream4Path = aStreamPrefix + "SubStream4";
+
+ String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
+ if ( sTempFileURL == null || sTempFileURL == "" )
+ {
+ m_aTestHelper.Error( "No valid temporary file was created!" );
+ return false;
+ }
+
+ // create temporary storage based on a previously created temporary file
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) sTempFileURL;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ // set the global password for the root storage
+ XEncryptionProtectedSource xTempStorageEncryption =
+ (XEncryptionProtectedSource) UnoRuntime.queryInterface( XEncryptionProtectedSource.class, xTempFileStorage );
+
+ if ( xTempStorageEncryption == null )
+ {
+ m_aTestHelper.Message( "Optional interface XEncryptionProtectedSource is not implemented, feature can not be tested!" );
+ return true;
+ }
+
+ String sPass1 = "12345";
+ String sPass2 = "54321";
+
+ try {
+ xTempStorageEncryption.setEncryptionPassword( sPass1 );
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Can't set a common encryption key for the storage, exception:" + e );
+ return false;
+ }
+
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+
+ // open a new substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and commit
+ if ( !m_aTestHelper.WBToSubstrOfEncrH( xTempFileStorage, aSubStream1Path, "MediaType1", true, pBytes1, true, true ) )
+ return false;
+
+ // open a new substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and commit
+ if ( !m_aTestHelper.WriteBytesToEncrStreamH( xTempFileStorage, aSubStream2Path, "MediaType2", false, pBytes2, sPass2, true ) )
+ return false;
+
+ // open a new substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and commit
+ if ( !m_aTestHelper.WriteBytesToEncrStreamH( xTempFileStorage, aSubStream3Path, "MediaType3", false, pBytes2, sPass2, true ) )
+ return false;
+
+ // open a new substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and dont commit
+ if ( !m_aTestHelper.WBToSubstrOfEncrH( xTempFileStorage, aSubStream4Path, "MediaType2", true, pBytes1, true, false ) )
+ return false;
+
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempFileStorage,
+ "MediaType3",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempFileStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+ // ================================================
+ // now reopen the storage,
+ // check all the written and copied information
+ // and change it
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ // set the global password for the root storage
+ xTempStorageEncryption =
+ (XEncryptionProtectedSource) UnoRuntime.queryInterface( XEncryptionProtectedSource.class, xTempFileStorage );
+
+ if ( xTempStorageEncryption == null )
+ {
+ m_aTestHelper.Error( "XEncryptionProtectedSource is supported, but can not be retrieved!" );
+ return false;
+ }
+
+ try {
+ xTempStorageEncryption.setEncryptionPassword( sPass2 );
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Can't set a common encryption key for the storage, exception:" + e );
+ return false;
+ }
+
+
+ if ( !m_aTestHelper.checkStorageProperties( xTempFileStorage, "MediaType3", true, ElementModes.WRITE ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStreamH( xTempFileStorage, aSubStream1Path, "MediaType1", pBytes1, sPass1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStreamH( xTempFileStorage, aSubStream2Path, "MediaType2", true, pBytes2 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStreamH( xTempFileStorage, aSubStream3Path, "MediaType3", true, pBytes2 ) )
+ return false;
+
+ if ( !m_aTestHelper.cantOpenEncrStreamH( xTempFileStorage, aSubStream4Path, ElementModes.READ, sPass1 ) )
+ return false;
+
+ // open existing substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and commit
+ if ( !m_aTestHelper.WriteBytesToEncrStreamH( xTempFileStorage, aSubStream1Path, "MediaType4", true, pBytes2, sPass1, true ) )
+ return false;
+
+ // open existing substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and don't commit
+ if ( !m_aTestHelper.WriteBytesToStreamH( xTempFileStorage, aSubStream2Path, "MediaType5", true, pBytes1, true ) )
+ return false;
+
+ // change the password of the existing stream
+ if ( m_aTestHelper.ChangeStreamPassH( xTempFileStorage, aSubStream2Path, sPass2, sPass1, true ) != 1 )
+ return false;
+
+ // open existing substream hierarchically, set "MediaType" and "Compressed" properties to it, write some bytes
+ // and don't commit
+ if ( !m_aTestHelper.WriteBytesToStreamH( xTempFileStorage, aSubStream3Path, "MediaType5", true, pBytes1, false ) )
+ return false;
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempFileStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+ // ================================================
+ // now reopen the storage,
+ // check all the written information
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ pArgs[1] = new Integer( ElementModes.READ );
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
+ return false;
+ }
+
+ // set the global password for the root storage
+ xTempStorageEncryption =
+ (XEncryptionProtectedSource) UnoRuntime.queryInterface( XEncryptionProtectedSource.class, xResultStorage );
+
+ if ( xTempStorageEncryption == null )
+ {
+ m_aTestHelper.Error( "XEncryptionProtectedSource is supported, but can not be retrieved!" );
+ return false;
+ }
+
+ try {
+ xTempStorageEncryption.setEncryptionPassword( sPass1 );
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Can't set a common encryption key for the storage, exception:" + e );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage, "MediaType3", true, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStreamH( xResultStorage, aSubStream1Path, "MediaType4", true, pBytes2 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStreamH( xResultStorage, aSubStream2Path, "MediaType5", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkEncrStreamH( xResultStorage, aSubStream3Path, "MediaType3", pBytes2, sPass2 ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/storages/Test16.java b/package/qa/storages/Test16.java
new file mode 100644
index 000000000000..6f432b0da730
--- /dev/null
+++ b/package/qa/storages/Test16.java
@@ -0,0 +1,159 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test16 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test16( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test16: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
+ if ( sTempFileURL == null || sTempFileURL == "" )
+ {
+ m_aTestHelper.Error( "No valid temporary file was created!" );
+ return false;
+ }
+
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ Object oTempStorage = m_xStorageFactory.createInstance();
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage\u0442\u0435\u0441\u04421",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream\u0442\u0435\u0441\u04421", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ byte pBytes2[] = { 2, 2, 2, 2, 2 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, "SubStream\u0442\u0435\u0441\u04422", "MediaType2", false, pBytes2 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType3",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType4",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // create temporary storage based on a previously created temporary file
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) sTempFileURL;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ // copy xTempStorage to xTempFileStorage
+ // xTempFileStorage will be automatically commited
+ if ( !m_aTestHelper.copyStorage( xTempStorage, xTempFileStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) || !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+ // ================================================
+ // now check all the written and copied information
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ pArgs[1] = new Integer( ElementModes.WRITE );
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage, "MediaType3", true, ElementModes.WRITE ) )
+ return false;
+
+ // open existing substorage
+ XStorage xResultSubStorage = m_aTestHelper.openSubStorage( xResultStorage,
+ "SubStorage\u0442\u0435\u0441\u04421",
+ ElementModes.READ );
+ if ( xResultSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultSubStorage, "MediaType4", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream\u0442\u0435\u0441\u04421", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream\u0442\u0435\u0441\u04422", "MediaType2", false, pBytes2 ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/storages/Test17.java b/package/qa/storages/Test17.java
new file mode 100644
index 000000000000..009344cefbc4
--- /dev/null
+++ b/package/qa/storages/Test17.java
@@ -0,0 +1,142 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.io.XStream;
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test17 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test17( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test17: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
+ if ( xTempFileStream == null )
+ return false;
+
+ // create storage based on the temporary stream
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFileStream;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+ String pNames[] = { "SubStream1", "SubStream2", "SubStream3", "SubStream4", "SubStream5", "SubStream6", "SubStream7" };
+
+ for ( int nInd = 0; nInd < pNames.length; nInd++ )
+ {
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstream( xTempSubStorage, pNames[nInd], "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // commit substorage first
+ if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
+ return false;
+ }
+
+ // commit the root storage so the contents must be stored now
+ if ( !m_aTestHelper.commitStorage( xTempStorage ) )
+ return false;
+
+ // dispose used storage to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) )
+ return false;
+
+
+ // ================================================
+ // now check all the written information
+ // ================================================
+
+ // close the output part of the temporary stream
+ // the output part must present since we already wrote to the stream
+ if ( !m_aTestHelper.closeOutput( xTempFileStream ) )
+ return false;
+
+ XInputStream xTempInStream = m_aTestHelper.getInputStream( xTempFileStream );
+ if ( xTempInStream == null )
+ return false;
+
+
+ // open input stream
+ // since no mode is provided the result storage must be opened readonly
+ Object pOneArg[] = new Object[1];
+ pOneArg[0] = (Object) xTempInStream;
+
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pOneArg );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open storage based on input stream!" );
+ return false;
+ }
+
+ // open existing substorage
+ XStorage xResultSubStorage = m_aTestHelper.openSubStorage( xResultStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xResultSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ for ( int nInd = 0; nInd < pNames.length; nInd++ )
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, pNames[nInd], "MediaType1", true, pBytes1 ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/storages/Test18.java b/package/qa/storages/Test18.java
new file mode 100644
index 000000000000..335a230027ce
--- /dev/null
+++ b/package/qa/storages/Test18.java
@@ -0,0 +1,172 @@
+package complex.storages;
+
+import com.sun.star.uno.XInterface;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+
+import com.sun.star.embed.*;
+
+import share.LogWriter;
+import complex.storages.TestHelper;
+import complex.storages.StorageTest;
+
+public class Test18 implements StorageTest {
+
+ XMultiServiceFactory m_xMSF;
+ XSingleServiceFactory m_xStorageFactory;
+ TestHelper m_aTestHelper;
+
+ public Test18( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_xStorageFactory = xStorageFactory;
+ m_aTestHelper = new TestHelper( aLogWriter, "Test18: " );
+ }
+
+ public boolean test()
+ {
+ try
+ {
+ // test the default value of Compressed property
+ String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
+ if ( sTempFileURL == null || sTempFileURL == "" )
+ {
+ m_aTestHelper.Error( "No valid temporary file was created!" );
+ return false;
+ }
+
+ // create temporary storage based on arbitrary medium
+ // after such a storage is closed it is lost
+ Object oTempStorage = m_xStorageFactory.createInstance();
+ XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xTempStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create temporary storage representation!" );
+ return false;
+ }
+
+ // open a new substorage
+ XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
+ "SubStorage1",
+ ElementModes.WRITE );
+ if ( xTempSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create substorage!" );
+ return false;
+ }
+
+ byte pBytes1[] = { 1, 1, 1, 1, 1 };
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstreamDefaultCompressed( xTempSubStorage, "SubStream1", "image/jpeg", pBytes1 ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstreamDefaultCompressed( xTempSubStorage, "SubStream2", "image/png", pBytes1 ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstreamDefaultCompressed( xTempSubStorage, "SubStream3", "image/gif", pBytes1 ) )
+ return false;
+
+ // open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
+ if ( !m_aTestHelper.WriteBytesToSubstreamDefaultCompressed( xTempSubStorage, "SubStream4", "MediaType1", pBytes1 ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
+ "MediaType3",
+ true,
+ ElementModes.WRITE ) )
+ return false;
+
+ // set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
+ if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
+ "MediaType4",
+ false,
+ ElementModes.WRITE ) )
+ return false;
+
+ // create temporary storage based on a previously created temporary file
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) sTempFileURL;
+ pArgs[1] = new Integer( ElementModes.WRITE );
+
+ Object oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
+ if ( xTempFileStorage == null )
+ {
+ m_aTestHelper.Error( "Can't create storage based on temporary file!" );
+ return false;
+ }
+
+ // copy xTempStorage to xTempFileStorage
+ // xTempFileStorage will be automatically commited
+ if ( !m_aTestHelper.copyStorage( xTempStorage, xTempFileStorage ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xTempStorage ) || !m_aTestHelper.disposeStorage( xTempFileStorage ) )
+ return false;
+
+ // ================================================
+ // now check all the written and copied information
+ // ================================================
+
+ // the temporary file must not be locked any more after storage disposing
+ pArgs[1] = new Integer( ElementModes.WRITE );
+ Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
+ XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
+ if ( xResultStorage == null )
+ {
+ m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultStorage, "MediaType3", true, ElementModes.WRITE ) )
+ return false;
+
+ // open existing substorage
+ XStorage xResultSubStorage = m_aTestHelper.openSubStorage( xResultStorage,
+ "SubStorage1",
+ ElementModes.READ );
+ if ( xResultSubStorage == null )
+ {
+ m_aTestHelper.Error( "Can't open existing substorage!" );
+ return false;
+ }
+
+ if ( !m_aTestHelper.checkStorageProperties( xResultSubStorage, "MediaType4", false, ElementModes.READ ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream1", "image/jpeg", false, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream2", "image/png", false, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream3", "image/gif", false, pBytes1 ) )
+ return false;
+
+ if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream4", "MediaType1", true, pBytes1 ) )
+ return false;
+
+ // dispose used storages to free resources
+ if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
+ return false;
+
+ return true;
+ }
+ catch( Exception e )
+ {
+ m_aTestHelper.Error( "Exception: " + e );
+ return false;
+ }
+ }
+
+}
+
diff --git a/package/qa/storages/TestHelper.java b/package/qa/storages/TestHelper.java
new file mode 100644
index 000000000000..dc28786513b1
--- /dev/null
+++ b/package/qa/storages/TestHelper.java
@@ -0,0 +1,1661 @@
+package complex.storages;
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.uno.AnyConverter;
+
+import com.sun.star.lang.*;
+import com.sun.star.embed.*;
+import com.sun.star.packages.*;
+import com.sun.star.io.*;
+import com.sun.star.beans.*;
+
+import share.LogWriter;
+
+public class TestHelper {
+
+ LogWriter m_aLogWriter;
+ String m_sTestPrefix;
+
+ public TestHelper( LogWriter aLogWriter, String sTestPrefix )
+ {
+ m_aLogWriter = aLogWriter;
+ m_sTestPrefix = sTestPrefix;
+ }
+
+ public boolean WriteBytesToStream( XStream xStream,
+ String sStreamName,
+ String sMediaType,
+ boolean bCompressed,
+ byte[] pBytes )
+ {
+ // get output stream of substream
+ XOutputStream xOutput = xStream.getOutputStream();
+ if ( xOutput == null )
+ {
+ Error( "Can't get XOutputStream implementation from substream '" + sStreamName + "'!" );
+ return false;
+ }
+
+ // get XTrucate implementation from output stream
+ XTruncate xTruncate = (XTruncate) UnoRuntime.queryInterface( XTruncate.class, xOutput );
+ if ( xTruncate == null )
+ {
+ Error( "Can't get XTruncate implementation from substream '" + sStreamName + "'!" );
+ return false;
+ }
+
+ // write requested byte sequence
+ try
+ {
+ xTruncate.truncate();
+ xOutput.writeBytes( pBytes );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't write to stream '" + sStreamName + "', exception: " + e );
+ return false;
+ }
+
+ // get access to the XPropertySet interface
+ XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStream );
+ if ( xPropSet == null )
+ {
+ Error( "Can't get XPropertySet implementation from substream '" + sStreamName + "'!" );
+ return false;
+ }
+
+ // set properties to the stream
+ try
+ {
+ xPropSet.setPropertyValue( "MediaType", sMediaType );
+ xPropSet.setPropertyValue( "Compressed", new Boolean( bCompressed ) );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't set properties to substream '" + sStreamName + "', exception: " + e );
+ return false;
+ }
+
+ // check size property of the stream
+ try
+ {
+ int nSize = AnyConverter.toInt( xPropSet.getPropertyValue( "Size" ) );
+ if ( nSize != pBytes.length )
+ {
+ Error( "The 'Size' property of substream '" + sStreamName + "' contains wrong value!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't get 'Size' property from substream '" + sStreamName + "', exception: " + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean WriteBytesToSubstreamDefaultCompressed( XStorage xStorage,
+ String sStreamName,
+ String sMediaType,
+ byte[] pBytes )
+ {
+ // open substream element
+ XStream xSubStream = null;
+ try
+ {
+ Object oSubStream = xStorage.openStreamElement( sStreamName, ElementModes.WRITE );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ {
+ Error( "Can't create substream '" + sStreamName + "'!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't create substream '" + sStreamName + "', exception : " + e + "!" );
+ return false;
+ }
+
+ // get output stream of substream
+ XOutputStream xOutput = xSubStream.getOutputStream();
+ if ( xOutput == null )
+ {
+ Error( "Can't get XOutputStream implementation from substream '" + sStreamName + "'!" );
+ return false;
+ }
+
+ // get XTrucate implementation from output stream
+ XTruncate xTruncate = (XTruncate) UnoRuntime.queryInterface( XTruncate.class, xOutput );
+ if ( xTruncate == null )
+ {
+ Error( "Can't get XTruncate implementation from substream '" + sStreamName + "'!" );
+ return false;
+ }
+
+ // write requested byte sequence
+ try
+ {
+ xTruncate.truncate();
+ xOutput.writeBytes( pBytes );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't write to stream '" + sStreamName + "', exception: " + e );
+ return false;
+ }
+
+ // get access to the XPropertySet interface
+ XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xSubStream );
+ if ( xPropSet == null )
+ {
+ Error( "Can't get XPropertySet implementation from substream '" + sStreamName + "'!" );
+ return false;
+ }
+
+ // set properties to the stream
+ // do not set the compressed property
+ try
+ {
+ xPropSet.setPropertyValue( "MediaType", sMediaType );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't set properties to substream '" + sStreamName + "', exception: " + e );
+ return false;
+ }
+
+ // check size property of the stream
+ try
+ {
+ int nSize = AnyConverter.toInt( xPropSet.getPropertyValue( "Size" ) );
+ if ( nSize != pBytes.length )
+ {
+ Error( "The 'Size' property of substream '" + sStreamName + "' contains wrong value!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't get 'Size' property from substream '" + sStreamName + "', exception: " + e );
+ return false;
+ }
+
+ // free the stream resources, garbage collector may remove the object too late
+ if ( !disposeStream( xSubStream, sStreamName ) )
+ return false;
+
+ return true;
+ }
+
+ public boolean WriteBytesToSubstream( XStorage xStorage,
+ String sStreamName,
+ String sMediaType,
+ boolean bCompressed,
+ byte[] pBytes )
+ {
+ // open substream element
+ XStream xSubStream = null;
+ try
+ {
+ Object oSubStream = xStorage.openStreamElement( sStreamName, ElementModes.WRITE );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ {
+ Error( "Can't create substream '" + sStreamName + "'!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't create substream '" + sStreamName + "', exception : " + e + "!" );
+ return false;
+ }
+
+ if ( !WriteBytesToStream( xSubStream, sStreamName, sMediaType, bCompressed, pBytes ) )
+ return false;
+
+ // free the stream resources, garbage collector may remove the object too late
+ if ( !disposeStream( xSubStream, sStreamName ) )
+ return false;
+
+ return true;
+ }
+
+ public boolean WriteBytesToEncrSubstream( XStorage xStorage,
+ String sStreamName,
+ String sMediaType,
+ boolean bCompressed,
+ byte[] pBytes,
+ String sPass )
+ {
+ // open substream element
+ XStream xSubStream = null;
+ try
+ {
+ Object oSubStream = xStorage.openEncryptedStreamElement( sStreamName, ElementModes.WRITE, sPass );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ {
+ Error( "Can't create substream '" + sStreamName + "'!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't create substream '" + sStreamName + "', exception : " + e + "!" );
+ return false;
+ }
+
+ if ( !WriteBytesToStream( xSubStream, sStreamName, sMediaType, bCompressed, pBytes ) )
+ return false;
+
+ // free the stream resources, garbage collector may remove the object too late
+ if ( !disposeStream( xSubStream, sStreamName ) )
+ return false;
+
+ return true;
+ }
+
+ public boolean WBToSubstrOfEncr( XStorage xStorage,
+ String sStreamName,
+ String sMediaType,
+ boolean bCompressed,
+ byte[] pBytes,
+ boolean bEncrypted )
+ {
+ // open substream element
+ XStream xSubStream = null;
+ try
+ {
+ Object oSubStream = xStorage.openStreamElement( sStreamName, ElementModes.WRITE );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ {
+ Error( "Can't create substream '" + sStreamName + "'!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't create substream '" + sStreamName + "', exception : " + e + "!" );
+ return false;
+ }
+
+ // get access to the XPropertySet interface
+ XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xSubStream );
+ if ( xPropSet == null )
+ {
+ Error( "Can't get XPropertySet implementation from substream '" + sStreamName + "'!" );
+ return false;
+ }
+
+ // set properties to the stream
+ try
+ {
+ xPropSet.setPropertyValue( "UseCommonStoragePasswordEncryption", new Boolean( bEncrypted ) );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't set 'UseCommonStoragePasswordEncryption' property to substream '" + sStreamName + "', exception: " + e );
+ return false;
+ }
+
+ if ( !WriteBytesToStream( xSubStream, sStreamName, sMediaType, bCompressed, pBytes ) )
+ return false;
+
+ // free the stream resources, garbage collector may remove the object too late
+ if ( !disposeStream( xSubStream, sStreamName ) )
+ return false;
+
+ return true;
+ }
+
+ public boolean WriteBytesToStreamH( XStorage xStorage,
+ String sStreamPath,
+ String sMediaType,
+ boolean bCompressed,
+ byte[] pBytes,
+ boolean bCommit )
+ {
+ // open substream element
+ XStream xSubStream = null;
+ try
+ {
+ XHierarchicalStorageAccess xHStorage =
+ (XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xStorage );
+ if ( xHStorage == null )
+ {
+ Error( "The storage does not support hierarchical access!" );
+ return false;
+ }
+
+ Object oSubStream = xHStorage.openStreamElementByHierarchicalName( sStreamPath, ElementModes.WRITE );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ {
+ Error( "Can't create substream '" + sStreamPath + "'!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't create substream '" + sStreamPath + "', exception : " + e + "!" );
+ return false;
+ }
+
+ if ( !WriteBytesToStream( xSubStream, sStreamPath, sMediaType, bCompressed, pBytes ) )
+ return false;
+
+ XTransactedObject xTransact =
+ (XTransactedObject) UnoRuntime.queryInterface( XTransactedObject.class, xSubStream );
+ if ( xTransact == null )
+ {
+ Error( "Substream '" + sStreamPath + "', stream opened for writing must be transacted!" );
+ return false;
+ }
+
+ if ( bCommit )
+ {
+ try {
+ xTransact.commit();
+ } catch( Exception e )
+ {
+ Error( "Can't commit storage after substream '" + sStreamPath + "' change, exception : " + e + "!" );
+ return false;
+ }
+ }
+
+ // free the stream resources, garbage collector may remove the object too late
+ if ( !disposeStream( xSubStream, sStreamPath ) )
+ return false;
+
+ return true;
+ }
+
+ public boolean WriteBytesToEncrStreamH( XStorage xStorage,
+ String sStreamPath,
+ String sMediaType,
+ boolean bCompressed,
+ byte[] pBytes,
+ String sPass,
+ boolean bCommit )
+ {
+ // open substream element
+ XStream xSubStream = null;
+ try
+ {
+ XHierarchicalStorageAccess xHStorage =
+ (XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xStorage );
+ if ( xHStorage == null )
+ {
+ Error( "The storage does not support hierarchical access!" );
+ return false;
+ }
+
+ Object oSubStream = xHStorage.openEncryptedStreamElementByHierarchicalName( sStreamPath,
+ ElementModes.WRITE,
+ sPass );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ {
+ Error( "Can't create substream '" + sStreamPath + "'!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't create substream '" + sStreamPath + "', exception : " + e + "!" );
+ return false;
+ }
+
+ if ( !WriteBytesToStream( xSubStream, sStreamPath, sMediaType, bCompressed, pBytes ) )
+ return false;
+
+ XTransactedObject xTransact =
+ (XTransactedObject) UnoRuntime.queryInterface( XTransactedObject.class, xSubStream );
+ if ( xTransact == null )
+ {
+ Error( "Substream '" + sStreamPath + "', stream opened for writing must be transacted!" );
+ return false;
+ }
+
+ if ( bCommit )
+ {
+ try {
+ xTransact.commit();
+ } catch( Exception e )
+ {
+ Error( "Can't commit storage after substream '" + sStreamPath + "' change, exception : " + e + "!" );
+ return false;
+ }
+ }
+
+ // free the stream resources, garbage collector may remove the object too late
+ if ( !disposeStream( xSubStream, sStreamPath ) )
+ return false;
+
+ return true;
+ }
+
+ public boolean WBToSubstrOfEncrH( XStorage xStorage,
+ String sStreamPath,
+ String sMediaType,
+ boolean bCompressed,
+ byte[] pBytes,
+ boolean bEncrypted,
+ boolean bCommit )
+ {
+ // open substream element
+ XStream xSubStream = null;
+ try
+ {
+ XHierarchicalStorageAccess xHStorage =
+ (XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xStorage );
+ if ( xHStorage == null )
+ {
+ Error( "The storage does not support hierarchical access!" );
+ return false;
+ }
+
+ Object oSubStream = xHStorage.openStreamElementByHierarchicalName( sStreamPath, ElementModes.WRITE );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ {
+ Error( "Can't create substream '" + sStreamPath + "'!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't create substream '" + sStreamPath + "', exception : " + e + "!" );
+ return false;
+ }
+
+ // get access to the XPropertySet interface
+ XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xSubStream );
+ if ( xPropSet == null )
+ {
+ Error( "Can't get XPropertySet implementation from substream '" + sStreamPath + "'!" );
+ return false;
+ }
+
+ // set properties to the stream
+ try
+ {
+ xPropSet.setPropertyValue( "UseCommonStoragePasswordEncryption", new Boolean( bEncrypted ) );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't set 'UseCommonStoragePasswordEncryption' property to substream '" + sStreamPath + "', exception: " + e );
+ return false;
+ }
+
+ if ( !WriteBytesToStream( xSubStream, sStreamPath, sMediaType, bCompressed, pBytes ) )
+ return false;
+
+ XTransactedObject xTransact =
+ (XTransactedObject) UnoRuntime.queryInterface( XTransactedObject.class, xSubStream );
+ if ( xTransact == null )
+ {
+ Error( "Substream '" + sStreamPath + "', stream opened for writing must be transacted!" );
+ return false;
+ }
+
+ if ( bCommit )
+ {
+ try {
+ xTransact.commit();
+ } catch( Exception e )
+ {
+ Error( "Can't commit storage after substream '" + sStreamPath + "' change, exception : " + e + "!" );
+ return false;
+ }
+ }
+
+ // free the stream resources, garbage collector may remove the object too late
+ if ( !disposeStream( xSubStream, sStreamPath ) )
+ return false;
+
+ return true;
+ }
+
+ public int ChangeStreamPass( XStorage xStorage,
+ String sStreamName,
+ String sOldPass,
+ String sNewPass )
+ {
+ // open substream element
+ XStream xSubStream = null;
+ try
+ {
+ Object oSubStream = xStorage.openEncryptedStreamElement( sStreamName, ElementModes.WRITE, sOldPass );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ {
+ Error( "Can't open substream '" + sStreamName + "'!" );
+ return 0;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't open substream '" + sStreamName + "', exception : " + e + "!" );
+ return 0;
+ }
+
+
+ // change the password for the stream
+ XEncryptionProtectedSource xStreamEncryption =
+ (XEncryptionProtectedSource) UnoRuntime.queryInterface( XEncryptionProtectedSource.class, xSubStream );
+
+ if ( xStreamEncryption == null )
+ {
+ Message( "Optional interface XEncryptionProtectedSource is not implemented, feature can not be tested!" );
+ return -1;
+ }
+
+ try {
+ xStreamEncryption.setEncryptionPassword( sNewPass );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't change encryption key of the substream '" + sStreamName + "', exception:" + e );
+ return 0;
+ }
+
+ // free the stream resources, garbage collector may remove the object too late
+ if ( !disposeStream( xSubStream, sStreamName ) )
+ return 0;
+
+ return 1;
+ }
+
+ public int ChangeStreamPassH( XStorage xStorage,
+ String sPath,
+ String sOldPass,
+ String sNewPass,
+ boolean bCommit )
+ {
+ // open substream element
+ XHierarchicalStorageAccess xHStorage =
+ (XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xStorage );
+ if ( xHStorage == null )
+ {
+ Error( "The storage does not support hierarchical access!" );
+ return 0;
+ }
+
+ XStream xSubStream = null;
+ try
+ {
+ Object oSubStream = xHStorage.openEncryptedStreamElementByHierarchicalName( sPath, ElementModes.WRITE, sOldPass );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ {
+ Error( "Can't open encrypted substream '" + sPath + "'!" );
+ return 0;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't open encrypted substream '" + sPath + "', exception : " + e + "!" );
+ return 0;
+ }
+
+ // change the password for the stream
+ XEncryptionProtectedSource xStreamEncryption =
+ (XEncryptionProtectedSource) UnoRuntime.queryInterface( XEncryptionProtectedSource.class, xSubStream );
+
+ if ( xStreamEncryption == null )
+ {
+ Message( "Optional interface XEncryptionProtectedSource is not implemented, feature can not be tested!" );
+ return -1;
+ }
+
+ try {
+ xStreamEncryption.setEncryptionPassword( sNewPass );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't change encryption key of the substream '" + sPath + "', exception:" + e );
+ return 0;
+ }
+
+ XTransactedObject xTransact =
+ (XTransactedObject) UnoRuntime.queryInterface( XTransactedObject.class, xSubStream );
+ if ( xTransact == null )
+ {
+ Error( "Substream '" + sPath + "', stream opened for writing must be transacted!" );
+ return 0;
+ }
+
+ if ( bCommit )
+ {
+ try {
+ xTransact.commit();
+ } catch( Exception e )
+ {
+ Error( "Can't commit storage after substream '" + sPath + "' change, exception : " + e + "!" );
+ return 0;
+ }
+ }
+
+ // free the stream resources, garbage collector may remove the object too late
+ if ( !disposeStream( xSubStream, sPath ) )
+ return 0;
+
+ return 1;
+ }
+
+ public boolean setStorageTypeAndCheckProps( XStorage xStorage, String sMediaType, boolean bIsRoot, int nMode )
+ {
+ boolean bOk = false;
+
+ // get access to the XPropertySet interface
+ XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStorage );
+ if ( xPropSet != null )
+ {
+ try
+ {
+ // set "MediaType" property to the stream
+ xPropSet.setPropertyValue( "MediaType", sMediaType );
+
+ // get "IsRoot" and "OpenMode" properties and control there values
+ boolean bPropIsRoot = AnyConverter.toBoolean( xPropSet.getPropertyValue( "IsRoot" ) );
+ int nPropMode = AnyConverter.toInt( xPropSet.getPropertyValue( "OpenMode" ) );
+
+ bOk = true;
+ if ( bPropIsRoot != bIsRoot )
+ {
+ Error( "'IsRoot' property contains wrong value!" );
+ bOk = false;
+ }
+
+ if ( ( bIsRoot
+ && ( nPropMode | ElementModes.READ ) != ( nMode | ElementModes.READ ) )
+ || ( !bIsRoot && ( nPropMode & nMode ) != nMode ) )
+ {
+ Error( "'OpenMode' property contains wrong value, expected " + nMode + ", in reality " + nPropMode + "!" );
+ bOk = false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't control properties of substorage, exception: " + e );
+ }
+ }
+ else
+ {
+ Error( "Can't get XPropertySet implementation from storage!" );
+ }
+
+ return bOk;
+ }
+
+ public boolean checkStorageProperties( XStorage xStorage, String sMediaType, boolean bIsRoot, int nMode )
+ {
+ boolean bOk = false;
+
+ // get access to the XPropertySet interface
+ XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStorage );
+ if ( xPropSet != null )
+ {
+ try
+ {
+ // get "MediaType", "IsRoot" and "OpenMode" properties and control there values
+ String sPropMediaType = AnyConverter.toString( xPropSet.getPropertyValue( "MediaType" ) );
+ boolean bPropIsRoot = AnyConverter.toBoolean( xPropSet.getPropertyValue( "IsRoot" ) );
+ int nPropMode = AnyConverter.toInt( xPropSet.getPropertyValue( "OpenMode" ) );
+
+ bOk = true;
+ if ( !sPropMediaType.equals( sMediaType ) )
+ {
+ Error( "'MediaType' property contains wrong value, expected '"
+ + sMediaType + "', set '" + sPropMediaType + "' !" );
+ bOk = false;
+ }
+
+ if ( bPropIsRoot != bIsRoot )
+ {
+ Error( "'IsRoot' property contains wrong value!" );
+ bOk = false;
+ }
+
+ if ( ( bIsRoot
+ && ( nPropMode | ElementModes.READ ) != ( nMode | ElementModes.READ ) )
+ || ( !bIsRoot && ( nPropMode & nMode ) != nMode ) )
+ {
+ Error( "'OpenMode' property contains wrong value, expected " + nMode + ", in reality " + nPropMode + "!" );
+ bOk = false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't get properties of substorage, exception: " + e );
+ }
+ }
+ else
+ {
+ Error( "Can't get XPropertySet implementation from storage!" );
+ }
+
+ return bOk;
+ }
+
+ public boolean InternalCheckStream( XStream xStream,
+ String sName,
+ String sMediaType,
+ boolean bCompressed,
+ byte[] pBytes,
+ boolean bCheckCompressed )
+ {
+ // get input stream of substream
+ XInputStream xInput = xStream.getInputStream();
+ if ( xInput == null )
+ {
+ Error( "Can't get XInputStream implementation from substream '" + sName + "'!" );
+ return false;
+ }
+
+ byte pContents[][] = new byte[1][]; // ???
+
+ // read contents
+ try
+ {
+ xInput.readBytes( pContents, pBytes.length + 1 );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't read from stream '" + sName + "', exception: " + e );
+ return false;
+ }
+
+ // check size of stream data
+ if ( pContents.length == 0 )
+ {
+ Error( "SubStream '" + sName + "' reading produced disaster!" );
+ return false;
+ }
+
+ if ( pBytes.length != pContents[0].length )
+ {
+ Error( "SubStream '" + sName + "' contains wrong amount of data! (" + pContents[0].length + "/" + pBytes.length + ")" );
+ return false;
+ }
+
+ // check stream data
+ for ( int ind = 0; ind < pBytes.length; ind++ )
+ {
+ if ( pBytes[ind] != pContents[0][ind] )
+ {
+ Error( "SubStream '" + sName + "' contains wrong data! ( byte num. "
+ + ind + " should be " + pBytes[ind] + " but it is " + pContents[0][ind] + ")" );
+ return false;
+ }
+ }
+
+ // check properties
+ boolean bOk = false;
+
+ // get access to the XPropertySet interface
+ XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStream );
+ if ( xPropSet != null )
+ {
+ try
+ {
+ // get "MediaType" and "Size" properties and control there values
+ String sPropMediaType = AnyConverter.toString( xPropSet.getPropertyValue( "MediaType" ) );
+ int nPropSize = AnyConverter.toInt( xPropSet.getPropertyValue( "Size" ) );
+ boolean bPropCompress = AnyConverter.toBoolean( xPropSet.getPropertyValue( "Compressed" ) );
+
+ bOk = true;
+ if ( !sPropMediaType.equals( sMediaType ) )
+ {
+ Error( "'MediaType' property contains wrong value for stream '" + sName + "',\nexpected: '"
+ + sMediaType + "', set: '" + sPropMediaType + "'!" );
+ bOk = false;
+ }
+
+ if ( nPropSize != pBytes.length )
+ {
+ Error( "'Size' property contains wrong value for stream'" + sName + "'!" );
+ bOk = false;
+ }
+
+ if ( bCheckCompressed && bPropCompress != bCompressed )
+ {
+ Error( "'Compressed' property contains wrong value for stream'" + sName + "'!" );
+ bOk = false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't get properties of substream '" + sName + "', exception: " + e );
+ }
+ }
+ else
+ {
+ Error( "Can't get XPropertySet implementation from stream '" + sName + "'!" );
+ }
+
+ return bOk;
+ }
+
+ public boolean checkStream( XStorage xParentStorage,
+ String sName,
+ String sMediaType,
+ boolean bCompressed,
+ byte[] pBytes )
+ {
+ // open substream element first
+ XStream xSubStream = null;
+ try
+ {
+ Object oSubStream = xParentStorage.openStreamElement( sName, ElementModes.READ );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ {
+ Error( "Can't open substream '" + sName + "'!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't open substream '" + sName + "', exception : " + e + "!" );
+ return false;
+ }
+
+ boolean bResult = InternalCheckStream( xSubStream, sName, sMediaType, bCompressed, pBytes, true );
+
+ // free the stream resources, garbage collector may remove the object too late
+ if ( !disposeStream( xSubStream, sName ) )
+ return false;
+
+ return bResult;
+ }
+
+ public boolean checkEncrStream( XStorage xParentStorage,
+ String sName,
+ String sMediaType,
+ byte[] pBytes,
+ String sPass )
+ {
+ // Important: a common password for any of parent storage should not be set or
+ // should be different from sPass
+
+ try
+ {
+ Object oSubStream = xParentStorage.openStreamElement( sName, ElementModes.READ );
+ Error( "Encrypted stream '" + sName + "' was opened without password!" );
+ return false;
+ }
+ catch( WrongPasswordException wpe )
+ {}
+ catch( Exception e )
+ {
+ Error( "Unexpected exception in case of opening of encrypted stream '" + sName + "' without password: " + e + "!" );
+ return false;
+ }
+
+ String sWrongPass = "11";
+ sWrongPass += sPass;
+ try
+ {
+ Object oSubStream = xParentStorage.openEncryptedStreamElement( sName, ElementModes.READ, sWrongPass );
+ Error( "Encrypted stream '" + sName + "' was opened with wrong password!" );
+ return false;
+ }
+ catch( WrongPasswordException wpe )
+ {}
+ catch( Exception e )
+ {
+ Error( "Unexpected exception in case of opening of encrypted stream '" + sName + "' with wrong password: " + e + "!" );
+ return false;
+ }
+
+ XStream xSubStream = null;
+ try
+ {
+ Object oSubStream = xParentStorage.openEncryptedStreamElement( sName, ElementModes.READ, sPass );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ {
+ Error( "Can't open encrypted substream '" + sName + "'!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't open encrypted substream '" + sName + "', exception : " + e + "!" );
+ return false;
+ }
+
+ // encrypted streams will be compressed always, so after the storing this property is always true,
+ // although before the storing it can be set to false ( it is not always clear whether a stream is encrypted
+ // before the storing )
+ boolean bResult = InternalCheckStream( xSubStream, sName, sMediaType, true, pBytes, false );
+
+ // free the stream resources, garbage collector may remove the object too late
+ if ( !disposeStream( xSubStream, sName ) )
+ return false;
+
+ return bResult;
+ }
+
+ public boolean checkStreamH( XStorage xParentStorage,
+ String sPath,
+ String sMediaType,
+ boolean bCompressed,
+ byte[] pBytes )
+ {
+ // open substream element first
+ XStream xSubStream = null;
+ try
+ {
+ XHierarchicalStorageAccess xHStorage =
+ (XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xParentStorage );
+ if ( xHStorage == null )
+ {
+ Error( "The storage does not support hierarchical access!" );
+ return false;
+ }
+
+ Object oSubStream = xHStorage.openStreamElementByHierarchicalName( sPath, ElementModes.READ );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ {
+ Error( "Can't open substream '" + sPath + "'!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't open substream '" + sPath + "', exception : " + e + "!" );
+ return false;
+ }
+
+ boolean bResult = InternalCheckStream( xSubStream, sPath, sMediaType, bCompressed, pBytes, true );
+
+ // free the stream resources, garbage collector may remove the object too late
+ if ( !disposeStream( xSubStream, sPath ) )
+ return false;
+
+ return bResult;
+ }
+
+ public boolean checkEncrStreamH( XStorage xParentStorage,
+ String sPath,
+ String sMediaType,
+ byte[] pBytes,
+ String sPass )
+ {
+ // Important: a common password for any of parent storage should not be set or
+ // should be different from sPass
+ XHierarchicalStorageAccess xHStorage =
+ (XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xParentStorage );
+ if ( xHStorage == null )
+ {
+ Error( "The storage does not support hierarchical access!" );
+ return false;
+ }
+
+ try
+ {
+ Object oSubStream = xHStorage.openStreamElementByHierarchicalName( sPath, ElementModes.READ );
+ XStream xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ Error( "Encrypted substream '" + sPath + "' was opened without password!" );
+ return false;
+ }
+ catch( WrongPasswordException wpe )
+ {}
+ catch( Exception e )
+ {
+ Error( "Unexpected exception in case of opening of encrypted stream '" + sPath + "' without password: " + e + "!" );
+ return false;
+ }
+
+ String sWrongPass = "11";
+ sWrongPass += sPass;
+ try
+ {
+ Object oSubStream = xHStorage.openEncryptedStreamElementByHierarchicalName( sPath, ElementModes.READ, sWrongPass );
+ XStream xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ Error( "Encrypted substream '" + sPath + "' was opened with wrong password!" );
+ return false;
+ }
+ catch( WrongPasswordException wpe )
+ {}
+ catch( Exception e )
+ {
+ Error( "Unexpected exception in case of opening of encrypted stream '" + sPath + "' with wrong password: " + e + "!" );
+ return false;
+ }
+
+ XStream xSubStream = null;
+ try
+ {
+ Object oSubStream = xHStorage.openEncryptedStreamElementByHierarchicalName( sPath, ElementModes.READ, sPass );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ {
+ Error( "Can't open encrypted substream '" + sPath + "'!" );
+ return false;
+ }
+ }
+ catch( Exception e )
+ {
+ Error( "Can't open encrypted substream '" + sPath + "', exception : " + e + "!" );
+ return false;
+ }
+
+ // encrypted streams will be compressed always, so after the storing this property is always true,
+ // although before the storing it can be set to false ( it is not always clear whether a stream is encrypted
+ // before the storing )
+ boolean bResult = InternalCheckStream( xSubStream, sPath, sMediaType, true, pBytes, false );
+
+ // free the stream resources, garbage collector may remove the object too late
+ if ( !disposeStream( xSubStream, sPath ) )
+ return false;
+
+ return bResult;
+ }
+
+ public boolean copyStorage( XStorage xSourceStorage, XStorage xDestStorage )
+ {
+ // copy xSourceStorage to xDestStorage
+ try
+ {
+ xSourceStorage.copyToStorage( xDestStorage );
+ }
+ catch( Exception e )
+ {
+ Error( "Storage copying failed, exception: " + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean commitStorage( XStorage xStorage )
+ {
+ // XTransactedObject must be supported by storages
+ XTransactedObject xTransact = (XTransactedObject) UnoRuntime.queryInterface( XTransactedObject.class, xStorage );
+ if ( xTransact == null )
+ {
+ Error( "Storage doesn't implement transacted access!" );
+ return false;
+ }
+
+ try
+ {
+ xTransact.commit();
+ }
+ catch( Exception e )
+ {
+ Error( "Storage commit failed, exception:" + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean disposeStream( XStream xStream, String sStreamName )
+ {
+ XComponent xComponent = (XComponent) UnoRuntime.queryInterface( XComponent.class, xStream );
+ if ( xComponent == null )
+ {
+ Error( "Can't get XComponent implementation from substream '" + sStreamName + "'!" );
+ return false;
+ }
+
+ try
+ {
+ xComponent.dispose();
+ }
+ catch( Exception e )
+ {
+ Error( "Substream '" + sStreamName + "' disposing throws exception: " + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean disposeStorage( XStorage xStorage )
+ {
+ // dispose the storage
+ XComponent xComponent = (XComponent) UnoRuntime.queryInterface( XComponent.class, xStorage );
+ if ( xComponent == null )
+ {
+ Error( "Can't retrieve XComponent implementation from storage!" );
+ return false;
+ }
+
+ try
+ {
+ xComponent.dispose();
+ }
+ catch( Exception e )
+ {
+ Error( "Storage disposing failed!" );
+ return false;
+ }
+
+ return true;
+ }
+
+ public XInputStream getInputStream( XStream xStream )
+ {
+ XInputStream xInTemp = null;
+ try
+ {
+ xInTemp = xStream.getInputStream();
+ if ( xInTemp == null )
+ Error( "Can't get the input part of a stream!" );
+ }
+ catch ( Exception e )
+ {
+ Error( "Can't get the input part of a stream, exception :" + e );
+ }
+
+ return xInTemp;
+ }
+
+ public boolean closeOutput( XStream xStream )
+ {
+ XOutputStream xOutTemp = null;
+ try
+ {
+ xOutTemp = xStream.getOutputStream();
+ if ( xOutTemp == null )
+ {
+ Error( "Can't get the output part of a stream!" );
+ return false;
+ }
+ }
+ catch ( Exception e )
+ {
+ Error( "Can't get the output part of a stream, exception :" + e );
+ return false;
+ }
+
+ try
+ {
+ xOutTemp.closeOutput();
+ }
+ catch ( Exception e )
+ {
+ Error( "Can't close output part of a stream, exception :" + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public XStorage openSubStorage( XStorage xStorage, String sName, int nMode )
+ {
+ // open existing substorage
+ try
+ {
+ Object oSubStorage = xStorage.openStorageElement( sName, nMode );
+ XStorage xSubStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oSubStorage );
+ return xSubStorage;
+ }
+ catch( Exception e )
+ {
+ Error( "Can't open substorage '" + sName + "', exception: " + e );
+ }
+
+ return null;
+ }
+
+ public XStream CreateTempFileStream( XMultiServiceFactory xMSF )
+ {
+ // try to get temporary file representation
+ XStream xTempFileStream = null;
+ try
+ {
+ Object oTempFile = xMSF.createInstance( "com.sun.star.io.TempFile" );
+ xTempFileStream = (XStream)UnoRuntime.queryInterface( XStream.class, oTempFile );
+ }
+ catch( Exception e )
+ {}
+
+ if ( xTempFileStream == null )
+ Error( "Can't create temporary file!" );
+
+ return xTempFileStream;
+ }
+
+ public String CreateTempFile( XMultiServiceFactory xMSF )
+ {
+ String sResult = null;
+
+ // try to get temporary file representation
+ XPropertySet xTempFileProps = null;
+ try
+ {
+ Object oTempFile = xMSF.createInstance( "com.sun.star.io.TempFile" );
+ xTempFileProps = (XPropertySet)UnoRuntime.queryInterface( XPropertySet.class, oTempFile );
+ }
+ catch( Exception e )
+ {}
+
+ if ( xTempFileProps != null )
+ {
+ try
+ {
+ xTempFileProps.setPropertyValue( "RemoveFile", new Boolean( false ) );
+ sResult = AnyConverter.toString( xTempFileProps.getPropertyValue( "Uri" ) );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't control TempFile properties, exception: " + e );
+ }
+ }
+ else
+ {
+ Error( "Can't create temporary file representation!" );
+ }
+
+ // close temporary file explicitly
+ try
+ {
+ XStream xStream = (XStream)UnoRuntime.queryInterface( XStream.class, xTempFileProps );
+ if ( xStream != null )
+ {
+ XOutputStream xOut = xStream.getOutputStream();
+ if ( xOut != null )
+ xOut.closeOutput();
+
+ XInputStream xIn = xStream.getInputStream();
+ if ( xIn != null )
+ xIn.closeInput();
+ }
+ else
+ Error( "Can't close TempFile!" );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't close TempFile, exception: " + e );
+ }
+
+ return sResult;
+ }
+
+ public boolean copyElementTo( XStorage xSource, String sName, XStorage xDest )
+ {
+ // copy element with name sName from xSource to xDest
+ try
+ {
+ xSource.copyElementTo( sName, xDest, sName );
+ }
+ catch( Exception e )
+ {
+ Error( "Element copying failed, exception: " + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean copyElementTo( XStorage xSource, String sName, XStorage xDest, String sTargetName )
+ {
+ // copy element with name sName from xSource to xDest
+ try
+ {
+ xSource.copyElementTo( sName, xDest, sTargetName );
+ }
+ catch( Exception e )
+ {
+ Error( "Element copying failed, exception: " + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean moveElementTo( XStorage xSource, String sName, XStorage xDest )
+ {
+ // move element with name sName from xSource to xDest
+ try
+ {
+ xSource.moveElementTo( sName, xDest, sName );
+ }
+ catch( Exception e )
+ {
+ Error( "Element moving failed, exception: " + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean renameElement( XStorage xStorage, String sOldName, String sNewName )
+ {
+ // rename element with name sOldName to sNewName
+ try
+ {
+ xStorage.renameElement( sOldName, sNewName );
+ }
+ catch( Exception e )
+ {
+ Error( "Element renaming failed, exception: " + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean removeElement( XStorage xStorage, String sName )
+ {
+ // remove element with name sName
+ try
+ {
+ xStorage.removeElement( sName );
+ }
+ catch( Exception e )
+ {
+ Error( "Element removing failed, exception: " + e );
+ return false;
+ }
+
+ return true;
+ }
+
+ public XStream OpenStream( XStorage xStorage,
+ String sStreamName,
+ int nMode )
+ {
+ // open substream element
+ XStream xSubStream = null;
+ try
+ {
+ Object oSubStream = xStorage.openStreamElement( sStreamName, nMode );
+ xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
+ if ( xSubStream == null )
+ Error( "Can't create substream '" + sStreamName + "'!" );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't create substream '" + sStreamName + "', exception : " + e + "!" );
+ }
+
+ return xSubStream;
+ }
+
+ public boolean compareRawMethodsOnEncrStream( XStorage xStorage, String sStreamName )
+ {
+
+ XStorageRawAccess xRawStorage;
+ try
+ {
+ xRawStorage = (XStorageRawAccess) UnoRuntime.queryInterface( XStorageRawAccess.class, xStorage );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't get raw access to the storage, exception : " + e + "!" );
+ return false;
+ }
+
+ if ( xRawStorage == null )
+ {
+ Error( "Can't get raw access to the storage!" );
+ return false;
+ }
+
+ XInputStream xHeadRawStream = null;
+ try
+ {
+ xHeadRawStream = xRawStorage.getRawEncrStreamElement( sStreamName );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't open encrypted stream '" + sStreamName + "' in raw mode with header, exception : " + e + "!" );
+ }
+
+ XInputStream xPlainRawStream = null;
+ try
+ {
+ xPlainRawStream = xRawStorage.getPlainRawStreamElement( sStreamName );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't open encrypted stream '" + sStreamName + "' in raw mode with header, exception : " + e + "!" );
+ }
+
+ if ( xHeadRawStream == null || xPlainRawStream == null )
+ {
+ Error( "Can't open encrypted stream '" + sStreamName + "' in raw modes!" );
+ return false;
+ }
+
+ try
+ {
+ byte pData[][] = new byte[1][22];
+ if ( xHeadRawStream.readBytes( pData, 22 ) != 22 )
+ {
+ Error( "Can't read header of encrypted stream '" + sStreamName + "' raw representations!" );
+ return false;
+ }
+
+ if ( pData[0][0] != 0x4d || pData[0][1] != 0x47 || pData[0][2] != 0x02 || pData[0][3] != 0x05 )
+ {
+ Error( "No signature in the header of encrypted stream '" + sStreamName + "' raw representations!" );
+ return false;
+ }
+
+ int nVariableHeaderLength =
+ ( pData[0][14] + pData[0][15] * 0x100 ) // salt length
+ + ( pData[0][16] + pData[0][17] * 0x100 ) // iv length
+ + ( pData[0][18] + pData[0][19] * 0x100 ) // digest length
+ + ( pData[0][20] + pData[0][21] * 0x100 ); // mediatype length
+
+ xHeadRawStream.skipBytes( nVariableHeaderLength );
+
+ byte pRawData1[][] = new byte[1][32000];
+ byte pRawData2[][] = new byte[1][32000];
+ int nRead1 = 0;
+ int nRead2 = 0;
+
+ do
+ {
+ nRead1 = xHeadRawStream.readBytes( pRawData1, 32000 );
+ nRead2 = xPlainRawStream.readBytes( pRawData2, 32000 );
+
+ if ( nRead1 != nRead2 )
+ {
+ Error( "The encrypted stream '" + sStreamName + "' raw representations have different size!" );
+ return false;
+ }
+
+ for ( int nInd = 0; nInd < nRead1; nInd++ )
+ if ( pRawData1[0][nInd] != pRawData2[0][nInd] )
+ {
+ Error( "The encrypted stream '" + sStreamName + "' raw representations have different data!" );
+ return false;
+ }
+ }
+ while( nRead1 == 32000 );
+ }
+ catch ( Exception e )
+ {
+ Error( "Can't compare stream '" + sStreamName + "' raw representations, exception : " + e + "!" );
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean cantOpenStorage( XStorage xStorage, String sName )
+ {
+ // try to open an opened substorage, open call must fail
+ try
+ {
+ Object oDummyStorage = xStorage.openStorageElement( sName, ElementModes.READ );
+ Error( "The trying to reopen opened substorage '" + sName + "' must fail!" );
+ }
+ catch( Exception e )
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean cantOpenStream( XStorage xStorage, String sName, int nMode )
+ {
+ // try to open the substream with specified mode must fail
+ try
+ {
+ Object oDummyStream = xStorage.openStreamElement( sName, nMode );
+ Error( "The trying to open substream '" + sName + "' must fail!" );
+ }
+ catch( Exception e )
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean cantOpenStreamH( XStorage xStorage, String sPath, int nMode )
+ {
+ // try to open the substream with specified mode must fail
+
+ XHierarchicalStorageAccess xHStorage =
+ (XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xStorage );
+ if ( xHStorage == null )
+ {
+ Error( "The storage does not support hierarchical access!" );
+ return false;
+ }
+
+ try
+ {
+ Object oDummyStream = xHStorage.openStreamElementByHierarchicalName( sPath, nMode );
+ Error( "The trying to open substream '" + sPath + "' must fail!" );
+ }
+ catch( Exception e )
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean cantOpenEncrStreamH( XStorage xStorage, String sPath, int nMode, String aPass )
+ {
+ // try to open the substream with specified mode must fail
+
+ XHierarchicalStorageAccess xHStorage =
+ (XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xStorage );
+ if ( xHStorage == null )
+ {
+ Error( "The storage does not support hierarchical access!" );
+ return false;
+ }
+
+ try
+ {
+ Object oDummyStream = xHStorage.openEncryptedStreamElementByHierarchicalName( sPath, nMode, aPass );
+ Error( "The trying to open substream '" + sPath + "' must fail!" );
+ }
+ catch( WrongPasswordException wpe )
+ {
+ Error( "The substream '" + sPath + "' must not exist!" );
+ return false;
+ }
+ catch( Exception e )
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public XStorage cloneStorage( XSingleServiceFactory xFactory, XStorage xStorage )
+ {
+ // create a copy of a last commited version of specified storage
+ XStorage xResult = null;
+ try
+ {
+ Object oTempStorage = xFactory.createInstance();
+ xResult = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xResult != null )
+ xStorage.copyLastCommitTo( xResult );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't clone storage, exception: " + e );
+ return null;
+ }
+
+ return xResult;
+ }
+
+ public XStorage cloneSubStorage( XSingleServiceFactory xFactory, XStorage xStorage, String sName )
+ {
+ // create a copy of a last commited version of specified substorage
+ XStorage xResult = null;
+ try
+ {
+ Object oTempStorage = xFactory.createInstance();
+ xResult = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
+ if ( xResult != null )
+ xStorage.copyStorageElementLastCommitTo( sName, xResult );
+ }
+ catch( Exception e )
+ {
+ Error( "Can't clone substorage '" + sName + "', exception: " + e );
+ return null;
+ }
+
+ return xResult;
+ }
+
+ public XStream cloneSubStream( XStorage xStorage, String sName )
+ {
+ // clone existing substream
+ try
+ {
+ XStream xStream = xStorage.cloneStreamElement( sName );
+ return xStream;
+ }
+ catch( Exception e )
+ {
+ Error( "Can't clone substream '" + sName + "', exception: " + e );
+ }
+
+ return null;
+ }
+
+ public XStream cloneEncrSubStream( XStorage xStorage, String sName, String sPass )
+ {
+ // clone existing substream
+ try
+ {
+ XStream xStream = xStorage.cloneEncryptedStreamElement( sName, sPass );
+ return xStream;
+ }
+ catch( Exception e )
+ {
+ Error( "Can't clone encrypted substream '" + sName + "', exception: " + e );
+ }
+
+ return null;
+ }
+
+ public void Error( String sError )
+ {
+ m_aLogWriter.println( m_sTestPrefix + "Error: " + sError );
+ }
+
+ public void Message( String sMessage )
+ {
+ m_aLogWriter.println( m_sTestPrefix + sMessage );
+ }
+}
+
diff --git a/package/qa/storages/makefile.mk b/package/qa/storages/makefile.mk
new file mode 100644
index 000000000000..95fe75a03e74
--- /dev/null
+++ b/package/qa/storages/makefile.mk
@@ -0,0 +1,116 @@
+#*************************************************************************
+#
+# 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 = ..$/..
+TARGET = StorageUnitTest
+PRJNAME = package
+PACKAGE = complex$/storages
+
+# --- Settings -----------------------------------------------------
+.INCLUDE: settings.mk
+
+
+#----- compile .java files -----------------------------------------
+
+JARFILES = ridl.jar unoil.jar jurt.jar juh.jar java_uno.jar OOoRunner.jar
+
+JAVAFILES =\
+ StorageUnitTest.java\
+ StorageTest.java\
+ TestHelper.java\
+ BorderedStream.java\
+ Test01.java\
+ Test02.java\
+ Test03.java\
+ Test04.java\
+ Test05.java\
+ Test06.java\
+ Test07.java\
+ Test08.java\
+ Test09.java\
+ Test10.java\
+ Test11.java\
+ Test12.java\
+ Test13.java\
+ Test14.java\
+ Test15.java\
+ Test16.java\
+ Test17.java\
+ Test18.java\
+ RegressionTest_114358.java\
+ RegressionTest_i29169.java\
+ RegressionTest_i30400.java\
+ RegressionTest_i29321.java\
+ RegressionTest_i30677.java\
+ RegressionTest_i27773.java\
+ RegressionTest_i46848.java\
+ RegressionTest_i55821.java\
+ RegressionTest_i35095.java\
+ RegressionTest_i49755.java\
+ RegressionTest_i59886.java\
+ RegressionTest_i61909.java\
+ RegressionTest_i84234.java\
+ RegressionTest_125919.java
+
+JAVACLASSFILES = $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class)
+
+#----- make a jar from compiled files ------------------------------
+
+MAXLINELENGTH = 100000
+
+JARCLASSDIRS = $(PACKAGE)
+JARTARGET = $(TARGET).jar
+JARCOMPRESS = TRUE
+
+# --- Parameters for the test --------------------------------------
+
+# start an office if the parameter is set for the makefile
+.IF "$(OFFICE)" == ""
+CT_APPEXECCOMMAND =
+.ELSE
+CT_APPEXECCOMMAND = -AppExecutionCommand "$(OFFICE)$/soffice -accept=socket,host=localhost,port=8100;urp;"
+.ENDIF
+
+# test base is java complex
+CT_TESTBASE = -TestBase java_complex
+
+# test looks something like the.full.package.TestName
+CT_TEST = -o $(PACKAGE:s\$/\.\).$(JAVAFILES:b)
+
+# start the runner application
+CT_APP = org.openoffice.Runner
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE: target.mk
+
+RUN: run
+
+run:
+ java -cp $(CLASSPATH) $(CT_APP) $(CT_TESTBASE) $(CT_APPEXECCOMMAND) $(CT_TEST)
+
+
diff --git a/package/source/manifest/Base64Codec.cxx b/package/source/manifest/Base64Codec.cxx
new file mode 100644
index 000000000000..b9ffed0b0514
--- /dev/null
+++ b/package/source/manifest/Base64Codec.cxx
@@ -0,0 +1,204 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include "Base64Codec.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+using namespace rtl;
+using namespace osl;
+using namespace com::sun::star;
+
+const
+ sal_Char aBase64EncodeTable[] =
+ { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };
+
+const
+ sal_uInt8 aBase64DecodeTable[] =
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, // 32-47
+// + /
+
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, // 48-63
+// 0 1 2 3 4 5 6 7 8 9 =
+
+ 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79
+// A B C D E F G H I J K L M N O
+
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, // 80-95
+// P Q R S T U V W X Y Z
+
+ 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
+// a b c d e f g h i j k l m n o
+
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, // 112-127
+// p q r s t u v w x y z
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+
+void ThreeByteToFourByte (const sal_uInt8* pBuffer, const sal_Int32 nStart, const sal_Int32 nFullLen, rtl::OUStringBuffer& sBuffer)
+{
+ sal_Int32 nLen(nFullLen - nStart);
+ if (nLen > 3)
+ nLen = 3;
+ if (nLen == 0)
+ {
+ sBuffer.setLength(0);
+ return;
+ }
+
+ sal_Int32 nBinaer;
+ switch (nLen)
+ {
+ case 1:
+ {
+ nBinaer = ((sal_uInt8)pBuffer[nStart + 0]) << 16;
+ }
+ break;
+ case 2:
+ {
+ nBinaer = (((sal_uInt8)pBuffer[nStart + 0]) << 16) +
+ (((sal_uInt8)pBuffer[nStart + 1]) << 8);
+ }
+ break;
+ default:
+ {
+ nBinaer = (((sal_uInt8)pBuffer[nStart + 0]) << 16) +
+ (((sal_uInt8)pBuffer[nStart + 1]) << 8) +
+ ((sal_uInt8)pBuffer[nStart + 2]);
+ }
+ break;
+ }
+
+ sBuffer.appendAscii("====");
+
+ sal_uInt8 nIndex = static_cast< sal_uInt8 >((nBinaer & 0xFC0000) >> 18);
+ sBuffer.setCharAt(0, aBase64EncodeTable [nIndex]);
+
+ nIndex = static_cast< sal_uInt8 >((nBinaer & 0x3F000) >> 12);
+ sBuffer.setCharAt(1, aBase64EncodeTable [nIndex]);
+ if (nLen == 1)
+ return;
+
+ nIndex = static_cast< sal_uInt8 >((nBinaer & 0xFC0) >> 6);
+ sBuffer.setCharAt(2, aBase64EncodeTable [nIndex]);
+ if (nLen == 2)
+ return;
+
+ nIndex = static_cast< sal_uInt8 >(nBinaer & 0x3F);
+ sBuffer.setCharAt(3, aBase64EncodeTable [nIndex]);
+}
+
+void Base64Codec::encodeBase64(rtl::OUStringBuffer& aStrBuffer, const uno::Sequence < sal_uInt8 >& aPass)
+{
+ sal_Int32 i(0);
+ sal_Int32 nBufferLength(aPass.getLength());
+ const sal_uInt8* pBuffer = aPass.getConstArray();
+ while (i < nBufferLength)
+ {
+ rtl::OUStringBuffer sBuffer;
+ ThreeByteToFourByte (pBuffer, i, nBufferLength, sBuffer);
+ aStrBuffer.append(sBuffer);
+ i += 3;
+ }
+}
+
+const rtl::OUString s2equal(RTL_CONSTASCII_USTRINGPARAM("=="));
+const rtl::OUString s1equal(RTL_CONSTASCII_USTRINGPARAM("="));
+
+void FourByteToThreeByte (sal_uInt8* pBuffer, sal_Int32& nLength, const sal_Int32 nStart, const rtl::OUString& sString)
+{
+ nLength = 0;
+ sal_Int32 nLen (sString.getLength());
+
+ OSL_ASSERT( nLen == 4 );
+ if (nLen != 4)
+ return;
+
+ if (sString.indexOf(s2equal) == 2)
+ nLength = 1;
+ else if (sString.indexOf(s1equal) == 3)
+ nLength = 2;
+ else
+ nLength = 3;
+
+ sal_Int32 nBinaer ((aBase64DecodeTable [sString [0]] << 18) +
+ (aBase64DecodeTable [sString [1]] << 12) +
+ (aBase64DecodeTable [sString [2]] << 6) +
+ (aBase64DecodeTable [sString [3]]));
+
+ sal_uInt8 OneByte = static_cast< sal_uInt8 >((nBinaer & 0xFF0000) >> 16);
+ pBuffer[nStart + 0] = (sal_uInt8)OneByte;
+
+ if (nLength == 1)
+ return;
+
+ OneByte = static_cast< sal_uInt8 >((nBinaer & 0xFF00) >> 8);
+ pBuffer[nStart + 1] = OneByte;
+
+ if (nLength == 2)
+ return;
+
+ OneByte = static_cast< sal_uInt8 >(nBinaer & 0xFF);
+ pBuffer[nStart + 2] = OneByte;
+}
+
+void Base64Codec::decodeBase64(uno::Sequence< sal_uInt8 >& aBuffer, const rtl::OUString& sBuffer)
+{
+ sal_Int32 nFirstLength((sBuffer.getLength() / 4) * 3);
+ sal_uInt8* pBuffer = new sal_uInt8[nFirstLength];
+ sal_Int32 nSecondLength(0);
+ sal_Int32 nLength(0);
+ sal_Int32 i = 0;
+ sal_Int32 k = 0;
+ while (i < sBuffer.getLength())
+ {
+ FourByteToThreeByte (pBuffer, nLength, k, sBuffer.copy(i, 4));
+ nSecondLength += nLength;
+ nLength = 0;
+ i += 4;
+ k += 3;
+ }
+ aBuffer = uno::Sequence<sal_uInt8>(pBuffer, nSecondLength);
+ delete[] pBuffer;
+}
diff --git a/package/source/manifest/Base64Codec.hxx b/package/source/manifest/Base64Codec.hxx
new file mode 100644
index 000000000000..04398c7bba29
--- /dev/null
+++ b/package/source/manifest/Base64Codec.hxx
@@ -0,0 +1,45 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _BASE64_CODEC_HXX
+#define _BASE64_CODEC_HXX
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+namespace rtl
+{
+class OUString;
+class OUStringBuffer;
+}
+
+class Base64Codec
+{
+public:
+ static void encodeBase64(rtl::OUStringBuffer& aStrBuffer, const com::sun::star::uno::Sequence<sal_uInt8>& aPass);
+ static void decodeBase64(com::sun::star::uno::Sequence<sal_uInt8>& aPass, const rtl::OUString& sBuffer);
+};
+#endif
diff --git a/package/source/manifest/ManifestDefines.hxx b/package/source/manifest/ManifestDefines.hxx
new file mode 100644
index 000000000000..d53337236bb2
--- /dev/null
+++ b/package/source/manifest/ManifestDefines.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _MANIFEST_DEFINES_HXX
+#define _MANIFEST_DEFINES_HXX
+
+#include <PackageConstants.hxx>
+
+#define MANIFEST_NSPREFIX "manifest:"
+#define ELEMENT_MANIFEST "manifest:manifest"
+#define ATTRIBUTE_XMLNS "xmlns:manifest"
+#define MANIFEST_NAMESPACE "http://openoffice.org/2001/manifest"
+#define MANIFEST_OASIS_NAMESPACE "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"
+#define MANIFEST_DOCTYPE "<!DOCTYPE manifest:manifest PUBLIC \"-//OpenOffice.org//DTD Manifest 1.0//EN\" \"Manifest.dtd\">"
+#define ATTRIBUTE_CDATA "CDATA"
+
+#define ELEMENT_FILE_ENTRY "manifest:file-entry"
+#define ATTRIBUTE_FULL_PATH "manifest:full-path"
+#define ATTRIBUTE_VERSION "manifest:version"
+#define ATTRIBUTE_MEDIA_TYPE "manifest:media-type"
+#define ATTRIBUTE_SIZE "manifest:size"
+
+#define ELEMENT_ENCRYPTION_DATA "manifest:encryption-data"
+#define ATTRIBUTE_CHECKSUM_TYPE "manifest:checksum-type"
+#define ATTRIBUTE_CHECKSUM "manifest:checksum"
+
+#define ELEMENT_ALGORITHM "manifest:algorithm"
+#define ATTRIBUTE_ALGORITHM_NAME "manifest:algorithm-name"
+#define ATTRIBUTE_INITIALISATION_VECTOR "manifest:initialisation-vector"
+
+#define ELEMENT_START_KEY_GENERATION "manifest:start-key-generation"
+#define ATTRIBUTE_START_KEY_GENERATION_NAME "manifest:start-key-generation-name"
+#define ALGORITHM_SHA1 "SHA1"
+#define ATTRIBUTE_KEY_SIZE "manifest:key-size"
+#define START_KEY_SIZE "20"
+
+#define ELEMENT_KEY_DERIVATION "manifest:key-derivation"
+#define ATTRIBUTE_KEY_DERIVATION_NAME "manifest:key-derivation-name"
+#define ATTRIBUTE_SALT "manifest:salt"
+#define ATTRIBUTE_ITERATION_COUNT "manifest:iteration-count"
+#define CHECKSUM_TYPE "SHA1/1K"
+#define DERIVED_KEY_SIZE "16"
+
+#endif
diff --git a/package/source/manifest/ManifestExport.cxx b/package/source/manifest/ManifestExport.cxx
new file mode 100644
index 000000000000..e4b9ec533c60
--- /dev/null
+++ b/package/source/manifest/ManifestExport.cxx
@@ -0,0 +1,323 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ManifestExport.hxx>
+#include <ManifestDefines.hxx>
+#ifndef _COM_SUN_STAR_XML_SAX_XATTRIBUTELIST_HXX
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#endif
+#include <rtl/ustrbuf.hxx>
+#ifndef _BASE64_CODEC_HXX_
+#include <Base64Codec.hxx>
+#endif
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#ifndef _COM_SUN_STAR_XML_SAX_XDOCUMENTHANDLER_HXX
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#endif
+#ifndef _COM_SUN_STAR_XML_BEANS_PROPERTYVALUE_HPP
+#include <com/sun/star/beans/PropertyValue.hpp>
+#endif
+
+#include <comphelper/documentconstants.hxx>
+#include <comphelper/attributelist.hxx>
+
+using namespace rtl;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::xml::sax;
+
+ManifestExport::ManifestExport(Reference < XDocumentHandler > xHandler, const Sequence < Sequence < PropertyValue > > &rManList )
+{
+ const OUString sFileEntryElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_FILE_ENTRY ) );
+ const OUString sManifestElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_MANIFEST ) );
+ const OUString sEncryptionDataElement( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_ENCRYPTION_DATA ) );
+ const OUString sAlgorithmElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_ALGORITHM ) );
+ const OUString sStartKeyGenerationElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_START_KEY_GENERATION ) );
+ const OUString sKeyDerivationElement( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_KEY_DERIVATION ) );
+
+ const OUString sCdataAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CDATA ) );
+ const OUString sMediaTypeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_MEDIA_TYPE ) );
+ const OUString sVersionAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_VERSION ) );
+ const OUString sFullPathAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_FULL_PATH ) );
+ const OUString sSizeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_SIZE ) );
+ const OUString sKeySizeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_KEY_SIZE ) );
+ const OUString sSaltAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_SALT ) );
+ const OUString sInitialisationVectorAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_INITIALISATION_VECTOR ) );
+ const OUString sIterationCountAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ITERATION_COUNT ) );
+ const OUString sAlgorithmNameAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ALGORITHM_NAME ) );
+ const OUString sStartKeyGenerationNameAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_START_KEY_GENERATION_NAME ) );
+ const OUString sKeyDerivationNameAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_KEY_DERIVATION_NAME ) );
+ const OUString sChecksumTypeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM_TYPE ) );
+ const OUString sChecksumAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM) );
+
+ const OUString sFullPathProperty ( RTL_CONSTASCII_USTRINGPARAM ( "FullPath" ) );
+ const OUString sVersionProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Version" ) );
+ const OUString sMediaTypeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) );
+ const OUString sIterationCountProperty ( RTL_CONSTASCII_USTRINGPARAM ( "IterationCount" ) );
+ const OUString sSaltProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Salt" ) );
+ const OUString sInitialisationVectorProperty( RTL_CONSTASCII_USTRINGPARAM ( "InitialisationVector" ) );
+ const OUString sSizeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Size" ) );
+ const OUString sDigestProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Digest" ) );
+
+ const OUString sWhiteSpace ( RTL_CONSTASCII_USTRINGPARAM ( " " ) );
+ const OUString sBlowfish ( RTL_CONSTASCII_USTRINGPARAM ( "Blowfish CFB" ) );
+ const OUString sPBKDF2 ( RTL_CONSTASCII_USTRINGPARAM ( "PBKDF2" ) );
+ const OUString sChecksumType ( RTL_CONSTASCII_USTRINGPARAM ( CHECKSUM_TYPE ) );
+ const OUString sStartKeySize ( RTL_CONSTASCII_USTRINGPARAM ( START_KEY_SIZE ) );
+ const OUString sDerivedKeySize ( RTL_CONSTASCII_USTRINGPARAM ( DERIVED_KEY_SIZE ) );
+ const OUString sSHA1 ( RTL_CONSTASCII_USTRINGPARAM ( ALGORITHM_SHA1 ) );
+
+ ::comphelper::AttributeList * pRootAttrList = new ::comphelper::AttributeList;
+ const Sequence < PropertyValue > *pSequence = rManList.getConstArray();
+ const sal_uInt32 nManLength = rManList.getLength();
+
+ // find the mediatype of the document if any
+ OUString aDocMediaType;
+ OUString aDocVersion;
+ for (sal_uInt32 nInd = 0; nInd < nManLength ; nInd++ )
+ {
+ OUString aMediaType;
+ OUString aPath;
+ OUString aVersion;
+
+ const PropertyValue *pValue = pSequence[nInd].getConstArray();
+ for (sal_uInt32 j = 0, nNum = pSequence[nInd].getLength(); j < nNum; j++, pValue++)
+ {
+ if (pValue->Name.equals (sMediaTypeProperty) )
+ {
+ pValue->Value >>= aMediaType;
+ }
+ else if (pValue->Name.equals (sFullPathProperty) )
+ {
+ pValue->Value >>= aPath;
+ }
+ else if (pValue->Name.equals (sVersionProperty) )
+ {
+ pValue->Value >>= aVersion;
+ }
+
+ if ( aPath.getLength() && aMediaType.getLength() && aVersion.getLength() )
+ break;
+ }
+
+ if ( aPath.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ) ) )
+ {
+ aDocMediaType = aMediaType;
+ aDocVersion = aVersion;
+ break;
+ }
+ }
+
+ sal_Bool bProvideDTD = sal_False;
+ sal_Bool bAcceptNonemptyVersion = sal_False;
+ sal_Bool bStoreStartKeyGeneration = sal_False;
+ if ( aDocMediaType.getLength() )
+ {
+ if ( aDocMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII ) ) )
+ || aDocMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII ) ) )
+ || aDocMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII ) ) )
+ || aDocMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII ) ) )
+ || aDocMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII ) ) )
+ || aDocMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII ) ) )
+ || aDocMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII ) ) )
+ || aDocMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII ) ) )
+ || aDocMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII ) ) )
+
+ || aDocMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII ) ) )
+ || aDocMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII ) ) )
+ || aDocMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII ) ) )
+ || aDocMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII ) ) )
+ || aDocMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_CHART_TEMPLATE_ASCII ) ) )
+ || aDocMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII ) ) ) )
+
+ {
+ // oasis format
+ pRootAttrList->AddAttribute ( OUString( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_XMLNS ) ),
+ sCdataAttribute,
+ OUString( RTL_CONSTASCII_USTRINGPARAM ( MANIFEST_OASIS_NAMESPACE ) ) );
+ bAcceptNonemptyVersion = sal_True;
+ if ( aDocVersion.compareTo( ODFVER_012_TEXT ) >= 0 )
+ {
+ // this is ODF12 generation, let encrypted streams contain start-key-generation entry
+ bStoreStartKeyGeneration = sal_True;
+ }
+ }
+ else
+ {
+ // even if it is no SO6 format the namespace must be specified
+ // thus SO6 format is used as default one
+ pRootAttrList->AddAttribute ( OUString( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_XMLNS ) ),
+ sCdataAttribute,
+ OUString( RTL_CONSTASCII_USTRINGPARAM ( MANIFEST_NAMESPACE ) ) );
+
+ bProvideDTD = sal_True;
+ }
+ }
+
+ Reference < XAttributeList > xRootAttrList (pRootAttrList);
+
+ xHandler->startDocument();
+ Reference < XExtendedDocumentHandler > xExtHandler ( xHandler, UNO_QUERY );
+ if ( xExtHandler.is() && bProvideDTD )
+ {
+ OUString aDocType ( RTL_CONSTASCII_USTRINGPARAM ( MANIFEST_DOCTYPE ) );
+ xExtHandler->unknown ( aDocType );
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ }
+ xHandler->startElement( sManifestElement, xRootAttrList );
+
+ for (sal_uInt32 i = 0 ; i < nManLength ; i++)
+ {
+ ::comphelper::AttributeList *pAttrList = new ::comphelper::AttributeList;
+ const PropertyValue *pValue = pSequence[i].getConstArray();
+ OUString aString;
+ const PropertyValue *pVector = NULL, *pSalt = NULL, *pIterationCount = NULL, *pDigest = NULL;
+ for (sal_uInt32 j = 0, nNum = pSequence[i].getLength(); j < nNum; j++, pValue++)
+ {
+ if (pValue->Name.equals (sMediaTypeProperty) )
+ {
+ pValue->Value >>= aString;
+ pAttrList->AddAttribute ( sMediaTypeAttribute, sCdataAttribute, aString );
+ }
+ else if (pValue->Name.equals (sVersionProperty) )
+ {
+ pValue->Value >>= aString;
+ // the version is stored only if it is not empty
+ if ( bAcceptNonemptyVersion && aString.getLength() )
+ pAttrList->AddAttribute ( sVersionAttribute, sCdataAttribute, aString );
+ }
+ else if (pValue->Name.equals (sFullPathProperty) )
+ {
+ pValue->Value >>= aString;
+ pAttrList->AddAttribute ( sFullPathAttribute, sCdataAttribute, aString );
+ }
+ else if (pValue->Name.equals (sSizeProperty) )
+ {
+ sal_Int32 nSize = 0;
+ pValue->Value >>= nSize;
+ OUStringBuffer aBuffer;
+ aBuffer.append ( nSize );
+ pAttrList->AddAttribute ( sSizeAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
+ }
+ else if (pValue->Name.equals (sInitialisationVectorProperty) )
+ pVector = pValue;
+ else if (pValue->Name.equals (sSaltProperty) )
+ pSalt = pValue;
+ else if (pValue->Name.equals (sIterationCountProperty) )
+ pIterationCount = pValue;
+ else if (pValue->Name.equals ( sDigestProperty ) )
+ pDigest = pValue;
+ }
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ Reference < XAttributeList > xAttrList ( pAttrList );
+ xHandler->startElement( sFileEntryElement , xAttrList);
+ if ( pVector && pSalt && pIterationCount )
+ {
+ // ==== Encryption Data
+ ::comphelper::AttributeList * pNewAttrList = new ::comphelper::AttributeList;
+ Reference < XAttributeList > xNewAttrList (pNewAttrList);
+ OUStringBuffer aBuffer;
+ Sequence < sal_uInt8 > aSequence;
+
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ if ( pDigest )
+ {
+ pNewAttrList->AddAttribute ( sChecksumTypeAttribute, sCdataAttribute, sChecksumType );
+ pDigest->Value >>= aSequence;
+ Base64Codec::encodeBase64 ( aBuffer, aSequence );
+ pNewAttrList->AddAttribute ( sChecksumAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
+ }
+ xHandler->startElement( sEncryptionDataElement , xNewAttrList);
+
+ // ==== Algorithm
+ pNewAttrList = new ::comphelper::AttributeList;
+ xNewAttrList = pNewAttrList;
+
+ pNewAttrList->AddAttribute ( sAlgorithmNameAttribute, sCdataAttribute, sBlowfish );
+
+ pVector->Value >>= aSequence;
+ Base64Codec::encodeBase64 ( aBuffer, aSequence );
+ pNewAttrList->AddAttribute ( sInitialisationVectorAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
+
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ xHandler->startElement( sAlgorithmElement , xNewAttrList);
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ xHandler->endElement( sAlgorithmElement );
+
+ // ==== Key Derivation
+ pNewAttrList = new ::comphelper::AttributeList;
+ xNewAttrList = pNewAttrList;
+
+ pNewAttrList->AddAttribute ( sKeyDerivationNameAttribute, sCdataAttribute, sPBKDF2 );
+
+ if ( bStoreStartKeyGeneration )
+ pNewAttrList->AddAttribute ( sKeySizeAttribute, sCdataAttribute, sDerivedKeySize );
+
+ sal_Int32 nCount = 0;
+ pIterationCount->Value >>= nCount;
+ aBuffer.append (nCount);
+ pNewAttrList->AddAttribute ( sIterationCountAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
+
+ pSalt->Value >>= aSequence;
+ Base64Codec::encodeBase64 ( aBuffer, aSequence );
+ pNewAttrList->AddAttribute ( sSaltAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
+
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ xHandler->startElement( sKeyDerivationElement , xNewAttrList);
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ xHandler->endElement( sKeyDerivationElement );
+
+ // we have to store start-key-generation element as the last one to workaround the parsing problem
+ // in OOo3.1 and older versions
+ if ( bStoreStartKeyGeneration )
+ {
+ // ==== Start Key Generation
+ pNewAttrList = new ::comphelper::AttributeList;
+ xNewAttrList = pNewAttrList;
+
+ // currently SHA1 is used to generate 20-bytes start key
+ pNewAttrList->AddAttribute ( sStartKeyGenerationNameAttribute, sCdataAttribute, sSHA1 );
+ pNewAttrList->AddAttribute ( sKeySizeAttribute, sCdataAttribute, sStartKeySize );
+
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ xHandler->startElement( sStartKeyGenerationElement , xNewAttrList);
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ xHandler->endElement( sStartKeyGenerationElement );
+ }
+
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ xHandler->endElement( sEncryptionDataElement );
+ }
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ xHandler->endElement( sFileEntryElement );
+ }
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ xHandler->endElement( sManifestElement );
+ xHandler->endDocument();
+}
diff --git a/package/source/manifest/ManifestExport.hxx b/package/source/manifest/ManifestExport.hxx
new file mode 100644
index 000000000000..13407a9dbbe2
--- /dev/null
+++ b/package/source/manifest/ManifestExport.hxx
@@ -0,0 +1,46 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _MANIFEST_EXPORT_HXX
+#define _MANIFEST_EXPORT_HXX
+
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/uno/Reference.h>
+#include <rtl/ustring.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace beans { struct PropertyValue;}
+ namespace xml { namespace sax { class XDocumentHandler; } }
+} } }
+class ManifestExport
+{
+public:
+ ManifestExport(com::sun::star::uno::Reference < com::sun::star::xml::sax::XDocumentHandler > xHandler, const com::sun::star::uno::Sequence < com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > > &rManList );
+};
+
+#endif
+
diff --git a/package/source/manifest/ManifestImport.cxx b/package/source/manifest/ManifestImport.cxx
new file mode 100644
index 000000000000..85de919a9acf
--- /dev/null
+++ b/package/source/manifest/ManifestImport.cxx
@@ -0,0 +1,332 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER( update_precomp.py ): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ManifestImport.hxx>
+#include <ManifestDefines.hxx>
+#ifndef _BASE64_CODEC_HXX_
+#include <Base64Codec.hxx>
+#endif
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star;
+using namespace rtl;
+using namespace std;
+
+// ---------------------------------------------------
+ManifestImport::ManifestImport( vector < Sequence < PropertyValue > > & rNewManVector )
+: nNumProperty ( 0 )
+, bIgnoreEncryptData ( sal_False )
+, rManVector ( rNewManVector )
+
+, sFileEntryElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_FILE_ENTRY ) )
+, sManifestElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_MANIFEST ) )
+, sEncryptionDataElement( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_ENCRYPTION_DATA ) )
+, sAlgorithmElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_ALGORITHM ) )
+, sKeyDerivationElement( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_KEY_DERIVATION ) )
+
+, sCdataAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CDATA ) )
+, sMediaTypeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_MEDIA_TYPE ) )
+, sVersionAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_VERSION ) )
+, sFullPathAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_FULL_PATH ) )
+, sSizeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_SIZE ) )
+, sSaltAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_SALT ) )
+, sInitialisationVectorAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_INITIALISATION_VECTOR ) )
+, sIterationCountAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ITERATION_COUNT ) )
+, sAlgorithmNameAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ALGORITHM_NAME ) )
+, sKeyDerivationNameAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_KEY_DERIVATION_NAME ) )
+, sChecksumAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM ) )
+, sChecksumTypeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM_TYPE ) )
+
+, sFullPathProperty ( RTL_CONSTASCII_USTRINGPARAM ( "FullPath" ) )
+, sMediaTypeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) )
+, sVersionProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Version" ) )
+, sIterationCountProperty ( RTL_CONSTASCII_USTRINGPARAM ( "IterationCount" ) )
+, sSaltProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Salt" ) )
+, sInitialisationVectorProperty ( RTL_CONSTASCII_USTRINGPARAM ( "InitialisationVector" ) )
+, sSizeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Size" ) )
+, sDigestProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Digest" ) )
+
+, sWhiteSpace ( RTL_CONSTASCII_USTRINGPARAM ( " " ) )
+, sBlowfish ( RTL_CONSTASCII_USTRINGPARAM ( "Blowfish CFB" ) )
+, sPBKDF2 ( RTL_CONSTASCII_USTRINGPARAM ( "PBKDF2" ) )
+, sChecksumType ( RTL_CONSTASCII_USTRINGPARAM ( CHECKSUM_TYPE ) )
+{
+ aStack.reserve( 10 );
+}
+
+// ---------------------------------------------------
+ManifestImport::~ManifestImport ( void )
+{
+}
+
+// ---------------------------------------------------
+void SAL_CALL ManifestImport::startDocument( )
+ throw( xml::sax::SAXException, uno::RuntimeException )
+{
+}
+
+// ---------------------------------------------------
+void SAL_CALL ManifestImport::endDocument( )
+ throw( xml::sax::SAXException, uno::RuntimeException )
+{
+}
+
+// ---------------------------------------------------
+void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs )
+ throw( xml::sax::SAXException, uno::RuntimeException )
+{
+ StringHashMap aConvertedAttribs;
+ ::rtl::OUString aConvertedName = PushNameAndNamespaces( aName, xAttribs, aConvertedAttribs );
+
+ if ( aConvertedName == sFileEntryElement )
+ {
+ aSequence.realloc ( PKG_SIZE_ENCR_MNFST );
+
+ // Put full-path property first for MBA
+ aSequence[nNumProperty].Name = sFullPathProperty;
+ aSequence[nNumProperty++].Value <<= aConvertedAttribs[sFullPathAttribute];
+ aSequence[nNumProperty].Name = sMediaTypeProperty;
+ aSequence[nNumProperty++].Value <<= aConvertedAttribs[sMediaTypeAttribute];
+
+ OUString sVersion = aConvertedAttribs[sVersionAttribute];
+ if ( sVersion.getLength() )
+ {
+ aSequence[nNumProperty].Name = sVersionProperty;
+ aSequence[nNumProperty++].Value <<= sVersion;
+ }
+
+ OUString sSize = aConvertedAttribs[sSizeAttribute];
+ if ( sSize.getLength() )
+ {
+ sal_Int32 nSize;
+ nSize = sSize.toInt32();
+ aSequence[nNumProperty].Name = sSizeProperty;
+ aSequence[nNumProperty++].Value <<= nSize;
+ }
+ }
+ else if ( aStack.size() > 1 )
+ {
+ ManifestStack::reverse_iterator aIter = aStack.rbegin();
+ aIter++;
+
+ if ( aIter->m_aConvertedName.equals( sFileEntryElement ) )
+ {
+ if ( aConvertedName.equals( sEncryptionDataElement ) )
+ {
+ // If this element exists, then this stream is encrypted and we need
+ // to store the initialisation vector, salt and iteration count used
+ OUString aString = aConvertedAttribs[sChecksumTypeAttribute];
+ if ( aString == sChecksumType && !bIgnoreEncryptData )
+ {
+ aString = aConvertedAttribs[sChecksumAttribute];
+ Sequence < sal_uInt8 > aDecodeBuffer;
+ Base64Codec::decodeBase64 ( aDecodeBuffer, aString );
+ aSequence[nNumProperty].Name = sDigestProperty;
+ aSequence[nNumProperty++].Value <<= aDecodeBuffer;
+ }
+ }
+ }
+ else if ( aIter->m_aConvertedName.equals( sEncryptionDataElement ) )
+ {
+ if ( aConvertedName == sAlgorithmElement )
+ {
+ OUString aString = aConvertedAttribs[sAlgorithmNameAttribute];
+ if ( aString == sBlowfish && !bIgnoreEncryptData )
+ {
+ aString = aConvertedAttribs[sInitialisationVectorAttribute];
+ Sequence < sal_uInt8 > aDecodeBuffer;
+ Base64Codec::decodeBase64 ( aDecodeBuffer, aString );
+ aSequence[nNumProperty].Name = sInitialisationVectorProperty;
+ aSequence[nNumProperty++].Value <<= aDecodeBuffer;
+ }
+ else
+ // If we don't recognise the algorithm, then the key derivation info
+ // is useless to us
+ bIgnoreEncryptData = sal_True;
+ }
+ else if ( aConvertedName == sKeyDerivationElement )
+ {
+ OUString aString = aConvertedAttribs[sKeyDerivationNameAttribute];
+ if ( aString == sPBKDF2 && !bIgnoreEncryptData )
+ {
+ aString = aConvertedAttribs[sSaltAttribute];
+ Sequence < sal_uInt8 > aDecodeBuffer;
+ Base64Codec::decodeBase64 ( aDecodeBuffer, aString );
+ aSequence[nNumProperty].Name = sSaltProperty;
+ aSequence[nNumProperty++].Value <<= aDecodeBuffer;
+
+ aString = aConvertedAttribs[sIterationCountAttribute];
+ aSequence[nNumProperty].Name = sIterationCountProperty;
+ aSequence[nNumProperty++].Value <<= aString.toInt32();
+ }
+ else
+ // If we don't recognise the key derivation technique, then the
+ // algorithm info is useless to us
+ bIgnoreEncryptData = sal_True;
+ }
+ }
+ }
+}
+
+// ---------------------------------------------------
+void SAL_CALL ManifestImport::endElement( const OUString& aName )
+ throw( xml::sax::SAXException, uno::RuntimeException )
+{
+ ::rtl::OUString aConvertedName = ConvertName( aName );
+ if ( !aStack.empty() && aStack.rbegin()->m_aConvertedName.equals( aConvertedName ) )
+ {
+ if ( aConvertedName.equals( sFileEntryElement ) )
+ {
+ aSequence.realloc ( nNumProperty );
+ bIgnoreEncryptData = sal_False;
+ rManVector.push_back ( aSequence );
+ nNumProperty = 0;
+ }
+
+ aStack.pop_back();
+ }
+}
+
+// ---------------------------------------------------
+void SAL_CALL ManifestImport::characters( const OUString& /*aChars*/ )
+ throw( xml::sax::SAXException, uno::RuntimeException )
+{
+}
+
+// ---------------------------------------------------
+void SAL_CALL ManifestImport::ignorableWhitespace( const OUString& /*aWhitespaces*/ )
+ throw( xml::sax::SAXException, uno::RuntimeException )
+{
+}
+
+// ---------------------------------------------------
+void SAL_CALL ManifestImport::processingInstruction( const OUString& /*aTarget*/, const OUString& /*aData*/ )
+ throw( xml::sax::SAXException, uno::RuntimeException )
+{
+}
+
+// ---------------------------------------------------
+void SAL_CALL ManifestImport::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /*xLocator*/ )
+ throw( xml::sax::SAXException, uno::RuntimeException )
+{
+}
+
+// ---------------------------------------------------
+::rtl::OUString ManifestImport::PushNameAndNamespaces( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs, StringHashMap& o_aConvertedAttribs )
+{
+ StringHashMap aNamespaces;
+ ::std::vector< ::std::pair< ::rtl::OUString, ::rtl::OUString > > aAttribsStrs;
+
+ if ( xAttribs.is() )
+ {
+ sal_Int16 nAttrCount = xAttribs.is() ? xAttribs->getLength() : 0;
+ aAttribsStrs.reserve( nAttrCount );
+
+ for( sal_Int16 nInd = 0; nInd < nAttrCount; nInd++ )
+ {
+ ::rtl::OUString aAttrName = xAttribs->getNameByIndex( nInd );
+ ::rtl::OUString aAttrValue = xAttribs->getValueByIndex( nInd );
+ if ( aAttrName.getLength() >= 5
+ && aAttrName.compareToAscii( "xmlns", 5 ) == 0
+ && ( aAttrName.getLength() == 5 || aAttrName.getStr()[5] == ( sal_Unicode )':' ) )
+ {
+ // this is a namespace declaration
+ ::rtl::OUString aNsName( ( aAttrName.getLength() == 5 ) ? ::rtl::OUString() : aAttrName.copy( 6 ) );
+ aNamespaces[aNsName] = aAttrValue;
+ }
+ else
+ {
+ // this is no namespace declaration
+ aAttribsStrs.push_back( pair< ::rtl::OUString, ::rtl::OUString >( aAttrName, aAttrValue ) );
+ }
+ }
+ }
+
+ ::rtl::OUString aConvertedName = ConvertNameWithNamespace( aName, aNamespaces );
+ if ( !aConvertedName.getLength() )
+ aConvertedName = ConvertName( aName );
+
+ aStack.push_back( ManifestScopeEntry( aConvertedName, aNamespaces ) );
+
+ for ( sal_uInt16 nInd = 0; nInd < aAttribsStrs.size(); nInd++ )
+ {
+ // convert the attribute names on filling
+ o_aConvertedAttribs[ConvertName( aAttribsStrs[nInd].first )] = aAttribsStrs[nInd].second;
+ }
+
+ return aConvertedName;
+}
+
+// ---------------------------------------------------
+::rtl::OUString ManifestImport::ConvertNameWithNamespace( const ::rtl::OUString& aName, const StringHashMap& aNamespaces )
+{
+ ::rtl::OUString aNsAlias;
+ ::rtl::OUString aPureName = aName;
+
+ sal_Int32 nInd = aName.indexOf( ( sal_Unicode )':' );
+ if ( nInd != -1 && nInd < aName.getLength() )
+ {
+ aNsAlias = aName.copy( 0, nInd );
+ aPureName = aName.copy( nInd + 1 );
+ }
+
+ ::rtl::OUString aResult;
+
+ StringHashMap::const_iterator aIter = aNamespaces.find( aNsAlias );
+ if ( aIter != aNamespaces.end()
+ && ( aIter->second.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MANIFEST_NAMESPACE ) ) )
+ || aIter->second.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MANIFEST_OASIS_NAMESPACE ) ) ) ) )
+ {
+ // no check for manifest.xml consistency currently since the old versions have supported inconsistent documents as well
+ aResult = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MANIFEST_NSPREFIX ) );
+ aResult += aPureName;
+ }
+
+ return aResult;
+}
+
+// ---------------------------------------------------
+::rtl::OUString ManifestImport::ConvertName( const ::rtl::OUString& aName )
+{
+ ::rtl::OUString aConvertedName;
+ for ( ManifestStack::reverse_iterator aIter = aStack.rbegin(); !aConvertedName.getLength() && aIter != aStack.rend(); aIter++ )
+ {
+ if ( !aIter->m_aNamespaces.empty() )
+ aConvertedName = ConvertNameWithNamespace( aName, aIter->m_aNamespaces );
+ }
+
+ if ( !aConvertedName.getLength() )
+ aConvertedName = aName;
+
+ return aConvertedName;
+}
+
diff --git a/package/source/manifest/ManifestImport.hxx b/package/source/manifest/ManifestImport.hxx
new file mode 100644
index 000000000000..f83c8b6c49df
--- /dev/null
+++ b/package/source/manifest/ManifestImport.hxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _MANIFEST_IMPORT_HXX
+#define _MANIFEST_IMPORT_HXX
+
+#include <cppuhelper/implbase1.hxx> // helper for implementations
+#ifndef _COM_SUN_STAR_XML_SAX_XDUCUMENTHANDLER_HPP_
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#endif
+#include <vector>
+
+#include <HashMaps.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace xml { namespace sax { class XAttributeList; } }
+ namespace beans { struct PropertyValue; }
+} } }
+
+typedef ::std::hash_map< ::rtl::OUString, ::rtl::OUString, ::rtl::OUStringHash, eqFunc > StringHashMap;
+
+struct ManifestScopeEntry
+{
+ ::rtl::OUString m_aConvertedName;
+ StringHashMap m_aNamespaces;
+
+ ManifestScopeEntry( const ::rtl::OUString& aConvertedName, const StringHashMap& aNamespaces )
+ : m_aConvertedName( aConvertedName )
+ , m_aNamespaces( aNamespaces )
+ {}
+
+ ~ManifestScopeEntry()
+ {}
+};
+
+typedef ::std::vector< ManifestScopeEntry > ManifestStack;
+
+class ManifestImport : public cppu::WeakImplHelper1 < com::sun::star::xml::sax::XDocumentHandler >
+{
+protected:
+ com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > aSequence;
+ sal_Int16 nNumProperty;
+ ManifestStack aStack;
+ sal_Bool bIgnoreEncryptData;
+ ::std::vector < ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue > > & rManVector;
+
+ const ::rtl::OUString sFileEntryElement;
+ const ::rtl::OUString sManifestElement;
+ const ::rtl::OUString sEncryptionDataElement;
+ const ::rtl::OUString sAlgorithmElement;
+ const ::rtl::OUString sKeyDerivationElement;
+
+ const ::rtl::OUString sCdataAttribute;
+ const ::rtl::OUString sMediaTypeAttribute;
+ const ::rtl::OUString sVersionAttribute;
+ const ::rtl::OUString sFullPathAttribute;
+ const ::rtl::OUString sSizeAttribute;
+ const ::rtl::OUString sSaltAttribute;
+ const ::rtl::OUString sInitialisationVectorAttribute;
+ const ::rtl::OUString sIterationCountAttribute;
+ const ::rtl::OUString sAlgorithmNameAttribute;
+ const ::rtl::OUString sKeyDerivationNameAttribute;
+ const ::rtl::OUString sChecksumAttribute;
+ const ::rtl::OUString sChecksumTypeAttribute;
+
+ const ::rtl::OUString sFullPathProperty;
+ const ::rtl::OUString sMediaTypeProperty;
+ const ::rtl::OUString sVersionProperty;
+ const ::rtl::OUString sIterationCountProperty;
+ const ::rtl::OUString sSaltProperty;
+ const ::rtl::OUString sInitialisationVectorProperty;
+ const ::rtl::OUString sSizeProperty;
+ const ::rtl::OUString sDigestProperty;
+
+ const ::rtl::OUString sWhiteSpace;
+ const ::rtl::OUString sBlowfish;
+ const ::rtl::OUString sPBKDF2;
+ const ::rtl::OUString sChecksumType;
+
+
+ ::rtl::OUString PushNameAndNamespaces( const ::rtl::OUString& aName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttribs,
+ StringHashMap& o_aConvertedAttribs );
+ ::rtl::OUString ConvertNameWithNamespace( const ::rtl::OUString& aName, const StringHashMap& aNamespaces );
+ ::rtl::OUString ConvertName( const ::rtl::OUString& aName );
+
+public:
+ ManifestImport( std::vector < ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue > > & rNewVector );
+ ~ManifestImport( void );
+ virtual void SAL_CALL startDocument( )
+ throw(::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endDocument( )
+ throw(::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL startElement( const ::rtl::OUString& aName, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttribs )
+ throw(::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endElement( const ::rtl::OUString& aName )
+ throw(::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL characters( const ::rtl::OUString& aChars )
+ throw(::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces )
+ throw(::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData )
+ throw(::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setDocumentLocator( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >& xLocator )
+ throw(::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+};
+#endif
diff --git a/package/source/manifest/ManifestReader.cxx b/package/source/manifest/ManifestReader.cxx
new file mode 100644
index 000000000000..5beefc177b39
--- /dev/null
+++ b/package/source/manifest/ManifestReader.cxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ManifestReader.hxx>
+#include <ManifestImport.hxx>
+#include <cppuhelper/factory.hxx>
+#ifndef _COM_SUN_STAR_XML_SAX_XDOCUMENTHANDLER_HPP
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#endif
+#ifndef _COM_SUN_STAR_XML_SAX_SAXPARSEEXCEPTION_HPP
+#include <com/sun/star/xml/sax/SAXParseException.hpp>
+#endif
+#ifndef _COM_SUN_STAR_XML_SAX_XPARSER_HPP
+#include <com/sun/star/xml/sax/XParser.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#endif
+#include <vector>
+
+using namespace ::rtl;
+using namespace ::std;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::packages;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::packages::manifest;
+
+ManifestReader::ManifestReader( const Reference < XMultiServiceFactory > & xNewFactory )
+: xFactory ( xNewFactory )
+{
+}
+ManifestReader::~ManifestReader()
+{
+}
+Sequence< Sequence< PropertyValue > > SAL_CALL ManifestReader::readManifestSequence( const Reference< XInputStream >& rStream )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ Sequence < Sequence < PropertyValue > > aManifestSequence;
+ Reference < XParser > xParser (xFactory->createInstance ( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.xml.sax.Parser" ) ) ), UNO_QUERY );
+ if (xParser.is())
+ {
+ try
+ {
+ vector < Sequence < PropertyValue > > aManVector;
+ Reference < XDocumentHandler > xFilter = new ManifestImport( aManVector );
+ InputSource aParserInput;
+ aParserInput.aInputStream = rStream;
+ aParserInput.sSystemId = OUString ( RTL_CONSTASCII_USTRINGPARAM ( "META-INF/manifest.xml" ) );
+ xParser->setDocumentHandler ( xFilter );
+ xParser->parseStream( aParserInput );
+ aManifestSequence.realloc ( aManVector.size() );
+ Sequence < PropertyValue > * pSequence = aManifestSequence.getArray();
+ ::std::vector < Sequence < PropertyValue > >::const_iterator aIter = aManVector.begin();
+ ::std::vector < Sequence < PropertyValue > >::const_iterator aEnd = aManVector.end();
+ while( aIter != aEnd )
+ *pSequence++ = (*aIter++);
+ }
+ catch (SAXParseException& )
+ {
+ }
+ catch (SAXException& )
+ {
+ }
+ catch (IOException& )
+ {
+ }
+ }
+ xParser->setDocumentHandler ( Reference < XDocumentHandler > () );
+ return aManifestSequence;
+}
+// Component functions
+
+Reference < XInterface > SAL_CALL ManifestReader_createInstance( Reference< XMultiServiceFactory > const & rServiceFactory )
+{
+ return *new ManifestReader( rServiceFactory );
+}
+OUString ManifestReader::static_getImplementationName()
+{
+ return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.manifest.comp.ManifestReader" ) );
+}
+
+sal_Bool SAL_CALL ManifestReader::static_supportsService(OUString const & rServiceName)
+{
+ return rServiceName == getSupportedServiceNames()[0];
+}
+
+Sequence < OUString > ManifestReader::static_getSupportedServiceNames()
+{
+ Sequence < OUString > aNames(1);
+ aNames[0] = OUString(RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.manifest.ManifestReader" ) );
+ return aNames;
+}
+
+OUString ManifestReader::getImplementationName()
+ throw (RuntimeException)
+{
+ return static_getImplementationName();
+}
+
+sal_Bool SAL_CALL ManifestReader::supportsService(OUString const & rServiceName)
+ throw (RuntimeException)
+{
+ return static_supportsService ( rServiceName );
+}
+
+Sequence < OUString > ManifestReader::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return static_getSupportedServiceNames();
+}
+Reference < XSingleServiceFactory > ManifestReader::createServiceFactory( Reference < XMultiServiceFactory > const & rServiceFactory )
+{
+ return cppu::createSingleFactory (rServiceFactory,
+ static_getImplementationName(),
+ ManifestReader_createInstance,
+ static_getSupportedServiceNames());
+}
diff --git a/package/source/manifest/ManifestReader.hxx b/package/source/manifest/ManifestReader.hxx
new file mode 100644
index 000000000000..92c99587f212
--- /dev/null
+++ b/package/source/manifest/ManifestReader.hxx
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _MANIFEST_READER_HXX
+#define _MANIFEST_READER_HXX
+
+#include <cppuhelper/implbase2.hxx>
+#ifndef _COM_SUN_STAR_PACKAGES_MANIFEST_XMANIFESTREADER_HPP
+#include <com/sun/star/packages/manifest/XManifestReader.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_XPSERVICEINFO_HPP_
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#endif
+
+namespace com { namespace sun { namespace star {
+ namespace lang { class XMultiServiceFactory; class XSingleServiceFactory; }
+} } }
+
+class ManifestReader: public ::cppu::WeakImplHelper2
+<
+ ::com::sun::star::packages::manifest::XManifestReader,
+ ::com::sun::star::lang::XServiceInfo
+>
+{
+protected:
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory;
+public:
+ ManifestReader( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xNewFactory );
+ virtual ~ManifestReader();
+
+ // XManifestReader
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > > SAL_CALL readManifestSequence( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rStream )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // Component constructor
+ static ::rtl::OUString static_getImplementationName();
+ static ::com::sun::star::uno::Sequence < ::rtl::OUString > static_getSupportedServiceNames();
+ sal_Bool SAL_CALL static_supportsService(rtl::OUString const & rServiceName);
+ static ::com::sun::star::uno::Reference < com::sun::star::lang::XSingleServiceFactory > createServiceFactory( com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > const & rServiceFactory );
+};
+#endif
diff --git a/package/source/manifest/ManifestWriter.cxx b/package/source/manifest/ManifestWriter.cxx
new file mode 100644
index 000000000000..dc4dbea2486e
--- /dev/null
+++ b/package/source/manifest/ManifestWriter.cxx
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ManifestWriter.hxx>
+#include <ManifestExport.hxx>
+#include <cppuhelper/factory.hxx>
+#ifndef _COM_SUN_STAR_IO_XACTIVEDATASOURCE_HPP
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#endif
+#ifndef _COM_SUN_STAR_XML_SAX_XDOCUMENTHANDLER_HPP
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#endif
+#ifndef _COM_SUN_STAR_XML_SAX_SAXEXCEPTION_HPP
+#include <com/sun/star/xml/sax/SAXException.hpp>
+#endif
+
+#include <osl/diagnose.hxx>
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::packages;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::packages::manifest;
+
+ManifestWriter::ManifestWriter( const Reference < XMultiServiceFactory > & xNewFactory )
+: xFactory ( xNewFactory )
+{
+}
+ManifestWriter::~ManifestWriter()
+{
+}
+
+// XManifestWriter methods
+void SAL_CALL ManifestWriter::writeManifestSequence( const Reference< XOutputStream >& rStream, const Sequence< Sequence< PropertyValue > >& rSequence )
+ throw (RuntimeException)
+{
+ OUString sSaxWriter ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.xml.sax.Writer" ) );
+ Reference < XActiveDataSource > xSource ( xFactory->createInstance ( sSaxWriter ), UNO_QUERY );
+ if (xSource.is())
+ {
+ xSource->setOutputStream ( rStream );
+ Reference < XDocumentHandler > xHandler ( xSource, UNO_QUERY );
+ if (xHandler.is())
+ try {
+ ManifestExport aExporter ( xHandler, rSequence);
+ }
+ catch( SAXException& )
+ {
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+ }
+}
+
+// Component methods
+Reference < XInterface > SAL_CALL ManifestWriter_createInstance( Reference< XMultiServiceFactory > const & rServiceFactory )
+{
+ return *new ManifestWriter( rServiceFactory );
+}
+
+OUString ManifestWriter::static_getImplementationName()
+{
+ return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.manifest.comp.ManifestWriter" ) );
+}
+
+sal_Bool SAL_CALL ManifestWriter::static_supportsService(OUString const & rServiceName)
+{
+ return rServiceName == getSupportedServiceNames()[0];
+}
+Sequence < OUString > ManifestWriter::static_getSupportedServiceNames()
+{
+ Sequence < OUString > aNames(1);
+ aNames[0] = OUString(RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.manifest.ManifestWriter" ) );
+ return aNames;
+}
+
+OUString ManifestWriter::getImplementationName()
+ throw (RuntimeException)
+{
+ return static_getImplementationName();
+}
+
+sal_Bool SAL_CALL ManifestWriter::supportsService(OUString const & rServiceName)
+ throw (RuntimeException)
+{
+ return static_supportsService ( rServiceName );
+}
+Sequence < OUString > ManifestWriter::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return static_getSupportedServiceNames();
+}
+Reference < XSingleServiceFactory > ManifestWriter::createServiceFactory( Reference < XMultiServiceFactory > const & rServiceFactory )
+{
+ return cppu::createSingleFactory (rServiceFactory,
+ static_getImplementationName(),
+ ManifestWriter_createInstance,
+ static_getSupportedServiceNames());
+}
diff --git a/package/source/manifest/ManifestWriter.hxx b/package/source/manifest/ManifestWriter.hxx
new file mode 100644
index 000000000000..3c5097e55cb2
--- /dev/null
+++ b/package/source/manifest/ManifestWriter.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _MANIFEST_WRITER_HXX
+#define _MANIFEST_WRITER_HXX
+
+#include <cppuhelper/implbase2.hxx>
+#ifndef _COM_SUN_STAR_PACKAGES_MANIFEST_XMANIFESTWRITER_HPP
+#include <com/sun/star/packages/manifest/XManifestWriter.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_XPSERVICEINFO_HPP_
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#endif
+
+namespace com { namespace sun { namespace star {
+ namespace lang { class XMultiServiceFactory; class XSingleServiceFactory; }
+} } }
+
+class ManifestWriter: public ::cppu::WeakImplHelper2
+<
+ ::com::sun::star::packages::manifest::XManifestWriter,
+ ::com::sun::star::lang::XServiceInfo
+>
+{
+protected:
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory;
+public:
+ ManifestWriter( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xNewFactory );
+ virtual ~ManifestWriter();
+
+ // XManifestWriter
+ virtual void SAL_CALL writeManifestSequence( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& rStream, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > >& rSequence )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // Component constructor
+ static ::rtl::OUString static_getImplementationName();
+ static ::com::sun::star::uno::Sequence < ::rtl::OUString > static_getSupportedServiceNames();
+ static ::com::sun::star::uno::Reference < com::sun::star::lang::XSingleServiceFactory > createServiceFactory( com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > const & rServiceFactory );
+ sal_Bool SAL_CALL static_supportsService(rtl::OUString const & rServiceName);
+};
+#endif
+
diff --git a/package/source/manifest/UnoRegister.cxx b/package/source/manifest/UnoRegister.cxx
new file mode 100644
index 000000000000..2405495f321f
--- /dev/null
+++ b/package/source/manifest/UnoRegister.cxx
@@ -0,0 +1,154 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ManifestReader.hxx>
+#include <ManifestWriter.hxx>
+#include <cppuhelper/factory.hxx>
+#ifndef _COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HPP
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#endif
+#include <vos/diagnose.hxx>
+#include <ZipPackage.hxx>
+
+#include <zipfileaccess.hxx>
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::packages;
+using namespace ::com::sun::star::packages::manifest;
+
+static sal_Bool writeInfo( void * pRegistryKey,
+ const OUString & rImplementationName,
+ Sequence< OUString > const & rServiceNames )
+{
+ OUString aKeyName( OUString::createFromAscii( "/" ) );
+ aKeyName += rImplementationName;
+ aKeyName += OUString::createFromAscii( "/UNO/SERVICES" );
+
+ Reference< XRegistryKey > xKey;
+ try
+ {
+ xKey = static_cast< XRegistryKey * >(
+ pRegistryKey )->createKey( aKeyName );
+ }
+ catch ( InvalidRegistryException const & )
+ {
+ }
+
+ if ( !xKey.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = sal_True;
+
+ for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n )
+ {
+ try
+ {
+ xKey->createKey( rServiceNames[ n ] );
+ }
+ catch ( InvalidRegistryException const & )
+ {
+ bSuccess = sal_False;
+ break;
+ }
+ }
+ return bSuccess;
+}
+// C functions to implement this as a component
+
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+/**
+ * This function creates an implementation section in the registry and another subkey
+ * for each supported service.
+ * @param pServiceManager generic uno interface providing a service manager
+ * @param pRegistryKey generic uno interface providing registry key to write
+ */
+extern "C" sal_Bool SAL_CALL component_writeInfo( void* /*pServiceManager*/, void* pRegistryKey )
+{
+ return pRegistryKey &&
+ writeInfo (pRegistryKey,
+ ManifestReader::static_getImplementationName(),
+ ManifestReader::static_getSupportedServiceNames() ) &&
+ writeInfo (pRegistryKey,
+ ManifestWriter::static_getImplementationName(),
+ ManifestWriter::static_getSupportedServiceNames() ) &&
+ writeInfo (pRegistryKey,
+ ZipPackage::static_getImplementationName(),
+ ZipPackage::static_getSupportedServiceNames() ) &&
+
+ writeInfo (pRegistryKey,
+ OZipFileAccess::impl_staticGetImplementationName(),
+ OZipFileAccess::impl_staticGetSupportedServiceNames() );
+
+}
+
+
+/**
+ * This function is called to get service factories for an implementation.
+ * @param pImplName name of implementation
+ * @param pServiceManager generic uno interface providing a service manager to instantiate components
+ * @param pRegistryKey registry data key to read and write component persistent data
+ * @return a component factory (generic uno interface)
+ */
+extern "C" void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
+{
+ void * pRet = 0;
+ Reference< XMultiServiceFactory > xSMgr(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ) );
+ Reference< XSingleServiceFactory > xFactory;
+
+ if (ManifestReader::static_getImplementationName().compareToAscii( pImplName ) == 0)
+ xFactory = ManifestReader::createServiceFactory ( xSMgr );
+ else if (ManifestWriter::static_getImplementationName().compareToAscii( pImplName ) == 0)
+ xFactory = ManifestWriter::createServiceFactory ( xSMgr );
+ else if (ZipPackage::static_getImplementationName().compareToAscii( pImplName ) == 0)
+ xFactory = ZipPackage::createServiceFactory ( xSMgr );
+ else if ( OZipFileAccess::impl_staticGetImplementationName().compareToAscii( pImplName ) == 0 )
+ xFactory = ::cppu::createSingleFactory( xSMgr,
+ OZipFileAccess::impl_staticGetImplementationName(),
+ OZipFileAccess::impl_staticCreateSelfInstance,
+ OZipFileAccess::impl_staticGetSupportedServiceNames() );
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ return pRet;
+}
+
diff --git a/package/source/manifest/makefile.mk b/package/source/manifest/makefile.mk
new file mode 100644
index 000000000000..abc61848fc45
--- /dev/null
+++ b/package/source/manifest/makefile.mk
@@ -0,0 +1,55 @@
+#*************************************************************************
+#
+# 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=package
+TARGET=manifest
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(L10N_framework)"==""
+
+SLOFILES= \
+ $(SLO)$/ManifestReader.obj \
+ $(SLO)$/ManifestWriter.obj \
+ $(SLO)$/ManifestImport.obj \
+ $(SLO)$/ManifestExport.obj \
+ $(SLO)$/Base64Codec.obj \
+ $(SLO)$/UnoRegister.obj
+
+.ENDIF # L10N_framework
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/package/source/xstor/disposelistener.cxx b/package/source/xstor/disposelistener.cxx
new file mode 100644
index 000000000000..73c0689a6a40
--- /dev/null
+++ b/package/source/xstor/disposelistener.cxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+
+#include "disposelistener.hxx"
+#include "xstorage.hxx"
+
+using namespace ::com::sun::star;
+
+OChildDispListener_Impl::OChildDispListener_Impl( OStorage& aStorage )
+: m_pStorage( &aStorage )
+{}
+
+OChildDispListener_Impl::~OChildDispListener_Impl()
+{}
+
+void OChildDispListener_Impl::OwnerIsDisposed()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_pStorage = NULL;
+}
+
+void SAL_CALL OChildDispListener_Impl::disposing( const lang::EventObject& Source )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ // ObjectIsDisposed must not contain any locking!
+ if ( m_pStorage && Source.Source.is() )
+ m_pStorage->ChildIsDisposed( Source.Source );
+}
+
diff --git a/package/source/xstor/disposelistener.hxx b/package/source/xstor/disposelistener.hxx
new file mode 100644
index 000000000000..73feb249e3de
--- /dev/null
+++ b/package/source/xstor/disposelistener.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __DISPOSELISTENER_HXX_
+#define __DISPOSELISTENER_HXX_
+
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <osl/mutex.hxx>
+
+class OStorage;
+class OChildDispListener_Impl : public ::cppu::WeakImplHelper1 < ::com::sun::star::lang::XEventListener >
+{
+ ::osl::Mutex m_aMutex;
+ OStorage* m_pStorage;
+
+public:
+ OChildDispListener_Impl( OStorage& aStorage );
+ virtual ~OChildDispListener_Impl();
+
+ void OwnerIsDisposed();
+
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
+};
+
+#endif
+
diff --git a/package/source/xstor/makefile.mk b/package/source/xstor/makefile.mk
new file mode 100644
index 000000000000..76494cb7dbe7
--- /dev/null
+++ b/package/source/xstor/makefile.mk
@@ -0,0 +1,75 @@
+#*************************************************************************
+#
+# 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=package
+TARGET=xstor
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(L10N_framework)"==""
+
+SLOFILES = \
+ $(SLO)$/ohierarchyholder.obj\
+ $(SLO)$/ocompinstream.obj\
+ $(SLO)$/oseekinstream.obj\
+ $(SLO)$/owriteablestream.obj\
+ $(SLO)$/xstorage.obj\
+ $(SLO)$/xfactory.obj\
+ $(SLO)$/disposelistener.obj\
+ $(SLO)$/selfterminatefilestream.obj\
+ $(SLO)$/switchpersistencestream.obj\
+ $(SLO)$/register.obj
+
+SHL1TARGET=$(TARGET)
+SHL1STDLIBS=\
+ $(SALLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(COMPHELPERLIB)
+
+SHL1OBJS=$(SLOFILES)
+SHL1DEF=$(MISC)$/$(TARGET).def
+
+SHL1IMPLIB=i$(SHL1TARGET)
+
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=$(SHL1TARGET).dxp
+
+.ENDIF # L10N_framework
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/package/source/xstor/ocompinstream.cxx b/package/source/xstor/ocompinstream.cxx
new file mode 100644
index 000000000000..fcb118f4b967
--- /dev/null
+++ b/package/source/xstor/ocompinstream.cxx
@@ -0,0 +1,759 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+
+#include "ocompinstream.hxx"
+#include <com/sun/star/embed/StorageFormats.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <osl/diagnose.h>
+
+#include "owriteablestream.hxx"
+#include "xstorage.hxx"
+
+using namespace ::com::sun::star;
+
+//-----------------------------------------------
+OInputCompStream::OInputCompStream( OWriteStream_Impl& aImpl,
+ uno::Reference < io::XInputStream > xStream,
+ const uno::Sequence< beans::PropertyValue >& aProps,
+ sal_Int32 nStorageType )
+: m_pImpl( &aImpl )
+, m_rMutexRef( m_pImpl->m_rMutexRef )
+, m_xStream( xStream )
+, m_pInterfaceContainer( NULL )
+, m_aProperties( aProps )
+, m_bDisposed( sal_False )
+, m_nStorageType( nStorageType )
+{
+ OSL_ENSURE( m_pImpl->m_rMutexRef.Is(), "No mutex is provided!\n" );
+ if ( !m_pImpl->m_rMutexRef.Is() )
+ throw uno::RuntimeException(); // just a disaster
+
+ OSL_ENSURE( xStream.is(), "No stream is provided!\n" );
+}
+
+//-----------------------------------------------
+OInputCompStream::OInputCompStream( uno::Reference < io::XInputStream > xStream,
+ const uno::Sequence< beans::PropertyValue >& aProps,
+ sal_Int32 nStorageType )
+: m_pImpl( NULL )
+, m_rMutexRef( new SotMutexHolder )
+, m_xStream( xStream )
+, m_pInterfaceContainer( NULL )
+, m_aProperties( aProps )
+, m_bDisposed( sal_False )
+, m_nStorageType( nStorageType )
+{
+ OSL_ENSURE( xStream.is(), "No stream is provided!\n" );
+}
+
+//-----------------------------------------------
+OInputCompStream::~OInputCompStream()
+{
+ {
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( !m_bDisposed )
+ {
+ m_refCount++;
+ dispose();
+ }
+
+ if ( m_pInterfaceContainer )
+ delete m_pInterfaceContainer;
+ }
+}
+
+//-----------------------------------------------
+uno::Any SAL_CALL OInputCompStream::queryInterface( const uno::Type& rType )
+ throw( uno::RuntimeException )
+{
+ uno::Any aReturn;
+
+ // common interfaces
+ aReturn <<= ::cppu::queryInterface
+ ( rType
+ , static_cast<io::XInputStream*> ( this )
+ , static_cast<io::XStream*> ( this )
+ , static_cast<lang::XComponent*> ( this )
+ , static_cast<beans::XPropertySet*> ( this )
+ , static_cast<embed::XExtendedStorageStream*> ( this ) );
+
+ if ( aReturn.hasValue() == sal_True )
+ return aReturn ;
+
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ aReturn <<= ::cppu::queryInterface
+ ( rType
+ , static_cast<embed::XRelationshipAccess*> ( this ) );
+
+ if ( aReturn.hasValue() == sal_True )
+ return aReturn ;
+ }
+
+ return OWeakObject::queryInterface( rType );
+}
+
+//-----------------------------------------------
+sal_Int32 SAL_CALL OInputCompStream::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xStream.is() )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No stream!" ) ) );
+ throw uno::RuntimeException();
+ }
+
+ return m_xStream->readBytes( aData, nBytesToRead );
+}
+
+//-----------------------------------------------
+sal_Int32 SAL_CALL OInputCompStream::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xStream.is() )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No stream!" ) ) );
+ throw uno::RuntimeException();
+ }
+
+ return m_xStream->readSomeBytes( aData, nMaxBytesToRead );
+
+}
+
+//-----------------------------------------------
+void SAL_CALL OInputCompStream::skipBytes( sal_Int32 nBytesToSkip )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xStream.is() )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No stream!" ) ) );
+ throw uno::RuntimeException();
+ }
+
+ m_xStream->skipBytes( nBytesToSkip );
+
+}
+
+//-----------------------------------------------
+sal_Int32 SAL_CALL OInputCompStream::available( )
+ throw ( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xStream.is() )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No stream!" ) ) );
+ throw uno::RuntimeException();
+ }
+
+ return m_xStream->available();
+
+}
+
+//-----------------------------------------------
+void SAL_CALL OInputCompStream::closeInput( )
+ throw ( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ dispose();
+}
+
+//-----------------------------------------------
+uno::Reference< io::XInputStream > SAL_CALL OInputCompStream::getInputStream()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xStream.is() )
+ return uno::Reference< io::XInputStream >();
+
+ return uno::Reference< io::XInputStream >( static_cast< io::XInputStream* >( this ), uno::UNO_QUERY );
+}
+
+//-----------------------------------------------
+uno::Reference< io::XOutputStream > SAL_CALL OInputCompStream::getOutputStream()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ return uno::Reference< io::XOutputStream >();
+}
+
+//-----------------------------------------------
+void OInputCompStream::InternalDispose()
+{
+ // can be called only by OWriteStream_Impl
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ // the source object is also a kind of locker for the current object
+ // since the listeners could dispose the object while being notified
+ lang::EventObject aSource( static_cast< ::cppu::OWeakObject*>( this ) );
+
+ if ( m_pInterfaceContainer )
+ m_pInterfaceContainer->disposeAndClear( aSource );
+
+ try
+ {
+ m_xStream->closeInput();
+ }
+ catch( uno::Exception& )
+ {}
+
+ m_pImpl = NULL;
+ m_bDisposed = sal_True;
+}
+
+//-----------------------------------------------
+void SAL_CALL OInputCompStream::dispose( )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_pInterfaceContainer )
+ {
+ lang::EventObject aSource( static_cast< ::cppu::OWeakObject*>( this ) );
+ m_pInterfaceContainer->disposeAndClear( aSource );
+ }
+
+ m_xStream->closeInput();
+
+ if ( m_pImpl )
+ {
+ m_pImpl->InputStreamDisposed( this );
+ m_pImpl = NULL;
+ }
+
+ m_bDisposed = sal_True;
+}
+
+//-----------------------------------------------
+void SAL_CALL OInputCompStream::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_pInterfaceContainer )
+ m_pInterfaceContainer = new ::cppu::OInterfaceContainerHelper( m_rMutexRef->GetMutex() );
+
+ m_pInterfaceContainer->addInterface( xListener );
+}
+
+//-----------------------------------------------
+void SAL_CALL OInputCompStream::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_pInterfaceContainer )
+ m_pInterfaceContainer->removeInterface( xListener );
+}
+
+//-----------------------------------------------
+sal_Bool SAL_CALL OInputCompStream::hasByID( const ::rtl::OUString& sID )
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ try
+ {
+ getRelationshipByID( sID );
+ return sal_True;
+ }
+ catch( container::NoSuchElementException& )
+ {}
+
+ return sal_False;
+}
+
+//-----------------------------------------------
+::rtl::OUString SAL_CALL OInputCompStream::getTargetByID( const ::rtl::OUString& sID )
+ throw ( container::NoSuchElementException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
+ for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
+ if ( aSeq[nInd].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Target" ) ) )
+ return aSeq[nInd].Second;
+
+ return ::rtl::OUString();
+}
+
+//-----------------------------------------------
+::rtl::OUString SAL_CALL OInputCompStream::getTypeByID( const ::rtl::OUString& sID )
+ throw ( container::NoSuchElementException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
+ for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
+ if ( aSeq[nInd].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
+ return aSeq[nInd].Second;
+
+ return ::rtl::OUString();
+}
+
+//-----------------------------------------------
+uno::Sequence< beans::StringPair > SAL_CALL OInputCompStream::getRelationshipByID( const ::rtl::OUString& sID )
+ throw ( container::NoSuchElementException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ // TODO/LATER: in future the unification of the ID could be checked
+ uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
+ for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
+ for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
+ if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Id" ) ) )
+ {
+ if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
+ return aSeq[nInd1];
+ break;
+ }
+
+ throw container::NoSuchElementException();
+}
+
+//-----------------------------------------------
+uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OInputCompStream::getRelationshipsByType( const ::rtl::OUString& sType )
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ uno::Sequence< uno::Sequence< beans::StringPair > > aResult;
+ sal_Int32 nEntriesNum = 0;
+
+ // TODO/LATER: in future the unification of the ID could be checked
+ uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
+ for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
+ for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
+ if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
+ {
+ if ( aSeq[nInd1][nInd2].Second.equals( sType ) )
+ {
+ aResult.realloc( nEntriesNum );
+ aResult[nEntriesNum-1] = aSeq[nInd1];
+ }
+ break;
+ }
+
+ return aResult;
+}
+
+//-----------------------------------------------
+uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OInputCompStream::getAllRelationships()
+ throw (io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ // TODO/LATER: in future the information could be taken directly from m_pImpl when possible
+ uno::Sequence< uno::Sequence< beans::StringPair > > aResult;
+ for ( sal_Int32 aInd = 0; aInd < m_aProperties.getLength(); aInd++ )
+ if ( m_aProperties[aInd].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "RelationsInfo" ) ) )
+ {
+ if ( m_aProperties[aInd].Value >>= aResult )
+ return aResult;
+
+ break;
+ }
+
+ throw io::IOException(); // the relations info could not be read
+}
+
+//-----------------------------------------------
+void SAL_CALL OInputCompStream::insertRelationshipByID( const ::rtl::OUString& /*sID*/, const uno::Sequence< beans::StringPair >& /*aEntry*/, ::sal_Bool /*bReplace*/ )
+ throw ( container::ElementExistException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ throw io::IOException(); // TODO: Access denied
+}
+
+//-----------------------------------------------
+void SAL_CALL OInputCompStream::removeRelationshipByID( const ::rtl::OUString& /*sID*/ )
+ throw ( container::NoSuchElementException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ throw io::IOException(); // TODO: Access denied
+}
+
+//-----------------------------------------------
+void SAL_CALL OInputCompStream::insertRelationships( const uno::Sequence< uno::Sequence< beans::StringPair > >& /*aEntries*/, ::sal_Bool /*bReplace*/ )
+ throw ( container::ElementExistException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ throw io::IOException(); // TODO: Access denied
+}
+
+//-----------------------------------------------
+void SAL_CALL OInputCompStream::clearRelationships()
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ throw io::IOException(); // TODO: Access denied
+}
+
+//-----------------------------------------------
+uno::Reference< beans::XPropertySetInfo > SAL_CALL OInputCompStream::getPropertySetInfo()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ //TODO:
+ return uno::Reference< beans::XPropertySetInfo >();
+}
+
+//-----------------------------------------------
+void SAL_CALL OInputCompStream::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& /*aValue*/ )
+ throw ( beans::UnknownPropertyException,
+ beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ // all the provided properties are accessible
+ for ( sal_Int32 aInd = 0; aInd < m_aProperties.getLength(); aInd++ )
+ {
+ if ( m_aProperties[aInd].Name.equals( aPropertyName ) )
+ {
+ throw beans::PropertyVetoException(); // TODO
+ }
+ }
+
+ throw beans::UnknownPropertyException(); // TODO
+}
+
+
+//-----------------------------------------------
+uno::Any SAL_CALL OInputCompStream::getPropertyValue( const ::rtl::OUString& aProp )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ ::rtl::OUString aPropertyName;
+ if ( aProp.equalsAscii( "IsEncrypted" ) )
+ aPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Encrypted" ) );
+ else
+ aPropertyName = aProp;
+
+ if ( aPropertyName.equalsAscii( "RelationsInfo" ) )
+ throw beans::UnknownPropertyException(); // TODO
+
+ // all the provided properties are accessible
+ for ( sal_Int32 aInd = 0; aInd < m_aProperties.getLength(); aInd++ )
+ {
+ if ( m_aProperties[aInd].Name.equals( aPropertyName ) )
+ {
+ return m_aProperties[aInd].Value;
+ }
+ }
+
+ throw beans::UnknownPropertyException(); // TODO
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OInputCompStream::addPropertyChangeListener(
+ const ::rtl::OUString& /*aPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ //TODO:
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OInputCompStream::removePropertyChangeListener(
+ const ::rtl::OUString& /*aPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ //TODO:
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OInputCompStream::addVetoableChangeListener(
+ const ::rtl::OUString& /*PropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ //TODO:
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OInputCompStream::removeVetoableChangeListener(
+ const ::rtl::OUString& /*PropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ //TODO:
+}
+
+
diff --git a/package/source/xstor/ocompinstream.hxx b/package/source/xstor/ocompinstream.hxx
new file mode 100644
index 000000000000..fcb472e3f92a
--- /dev/null
+++ b/package/source/xstor/ocompinstream.hxx
@@ -0,0 +1,128 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _INPUTCOMPSTREAM_HXX_
+#define _INPUTCOMPSTREAM_HXX_
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/embed/XExtendedStorageStream.hpp>
+#include <com/sun/star/embed/XRelationshipAccess.hpp>
+#include <cppuhelper/implbase4.hxx>
+#include <cppuhelper/interfacecontainer.h>
+
+#include "mutexholder.hxx"
+
+struct OWriteStream_Impl;
+
+class OInputCompStream : public cppu::WeakImplHelper4 < ::com::sun::star::io::XInputStream
+ ,::com::sun::star::embed::XExtendedStorageStream
+ ,::com::sun::star::embed::XRelationshipAccess
+ ,::com::sun::star::beans::XPropertySet >
+{
+protected:
+ OWriteStream_Impl* m_pImpl;
+
+ SotMutexHolderRef m_rMutexRef;
+
+ ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > m_xStream;
+
+ ::cppu::OInterfaceContainerHelper* m_pInterfaceContainer;
+
+ ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue > m_aProperties;
+
+ sal_Bool m_bDisposed;
+
+ sal_Int32 m_nStorageType;
+
+public:
+ OInputCompStream( OWriteStream_Impl& pImpl,
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xStream,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps,
+ sal_Int32 nStorageType );
+
+ OInputCompStream( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xStream,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps,
+ sal_Int32 nStorageType );
+
+ virtual ~OInputCompStream();
+
+ void InternalDispose();
+
+ // XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL available( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeInput( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ //XStream
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream( ) throw (::com::sun::star::uno::RuntimeException);
+
+ //XComponent
+ virtual void SAL_CALL dispose( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ //XRelationshipAccess
+ virtual ::sal_Bool SAL_CALL hasByID( const ::rtl::OUString& sID ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getTargetByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getTypeByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > SAL_CALL getRelationshipByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > SAL_CALL getRelationshipsByType( const ::rtl::OUString& sType ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > SAL_CALL getAllRelationships( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL insertRelationshipByID( const ::rtl::OUString& sID, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair >& aEntry, ::sal_Bool bReplace ) throw (::com::sun::star::container::ElementExistException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeRelationshipByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL insertRelationships( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > >& aEntries, ::sal_Bool bReplace ) throw (::com::sun::star::container::ElementExistException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL clearRelationships( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ //XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() throw ( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
+
+};
+
+#endif
+
diff --git a/package/source/xstor/ohierarchyholder.cxx b/package/source/xstor/ohierarchyholder.cxx
new file mode 100644
index 000000000000..8e22b2b3a093
--- /dev/null
+++ b/package/source/xstor/ohierarchyholder.cxx
@@ -0,0 +1,356 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+
+#include "ohierarchyholder.hxx"
+
+using namespace ::com::sun::star;
+
+//===============================================
+// OHierarchyHolder_Impl
+//===============================================
+
+//-----------------------------------------------
+uno::Reference< embed::XExtendedStorageStream > OHierarchyHolder_Impl::GetStreamHierarchically( sal_Int32 nStorageMode, OStringList_Impl& aListPath, sal_Int32 nStreamMode, const ::rtl::OUString& aPass )
+{
+ uno::Reference< embed::XStorage > xOwnStor( m_xWeakOwnStorage.get(), uno::UNO_QUERY_THROW );
+
+ if ( !( nStorageMode & embed::ElementModes::WRITE ) && ( nStreamMode & embed::ElementModes::WRITE ) )
+ throw io::IOException();
+
+ uno::Reference< embed::XExtendedStorageStream > xResult =
+ m_xChild->GetStreamHierarchically( nStorageMode, aListPath, nStreamMode, aPass );
+ if ( !xResult.is() )
+ throw uno::RuntimeException();
+
+ return xResult;
+}
+
+//-----------------------------------------------
+void OHierarchyHolder_Impl::RemoveStreamHierarchically( OStringList_Impl& aListPath )
+{
+ uno::Reference< embed::XStorage > xOwnStor( m_xWeakOwnStorage.get(), uno::UNO_QUERY_THROW );
+
+ m_xChild->RemoveStreamHierarchically( aListPath );
+}
+
+//-----------------------------------------------
+// static
+OStringList_Impl OHierarchyHolder_Impl::GetListPathFromString( const ::rtl::OUString& aPath )
+{
+ OStringList_Impl aResult;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ ::rtl::OUString aName = aPath.getToken( 0, '/', nIndex );
+ if ( !aName.getLength() )
+ throw lang::IllegalArgumentException();
+
+ aResult.push_back( aName );
+ }
+ while ( nIndex >= 0 );
+
+ return aResult;
+}
+
+//===============================================
+// OHierarchyElement_Impl
+//===============================================
+
+//-----------------------------------------------
+uno::Reference< embed::XExtendedStorageStream > OHierarchyElement_Impl::GetStreamHierarchically( sal_Int32 nStorageMode, OStringList_Impl& aListPath, sal_Int32 nStreamMode, const ::rtl::OUString& aPass )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !( nStorageMode & embed::ElementModes::WRITE ) && ( nStreamMode & embed::ElementModes::WRITE ) )
+ throw io::IOException();
+
+ if ( !aListPath.size() )
+ throw uno::RuntimeException();
+
+ ::rtl::OUString aNextName = *(aListPath.begin());
+ aListPath.erase( aListPath.begin() );
+
+ uno::Reference< embed::XExtendedStorageStream > xResult;
+
+ uno::Reference< embed::XStorage > xOwnStor = m_xOwnStorage.is() ? m_xOwnStorage
+ : uno::Reference< embed::XStorage >( m_xWeakOwnStorage.get(), uno::UNO_QUERY );
+ if ( !xOwnStor.is() )
+ throw uno::RuntimeException();
+
+ if ( !aListPath.size() )
+ {
+ uno::Reference< embed::XHierarchicalStorageAccess > xHStorage( xOwnStor, uno::UNO_QUERY_THROW );
+ if ( !aPass.getLength() )
+ xResult = xHStorage->openStreamElementByHierarchicalName( aNextName, nStreamMode );
+ else
+ xResult = xHStorage->openEncryptedStreamElementByHierarchicalName( aNextName, nStreamMode, aPass );
+
+ uno::Reference< embed::XTransactedObject > xTransact( xResult, uno::UNO_QUERY );
+ if ( xTransact.is() )
+ {
+ // the existance of the transacted object means that the stream is opened for writing also
+ // so the whole chain must be commited
+ uno::Reference< embed::XTransactionBroadcaster > xTrBroadcast( xTransact, uno::UNO_QUERY_THROW );
+ xTrBroadcast->addTransactionListener( static_cast< embed::XTransactionListener* >( this ) );
+ }
+ else
+ {
+ uno::Reference< lang::XComponent > xStreamComp( xResult, uno::UNO_QUERY_THROW );
+ xStreamComp->addEventListener( static_cast< lang::XEventListener* >( this ) );
+ }
+
+ m_aOpenStreams.push_back( uno::WeakReference< embed::XExtendedStorageStream >( xResult ) );
+ }
+ else
+ {
+ sal_Bool bNewElement = sal_False;
+ ::rtl::Reference< OHierarchyElement_Impl > aElement;
+ OHierarchyElementList_Impl::iterator aIter = m_aChildren.find( aNextName );
+ if ( aIter != m_aChildren.end() )
+ aElement = aIter->second;
+
+ if ( !aElement.is() )
+ {
+ bNewElement = sal_True;
+ uno::Reference< embed::XStorage > xChildStorage = xOwnStor->openStorageElement( aNextName, nStorageMode );
+ if ( !xChildStorage.is() )
+ throw uno::RuntimeException();
+
+ aElement = new OHierarchyElement_Impl( NULL, xChildStorage );
+ }
+
+ xResult = aElement->GetStreamHierarchically( nStorageMode, aListPath, nStreamMode, aPass );
+ if ( !xResult.is() )
+ throw uno::RuntimeException();
+
+ if ( bNewElement )
+ {
+ m_aChildren[aNextName] = aElement;
+ aElement->SetParent( this );
+ }
+ }
+
+ // the subelement was opened successfuly, remember the storage to let it be locked
+ m_xOwnStorage = xOwnStor;
+
+ return xResult;
+}
+
+//-----------------------------------------------
+void OHierarchyElement_Impl::RemoveStreamHierarchically( OStringList_Impl& aListPath )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !aListPath.size() )
+ throw uno::RuntimeException();
+
+ ::rtl::OUString aNextName = *(aListPath.begin());
+ aListPath.erase( aListPath.begin() );
+
+ uno::Reference< embed::XExtendedStorageStream > xResult;
+
+ uno::Reference< embed::XStorage > xOwnStor = m_xOwnStorage.is() ? m_xOwnStorage
+ : uno::Reference< embed::XStorage >( m_xWeakOwnStorage.get(), uno::UNO_QUERY );
+ if ( !xOwnStor.is() )
+ throw uno::RuntimeException();
+
+ if ( !aListPath.size() )
+ {
+ xOwnStor->removeElement( aNextName );
+ }
+ else
+ {
+ sal_Bool bNewElement = sal_False;
+ ::rtl::Reference< OHierarchyElement_Impl > aElement;
+ OHierarchyElementList_Impl::iterator aIter = m_aChildren.find( aNextName );
+ if ( aIter != m_aChildren.end() )
+ aElement = aIter->second;
+
+ if ( !aElement.is() )
+ {
+ bNewElement = sal_True;
+ uno::Reference< embed::XStorage > xChildStorage = xOwnStor->openStorageElement( aNextName,
+ embed::ElementModes::READWRITE );
+ if ( !xChildStorage.is() )
+ throw uno::RuntimeException();
+
+ aElement = new OHierarchyElement_Impl( NULL, xChildStorage );
+ }
+
+ aElement->RemoveStreamHierarchically( aListPath );
+ }
+
+ uno::Reference< embed::XTransactedObject > xTransact( xOwnStor, uno::UNO_QUERY );
+ if ( xTransact.is() )
+ xTransact->commit();
+
+ TestForClosing();
+}
+
+//-----------------------------------------------
+void OHierarchyElement_Impl::Commit()
+{
+ ::rtl::Reference< OHierarchyElement_Impl > aLocker( this );
+ ::rtl::Reference< OHierarchyElement_Impl > aParent;
+ uno::Reference< embed::XStorage > xOwnStor;
+
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ aParent = m_rParent;
+ xOwnStor = m_xOwnStorage;
+ }
+
+ if ( xOwnStor.is() )
+ {
+ uno::Reference< embed::XTransactedObject > xTransact( xOwnStor, uno::UNO_QUERY_THROW );
+ xTransact->commit();
+ if ( aParent.is() )
+ aParent->Commit();
+ }
+}
+
+//-----------------------------------------------
+void OHierarchyElement_Impl::TestForClosing()
+{
+ ::rtl::Reference< OHierarchyElement_Impl > aLocker( this );
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_aOpenStreams.size() && !m_aChildren.size() )
+ {
+ if ( m_rParent.is() )
+ {
+ // only the root storage should not be disposed, other storages can be disposed
+ if ( m_xOwnStorage.is() )
+ {
+ try
+ {
+ m_xOwnStorage->dispose();
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ m_rParent->RemoveElement( this );
+ }
+
+ m_xOwnStorage = uno::Reference< embed::XStorage >();
+ }
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL OHierarchyElement_Impl::disposing( const lang::EventObject& Source )
+ throw ( uno::RuntimeException )
+{
+ uno::Sequence< embed::XStorage > aStoragesToCommit;
+
+ try
+ {
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+ uno::Reference< embed::XExtendedStorageStream > xStream( Source.Source, uno::UNO_QUERY );
+
+ for ( OWeakStorRefList_Impl::iterator pStorageIter = m_aOpenStreams.begin();
+ pStorageIter != m_aOpenStreams.end(); )
+ {
+ OWeakStorRefList_Impl::iterator pTmp = pStorageIter++;
+ if ( !pTmp->get().is() || pTmp->get() == xStream )
+ m_aOpenStreams.erase( pTmp );
+ }
+
+ aGuard.clear();
+
+ TestForClosing();
+ }
+ catch( uno::Exception& )
+ {
+ throw uno::RuntimeException(); // no exception must happen here, usually an exception means disaster
+ }
+}
+
+//-----------------------------------------------
+void OHierarchyElement_Impl::RemoveElement( const ::rtl::Reference< OHierarchyElement_Impl >& aRef )
+{
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ for ( OHierarchyElementList_Impl::iterator aIter = m_aChildren.begin();
+ aIter != m_aChildren.end(); /* increment is done in body */)
+ {
+ OHierarchyElementList_Impl::iterator aTmpIter = aIter;
+ aIter++;
+
+ if ( aTmpIter->second == aRef )
+ m_aChildren.erase( aTmpIter );
+ }
+ }
+
+ TestForClosing();
+}
+
+// XTransactionListener
+//-----------------------------------------------
+void SAL_CALL OHierarchyElement_Impl::preCommit( const ::com::sun::star::lang::EventObject& /*aEvent*/ )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+}
+
+//-----------------------------------------------
+void SAL_CALL OHierarchyElement_Impl::commited( const ::com::sun::star::lang::EventObject& /*aEvent*/ )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ try
+ {
+ Commit();
+ }
+ catch( uno::Exception& e )
+ {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can not commit storage sequence!" ) ),
+ uno::Reference< uno::XInterface >(),
+ uno::makeAny( e ) );
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL OHierarchyElement_Impl::preRevert( const ::com::sun::star::lang::EventObject& /*aEvent*/ )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+}
+
+//-----------------------------------------------
+void SAL_CALL OHierarchyElement_Impl::reverted( const ::com::sun::star::lang::EventObject& /*aEvent*/ )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
diff --git a/package/source/xstor/ohierarchyholder.hxx b/package/source/xstor/ohierarchyholder.hxx
new file mode 100644
index 000000000000..17c14d3a6001
--- /dev/null
+++ b/package/source/xstor/ohierarchyholder.hxx
@@ -0,0 +1,139 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _OHIERARCHYHOLDER_HXX_
+#define _OHIERARCHYHOLDER_HXX_
+
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/XTransactionListener.hpp>
+#include <com/sun/star/embed/XExtendedStorageStream.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+#include <rtl/ref.hxx>
+
+#include <hash_map>
+#include <list>
+#include <vector>
+
+struct OHierarchyElement_Impl;
+
+struct eqFunc
+{
+ sal_Bool operator()( const rtl::OUString &r1,
+ const rtl::OUString &r2) const
+ {
+ return r1 == r2;
+ }
+};
+typedef ::std::hash_map< ::rtl::OUString,
+ ::rtl::Reference< OHierarchyElement_Impl >,
+ ::rtl::OUStringHash,
+ eqFunc > OHierarchyElementList_Impl;
+
+typedef ::std::vector< ::rtl::OUString > OStringList_Impl;
+typedef ::std::list< ::com::sun::star::uno::WeakReference< ::com::sun::star::embed::XExtendedStorageStream > >
+ OWeakStorRefList_Impl;
+
+struct OHierarchyElement_Impl : public cppu::WeakImplHelper1< ::com::sun::star::embed::XTransactionListener >
+{
+ ::osl::Mutex m_aMutex;
+
+ ::rtl::Reference< OHierarchyElement_Impl > m_rParent;
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > m_xOwnStorage;
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::embed::XStorage > m_xWeakOwnStorage;
+
+ OHierarchyElementList_Impl m_aChildren;
+
+ OWeakStorRefList_Impl m_aOpenStreams;
+
+public:
+ OHierarchyElement_Impl( OHierarchyElement_Impl* pParent, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage )
+ : m_rParent( pParent )
+ , m_xOwnStorage( xStorage )
+ {}
+
+ OHierarchyElement_Impl( const ::com::sun::star::uno::WeakReference< ::com::sun::star::embed::XStorage >& xWeakStorage )
+ : m_rParent( NULL )
+ , m_xWeakOwnStorage( xWeakStorage )
+ {}
+
+ void Commit();
+
+ void SetParent( const ::rtl::Reference< OHierarchyElement_Impl >& rParent ) { m_rParent = rParent; }
+
+ void TestForClosing();
+
+ void RemoveElement( const ::rtl::Reference< OHierarchyElement_Impl >& aRef );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XExtendedStorageStream >
+ GetStreamHierarchically( sal_Int32 nStorageMode,
+ OStringList_Impl& aPath,
+ sal_Int32 nStreamMode,
+ const ::rtl::OUString& aPassword = ::rtl::OUString() );
+
+ void RemoveStreamHierarchically( OStringList_Impl& aListPath );
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
+ throw (::com::sun::star::uno::RuntimeException);
+
+
+ // XTransactionListener
+ virtual void SAL_CALL preCommit( const ::com::sun::star::lang::EventObject& aEvent )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL commited( const ::com::sun::star::lang::EventObject& aEvent )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL preRevert( const ::com::sun::star::lang::EventObject& aEvent )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL reverted( const ::com::sun::star::lang::EventObject& aEvent )
+ throw (::com::sun::star::uno::RuntimeException);
+
+};
+
+class OHierarchyHolder_Impl : public ::cppu::OWeakObject
+{
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::embed::XStorage > m_xWeakOwnStorage;
+ ::rtl::Reference< OHierarchyElement_Impl > m_xChild;
+public:
+ OHierarchyHolder_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xOwnStorage )
+ : m_xWeakOwnStorage( xOwnStorage )
+ , m_xChild( new OHierarchyElement_Impl( ::com::sun::star::uno::WeakReference< ::com::sun::star::embed::XStorage >( xOwnStorage ) ) )
+ {}
+
+ static OStringList_Impl GetListPathFromString( const ::rtl::OUString& aPath );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XExtendedStorageStream >
+ GetStreamHierarchically( sal_Int32 nStorageMode,
+ OStringList_Impl& aListPath,
+ sal_Int32 nStreamMode,
+ const ::rtl::OUString& aPassword = ::rtl::OUString() );
+
+ void RemoveStreamHierarchically( OStringList_Impl& aListPath );
+};
+
+#endif // _OHIERARCHYHOLDER
+
diff --git a/package/source/xstor/oseekinstream.cxx b/package/source/xstor/oseekinstream.cxx
new file mode 100644
index 000000000000..0cd3f595c2b3
--- /dev/null
+++ b/package/source/xstor/oseekinstream.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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <cppuhelper/typeprovider.hxx>
+#include <osl/diagnose.h>
+
+#include "oseekinstream.hxx"
+#include "owriteablestream.hxx"
+
+using namespace ::com::sun::star;
+
+OInputSeekStream::OInputSeekStream( OWriteStream_Impl& pImpl,
+ uno::Reference < io::XInputStream > xStream,
+ const uno::Sequence< beans::PropertyValue >& aProps,
+ sal_Int32 nStorageType )
+: OInputCompStream( pImpl, xStream, aProps, nStorageType )
+{
+ if ( m_xStream.is() )
+ {
+ m_xSeekable = uno::Reference< io::XSeekable >( m_xStream, uno::UNO_QUERY );
+ OSL_ENSURE( m_xSeekable.is(), "No seeking support!\n" );
+ }
+}
+
+OInputSeekStream::OInputSeekStream( uno::Reference < io::XInputStream > xStream,
+ const uno::Sequence< beans::PropertyValue >& aProps,
+ sal_Int32 nStorageType )
+: OInputCompStream( xStream, aProps, nStorageType )
+{
+ if ( m_xStream.is() )
+ {
+ m_xSeekable = uno::Reference< io::XSeekable >( m_xStream, uno::UNO_QUERY );
+ OSL_ENSURE( m_xSeekable.is(), "No seeking support!\n" );
+ }
+}
+
+OInputSeekStream::~OInputSeekStream()
+{
+}
+
+uno::Sequence< uno::Type > SAL_CALL OInputSeekStream::getTypes()
+ throw ( uno::RuntimeException )
+{
+ static ::cppu::OTypeCollection* pTypeCollection = NULL ;
+
+ if ( pTypeCollection == NULL )
+ {
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
+
+ if ( pTypeCollection == NULL )
+ {
+ static ::cppu::OTypeCollection aTypeCollection(
+ ::getCppuType(( const uno::Reference< io::XSeekable >* )NULL ),
+ OInputCompStream::getTypes() );
+
+ pTypeCollection = &aTypeCollection ;
+ }
+ }
+
+ return pTypeCollection->getTypes() ;
+}
+
+uno::Any SAL_CALL OInputSeekStream::queryInterface( const uno::Type& rType )
+ throw( uno::RuntimeException )
+{
+ // Attention:
+ // Don't use mutex or guard in this method!!! Is a method of XInterface.
+
+ uno::Any aReturn( ::cppu::queryInterface( rType,
+ static_cast< io::XSeekable* >( this ) ) );
+
+ if ( aReturn.hasValue() == sal_True )
+ {
+ return aReturn ;
+ }
+
+ return OInputCompStream::queryInterface( rType ) ;
+}
+
+void SAL_CALL OInputSeekStream::acquire()
+ throw()
+{
+ OInputCompStream::acquire();
+}
+
+void SAL_CALL OInputSeekStream::release()
+ throw()
+{
+ OInputCompStream::release();
+}
+
+
+void SAL_CALL OInputSeekStream::seek( sal_Int64 location )
+ throw ( lang::IllegalArgumentException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xSeekable.is() )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No seekable!" ) ) );
+ throw uno::RuntimeException();
+ }
+
+ m_xSeekable->seek( location );
+}
+
+sal_Int64 SAL_CALL OInputSeekStream::getPosition()
+ throw ( io::IOException,
+ uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xSeekable.is() )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No seekable!" ) ) );
+ throw uno::RuntimeException();
+ }
+
+ return m_xSeekable->getPosition();
+}
+
+sal_Int64 SAL_CALL OInputSeekStream::getLength()
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ if ( m_bDisposed )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xSeekable.is() )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No seekable!" ) ) );
+ throw uno::RuntimeException();
+ }
+
+ return m_xSeekable->getLength();
+}
+
diff --git a/package/source/xstor/oseekinstream.hxx b/package/source/xstor/oseekinstream.hxx
new file mode 100644
index 000000000000..92a611af16aa
--- /dev/null
+++ b/package/source/xstor/oseekinstream.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _INPUTSEEKSTREAM_HXX_
+#define _INPUTSEEKSTREAM_HXX_
+
+#include <com/sun/star/io/XSeekable.hpp>
+
+#include "ocompinstream.hxx"
+
+class OInputSeekStream : public OInputCompStream
+ , public ::com::sun::star::io::XSeekable
+{
+protected:
+ ::com::sun::star::uno::Reference < ::com::sun::star::io::XSeekable > m_xSeekable;
+
+public:
+ OInputSeekStream( OWriteStream_Impl& pImpl,
+ ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > xStream,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps,
+ sal_Int32 nStorageType );
+
+ OInputSeekStream( ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > xStream,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps,
+ sal_Int32 nStorageType );
+
+ virtual ~OInputSeekStream();
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
+
+ // XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ //XSeekable
+ virtual void SAL_CALL seek( sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getPosition() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getLength() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+};
+
+#endif
+
diff --git a/package/source/xstor/owriteablestream.cxx b/package/source/xstor/owriteablestream.cxx
new file mode 100644
index 000000000000..be11586bc4fb
--- /dev/null
+++ b/package/source/xstor/owriteablestream.cxx
@@ -0,0 +1,3613 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/StorageFormats.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <osl/diagnose.h>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <comphelper/ofopxmlhelper.hxx>
+
+#include "selfterminatefilestream.hxx"
+#include "owriteablestream.hxx"
+#include "oseekinstream.hxx"
+#include "mutexholder.hxx"
+#include "xstorage.hxx"
+
+#include <rtl/digest.h>
+#include <rtl/logfile.hxx>
+
+// since the copying uses 32000 blocks usually, it makes sense to have a smaller size
+#define MAX_STORCACHE_SIZE 30000
+
+
+using namespace ::com::sun::star;
+
+namespace package
+{
+//-----------------------------------------------
+uno::Sequence< sal_Int8 > MakeKeyFromPass( const ::rtl::OUString& aPass, sal_Bool bUseUTF )
+{
+ // MS_1252 encoding was used for SO60 document format password encoding,
+ // this encoding supports only a minor subset of nonascii characters,
+ // but for compatibility reasons it has to be used for old document formats
+
+ ::rtl::OString aByteStrPass;
+ if ( bUseUTF )
+ aByteStrPass = ::rtl::OUStringToOString( aPass, RTL_TEXTENCODING_UTF8 );
+ else
+ aByteStrPass = ::rtl::OUStringToOString( aPass, RTL_TEXTENCODING_MS_1252 );
+
+ sal_uInt8 pBuffer[RTL_DIGEST_LENGTH_SHA1];
+ rtlDigestError nError = rtl_digest_SHA1( aByteStrPass.getStr(),
+ aByteStrPass.getLength(),
+ pBuffer,
+ RTL_DIGEST_LENGTH_SHA1 );
+
+ if ( nError != rtl_Digest_E_None )
+ throw uno::RuntimeException();
+
+ return uno::Sequence< sal_Int8 >( (sal_Int8*)pBuffer, RTL_DIGEST_LENGTH_SHA1 );
+
+}
+
+//-----------------------------------------------
+void StaticAddLog( const ::rtl::OUString& aMessage )
+{
+ try
+ {
+ ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
+ if ( aContext.is() )
+ {
+ uno::Reference< logging::XSimpleLogRing > xLogRing( aContext.getSingleton( "com.sun.star.logging.DocumentIOLogRing" ), uno::UNO_QUERY_THROW );
+ xLogRing->logString( aMessage );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ // No log
+ }
+}
+} // namespace package
+
+// ================================================================
+namespace
+{
+//-----------------------------------------------
+void SetEncryptionKeyProperty_Impl( const uno::Reference< beans::XPropertySet >& xPropertySet,
+ const uno::Sequence< sal_Int8 >& aKey )
+{
+ OSL_ENSURE( xPropertySet.is(), "No property set is provided!\n" );
+ if ( !xPropertySet.is() )
+ throw uno::RuntimeException();
+
+ ::rtl::OUString aString_EncryptionKey = ::rtl::OUString::createFromAscii( "EncryptionKey" );
+ try {
+ xPropertySet->setPropertyValue( aString_EncryptionKey, uno::makeAny( aKey ) );
+ }
+ catch ( uno::Exception& aException )
+ {
+ ::package::StaticAddLog( aException.Message );
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't set encryption" ) ) );
+ OSL_ENSURE( sal_False, "Can't write encryption related properties!\n" );
+ throw io::IOException(); // TODO
+ }
+}
+
+//-----------------------------------------------
+uno::Any GetEncryptionKeyProperty_Impl( const uno::Reference< beans::XPropertySet >& xPropertySet )
+{
+ OSL_ENSURE( xPropertySet.is(), "No property set is provided!\n" );
+ if ( !xPropertySet.is() )
+ throw uno::RuntimeException();
+
+ ::rtl::OUString aString_EncryptionKey = ::rtl::OUString::createFromAscii( "EncryptionKey" );
+ try {
+ return xPropertySet->getPropertyValue( aString_EncryptionKey );
+ }
+ catch ( uno::Exception& aException )
+ {
+ ::package::StaticAddLog( aException.Message );
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't get encryption property" ) ) );
+
+ OSL_ENSURE( sal_False, "Can't get encryption related properties!\n" );
+ throw io::IOException(); // TODO
+ }
+}
+
+//-----------------------------------------------
+sal_Bool SequencesEqual( uno::Sequence< sal_Int8 > aSequence1, uno::Sequence< sal_Int8 > aSequence2 )
+{
+ if ( aSequence1.getLength() != aSequence2.getLength() )
+ return sal_False;
+
+ for ( sal_Int32 nInd = 0; nInd < aSequence1.getLength(); nInd++ )
+ if ( aSequence1[nInd] != aSequence2[nInd] )
+ return sal_False;
+
+ return sal_True;
+}
+
+//-----------------------------------------------
+sal_Bool KillFile( const ::rtl::OUString& aURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory )
+{
+ if ( !xFactory.is() )
+ return sal_False;
+
+ sal_Bool bRet = sal_False;
+
+ try
+ {
+ uno::Reference < ucb::XSimpleFileAccess > xAccess(
+ xFactory->createInstance (
+ ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
+ uno::UNO_QUERY );
+
+ if ( xAccess.is() )
+ {
+ xAccess->kill( aURL );
+ bRet = sal_True;
+ }
+ }
+ catch( uno::Exception& aException )
+ {
+ ::package::StaticAddLog( aException.Message );
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+ }
+
+ return bRet;
+}
+
+const sal_Int32 n_ConstBufferSize = 32000;
+
+//-----------------------------------------------
+::rtl::OUString GetNewTempFileURL( const uno::Reference< lang::XMultiServiceFactory > xFactory )
+{
+ ::rtl::OUString aTempURL;
+
+ uno::Reference < beans::XPropertySet > xTempFile(
+ xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
+ uno::UNO_QUERY );
+
+ if ( !xTempFile.is() )
+ throw uno::RuntimeException(); // TODO
+
+ try {
+ xTempFile->setPropertyValue( ::rtl::OUString::createFromAscii( "RemoveFile" ), uno::makeAny( sal_False ) );
+ uno::Any aUrl = xTempFile->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
+ aUrl >>= aTempURL;
+ }
+ catch ( uno::Exception& aException )
+ {
+ ::package::StaticAddLog( aException.Message );
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+ }
+
+ if ( !aTempURL.getLength() )
+ throw uno::RuntimeException(); // TODO: can not create tempfile
+
+ return aTempURL;
+}
+
+//-----------------------------------------------
+uno::Reference< io::XStream > CreateMemoryStream( const uno::Reference< lang::XMultiServiceFactory >& xFactory )
+{
+ if ( !xFactory.is() )
+ throw uno::RuntimeException();
+
+ return uno::Reference< io::XStream >( xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.comp.MemoryStream" ) ), uno::UNO_QUERY_THROW );
+}
+
+} // anonymous namespace
+// ================================================================
+
+//-----------------------------------------------
+OWriteStream_Impl::OWriteStream_Impl( OStorage_Impl* pParent,
+ const uno::Reference< packages::XDataSinkEncrSupport >& xPackageStream,
+ const uno::Reference< lang::XSingleServiceFactory >& xPackage,
+ const uno::Reference< lang::XMultiServiceFactory >& xFactory,
+ sal_Bool bForceEncrypted,
+ sal_Int32 nStorageType,
+ sal_Bool bDefaultCompress,
+ const uno::Reference< io::XInputStream >& xRelInfoStream )
+: m_pAntiImpl( NULL )
+, m_bHasDataToFlush( sal_False )
+, m_bFlushed( sal_False )
+, m_xPackageStream( xPackageStream )
+, m_xFactory( xFactory )
+, m_pParent( pParent )
+, m_bForceEncrypted( bForceEncrypted )
+, m_bUseCommonPass( !bForceEncrypted && nStorageType == embed::StorageFormats::PACKAGE )
+, m_bHasCachedPassword( sal_False )
+, m_bCompressedSetExplicit( !bDefaultCompress )
+, m_xPackage( xPackage )
+, m_bHasInsertedStreamOptimization( sal_False )
+, m_nStorageType( nStorageType )
+, m_xOrigRelInfoStream( xRelInfoStream )
+, m_bOrigRelInfoBroken( sal_False )
+, m_nRelInfoStatus( RELINFO_NO_INIT )
+, m_nRelId( 1 )
+{
+ OSL_ENSURE( xPackageStream.is(), "No package stream is provided!\n" );
+ OSL_ENSURE( xPackage.is(), "No package component is provided!\n" );
+ OSL_ENSURE( m_xFactory.is(), "No package stream is provided!\n" );
+ OSL_ENSURE( pParent, "No parent storage is provided!\n" );
+ OSL_ENSURE( m_nStorageType == embed::StorageFormats::OFOPXML || !m_xOrigRelInfoStream.is(), "The Relations info makes sence only for OFOPXML format!\n" );
+}
+
+//-----------------------------------------------
+OWriteStream_Impl::~OWriteStream_Impl()
+{
+ DisposeWrappers();
+
+ if ( m_aTempURL.getLength() )
+ {
+ KillFile( m_aTempURL, GetServiceFactory() );
+ m_aTempURL = ::rtl::OUString();
+ }
+
+ CleanCacheStream();
+}
+
+//-----------------------------------------------
+void OWriteStream_Impl::CleanCacheStream()
+{
+ if ( m_xCacheStream.is() )
+ {
+ try
+ {
+ uno::Reference< io::XInputStream > xInputCache = m_xCacheStream->getInputStream();
+ if ( xInputCache.is() )
+ xInputCache->closeInput();
+ }
+ catch( uno::Exception& )
+ {}
+
+ try
+ {
+ uno::Reference< io::XOutputStream > xOutputCache = m_xCacheStream->getOutputStream();
+ if ( xOutputCache.is() )
+ xOutputCache->closeOutput();
+ }
+ catch( uno::Exception& )
+ {}
+
+ m_xCacheStream = uno::Reference< io::XStream >();
+ m_xCacheSeek = uno::Reference< io::XSeekable >();
+ }
+}
+
+//-----------------------------------------------
+void OWriteStream_Impl::AddLog( const ::rtl::OUString& aMessage )
+{
+ if ( !m_xLogRing.is() )
+ {
+ try
+ {
+ ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
+ if ( aContext.is() )
+ m_xLogRing.set( aContext.getSingleton( "com.sun.star.logging.DocumentIOLogRing" ), uno::UNO_QUERY_THROW );
+ }
+ catch( uno::Exception& )
+ {
+ // No log
+ }
+ }
+
+ if ( m_xLogRing.is() )
+ m_xLogRing->logString( aMessage );
+}
+
+
+//-----------------------------------------------
+void OWriteStream_Impl::InsertIntoPackageFolder( const ::rtl::OUString& aName,
+ const uno::Reference< container::XNameContainer >& xParentPackageFolder )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ OSL_ENSURE( m_bFlushed, "This method must not be called for nonflushed streams!\n" );
+ if ( m_bFlushed )
+ {
+ OSL_ENSURE( m_xPackageStream.is(), "An inserted stream is incomplete!\n" );
+ uno::Reference< lang::XUnoTunnel > xTunnel( m_xPackageStream, uno::UNO_QUERY );
+ if ( !xTunnel.is() )
+ throw uno::RuntimeException(); // TODO
+
+ xParentPackageFolder->insertByName( aName, uno::makeAny( xTunnel ) );
+
+ m_bFlushed = sal_False;
+ m_bHasInsertedStreamOptimization = sal_False;
+ }
+}
+//-----------------------------------------------
+sal_Bool OWriteStream_Impl::IsEncrypted()
+{
+ if ( m_nStorageType != embed::StorageFormats::PACKAGE )
+ return sal_False;
+
+ if ( m_bForceEncrypted || m_bHasCachedPassword )
+ return sal_True;
+
+ if ( m_aTempURL.getLength() || m_xCacheStream.is() )
+ return sal_False;
+
+ GetStreamProperties();
+
+ // the following value can not be cached since it can change after root commit
+ sal_Bool bWasEncr = sal_False;
+ uno::Reference< beans::XPropertySet > xPropSet( m_xPackageStream, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ uno::Any aValue = xPropSet->getPropertyValue( ::rtl::OUString::createFromAscii( "WasEncrypted" ) );
+ if ( !( aValue >>= bWasEncr ) )
+ {
+ OSL_ENSURE( sal_False, "The property WasEncrypted has wrong type!\n" );
+ }
+ }
+
+ sal_Bool bToBeEncr = sal_False;
+ for ( sal_Int32 nInd = 0; nInd < m_aProps.getLength(); nInd++ )
+ {
+ if ( m_aProps[nInd].Name.equalsAscii( "Encrypted" ) )
+ {
+ if ( !( m_aProps[nInd].Value >>= bToBeEncr ) )
+ {
+ OSL_ENSURE( sal_False, "The property has wrong type!\n" );
+ }
+ }
+ }
+
+ // since a new key set to the package stream it should not be removed except the case when
+ // the stream becomes nonencrypted
+ uno::Sequence< sal_Int8 > aKey;
+ if ( bToBeEncr )
+ GetEncryptionKeyProperty_Impl( xPropSet ) >>= aKey;
+
+ // If the properties must be investigated the stream is either
+ // was never changed or was changed, the parent was commited
+ // and the stream was closed.
+ // That means that if it is intended to use common storage key
+ // it is already has no encryption but is marked to be stored
+ // encrypted and the key is empty.
+ if ( !bWasEncr && bToBeEncr && !aKey.getLength() )
+ {
+ // the stream is intended to use common storage password
+ m_bUseCommonPass = sal_True;
+ return sal_False;
+ }
+ else
+ return bToBeEncr;
+}
+
+//-----------------------------------------------
+void OWriteStream_Impl::SetDecrypted()
+{
+ OSL_ENSURE( m_nStorageType == embed::StorageFormats::PACKAGE, "The encryption is supported only for package storages!\n" );
+ if ( m_nStorageType != embed::StorageFormats::PACKAGE )
+ throw uno::RuntimeException();
+
+ GetStreamProperties();
+
+ // let the stream be modified
+ FillTempGetFileName();
+ m_bHasDataToFlush = sal_True;
+
+ // remove encryption
+ m_bForceEncrypted = sal_False;
+ m_bHasCachedPassword = sal_False;
+ m_aPass = ::rtl::OUString();
+
+ for ( sal_Int32 nInd = 0; nInd < m_aProps.getLength(); nInd++ )
+ {
+ if ( m_aProps[nInd].Name.equalsAscii( "Encrypted" ) )
+ m_aProps[nInd].Value <<= sal_False;
+ }
+}
+
+//-----------------------------------------------
+void OWriteStream_Impl::SetEncryptedWithPass( const ::rtl::OUString& aPass )
+{
+ OSL_ENSURE( m_nStorageType == embed::StorageFormats::PACKAGE, "The encryption is supported only for package storages!\n" );
+ if ( m_nStorageType != embed::StorageFormats::PACKAGE )
+ throw uno::RuntimeException();
+
+ GetStreamProperties();
+
+ // let the stream be modified
+ FillTempGetFileName();
+ m_bHasDataToFlush = sal_True;
+
+ // introduce encryption info
+ for ( sal_Int32 nInd = 0; nInd < m_aProps.getLength(); nInd++ )
+ {
+ if ( m_aProps[nInd].Name.equalsAscii( "Encrypted" ) )
+ m_aProps[nInd].Value <<= sal_True;
+ }
+
+ m_bUseCommonPass = sal_False; // very important to set it to false
+
+ m_bHasCachedPassword = sal_True;
+ m_aPass = aPass;
+}
+
+//-----------------------------------------------
+void OWriteStream_Impl::DisposeWrappers()
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ if ( m_pAntiImpl )
+ {
+ try {
+ m_pAntiImpl->dispose();
+ }
+ catch ( uno::RuntimeException& aRuntimeException )
+ {
+ AddLog( aRuntimeException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+ }
+
+ m_pAntiImpl = NULL;
+ }
+ m_pParent = NULL;
+
+ if ( !m_aInputStreamsList.empty() )
+ {
+ for ( InputStreamsList_Impl::iterator pStreamIter = m_aInputStreamsList.begin();
+ pStreamIter != m_aInputStreamsList.end(); pStreamIter++ )
+ {
+ if ( (*pStreamIter) )
+ {
+ (*pStreamIter)->InternalDispose();
+ (*pStreamIter) = NULL;
+ }
+ }
+
+ m_aInputStreamsList.clear();
+ }
+}
+
+//-----------------------------------------------
+uno::Reference< lang::XMultiServiceFactory > OWriteStream_Impl::GetServiceFactory()
+{
+ if ( m_xFactory.is() )
+ return m_xFactory;
+
+ return ::comphelper::getProcessServiceFactory();
+}
+
+//-----------------------------------------------
+::rtl::OUString OWriteStream_Impl::GetFilledTempFileIfNo( const uno::Reference< io::XInputStream >& xStream )
+{
+ if ( !m_aTempURL.getLength() )
+ {
+ ::rtl::OUString aTempURL = GetNewTempFileURL( GetServiceFactory() );
+
+ try {
+ if ( aTempURL && xStream.is() )
+ {
+ uno::Reference < ucb::XSimpleFileAccess > xTempAccess(
+ GetServiceFactory()->createInstance (
+ ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
+ uno::UNO_QUERY );
+
+ if ( !xTempAccess.is() )
+ throw uno::RuntimeException(); // TODO:
+
+ uno::Reference< io::XOutputStream > xTempOutStream = xTempAccess->openFileWrite( aTempURL );
+ if ( xTempOutStream.is() )
+ {
+ // the current position of the original stream should be still OK, copy further
+ ::comphelper::OStorageHelper::CopyInputToOutput( xStream, xTempOutStream );
+ xTempOutStream->closeOutput();
+ xTempOutStream = uno::Reference< io::XOutputStream >();
+ }
+ else
+ throw io::IOException(); // TODO:
+ }
+ }
+ catch( packages::WrongPasswordException& aWrongPasswordException )
+ {
+ AddLog( aWrongPasswordException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ KillFile( aTempURL, GetServiceFactory() );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ AddLog( aException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ KillFile( aTempURL, GetServiceFactory() );
+ throw;
+ }
+
+ if ( aTempURL.getLength() )
+ CleanCacheStream();
+
+ m_aTempURL = aTempURL;
+ }
+
+ return m_aTempURL;
+}
+
+//-----------------------------------------------
+::rtl::OUString OWriteStream_Impl::FillTempGetFileName()
+{
+ // should try to create cache first, if the amount of contents is too big, the temp file should be taken
+ if ( !m_xCacheStream.is() && !m_aTempURL.getLength() )
+ {
+ uno::Reference< io::XInputStream > xOrigStream = m_xPackageStream->getDataStream();
+ if ( !xOrigStream.is() )
+ {
+ // in case of new inserted package stream it is possible that input stream still was not set
+ uno::Reference< io::XStream > xCacheStream = CreateMemoryStream( GetServiceFactory() );
+ OSL_ENSURE( xCacheStream.is(), "If the stream can not be created an exception must be thrown!\n" );
+ m_xCacheSeek.set( xCacheStream, uno::UNO_QUERY_THROW );
+ m_xCacheStream = xCacheStream;
+ }
+ else
+ {
+ sal_Int32 nRead = 0;
+ uno::Sequence< sal_Int8 > aData( MAX_STORCACHE_SIZE + 1 );
+ nRead = xOrigStream->readBytes( aData, MAX_STORCACHE_SIZE + 1 );
+ if ( aData.getLength() > nRead )
+ aData.realloc( nRead );
+
+ if ( nRead <= MAX_STORCACHE_SIZE )
+ {
+ uno::Reference< io::XStream > xCacheStream = CreateMemoryStream( GetServiceFactory() );
+ OSL_ENSURE( xCacheStream.is(), "If the stream can not be created an exception must be thrown!\n" );
+
+ if ( nRead )
+ {
+ uno::Reference< io::XOutputStream > xOutStream( xCacheStream->getOutputStream(), uno::UNO_SET_THROW );
+ xOutStream->writeBytes( aData );
+ }
+ m_xCacheSeek.set( xCacheStream, uno::UNO_QUERY_THROW );
+ m_xCacheStream = xCacheStream;
+ m_xCacheSeek->seek( 0 );
+ }
+ else if ( !m_aTempURL.getLength() )
+ {
+ m_aTempURL = GetNewTempFileURL( GetServiceFactory() );
+
+ try {
+ if ( m_aTempURL.getLength() )
+ {
+ uno::Reference < ucb::XSimpleFileAccess > xTempAccess(
+ GetServiceFactory()->createInstance (
+ ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
+ uno::UNO_QUERY );
+
+ if ( !xTempAccess.is() )
+ throw uno::RuntimeException(); // TODO:
+
+
+ uno::Reference< io::XOutputStream > xTempOutStream = xTempAccess->openFileWrite( m_aTempURL );
+ if ( xTempOutStream.is() )
+ {
+ // copy stream contents to the file
+ xTempOutStream->writeBytes( aData );
+
+ // the current position of the original stream should be still OK, copy further
+ ::comphelper::OStorageHelper::CopyInputToOutput( xOrigStream, xTempOutStream );
+ xTempOutStream->closeOutput();
+ xTempOutStream = uno::Reference< io::XOutputStream >();
+ }
+ else
+ throw io::IOException(); // TODO:
+ }
+ }
+ catch( packages::WrongPasswordException& )
+ {
+ KillFile( m_aTempURL, GetServiceFactory() );
+ m_aTempURL = ::rtl::OUString();
+
+ throw;
+ }
+ catch( uno::Exception& )
+ {
+ KillFile( m_aTempURL, GetServiceFactory() );
+ m_aTempURL = ::rtl::OUString();
+ }
+ }
+ }
+ }
+
+ return m_aTempURL;
+}
+
+//-----------------------------------------------
+uno::Reference< io::XStream > OWriteStream_Impl::GetTempFileAsStream()
+{
+ uno::Reference< io::XStream > xTempStream;
+
+ if ( !m_xCacheStream.is() )
+ {
+ if ( !m_aTempURL.getLength() )
+ m_aTempURL = FillTempGetFileName();
+
+ if ( m_aTempURL.getLength() )
+ {
+ // the temporary file is not used if the cache is used
+ uno::Reference < ucb::XSimpleFileAccess > xTempAccess(
+ GetServiceFactory()->createInstance (
+ ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
+ uno::UNO_QUERY );
+
+ if ( !xTempAccess.is() )
+ throw uno::RuntimeException(); // TODO:
+
+ try
+ {
+ xTempStream = xTempAccess->openFileReadWrite( m_aTempURL );
+ }
+ catch( uno::Exception& aException )
+ {
+ AddLog( aException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+ }
+ }
+ }
+
+ if ( m_xCacheStream.is() )
+ xTempStream = m_xCacheStream;
+
+ // the method must always return a stream
+ // in case the stream can not be open
+ // an exception should be thrown
+ if ( !xTempStream.is() )
+ throw io::IOException(); //TODO:
+
+ return xTempStream;
+}
+
+//-----------------------------------------------
+uno::Reference< io::XInputStream > OWriteStream_Impl::GetTempFileAsInputStream()
+{
+ uno::Reference< io::XInputStream > xInputStream;
+
+ if ( !m_xCacheStream.is() )
+ {
+ if ( !m_aTempURL.getLength() )
+ m_aTempURL = FillTempGetFileName();
+
+ if ( m_aTempURL.getLength() )
+ {
+ // the temporary file is not used if the cache is used
+ uno::Reference < ucb::XSimpleFileAccess > xTempAccess(
+ GetServiceFactory()->createInstance (
+ ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
+ uno::UNO_QUERY );
+
+ if ( !xTempAccess.is() )
+ throw uno::RuntimeException(); // TODO:
+
+ try
+ {
+ xInputStream = xTempAccess->openFileRead( m_aTempURL );
+ }
+ catch( uno::Exception& aException )
+ {
+ AddLog( aException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+ }
+ }
+ }
+
+ if ( m_xCacheStream.is() )
+ xInputStream = m_xCacheStream->getInputStream();
+
+ // the method must always return a stream
+ // in case the stream can not be open
+ // an exception should be thrown
+ if ( !xInputStream.is() )
+ throw io::IOException(); // TODO:
+
+ return xInputStream;
+}
+
+// =================================================================================================
+
+//-----------------------------------------------
+void OWriteStream_Impl::InsertStreamDirectly( const uno::Reference< io::XInputStream >& xInStream,
+ const uno::Sequence< beans::PropertyValue >& aProps )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
+
+ // this call can be made only during parent storage commit
+ // the parent storage is responsible for the correct handling
+ // of deleted and renamed contents
+
+ OSL_ENSURE( m_xPackageStream.is(), "No package stream is set!\n" );
+
+ if ( m_bHasDataToFlush )
+ throw io::IOException();
+
+ OSL_ENSURE( !m_aTempURL.getLength() && !m_xCacheStream.is(), "The temporary must not exist!\n" );
+
+ // use new file as current persistent representation
+ // the new file will be removed after it's stream is closed
+ m_xPackageStream->setDataStream( xInStream );
+
+ // copy properties to the package stream
+ uno::Reference< beans::XPropertySet > xPropertySet( m_xPackageStream, uno::UNO_QUERY );
+ if ( !xPropertySet.is() )
+ throw uno::RuntimeException();
+
+ // The storage-package communication has a problem
+ // the storage caches properties, thus if the package changes one of them itself
+ // the storage does not know about it
+
+ // Depending from MediaType value the package can change the compressed property itself
+ // Thus if Compressed property is provided it must be set as the latest one
+ sal_Bool bCompressedIsSet = sal_False;
+ sal_Bool bCompressed = sal_False;
+ ::rtl::OUString aComprPropName( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) );
+ ::rtl::OUString aMedTypePropName( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
+ for ( sal_Int32 nInd = 0; nInd < aProps.getLength(); nInd++ )
+ {
+ if ( aProps[nInd].Name.equals( aComprPropName ) )
+ {
+ bCompressedIsSet = sal_True;
+ aProps[nInd].Value >>= bCompressed;
+ }
+ else if ( ( m_nStorageType == embed::StorageFormats::OFOPXML || m_nStorageType == embed::StorageFormats::PACKAGE )
+ && aProps[nInd].Name.equals( aMedTypePropName ) )
+ {
+ xPropertySet->setPropertyValue( aProps[nInd].Name, aProps[nInd].Value );
+ }
+ else if ( m_nStorageType == embed::StorageFormats::PACKAGE && aProps[nInd].Name.equalsAscii( "UseCommonStoragePasswordEncryption" ) )
+ aProps[nInd].Value >>= m_bUseCommonPass;
+ else
+ throw lang::IllegalArgumentException();
+
+ // if there are cached properties update them
+ if ( aProps[nInd].Name.equals( aMedTypePropName ) || aProps[nInd].Name.equals( aComprPropName ) )
+ for ( sal_Int32 nMemInd = 0; nMemInd < m_aProps.getLength(); nMemInd++ )
+ {
+ if ( aProps[nInd].Name.equals( m_aProps[nMemInd].Name ) )
+ m_aProps[nMemInd].Value = aProps[nInd].Value;
+ }
+ }
+
+ if ( bCompressedIsSet )
+ {
+ xPropertySet->setPropertyValue( aComprPropName, uno::makeAny( (sal_Bool)bCompressed ) );
+ m_bCompressedSetExplicit = sal_True;
+ }
+
+ if ( m_bUseCommonPass )
+ {
+ if ( m_nStorageType != embed::StorageFormats::PACKAGE )
+ throw uno::RuntimeException();
+
+ // set to be encrypted but do not use encryption key
+ xPropertySet->setPropertyValue( ::rtl::OUString::createFromAscii( "EncryptionKey" ),
+ uno::makeAny( uno::Sequence< sal_Int8 >() ) );
+ xPropertySet->setPropertyValue( ::rtl::OUString::createFromAscii( "Encrypted" ),
+ uno::makeAny( sal_True ) );
+ }
+
+ // the stream should be free soon, after package is stored
+ m_bHasDataToFlush = sal_False;
+ m_bFlushed = sal_True; // will allow to use transaction on stream level if will need it
+ m_bHasInsertedStreamOptimization = sal_True;
+}
+
+//-----------------------------------------------
+void OWriteStream_Impl::Commit()
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
+
+ OSL_ENSURE( m_xPackageStream.is(), "No package stream is set!\n" );
+
+ if ( !m_bHasDataToFlush )
+ return;
+
+ uno::Reference< packages::XDataSinkEncrSupport > xNewPackageStream;
+ uno::Sequence< uno::Any > aSeq( 1 );
+ aSeq[0] <<= sal_False;
+
+ if ( m_xCacheStream.is() )
+ {
+ if ( m_pAntiImpl )
+ m_pAntiImpl->DeInit();
+
+ uno::Reference< io::XInputStream > xInStream( m_xCacheStream->getInputStream(), uno::UNO_SET_THROW );
+
+ xNewPackageStream = uno::Reference< packages::XDataSinkEncrSupport >(
+ m_xPackage->createInstanceWithArguments( aSeq ),
+ uno::UNO_QUERY_THROW );
+
+ xNewPackageStream->setDataStream( xInStream );
+
+ m_xCacheStream = uno::Reference< io::XStream >();
+ m_xCacheSeek = uno::Reference< io::XSeekable >();
+
+ }
+ else if ( m_aTempURL.getLength() )
+ {
+ if ( m_pAntiImpl )
+ m_pAntiImpl->DeInit();
+
+ uno::Reference< io::XInputStream > xInStream;
+ try
+ {
+ xInStream.set( static_cast< io::XInputStream* >( new OSelfTerminateFileStream( GetServiceFactory(), m_aTempURL ) ), uno::UNO_QUERY );
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ if ( !xInStream.is() )
+ throw io::IOException();
+
+ xNewPackageStream = uno::Reference< packages::XDataSinkEncrSupport >(
+ m_xPackage->createInstanceWithArguments( aSeq ),
+ uno::UNO_QUERY_THROW );
+
+ // TODO/NEW: Let the temporary file be removed after commit
+ xNewPackageStream->setDataStream( xInStream );
+ m_aTempURL = ::rtl::OUString();
+ }
+ else // if ( m_bHasInsertedStreamOptimization )
+ {
+ // if the optimization is used the stream can be accessed directly
+ xNewPackageStream = m_xPackageStream;
+ }
+
+ // copy properties to the package stream
+ uno::Reference< beans::XPropertySet > xPropertySet( xNewPackageStream, uno::UNO_QUERY );
+ if ( !xPropertySet.is() )
+ throw uno::RuntimeException();
+
+ for ( sal_Int32 nInd = 0; nInd < m_aProps.getLength(); nInd++ )
+ {
+ if ( m_aProps[nInd].Name.equalsAscii( "Size" ) )
+ {
+ if ( m_pAntiImpl && !m_bHasInsertedStreamOptimization && m_pAntiImpl->m_xSeekable.is() )
+ {
+ m_aProps[nInd].Value <<= ((sal_Int32)m_pAntiImpl->m_xSeekable->getLength());
+ xPropertySet->setPropertyValue( m_aProps[nInd].Name, m_aProps[nInd].Value );
+ }
+ }
+ else
+ xPropertySet->setPropertyValue( m_aProps[nInd].Name, m_aProps[nInd].Value );
+ }
+
+ if ( m_bUseCommonPass )
+ {
+ if ( m_nStorageType != embed::StorageFormats::PACKAGE )
+ throw uno::RuntimeException();
+
+ // set to be encrypted but do not use encryption key
+ xPropertySet->setPropertyValue( ::rtl::OUString::createFromAscii( "EncryptionKey" ),
+ uno::makeAny( uno::Sequence< sal_Int8 >() ) );
+ xPropertySet->setPropertyValue( ::rtl::OUString::createFromAscii( "Encrypted" ),
+ uno::makeAny( sal_True ) );
+ }
+ else if ( m_bHasCachedPassword )
+ {
+ if ( m_nStorageType != embed::StorageFormats::PACKAGE )
+ throw uno::RuntimeException();
+
+ xPropertySet->setPropertyValue( ::rtl::OUString::createFromAscii( "EncryptionKey" ),
+ uno::makeAny( ::package::MakeKeyFromPass( m_aPass, sal_True ) ) );
+ }
+
+ // the stream should be free soon, after package is stored
+ m_xPackageStream = xNewPackageStream;
+ m_bHasDataToFlush = sal_False;
+ m_bFlushed = sal_True; // will allow to use transaction on stream level if will need it
+}
+
+//-----------------------------------------------
+void OWriteStream_Impl::Revert()
+{
+ // can be called only from parent storage
+ // means complete reload of the stream
+
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
+
+ if ( !m_bHasDataToFlush )
+ return; // nothing to do
+
+ OSL_ENSURE( m_aTempURL.getLength() || m_xCacheStream.is(), "The temporary must exist!\n" );
+
+ if ( m_xCacheStream.is() )
+ {
+ m_xCacheStream = uno::Reference< io::XStream >();
+ m_xCacheSeek = uno::Reference< io::XSeekable >();
+ }
+
+ if ( m_aTempURL.getLength() )
+ {
+ KillFile( m_aTempURL, GetServiceFactory() );
+ m_aTempURL = ::rtl::OUString();
+ }
+
+ m_aProps.realloc( 0 );
+
+ m_bHasDataToFlush = sal_False;
+
+ m_bUseCommonPass = sal_True;
+ m_bHasCachedPassword = sal_False;
+ m_aPass = ::rtl::OUString();
+
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ // currently the relations storage is changed only on commit
+ m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
+ m_aNewRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
+ if ( m_xOrigRelInfoStream.is() )
+ {
+ // the original stream is still here, that means that it was not parsed
+ m_aOrigRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
+ m_nRelInfoStatus = RELINFO_NO_INIT;
+ }
+ else
+ {
+ // the original stream was aready parsed
+ if ( !m_bOrigRelInfoBroken )
+ m_nRelInfoStatus = RELINFO_READ;
+ else
+ m_nRelInfoStatus = RELINFO_BROKEN;
+ }
+ }
+}
+
+//-----------------------------------------------
+uno::Sequence< beans::PropertyValue > OWriteStream_Impl::GetStreamProperties()
+{
+ if ( !m_aProps.getLength() )
+ m_aProps = ReadPackageStreamProperties();
+
+ return m_aProps;
+}
+
+//-----------------------------------------------
+uno::Sequence< beans::PropertyValue > OWriteStream_Impl::InsertOwnProps(
+ const uno::Sequence< beans::PropertyValue >& aProps,
+ sal_Bool bUseCommonPass )
+{
+ uno::Sequence< beans::PropertyValue > aResult( aProps );
+ sal_Int32 nLen = aResult.getLength();
+
+ if ( m_nStorageType == embed::StorageFormats::PACKAGE )
+ {
+ for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ )
+ if ( aResult[nInd].Name.equalsAscii( "UseCommonStoragePasswordEncryption" ) )
+ {
+ aResult[nInd].Value <<= bUseCommonPass;
+ return aResult;
+ }
+
+ aResult.realloc( ++nLen );
+ aResult[nLen - 1].Name = ::rtl::OUString::createFromAscii( "UseCommonStoragePasswordEncryption" );
+ aResult[nLen - 1].Value <<= bUseCommonPass;
+ }
+ else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ ReadRelInfoIfNecessary();
+
+ uno::Any aValue;
+ if ( m_nRelInfoStatus == RELINFO_READ )
+ aValue <<= m_aOrigRelInfo;
+ else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ || m_nRelInfoStatus == RELINFO_CHANGED )
+ aValue <<= m_aNewRelInfo;
+ else // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Wrong relinfo stream!" ) ),
+ uno::Reference< uno::XInterface >() );
+
+ for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ )
+ if ( aResult[nInd].Name.equalsAscii( "RelationsInfo" ) )
+ {
+ aResult[nInd].Value = aValue;
+ return aResult;
+ }
+
+ aResult.realloc( ++nLen );
+ aResult[nLen - 1].Name = ::rtl::OUString::createFromAscii( "RelationsInfo" );
+ aResult[nLen - 1].Value = aValue;
+ }
+
+ return aResult;
+}
+
+//-----------------------------------------------
+sal_Bool OWriteStream_Impl::IsTransacted()
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
+ return ( m_pAntiImpl && m_pAntiImpl->m_bTransacted );
+}
+
+void OWriteStream_Impl::ReadRelInfoIfNecessary()
+{
+ if ( m_nStorageType != embed::StorageFormats::OFOPXML )
+ return;
+
+ if ( m_nRelInfoStatus == RELINFO_NO_INIT )
+ {
+ try
+ {
+ // Init from original stream
+ if ( m_xOrigRelInfoStream.is() )
+ m_aOrigRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
+ m_xOrigRelInfoStream,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels/*.rels" ) ),
+ m_xFactory );
+
+ // in case of success the stream must be thrown away, that means that the OrigRelInfo is initialized
+ // the reason for this is that the original stream might not be seekable ( at the same time the new
+ // provided stream must be seekable ), so it must be read only once
+ m_xOrigRelInfoStream = uno::Reference< io::XInputStream >();
+ m_nRelInfoStatus = RELINFO_READ;
+ }
+ catch( uno::Exception& aException )
+ {
+ AddLog( aException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+
+ m_nRelInfoStatus = RELINFO_BROKEN;
+ m_bOrigRelInfoBroken = sal_True;
+ }
+ }
+ else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
+ {
+ // Init from the new stream
+ try
+ {
+ if ( m_xNewRelInfoStream.is() )
+ m_aNewRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
+ m_xNewRelInfoStream,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels/*.rels" ) ),
+ m_xFactory );
+
+ m_nRelInfoStatus = RELINFO_CHANGED_STREAM_READ;
+ }
+ catch( uno::Exception )
+ {
+ m_nRelInfoStatus = RELINFO_CHANGED_BROKEN;
+ }
+ }
+}
+
+//-----------------------------------------------
+uno::Sequence< beans::PropertyValue > OWriteStream_Impl::ReadPackageStreamProperties()
+{
+ sal_Int32 nPropNum = 0;
+ if ( m_nStorageType == embed::StorageFormats::ZIP )
+ nPropNum = 2;
+ else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
+ nPropNum = 3;
+ else if ( m_nStorageType == embed::StorageFormats::PACKAGE )
+ nPropNum = 4;
+ uno::Sequence< beans::PropertyValue > aResult( nPropNum );
+
+ // The "Compressed" property must be set after "MediaType" property,
+ // since the setting of the last one can change the value of the first one
+
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML || m_nStorageType == embed::StorageFormats::PACKAGE )
+ {
+ aResult[0].Name = ::rtl::OUString::createFromAscii("MediaType");
+ aResult[1].Name = ::rtl::OUString::createFromAscii("Compressed");
+ aResult[2].Name = ::rtl::OUString::createFromAscii("Size");
+
+ if ( m_nStorageType == embed::StorageFormats::PACKAGE )
+ aResult[3].Name = ::rtl::OUString::createFromAscii("Encrypted");
+ }
+ else
+ {
+ aResult[0].Name = ::rtl::OUString::createFromAscii("Compressed");
+ aResult[1].Name = ::rtl::OUString::createFromAscii("Size");
+
+ }
+
+ // TODO: may be also raw stream should be marked
+
+ uno::Reference< beans::XPropertySet > xPropSet( m_xPackageStream, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ for ( sal_Int32 nInd = 0; nInd < aResult.getLength(); nInd++ )
+ {
+ try {
+ aResult[nInd].Value = xPropSet->getPropertyValue( aResult[nInd].Name );
+ }
+ catch( uno::Exception& aException )
+ {
+ AddLog( aException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+
+ OSL_ENSURE( sal_False, "A property can't be retrieved!\n" );
+ }
+ }
+ }
+ else
+ {
+ OSL_ENSURE( sal_False, "Can not get properties from a package stream!\n" );
+ throw uno::RuntimeException();
+ }
+
+ return aResult;
+}
+
+//-----------------------------------------------
+void OWriteStream_Impl::CopyInternallyTo_Impl( const uno::Reference< io::XStream >& xDestStream,
+ const ::rtl::OUString& aPass )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
+
+ OSL_ENSURE( !m_bUseCommonPass, "The stream can not be encrypted!" );
+
+ if ( m_nStorageType != embed::StorageFormats::PACKAGE )
+ throw packages::NoEncryptionException();
+
+ if ( m_pAntiImpl )
+ {
+ m_pAntiImpl->CopyToStreamInternally_Impl( xDestStream );
+ }
+ else
+ {
+ uno::Reference< io::XStream > xOwnStream = GetStream( embed::ElementModes::READ, aPass, sal_False );
+ if ( !xOwnStream.is() )
+ throw io::IOException(); // TODO
+
+ OStorage_Impl::completeStorageStreamCopy_Impl( xOwnStream, xDestStream, m_nStorageType, GetAllRelationshipsIfAny() );
+ }
+
+ uno::Reference< embed::XEncryptionProtectedSource > xEncr( xDestStream, uno::UNO_QUERY );
+ if ( xEncr.is() )
+ xEncr->setEncryptionPassword( aPass );
+}
+
+//-----------------------------------------------
+uno::Sequence< uno::Sequence< beans::StringPair > > OWriteStream_Impl::GetAllRelationshipsIfAny()
+{
+ if ( m_nStorageType != embed::StorageFormats::OFOPXML )
+ return uno::Sequence< uno::Sequence< beans::StringPair > >();
+
+ ReadRelInfoIfNecessary();
+
+ if ( m_nRelInfoStatus == RELINFO_READ )
+ return m_aOrigRelInfo;
+ else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ || m_nRelInfoStatus == RELINFO_CHANGED )
+ return m_aNewRelInfo;
+ else // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Wrong relinfo stream!" ) ),
+ uno::Reference< uno::XInterface >() );
+}
+
+//-----------------------------------------------
+void OWriteStream_Impl::CopyInternallyTo_Impl( const uno::Reference< io::XStream >& xDestStream )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
+
+ if ( m_pAntiImpl )
+ {
+ m_pAntiImpl->CopyToStreamInternally_Impl( xDestStream );
+ }
+ else
+ {
+ uno::Reference< io::XStream > xOwnStream = GetStream( embed::ElementModes::READ, sal_False );
+ if ( !xOwnStream.is() )
+ throw io::IOException(); // TODO
+
+ OStorage_Impl::completeStorageStreamCopy_Impl( xOwnStream, xDestStream, m_nStorageType, GetAllRelationshipsIfAny() );
+ }
+}
+
+//-----------------------------------------------
+uno::Reference< io::XStream > OWriteStream_Impl::GetStream( sal_Int32 nStreamMode, const ::rtl::OUString& aPass, sal_Bool bHierarchyAccess )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
+
+ OSL_ENSURE( m_xPackageStream.is(), "No package stream is set!\n" );
+
+ if ( m_pAntiImpl )
+ throw io::IOException(); // TODO:
+
+ if ( !IsEncrypted() )
+ throw packages::NoEncryptionException();
+
+ uno::Reference< io::XStream > xResultStream;
+
+ uno::Reference< beans::XPropertySet > xPropertySet( m_xPackageStream, uno::UNO_QUERY );
+ if ( !xPropertySet.is() )
+ throw uno::RuntimeException();
+
+ if ( m_bHasCachedPassword )
+ {
+ if ( !m_aPass.equals( aPass ) )
+ throw packages::WrongPasswordException();
+
+ // the correct key must be set already
+ xResultStream = GetStream_Impl( nStreamMode, bHierarchyAccess );
+ }
+ else
+ {
+ SetEncryptionKeyProperty_Impl( xPropertySet, ::package::MakeKeyFromPass( aPass, sal_True ) );
+
+ try {
+ xResultStream = GetStream_Impl( nStreamMode, bHierarchyAccess );
+
+ m_bUseCommonPass = sal_False; // very important to set it to false
+ m_bHasCachedPassword = sal_True;
+ m_aPass = aPass;
+ }
+ catch( packages::WrongPasswordException& )
+ {
+ // retry with different encoding
+ SetEncryptionKeyProperty_Impl( xPropertySet, ::package::MakeKeyFromPass( aPass, sal_False ) );
+ try {
+ // the stream must be cashed to be resaved
+ xResultStream = GetStream_Impl( nStreamMode | embed::ElementModes::SEEKABLE, bHierarchyAccess );
+
+ m_bUseCommonPass = sal_False; // very important to set it to false
+ m_bHasCachedPassword = sal_True;
+ m_aPass = aPass;
+
+ // the stream must be resaved with new password encryption
+ if ( nStreamMode & embed::ElementModes::WRITE )
+ {
+ FillTempGetFileName();
+ m_bHasDataToFlush = sal_True;
+
+ // TODO/LATER: should the notification be done?
+ if ( m_pParent )
+ m_pParent->m_bIsModified = sal_True;
+ }
+ }
+ catch( packages::WrongPasswordException& aWrongPasswordException )
+ {
+ SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
+ AddLog( aWrongPasswordException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch ( uno::Exception& aException )
+ {
+ AddLog( aException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+
+ OSL_ENSURE( sal_False, "Can't write encryption related properties!\n" );
+ SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
+ throw io::IOException(); // TODO:
+ }
+ }
+ catch( uno::Exception& aException )
+ {
+ SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
+
+ AddLog( aException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+
+ }
+
+ OSL_ENSURE( xResultStream.is(), "In case stream can not be retrieved an exception must be thrown!\n" );
+
+ return xResultStream;
+}
+
+//-----------------------------------------------
+uno::Reference< io::XStream > OWriteStream_Impl::GetStream( sal_Int32 nStreamMode, sal_Bool bHierarchyAccess )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
+
+ OSL_ENSURE( m_xPackageStream.is(), "No package stream is set!\n" );
+
+ if ( m_pAntiImpl )
+ throw io::IOException(); // TODO:
+
+ uno::Reference< io::XStream > xResultStream;
+
+ if ( IsEncrypted() )
+ {
+ ::rtl::OUString aGlobalPass;
+ try
+ {
+ aGlobalPass = GetCommonRootPass();
+ }
+ catch( packages::NoEncryptionException& aNoEncryptionException )
+ {
+ AddLog( aNoEncryptionException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ throw packages::WrongPasswordException();
+ }
+
+ xResultStream = GetStream( nStreamMode, aGlobalPass, bHierarchyAccess );
+ }
+ else
+ xResultStream = GetStream_Impl( nStreamMode, bHierarchyAccess );
+
+ return xResultStream;
+}
+
+//-----------------------------------------------
+uno::Reference< io::XStream > OWriteStream_Impl::GetStream_Impl( sal_Int32 nStreamMode, sal_Bool bHierarchyAccess )
+{
+ // private method, no mutex is used
+ GetStreamProperties();
+
+ // TODO/LATER: this info might be read later, on demand in future
+ ReadRelInfoIfNecessary();
+
+ if ( ( nStreamMode & embed::ElementModes::READWRITE ) == embed::ElementModes::READ )
+ {
+ uno::Reference< io::XInputStream > xInStream;
+ if ( m_xCacheStream.is() || m_aTempURL.getLength() )
+ xInStream = GetTempFileAsInputStream(); //TODO:
+ else
+ xInStream = m_xPackageStream->getDataStream();
+
+ // The stream does not exist in the storage
+ if ( !xInStream.is() )
+ throw io::IOException();
+
+ OInputCompStream* pStream = new OInputCompStream( *this, xInStream, InsertOwnProps( m_aProps, m_bUseCommonPass ), m_nStorageType );
+ uno::Reference< io::XStream > xCompStream(
+ static_cast< ::cppu::OWeakObject* >( pStream ),
+ uno::UNO_QUERY );
+ OSL_ENSURE( xCompStream.is(),
+ "OInputCompStream MUST provide XStream interfaces!\n" );
+
+ m_aInputStreamsList.push_back( pStream );
+ return xCompStream;
+ }
+ else if ( ( nStreamMode & embed::ElementModes::READWRITE ) == embed::ElementModes::SEEKABLEREAD )
+ {
+ if ( !m_xCacheStream.is() && !m_aTempURL.getLength() && !( m_xPackageStream->getDataStream().is() ) )
+ {
+ // The stream does not exist in the storage
+ throw io::IOException();
+ }
+
+ uno::Reference< io::XInputStream > xInStream;
+
+ xInStream = GetTempFileAsInputStream(); //TODO:
+
+ if ( !xInStream.is() )
+ throw io::IOException();
+
+ OInputSeekStream* pStream = new OInputSeekStream( *this, xInStream, InsertOwnProps( m_aProps, m_bUseCommonPass ), m_nStorageType );
+ uno::Reference< io::XStream > xSeekStream(
+ static_cast< ::cppu::OWeakObject* >( pStream ),
+ uno::UNO_QUERY );
+ OSL_ENSURE( xSeekStream.is(),
+ "OInputSeekStream MUST provide XStream interfaces!\n" );
+
+ m_aInputStreamsList.push_back( pStream );
+ return xSeekStream;
+ }
+ else if ( ( nStreamMode & embed::ElementModes::WRITE ) == embed::ElementModes::WRITE )
+ {
+ if ( !m_aInputStreamsList.empty() )
+ throw io::IOException(); // TODO:
+
+ uno::Reference< io::XStream > xStream;
+ if ( ( nStreamMode & embed::ElementModes::TRUNCATE ) == embed::ElementModes::TRUNCATE )
+ {
+ if ( m_aTempURL.getLength() )
+ {
+ KillFile( m_aTempURL, GetServiceFactory() );
+ m_aTempURL = ::rtl::OUString();
+ }
+ if ( m_xCacheStream.is() )
+ CleanCacheStream();
+
+ m_bHasDataToFlush = sal_True;
+
+ // this call is triggered by the parent and it will recognize the change of the state
+ if ( m_pParent )
+ m_pParent->m_bIsModified = sal_True;
+
+ xStream = CreateMemoryStream( GetServiceFactory() );
+ m_xCacheSeek.set( xStream, uno::UNO_QUERY_THROW );
+ m_xCacheStream = xStream;
+ }
+ else if ( !m_bHasInsertedStreamOptimization )
+ {
+ if ( !m_aTempURL.getLength() && !m_xCacheStream.is() && !( m_xPackageStream->getDataStream().is() ) )
+ {
+ // The stream does not exist in the storage
+ m_bHasDataToFlush = sal_True;
+
+ // this call is triggered by the parent and it will recognize the change of the state
+ if ( m_pParent )
+ m_pParent->m_bIsModified = sal_True;
+ xStream = GetTempFileAsStream();
+ }
+
+ // if the stream exists the temporary file is created on demand
+ // xStream = GetTempFileAsStream();
+ }
+
+ if ( !xStream.is() )
+ m_pAntiImpl = new OWriteStream( this, bHierarchyAccess );
+ else
+ m_pAntiImpl = new OWriteStream( this, xStream, bHierarchyAccess );
+
+ uno::Reference< io::XStream > xWriteStream =
+ uno::Reference< io::XStream >( static_cast< ::cppu::OWeakObject* >( m_pAntiImpl ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE( xWriteStream.is(), "OWriteStream MUST implement XStream && XComponent interfaces!\n" );
+
+ return xWriteStream;
+ }
+
+ throw lang::IllegalArgumentException(); // TODO
+}
+
+//-----------------------------------------------
+uno::Reference< io::XInputStream > OWriteStream_Impl::GetPlainRawInStream()
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
+
+ OSL_ENSURE( m_xPackageStream.is(), "No package stream is set!\n" );
+
+ // this method is used only internally, this stream object should not go outside of this implementation
+ // if ( m_pAntiImpl )
+ // throw io::IOException(); // TODO:
+
+ return m_xPackageStream->getPlainRawStream();
+}
+
+//-----------------------------------------------
+uno::Reference< io::XInputStream > OWriteStream_Impl::GetRawInStream()
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
+
+ OSL_ENSURE( m_xPackageStream.is(), "No package stream is set!\n" );
+
+ if ( m_pAntiImpl )
+ throw io::IOException(); // TODO:
+
+ OSL_ENSURE( IsEncrypted(), "Impossible to get raw representation for nonencrypted stream!\n" );
+ if ( !IsEncrypted() )
+ throw packages::NoEncryptionException();
+
+ return m_xPackageStream->getRawStream();
+}
+
+//-----------------------------------------------
+::rtl::OUString OWriteStream_Impl::GetCommonRootPass()
+ throw ( packages::NoEncryptionException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
+
+ if ( m_nStorageType != embed::StorageFormats::PACKAGE || !m_pParent )
+ throw packages::NoEncryptionException();
+
+ return m_pParent->GetCommonRootPass();
+}
+
+//-----------------------------------------------
+void OWriteStream_Impl::InputStreamDisposed( OInputCompStream* pStream )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ m_aInputStreamsList.remove( pStream );
+}
+
+//-----------------------------------------------
+void OWriteStream_Impl::CreateReadonlyCopyBasedOnData( const uno::Reference< io::XInputStream >& xDataToCopy, const uno::Sequence< beans::PropertyValue >& aProps, sal_Bool, uno::Reference< io::XStream >& xTargetStream )
+{
+ uno::Reference < io::XStream > xTempFile;
+ if ( !xTargetStream.is() )
+ xTempFile = uno::Reference < io::XStream >(
+ m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
+ uno::UNO_QUERY );
+ else
+ xTempFile = xTargetStream;
+
+ uno::Reference < io::XSeekable > xTempSeek( xTempFile, uno::UNO_QUERY );
+ if ( !xTempSeek.is() )
+ throw uno::RuntimeException(); // TODO
+
+ uno::Reference < io::XOutputStream > xTempOut = xTempFile->getOutputStream();
+ if ( !xTempOut.is() )
+ throw uno::RuntimeException();
+
+ if ( xDataToCopy.is() )
+ ::comphelper::OStorageHelper::CopyInputToOutput( xDataToCopy, xTempOut );
+
+ xTempOut->closeOutput();
+ xTempSeek->seek( 0 );
+
+ uno::Reference< io::XInputStream > xInStream = xTempFile->getInputStream();
+ if ( !xInStream.is() )
+ throw io::IOException();
+
+ // TODO: remember last state of m_bUseCommonPass
+ if ( !xTargetStream.is() )
+ xTargetStream = uno::Reference< io::XStream > (
+ static_cast< ::cppu::OWeakObject* >(
+ new OInputSeekStream( xInStream, InsertOwnProps( aProps, m_bUseCommonPass ), m_nStorageType ) ),
+ uno::UNO_QUERY_THROW );
+}
+
+//-----------------------------------------------
+void OWriteStream_Impl::GetCopyOfLastCommit( uno::Reference< io::XStream >& xTargetStream )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ OSL_ENSURE( m_xPackageStream.is(), "The source stream for copying is incomplete!\n" );
+ if ( !m_xPackageStream.is() )
+ throw uno::RuntimeException();
+
+ uno::Reference< io::XInputStream > xDataToCopy;
+ if ( IsEncrypted() )
+ {
+ // an encrypted stream must contain input stream
+ ::rtl::OUString aGlobalPass;
+ try
+ {
+ aGlobalPass = GetCommonRootPass();
+ }
+ catch( packages::NoEncryptionException& aNoEncryptionException )
+ {
+ AddLog( aNoEncryptionException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No Element" ) ) );
+
+ throw packages::WrongPasswordException();
+ }
+
+ GetCopyOfLastCommit( xTargetStream, aGlobalPass );
+ }
+ else
+ {
+ xDataToCopy = m_xPackageStream->getDataStream();
+
+ // in case of new inserted package stream it is possible that input stream still was not set
+ GetStreamProperties();
+
+ CreateReadonlyCopyBasedOnData( xDataToCopy, m_aProps, m_bUseCommonPass, xTargetStream );
+ }
+}
+
+//-----------------------------------------------
+void OWriteStream_Impl::GetCopyOfLastCommit( uno::Reference< io::XStream >& xTargetStream, const ::rtl::OUString& aPass )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ OSL_ENSURE( m_xPackageStream.is(), "The source stream for copying is incomplete!\n" );
+ if ( !m_xPackageStream.is() )
+ throw uno::RuntimeException();
+
+ if ( !IsEncrypted() )
+ throw packages::NoEncryptionException();
+
+ uno::Reference< io::XInputStream > xDataToCopy;
+
+ if ( m_bHasCachedPassword )
+ {
+ // TODO: introduce last commited cashed password information and use it here
+ // that means "use common pass" also should be remembered on flash
+ uno::Sequence< sal_Int8 > aNewKey = ::package::MakeKeyFromPass( aPass, sal_True );
+ uno::Sequence< sal_Int8 > aOldKey = ::package::MakeKeyFromPass( aPass, sal_False );
+
+ uno::Reference< beans::XPropertySet > xProps( m_xPackageStream, uno::UNO_QUERY );
+ if ( !xProps.is() )
+ throw uno::RuntimeException();
+
+ sal_Bool bEncr = sal_False;
+ xProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Encrypted" ) ) >>= bEncr;
+ if ( !bEncr )
+ throw packages::NoEncryptionException();
+
+ uno::Sequence< sal_Int8 > aEncrKey;
+ xProps->getPropertyValue( ::rtl::OUString::createFromAscii( "EncryptionKey" ) ) >>= aEncrKey;
+ if ( !SequencesEqual( aNewKey, aEncrKey ) && !SequencesEqual( aOldKey, aEncrKey ) )
+ throw packages::WrongPasswordException();
+
+ // the correct key must be set already
+ xDataToCopy = m_xPackageStream->getDataStream();
+ }
+ else
+ {
+ uno::Reference< beans::XPropertySet > xPropertySet( m_xPackageStream, uno::UNO_QUERY );
+ SetEncryptionKeyProperty_Impl( xPropertySet, ::package::MakeKeyFromPass( aPass, sal_True ) );
+
+ try {
+ xDataToCopy = m_xPackageStream->getDataStream();
+
+ if ( !xDataToCopy.is() )
+ {
+ OSL_ENSURE( sal_False, "Encrypted ZipStream must already have input stream inside!\n" );
+ SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
+ }
+ }
+ catch( packages::WrongPasswordException& aWrongPasswordException )
+ {
+ SetEncryptionKeyProperty_Impl( xPropertySet, ::package::MakeKeyFromPass( aPass, sal_False ) );
+ try {
+ xDataToCopy = m_xPackageStream->getDataStream();
+
+ if ( !xDataToCopy.is() )
+ {
+ OSL_ENSURE( sal_False, "Encrypted ZipStream must already have input stream inside!\n" );
+ SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
+ AddLog( aWrongPasswordException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ }
+ catch( uno::Exception& aException )
+ {
+ SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
+ AddLog( aException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ }
+ catch( uno::Exception& aException )
+ {
+ OSL_ENSURE( sal_False, "Can't open encrypted stream!\n" );
+ SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
+ AddLog( aException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+
+ SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
+ }
+
+ // in case of new inserted package stream it is possible that input stream still was not set
+ GetStreamProperties();
+
+ CreateReadonlyCopyBasedOnData( xDataToCopy, m_aProps, m_bUseCommonPass, xTargetStream );
+}
+
+//-----------------------------------------------
+void OWriteStream_Impl::CommitStreamRelInfo( const uno::Reference< embed::XStorage >& xRelStorage, const ::rtl::OUString& aOrigStreamName, const ::rtl::OUString& aNewStreamName )
+{
+ // at this point of time the old stream must be already cleaned
+ OSL_ENSURE( m_nStorageType == embed::StorageFormats::OFOPXML, "The method should be used only with OFOPXML format!\n" );
+
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ OSL_ENSURE( aOrigStreamName.getLength() && aNewStreamName.getLength() && xRelStorage.is(),
+ "Wrong relation persistence information is provided!\n" );
+
+ if ( !xRelStorage.is() || !aOrigStreamName.getLength() || !aNewStreamName.getLength() )
+ throw uno::RuntimeException();
+
+ if ( m_nRelInfoStatus == RELINFO_BROKEN || m_nRelInfoStatus == RELINFO_CHANGED_BROKEN )
+ throw io::IOException(); // TODO:
+
+ ::rtl::OUString aOrigRelStreamName = aOrigStreamName;
+ aOrigRelStreamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) );
+
+ ::rtl::OUString aNewRelStreamName = aNewStreamName;
+ aNewRelStreamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) );
+
+ sal_Bool bRenamed = !aOrigRelStreamName.equals( aNewRelStreamName );
+ if ( m_nRelInfoStatus == RELINFO_CHANGED
+ || m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
+ || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
+ {
+ if ( bRenamed && xRelStorage->hasByName( aOrigRelStreamName ) )
+ xRelStorage->removeElement( aOrigRelStreamName );
+
+ if ( m_nRelInfoStatus == RELINFO_CHANGED )
+ {
+ if ( m_aNewRelInfo.getLength() )
+ {
+ uno::Reference< io::XStream > xRelsStream =
+ xRelStorage->openStreamElement( aNewRelStreamName,
+ embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
+
+ uno::Reference< io::XOutputStream > xOutStream = xRelsStream->getOutputStream();
+ if ( !xOutStream.is() )
+ throw uno::RuntimeException();
+
+ ::comphelper::OFOPXMLHelper::WriteRelationsInfoSequence( xOutStream, m_aNewRelInfo, m_xFactory );
+
+ // set the mediatype
+ uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
+ xPropSet->setPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
+ uno::makeAny( ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) );
+
+ m_nRelInfoStatus = RELINFO_READ;
+ }
+ }
+ else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
+ || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
+ {
+ uno::Reference< io::XStream > xRelsStream =
+ xRelStorage->openStreamElement( aNewRelStreamName,
+ embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
+
+ uno::Reference< io::XOutputStream > xOutputStream = xRelsStream->getOutputStream();
+ if ( !xOutputStream.is() )
+ throw uno::RuntimeException();
+
+ uno::Reference< io::XSeekable > xSeek( m_xNewRelInfoStream, uno::UNO_QUERY_THROW );
+ xSeek->seek( 0 );
+ ::comphelper::OStorageHelper::CopyInputToOutput( m_xNewRelInfoStream, xOutputStream );
+ xSeek->seek( 0 );
+
+ // set the mediatype
+ uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
+ xPropSet->setPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
+ uno::makeAny( ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) );
+
+ if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
+ m_nRelInfoStatus = RELINFO_NO_INIT;
+ else
+ {
+ // the information is already parsed and the stream is stored, no need in temporary stream any more
+ m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
+ m_nRelInfoStatus = RELINFO_READ;
+ }
+ }
+
+ // the original stream makes no sence after this step
+ m_xOrigRelInfoStream = m_xNewRelInfoStream;
+ m_aOrigRelInfo = m_aNewRelInfo;
+ m_bOrigRelInfoBroken = sal_False;
+ m_aNewRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
+ m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
+ }
+ else
+ {
+ // the stream is not changed but it might be renamed
+ if ( bRenamed && xRelStorage->hasByName( aOrigRelStreamName ) )
+ xRelStorage->renameElement( aOrigRelStreamName, aNewRelStreamName );
+ }
+ }
+}
+
+//===============================================
+// OWriteStream implementation
+//===============================================
+
+//-----------------------------------------------
+OWriteStream::OWriteStream( OWriteStream_Impl* pImpl, sal_Bool bTransacted )
+: m_pImpl( pImpl )
+, m_bInStreamDisconnected( sal_False )
+, m_bInitOnDemand( sal_True )
+, m_nInitPosition( 0 )
+, m_bTransacted( bTransacted )
+{
+ OSL_ENSURE( pImpl, "No base implementation!\n" );
+ OSL_ENSURE( m_pImpl->m_rMutexRef.Is(), "No mutex!\n" );
+
+ if ( !m_pImpl || !m_pImpl->m_rMutexRef.Is() )
+ throw uno::RuntimeException(); // just a disaster
+
+ m_pData = new WSInternalData_Impl( pImpl->m_rMutexRef, m_pImpl->m_nStorageType );
+}
+
+//-----------------------------------------------
+OWriteStream::OWriteStream( OWriteStream_Impl* pImpl, uno::Reference< io::XStream > xStream, sal_Bool bTransacted )
+: m_pImpl( pImpl )
+, m_bInStreamDisconnected( sal_False )
+, m_bInitOnDemand( sal_False )
+, m_nInitPosition( 0 )
+, m_bTransacted( bTransacted )
+{
+ OSL_ENSURE( pImpl && xStream.is(), "No base implementation!\n" );
+ OSL_ENSURE( m_pImpl->m_rMutexRef.Is(), "No mutex!\n" );
+
+ if ( !m_pImpl || !m_pImpl->m_rMutexRef.Is() )
+ throw uno::RuntimeException(); // just a disaster
+
+ m_pData = new WSInternalData_Impl( pImpl->m_rMutexRef, m_pImpl->m_nStorageType );
+
+ if ( xStream.is() )
+ {
+ m_xInStream = xStream->getInputStream();
+ m_xOutStream = xStream->getOutputStream();
+ m_xSeekable = uno::Reference< io::XSeekable >( xStream, uno::UNO_QUERY );
+ OSL_ENSURE( m_xInStream.is() && m_xOutStream.is() && m_xSeekable.is(), "Stream implementation is incomplete!\n" );
+ }
+}
+
+//-----------------------------------------------
+OWriteStream::~OWriteStream()
+{
+ {
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+ if ( m_pImpl )
+ {
+ m_refCount++;
+ try {
+ dispose();
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+ }
+ }
+ }
+
+ if ( m_pData && m_pData->m_pTypeCollection )
+ delete m_pData->m_pTypeCollection;
+
+ if ( m_pData )
+ delete m_pData;
+}
+
+//-----------------------------------------------
+void OWriteStream::DeInit()
+{
+ if ( !m_pImpl )
+ return; // do nothing
+
+ if ( m_xSeekable.is() )
+ m_nInitPosition = m_xSeekable->getPosition();
+
+ m_xInStream = uno::Reference< io::XInputStream >();
+ m_xOutStream = uno::Reference< io::XOutputStream >();
+ m_xSeekable = uno::Reference< io::XSeekable >();
+ m_bInitOnDemand = sal_True;
+}
+
+//-----------------------------------------------
+void OWriteStream::CheckInitOnDemand()
+{
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_bInitOnDemand )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OWriteStream::CheckInitOnDemand, initializing" );
+ uno::Reference< io::XStream > xStream = m_pImpl->GetTempFileAsStream();
+ if ( xStream.is() )
+ {
+ m_xInStream.set( xStream->getInputStream(), uno::UNO_SET_THROW );
+ m_xOutStream.set( xStream->getOutputStream(), uno::UNO_SET_THROW );
+ m_xSeekable.set( xStream, uno::UNO_QUERY_THROW );
+ m_xSeekable->seek( m_nInitPosition );
+
+ m_nInitPosition = 0;
+ m_bInitOnDemand = sal_False;
+ }
+ }
+}
+
+//-----------------------------------------------
+void OWriteStream::CopyToStreamInternally_Impl( const uno::Reference< io::XStream >& xDest )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ CheckInitOnDemand();
+
+ if ( !m_xInStream.is() )
+ throw uno::RuntimeException();
+
+ if ( !m_xSeekable.is() )
+ throw uno::RuntimeException();
+
+ uno::Reference< beans::XPropertySet > xDestProps( xDest, uno::UNO_QUERY );
+ if ( !xDestProps.is() )
+ throw uno::RuntimeException(); //TODO
+
+ uno::Reference< io::XOutputStream > xDestOutStream = xDest->getOutputStream();
+ if ( !xDestOutStream.is() )
+ throw io::IOException(); // TODO
+
+ sal_Int64 nCurPos = m_xSeekable->getPosition();
+ m_xSeekable->seek( 0 );
+
+ uno::Exception eThrown;
+ sal_Bool bThrown = sal_False;
+ try {
+ ::comphelper::OStorageHelper::CopyInputToOutput( m_xInStream, xDestOutStream );
+ }
+ catch ( uno::Exception& e )
+ {
+ eThrown = e;
+ bThrown = sal_True;
+ }
+
+ // position-related section below is critical
+ // if it fails the stream will become invalid
+ try {
+ m_xSeekable->seek( nCurPos );
+ }
+ catch ( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+
+ // TODO: set the stoream in invalid state or dispose
+ OSL_ENSURE( sal_False, "The stream become invalid during copiing!\n" );
+ throw uno::RuntimeException();
+ }
+
+ if ( bThrown )
+ throw eThrown;
+
+ // now the properties can be copied
+ // the order of the properties setting is not important for StorageStream API
+ ::rtl::OUString aPropName = ::rtl::OUString::createFromAscii( "Compressed" );
+ xDestProps->setPropertyValue( aPropName, getPropertyValue( aPropName ) );
+ if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE || m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ aPropName = ::rtl::OUString::createFromAscii( "MediaType" );
+ xDestProps->setPropertyValue( aPropName, getPropertyValue( aPropName ) );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
+ {
+ aPropName = ::rtl::OUString::createFromAscii( "UseCommonStoragePasswordEncryption" );
+ xDestProps->setPropertyValue( aPropName, getPropertyValue( aPropName ) );
+ }
+ }
+}
+
+//-----------------------------------------------
+void OWriteStream::ModifyParentUnlockMutex_Impl( ::osl::ResettableMutexGuard& aGuard )
+{
+ if ( m_pImpl->m_pParent )
+ {
+ if ( m_pImpl->m_pParent->m_pAntiImpl )
+ {
+ uno::Reference< util::XModifiable > xParentModif( (util::XModifiable*)(m_pImpl->m_pParent->m_pAntiImpl) );
+ aGuard.clear();
+ xParentModif->setModified( sal_True );
+ }
+ else
+ m_pImpl->m_pParent->m_bIsModified = sal_True;
+ }
+}
+
+//-----------------------------------------------
+uno::Any SAL_CALL OWriteStream::queryInterface( const uno::Type& rType )
+ throw( uno::RuntimeException )
+{
+ uno::Any aReturn;
+
+ // common interfaces
+ aReturn <<= ::cppu::queryInterface
+ ( rType
+ , static_cast<lang::XTypeProvider*> ( this )
+ , static_cast<io::XInputStream*> ( this )
+ , static_cast<io::XOutputStream*> ( this )
+ , static_cast<io::XStream*> ( this )
+ , static_cast<embed::XExtendedStorageStream*> ( this )
+ , static_cast<io::XSeekable*> ( this )
+ , static_cast<io::XTruncate*> ( this )
+ , static_cast<lang::XComponent*> ( this )
+ , static_cast<beans::XPropertySet*> ( this ) );
+
+ if ( aReturn.hasValue() == sal_True )
+ return aReturn ;
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
+ {
+ aReturn <<= ::cppu::queryInterface
+ ( rType
+ , static_cast<embed::XEncryptionProtectedSource*> ( this ) );
+ }
+ else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ aReturn <<= ::cppu::queryInterface
+ ( rType
+ , static_cast<embed::XRelationshipAccess*> ( this ) );
+ }
+
+ if ( aReturn.hasValue() == sal_True )
+ return aReturn ;
+
+ if ( m_bTransacted )
+ {
+ aReturn <<= ::cppu::queryInterface
+ ( rType
+ , static_cast<embed::XTransactedObject*> ( this )
+ , static_cast<embed::XTransactionBroadcaster*> ( this ) );
+
+ if ( aReturn.hasValue() == sal_True )
+ return aReturn ;
+ }
+
+ return OWeakObject::queryInterface( rType );
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::acquire() throw()
+{
+ OWeakObject::acquire();
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::release() throw()
+{
+ OWeakObject::release();
+}
+
+//-----------------------------------------------
+uno::Sequence< uno::Type > SAL_CALL OWriteStream::getTypes()
+ throw( uno::RuntimeException )
+{
+ if ( m_pData->m_pTypeCollection == NULL )
+ {
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( m_pData->m_pTypeCollection == NULL )
+ {
+ if ( m_bTransacted )
+ {
+ if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
+ {
+ m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
+ ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XInputStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XOutputStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XSeekable >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XTruncate >* )NULL )
+ , ::getCppuType( ( const uno::Reference< lang::XComponent >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedSource >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XExtendedStorageStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
+ , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
+ }
+ else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
+ ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XInputStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XOutputStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XSeekable >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XTruncate >* )NULL )
+ , ::getCppuType( ( const uno::Reference< lang::XComponent >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XRelationshipAccess >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XExtendedStorageStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
+ , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
+ }
+ else // if ( m_pData->m_nStorageType == embed::StorageFormats::ZIP )
+ {
+ m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
+ ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XInputStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XOutputStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XSeekable >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XTruncate >* )NULL )
+ , ::getCppuType( ( const uno::Reference< lang::XComponent >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XExtendedStorageStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
+ , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
+ }
+ }
+ else
+ {
+ if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
+ {
+ m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
+ ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XInputStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XOutputStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XSeekable >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XTruncate >* )NULL )
+ , ::getCppuType( ( const uno::Reference< lang::XComponent >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedSource >* )NULL )
+ , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
+ }
+ else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
+ ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XInputStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XOutputStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XSeekable >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XTruncate >* )NULL )
+ , ::getCppuType( ( const uno::Reference< lang::XComponent >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XRelationshipAccess >* )NULL )
+ , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
+ }
+ else // if ( m_pData->m_nStorageType == embed::StorageFormats::ZIP )
+ {
+ m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
+ ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XInputStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XOutputStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XStream >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XSeekable >* )NULL )
+ , ::getCppuType( ( const uno::Reference< io::XTruncate >* )NULL )
+ , ::getCppuType( ( const uno::Reference< lang::XComponent >* )NULL )
+ , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
+ }
+ }
+ }
+ }
+
+ return m_pData->m_pTypeCollection->getTypes() ;
+}
+
+//-----------------------------------------------
+uno::Sequence< sal_Int8 > SAL_CALL OWriteStream::getImplementationId()
+ throw( uno::RuntimeException )
+{
+ static ::cppu::OImplementationId* pID = NULL ;
+
+ if ( pID == NULL )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ;
+
+ if ( pID == NULL )
+ {
+ static ::cppu::OImplementationId aID( sal_False ) ;
+ pID = &aID ;
+ }
+ }
+
+ return pID->getImplementationId() ;
+
+}
+
+//-----------------------------------------------
+sal_Int32 SAL_CALL OWriteStream::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ CheckInitOnDemand();
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xInStream.is() )
+ throw io::NotConnectedException();
+
+ return m_xInStream->readBytes( aData, nBytesToRead );
+}
+
+//-----------------------------------------------
+sal_Int32 SAL_CALL OWriteStream::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ CheckInitOnDemand();
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xInStream.is() )
+ throw io::NotConnectedException();
+
+ return m_xInStream->readSomeBytes( aData, nMaxBytesToRead );
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::skipBytes( sal_Int32 nBytesToSkip )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ CheckInitOnDemand();
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xInStream.is() )
+ throw io::NotConnectedException();
+
+ m_xInStream->skipBytes( nBytesToSkip );
+}
+
+//-----------------------------------------------
+sal_Int32 SAL_CALL OWriteStream::available( )
+ throw ( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ CheckInitOnDemand();
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xInStream.is() )
+ throw io::NotConnectedException();
+
+ return m_xInStream->available();
+
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::closeInput( )
+ throw ( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_bInitOnDemand && ( m_bInStreamDisconnected || !m_xInStream.is() ) )
+ throw io::NotConnectedException();
+
+ // the input part of the stream stays open for internal purposes ( to allow reading during copiing )
+ // since it can not be reopened until output part is closed, it will be closed with output part.
+ m_bInStreamDisconnected = sal_True;
+ // m_xInStream->closeInput();
+ // m_xInStream = uno::Reference< io::XInputStream >();
+
+ if ( !m_xOutStream.is() )
+ dispose();
+}
+
+//-----------------------------------------------
+uno::Reference< io::XInputStream > SAL_CALL OWriteStream::getInputStream()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_bInitOnDemand && ( m_bInStreamDisconnected || !m_xInStream.is() ) )
+ return uno::Reference< io::XInputStream >();
+
+ return uno::Reference< io::XInputStream >( static_cast< io::XInputStream* >( this ), uno::UNO_QUERY );
+}
+
+//-----------------------------------------------
+uno::Reference< io::XOutputStream > SAL_CALL OWriteStream::getOutputStream()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ CheckInitOnDemand();
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xOutStream.is() )
+ return uno::Reference< io::XOutputStream >();
+
+ return uno::Reference< io::XOutputStream >( static_cast< io::XOutputStream* >( this ), uno::UNO_QUERY );
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::writeBytes( const uno::Sequence< sal_Int8 >& aData )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ // the write method makes initialization itself, since it depends from the aData length
+ // NO CheckInitOnDemand()!
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_bInitOnDemand )
+ {
+ if ( !m_xOutStream.is() || !m_xSeekable.is())
+ throw io::NotConnectedException();
+
+ if ( m_pImpl->m_xCacheStream.is() )
+ {
+ // check whether the cache should be turned off
+ sal_Int64 nPos = m_xSeekable->getPosition();
+ if ( nPos + aData.getLength() > MAX_STORCACHE_SIZE )
+ {
+ // disconnect the cache and copy the data to the temporary file
+ m_xSeekable->seek( 0 );
+
+ // it is enough to copy the cached stream, the cache should already contain everything
+ if ( m_pImpl->GetFilledTempFileIfNo( m_xInStream ).getLength() )
+ {
+ DeInit();
+ // the last position is known and it is differs from the current stream position
+ m_nInitPosition = nPos;
+ }
+ }
+ }
+ }
+
+ if ( m_bInitOnDemand )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OWriteStream::CheckInitOnDemand, initializing" );
+ uno::Reference< io::XStream > xStream = m_pImpl->GetTempFileAsStream();
+ if ( xStream.is() )
+ {
+ m_xInStream.set( xStream->getInputStream(), uno::UNO_SET_THROW );
+ m_xOutStream.set( xStream->getOutputStream(), uno::UNO_SET_THROW );
+ m_xSeekable.set( xStream, uno::UNO_QUERY_THROW );
+ m_xSeekable->seek( m_nInitPosition );
+
+ m_nInitPosition = 0;
+ m_bInitOnDemand = sal_False;
+ }
+ }
+
+
+ if ( !m_xOutStream.is() )
+ throw io::NotConnectedException();
+
+ m_xOutStream->writeBytes( aData );
+ m_pImpl->m_bHasDataToFlush = sal_True;
+
+ ModifyParentUnlockMutex_Impl( aGuard );
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::flush()
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ // In case stream is flushed it's current version becomes visible
+ // to the parent storage. Usually parent storage flushes the stream
+ // during own commit but a user can explicitly flush the stream
+ // so the changes will be available through cloning functionality.
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_bInitOnDemand )
+ {
+ if ( !m_xOutStream.is() )
+ throw io::NotConnectedException();
+
+ m_xOutStream->flush();
+ m_pImpl->Commit();
+ }
+}
+
+//-----------------------------------------------
+void OWriteStream::CloseOutput_Impl()
+{
+ // all the checks must be done in calling method
+
+ m_xOutStream->closeOutput();
+ m_xOutStream = uno::Reference< io::XOutputStream >();
+
+ if ( !m_bInitOnDemand )
+ {
+ // after the stream is disposed it can be commited
+ // so transport correct size property
+ if ( !m_xSeekable.is() )
+ throw uno::RuntimeException();
+
+ for ( sal_Int32 nInd = 0; nInd < m_pImpl->m_aProps.getLength(); nInd++ )
+ {
+ if ( m_pImpl->m_aProps[nInd].Name.equalsAscii( "Size" ) )
+ m_pImpl->m_aProps[nInd].Value <<= ((sal_Int32)m_xSeekable->getLength());
+ }
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::closeOutput()
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ CheckInitOnDemand();
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xOutStream.is() )
+ throw io::NotConnectedException();
+
+ CloseOutput_Impl();
+
+ if ( m_bInStreamDisconnected || !m_xInStream.is() )
+ dispose();
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::seek( sal_Int64 location )
+ throw ( lang::IllegalArgumentException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ CheckInitOnDemand();
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xSeekable.is() )
+ throw uno::RuntimeException();
+
+ m_xSeekable->seek( location );
+}
+
+//-----------------------------------------------
+sal_Int64 SAL_CALL OWriteStream::getPosition()
+ throw ( io::IOException,
+ uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ CheckInitOnDemand();
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xSeekable.is() )
+ throw uno::RuntimeException();
+
+ return m_xSeekable->getPosition();
+}
+
+//-----------------------------------------------
+sal_Int64 SAL_CALL OWriteStream::getLength()
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ CheckInitOnDemand();
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xSeekable.is() )
+ throw uno::RuntimeException();
+
+ return m_xSeekable->getLength();
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::truncate()
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ CheckInitOnDemand();
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_xOutStream.is() )
+ throw uno::RuntimeException();
+
+ uno::Reference< io::XTruncate > xTruncate( m_xOutStream, uno::UNO_QUERY );
+
+ if ( !xTruncate.is() )
+ {
+ OSL_ENSURE( sal_False, "The output stream must support XTruncate interface!\n" );
+ throw uno::RuntimeException();
+ }
+
+ xTruncate->truncate();
+
+ m_pImpl->m_bHasDataToFlush = sal_True;
+
+ ModifyParentUnlockMutex_Impl( aGuard );
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::dispose()
+ throw ( uno::RuntimeException )
+{
+ // should be an internal method since it can be called only from parent storage
+ {
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_xOutStream.is() )
+ CloseOutput_Impl();
+
+ if ( m_xInStream.is() )
+ {
+ m_xInStream->closeInput();
+ m_xInStream = uno::Reference< io::XInputStream >();
+ }
+
+ m_xSeekable = uno::Reference< io::XSeekable >();
+
+ m_pImpl->m_pAntiImpl = NULL;
+
+ if ( !m_bInitOnDemand )
+ {
+ try
+ {
+ if ( !m_bTransacted )
+ {
+ m_pImpl->Commit();
+ }
+ else
+ {
+ // throw away all the changes
+ m_pImpl->Revert();
+ }
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii( "Can not commit/revert the storage!\n" ),
+ uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
+ uno::UNO_QUERY ),
+ aCaught );
+ }
+ }
+
+ m_pImpl = NULL;
+ }
+
+ // the listener might try to get rid of parent storage, and the storage would delete this object;
+ // for now the listener is just notified at the end of the method to workaround the problem
+ // in future a more elegant way should be found
+
+ lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
+ m_pData->m_aListenersContainer.disposeAndClear( aSource );
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::addEventListener(
+ const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ m_pData->m_aListenersContainer.addInterface( ::getCppuType((const uno::Reference< lang::XEventListener >*)0),
+ xListener );
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::removeEventListener(
+ const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ m_pData->m_aListenersContainer.removeInterface( ::getCppuType((const uno::Reference< lang::XEventListener >*)0),
+ xListener );
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::setEncryptionPassword( const ::rtl::OUString& aPass )
+ throw ( uno::RuntimeException,
+ io::IOException )
+{
+ ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ CheckInitOnDemand();
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ OSL_ENSURE( m_pImpl->m_xPackageStream.is(), "No package stream is set!\n" );
+
+ m_pImpl->SetEncryptedWithPass( aPass );
+
+ ModifyParentUnlockMutex_Impl( aGuard );
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::removeEncryption()
+ throw ( uno::RuntimeException,
+ io::IOException )
+{
+ ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ CheckInitOnDemand();
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ OSL_ENSURE( m_pImpl->m_xPackageStream.is(), "No package stream is set!\n" );
+
+ m_pImpl->SetDecrypted();
+
+ ModifyParentUnlockMutex_Impl( aGuard );
+}
+
+//-----------------------------------------------
+sal_Bool SAL_CALL OWriteStream::hasByID( const ::rtl::OUString& sID )
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ try
+ {
+ getRelationshipByID( sID );
+ return sal_True;
+ }
+ catch( container::NoSuchElementException& aNoSuchElementException )
+ {
+ m_pImpl->AddLog( aNoSuchElementException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No Element" ) ) );
+ }
+
+ return sal_False;
+}
+
+//-----------------------------------------------
+::rtl::OUString SAL_CALL OWriteStream::getTargetByID( const ::rtl::OUString& sID )
+ throw ( container::NoSuchElementException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
+ for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
+ if ( aSeq[nInd].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Target" ) ) )
+ return aSeq[nInd].Second;
+
+ return ::rtl::OUString();
+}
+
+//-----------------------------------------------
+::rtl::OUString SAL_CALL OWriteStream::getTypeByID( const ::rtl::OUString& sID )
+ throw ( container::NoSuchElementException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
+ for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
+ if ( aSeq[nInd].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
+ return aSeq[nInd].Second;
+
+ return ::rtl::OUString();
+}
+
+//-----------------------------------------------
+uno::Sequence< beans::StringPair > SAL_CALL OWriteStream::getRelationshipByID( const ::rtl::OUString& sID )
+ throw ( container::NoSuchElementException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ // TODO/LATER: in future the unification of the ID could be checked
+ uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
+ for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
+ for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
+ if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Id" ) ) )
+ {
+ if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
+ return aSeq[nInd1];
+ break;
+ }
+
+ throw container::NoSuchElementException();
+}
+
+//-----------------------------------------------
+uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OWriteStream::getRelationshipsByType( const ::rtl::OUString& sType )
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ uno::Sequence< uno::Sequence< beans::StringPair > > aResult;
+ sal_Int32 nEntriesNum = 0;
+
+ // TODO/LATER: in future the unification of the ID could be checked
+ uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
+ for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
+ for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
+ if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
+ {
+ if ( aSeq[nInd1][nInd2].Second.equals( sType ) )
+ {
+ aResult.realloc( nEntriesNum );
+ aResult[nEntriesNum-1] = aSeq[nInd1];
+ }
+ break;
+ }
+
+ return aResult;
+}
+
+//-----------------------------------------------
+uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OWriteStream::getAllRelationships()
+ throw (io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ return m_pImpl->GetAllRelationshipsIfAny();
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::insertRelationshipByID( const ::rtl::OUString& sID, const uno::Sequence< beans::StringPair >& aEntry, ::sal_Bool bReplace )
+ throw ( container::ElementExistException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ ::rtl::OUString aIDTag( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
+
+ sal_Int32 nIDInd = -1;
+
+ // TODO/LATER: in future the unification of the ID could be checked
+ uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
+ for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
+ for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
+ if ( aSeq[nInd1][nInd2].First.equals( aIDTag ) )
+ {
+ if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
+ nIDInd = nInd1;
+
+ break;
+ }
+
+ if ( nIDInd == -1 || bReplace )
+ {
+ if ( nIDInd == -1 )
+ {
+ nIDInd = aSeq.getLength();
+ aSeq.realloc( nIDInd + 1 );
+ }
+
+ aSeq[nIDInd].realloc( aEntry.getLength() + 1 );
+
+ aSeq[nIDInd][0].First = aIDTag;
+ aSeq[nIDInd][0].Second = sID;
+ sal_Int32 nIndTarget = 1;
+ for ( sal_Int32 nIndOrig = 0;
+ nIndOrig < aEntry.getLength();
+ nIndOrig++ )
+ {
+ if ( !aEntry[nIndOrig].First.equals( aIDTag ) )
+ aSeq[nIDInd][nIndTarget++] = aEntry[nIndOrig];
+ }
+
+ aSeq[nIDInd].realloc( nIndTarget );
+ }
+ else
+ throw container::ElementExistException(); // TODO
+
+
+ m_pImpl->m_aNewRelInfo = aSeq;
+ m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
+ m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::removeRelationshipByID( const ::rtl::OUString& sID )
+ throw ( container::NoSuchElementException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
+ for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
+ for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
+ if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Id" ) ) )
+ {
+ if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
+ {
+ sal_Int32 nLength = aSeq.getLength();
+ aSeq[nInd1] = aSeq[nLength-1];
+ aSeq.realloc( nLength - 1 );
+
+ m_pImpl->m_aNewRelInfo = aSeq;
+ m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
+ m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
+
+ // TODO/LATER: in future the unification of the ID could be checked
+ return;
+ }
+
+ break;
+ }
+
+ throw container::NoSuchElementException();
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::insertRelationships( const uno::Sequence< uno::Sequence< beans::StringPair > >& aEntries, ::sal_Bool bReplace )
+ throw ( container::ElementExistException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ ::rtl::OUString aIDTag( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
+ uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
+ uno::Sequence< uno::Sequence< beans::StringPair > > aResultSeq( aSeq.getLength() + aEntries.getLength() );
+ sal_Int32 nResultInd = 0;
+
+ for ( sal_Int32 nIndTarget1 = 0; nIndTarget1 < aSeq.getLength(); nIndTarget1++ )
+ for ( sal_Int32 nIndTarget2 = 0; nIndTarget2 < aSeq[nIndTarget1].getLength(); nIndTarget2++ )
+ if ( aSeq[nIndTarget1][nIndTarget2].First.equals( aIDTag ) )
+ {
+ sal_Int32 nIndSourceSame = -1;
+
+ for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
+ for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
+ {
+ if ( aEntries[nIndSource1][nIndSource2].First.equals( aIDTag ) )
+ {
+ if ( aEntries[nIndSource1][nIndSource2].Second.equals( aSeq[nIndTarget1][nIndTarget2].Second ) )
+ {
+ if ( !bReplace )
+ throw container::ElementExistException();
+
+ nIndSourceSame = nIndSource1;
+ }
+
+ break;
+ }
+ }
+
+ if ( nIndSourceSame == -1 )
+ {
+ // no such element in the provided sequence
+ aResultSeq[nResultInd++] = aSeq[nIndTarget1];
+ }
+
+ break;
+ }
+
+ for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
+ {
+ aResultSeq[nResultInd].realloc( aEntries[nIndSource1].getLength() );
+ sal_Bool bHasID = sal_False;
+ sal_Int32 nResInd2 = 1;
+
+ for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
+ if ( aEntries[nIndSource1][nIndSource2].First.equals( aIDTag ) )
+ {
+ aResultSeq[nResultInd][0] = aEntries[nIndSource1][nIndSource2];
+ bHasID = sal_True;
+ }
+ else if ( nResInd2 < aResultSeq[nResultInd].getLength() )
+ aResultSeq[nResultInd][nResInd2++] = aEntries[nIndSource1][nIndSource2];
+ else
+ throw io::IOException(); // TODO: illegal relation ( no ID )
+
+ if ( !bHasID )
+ throw io::IOException(); // TODO: illegal relations
+
+ nResultInd++;
+ }
+
+ aResultSeq.realloc( nResultInd );
+ m_pImpl->m_aNewRelInfo = aResultSeq;
+ m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
+ m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::clearRelationships()
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException();
+
+ m_pImpl->m_aNewRelInfo.realloc( 0 );
+ m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
+ m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
+}
+
+//-----------------------------------------------
+uno::Reference< beans::XPropertySetInfo > SAL_CALL OWriteStream::getPropertySetInfo()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ //TODO:
+ return uno::Reference< beans::XPropertySetInfo >();
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw ( beans::UnknownPropertyException,
+ beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ m_pImpl->GetStreamProperties();
+ ::rtl::OUString aCompressedString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) );
+ ::rtl::OUString aMediaTypeString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
+ if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE && aPropertyName.equals( aMediaTypeString ) )
+ {
+ // if the "Compressed" property is not set explicitly, the MediaType can change the default value
+ sal_Bool bCompressedValueFromType = sal_True;
+ ::rtl::OUString aType;
+ aValue >>= aType;
+
+ if ( !m_pImpl->m_bCompressedSetExplicit )
+ {
+ if ( aType.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/jpeg" ) ) )
+ || aType.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/png" ) ) )
+ || aType.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/gif" ) ) ) )
+ bCompressedValueFromType = sal_False;
+ }
+
+ for ( sal_Int32 nInd = 0; nInd < m_pImpl->m_aProps.getLength(); nInd++ )
+ {
+ if ( aPropertyName.equals( m_pImpl->m_aProps[nInd].Name ) )
+ m_pImpl->m_aProps[nInd].Value = aValue;
+ else if ( !m_pImpl->m_bCompressedSetExplicit && aCompressedString.equals( m_pImpl->m_aProps[nInd].Name ) )
+ m_pImpl->m_aProps[nInd].Value <<= bCompressedValueFromType;
+ }
+ }
+ else if ( aPropertyName.equals( aCompressedString ) )
+ {
+ // if the "Compressed" property is not set explicitly, the MediaType can change the default value
+ m_pImpl->m_bCompressedSetExplicit = sal_True;
+ for ( sal_Int32 nInd = 0; nInd < m_pImpl->m_aProps.getLength(); nInd++ )
+ {
+ if ( aPropertyName.equals( m_pImpl->m_aProps[nInd].Name ) )
+ m_pImpl->m_aProps[nInd].Value = aValue;
+ }
+ }
+ else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
+ && aPropertyName.equalsAscii( "UseCommonStoragePasswordEncryption" ) )
+ {
+ sal_Bool bUseCommonPass = sal_False;
+ if ( aValue >>= bUseCommonPass )
+ {
+ if ( m_bInitOnDemand && m_pImpl->m_bHasInsertedStreamOptimization )
+ {
+ // the data stream is provided to the packagestream directly
+ m_pImpl->m_bUseCommonPass = bUseCommonPass;
+ }
+ else if ( bUseCommonPass )
+ {
+ if ( !m_pImpl->m_bUseCommonPass )
+ {
+ m_pImpl->SetDecrypted();
+ m_pImpl->m_bUseCommonPass = sal_True;
+ }
+ }
+ else
+ m_pImpl->m_bUseCommonPass = sal_False;
+ }
+ else
+ throw lang::IllegalArgumentException(); //TODO
+ }
+ else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aPropertyName.equals( aMediaTypeString ) )
+ {
+ for ( sal_Int32 nInd = 0; nInd < m_pImpl->m_aProps.getLength(); nInd++ )
+ {
+ if ( aPropertyName.equals( m_pImpl->m_aProps[nInd].Name ) )
+ m_pImpl->m_aProps[nInd].Value = aValue;
+ }
+ }
+ else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aPropertyName.equalsAscii( "RelationsInfoStream" ) )
+ {
+ uno::Reference< io::XInputStream > xInRelStream;
+ if ( ( aValue >>= xInRelStream ) && xInRelStream.is() )
+ {
+ uno::Reference< io::XSeekable > xSeek( xInRelStream, uno::UNO_QUERY );
+ if ( !xSeek.is() )
+ {
+ // currently this is an internal property that is used for optimization
+ // and the stream must support XSeekable interface
+ // TODO/LATER: in future it can be changed if property is used from outside
+ throw lang::IllegalArgumentException(); // TODO
+ }
+
+ m_pImpl->m_xNewRelInfoStream = xInRelStream;
+ m_pImpl->m_aNewRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
+ m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED_STREAM;
+ }
+ else
+ throw lang::IllegalArgumentException(); // TODO
+ }
+ else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aPropertyName.equalsAscii( "RelationsInfo" ) )
+ {
+ if ( aValue >>= m_pImpl->m_aNewRelInfo )
+ {
+ }
+ else
+ throw lang::IllegalArgumentException(); // TODO
+ }
+ else if ( aPropertyName.equalsAscii( "Size" ) )
+ throw beans::PropertyVetoException(); // TODO
+ else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
+ && ( aPropertyName.equalsAscii( "IsEncrypted" ) || aPropertyName.equalsAscii( "Encrypted" ) ) )
+ throw beans::PropertyVetoException(); // TODO
+ else
+ throw beans::UnknownPropertyException(); // TODO
+
+ m_pImpl->m_bHasDataToFlush = sal_True;
+ ModifyParentUnlockMutex_Impl( aGuard );
+}
+
+
+//-----------------------------------------------
+uno::Any SAL_CALL OWriteStream::getPropertyValue( const ::rtl::OUString& aProp )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( aProp.equalsAscii( "RelId" ) )
+ {
+ return uno::makeAny( m_pImpl->GetNewRelId() );
+ }
+
+ ::rtl::OUString aPropertyName;
+ if ( aProp.equalsAscii( "IsEncrypted" ) )
+ aPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Encrypted" ) );
+ else
+ aPropertyName = aProp;
+
+ if ( ( ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE || m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
+ && aPropertyName.equalsAscii( "MediaType" ) )
+ || ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE && aPropertyName.equalsAscii( "Encrypted" ) )
+ || aPropertyName.equalsAscii( "Compressed" ) )
+ {
+ m_pImpl->GetStreamProperties();
+
+ for ( sal_Int32 nInd = 0; nInd < m_pImpl->m_aProps.getLength(); nInd++ )
+ {
+ if ( aPropertyName.equals( m_pImpl->m_aProps[nInd].Name ) )
+ return m_pImpl->m_aProps[nInd].Value;
+ }
+ }
+ else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
+ && aPropertyName.equalsAscii( "UseCommonStoragePasswordEncryption" ) )
+ return uno::makeAny( m_pImpl->m_bUseCommonPass );
+ else if ( aPropertyName.equalsAscii( "Size" ) )
+ {
+ CheckInitOnDemand();
+
+ if ( !m_xSeekable.is() )
+ throw uno::RuntimeException();
+
+ return uno::makeAny( (sal_Int32)m_xSeekable->getLength() );
+ }
+
+ throw beans::UnknownPropertyException(); // TODO
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::addPropertyChangeListener(
+ const ::rtl::OUString& /*aPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ //TODO:
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::removePropertyChangeListener(
+ const ::rtl::OUString& /*aPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ //TODO:
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::addVetoableChangeListener(
+ const ::rtl::OUString& /*PropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ //TODO:
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::removeVetoableChangeListener(
+ const ::rtl::OUString& /*PropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ //TODO:
+}
+
+//____________________________________________________________________________________________________
+// XTransactedObject
+//____________________________________________________________________________________________________
+
+//-----------------------------------------------
+void OWriteStream::BroadcastTransaction( sal_Int8 nMessage )
+/*
+ 1 - preCommit
+ 2 - commited
+ 3 - preRevert
+ 4 - reverted
+*/
+{
+ // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
+
+ ::cppu::OInterfaceContainerHelper* pContainer =
+ m_pData->m_aListenersContainer.getContainer(
+ ::getCppuType( ( const uno::Reference< embed::XTransactionListener >*) NULL ) );
+ if ( pContainer )
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
+ while ( pIterator.hasMoreElements( ) )
+ {
+ OSL_ENSURE( nMessage >= 1 && nMessage <= 4, "Wrong internal notification code is used!\n" );
+
+ switch( nMessage )
+ {
+ case STOR_MESS_PRECOMMIT:
+ ( ( embed::XTransactionListener* )pIterator.next( ) )->preCommit( aSource );
+ break;
+ case STOR_MESS_COMMITED:
+ ( ( embed::XTransactionListener* )pIterator.next( ) )->commited( aSource );
+ break;
+ case STOR_MESS_PREREVERT:
+ ( ( embed::XTransactionListener* )pIterator.next( ) )->preRevert( aSource );
+ break;
+ case STOR_MESS_REVERTED:
+ ( ( embed::XTransactionListener* )pIterator.next( ) )->reverted( aSource );
+ break;
+ }
+ }
+ }
+}
+//-----------------------------------------------
+void SAL_CALL OWriteStream::commit()
+ throw ( io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OWriteStream::commit" );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_bTransacted )
+ throw uno::RuntimeException();
+
+ try {
+ BroadcastTransaction( STOR_MESS_PRECOMMIT );
+
+ ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ m_pImpl->Commit();
+
+ // when the storage is commited the parent is modified
+ ModifyParentUnlockMutex_Impl( aGuard );
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Problems on commit!" ),
+ uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ),
+ aCaught );
+ }
+
+ BroadcastTransaction( STOR_MESS_COMMITED );
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::revert()
+ throw ( io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OWriteStream::revert" );
+
+ // the method removes all the changes done after last commit
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_bTransacted )
+ throw uno::RuntimeException();
+
+ BroadcastTransaction( STOR_MESS_PREREVERT );
+
+ ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ try {
+ m_pImpl->Revert();
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Problems on revert!" ),
+ uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ),
+ aCaught );
+ }
+
+ aGuard.clear();
+
+ BroadcastTransaction( STOR_MESS_REVERTED );
+}
+
+//____________________________________________________________________________________________________
+// XTransactionBroadcaster
+//____________________________________________________________________________________________________
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::addTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_bTransacted )
+ throw uno::RuntimeException();
+
+ m_pData->m_aListenersContainer.addInterface( ::getCppuType((const uno::Reference< embed::XTransactionListener >*)0),
+ aListener );
+}
+
+//-----------------------------------------------
+void SAL_CALL OWriteStream::removeTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException();
+ }
+
+ if ( !m_bTransacted )
+ throw uno::RuntimeException();
+
+ m_pData->m_aListenersContainer.removeInterface( ::getCppuType((const uno::Reference< embed::XTransactionListener >*)0),
+ aListener );
+}
+
+
diff --git a/package/source/xstor/owriteablestream.hxx b/package/source/xstor/owriteablestream.hxx
new file mode 100644
index 000000000000..0d4a29893887
--- /dev/null
+++ b/package/source/xstor/owriteablestream.hxx
@@ -0,0 +1,411 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _WRITESTREAM_HXX_
+#define _WRITESTREAM_HXX_
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/packages/XDataSinkEncrSupport.hpp>
+#include <com/sun/star/packages/NoEncryptionException.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/embed/XEncryptionProtectedSource.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/XRelationshipAccess.hpp>
+#include <com/sun/star/embed/XExtendedStorageStream.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/embed/XTransactionBroadcaster.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/beans/StringPair.hpp>
+#include <com/sun/star/logging/XSimpleLogRing.hpp>
+
+
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/interfacecontainer.h>
+
+#include <list>
+
+#include "ocompinstream.hxx"
+#include "mutexholder.hxx"
+
+
+struct PreCreationStruct
+{
+ SotMutexHolderRef m_rMutexRef;
+
+ PreCreationStruct()
+ : m_rMutexRef( new SotMutexHolder )
+ {}
+
+};
+
+namespace cppu {
+ class OTypeCollection;
+}
+
+namespace package {
+ void StaticAddLog( const ::rtl::OUString& aMessage );
+ ::com::sun::star::uno::Sequence< sal_Int8 > MakeKeyFromPass( const ::rtl::OUString& aPass, sal_Bool bUseUTF );
+}
+
+struct WSInternalData_Impl
+{
+ SotMutexHolderRef m_rSharedMutexRef;
+ ::cppu::OTypeCollection* m_pTypeCollection;
+ ::cppu::OMultiTypeInterfaceContainerHelper m_aListenersContainer; // list of listeners
+ sal_Int32 m_nStorageType;
+
+ // the mutex reference MUST NOT be empty
+ WSInternalData_Impl( const SotMutexHolderRef rMutexRef, sal_Int32 nStorageType )
+ : m_rSharedMutexRef( rMutexRef )
+ , m_pTypeCollection( NULL )
+ , m_aListenersContainer( rMutexRef->GetMutex() )
+ , m_nStorageType( nStorageType )
+ {}
+};
+
+typedef ::std::list< OInputCompStream* > InputStreamsList_Impl;
+
+struct OStorage_Impl;
+class OWriteStream;
+
+struct OWriteStream_Impl : public PreCreationStruct
+{
+ friend struct OStorage_Impl;
+ friend class OWriteStream;
+ friend class OInputCompStream;
+
+ OWriteStream* m_pAntiImpl;
+ ::rtl::OUString m_aTempURL;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > m_xCacheStream;
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XSeekable > m_xCacheSeek;
+
+ InputStreamsList_Impl m_aInputStreamsList;
+
+ sal_Bool m_bHasDataToFlush; // only modified elements will be sent to the original content
+ sal_Bool m_bFlushed; // sending the streams is coordinated by the root storage of the package
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::packages::XDataSinkEncrSupport > m_xPackageStream;
+ ::com::sun::star::uno::Reference< ::com::sun::star::logging::XSimpleLogRing > m_xLogRing;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;
+
+ OStorage_Impl* m_pParent;
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > m_aProps;
+
+ sal_Bool m_bForceEncrypted;
+
+ sal_Bool m_bUseCommonPass;
+ sal_Bool m_bHasCachedPassword;
+ ::rtl::OUString m_aPass;
+
+ sal_Bool m_bCompressedSetExplicit;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > m_xPackage;
+
+ sal_Bool m_bHasInsertedStreamOptimization;
+
+ sal_Int32 m_nStorageType;
+
+ // Relations info related data, stored in *.rels file in OFOPXML format
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > m_xOrigRelInfoStream;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > m_aOrigRelInfo;
+ sal_Bool m_bOrigRelInfoBroken;
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > m_aNewRelInfo;
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > m_xNewRelInfoStream;
+ sal_Int16 m_nRelInfoStatus;
+ sal_Int32 m_nRelId;
+
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > GetServiceFactory();
+
+ ::rtl::OUString GetFilledTempFileIfNo( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xStream );
+ ::rtl::OUString FillTempGetFileName();
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > GetTempFileAsStream();
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetTempFileAsInputStream();
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > GetStream_Impl( sal_Int32 nStreamMode,
+ sal_Bool bHierarchyAccess );
+
+ ::rtl::OUString GetCommonRootPass() throw ( ::com::sun::star::packages::NoEncryptionException );
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > ReadPackageStreamProperties();
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > InsertOwnProps(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps,
+ sal_Bool bUseCommonPass );
+
+public:
+ OWriteStream_Impl(
+ OStorage_Impl* pParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::packages::XDataSinkEncrSupport >& xPackageStream,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory >& xPackage,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
+ sal_Bool bForceEncrypted,
+ sal_Int32 nStorageType,
+ sal_Bool bDefaultCompress,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xRelInfoStream =
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >() );
+
+ ~OWriteStream_Impl();
+
+ void CleanCacheStream();
+
+ void AddLog( const ::rtl::OUString& aMessage );
+
+ sal_Bool UsesCommonPass_Impl() { return m_bUseCommonPass; }
+ sal_Bool HasTempFile_Impl() { return ( m_aTempURL.getLength() != 0 ); }
+ sal_Bool IsTransacted();
+
+ sal_Bool HasWriteOwner_Impl() { return ( m_pAntiImpl != NULL ); }
+
+ void InsertIntoPackageFolder(
+ const ::rtl::OUString& aName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& xParentPackageFolder );
+
+ void SetToBeCommited() { m_bFlushed = sal_True; }
+
+ sal_Bool HasCachedPassword() { return m_bHasCachedPassword; }
+ ::rtl::OUString GetCachedPassword() { return m_aPass; }
+ sal_Bool IsModified() { return m_bHasDataToFlush || m_bFlushed; }
+
+ sal_Bool IsEncrypted();
+ void SetDecrypted();
+ void SetEncryptedWithPass( const ::rtl::OUString& aPass );
+
+ void DisposeWrappers();
+
+ void InsertStreamDirectly(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInStream,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps );
+
+ void Commit();
+ void Revert();
+
+ void Free( sal_Bool bMust ); // allows to try to disconnect from the temporary stream
+ // in case bMust is set to sal_True the method
+ // will throw exception in case the file is still busy
+
+ void SetModified(); // can be done only by parent storage after renaming
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > GetStreamProperties();
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > GetAllRelationshipsIfAny();
+
+ void CopyInternallyTo_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xDestStream,
+ const ::rtl::OUString& aPass );
+ void CopyInternallyTo_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xDestStream );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > GetStream(
+ sal_Int32 nStreamMode,
+ const ::rtl::OUString& aPass,
+ sal_Bool bHierarchyAccess );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > GetStream(
+ sal_Int32 nStreamMode,
+ sal_Bool bHierarchyAccess );
+
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetRawInStream();
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetPlainRawInStream();
+
+ void InputStreamDisposed( OInputCompStream* pStream );
+
+ void CreateReadonlyCopyBasedOnData(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xDataToCopy,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps,
+ sal_Bool bUseCommonPass,
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xTargetStream );
+
+ void GetCopyOfLastCommit( ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xTargetStream );
+ void GetCopyOfLastCommit(
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xTargetStream,
+ const ::rtl::OUString& aPass );
+
+
+ void CommitStreamRelInfo(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xRelStorage,
+ const ::rtl::OUString& aOrigStreamName,
+ const ::rtl::OUString& aNewStreamName );
+
+ void ReadRelInfoIfNecessary();
+
+ sal_Int32 GetNewRelId() { return m_nRelId ++; }
+};
+
+class OWriteStream : ::com::sun::star::lang::XTypeProvider
+ , public ::com::sun::star::io::XInputStream
+ , public ::com::sun::star::io::XOutputStream
+ , public ::com::sun::star::embed::XExtendedStorageStream
+ , public ::com::sun::star::io::XSeekable
+ , public ::com::sun::star::io::XTruncate
+ , public ::com::sun::star::embed::XEncryptionProtectedSource
+ , public ::com::sun::star::embed::XRelationshipAccess
+ , public ::com::sun::star::embed::XTransactedObject
+ , public ::com::sun::star::embed::XTransactionBroadcaster
+ , public ::com::sun::star::beans::XPropertySet
+ , public ::cppu::OWeakObject
+{
+ friend struct OWriteStream_Impl;
+
+protected:
+ ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > m_xInStream;
+ ::com::sun::star::uno::Reference < ::com::sun::star::io::XOutputStream > m_xOutStream;
+ ::com::sun::star::uno::Reference < ::com::sun::star::io::XSeekable > m_xSeekable;
+
+ OWriteStream_Impl* m_pImpl;
+ WSInternalData_Impl* m_pData;
+
+ sal_Bool m_bInStreamDisconnected;
+ sal_Bool m_bInitOnDemand;
+ sal_Int64 m_nInitPosition;
+
+ sal_Bool m_bTransacted;
+
+ OWriteStream( OWriteStream_Impl* pImpl, sal_Bool bTransacted );
+ OWriteStream( OWriteStream_Impl* pImpl, ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > xStream, sal_Bool bTransacted );
+
+ void CloseOutput_Impl();
+
+ void CopyToStreamInternally_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xStream );
+
+ void ModifyParentUnlockMutex_Impl( ::osl::ResettableMutexGuard& aGuard );
+
+ void BroadcastTransaction( sal_Int8 nMessage );
+
+public:
+
+ virtual ~OWriteStream();
+
+ void CheckInitOnDemand();
+ void DeInit();
+
+ // XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType )
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes()
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL available( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeInput( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // XOutputStream
+ virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< sal_Int8 >& aData ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL flush( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeOutput( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ //XSeekable
+ virtual void SAL_CALL seek( sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getPosition() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getLength() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ //XStream
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XTruncate
+ virtual void SAL_CALL truncate() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ //XComponent
+ virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ //XEncryptionProtectedSource
+ virtual void SAL_CALL setEncryptionPassword( const ::rtl::OUString& aPass )
+ throw ( ::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::io::IOException );
+ virtual void SAL_CALL removeEncryption()
+ throw ( ::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::io::IOException );
+
+ //XRelationshipAccess
+ virtual ::sal_Bool SAL_CALL hasByID( const ::rtl::OUString& sID ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getTargetByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getTypeByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > SAL_CALL getRelationshipByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > SAL_CALL getRelationshipsByType( const ::rtl::OUString& sType ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > SAL_CALL getAllRelationships( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL insertRelationshipByID( const ::rtl::OUString& sID, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair >& aEntry, ::sal_Bool bReplace ) throw (::com::sun::star::container::ElementExistException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeRelationshipByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL insertRelationships( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > >& aEntries, ::sal_Bool bReplace ) throw (::com::sun::star::container::ElementExistException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL clearRelationships( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ //XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() throw ( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
+
+ // XTransactedObject
+ virtual void SAL_CALL commit()
+ throw ( ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL revert()
+ throw ( ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ // XTransactionBroadcaster
+ virtual void SAL_CALL addTransactionListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XTransactionListener >& aListener )
+ throw ( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL removeTransactionListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XTransactionListener >& aListener )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+};
+
+#endif
+
diff --git a/package/source/xstor/register.cxx b/package/source/xstor/register.cxx
new file mode 100644
index 000000000000..1e3ae15fe383
--- /dev/null
+++ b/package/source/xstor/register.cxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+
+
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/registry/InvalidRegistryException.hpp>
+#include <cppuhelper/factory.hxx>
+
+#include "xfactory.hxx"
+
+using namespace ::com::sun::star;
+
+
+extern "C" {
+
+void SAL_CALL component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+void * SAL_CALL component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
+{
+ void * pRet = 0;
+
+ ::rtl::OUString aImplName( ::rtl::OUString::createFromAscii( pImplName ) );
+ uno::Reference< lang::XSingleServiceFactory > xFactory;
+
+ if ( pServiceManager && aImplName.equals( OStorageFactory::impl_staticGetImplementationName() ) )
+ {
+ xFactory= ::cppu::createOneInstanceFactory( reinterpret_cast< lang::XMultiServiceFactory*>( pServiceManager ),
+ OStorageFactory::impl_staticGetImplementationName(),
+ OStorageFactory::impl_staticCreateSelfInstance,
+ OStorageFactory::impl_staticGetSupportedServiceNames() );
+ }
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
+sal_Bool SAL_CALL component_writeInfo( void * /*pServiceManager*/, void * pRegistryKey )
+{
+ if (pRegistryKey)
+ {
+ try
+ {
+ uno::Reference< registry::XRegistryKey > xKey( reinterpret_cast< registry::XRegistryKey* >( pRegistryKey ) );
+
+ uno::Reference< registry::XRegistryKey > xNewKey;
+
+ xNewKey = xKey->createKey( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) +
+ OStorageFactory::impl_staticGetImplementationName() +
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") ) );
+
+ const uno::Sequence< ::rtl::OUString > aServices = OStorageFactory::impl_staticGetSupportedServiceNames();
+ for( sal_Int32 ind = 0; ind < aServices.getLength(); ind++ )
+ xNewKey->createKey( aServices.getConstArray()[ind] );
+
+ return sal_True;
+ }
+ catch (registry::InvalidRegistryException &)
+ {
+ OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
+ }
+ }
+ return sal_False;
+}
+
+} // extern "C"
+
diff --git a/package/source/xstor/selfterminatefilestream.cxx b/package/source/xstor/selfterminatefilestream.cxx
new file mode 100644
index 000000000000..61df5e486250
--- /dev/null
+++ b/package/source/xstor/selfterminatefilestream.cxx
@@ -0,0 +1,153 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+
+#include "selfterminatefilestream.hxx"
+#include <comphelper/processfactory.hxx>
+
+using namespace ::com::sun::star;
+
+//-----------------------------------------------
+OSelfTerminateFileStream::OSelfTerminateFileStream( const uno::Reference< lang::XMultiServiceFactory > xFactory, const ::rtl::OUString& aURL )
+: m_aURL( aURL )
+{
+ uno::Reference< lang::XMultiServiceFactory > xOwnFactory = xFactory;
+ if ( !xOwnFactory.is() )
+ xOwnFactory.set( ::comphelper::getProcessServiceFactory(), uno::UNO_SET_THROW );
+
+ // IMPORTANT: The implementation is based on idea that m_xFileAccess, m_xInputStream and m_xSeekable are always set
+ // otherwise an exception is thrown in constructor
+
+ m_xFileAccess.set( xOwnFactory->createInstance (
+ ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
+ uno::UNO_QUERY_THROW );
+
+ m_xInputStream.set( m_xFileAccess->openFileRead( aURL ), uno::UNO_SET_THROW );
+ m_xSeekable.set( m_xInputStream, uno::UNO_QUERY_THROW );
+}
+
+//-----------------------------------------------
+OSelfTerminateFileStream::~OSelfTerminateFileStream()
+{
+ CloseStreamDeleteFile();
+}
+
+//-----------------------------------------------
+void OSelfTerminateFileStream::CloseStreamDeleteFile()
+{
+ try
+ {
+ m_xInputStream->closeInput();
+ }
+ catch( uno::Exception& )
+ {}
+
+ try
+ {
+ m_xFileAccess->kill( m_aURL );
+ }
+ catch( uno::Exception& )
+ {}
+}
+
+//-----------------------------------------------
+sal_Int32 SAL_CALL OSelfTerminateFileStream::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ return m_xInputStream->readBytes( aData, nBytesToRead );
+}
+
+//-----------------------------------------------
+sal_Int32 SAL_CALL OSelfTerminateFileStream::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ return m_xInputStream->readSomeBytes( aData, nMaxBytesToRead );
+}
+
+//-----------------------------------------------
+void SAL_CALL OSelfTerminateFileStream::skipBytes( sal_Int32 nBytesToSkip )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ return m_xInputStream->skipBytes( nBytesToSkip );
+}
+
+//-----------------------------------------------
+sal_Int32 SAL_CALL OSelfTerminateFileStream::available( )
+ throw ( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ return m_xInputStream->available();
+}
+
+//-----------------------------------------------
+void SAL_CALL OSelfTerminateFileStream::closeInput( )
+ throw ( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ CloseStreamDeleteFile();
+}
+
+//-----------------------------------------------
+void SAL_CALL OSelfTerminateFileStream::seek( sal_Int64 location )
+ throw ( lang::IllegalArgumentException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ m_xSeekable->seek( location );
+}
+
+//-----------------------------------------------
+sal_Int64 SAL_CALL OSelfTerminateFileStream::getPosition()
+ throw ( io::IOException,
+ uno::RuntimeException)
+{
+ return m_xSeekable->getPosition();
+}
+
+//-----------------------------------------------
+sal_Int64 SAL_CALL OSelfTerminateFileStream::getLength()
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ return m_xSeekable->getLength();
+}
+
diff --git a/package/source/xstor/selfterminatefilestream.hxx b/package/source/xstor/selfterminatefilestream.hxx
new file mode 100644
index 000000000000..e0dde5d837e8
--- /dev/null
+++ b/package/source/xstor/selfterminatefilestream.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SELFTERMINATEFILESTREAM_HXX_
+#define _SELFTERMINATEFILESTREAM_HXX_
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <cppuhelper/implbase2.hxx>
+
+struct OWriteStream_Impl;
+
+class OSelfTerminateFileStream : public cppu::WeakImplHelper2< ::com::sun::star::io::XInputStream,
+ ::com::sun::star::io::XSeekable >
+{
+protected:
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > m_xFileAccess;
+
+ ::rtl::OUString m_aURL;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > m_xInputStream;
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XSeekable > m_xSeekable;
+
+public:
+ OSelfTerminateFileStream( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory, const ::rtl::OUString& aURL );
+
+ virtual ~OSelfTerminateFileStream();
+
+ void CloseStreamDeleteFile();
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL available()
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeInput()
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ //XSeekable
+ virtual void SAL_CALL seek( sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getPosition() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getLength() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+};
+
+#endif
+
diff --git a/package/source/xstor/switchpersistencestream.cxx b/package/source/xstor/switchpersistencestream.cxx
new file mode 100644
index 000000000000..8756b1d61815
--- /dev/null
+++ b/package/source/xstor/switchpersistencestream.cxx
@@ -0,0 +1,488 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <osl/diagnose.h>
+
+#include <comphelper/storagehelper.hxx>
+#include <switchpersistencestream.hxx>
+
+using namespace ::com::sun::star;
+
+// ========================================================================
+struct SPStreamData_Impl
+{
+ uno::Reference< lang::XMultiServiceFactory > m_xFactory;
+
+ sal_Bool m_bInStreamBased;
+
+ // the streams below are not visible from outside so there is no need to remember position
+
+ // original stream related members
+ uno::Reference< io::XStream > m_xOrigStream;
+ uno::Reference< io::XTruncate > m_xOrigTruncate;
+ uno::Reference< io::XSeekable > m_xOrigSeekable;
+ uno::Reference< io::XInputStream > m_xOrigInStream;
+ uno::Reference< io::XOutputStream > m_xOrigOutStream;
+
+ sal_Bool m_bInOpen;
+ sal_Bool m_bOutOpen;
+
+
+ SPStreamData_Impl(
+ const uno::Reference< lang::XMultiServiceFactory >& xFactory,
+ sal_Bool bInStreamBased,
+ const uno::Reference< io::XStream >& xOrigStream,
+ const uno::Reference< io::XTruncate >& xOrigTruncate,
+ const uno::Reference< io::XSeekable >& xOrigSeekable,
+ const uno::Reference< io::XInputStream >& xOrigInStream,
+ const uno::Reference< io::XOutputStream >& xOrigOutStream,
+ sal_Bool bInOpen,
+ sal_Bool bOutOpen )
+ : m_xFactory( xFactory )
+ , m_bInStreamBased( bInStreamBased )
+ , m_xOrigStream( xOrigStream )
+ , m_xOrigTruncate( xOrigTruncate )
+ , m_xOrigSeekable( xOrigSeekable )
+ , m_xOrigInStream( xOrigInStream )
+ , m_xOrigOutStream( xOrigOutStream )
+ , m_bInOpen( bInOpen )
+ , m_bOutOpen( bOutOpen )
+ {
+ }
+};
+
+// ========================================================================
+// ------------------------------------------------------------------------
+SwitchablePersistenceStream::SwitchablePersistenceStream(
+ const uno::Reference< lang::XMultiServiceFactory >& xFactory,
+ const uno::Reference< io::XStream >& xStream )
+: m_xFactory( xFactory )
+, m_pStreamData( NULL )
+{
+ SwitchPersistenceTo( xStream );
+}
+
+// ------------------------------------------------------------------------
+SwitchablePersistenceStream::SwitchablePersistenceStream(
+ const uno::Reference< lang::XMultiServiceFactory >& xFactory,
+ const uno::Reference< io::XInputStream >& xInputStream )
+: m_xFactory( xFactory )
+, m_pStreamData( NULL )
+{
+ SwitchPersistenceTo( xInputStream );
+}
+
+// ------------------------------------------------------------------------
+SwitchablePersistenceStream::~SwitchablePersistenceStream()
+{
+ CloseAll_Impl();
+}
+
+// ------------------------------------------------------------------------
+void SwitchablePersistenceStream::SwitchPersistenceTo( const uno::Reference< io::XStream >& xStream )
+{
+ uno::Reference< io::XTruncate > xNewTruncate( xStream, uno::UNO_QUERY_THROW );
+ uno::Reference< io::XSeekable > xNewSeekable( xStream, uno::UNO_QUERY_THROW );
+ uno::Reference< io::XInputStream > xNewInStream = xStream->getInputStream();
+ uno::Reference< io::XOutputStream > xNewOutStream = xStream->getOutputStream();
+ if ( !xNewInStream.is() || !xNewOutStream.is() )
+ throw uno::RuntimeException();
+
+ sal_Int64 nPos = 0;
+ sal_Bool bInOpen = sal_False;
+ sal_Bool bOutOpen = sal_False;
+
+ if ( m_pStreamData && m_pStreamData->m_xOrigSeekable.is() )
+ {
+ // check that the length is the same
+ if ( m_pStreamData->m_xOrigSeekable->getLength() != xNewSeekable->getLength() )
+ throw uno::RuntimeException();
+
+ // get the current position
+ nPos = m_pStreamData->m_xOrigSeekable->getPosition();
+ bInOpen = m_pStreamData->m_bInOpen;
+ bOutOpen = m_pStreamData->m_bOutOpen;
+ }
+
+ xNewSeekable->seek( nPos );
+
+ CloseAll_Impl();
+
+ m_pStreamData = new SPStreamData_Impl( m_xFactory, sal_False,
+ xStream, xNewTruncate, xNewSeekable, xNewInStream, xNewOutStream,
+ bInOpen, bOutOpen );
+}
+
+// ------------------------------------------------------------------------
+void SwitchablePersistenceStream::SwitchPersistenceTo( const uno::Reference< io::XInputStream >& xInputStream )
+{
+ uno::Reference< io::XStream > xNewStream;
+ uno::Reference< io::XTruncate > xNewTruncate;
+ uno::Reference< io::XSeekable > xNewSeekable( xInputStream, uno::UNO_QUERY_THROW );
+ uno::Reference< io::XOutputStream > xNewOutStream;
+ if ( !xInputStream.is() )
+ throw uno::RuntimeException();
+
+ sal_Int64 nPos = 0;
+ sal_Bool bInOpen = sal_False;
+ sal_Bool bOutOpen = sal_False;
+
+ if ( m_pStreamData && m_pStreamData->m_xOrigSeekable.is() )
+ {
+ // check that the length is the same
+ if ( m_pStreamData->m_xOrigSeekable->getLength() != xNewSeekable->getLength() )
+ throw uno::RuntimeException();
+
+ // get the current position
+ nPos = m_pStreamData->m_xOrigSeekable->getPosition();
+ bInOpen = m_pStreamData->m_bInOpen;
+ bOutOpen = m_pStreamData->m_bOutOpen;
+ }
+
+ xNewSeekable->seek( nPos );
+
+ CloseAll_Impl();
+
+ m_pStreamData = new SPStreamData_Impl( m_xFactory, sal_True,
+ xNewStream, xNewTruncate, xNewSeekable, xInputStream, xNewOutStream,
+ bInOpen, bOutOpen );
+
+}
+
+// ------------------------------------------------------------------------
+void SwitchablePersistenceStream::CopyAndSwitchPersistenceTo( const uno::Reference< io::XStream >& xStream )
+{
+ uno::Reference< io::XStream > xTargetStream = xStream;
+ uno::Reference< io::XSeekable > xTargetSeek;
+
+ if ( !xTargetStream.is() )
+ {
+ xTargetStream = uno::Reference < io::XStream >(
+ m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
+ uno::UNO_QUERY_THROW );
+
+ xTargetSeek = uno::Reference< io::XSeekable >( xTargetStream, uno::UNO_QUERY_THROW );
+ }
+ else
+ {
+ // the provided stream must be empty
+ xTargetSeek = uno::Reference< io::XSeekable >( xTargetStream, uno::UNO_QUERY_THROW );
+ if ( xTargetSeek->getLength() )
+ throw io::IOException();
+ }
+
+ uno::Reference< io::XTruncate > xTargetTruncate( xTargetStream, uno::UNO_QUERY_THROW );
+ uno::Reference< io::XInputStream > xTargetInStream = xTargetStream->getInputStream();
+ uno::Reference< io::XOutputStream > xTargetOutStream = xTargetStream->getOutputStream();
+ if ( !xTargetInStream.is() || !xTargetOutStream.is() )
+ throw uno::RuntimeException();
+
+ if ( !m_pStreamData->m_xOrigInStream.is() || !m_pStreamData->m_xOrigSeekable.is() )
+ throw uno::RuntimeException();
+
+ sal_Int64 nPos = m_pStreamData->m_xOrigSeekable->getPosition();
+ m_pStreamData->m_xOrigSeekable->seek( 0 );
+ ::comphelper::OStorageHelper::CopyInputToOutput( m_pStreamData->m_xOrigInStream, xTargetOutStream );
+ xTargetOutStream->flush();
+ xTargetSeek->seek( nPos );
+
+ sal_Bool bInOpen = m_pStreamData->m_bInOpen;
+ sal_Bool bOutOpen = m_pStreamData->m_bOutOpen;
+
+ CloseAll_Impl();
+
+ m_pStreamData = new SPStreamData_Impl( m_xFactory, sal_False,
+ xTargetStream, xTargetTruncate, xTargetSeek, xTargetInStream, xTargetOutStream,
+ bInOpen, bOutOpen );
+}
+
+// ------------------------------------------------------------------------
+void SwitchablePersistenceStream::CloseAll_Impl()
+{
+ if ( m_pStreamData )
+ {
+ delete m_pStreamData;
+ m_pStreamData = NULL;
+ }
+}
+
+// com::sun::star::io::XStream
+// ------------------------------------------------------------------------
+uno::Reference< io::XInputStream > SAL_CALL SwitchablePersistenceStream::getInputStream( )
+ throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_pStreamData )
+ m_pStreamData->m_bInOpen = sal_True;
+ return static_cast< io::XInputStream* >( this );
+}
+
+
+// ------------------------------------------------------------------------
+uno::Reference< io::XOutputStream > SAL_CALL SwitchablePersistenceStream::getOutputStream( )
+ throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_pStreamData )
+ m_pStreamData->m_bOutOpen = sal_True;
+ return static_cast< io::XOutputStream* >( this );
+}
+
+
+
+// com::sun::star::io::XInputStream
+// ------------------------------------------------------------------------
+::sal_Int32 SAL_CALL SwitchablePersistenceStream::readBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead )
+ throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigInStream.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_xOrigInStream->readBytes( aData, nBytesToRead );
+}
+
+
+// ------------------------------------------------------------------------
+::sal_Int32 SAL_CALL SwitchablePersistenceStream::readSomeBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead )
+ throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigInStream.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_xOrigInStream->readBytes( aData, nMaxBytesToRead );
+}
+
+// ------------------------------------------------------------------------
+void SAL_CALL SwitchablePersistenceStream::skipBytes( ::sal_Int32 nBytesToSkip )
+ throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigInStream.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData->m_xOrigInStream->skipBytes( nBytesToSkip );
+}
+
+
+// ------------------------------------------------------------------------
+::sal_Int32 SAL_CALL SwitchablePersistenceStream::available( )
+ throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigInStream.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_xOrigInStream->available();
+}
+
+
+// ------------------------------------------------------------------------
+void SAL_CALL SwitchablePersistenceStream::closeInput()
+ throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ m_pStreamData->m_bInOpen = sal_False;
+ if ( !m_pStreamData->m_bOutOpen )
+ CloseAll_Impl();
+}
+
+
+
+// com::sun::star::io::XOutputStream
+// ------------------------------------------------------------------------
+void SAL_CALL SwitchablePersistenceStream::writeBytes( const uno::Sequence< ::sal_Int8 >& aData )
+ throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ if ( m_pStreamData->m_bInStreamBased )
+ throw io::IOException();
+
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigOutStream.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData->m_xOrigOutStream->writeBytes( aData );
+}
+
+
+// ------------------------------------------------------------------------
+void SAL_CALL SwitchablePersistenceStream::flush( )
+ throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData || m_pStreamData->m_bInStreamBased )
+ {
+ OSL_ENSURE( sal_False, "flush() is not acceptable!\n" );
+ return;
+ // in future throw exception, for now some code might call flush() on closed stream
+ // since file ucp implementation allows it
+ // throw io::NotConnectedException();
+ }
+
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigOutStream.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData->m_xOrigOutStream->flush();
+}
+
+
+// ------------------------------------------------------------------------
+void SAL_CALL SwitchablePersistenceStream::closeOutput( )
+ throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ m_pStreamData->m_bOutOpen = sal_False;
+ if ( !m_pStreamData->m_bInOpen )
+ CloseAll_Impl();
+}
+
+
+
+// com::sun::star::io::XTruncate
+// ------------------------------------------------------------------------
+void SAL_CALL SwitchablePersistenceStream::truncate( )
+ throw (io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ if ( m_pStreamData->m_bInStreamBased )
+ throw io::IOException();
+
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigTruncate.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData->m_xOrigTruncate->truncate();
+}
+
+
+// com::sun::star::io::XSeekable
+// ------------------------------------------------------------------------
+void SAL_CALL SwitchablePersistenceStream::seek( ::sal_Int64 location )
+ throw (lang::IllegalArgumentException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigSeekable.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData->m_xOrigSeekable->seek( location );
+}
+
+
+// ------------------------------------------------------------------------
+::sal_Int64 SAL_CALL SwitchablePersistenceStream::getPosition( )
+ throw (io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigSeekable.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_xOrigSeekable->getPosition();
+}
+
+
+// ------------------------------------------------------------------------
+::sal_Int64 SAL_CALL SwitchablePersistenceStream::getLength( )
+ throw (io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigSeekable.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_xOrigSeekable->getLength();
+}
+
+// ------------------------------------------------------------------------
+void SAL_CALL SwitchablePersistenceStream::waitForCompletion()
+ throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ uno::Reference< io::XAsyncOutputMonitor > asyncOutputMonitor( m_pStreamData->m_xOrigOutStream, uno::UNO_QUERY );
+ if ( asyncOutputMonitor.is() )
+ asyncOutputMonitor->waitForCompletion();
+}
+
diff --git a/package/source/xstor/switchpersistencestream.hxx b/package/source/xstor/switchpersistencestream.hxx
new file mode 100644
index 000000000000..f37d0ed892fa
--- /dev/null
+++ b/package/source/xstor/switchpersistencestream.hxx
@@ -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.
+ *
+ ************************************************************************/
+#ifndef _SPSTREAM_HXX
+#define _SPSTREAM_HXX
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/io/XAsyncOutputMonitor.hpp>
+#include <osl/mutex.hxx>
+#include <cppuhelper/implbase6.hxx>
+
+//==================================================================
+// SwitchablePersistenceStream
+//
+// Allows to switch the stream persistence on the fly. The target
+// stream ( if not filled by the implementation ) MUST have the same
+// size as the original one!
+//==================================================================
+
+struct SPStreamData_Impl;
+class SwitchablePersistenceStream
+ : public ::cppu::WeakImplHelper6 <
+ ::com::sun::star::io::XStream,
+ ::com::sun::star::io::XInputStream,
+ ::com::sun::star::io::XOutputStream,
+ ::com::sun::star::io::XTruncate,
+ ::com::sun::star::io::XSeekable,
+ ::com::sun::star::io::XAsyncOutputMonitor >
+{
+ ::osl::Mutex m_aMutex;
+
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;
+
+ SPStreamData_Impl* m_pStreamData;
+
+ void CloseAll_Impl();
+
+public:
+
+ SwitchablePersistenceStream(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xStream );
+
+ SwitchablePersistenceStream(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInStream );
+
+ ~SwitchablePersistenceStream();
+
+ void SwitchPersistenceTo( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xStream );
+
+ void SwitchPersistenceTo( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInputStream );
+
+ void CopyAndSwitchPersistenceTo( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xStream );
+
+// com::sun::star::io::XStream
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream( ) throw (::com::sun::star::uno::RuntimeException);
+
+// com::sun::star::io::XInputStream
+ virtual ::sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL skipBytes( ::sal_Int32 nBytesToSkip ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL available( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeInput( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+// com::sun::star::io::XOutputStream
+ virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL flush( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeOutput( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+// com::sun::star::io::XTruncate
+ virtual void SAL_CALL truncate( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+// com::sun::star::io::XSeekable
+ virtual void SAL_CALL seek( ::sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int64 SAL_CALL getPosition( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int64 SAL_CALL getLength( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::io::XAsyncOutputMonitor
+ virtual void SAL_CALL waitForCompletion( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+};
+
+#endif //_SPSTREAM_HXX
+
+
diff --git a/package/source/xstor/xfactory.cxx b/package/source/xstor/xfactory.cxx
new file mode 100644
index 000000000000..12aa89e03db0
--- /dev/null
+++ b/package/source/xstor/xfactory.cxx
@@ -0,0 +1,324 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/StorageFormats.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+
+#include <comphelper/storagehelper.hxx>
+
+#include "xfactory.hxx"
+#include "xstorage.hxx"
+
+
+using namespace ::com::sun::star;
+
+//-------------------------------------------------------------------------
+sal_Bool CheckPackageSignature_Impl( const uno::Reference< io::XInputStream >& xInputStream,
+ const uno::Reference< io::XSeekable >& xSeekable )
+{
+ if ( !xInputStream.is() || !xSeekable.is() )
+ throw uno::RuntimeException();
+
+ if ( xSeekable->getLength() )
+ {
+ uno::Sequence< sal_Int8 > aData( 4 );
+ xSeekable->seek( 0 );
+ sal_Int32 nRead = xInputStream->readBytes( aData, 4 );
+ xSeekable->seek( 0 );
+
+ // TODO/LATER: should the disk spanned files be supported?
+ // 0x50, 0x4b, 0x07, 0x08
+ return ( nRead == 4 && aData[0] == 0x50 && aData[1] == 0x4b && aData[2] == 0x03 && aData[3] == 0x04 );
+ }
+ else
+ return sal_True; // allow to create a storage based on empty stream
+}
+
+//-------------------------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL OStorageFactory::impl_staticGetSupportedServiceNames()
+{
+ uno::Sequence< ::rtl::OUString > aRet(2);
+ aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.embed.StorageFactory");
+ aRet[1] = ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.StorageFactory");
+ return aRet;
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OStorageFactory::impl_staticGetImplementationName()
+{
+ return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.StorageFactory");
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< uno::XInterface > SAL_CALL OStorageFactory::impl_staticCreateSelfInstance(
+ const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
+{
+ return uno::Reference< uno::XInterface >( *new OStorageFactory( xServiceManager ) );
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< uno::XInterface > SAL_CALL OStorageFactory::createInstance()
+ throw ( uno::Exception,
+ uno::RuntimeException )
+{
+ // TODO: reimplement TempStream service to support XStream interface
+ uno::Reference < io::XStream > xTempStream(
+ m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
+ uno::UNO_QUERY );
+
+ if ( !xTempStream.is() )
+ throw uno::RuntimeException(); // TODO:
+
+ return uno::Reference< uno::XInterface >(
+ static_cast< OWeakObject* >( new OStorage( xTempStream,
+ embed::ElementModes::READWRITE,
+ uno::Sequence< beans::PropertyValue >(),
+ m_xFactory,
+ embed::StorageFormats::PACKAGE ) ),
+ uno::UNO_QUERY );
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< uno::XInterface > SAL_CALL OStorageFactory::createInstanceWithArguments(
+ const uno::Sequence< uno::Any >& aArguments )
+ throw ( uno::Exception,
+ uno::RuntimeException )
+{
+ // The request for storage can be done with up to three arguments
+
+ // The first argument specifies a source for the storage
+ // it can be URL, XStream, XInputStream.
+ // The second value is a mode the storage should be open in.
+ // And the third value is a media descriptor.
+
+ sal_Int32 nArgNum = aArguments.getLength();
+ OSL_ENSURE( nArgNum < 4, "Wrong parameter number" );
+
+ if ( !nArgNum )
+ return createInstance();
+
+ // first try to retrieve storage open mode if any
+ // by default the storage will be open in readonly mode
+ sal_Int32 nStorageMode = embed::ElementModes::READ;
+ if ( nArgNum >= 2 )
+ {
+ if( !( aArguments[1] >>= nStorageMode ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong second argument!\n" );
+ throw lang::IllegalArgumentException(); // TODO:
+ }
+ // it's allways possible to read written storage in this implementation
+ nStorageMode |= embed::ElementModes::READ;
+ }
+
+ if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) == embed::ElementModes::TRUNCATE
+ && ( nStorageMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE )
+ throw lang::IllegalArgumentException(); // TODO:
+
+ // retrieve storage source stream
+ ::rtl::OUString aURL;
+ uno::Reference< io::XStream > xStream;
+ uno::Reference< io::XInputStream > xInputStream;
+
+ if ( aArguments[0] >>= aURL )
+ {
+ if ( !aURL.getLength() )
+ {
+ OSL_ENSURE( sal_False, "Empty URL is provided!\n" );
+ throw lang::IllegalArgumentException(); // TODO:
+ }
+
+ if ( aURL.equalsIgnoreAsciiCaseAsciiL( "vnd.sun.star.pkg", 16 ) )
+ {
+ OSL_ENSURE( sal_False, "Packages URL's are not valid for storages!\n" ); // ???
+ throw lang::IllegalArgumentException(); // TODO:
+ }
+
+ uno::Reference < ::com::sun::star::ucb::XSimpleFileAccess > xTempAccess(
+ m_xFactory->createInstance (
+ ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
+ uno::UNO_QUERY );
+
+ if ( !xTempAccess.is() )
+ throw uno::RuntimeException(); // TODO:
+
+ if ( nStorageMode & embed::ElementModes::WRITE )
+ xStream = xTempAccess->openFileReadWrite( aURL );
+ else
+ xInputStream = xTempAccess->openFileRead( aURL );
+ }
+ else if ( !( aArguments[0] >>= xStream ) && !( aArguments[0] >>= xInputStream ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong first argument!\n" );
+ throw uno::Exception(); // TODO: Illegal argument
+ }
+
+ // retrieve mediadescriptor and set storage properties
+ uno::Sequence< beans::PropertyValue > aDescr;
+ uno::Sequence< beans::PropertyValue > aPropsToSet;
+
+ sal_Int32 nStorageType = embed::StorageFormats::PACKAGE;
+
+ if ( nArgNum >= 3 )
+ {
+ if( aArguments[2] >>= aDescr )
+ {
+ if ( aURL.getLength() )
+ {
+ aPropsToSet.realloc(1);
+ aPropsToSet[0].Name = ::rtl::OUString::createFromAscii( "URL" );
+ aPropsToSet[0].Value <<= aURL;
+ }
+
+ for ( sal_Int32 nInd = 0, nNumArgs = 1; nInd < aDescr.getLength(); nInd++ )
+ {
+ if ( aDescr[nInd].Name.equalsAscii( "InteractionHandler" )
+ || aDescr[nInd].Name.equalsAscii( "Password" )
+ || aDescr[nInd].Name.equalsAscii( "RepairPackage" )
+ || aDescr[nInd].Name.equalsAscii( "StatusIndicator" ) )
+ // || aDescr[nInd].Name.equalsAscii( "Unpacked" ) // TODO:
+ {
+ aPropsToSet.realloc( ++nNumArgs );
+ aPropsToSet[nNumArgs-1].Name = aDescr[nInd].Name;
+ aPropsToSet[nNumArgs-1].Value = aDescr[nInd].Value;
+ }
+ else if ( aDescr[nInd].Name.equalsAscii( "StorageFormat" ) )
+ {
+ ::rtl::OUString aFormatName;
+ sal_Int32 nFormatID = 0;
+ if ( aDescr[nInd].Value >>= aFormatName )
+ {
+ if ( aFormatName.equals( PACKAGE_STORAGE_FORMAT_STRING ) )
+ nStorageType = embed::StorageFormats::PACKAGE;
+ else if ( aFormatName.equals( ZIP_STORAGE_FORMAT_STRING ) )
+ nStorageType = embed::StorageFormats::ZIP;
+ else if ( aFormatName.equals( OFOPXML_STORAGE_FORMAT_STRING ) )
+ nStorageType = embed::StorageFormats::OFOPXML;
+ else
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+ }
+ else if ( aDescr[nInd].Value >>= nFormatID )
+ {
+ if ( nFormatID != embed::StorageFormats::PACKAGE
+ && nFormatID != embed::StorageFormats::ZIP
+ && nFormatID != embed::StorageFormats::OFOPXML )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ nStorageType = nFormatID;
+ }
+ else
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+ }
+ else
+ OSL_ENSURE( sal_False, "Unacceptable property, will be ignored!\n" );
+ }
+ }
+ else
+ {
+ OSL_ENSURE( sal_False, "Wrong third argument!\n" );
+ throw uno::Exception(); // TODO: Illegal argument
+ }
+
+ }
+
+ // create storage based on source
+ if ( xInputStream.is() )
+ {
+ // if xInputStream is set the storage should be open from it
+ if ( ( nStorageMode & embed::ElementModes::WRITE ) )
+ throw uno::Exception(); // TODO: access denied
+
+ uno::Reference< io::XSeekable > xSeekable( xInputStream, uno::UNO_QUERY );
+ if ( !xSeekable.is() )
+ {
+ // TODO: wrap stream to let it be seekable
+ OSL_ENSURE( sal_False, "Nonseekable streams are not supported for now!\n" );
+ }
+
+ if ( !CheckPackageSignature_Impl( xInputStream, xSeekable ) )
+ throw io::IOException(); // TODO: this is not a package file
+
+ return uno::Reference< uno::XInterface >(
+ static_cast< OWeakObject* >( new OStorage( xInputStream, nStorageMode, aPropsToSet, m_xFactory, nStorageType ) ),
+ uno::UNO_QUERY );
+ }
+ else if ( xStream.is() )
+ {
+ if ( ( ( nStorageMode & embed::ElementModes::WRITE ) && !xStream->getOutputStream().is() )
+ || !xStream->getInputStream().is() )
+ throw uno::Exception(); // TODO: access denied
+
+ uno::Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY );
+ if ( !xSeekable.is() )
+ {
+ // TODO: wrap stream to let it be seekable
+ OSL_ENSURE( sal_False, "Nonseekable streams are not supported for now!\n" );
+ }
+
+ if ( !CheckPackageSignature_Impl( xStream->getInputStream(), xSeekable ) )
+ throw io::IOException(); // TODO: this is not a package file
+
+ return uno::Reference< uno::XInterface >(
+ static_cast< OWeakObject* >( new OStorage( xStream, nStorageMode, aPropsToSet, m_xFactory, nStorageType ) ),
+ uno::UNO_QUERY );
+ }
+
+ throw uno::Exception(); // general error during creation
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OStorageFactory::getImplementationName()
+ throw ( uno::RuntimeException )
+{
+ return impl_staticGetImplementationName();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL OStorageFactory::supportsService( const ::rtl::OUString& ServiceName )
+ throw ( uno::RuntimeException )
+{
+ uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();
+
+ for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
+ if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
+ return sal_True;
+
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL OStorageFactory::getSupportedServiceNames()
+ throw ( uno::RuntimeException )
+{
+ return impl_staticGetSupportedServiceNames();
+}
+
diff --git a/package/source/xstor/xfactory.hxx b/package/source/xstor/xfactory.hxx
new file mode 100644
index 000000000000..cdc6c3abe584
--- /dev/null
+++ b/package/source/xstor/xfactory.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __XFACTORY_HXX_
+#define __XFACTORY_HXX_
+
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+
+#include <cppuhelper/implbase2.hxx>
+
+
+class OStorage;
+
+class OStorageFactory : public ::cppu::WeakImplHelper2< ::com::sun::star::lang::XSingleServiceFactory,
+ ::com::sun::star::lang::XServiceInfo >
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;
+
+public:
+ OStorageFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory )
+ : m_xFactory( xFactory )
+ {
+ OSL_ENSURE( xFactory.is(), "No service manager is provided!\n" );
+ }
+
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ impl_staticGetSupportedServiceNames();
+
+ static ::rtl::OUString SAL_CALL impl_staticGetImplementationName();
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
+ impl_staticCreateSelfInstance(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager );
+
+
+ // XSingleServiceFactory
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstance() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithArguments( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException);
+
+};
+
+#endif
+
diff --git a/package/source/xstor/xstor.dxp b/package/source/xstor/xstor.dxp
new file mode 100644
index 000000000000..9630d7e06768
--- /dev/null
+++ b/package/source/xstor/xstor.dxp
@@ -0,0 +1,3 @@
+component_getImplementationEnvironment
+component_writeInfo
+component_getFactory
diff --git a/package/source/xstor/xstorage.cxx b/package/source/xstor/xstorage.cxx
new file mode 100644
index 000000000000..9c90c4ce35dd
--- /dev/null
+++ b/package/source/xstor/xstorage.cxx
@@ -0,0 +1,6175 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/UseBackupException.hpp>
+#include <com/sun/star/embed/StorageFormats.hpp>
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+
+
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+
+
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <rtl/logfile.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <comphelper/ofopxmlhelper.hxx>
+
+#include "xstorage.hxx"
+#include "owriteablestream.hxx"
+#include "disposelistener.hxx"
+#include "switchpersistencestream.hxx"
+#include "ohierarchyholder.hxx"
+
+using namespace ::com::sun::star;
+
+//=========================================================
+
+typedef ::std::list< uno::WeakReference< lang::XComponent > > WeakComponentList;
+
+struct StorInternalData_Impl
+{
+ SotMutexHolderRef m_rSharedMutexRef;
+ ::cppu::OMultiTypeInterfaceContainerHelper m_aListenersContainer; // list of listeners
+ ::cppu::OTypeCollection* m_pTypeCollection;
+ sal_Bool m_bIsRoot;
+ sal_Int32 m_nStorageType; // the mode in wich the storage is used
+ sal_Bool m_bReadOnlyWrap;
+
+ OChildDispListener_Impl* m_pSubElDispListener;
+
+ WeakComponentList m_aOpenSubComponentsList;
+
+ ::rtl::Reference< OHierarchyHolder_Impl > m_rHierarchyHolder;
+
+ // the mutex reference MUST NOT be empty
+ StorInternalData_Impl( const SotMutexHolderRef& rMutexRef, sal_Bool bRoot, sal_Int32 nStorageType, sal_Bool bReadOnlyWrap )
+ : m_rSharedMutexRef( rMutexRef )
+ , m_aListenersContainer( rMutexRef->GetMutex() )
+ , m_pTypeCollection( NULL )
+ , m_bIsRoot( bRoot )
+ , m_nStorageType( nStorageType )
+ , m_bReadOnlyWrap( bReadOnlyWrap )
+ , m_pSubElDispListener( NULL )
+ {}
+
+ ~StorInternalData_Impl();
+};
+
+//=========================================================
+::rtl::OUString GetNewTempFileURL( const uno::Reference< lang::XMultiServiceFactory > xFactory );
+
+// static
+void OStorage_Impl::completeStorageStreamCopy_Impl(
+ const uno::Reference< io::XStream >& xSource,
+ const uno::Reference< io::XStream >& xDest,
+ sal_Int32 nStorageType,
+ const uno::Sequence< uno::Sequence< beans::StringPair > >& aRelInfo )
+{
+ uno::Reference< beans::XPropertySet > xSourceProps( xSource, uno::UNO_QUERY );
+ uno::Reference< beans::XPropertySet > xDestProps( xDest, uno::UNO_QUERY );
+ if ( !xSourceProps.is() || !xDestProps.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< io::XOutputStream > xDestOutStream = xDest->getOutputStream();
+ if ( !xDestOutStream.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< io::XInputStream > xSourceInStream = xSource->getInputStream();
+ if ( !xSourceInStream.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // TODO: headers of encripted streams should be copied also
+ ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInStream, xDestOutStream );
+
+ uno::Sequence< ::rtl::OUString > aPropNames( 1 );
+ aPropNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) );
+
+ if ( nStorageType == embed::StorageFormats::PACKAGE )
+ {
+ aPropNames.realloc( 3 );
+ aPropNames[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
+ aPropNames[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
+ }
+ else if ( nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ // TODO/LATER: in future it might make sence to provide the stream if there is one
+ uno::Reference< embed::XRelationshipAccess > xRelAccess( xDest, uno::UNO_QUERY_THROW );
+ xRelAccess->clearRelationships();
+ xRelAccess->insertRelationships( aRelInfo, sal_False );
+
+ aPropNames.realloc( 2 );
+ aPropNames[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
+ }
+
+ for ( int ind = 0; ind < aPropNames.getLength(); ind++ )
+ xDestProps->setPropertyValue( aPropNames[ind], xSourceProps->getPropertyValue( aPropNames[ind] ) );
+}
+
+uno::Reference< io::XInputStream > GetSeekableTempCopy( uno::Reference< io::XInputStream > xInStream,
+ uno::Reference< lang::XMultiServiceFactory > xFactory )
+{
+ uno::Reference < io::XOutputStream > xTempOut(
+ xFactory->createInstance ( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
+ uno::UNO_QUERY );
+ uno::Reference < io::XInputStream > xTempIn( xTempOut, uno::UNO_QUERY );
+
+ if ( !xTempOut.is() || !xTempIn.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOut );
+ xTempOut->closeOutput();
+
+ return xTempIn;
+}
+
+StorInternalData_Impl::~StorInternalData_Impl()
+{
+ if ( m_pTypeCollection )
+ delete m_pTypeCollection;
+}
+
+
+SotElement_Impl::SotElement_Impl( const ::rtl::OUString& rName, sal_Bool bStor, sal_Bool bNew )
+: m_aName( rName )
+, m_aOriginalName( rName )
+, m_bIsRemoved( sal_False )
+, m_bIsInserted( bNew )
+, m_bIsStorage( bStor )
+, m_pStorage( NULL )
+, m_pStream( NULL )
+{
+}
+
+SotElement_Impl::~SotElement_Impl()
+{
+ if ( m_pStorage )
+ delete m_pStorage;
+
+ if ( m_pStream )
+ delete m_pStream;
+}
+
+//-----------------------------------------------
+// most of properties are holt by the storage but are not used
+OStorage_Impl::OStorage_Impl( uno::Reference< io::XInputStream > xInputStream,
+ sal_Int32 nMode,
+ uno::Sequence< beans::PropertyValue > xProperties,
+ uno::Reference< lang::XMultiServiceFactory > xFactory,
+ sal_Int32 nStorageType )
+: m_rMutexRef( new SotMutexHolder )
+, m_pAntiImpl( NULL )
+, m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
+, m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
+, m_bBroadcastModified( sal_False )
+, m_bCommited( sal_False )
+, m_bIsRoot( sal_True )
+, m_bListCreated( sal_False )
+, m_xFactory( xFactory )
+, m_xProperties( xProperties )
+, m_bHasCommonPassword( sal_False )
+, m_pParent( NULL )
+, m_bControlMediaType( sal_False )
+, m_bMTFallbackUsed( sal_False )
+, m_bControlVersion( sal_False )
+, m_pSwitchStream( NULL )
+, m_nStorageType( nStorageType )
+, m_pRelStorElement( NULL )
+, m_nRelInfoStatus( RELINFO_NO_INIT )
+{
+ // all the checks done below by assertion statements must be done by factory
+ OSL_ENSURE( xInputStream.is(), "No input stream is provided!\n" );
+
+ m_pSwitchStream = (SwitchablePersistenceStream*) new SwitchablePersistenceStream( xFactory, xInputStream );
+ m_xInputStream = m_pSwitchStream->getInputStream();
+
+ if ( m_nStorageMode & embed::ElementModes::WRITE )
+ {
+ // check that the stream allows to write
+ OSL_ENSURE( sal_False, "No stream for writing is provided!\n" );
+ }
+}
+
+//-----------------------------------------------
+// most of properties are holt by the storage but are not used
+OStorage_Impl::OStorage_Impl( uno::Reference< io::XStream > xStream,
+ sal_Int32 nMode,
+ uno::Sequence< beans::PropertyValue > xProperties,
+ uno::Reference< lang::XMultiServiceFactory > xFactory,
+ sal_Int32 nStorageType )
+: m_rMutexRef( new SotMutexHolder )
+, m_pAntiImpl( NULL )
+, m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
+, m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
+, m_bBroadcastModified( sal_False )
+, m_bCommited( sal_False )
+, m_bIsRoot( sal_True )
+, m_bListCreated( sal_False )
+, m_xFactory( xFactory )
+, m_xProperties( xProperties )
+, m_bHasCommonPassword( sal_False )
+, m_pParent( NULL )
+, m_bControlMediaType( sal_False )
+, m_bMTFallbackUsed( sal_False )
+, m_bControlVersion( sal_False )
+, m_pSwitchStream( NULL )
+, m_nStorageType( nStorageType )
+, m_pRelStorElement( NULL )
+, m_nRelInfoStatus( RELINFO_NO_INIT )
+{
+ // all the checks done below by assertion statements must be done by factory
+ OSL_ENSURE( xStream.is(), "No stream is provided!\n" );
+
+ if ( m_nStorageMode & embed::ElementModes::WRITE )
+ {
+ m_pSwitchStream = (SwitchablePersistenceStream*) new SwitchablePersistenceStream( xFactory, xStream );
+ m_xStream = static_cast< io::XStream* >( m_pSwitchStream );
+ }
+ else
+ {
+ m_pSwitchStream = (SwitchablePersistenceStream*) new SwitchablePersistenceStream( xFactory,
+ xStream->getInputStream() );
+ m_xInputStream = m_pSwitchStream->getInputStream();
+ }
+}
+
+//-----------------------------------------------
+OStorage_Impl::OStorage_Impl( OStorage_Impl* pParent,
+ sal_Int32 nMode,
+ uno::Reference< container::XNameContainer > xPackageFolder,
+ uno::Reference< lang::XSingleServiceFactory > xPackage,
+ uno::Reference< lang::XMultiServiceFactory > xFactory,
+ sal_Int32 nStorageType )
+: m_rMutexRef( new SotMutexHolder )
+, m_pAntiImpl( NULL )
+, m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
+, m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
+, m_bBroadcastModified( sal_False )
+, m_bCommited( sal_False )
+, m_bIsRoot( sal_False )
+, m_bListCreated( sal_False )
+, m_xPackageFolder( xPackageFolder )
+, m_xPackage( xPackage )
+, m_xFactory( xFactory )
+, m_bHasCommonPassword( sal_False )
+, m_pParent( pParent ) // can be empty in case of temporary readonly substorages and relation storage
+, m_bControlMediaType( sal_False )
+, m_bMTFallbackUsed( sal_False )
+, m_bControlVersion( sal_False )
+, m_pSwitchStream( NULL )
+, m_nStorageType( nStorageType )
+, m_pRelStorElement( NULL )
+, m_nRelInfoStatus( RELINFO_NO_INIT )
+{
+ OSL_ENSURE( xPackageFolder.is(), "No package folder!\n" );
+}
+
+//-----------------------------------------------
+OStorage_Impl::~OStorage_Impl()
+{
+ {
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+ if ( m_pAntiImpl ) // root storage wrapper must set this member to NULL before destruction of object
+ {
+ OSL_ENSURE( !m_bIsRoot, "The root storage wrapper must be disposed already" );
+
+ try {
+ m_pAntiImpl->InternalDispose( sal_False );
+ }
+ catch ( uno::Exception& aException )
+ {
+ AddLog( aException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+ }
+ m_pAntiImpl = NULL;
+ }
+ else if ( !m_aReadOnlyWrapList.empty() )
+ {
+ for ( OStorageList_Impl::iterator pStorageIter = m_aReadOnlyWrapList.begin();
+ pStorageIter != m_aReadOnlyWrapList.end(); pStorageIter++ )
+ {
+ uno::Reference< embed::XStorage > xTmp = pStorageIter->m_xWeakRef;
+ if ( xTmp.is() )
+ try {
+ pStorageIter->m_pPointer->InternalDispose( sal_False );
+ } catch( uno::Exception& aException )
+ {
+ AddLog( aException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+ }
+ }
+
+ m_aReadOnlyWrapList.clear();
+ }
+
+ m_pParent = NULL;
+ }
+
+ for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
+ pElementIter != m_aChildrenList.end(); pElementIter++ )
+ delete *pElementIter;
+
+ m_aChildrenList.clear();
+
+ for ( SotElementList_Impl::iterator pDeletedIter = m_aDeletedList.begin();
+ pDeletedIter != m_aDeletedList.end(); pDeletedIter++ )
+ delete *pDeletedIter;
+
+ m_aDeletedList.clear();
+
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML && m_pRelStorElement )
+ {
+ delete m_pRelStorElement;
+ m_pRelStorElement = NULL;
+ }
+
+ m_xPackageFolder = uno::Reference< container::XNameContainer >();
+ m_xPackage = uno::Reference< lang::XSingleServiceFactory >();
+
+ ::rtl::OUString aPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
+ for ( sal_Int32 aInd = 0; aInd < m_xProperties.getLength(); aInd++ )
+ {
+ if ( m_xProperties[aInd].Name.equals( aPropertyName ) )
+ {
+ // the storage is URL based so all the streams are opened by factory and should be closed
+ try
+ {
+ if ( m_xInputStream.is() )
+ {
+ m_xInputStream->closeInput();
+ m_xInputStream = uno::Reference< io::XInputStream >();
+ }
+
+ if ( m_xStream.is() )
+ {
+ uno::Reference< io::XInputStream > xInStr = m_xStream->getInputStream();
+ if ( xInStr.is() )
+ xInStr->closeInput();
+
+ uno::Reference< io::XOutputStream > xOutStr = m_xStream->getOutputStream();
+ if ( xOutStr.is() )
+ xOutStr->closeOutput();
+
+ m_xStream = uno::Reference< io::XStream >();
+ }
+ }
+ catch( uno::Exception& aException )
+ {
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+ AddLog( aException.Message );
+ }
+ }
+ }
+}
+
+//-----------------------------------------------
+void OStorage_Impl::AddLog( const ::rtl::OUString& aMessage )
+{
+ if ( !m_xLogRing.is() )
+ {
+ try
+ {
+ ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
+ if ( aContext.is() )
+ m_xLogRing.set( aContext.getSingleton( "com.sun.star.logging.DocumentIOLogRing" ), uno::UNO_QUERY_THROW );
+ }
+ catch( uno::Exception& )
+ {
+ // No log
+ }
+ }
+
+ if ( m_xLogRing.is() )
+ m_xLogRing->logString( aMessage );
+}
+
+//-----------------------------------------------
+void OStorage_Impl::SetReadOnlyWrap( OStorage& aStorage )
+{
+ // Weak reference is used inside the holder so the refcount must not be zero at this point
+ OSL_ENSURE( aStorage.GetRefCount_Impl(), "There must be a reference alive to use this method!\n" );
+ m_aReadOnlyWrapList.push_back( StorageHolder_Impl( &aStorage ) );
+}
+
+//-----------------------------------------------
+void OStorage_Impl::RemoveReadOnlyWrap( OStorage& aStorage )
+{
+ for ( OStorageList_Impl::iterator pStorageIter = m_aReadOnlyWrapList.begin();
+ pStorageIter != m_aReadOnlyWrapList.end();)
+ {
+ uno::Reference< embed::XStorage > xTmp = pStorageIter->m_xWeakRef;
+ if ( !xTmp.is() || pStorageIter->m_pPointer == &aStorage )
+ {
+ try {
+ pStorageIter->m_pPointer->InternalDispose( sal_False );
+ } catch( uno::Exception& aException )
+ {
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+ AddLog( aException.Message );
+ }
+
+ OStorageList_Impl::iterator pIterToDelete( pStorageIter );
+ pStorageIter++;
+ m_aReadOnlyWrapList.erase( pIterToDelete );
+ }
+ else
+ pStorageIter++;
+ }
+}
+
+//-----------------------------------------------
+void OStorage_Impl::OpenOwnPackage()
+{
+ OSL_ENSURE( m_bIsRoot, "Opening of the package has no sence!\n" );
+
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( !m_xPackageFolder.is() )
+ {
+ if ( !m_xPackage.is() )
+ {
+ uno::Sequence< uno::Any > aArguments( 2 );
+ if ( m_nStorageMode & embed::ElementModes::WRITE )
+ aArguments[ 0 ] <<= m_xStream;
+ else
+ {
+ OSL_ENSURE( m_xInputStream.is(), "Input stream must be set for readonly access!\n" );
+ aArguments[ 0 ] <<= m_xInputStream;
+ // TODO: if input stream is not seekable or XSeekable interface is supported
+ // on XStream object a wrapper must be used
+ }
+
+ // do not allow elements to remove themself from the old container in case of insertion to another container
+ aArguments[ 1 ] <<= beans::NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowRemoveOnInsert" ) ),
+ uno::makeAny( (sal_Bool)sal_False ) );
+
+ sal_Int32 nArgNum = 2;
+ for ( sal_Int32 aInd = 0; aInd < m_xProperties.getLength(); aInd++ )
+ {
+ if ( m_xProperties[aInd].Name.equalsAscii( "RepairPackage" )
+ || m_xProperties[aInd].Name.equalsAscii( "ProgressHandler" ) )
+ {
+ beans::NamedValue aNamedValue( m_xProperties[aInd].Name,
+ m_xProperties[aInd].Value );
+ aArguments.realloc( ++nArgNum );
+ aArguments[nArgNum-1] <<= aNamedValue;
+ }
+ else if ( m_xProperties[aInd].Name.equalsAscii( "Password" ) )
+ {
+ // TODO: implement password setting for documents
+ // the password entry must be removed after setting
+ }
+ }
+
+ if ( m_nStorageType == embed::StorageFormats::ZIP )
+ {
+ // let the package support only plain zip format
+ beans::NamedValue aNamedValue;
+ aNamedValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
+ aNamedValue.Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ZipFormat" ) );
+ aArguments.realloc( ++nArgNum );
+ aArguments[nArgNum-1] <<= aNamedValue;
+ }
+ else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ // let the package support OFOPXML media type handling
+ beans::NamedValue aNamedValue;
+ aNamedValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
+ aNamedValue.Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OFOPXMLFormat" ) );
+ aArguments.realloc( ++nArgNum );
+ aArguments[nArgNum-1] <<= aNamedValue;
+ }
+
+ m_xPackage = uno::Reference< lang::XSingleServiceFactory > (
+ GetServiceFactory()->createInstanceWithArguments(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.packages.comp.ZipPackage" ) ),
+ aArguments ),
+ uno::UNO_QUERY );
+ }
+
+ uno::Reference< container::XHierarchicalNameAccess > xHNameAccess( m_xPackage, uno::UNO_QUERY );
+ OSL_ENSURE( xHNameAccess.is(), "The package could not be created!\n" );
+
+ if ( xHNameAccess.is() )
+ {
+ uno::Any aFolder = xHNameAccess->getByHierarchicalName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ) );
+ aFolder >>= m_xPackageFolder;
+ }
+ }
+
+ OSL_ENSURE( m_xPackageFolder.is(), "The package root folder can not be opened!\n" );
+ if ( !m_xPackageFolder.is() )
+ throw embed::InvalidStorageException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+//-----------------------------------------------
+uno::Reference< lang::XMultiServiceFactory > OStorage_Impl::GetServiceFactory()
+{
+ if ( m_xFactory.is() )
+ return m_xFactory;
+
+ return ::comphelper::getProcessServiceFactory();
+}
+
+//-----------------------------------------------
+SotElementList_Impl& OStorage_Impl::GetChildrenList()
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ ReadContents();
+ return m_aChildrenList;
+}
+
+//-----------------------------------------------
+void OStorage_Impl::GetStorageProperties()
+{
+ if ( m_nStorageType == embed::StorageFormats::PACKAGE )
+ {
+ uno::Reference< beans::XPropertySet > xProps( m_xPackageFolder, uno::UNO_QUERY_THROW );
+
+ if ( !m_bControlMediaType )
+ {
+ uno::Reference< beans::XPropertySet > xPackageProps( m_xPackage, uno::UNO_QUERY_THROW );
+ xPackageProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaTypeFallbackUsed" ) ) ) >>= m_bMTFallbackUsed;
+
+ xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ) ) >>= m_aMediaType;
+ m_bControlMediaType = sal_True;
+ }
+
+ if ( !m_bControlVersion )
+ {
+ xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= m_aVersion;
+ m_bControlVersion = sal_True;
+ }
+ }
+
+ // the properties of OFOPXML will be handled directly
+}
+
+//-----------------------------------------------
+void OStorage_Impl::ReadRelInfoIfNecessary()
+{
+ if ( m_nStorageType != embed::StorageFormats::OFOPXML )
+ return;
+
+ if ( m_nRelInfoStatus == RELINFO_NO_INIT )
+ {
+ // Init from original stream
+ uno::Reference< io::XInputStream > xRelInfoStream = GetRelInfoStreamForName( ::rtl::OUString() );
+ if ( xRelInfoStream.is() )
+ m_aRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
+ xRelInfoStream,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels/.rels" ) ),
+ m_xFactory );
+
+ m_nRelInfoStatus = RELINFO_READ;
+ }
+ else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
+ {
+ // Init from the new stream
+ try
+ {
+ if ( m_xNewRelInfoStream.is() )
+ m_aRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
+ m_xNewRelInfoStream,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels/.rels" ) ),
+ m_xFactory );
+
+ m_nRelInfoStatus = RELINFO_CHANGED_STREAM_READ;
+ }
+ catch( uno::Exception )
+ {
+ m_nRelInfoStatus = RELINFO_CHANGED_BROKEN;
+ }
+ }
+}
+
+//-----------------------------------------------
+void OStorage_Impl::ReadContents()
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( m_bListCreated )
+ return;
+
+ if ( m_bIsRoot )
+ OpenOwnPackage();
+
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xPackageFolder, uno::UNO_QUERY );
+ if ( !xEnumAccess.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration();
+ if ( !xEnum.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ m_bListCreated = sal_True;
+
+ while( xEnum->hasMoreElements() )
+ {
+ try {
+ uno::Reference< container::XNamed > xNamed;
+ xEnum->nextElement() >>= xNamed;
+
+ if ( !xNamed.is() )
+ {
+ OSL_ENSURE( sal_False, "XNamed is not supported!\n" );
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ ::rtl::OUString aName = xNamed->getName();
+ OSL_ENSURE( aName.getLength(), "Empty name!\n" );
+
+ uno::Reference< container::XNameContainer > xNameContainer( xNamed, uno::UNO_QUERY );
+
+ SotElement_Impl* pNewElement = new SotElement_Impl( aName, xNameContainer.is(), sal_False );
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML && aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
+ {
+ if ( !pNewElement->m_bIsStorage )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: Unexpected format
+
+ m_pRelStorElement = pNewElement;
+ CreateRelStorage();
+ }
+ else
+ {
+ if ( ( m_nStorageMode & embed::ElementModes::TRUNCATE ) == embed::ElementModes::TRUNCATE )
+ {
+ // if a storage is truncated all of it elements are marked as deleted
+ pNewElement->m_bIsRemoved = sal_True;
+ }
+
+ m_aChildrenList.push_back( pNewElement );
+ }
+ }
+ catch( container::NoSuchElementException& aNoSuchElementException )
+ {
+ AddLog( aNoSuchElementException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "NoSuchElement" ) ) );
+
+ OSL_ENSURE( sal_False, "hasMoreElements() implementation has problems!\n" );
+ break;
+ }
+ }
+ if ( ( m_nStorageMode & embed::ElementModes::TRUNCATE ) == embed::ElementModes::TRUNCATE )
+ {
+ // if a storage is truncated the relations information should be cleaned
+ m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
+ m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
+ m_nRelInfoStatus = RELINFO_CHANGED;
+ }
+
+ // cache changeable folder properties
+ GetStorageProperties();
+}
+
+//-----------------------------------------------
+void OStorage_Impl::CopyToStorage( const uno::Reference< embed::XStorage >& xDest, sal_Bool bDirect )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ uno::Reference< beans::XPropertySet > xPropSet( xDest, uno::UNO_QUERY );
+ if ( !xPropSet.is() )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ sal_Int32 nDestMode = embed::ElementModes::READ;
+ xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ) ) ) >>= nDestMode;
+
+ if ( !( nDestMode & embed::ElementModes::WRITE ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
+
+ ReadContents();
+
+ if ( !m_xPackageFolder.is() )
+ throw embed::InvalidStorageException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
+ pElementIter != m_aChildrenList.end(); pElementIter++ )
+ {
+ if ( !(*pElementIter)->m_bIsRemoved )
+ CopyStorageElement( *pElementIter, xDest, (*pElementIter)->m_aName, bDirect );
+ }
+
+ // move storage properties to the destination one ( means changeable properties )
+ if ( m_nStorageType == embed::StorageFormats::PACKAGE )
+ {
+ ::rtl::OUString aMediaTypeString = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
+ ::rtl::OUString aVersionString = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) );
+ xPropSet->setPropertyValue( aMediaTypeString, uno::makeAny( m_aMediaType ) );
+ xPropSet->setPropertyValue( aVersionString, uno::makeAny( m_aVersion ) );
+ }
+
+ if ( m_nStorageType == embed::StorageFormats::PACKAGE )
+ {
+ // if this is a root storage, the common key from current one should be moved there
+ sal_Bool bIsRoot = sal_False;
+ ::rtl::OUString aRootString = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsRoot" ) );
+ if ( ( xPropSet->getPropertyValue( aRootString ) >>= bIsRoot ) && bIsRoot )
+ {
+ try
+ {
+ ::rtl::OUString aCommonPass = GetCommonRootPass();
+ uno::Reference< embed::XEncryptionProtectedSource > xEncr( xDest, uno::UNO_QUERY );
+ if ( xEncr.is() )
+ xEncr->setEncryptionPassword( aCommonPass );
+ }
+ catch( packages::NoEncryptionException& aNoEncryptionException )
+ {
+ AddLog( aNoEncryptionException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No Encryption" ) ) );
+ }
+ }
+ }
+ else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+
+ // TODO/LATER: currently the optimization is not active
+ // uno::Reference< io::XInputStream > xRelInfoStream = GetRelInfoStreamForName( ::rtl::OUString() ); // own stream
+ // if ( xRelInfoStream.is() )
+ // {
+ // // Relations info stream is a writeonly property, introduced only to optimyze copying
+ // // Should be used carefuly since no check for stream consistency is done, and the stream must not stay locked
+ //
+ // ::rtl::OUString aRelInfoString = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RelationsInfoStream" ) );
+ // xPropSet->setPropertyValue( aRelInfoString, uno::makeAny( GetSeekableTempCopy( xRelInfoStream, m_xFactory ) ) );
+ // }
+
+ uno::Reference< embed::XRelationshipAccess > xRels( xDest, uno::UNO_QUERY );
+ if ( !xRels.is() )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ xRels->insertRelationships( GetAllRelationshipsIfAny(), sal_False );
+ }
+
+ // if possible the destination storage should be commited after successful copying
+ uno::Reference< embed::XTransactedObject > xObjToCommit( xDest, uno::UNO_QUERY );
+ if ( xObjToCommit.is() )
+ xObjToCommit->commit();
+}
+
+//-----------------------------------------------
+void OStorage_Impl::CopyStorageElement( SotElement_Impl* pElement,
+ uno::Reference< embed::XStorage > xDest,
+ ::rtl::OUString aName,
+ sal_Bool bDirect )
+{
+ OSL_ENSURE( xDest.is(), "No destination storage!\n" );
+ OSL_ENSURE( aName.getLength(), "Empty element name!\n" );
+
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ uno::Reference< container::XNameAccess > xDestAccess( xDest, uno::UNO_QUERY );
+ if ( !xDestAccess.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( xDestAccess->hasByName( aName )
+ && !( pElement->m_bIsStorage && xDest->isStorageElement( aName ) ) )
+ xDest->removeElement( aName );
+
+ if ( pElement->m_bIsStorage )
+ {
+ uno::Reference< embed::XStorage > xSubDest =
+ xDest->openStorageElement( aName,
+ embed::ElementModes::WRITE );
+
+ OSL_ENSURE( xSubDest.is(), "No destination substorage!\n" );
+
+ if ( !pElement->m_pStorage )
+ {
+ OpenSubStorage( pElement, embed::ElementModes::READ );
+ if ( !pElement->m_pStorage )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ pElement->m_pStorage->CopyToStorage( xSubDest, bDirect );
+ }
+ else
+ {
+ if ( !pElement->m_pStream )
+ {
+ OpenSubStream( pElement );
+ if ( !pElement->m_pStream )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !pElement->m_pStream->IsEncrypted() )
+ {
+ if ( bDirect )
+ {
+ // fill in the properties for the stream
+ uno::Sequence< beans::PropertyValue > aStrProps(0);
+ uno::Sequence< beans::PropertyValue > aSrcPkgProps = pElement->m_pStream->GetStreamProperties();
+ sal_Int32 nNum = 0;
+ for ( int ind = 0; ind < aSrcPkgProps.getLength(); ind++ )
+ {
+ if ( aSrcPkgProps[ind].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) ) )
+ || aSrcPkgProps[ind].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "Compressed" ) ) ) )
+ {
+ aStrProps.realloc( ++nNum );
+ aStrProps[nNum-1].Name = aSrcPkgProps[ind].Name;
+ aStrProps[nNum-1].Value = aSrcPkgProps[ind].Value;
+ }
+ }
+
+ if ( m_nStorageType == embed::StorageFormats::PACKAGE )
+ {
+ aStrProps.realloc( ++nNum );
+ aStrProps[nNum-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
+ aStrProps[nNum-1].Value <<= (sal_Bool)( pElement->m_pStream->UsesCommonPass_Impl() );
+ }
+ else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ // TODO/LATER: currently the optimization is not active
+ // uno::Reference< io::XInputStream > xInStream = GetRelInfoStreamForName( ::rtl::OUString() ); // own rels stream
+ // if ( xInStream.is() )
+ // {
+ // aStrProps.realloc( ++nNum );
+ // aStrProps[nNum-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RelationsInfoStream" ) );
+ // aStrProps[nNum-1].Value <<= GetSeekableTempCopy( xInStream, m_xFactory );
+ // }
+
+ uno::Reference< embed::XRelationshipAccess > xRels( xDest, uno::UNO_QUERY );
+ if ( !xRels.is() )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
+
+ xRels->insertRelationships( GetAllRelationshipsIfAny(), sal_False );
+ }
+
+ uno::Reference< embed::XOptimizedStorage > xOptDest( xDest, uno::UNO_QUERY_THROW );
+ uno::Reference < io::XInputStream > xInputToInsert;
+
+ if ( pElement->m_pStream->HasTempFile_Impl() || !pElement->m_pStream->m_xPackageStream.is() )
+ {
+ OSL_ENSURE( pElement->m_pStream->m_xPackageStream.is(), "No package stream!" );
+
+ // if the stream is modified - the temporary file must be used for insertion
+ xInputToInsert = pElement->m_pStream->GetTempFileAsInputStream();
+ }
+ else
+ {
+ // for now get just nonseekable access to the stream
+ // TODO/LATER: the raw stream can be used
+
+ xInputToInsert = pElement->m_pStream->m_xPackageStream->getDataStream();
+ }
+
+ if ( !xInputToInsert.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ xOptDest->insertStreamElementDirect( aName, xInputToInsert, aStrProps );
+ }
+ else
+ {
+ uno::Reference< io::XStream > xSubStr =
+ xDest->openStreamElement( aName,
+ embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
+ OSL_ENSURE( xSubStr.is(), "No destination substream!\n" );
+
+ pElement->m_pStream->CopyInternallyTo_Impl( xSubStr );
+ }
+ }
+ else if ( m_nStorageType != embed::StorageFormats::PACKAGE )
+ {
+ OSL_ENSURE( sal_False, "Encryption is only supported in package storage!\n" );
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+ else if ( pElement->m_pStream->HasCachedPassword()
+ && ( pElement->m_pStream->IsModified() || pElement->m_pStream->HasWriteOwner_Impl() ) )
+ {
+ ::rtl::OUString aCommonPass;
+ sal_Bool bHasCommonPass = sal_False;
+ try
+ {
+ aCommonPass = GetCommonRootPass();
+ bHasCommonPass = sal_True;
+ }
+ catch( packages::NoEncryptionException& aNoEncryptionException )
+ {
+ AddLog( aNoEncryptionException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No Encryption" ) ) );
+ }
+
+ if ( bHasCommonPass && pElement->m_pStream->GetCachedPassword().equals( aCommonPass ) )
+ {
+ // If the stream can be opened with the common storage password
+ // it must be stored with the common storage password as well
+ uno::Reference< io::XStream > xDestStream =
+ xDest->openStreamElement( aName,
+ embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
+
+ pElement->m_pStream->CopyInternallyTo_Impl( xDestStream );
+
+ uno::Reference< beans::XPropertySet > xProps( xDestStream, uno::UNO_QUERY_THROW );
+ xProps->setPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ),
+ uno::Any( (sal_Bool) sal_True ) );
+ }
+ else
+ {
+ // the stream is already opened for writing or was changed
+ uno::Reference< io::XStream > xSubStr =
+ xDest->openEncryptedStreamElement( aName,
+ embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE,
+ pElement->m_pStream->GetCachedPassword() );
+ OSL_ENSURE( xSubStr.is(), "No destination substream!\n" );
+
+ pElement->m_pStream->CopyInternallyTo_Impl( xSubStr, pElement->m_pStream->GetCachedPassword() );
+ }
+ }
+ else
+ {
+ // the stream is not opened at all, so it can be just opened for reading
+ try
+ {
+ // If the stream can be opened with the common storage password
+ // it must be stored with the common storage password as well
+
+ uno::Reference< io::XStream > xOwnStream = pElement->m_pStream->GetStream( embed::ElementModes::READ,
+ sal_False );
+ uno::Reference< io::XStream > xDestStream =
+ xDest->openStreamElement( aName,
+ embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
+ OSL_ENSURE( xDestStream.is(), "No destination substream!\n" );
+ completeStorageStreamCopy_Impl( xOwnStream, xDestStream, m_nStorageType, GetAllRelationshipsIfAny() );
+
+ uno::Reference< beans::XPropertySet > xProps( xDestStream, uno::UNO_QUERY_THROW );
+ xProps->setPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ),
+ uno::Any( (sal_Bool) sal_True ) );
+ }
+ catch( packages::WrongPasswordException& aWrongPasswordException )
+ {
+ AddLog( aWrongPasswordException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Handled exception" ) ) );
+
+ // If the common storage password does not allow to open the stream
+ // it must be copyed in raw way
+ uno::Reference< embed::XStorageRawAccess > xRawDest( xDest, uno::UNO_QUERY_THROW );
+ uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetRawInStream();
+ xRawDest->insertRawEncrStreamElement( aName, xRawInStream );
+ }
+ }
+ }
+}
+
+//-----------------------------------------------
+uno::Sequence< uno::Sequence< beans::StringPair > > OStorage_Impl::GetAllRelationshipsIfAny()
+{
+ if ( m_nStorageType != embed::StorageFormats::OFOPXML )
+ return uno::Sequence< uno::Sequence< beans::StringPair > >();
+
+ ReadRelInfoIfNecessary();
+
+ if ( m_nRelInfoStatus == RELINFO_READ
+ || m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ || m_nRelInfoStatus == RELINFO_CHANGED )
+ return m_aRelInfo;
+ else // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong relinfo stream!" ) ),
+ uno::Reference< uno::XInterface >() );
+}
+
+//-----------------------------------------------
+void OStorage_Impl::CopyLastCommitTo( const uno::Reference< embed::XStorage >& xNewStor )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ OSL_ENSURE( m_xPackageFolder.is(), "A commited storage is incomplete!\n" );
+ if ( !m_xPackageFolder.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ OStorage_Impl aTempRepresent( NULL,
+ embed::ElementModes::READ,
+ m_xPackageFolder,
+ m_xPackage,
+ m_xFactory,
+ m_nStorageType);
+
+ // TODO/LATER: could use direct copying
+ aTempRepresent.CopyToStorage( xNewStor, sal_False );
+}
+
+//-----------------------------------------------
+void OStorage_Impl::InsertIntoPackageFolder( const ::rtl::OUString& aName,
+ const uno::Reference< container::XNameContainer >& xParentPackageFolder )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ OSL_ENSURE( m_xPackageFolder.is(), "An inserted storage is incomplete!\n" );
+ uno::Reference< lang::XUnoTunnel > xTunnel( m_xPackageFolder, uno::UNO_QUERY );
+ if ( !xTunnel.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ xParentPackageFolder->insertByName( aName, uno::makeAny( xTunnel ) );
+
+ m_bCommited = sal_False;
+}
+
+//-----------------------------------------------
+void OStorage_Impl::Commit()
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( !m_bIsModified )
+ return;
+
+ // in case of a new empty storage it is possible that the contents are still not read
+ // ( the storage of course has no contents, but the initialization is postponed till the first use,
+ // thus if a new storage was created and commited immediatelly it must be initialized here )
+ ReadContents();
+
+ // if storage is commited it should have a valid Package representation
+ OSL_ENSURE( m_xPackageFolder.is(), "The package representation should exist!\n" );
+ if ( !m_xPackageFolder.is() )
+ throw embed::InvalidStorageException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ OSL_ENSURE( m_nStorageMode & embed::ElementModes::WRITE,
+ "Commit of readonly storage, should be detected before!\n" );
+
+ uno::Reference< container::XNameContainer > xNewPackageFolder;
+
+ // here the storage will switch to the temporary package folder
+ // if the storage was already commited and the parent was not commited after that
+ // the switch should not be done since the package folder in use is a temporary one;
+ // it can be detected by m_bCommited flag ( root storage doesn't need temporary representation )
+ if ( !m_bCommited && !m_bIsRoot )
+ {
+ uno::Sequence< uno::Any > aSeq( 1 );
+ aSeq[0] <<= sal_True;
+
+ xNewPackageFolder = uno::Reference< container::XNameContainer >(
+ m_xPackage->createInstanceWithArguments( aSeq ),
+ uno::UNO_QUERY );
+ }
+ else
+ xNewPackageFolder = m_xPackageFolder;
+
+ // remove replaced removed elements
+ for ( SotElementList_Impl::iterator pDeletedIter = m_aDeletedList.begin();
+ pDeletedIter != m_aDeletedList.end();
+ pDeletedIter++ )
+ {
+
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML && !(*pDeletedIter)->m_bIsStorage )
+ RemoveStreamRelInfo( (*pDeletedIter)->m_aOriginalName );
+
+ // the removed elements are not in new temporary storage
+ if ( m_bCommited || m_bIsRoot )
+ xNewPackageFolder->removeByName( (*pDeletedIter)->m_aOriginalName );
+ delete *pDeletedIter;
+ *pDeletedIter = NULL;
+ }
+ m_aDeletedList.clear();
+
+ // remove removed elements
+ SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
+ while ( pElementIter != m_aChildrenList.end() )
+ {
+ // renamed and inserted elements must be really inserted to package later
+ // since thay can conflict with removed elements
+
+ if ( (*pElementIter)->m_bIsRemoved )
+ {
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML && !(*pElementIter)->m_bIsStorage )
+ RemoveStreamRelInfo( (*pElementIter)->m_aOriginalName );
+
+ // the removed elements are not in new temporary storage
+ if ( m_bCommited || m_bIsRoot )
+ xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
+
+ SotElement_Impl* pToDelete = *pElementIter;
+
+ pElementIter++; // to let the iterator be valid it should be increased before removing
+
+ m_aChildrenList.remove( pToDelete );
+ delete pToDelete;
+ }
+ else
+ pElementIter++;
+ }
+
+ // there should be no more deleted elements
+ for ( pElementIter = m_aChildrenList.begin(); pElementIter != m_aChildrenList.end(); pElementIter++ )
+ {
+ // if it is a 'duplicate commit' inserted elements must be really inserted to package later
+ // since thay can conflict with renamed elements
+
+ if ( !(*pElementIter)->m_bIsInserted )
+ {
+ // for now stream is opened in direct mode that means that in case
+ // storage is commited all the streams from it are commited in current state.
+ // following two steps are separated to allow easily implement transacted mode
+ // for streams if we need it in future.
+ // Only hierarchical access uses transacted streams currently
+ if ( !(*pElementIter)->m_bIsStorage && (*pElementIter)->m_pStream
+ && !(*pElementIter)->m_pStream->IsTransacted() )
+ (*pElementIter)->m_pStream->Commit();
+
+ // if the storage was not open, there is no need to commit it ???
+ // the storage should be checked that it is commited
+ if ( (*pElementIter)->m_bIsStorage && (*pElementIter)->m_pStorage && (*pElementIter)->m_pStorage->m_bCommited )
+ {
+ // it's temporary PackageFolder should be inserted instead of current one
+ // also the new copy of PackageFolder should be used by the children storages
+
+ // the renamed elements are not in new temporary storage
+ if ( m_bCommited || m_bIsRoot )
+ xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
+
+ (*pElementIter)->m_pStorage->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
+ }
+ else if ( !(*pElementIter)->m_bIsStorage && (*pElementIter)->m_pStream && (*pElementIter)->m_pStream->m_bFlushed )
+ {
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML )
+ CommitStreamRelInfo( *pElementIter );
+
+ // the renamed elements are not in new temporary storage
+ if ( m_bCommited || m_bIsRoot )
+ xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
+
+ (*pElementIter)->m_pStream->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
+ }
+ else if ( !m_bCommited && !m_bIsRoot )
+ {
+ // the element must be just copied to the new temporary package folder
+ // the connection with the original package should not be lost just because
+ // the element is still refered by the folder in the original hierarchy
+ uno::Any aPackageElement = m_xPackageFolder->getByName( (*pElementIter)->m_aOriginalName );
+ xNewPackageFolder->insertByName( (*pElementIter)->m_aName, aPackageElement );
+ }
+ else if ( (*pElementIter)->m_aName.compareTo( (*pElementIter)->m_aOriginalName ) )
+ {
+ // this is the case when xNewPackageFolder refers to m_xPackageFolder
+ // in case the name was changed and it is not a changed storage - rename the element
+ uno::Reference< container::XNamed > xNamed;
+ uno::Any aPackageElement = xNewPackageFolder->getByName( (*pElementIter)->m_aOriginalName );
+ xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
+ xNewPackageFolder->insertByName( (*pElementIter)->m_aName, aPackageElement );
+
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML && !(*pElementIter)->m_bIsStorage )
+ {
+ if ( !(*pElementIter)->m_pStream )
+ {
+ OpenSubStream( *pElementIter );
+ if ( !(*pElementIter)->m_pStream )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ CommitStreamRelInfo( *pElementIter );
+ }
+ }
+
+ (*pElementIter)->m_aOriginalName = (*pElementIter)->m_aName;
+ }
+ }
+
+ for ( pElementIter = m_aChildrenList.begin(); pElementIter != m_aChildrenList.end(); pElementIter++ )
+ {
+ // now inserted elements can be inserted to the package
+ if ( (*pElementIter)->m_bIsInserted )
+ {
+ (*pElementIter)->m_aOriginalName = (*pElementIter)->m_aName;
+ uno::Reference< lang::XUnoTunnel > xNewElement;
+
+ if ( (*pElementIter)->m_bIsStorage )
+ {
+ if ( (*pElementIter)->m_pStorage->m_bCommited )
+ {
+ OSL_ENSURE( (*pElementIter)->m_pStorage, "An inserted storage is incomplete!\n" );
+ if ( !(*pElementIter)->m_pStorage )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ (*pElementIter)->m_pStorage->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
+
+ (*pElementIter)->m_bIsInserted = sal_False;
+ }
+ }
+ else
+ {
+ OSL_ENSURE( (*pElementIter)->m_pStream, "An inserted stream is incomplete!\n" );
+ if ( !(*pElementIter)->m_pStream )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !(*pElementIter)->m_pStream->IsTransacted() )
+ (*pElementIter)->m_pStream->Commit();
+
+ if ( (*pElementIter)->m_pStream->m_bFlushed )
+ {
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML )
+ CommitStreamRelInfo( *pElementIter );
+
+ (*pElementIter)->m_pStream->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
+
+ (*pElementIter)->m_bIsInserted = sal_False;
+ }
+ }
+ }
+ }
+
+ if ( m_nStorageType == embed::StorageFormats::PACKAGE )
+ {
+ // move properties to the destination package folder
+ uno::Reference< beans::XPropertySet > xProps( xNewPackageFolder, uno::UNO_QUERY );
+ if ( !xProps.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ xProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ), uno::makeAny( m_aMediaType ) );
+ xProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ), uno::makeAny( m_aVersion ) );
+ }
+
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML )
+ CommitRelInfo( xNewPackageFolder ); // store own relations and commit complete relations storage
+
+ if ( m_bIsRoot )
+ {
+ uno::Reference< util::XChangesBatch > xChangesBatch( m_xPackage, uno::UNO_QUERY );
+
+ OSL_ENSURE( xChangesBatch.is(), "Impossible to commit package!\n" );
+ if ( !xChangesBatch.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ try
+ {
+ xChangesBatch->commitChanges();
+ }
+ catch( lang::WrappedTargetException& r )
+ {
+ // the wrapped UseBackupException means that the target medium can be corrupted
+ embed::UseBackupException aException;
+ if ( r.TargetException >>= aException )
+ {
+ m_xStream = uno::Reference< io::XStream >();
+ m_xInputStream = uno::Reference< io::XInputStream >();
+ throw aException;
+ }
+
+ AddLog( aException.Message );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ }
+ else if ( !m_bCommited )
+ {
+ m_xPackageFolder = xNewPackageFolder;
+ m_bCommited = sal_True;
+ }
+
+ // after commit the mediatype treated as the correct one
+ m_bMTFallbackUsed = sal_False;
+}
+
+//-----------------------------------------------
+void OStorage_Impl::Revert()
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( !( m_nStorageMode & embed::ElementModes::WRITE ) )
+ return; // nothing to do
+
+ // all the children must be removed
+ // they will be created later on demand
+
+ SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
+ while ( pElementIter != m_aChildrenList.end() )
+ {
+ if ( (*pElementIter)->m_bIsInserted )
+ {
+ SotElement_Impl* pToDelete = *pElementIter;
+
+ pElementIter++; // to let the iterator be valid it should be increased before removing
+
+ m_aChildrenList.remove( pToDelete );
+ delete pToDelete;
+ }
+ else
+ {
+ ClearElement( *pElementIter );
+
+ (*pElementIter)->m_aName = (*pElementIter)->m_aOriginalName;
+ (*pElementIter)->m_bIsRemoved = sal_False;
+
+ pElementIter++;
+ }
+ }
+
+ // return replaced removed elements
+ for ( SotElementList_Impl::iterator pDeletedIter = m_aDeletedList.begin();
+ pDeletedIter != m_aDeletedList.end();
+ pDeletedIter++ )
+ {
+ m_aChildrenList.push_back( (*pDeletedIter) );
+
+ ClearElement( *pDeletedIter );
+
+ (*pDeletedIter)->m_aName = (*pDeletedIter)->m_aOriginalName;
+ (*pDeletedIter)->m_bIsRemoved = sal_False;
+ }
+ m_aDeletedList.clear();
+
+ m_bControlMediaType = sal_False;
+ m_bControlVersion = sal_False;
+
+ GetStorageProperties();
+
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ // currently the relations storage is changed only on commit
+ m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
+ m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
+ m_nRelInfoStatus = RELINFO_NO_INIT;
+ }
+}
+
+//-----------------------------------------------
+::rtl::OUString OStorage_Impl::GetCommonRootPass()
+ throw ( packages::NoEncryptionException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
+
+ if ( m_nStorageType != embed::StorageFormats::PACKAGE )
+ throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( m_bIsRoot )
+ {
+ if ( !m_bHasCommonPassword )
+ throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return m_aCommonPassword;
+ }
+ else
+ {
+ if ( !m_pParent )
+ throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return m_pParent->GetCommonRootPass();
+ }
+}
+
+//-----------------------------------------------
+SotElement_Impl* OStorage_Impl::FindElement( const ::rtl::OUString& rName )
+{
+ OSL_ENSURE( rName.getLength(), "Name is empty!" );
+
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ ReadContents();
+
+ for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
+ pElementIter != m_aChildrenList.end(); pElementIter++ )
+ {
+ if ( (*pElementIter)->m_aName == rName && !(*pElementIter)->m_bIsRemoved )
+ return *pElementIter;
+ }
+
+ return NULL;
+}
+
+//-----------------------------------------------
+SotElement_Impl* OStorage_Impl::InsertStream( ::rtl::OUString aName, sal_Bool bEncr )
+{
+ OSL_ENSURE( m_xPackage.is(), "Not possible to refer to package as to factory!\n" );
+ if ( !m_xPackage.is() )
+ throw embed::InvalidStorageException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Sequence< uno::Any > aSeq( 1 );
+ aSeq[0] <<= sal_False;
+ uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE( xNewElement.is(), "Not possible to create a new stream!\n" );
+ if ( !xNewElement.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xNewElement, uno::UNO_QUERY );
+ if ( !xPackageSubStream.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ OSL_ENSURE( m_nStorageType == embed::StorageFormats::PACKAGE || !bEncr, "Only package storage supports encryption!\n" );
+ if ( m_nStorageType != embed::StorageFormats::PACKAGE && bEncr )
+ throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // the mode is not needed for storage stream internal implementation
+ SotElement_Impl* pNewElement = InsertElement( aName, sal_False );
+ pNewElement->m_pStream = new OWriteStream_Impl( this, xPackageSubStream, m_xPackage, m_xFactory, bEncr, m_nStorageType, sal_True );
+
+ m_aChildrenList.push_back( pNewElement );
+ m_bIsModified = sal_True;
+ m_bBroadcastModified = sal_True;
+
+ return pNewElement;
+}
+
+//-----------------------------------------------
+SotElement_Impl* OStorage_Impl::InsertRawStream( ::rtl::OUString aName, const uno::Reference< io::XInputStream >& xInStream )
+{
+ // insert of raw stream means insert and commit
+ OSL_ENSURE( m_xPackage.is(), "Not possible to refer to package as to factory!\n" );
+ if ( !m_xPackage.is() )
+ throw embed::InvalidStorageException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( m_nStorageType != embed::StorageFormats::PACKAGE )
+ throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< io::XSeekable > xSeek( xInStream, uno::UNO_QUERY );
+ uno::Reference< io::XInputStream > xInStrToInsert = xSeek.is() ? xInStream :
+ GetSeekableTempCopy( xInStream, GetServiceFactory() );
+
+ uno::Sequence< uno::Any > aSeq( 1 );
+ aSeq[0] <<= sal_False;
+ uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE( xNewElement.is(), "Not possible to create a new stream!\n" );
+ if ( !xNewElement.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xNewElement, uno::UNO_QUERY );
+ if ( !xPackageSubStream.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ xPackageSubStream->setRawStream( xInStrToInsert );
+
+ // the mode is not needed for storage stream internal implementation
+ SotElement_Impl* pNewElement = InsertElement( aName, sal_False );
+ pNewElement->m_pStream = new OWriteStream_Impl( this, xPackageSubStream, m_xPackage, m_xFactory, sal_True, m_nStorageType, sal_False );
+ // the stream is inserted and must be treated as a commited one
+ pNewElement->m_pStream->SetToBeCommited();
+
+ m_aChildrenList.push_back( pNewElement );
+ m_bIsModified = sal_True;
+ m_bBroadcastModified = sal_True;
+
+ return pNewElement;
+}
+
+//-----------------------------------------------
+OStorage_Impl* OStorage_Impl::CreateNewStorageImpl( sal_Int32 nStorageMode )
+{
+ OSL_ENSURE( m_xPackage.is(), "Not possible to refer to package as to factory!\n" );
+ if ( !m_xPackage.is() )
+ throw embed::InvalidStorageException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Sequence< uno::Any > aSeq( 1 );
+ aSeq[0] <<= sal_True;
+ uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE( xNewElement.is(), "Not possible to create a new storage!\n" );
+ if ( !xNewElement.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< container::XNameContainer > xPackageSubFolder( xNewElement, uno::UNO_QUERY );
+ if ( !xPackageSubFolder.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ OStorage_Impl* pResult =
+ new OStorage_Impl( this, nStorageMode, xPackageSubFolder, m_xPackage, m_xFactory, m_nStorageType );
+ pResult->m_bIsModified = sal_True;
+
+ return pResult;
+}
+
+//-----------------------------------------------
+SotElement_Impl* OStorage_Impl::InsertStorage( ::rtl::OUString aName, sal_Int32 nStorageMode )
+{
+ SotElement_Impl* pNewElement = InsertElement( aName, sal_True );
+
+ pNewElement->m_pStorage = CreateNewStorageImpl( nStorageMode );
+
+ m_aChildrenList.push_back( pNewElement );
+
+ return pNewElement;
+}
+
+//-----------------------------------------------
+SotElement_Impl* OStorage_Impl::InsertElement( ::rtl::OUString aName, sal_Bool bIsStorage )
+{
+ OSL_ENSURE( FindElement( aName ) == NULL, "Should not try to insert existing element" );
+
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ SotElement_Impl* pDeletedElm = NULL;
+
+ for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
+ pElementIter != m_aChildrenList.end(); pElementIter++ )
+ {
+ if ( (*pElementIter)->m_aName == aName )
+ {
+ OSL_ENSURE( (*pElementIter)->m_bIsRemoved, "Try to insert an element instead of existing one!\n" );
+ if ( (*pElementIter)->m_bIsRemoved )
+ {
+ OSL_ENSURE( !(*pElementIter)->m_bIsInserted, "Inserted elements must be deleted immediatelly!\n" );
+ pDeletedElm = *pElementIter;
+ break;
+ }
+ }
+ }
+
+ if ( pDeletedElm )
+ {
+ if ( pDeletedElm->m_bIsStorage )
+ OpenSubStorage( pDeletedElm, embed::ElementModes::READWRITE );
+ else
+ OpenSubStream( pDeletedElm );
+
+ m_aChildrenList.remove( pDeletedElm ); // correct usage of list ???
+ m_aDeletedList.push_back( pDeletedElm );
+ }
+
+ // create new element
+ return new SotElement_Impl( aName, bIsStorage, sal_True );
+}
+
+//-----------------------------------------------
+void OStorage_Impl::OpenSubStorage( SotElement_Impl* pElement, sal_Int32 nStorageMode )
+{
+ OSL_ENSURE( pElement, "pElement is not set!\n" );
+ OSL_ENSURE( pElement->m_bIsStorage, "Storage flag is not set!\n" );
+
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( !pElement->m_pStorage )
+ {
+ OSL_ENSURE( !pElement->m_bIsInserted, "Inserted element must be created already!\n" );
+
+ uno::Reference< lang::XUnoTunnel > xTunnel;
+ m_xPackageFolder->getByName( pElement->m_aOriginalName ) >>= xTunnel;
+ if ( !xTunnel.is() )
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< container::XNameContainer > xPackageSubFolder( xTunnel, uno::UNO_QUERY );
+
+ OSL_ENSURE( xPackageSubFolder.is(), "Can not get XNameContainer interface from folder!\n" );
+
+ if ( !xPackageSubFolder.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ pElement->m_pStorage = new OStorage_Impl( this, nStorageMode, xPackageSubFolder, m_xPackage, m_xFactory, m_nStorageType );
+ }
+}
+
+//-----------------------------------------------
+void OStorage_Impl::OpenSubStream( SotElement_Impl* pElement )
+{
+ OSL_ENSURE( pElement, "pElement is not set!\n" );
+ OSL_ENSURE( !pElement->m_bIsStorage, "Storage flag is set!\n" );
+
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( !pElement->m_pStream )
+ {
+ OSL_ENSURE( !pElement->m_bIsInserted, "Inserted element must be created already!\n" );
+
+ uno::Reference< lang::XUnoTunnel > xTunnel;
+ m_xPackageFolder->getByName( pElement->m_aOriginalName ) >>= xTunnel;
+ if ( !xTunnel.is() )
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xTunnel, uno::UNO_QUERY );
+ if ( !xPackageSubStream.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // the stream can never be inserted here, because inserted stream element holds the stream till commit or destruction
+ pElement->m_pStream = new OWriteStream_Impl( this, xPackageSubStream, m_xPackage, m_xFactory, sal_False, m_nStorageType, sal_False, GetRelInfoStreamForName( pElement->m_aOriginalName ) );
+ }
+}
+
+//-----------------------------------------------
+uno::Sequence< ::rtl::OUString > OStorage_Impl::GetElementNames()
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ ReadContents();
+
+ sal_uInt32 nSize = m_aChildrenList.size();
+ uno::Sequence< ::rtl::OUString > aElementNames( nSize );
+
+ sal_uInt32 nInd = 0;
+ for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
+ pElementIter != m_aChildrenList.end(); pElementIter++ )
+ {
+ if ( !(*pElementIter)->m_bIsRemoved )
+ aElementNames[nInd++] = (*pElementIter)->m_aName;
+ }
+
+ aElementNames.realloc( nInd );
+ return aElementNames;
+}
+
+//-----------------------------------------------
+void OStorage_Impl::RemoveElement( SotElement_Impl* pElement )
+{
+ OSL_ENSURE( pElement, "Element must be provided!" );
+
+ if ( !pElement )
+ return;
+
+ if ( (pElement->m_pStorage && ( pElement->m_pStorage->m_pAntiImpl || !pElement->m_pStorage->m_aReadOnlyWrapList.empty() ))
+ || (pElement->m_pStream && ( pElement->m_pStream->m_pAntiImpl || !pElement->m_pStream->m_aInputStreamsList.empty() )) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: Access denied
+
+ if ( pElement->m_bIsInserted )
+ {
+ m_aChildrenList.remove( pElement );
+ delete pElement; // ???
+ }
+ else
+ {
+ pElement->m_bIsRemoved = sal_True;
+ ClearElement( pElement );
+ }
+
+ // TODO/OFOPXML: the rel stream should be removed as well
+}
+
+//-----------------------------------------------
+void OStorage_Impl::ClearElement( SotElement_Impl* pElement )
+{
+ if ( pElement->m_pStorage )
+ {
+ delete pElement->m_pStorage;
+ pElement->m_pStorage = NULL;
+ }
+
+ if ( pElement->m_pStream )
+ {
+ delete pElement->m_pStream;
+ pElement->m_pStream = NULL;
+ }
+}
+
+//-----------------------------------------------
+void OStorage_Impl::CloneStreamElement( const ::rtl::OUString& aStreamName,
+ sal_Bool bPassProvided,
+ const ::rtl::OUString& aPass,
+ uno::Reference< io::XStream >& xTargetStream )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ SotElement_Impl *pElement = FindElement( aStreamName );
+ if ( !pElement )
+ {
+ // element does not exist, throw exception
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
+ }
+ else if ( pElement->m_bIsStorage )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !pElement->m_pStream )
+ OpenSubStream( pElement );
+
+ if ( pElement->m_pStream && pElement->m_pStream->m_xPackageStream.is() )
+ {
+ // the existence of m_pAntiImpl of the child is not interesting,
+ // the copy will be created internally
+
+ // usual copying is not applicable here, only last flushed version of the
+ // child stream should be used for copiing. Probably the childs m_xPackageStream
+ // can be used as a base of a new stream, that would be copied to result
+ // storage. The only problem is that some package streams can be accessed from outside
+ // at the same time ( now solwed by wrappers that remember own position ).
+
+ if ( bPassProvided )
+ pElement->m_pStream->GetCopyOfLastCommit( xTargetStream, aPass );
+ else
+ pElement->m_pStream->GetCopyOfLastCommit( xTargetStream );
+ }
+ else
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: general_error
+}
+
+//-----------------------------------------------
+void OStorage_Impl::RemoveStreamRelInfo( const ::rtl::OUString& aOriginalName )
+{
+ // this method should be used only in OStorage_Impl::Commit() method
+ // the aOriginalName can be empty, in this case the storage relation info should be removed
+
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML && m_xRelStorage.is() )
+ {
+ ::rtl::OUString aRelStreamName = aOriginalName;
+ aRelStreamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) );
+
+ if ( m_xRelStorage->hasByName( aRelStreamName ) )
+ m_xRelStorage->removeElement( aRelStreamName );
+ }
+}
+
+//-----------------------------------------------
+void OStorage_Impl::CreateRelStorage()
+{
+ if ( m_nStorageType != embed::StorageFormats::OFOPXML )
+ return;
+
+ if ( !m_xRelStorage.is() )
+ {
+ if ( !m_pRelStorElement )
+ {
+ m_pRelStorElement = new SotElement_Impl( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ), sal_True, sal_True );
+ m_pRelStorElement->m_pStorage = CreateNewStorageImpl( embed::ElementModes::WRITE );
+ if ( m_pRelStorElement->m_pStorage )
+ m_pRelStorElement->m_pStorage->m_pParent = NULL; // the relation storage is completely controlled by parent
+ }
+
+ if ( !m_pRelStorElement->m_pStorage )
+ OpenSubStorage( m_pRelStorElement, embed::ElementModes::WRITE );
+
+ if ( !m_pRelStorElement->m_pStorage )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ OStorage* pResultStorage = new OStorage( m_pRelStorElement->m_pStorage, sal_False );
+ m_xRelStorage = uno::Reference< embed::XStorage >( (embed::XStorage*) pResultStorage );
+ }
+}
+
+//-----------------------------------------------
+void OStorage_Impl::CommitStreamRelInfo( SotElement_Impl* pStreamElement )
+{
+ // this method should be used only in OStorage_Impl::Commit() method
+
+ // the stream element must be provided
+ if ( !pStreamElement )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML && pStreamElement->m_pStream )
+ {
+ OSL_ENSURE( pStreamElement->m_aName.getLength(), "The name must not be empty!\n" );
+
+ if ( !m_xRelStorage.is() )
+ {
+ // Create new rels storage, this is commit scenario so it must be possible
+ CreateRelStorage();
+ }
+
+ pStreamElement->m_pStream->CommitStreamRelInfo( m_xRelStorage, pStreamElement->m_aOriginalName, pStreamElement->m_aName );
+ }
+}
+
+//-----------------------------------------------
+uno::Reference< io::XInputStream > OStorage_Impl::GetRelInfoStreamForName( const ::rtl::OUString& aName )
+{
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ ReadContents();
+ if ( m_xRelStorage.is() )
+ {
+ ::rtl::OUString aRelStreamName = aName;
+ aRelStreamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) );
+ if ( m_xRelStorage->hasByName( aRelStreamName ) )
+ {
+ uno::Reference< io::XStream > xStream = m_xRelStorage->openStreamElement( aRelStreamName, embed::ElementModes::READ );
+ if ( xStream.is() )
+ return xStream->getInputStream();
+ }
+ }
+ }
+
+ return uno::Reference< io::XInputStream >();
+}
+
+//-----------------------------------------------
+void OStorage_Impl::CommitRelInfo( const uno::Reference< container::XNameContainer >& xNewPackageFolder )
+{
+ // this method should be used only in OStorage_Impl::Commit() method
+ ::rtl::OUString aRelsStorName( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) );
+
+ if ( !xNewPackageFolder.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ if ( m_nRelInfoStatus == RELINFO_BROKEN || m_nRelInfoStatus == RELINFO_CHANGED_BROKEN )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( m_nRelInfoStatus == RELINFO_CHANGED
+ || m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
+ || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
+ {
+ if ( m_nRelInfoStatus == RELINFO_CHANGED )
+ {
+ if ( m_aRelInfo.getLength() )
+ {
+ CreateRelStorage();
+
+ uno::Reference< io::XStream > xRelsStream =
+ m_xRelStorage->openStreamElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) ),
+ embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
+
+ uno::Reference< io::XOutputStream > xOutStream = xRelsStream->getOutputStream();
+ if ( !xOutStream.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ ::comphelper::OFOPXMLHelper::WriteRelationsInfoSequence( xOutStream, m_aRelInfo, m_xFactory );
+
+ // set the mediatype
+ uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
+ xPropSet->setPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
+ uno::makeAny( ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) );
+
+ m_nRelInfoStatus = RELINFO_READ;
+ }
+ else if ( m_xRelStorage.is() )
+ RemoveStreamRelInfo( ::rtl::OUString() ); // remove own rel info
+ }
+ else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
+ || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
+ {
+ CreateRelStorage();
+
+ uno::Reference< io::XStream > xRelsStream =
+ m_xRelStorage->openStreamElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) ),
+ embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
+
+ uno::Reference< io::XOutputStream > xOutputStream = xRelsStream->getOutputStream();
+ if ( !xOutputStream.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< io::XSeekable > xSeek( m_xNewRelInfoStream, uno::UNO_QUERY_THROW );
+ xSeek->seek( 0 );
+ ::comphelper::OStorageHelper::CopyInputToOutput( m_xNewRelInfoStream, xOutputStream );
+
+ // set the mediatype
+ uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
+ xPropSet->setPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
+ uno::makeAny( ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) );
+
+ m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
+ if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
+ {
+ m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
+ m_nRelInfoStatus = RELINFO_NO_INIT;
+ }
+ else
+ m_nRelInfoStatus = RELINFO_READ;
+ }
+ }
+
+ if ( m_xRelStorage.is() )
+ {
+ if ( m_xRelStorage->hasElements() )
+ {
+ uno::Reference< embed::XTransactedObject > xTrans( m_xRelStorage, uno::UNO_QUERY_THROW );
+ if ( xTrans.is() )
+ xTrans->commit();
+ }
+
+ if ( xNewPackageFolder.is() && xNewPackageFolder->hasByName( aRelsStorName ) )
+ xNewPackageFolder->removeByName( aRelsStorName );
+
+ if ( !m_xRelStorage->hasElements() )
+ {
+ // the empty relations storage should not be created
+ delete m_pRelStorElement;
+ m_pRelStorElement = NULL;
+ m_xRelStorage = uno::Reference< embed::XStorage >();
+ }
+ else if ( m_pRelStorElement && m_pRelStorElement->m_pStorage && xNewPackageFolder.is() )
+ m_pRelStorElement->m_pStorage->InsertIntoPackageFolder( aRelsStorName, xNewPackageFolder );
+ }
+ }
+}
+
+//=====================================================
+// OStorage implementation
+//=====================================================
+
+//-----------------------------------------------
+OStorage::OStorage( uno::Reference< io::XInputStream > xInputStream,
+ sal_Int32 nMode,
+ uno::Sequence< beans::PropertyValue > xProperties,
+ uno::Reference< lang::XMultiServiceFactory > xFactory,
+ sal_Int32 nStorageType )
+: m_pImpl( new OStorage_Impl( xInputStream, nMode, xProperties, xFactory, nStorageType ) )
+{
+ m_pImpl->m_pAntiImpl = this;
+ m_pData = new StorInternalData_Impl( m_pImpl->m_rMutexRef, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, sal_False );
+}
+
+//-----------------------------------------------
+OStorage::OStorage( uno::Reference< io::XStream > xStream,
+ sal_Int32 nMode,
+ uno::Sequence< beans::PropertyValue > xProperties,
+ uno::Reference< lang::XMultiServiceFactory > xFactory,
+ sal_Int32 nStorageType )
+: m_pImpl( new OStorage_Impl( xStream, nMode, xProperties, xFactory, nStorageType ) )
+{
+ m_pImpl->m_pAntiImpl = this;
+ m_pData = new StorInternalData_Impl( m_pImpl->m_rMutexRef, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, sal_False );
+}
+
+//-----------------------------------------------
+OStorage::OStorage( OStorage_Impl* pImpl, sal_Bool bReadOnlyWrap )
+: m_pImpl( pImpl )
+{
+ // this call can be done only from OStorage_Impl implementation to create child storage
+ OSL_ENSURE( m_pImpl && m_pImpl->m_rMutexRef.Is(), "The provided pointer & mutex MUST NOT be empty!\n" );
+
+ m_pData = new StorInternalData_Impl( m_pImpl->m_rMutexRef, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, bReadOnlyWrap );
+
+ OSL_ENSURE( ( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) == embed::ElementModes::WRITE ||
+ m_pData->m_bReadOnlyWrap,
+ "The wrapper can not allow writing in case implementation does not!\n" );
+
+ if ( !bReadOnlyWrap )
+ m_pImpl->m_pAntiImpl = this;
+}
+
+//-----------------------------------------------
+OStorage::~OStorage()
+{
+ {
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+ if ( m_pImpl )
+ {
+ m_refCount++; // to call dispose
+ try {
+ dispose();
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Handled exception" ) ) );
+ }
+ }
+ }
+
+ if ( m_pData )
+ {
+ if ( m_pData->m_pSubElDispListener )
+ {
+ m_pData->m_pSubElDispListener->release();
+ m_pData->m_pSubElDispListener = NULL;
+ }
+
+ if ( m_pData->m_pTypeCollection )
+ {
+ delete m_pData->m_pTypeCollection;
+ m_pData->m_pTypeCollection = NULL;
+ }
+
+ delete m_pData;
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::InternalDispose( sal_Bool bNotifyImpl )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::InternalDispose" );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ // the source object is also a kind of locker for the current object
+ // since the listeners could dispose the object while being notified
+ lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
+ m_pData->m_aListenersContainer.disposeAndClear( aSource );
+
+ if ( m_pData->m_bReadOnlyWrap )
+ {
+ OSL_ENSURE( !m_pData->m_aOpenSubComponentsList.size() || m_pData->m_pSubElDispListener,
+ "If any subelements are open the listener must exist!\n" );
+
+ if ( m_pData->m_pSubElDispListener )
+ {
+ m_pData->m_pSubElDispListener->OwnerIsDisposed();
+
+ // iterate through m_pData->m_aOpenSubComponentsList
+ // deregister m_pData->m_pSubElDispListener and dispose all of them
+ if ( !m_pData->m_aOpenSubComponentsList.empty() )
+ {
+ for ( WeakComponentList::iterator pCompIter = m_pData->m_aOpenSubComponentsList.begin();
+ pCompIter != m_pData->m_aOpenSubComponentsList.end(); pCompIter++ )
+ {
+ uno::Reference< lang::XComponent > xTmp = (*pCompIter);
+ if ( xTmp.is() )
+ {
+ xTmp->removeEventListener( uno::Reference< lang::XEventListener >(
+ static_cast< lang::XEventListener* >( m_pData->m_pSubElDispListener ) ) );
+
+ try {
+ xTmp->dispose();
+ } catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+ }
+ }
+ }
+
+ m_pData->m_aOpenSubComponentsList.clear();
+ }
+ }
+
+ if ( bNotifyImpl )
+ m_pImpl->RemoveReadOnlyWrap( *this );
+ }
+ else
+ {
+ m_pImpl->m_pAntiImpl = NULL;
+
+ if ( bNotifyImpl )
+ {
+ if ( m_pData->m_bIsRoot )
+ delete m_pImpl;
+ else
+ {
+ // the noncommited changes for the storage must be removed
+ m_pImpl->Revert();
+ }
+ }
+ }
+
+ m_pImpl = NULL;
+}
+
+//-----------------------------------------------
+void OStorage::ChildIsDisposed( const uno::Reference< uno::XInterface >& xChild )
+{
+ // this method can only be called by child disposing listener
+
+ // this method must not contain any locking
+ // the locking is done in the listener
+
+ if ( !m_pData->m_aOpenSubComponentsList.empty() )
+ {
+ for ( WeakComponentList::iterator pCompIter = m_pData->m_aOpenSubComponentsList.begin();
+ pCompIter != m_pData->m_aOpenSubComponentsList.end(); )
+ {
+ uno::Reference< lang::XComponent > xTmp = (*pCompIter);
+ if ( !xTmp.is() || xTmp == xChild )
+ {
+ WeakComponentList::iterator pIterToRemove = pCompIter;
+ pCompIter++;
+ m_pData->m_aOpenSubComponentsList.erase( pIterToRemove );
+ }
+ else
+ pCompIter++;
+ }
+ }
+}
+
+//-----------------------------------------------
+void OStorage::BroadcastModifiedIfNecessary()
+{
+ // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !m_pImpl->m_bBroadcastModified )
+ return;
+
+ m_pImpl->m_bBroadcastModified = sal_False;
+
+ OSL_ENSURE( !m_pData->m_bReadOnlyWrap, "The storage can not be modified at all!\n" );
+
+ lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
+
+ ::cppu::OInterfaceContainerHelper* pContainer =
+ m_pData->m_aListenersContainer.getContainer(
+ ::getCppuType( ( const uno::Reference< util::XModifyListener >*) NULL ) );
+ if ( pContainer )
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
+ while ( pIterator.hasMoreElements( ) )
+ {
+ ( ( util::XModifyListener* )pIterator.next( ) )->modified( aSource );
+ }
+ }
+}
+
+//-----------------------------------------------
+void OStorage::BroadcastTransaction( sal_Int8 nMessage )
+/*
+ 1 - preCommit
+ 2 - commited
+ 3 - preRevert
+ 4 - reverted
+*/
+{
+ // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ OSL_ENSURE( !m_pData->m_bReadOnlyWrap, "The storage can not be modified at all!\n" );
+
+ lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
+
+ ::cppu::OInterfaceContainerHelper* pContainer =
+ m_pData->m_aListenersContainer.getContainer(
+ ::getCppuType( ( const uno::Reference< embed::XTransactionListener >*) NULL ) );
+ if ( pContainer )
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
+ while ( pIterator.hasMoreElements( ) )
+ {
+ OSL_ENSURE( nMessage >= 1 && nMessage <= 4, "Wrong internal notification code is used!\n" );
+
+ switch( nMessage )
+ {
+ case STOR_MESS_PRECOMMIT:
+ ( ( embed::XTransactionListener* )pIterator.next( ) )->preCommit( aSource );
+ break;
+ case STOR_MESS_COMMITED:
+ ( ( embed::XTransactionListener* )pIterator.next( ) )->commited( aSource );
+ break;
+ case STOR_MESS_PREREVERT:
+ ( ( embed::XTransactionListener* )pIterator.next( ) )->preRevert( aSource );
+ break;
+ case STOR_MESS_REVERTED:
+ ( ( embed::XTransactionListener* )pIterator.next( ) )->reverted( aSource );
+ break;
+ }
+ }
+ }
+}
+
+//-----------------------------------------------
+SotElement_Impl* OStorage::OpenStreamElement_Impl( const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode, sal_Bool bEncr )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ OSL_ENSURE( !m_pData->m_bReadOnlyWrap || ( nOpenMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE,
+ "An element can not be opened for writing in readonly storage!\n" );
+
+ SotElement_Impl *pElement = m_pImpl->FindElement( aStreamName );
+ if ( !pElement )
+ {
+ // element does not exist, check if creation is allowed
+ if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
+ || (( nOpenMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE )
+ || ( nOpenMode & embed::ElementModes::NOCREATE ) == embed::ElementModes::NOCREATE )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
+
+ // create a new StreamElement and insert it into the list
+ pElement = m_pImpl->InsertStream( aStreamName, bEncr );
+ }
+ else if ( pElement->m_bIsStorage )
+ {
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ OSL_ENSURE( pElement, "In case element can not be created an exception must be thrown!" );
+
+ if ( !pElement->m_pStream )
+ m_pImpl->OpenSubStream( pElement );
+
+ if ( !pElement->m_pStream )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return pElement;
+}
+
+//-----------------------------------------------
+void OStorage::MakeLinkToSubComponent_Impl( const uno::Reference< lang::XComponent >& xComponent )
+{
+ if ( !xComponent.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !m_pData->m_pSubElDispListener )
+ {
+ m_pData->m_pSubElDispListener = new OChildDispListener_Impl( *this );
+ m_pData->m_pSubElDispListener->acquire();
+ }
+
+ xComponent->addEventListener( uno::Reference< lang::XEventListener >(
+ static_cast< ::cppu::OWeakObject* >( m_pData->m_pSubElDispListener ), uno::UNO_QUERY ) );
+
+ m_pData->m_aOpenSubComponentsList.push_back( xComponent );
+}
+
+//____________________________________________________________________________________________________
+// XInterface
+//____________________________________________________________________________________________________
+
+//-----------------------------------------------
+uno::Any SAL_CALL OStorage::queryInterface( const uno::Type& rType )
+ throw( uno::RuntimeException )
+{
+ uno::Any aReturn;
+
+ // common interfaces
+ aReturn <<= ::cppu::queryInterface
+ ( rType
+ , static_cast<lang::XTypeProvider*> ( this )
+ , static_cast<embed::XStorage*> ( this )
+ , static_cast<embed::XTransactedObject*> ( this )
+ , static_cast<embed::XTransactionBroadcaster*> ( this )
+ , static_cast<util::XModifiable*> ( this )
+ , static_cast<container::XNameAccess*> ( this )
+ , static_cast<container::XElementAccess*> ( this )
+ , static_cast<lang::XComponent*> ( this )
+ , static_cast<beans::XPropertySet*> ( this )
+ , static_cast<embed::XOptimizedStorage*> ( this )
+ , static_cast<embed::XHierarchicalStorageAccess*> ( this ) );
+
+ if ( aReturn.hasValue() == sal_True )
+ return aReturn ;
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
+ {
+ if ( m_pData->m_bIsRoot )
+ {
+ aReturn <<= ::cppu::queryInterface
+ ( rType
+ , static_cast<embed::XStorageRawAccess*> ( this )
+ , static_cast<embed::XEncryptionProtectedSource*> ( this ) );
+ }
+ else
+ {
+ aReturn <<= ::cppu::queryInterface
+ ( rType
+ , static_cast<embed::XStorageRawAccess*> ( this ) );
+ }
+ }
+ else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ aReturn <<= ::cppu::queryInterface
+ ( rType
+ , static_cast<embed::XRelationshipAccess*> ( this ) );
+ }
+
+ if ( aReturn.hasValue() == sal_True )
+ return aReturn ;
+
+ return OWeakObject::queryInterface( rType );
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::acquire() throw()
+{
+ OWeakObject::acquire();
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::release() throw()
+{
+ OWeakObject::release();
+}
+
+//____________________________________________________________________________________________________
+// XTypeProvider
+//____________________________________________________________________________________________________
+
+//-----------------------------------------------
+uno::Sequence< uno::Type > SAL_CALL OStorage::getTypes()
+ throw( uno::RuntimeException )
+{
+ if ( m_pData->m_pTypeCollection == NULL )
+ {
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( m_pData->m_pTypeCollection == NULL )
+ {
+ if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
+ {
+ if ( m_pData->m_bIsRoot )
+ {
+ m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
+ ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XStorageRawAccess >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
+ , ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedSource >* )NULL )
+ , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
+ }
+ else
+ {
+ m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
+ ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XStorageRawAccess >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
+ , ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
+ , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
+ }
+ }
+ else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
+ ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
+ , ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XRelationshipAccess >* )NULL )
+ , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
+ }
+ else
+ {
+ m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
+ ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
+ , ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
+ , ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
+ , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
+ }
+ }
+ }
+
+ return m_pData->m_pTypeCollection->getTypes() ;
+}
+
+//-----------------------------------------------
+uno::Sequence< sal_Int8 > SAL_CALL OStorage::getImplementationId()
+ throw( uno::RuntimeException )
+{
+ static ::cppu::OImplementationId* pID = NULL ;
+
+ if ( pID == NULL )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ;
+
+ if ( pID == NULL )
+ {
+ static ::cppu::OImplementationId aID( sal_False ) ;
+ pID = &aID ;
+ }
+ }
+
+ return pID->getImplementationId() ;
+
+}
+
+//____________________________________________________________________________________________________
+// XStorage
+//____________________________________________________________________________________________________
+
+
+//-----------------------------------------------
+void SAL_CALL OStorage::copyToStorage( const uno::Reference< embed::XStorage >& xDest )
+ throw ( embed::InvalidStorageException,
+ io::IOException,
+ lang::IllegalArgumentException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyToStorage" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject*> ( this ), uno::UNO_QUERY ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ try {
+ m_pImpl->CopyToStorage( xDest, sal_False );
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy storage!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+}
+
+//-----------------------------------------------
+uno::Reference< io::XStream > SAL_CALL OStorage::openStreamElement(
+ const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openStreamElement" );
+
+ ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable element name
+
+ if ( ( nOpenMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
+
+ uno::Reference< io::XStream > xResult;
+ try
+ {
+ SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamName, nOpenMode, sal_False );
+ OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
+
+ xResult = pElement->m_pStream->GetStream( nOpenMode, sal_False );
+ OSL_ENSURE( xResult.is(), "The method must throw exception instead of removing empty result!\n" );
+
+ if ( m_pData->m_bReadOnlyWrap )
+ {
+ // before the storage disposes the stream it must deregister itself as listener
+ uno::Reference< lang::XComponent > xStreamComponent( xResult, uno::UNO_QUERY );
+ if ( !xStreamComponent.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ MakeLinkToSubComponent_Impl( xStreamComponent );
+ }
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( packages::WrongPasswordException& aWrongPasswordException )
+ {
+ m_pImpl->AddLog( aWrongPasswordException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't open stream element!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+
+ aGuard.clear();
+
+ BroadcastModifiedIfNecessary();
+
+ return xResult;
+}
+
+//-----------------------------------------------
+uno::Reference< io::XStream > SAL_CALL OStorage::openEncryptedStreamElement(
+ const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode, const ::rtl::OUString& aPass )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::NoEncryptionException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openEncryptedStreamElement" );
+
+ ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
+ packages::NoEncryptionException();
+
+ if ( ( nOpenMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
+
+ if ( !aPass.getLength() )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 3 );
+
+ uno::Reference< io::XStream > xResult;
+ try
+ {
+ SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamName, nOpenMode, sal_True );
+ OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
+
+ xResult = pElement->m_pStream->GetStream( nOpenMode, aPass, sal_False );
+ OSL_ENSURE( xResult.is(), "The method must throw exception instead of removing empty result!\n" );
+
+ if ( m_pData->m_bReadOnlyWrap )
+ {
+ // before the storage disposes the stream it must deregister itself as listener
+ uno::Reference< lang::XComponent > xStreamComponent( xResult, uno::UNO_QUERY );
+ if ( !xStreamComponent.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ MakeLinkToSubComponent_Impl( xStreamComponent );
+ }
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( packages::NoEncryptionException& aNoEncryptionException )
+ {
+ m_pImpl->AddLog( aNoEncryptionException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( packages::WrongPasswordException& aWrongPasswordException )
+ {
+ m_pImpl->AddLog( aWrongPasswordException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't open encrypted stream stream!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+
+ aGuard.clear();
+
+ BroadcastModifiedIfNecessary();
+
+ return xResult;
+}
+
+//-----------------------------------------------
+uno::Reference< embed::XStorage > SAL_CALL OStorage::openStorageElement(
+ const ::rtl::OUString& aStorName, sal_Int32 nStorageMode )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openStorageElement" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aStorName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && aStorName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
+
+ if ( ( nStorageMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
+
+ if ( ( nStorageMode & embed::ElementModes::TRUNCATE )
+ && !( nStorageMode & embed::ElementModes::WRITE ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
+
+ // it's allways possible to read written storage in this implementation
+ nStorageMode |= embed::ElementModes::READ;
+
+ uno::Reference< embed::XStorage > xResult;
+ try
+ {
+ SotElement_Impl *pElement = m_pImpl->FindElement( aStorName );
+ if ( !pElement )
+ {
+ // element does not exist, check if creation is allowed
+ if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
+ || (( nStorageMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE )
+ || ( nStorageMode & embed::ElementModes::NOCREATE ) == embed::ElementModes::NOCREATE )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
+
+ // create a new StorageElement and insert it into the list
+ pElement = m_pImpl->InsertStorage( aStorName, nStorageMode );
+ }
+ else if ( !pElement->m_bIsStorage )
+ {
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+ else if ( pElement->m_pStorage )
+ {
+ // storage has already been opened; it may be opened another time, if it the mode allows to do so
+ if ( pElement->m_pStorage->m_pAntiImpl )
+ {
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
+ }
+ else if ( !pElement->m_pStorage->m_aReadOnlyWrapList.empty()
+ && ( nStorageMode & embed::ElementModes::WRITE ) )
+ {
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
+ }
+ else
+ {
+ // in case parent storage allows writing the readonly mode of the child storage is
+ // virtual, that means that it is just enough to change the flag to let it be writable
+ // and since there is no AntiImpl nobody should be notified about it
+ pElement->m_pStorage->m_nStorageMode = nStorageMode | embed::ElementModes::READ;
+
+ if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) )
+ {
+ for ( SotElementList_Impl::iterator pElementIter = pElement->m_pStorage->m_aChildrenList.begin();
+ pElementIter != pElement->m_pStorage->m_aChildrenList.end(); )
+ {
+ SotElement_Impl* pElementToDel = (*pElementIter);
+ pElementIter++;
+
+ m_pImpl->RemoveElement( pElementToDel );
+ }
+ }
+ }
+ }
+
+ if ( !pElement->m_pStorage )
+ m_pImpl->OpenSubStorage( pElement, nStorageMode );
+
+ if ( !pElement->m_pStorage )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: general_error
+
+ sal_Bool bReadOnlyWrap = ( ( nStorageMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE );
+ OStorage* pResultStorage = new OStorage( pElement->m_pStorage, bReadOnlyWrap );
+ xResult = uno::Reference< embed::XStorage >( (embed::XStorage*) pResultStorage );
+
+ if ( bReadOnlyWrap )
+ {
+ // Before this call is done the object must be refcounted already
+ pElement->m_pStorage->SetReadOnlyWrap( *pResultStorage );
+
+ // before the storage disposes the stream it must deregister itself as listener
+ uno::Reference< lang::XComponent > xStorageComponent( xResult, uno::UNO_QUERY );
+ if ( !xStorageComponent.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ MakeLinkToSubComponent_Impl( xStorageComponent );
+ }
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't open storage!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+
+ return xResult;
+}
+
+//-----------------------------------------------
+uno::Reference< io::XStream > SAL_CALL OStorage::cloneStreamElement( const ::rtl::OUString& aStreamName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::cloneStreamElement" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
+
+ try
+ {
+ uno::Reference< io::XStream > xResult;
+ m_pImpl->CloneStreamElement( aStreamName, sal_False, ::rtl::OUString(), xResult );
+ if ( !xResult.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ return xResult;
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( packages::WrongPasswordException& aWrongPasswordException )
+ {
+ m_pImpl->AddLog( aWrongPasswordException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't clone stream!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+}
+
+//-----------------------------------------------
+uno::Reference< io::XStream > SAL_CALL OStorage::cloneEncryptedStreamElement(
+ const ::rtl::OUString& aStreamName,
+ const ::rtl::OUString& aPass )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::NoEncryptionException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::cloneEncryptedStreamElement" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
+ packages::NoEncryptionException();
+
+ if ( !aPass.getLength() )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
+
+ try
+ {
+ uno::Reference< io::XStream > xResult;
+ m_pImpl->CloneStreamElement( aStreamName, sal_True, aPass, xResult );
+ if ( !xResult.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ return xResult;
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( packages::NoEncryptionException& aNoEncryptionException )
+ {
+ m_pImpl->AddLog( aNoEncryptionException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( packages::WrongPasswordException& aWrongPasswordException )
+ {
+ m_pImpl->AddLog( aWrongPasswordException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't clone encrypted stream!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::copyLastCommitTo(
+ const uno::Reference< embed::XStorage >& xTargetStorage )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyLastCommitTo" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ try
+ {
+ m_pImpl->CopyLastCommitTo( xTargetStorage );
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy last commit version!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::copyStorageElementLastCommitTo(
+ const ::rtl::OUString& aStorName,
+ const uno::Reference< embed::XStorage >& xTargetStorage )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyStorageElementLastCommitTo" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aStorName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && aStorName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
+
+ // it's allways possible to read written storage in this implementation
+ sal_Int32 nStorageMode = embed::ElementModes::READ;
+
+ try
+ {
+ SotElement_Impl *pElement = m_pImpl->FindElement( aStorName );
+ if ( !pElement )
+ {
+ // element does not exist, throw exception
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
+ }
+ else if ( !pElement->m_bIsStorage )
+ {
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !pElement->m_pStorage )
+ m_pImpl->OpenSubStorage( pElement, nStorageMode );
+
+ uno::Reference< embed::XStorage > xResult;
+ if ( pElement->m_pStorage )
+ {
+ // the existence of m_pAntiImpl of the child is not interesting,
+ // the copy will be created internally
+
+ pElement->m_pStorage->CopyLastCommitTo( xTargetStorage );
+ }
+ else
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: general_error
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy last commit element version!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+}
+
+//-----------------------------------------------
+sal_Bool SAL_CALL OStorage::isStreamElement( const ::rtl::OUString& aElementName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable name
+
+ SotElement_Impl* pElement = NULL;
+
+ try
+ {
+ pElement = m_pImpl->FindElement( aElementName );
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::NoSuchElementException& aNoSuchElementException )
+ {
+ m_pImpl->AddLog( aNoSuchElementException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't detect whether it is a stream!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+
+ if ( !pElement )
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
+
+ return !pElement->m_bIsStorage;
+}
+
+//-----------------------------------------------
+sal_Bool SAL_CALL OStorage::isStorageElement( const ::rtl::OUString& aElementName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ SotElement_Impl* pElement = NULL;
+
+ try
+ {
+ pElement = m_pImpl->FindElement( aElementName );
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::NoSuchElementException& aNoSuchElementException )
+ {
+ m_pImpl->AddLog( aNoSuchElementException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "can't detect whether it is a storage" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+
+ if ( !pElement )
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
+
+ return pElement->m_bIsStorage;
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::removeElement( const ::rtl::OUString& aElementName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::removeElement" );
+
+ ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // TODO: unacceptable name
+
+ if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
+
+ try
+ {
+ SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
+
+ if ( !pElement )
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
+
+ m_pImpl->RemoveElement( pElement );
+
+ m_pImpl->m_bIsModified = sal_True;
+ m_pImpl->m_bBroadcastModified = sal_True;
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::NoSuchElementException& aNoSuchElementException )
+ {
+ m_pImpl->AddLog( aNoSuchElementException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't remove element!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+
+ aGuard.clear();
+
+ BroadcastModifiedIfNecessary();
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::renameElement( const ::rtl::OUString& aElementName, const ::rtl::OUString& aNewName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ container::ElementExistException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::renameElement" );
+
+ ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
+ || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && ( aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) )
+ || aNewName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); // TODO: unacceptable element name
+
+ if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
+
+ try
+ {
+ SotElement_Impl* pRefElement = m_pImpl->FindElement( aNewName );
+ if ( pRefElement )
+ throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
+
+ SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
+ if ( !pElement )
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
+
+ pElement->m_aName = aNewName;
+
+ m_pImpl->m_bIsModified = sal_True;
+ m_pImpl->m_bBroadcastModified = sal_True;
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::NoSuchElementException& aNoSuchElementException )
+ {
+ m_pImpl->AddLog( aNoSuchElementException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::ElementExistException& aElementExistException )
+ {
+ m_pImpl->AddLog( aElementExistException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't rename element!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+
+ aGuard.clear();
+
+ BroadcastModifiedIfNecessary();
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::copyElementTo( const ::rtl::OUString& aElementName,
+ const uno::Reference< embed::XStorage >& xDest,
+ const ::rtl::OUString& aNewName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ container::ElementExistException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyElementTo" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
+ || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( !xDest.is() )
+ // || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && ( aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) )
+ || aNewName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); // unacceptable element name
+
+ try
+ {
+ SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
+ if ( !pElement )
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY );
+ if ( !xNameAccess.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( xNameAccess->hasByName( aNewName ) )
+ throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ m_pImpl->CopyStorageElement( pElement, xDest, aNewName, sal_False );
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::NoSuchElementException& aNoSuchElementException )
+ {
+ m_pImpl->AddLog( aNoSuchElementException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::ElementExistException& aElementExistException )
+ {
+ m_pImpl->AddLog( aElementExistException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy element!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OStorage::moveElementTo( const ::rtl::OUString& aElementName,
+ const uno::Reference< embed::XStorage >& xDest,
+ const ::rtl::OUString& aNewName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ container::ElementExistException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::moveElementTo" );
+
+ ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
+ || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && ( aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) )
+ || aNewName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); // unacceptable element name
+
+ if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
+
+ try
+ {
+ SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
+ if ( !pElement )
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
+
+ uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY );
+ if ( !xNameAccess.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( xNameAccess->hasByName( aNewName ) )
+ throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ m_pImpl->CopyStorageElement( pElement, xDest, aNewName, sal_False );
+
+ m_pImpl->RemoveElement( pElement );
+
+ m_pImpl->m_bIsModified = sal_True;
+ m_pImpl->m_bBroadcastModified = sal_True;
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::NoSuchElementException& aNoSuchElementException )
+ {
+ m_pImpl->AddLog( aNoSuchElementException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::ElementExistException& aElementExistException )
+ {
+ m_pImpl->AddLog( aElementExistException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't move element!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+
+ aGuard.clear();
+
+ BroadcastModifiedIfNecessary();
+}
+
+//____________________________________________________________________________________________________
+// XStorageRawAccess
+//____________________________________________________________________________________________________
+
+//-----------------------------------------------
+uno::Reference< io::XInputStream > SAL_CALL OStorage::getPlainRawStreamElement(
+ const ::rtl::OUString& sStreamName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getPlainRawStreamElement" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // the interface is not supported and must not be accessible
+
+ if ( !sStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ uno::Reference < io::XInputStream > xTempIn;
+ try
+ {
+ SotElement_Impl* pElement = m_pImpl->FindElement( sStreamName );
+ if ( !pElement )
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !pElement->m_pStream )
+ {
+ m_pImpl->OpenSubStream( pElement );
+ if ( !pElement->m_pStream )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetPlainRawInStream();
+ if ( !xRawInStream.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference < io::XOutputStream > xTempOut(
+ m_pImpl->GetServiceFactory()->createInstance (
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
+ uno::UNO_QUERY );
+ xTempIn = uno::Reference < io::XInputStream >( xTempOut, uno::UNO_QUERY );
+ uno::Reference < io::XSeekable > xSeek( xTempOut, uno::UNO_QUERY );
+
+ if ( !xTempOut.is() || !xTempIn.is() || !xSeek.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // Copy temporary file to a new one
+ ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
+ xTempOut->closeOutput();
+ xSeek->seek( 0 );
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::NoSuchElementException& aNoSuchElementException )
+ {
+ m_pImpl->AddLog( aNoSuchElementException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't get plain raw stream!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+
+ return xTempIn;
+}
+
+//-----------------------------------------------
+uno::Reference< io::XInputStream > SAL_CALL OStorage::getRawEncrStreamElement(
+ const ::rtl::OUString& sStreamName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::NoEncryptionException,
+ container::NoSuchElementException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getRawEncrStreamElement" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
+ throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !sStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ uno::Reference < io::XInputStream > xTempIn;
+ try
+ {
+ SotElement_Impl* pElement = m_pImpl->FindElement( sStreamName );
+ if ( !pElement )
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !pElement->m_pStream )
+ {
+ m_pImpl->OpenSubStream( pElement );
+ if ( !pElement->m_pStream )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !pElement->m_pStream->IsEncrypted() )
+ throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetRawInStream();
+ if ( !xRawInStream.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference < io::XOutputStream > xTempOut(
+ m_pImpl->GetServiceFactory()->createInstance (
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
+ uno::UNO_QUERY );
+ xTempIn = uno::Reference < io::XInputStream >( xTempOut, uno::UNO_QUERY );
+ uno::Reference < io::XSeekable > xSeek( xTempOut, uno::UNO_QUERY );
+
+ if ( !xTempOut.is() || !xTempIn.is() || !xSeek.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // Copy temporary file to a new one
+ ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
+ xTempOut->closeOutput();
+ xSeek->seek( 0 );
+
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( packages::NoEncryptionException& aNoEncryptionException )
+ {
+ m_pImpl->AddLog( aNoEncryptionException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::NoSuchElementException& aNoSuchElementException )
+ {
+ m_pImpl->AddLog( aNoSuchElementException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't get raw stream!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+
+ return xTempIn;
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::insertRawEncrStreamElement( const ::rtl::OUString& aStreamName,
+ const uno::Reference< io::XInputStream >& xInStream )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::NoRawFormatException,
+ container::ElementExistException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::insertRawEncrStreamElement" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
+ throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( !xInStream.is() )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
+
+ if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
+
+ try
+ {
+ SotElement_Impl* pElement = m_pImpl->FindElement( aStreamName );
+ if ( pElement )
+ throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ m_pImpl->InsertRawStream( aStreamName, xInStream );
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( packages::NoRawFormatException& aNoRawFormatException )
+ {
+ m_pImpl->AddLog( aNoRawFormatException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::ElementExistException& aElementExistException )
+ {
+ m_pImpl->AddLog( aElementExistException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't insert raw stream!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+}
+
+//____________________________________________________________________________________________________
+// XTransactedObject
+//____________________________________________________________________________________________________
+
+//-----------------------------------------------
+void SAL_CALL OStorage::commit()
+ throw ( io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::commit" );
+
+ uno::Reference< util::XModifiable > xParentModif;
+
+ try {
+ BroadcastTransaction( STOR_MESS_PRECOMMIT );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_bReadOnlyWrap )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
+
+ m_pImpl->Commit(); // the root storage initiates the storing to source
+
+ // when the storage is commited the parent is modified
+ if ( m_pImpl->m_pParent && m_pImpl->m_pParent->m_pAntiImpl )
+ xParentModif = (util::XModifiable*)m_pImpl->m_pParent->m_pAntiImpl;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Problems on commit!" ) ),
+ uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ),
+ aCaught );
+ }
+
+ setModified( sal_False );
+ if ( xParentModif.is() )
+ xParentModif->setModified( sal_True );
+
+ BroadcastTransaction( STOR_MESS_COMMITED );
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::revert()
+ throw ( io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::revert" );
+
+ // the method removes all the changes done after last commit
+
+ BroadcastTransaction( STOR_MESS_PREREVERT );
+
+ ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ for ( SotElementList_Impl::iterator pElementIter = m_pImpl->m_aChildrenList.begin();
+ pElementIter != m_pImpl->m_aChildrenList.end(); pElementIter++ )
+ {
+ if ( ((*pElementIter)->m_pStorage
+ && ( (*pElementIter)->m_pStorage->m_pAntiImpl || !(*pElementIter)->m_pStorage->m_aReadOnlyWrapList.empty() ))
+ || ((*pElementIter)->m_pStream
+ && ( (*pElementIter)->m_pStream->m_pAntiImpl || !(*pElementIter)->m_pStream->m_aInputStreamsList.empty()) ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
+ }
+
+ if ( m_pData->m_bReadOnlyWrap || !m_pImpl->m_bListCreated )
+ return; // nothing to do
+
+ try {
+ m_pImpl->Revert();
+ m_pImpl->m_bIsModified = sal_False;
+ m_pImpl->m_bBroadcastModified = sal_True;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Problems on revert!" ) ),
+ uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ),
+ aCaught );
+ }
+
+ aGuard.clear();
+
+ setModified( sal_False );
+ BroadcastTransaction( STOR_MESS_REVERTED );
+}
+
+//____________________________________________________________________________________________________
+// XTransactionBroadcaster
+//____________________________________________________________________________________________________
+
+//-----------------------------------------------
+void SAL_CALL OStorage::addTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ m_pData->m_aListenersContainer.addInterface( ::getCppuType((const uno::Reference< embed::XTransactionListener >*)0),
+ aListener );
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::removeTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ m_pData->m_aListenersContainer.removeInterface( ::getCppuType((const uno::Reference< embed::XTransactionListener >*)0),
+ aListener );
+}
+
+//____________________________________________________________________________________________________
+// XModifiable
+// TODO: if there will be no demand on this interface it will be removed from implementation,
+// I do not want to remove it now since it is still possible that it will be inserted
+// to the service back.
+//____________________________________________________________________________________________________
+
+//-----------------------------------------------
+sal_Bool SAL_CALL OStorage::isModified()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ return m_pImpl->m_bIsModified;
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OStorage::setModified( sal_Bool bModified )
+ throw ( beans::PropertyVetoException,
+ uno::RuntimeException )
+{
+ ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_bReadOnlyWrap )
+ throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
+
+ if ( m_pImpl->m_bIsModified != bModified )
+ m_pImpl->m_bIsModified = bModified;
+
+ aGuard.clear();
+ if ( bModified )
+ {
+ m_pImpl->m_bBroadcastModified = sal_True;
+ BroadcastModifiedIfNecessary();
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::addModifyListener(
+ const uno::Reference< util::XModifyListener >& aListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ m_pData->m_aListenersContainer.addInterface(
+ ::getCppuType( ( const uno::Reference< util::XModifyListener >* )0 ), aListener );
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OStorage::removeModifyListener(
+ const uno::Reference< util::XModifyListener >& aListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ m_pData->m_aListenersContainer.removeInterface(
+ ::getCppuType( ( const uno::Reference< util::XModifyListener >* )0 ), aListener );
+}
+
+//____________________________________________________________________________________________________
+// XNameAccess
+//____________________________________________________________________________________________________
+
+//-----------------------------------------------
+uno::Any SAL_CALL OStorage::getByName( const ::rtl::OUString& aName )
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getByName" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable element name
+
+ uno::Any aResult;
+ try
+ {
+ SotElement_Impl* pElement = m_pImpl->FindElement( aName );
+ if ( !pElement )
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( pElement->m_bIsStorage )
+ aResult <<= openStorageElement( aName, embed::ElementModes::READ );
+ else
+ aResult <<= openStreamElement( aName, embed::ElementModes::READ );
+ }
+ catch( container::NoSuchElementException& aNoSuchElementException )
+ {
+ m_pImpl->AddLog( aNoSuchElementException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::WrappedTargetException& aWrappedTargetException )
+ {
+ m_pImpl->AddLog( aWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch ( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open storage!\n" ) ),
+ uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
+ uno::UNO_QUERY ),
+ aCaught );
+ }
+
+ return aResult;
+}
+
+
+//-----------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL OStorage::getElementNames()
+ throw ( uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getElementNames" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ try
+ {
+ return m_pImpl->GetElementNames();
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch ( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open storage!\n" ) ),
+ uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
+ uno::UNO_QUERY ),
+ aCaught );
+ }
+}
+
+
+//-----------------------------------------------
+sal_Bool SAL_CALL OStorage::hasByName( const ::rtl::OUString& aName )
+ throw ( uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::hasByName" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aName.getLength() )
+ return sal_False;
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
+ return sal_False;
+
+ SotElement_Impl* pElement = NULL;
+ try
+ {
+ pElement = m_pImpl->FindElement( aName );
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch ( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open storage!\n" ) ),
+ uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
+ uno::UNO_QUERY ),
+ aCaught );
+ }
+
+ return ( pElement != NULL );
+}
+
+
+//-----------------------------------------------
+uno::Type SAL_CALL OStorage::getElementType()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ // it is a multitype container
+ return uno::Type();
+}
+
+
+//-----------------------------------------------
+sal_Bool SAL_CALL OStorage::hasElements()
+ throw ( uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::hasElements" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ try
+ {
+ return ( m_pImpl->GetChildrenList().size() != 0 );
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch ( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open storage!\n" ) ),
+ uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
+ uno::UNO_QUERY ),
+ aCaught );
+ }
+}
+
+
+//____________________________________________________________________________________________________
+// XComponent
+//____________________________________________________________________________________________________
+
+//-----------------------------------------------
+void SAL_CALL OStorage::dispose()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ try
+ {
+ InternalDispose( sal_True );
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch ( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open storage!\n" ) ),
+ uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
+ uno::UNO_QUERY ),
+ aCaught );
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::addEventListener(
+ const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ m_pData->m_aListenersContainer.addInterface(
+ ::getCppuType( ( const uno::Reference< lang::XEventListener >* )0 ), xListener );
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::removeEventListener(
+ const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ m_pData->m_aListenersContainer.removeInterface(
+ ::getCppuType( ( const uno::Reference< lang::XEventListener >* )0 ), xListener );
+}
+
+//____________________________________________________________________________________________________
+// XEncryptionProtectedSource
+//____________________________________________________________________________________________________
+
+void SAL_CALL OStorage::setEncryptionPassword( const ::rtl::OUString& aPass )
+ throw ( uno::RuntimeException,
+ io::IOException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setEncryptionPassword" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // the interface must be visible only for package storage
+
+ OSL_ENSURE( m_pData->m_bIsRoot, "setEncryptionPassword() method is not available for nonroot storages!\n" );
+
+ if ( m_pData->m_bIsRoot )
+ {
+ try {
+ m_pImpl->ReadContents();
+ }
+ catch ( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch ( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
+ uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
+ uno::UNO_QUERY ),
+ aCaught );
+ }
+
+ uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY );
+ if ( !xPackPropSet.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ try
+ {
+ xPackPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionKey" ) ),
+ uno::makeAny( ::package::MakeKeyFromPass( aPass, sal_True ) ) );
+
+ m_pImpl->m_bHasCommonPassword = sal_True;
+ m_pImpl->m_aCommonPassword = aPass;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ OSL_ENSURE( sal_False, "The call must not fail, it is pretty simple!" );
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::removeEncryption()
+ throw ( uno::RuntimeException,
+ io::IOException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::removeEncryption" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // the interface must be visible only for package storage
+
+ OSL_ENSURE( m_pData->m_bIsRoot, "removeEncryption() method is not available for nonroot storages!\n" );
+
+ if ( m_pData->m_bIsRoot )
+ {
+ try {
+ m_pImpl->ReadContents();
+ }
+ catch ( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch ( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
+ uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
+ uno::UNO_QUERY ),
+ aCaught );
+ }
+
+ // TODO: check if the password is valid
+ // update all streams that was encrypted with old password
+
+ uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY );
+ if ( !xPackPropSet.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ try
+ {
+ xPackPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionKey" ) ),
+ uno::makeAny( uno::Sequence< sal_Int8 >() ) );
+
+ m_pImpl->m_bHasCommonPassword = sal_False;
+ m_pImpl->m_aCommonPassword = ::rtl::OUString();
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ OSL_ENSURE( sal_False, "The call must not fail, it is pretty simple!" );
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+ }
+}
+
+//____________________________________________________________________________________________________
+// XPropertySet
+//____________________________________________________________________________________________________
+
+//-----------------------------------------------
+uno::Reference< beans::XPropertySetInfo > SAL_CALL OStorage::getPropertySetInfo()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ //TODO:
+ return uno::Reference< beans::XPropertySetInfo >();
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OStorage::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw ( beans::UnknownPropertyException,
+ beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setPropertyValue" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ //TODO: think about interaction handler
+
+ // WORKAROUND:
+ // The old document might have no version in the manifest.xml, so we have to allow to set the version
+ // even for readonly storages, so that the version from content.xml can be used.
+ if ( m_pData->m_bReadOnlyWrap && !aPropertyName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: Access denied
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::ZIP )
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
+ {
+ if ( aPropertyName.equalsAscii( "MediaType" ) )
+ {
+ aValue >>= m_pImpl->m_aMediaType;
+ m_pImpl->m_bControlMediaType = sal_True;
+
+ m_pImpl->m_bBroadcastModified = sal_True;
+ m_pImpl->m_bIsModified = sal_True;
+ }
+ else if ( aPropertyName.equalsAscii( "Version" ) )
+ {
+ aValue >>= m_pImpl->m_aVersion;
+ m_pImpl->m_bControlVersion = sal_True;
+
+ // this property can be set even for readonly storage
+ if ( !m_pData->m_bReadOnlyWrap )
+ {
+ m_pImpl->m_bBroadcastModified = sal_True;
+ m_pImpl->m_bIsModified = sal_True;
+ }
+ }
+ else if ( ( m_pData->m_bIsRoot && ( aPropertyName.equalsAscii( "HasEncryptedEntries" )
+ || aPropertyName.equalsAscii( "HasNonEncryptedEntries" )
+ || aPropertyName.equalsAscii( "IsInconsistent" )
+ || aPropertyName.equalsAscii( "URL" )
+ || aPropertyName.equalsAscii( "RepairPackage" ) ) )
+ || aPropertyName.equalsAscii( "IsRoot" )
+ || aPropertyName.equalsAscii( "MediaTypeFallbackUsed" ) )
+ throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ else
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+ else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
+ {
+ if ( aPropertyName.equalsAscii( "RelationsInfoStream" ) )
+ {
+ uno::Reference< io::XInputStream > xInRelStream;
+ if ( ( aValue >>= xInRelStream ) && xInRelStream.is() )
+ {
+ uno::Reference< io::XSeekable > xSeek( xInRelStream, uno::UNO_QUERY );
+ if ( !xSeek.is() )
+ {
+ // currently this is an internal property that is used for optimization
+ // and the stream must support XSeekable interface
+ // TODO/LATER: in future it can be changed if property is used from outside
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
+ }
+
+ m_pImpl->m_xNewRelInfoStream = xInRelStream;
+ m_pImpl->m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
+ m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED_STREAM;
+ m_pImpl->m_bBroadcastModified = sal_True;
+ m_pImpl->m_bIsModified = sal_True;
+ }
+ else
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
+ }
+ else if ( aPropertyName.equalsAscii( "RelationsInfo" ) )
+ {
+ if ( aValue >>= m_pImpl->m_aRelInfo )
+ {
+ m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
+ m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
+ m_pImpl->m_bBroadcastModified = sal_True;
+ m_pImpl->m_bIsModified = sal_True;
+ }
+ else
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
+ }
+ else if ( ( m_pData->m_bIsRoot && ( aPropertyName.equalsAscii( "URL" )
+ || aPropertyName.equalsAscii( "RepairPackage" ) ) )
+ || aPropertyName.equalsAscii( "IsRoot" ) )
+ throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ else
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+ else
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ BroadcastModifiedIfNecessary();
+}
+
+
+//-----------------------------------------------
+uno::Any SAL_CALL OStorage::getPropertyValue( const ::rtl::OUString& aPropertyName )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getPropertyValue" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
+ && ( aPropertyName.equalsAscii( "MediaType" )
+ || aPropertyName.equalsAscii( "MediaTypeFallbackUsed" )
+ || aPropertyName.equalsAscii( "Version" ) ) )
+ {
+ try
+ {
+ m_pImpl->ReadContents();
+ }
+ catch ( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch ( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't read contents!" ) ),
+ uno::Reference< XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ),
+ aCaught );
+ }
+
+ if ( aPropertyName.equalsAscii( "MediaType" ) )
+ return uno::makeAny( m_pImpl->m_aMediaType );
+ else if ( aPropertyName.equalsAscii( "Version" ) )
+ return uno::makeAny( m_pImpl->m_aVersion );
+ else
+ return uno::makeAny( m_pImpl->m_bMTFallbackUsed );
+ }
+ else if ( aPropertyName.equalsAscii( "IsRoot" ) )
+ {
+ return uno::makeAny( m_pData->m_bIsRoot );
+ }
+ else if ( aPropertyName.equalsAscii( "OpenMode" ) )
+ {
+ return uno::makeAny( m_pImpl->m_nStorageMode );
+ }
+ else if ( m_pData->m_bIsRoot )
+ {
+ if ( aPropertyName.equalsAscii( "URL" )
+ || aPropertyName.equalsAscii( "RepairPackage" ) )
+ {
+ for ( sal_Int32 aInd = 0; aInd < m_pImpl->m_xProperties.getLength(); aInd++ )
+ {
+ if ( m_pImpl->m_xProperties[aInd].Name.equals( aPropertyName ) )
+ return m_pImpl->m_xProperties[aInd].Value;
+ }
+
+ if ( aPropertyName.equalsAscii( "URL" ) )
+ return uno::makeAny( ::rtl::OUString() );
+
+ return uno::makeAny( sal_False ); // RepairPackage
+ }
+ else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
+ && ( aPropertyName.equalsAscii( "HasEncryptedEntries" )
+ || aPropertyName.equalsAscii( "HasNonEncryptedEntries" )
+ || aPropertyName.equalsAscii( "IsInconsistent" ) ) )
+ {
+ try {
+ m_pImpl->ReadContents();
+ uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY );
+ if ( !xPackPropSet.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return xPackPropSet->getPropertyValue( aPropertyName );
+ }
+ catch ( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch ( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
+ uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
+ uno::UNO_QUERY ),
+ aCaught );
+ }
+ }
+ }
+
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OStorage::addPropertyChangeListener(
+ const ::rtl::OUString& /*aPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ //TODO:
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OStorage::removePropertyChangeListener(
+ const ::rtl::OUString& /*aPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ //TODO:
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OStorage::addVetoableChangeListener(
+ const ::rtl::OUString& /*PropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ //TODO:
+}
+
+
+//-----------------------------------------------
+void SAL_CALL OStorage::removeVetoableChangeListener(
+ const ::rtl::OUString& /*PropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ //TODO:
+}
+
+//____________________________________________________________________________________________________
+// XRelationshipAccess
+//____________________________________________________________________________________________________
+
+// TODO/LATER: the storage and stream implementations of this interface are very similar, they could use a helper class
+
+//-----------------------------------------------
+sal_Bool SAL_CALL OStorage::hasByID( const ::rtl::OUString& sID )
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ try
+ {
+ getRelationshipByID( sID );
+ return sal_True;
+ }
+ catch( container::NoSuchElementException& aNoSuchElementException )
+ {
+ m_pImpl->AddLog( aNoSuchElementException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+ }
+
+ return sal_False;
+}
+
+//-----------------------------------------------
+::rtl::OUString SAL_CALL OStorage::getTargetByID( const ::rtl::OUString& sID )
+ throw ( container::NoSuchElementException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
+ for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
+ if ( aSeq[nInd].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Target" ) ) )
+ return aSeq[nInd].Second;
+
+ return ::rtl::OUString();
+}
+
+//-----------------------------------------------
+::rtl::OUString SAL_CALL OStorage::getTypeByID( const ::rtl::OUString& sID )
+ throw ( container::NoSuchElementException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
+ for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
+ if ( aSeq[nInd].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
+ return aSeq[nInd].Second;
+
+ return ::rtl::OUString();
+}
+
+//-----------------------------------------------
+uno::Sequence< beans::StringPair > SAL_CALL OStorage::getRelationshipByID( const ::rtl::OUString& sID )
+ throw ( container::NoSuchElementException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // TODO/LATER: in future the unification of the ID could be checked
+ uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
+ for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
+ for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
+ if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Id" ) ) )
+ {
+ if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
+ return aSeq[nInd1];
+ break;
+ }
+
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+//-----------------------------------------------
+uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OStorage::getRelationshipsByType( const ::rtl::OUString& sType )
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Sequence< uno::Sequence< beans::StringPair > > aResult;
+ sal_Int32 nEntriesNum = 0;
+
+ // TODO/LATER: in future the unification of the ID could be checked
+ uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
+ for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
+ for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
+ if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
+ {
+ // the type is usually an URL, so the check should be case insensitive
+ if ( aSeq[nInd1][nInd2].Second.equalsIgnoreAsciiCase( sType ) )
+ {
+ aResult.realloc( ++nEntriesNum );
+ aResult[nEntriesNum-1] = aSeq[nInd1];
+ }
+ break;
+ }
+
+ return aResult;
+}
+
+//-----------------------------------------------
+uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OStorage::getAllRelationships()
+ throw (io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return m_pImpl->GetAllRelationshipsIfAny();
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::insertRelationshipByID( const ::rtl::OUString& sID, const uno::Sequence< beans::StringPair >& aEntry, ::sal_Bool bReplace )
+ throw ( container::ElementExistException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ ::rtl::OUString aIDTag( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
+
+ sal_Int32 nIDInd = -1;
+
+ // TODO/LATER: in future the unification of the ID could be checked
+ uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
+ for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
+ for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
+ if ( aSeq[nInd1][nInd2].First.equals( aIDTag ) )
+ {
+ if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
+ nIDInd = nInd1;
+
+ break;
+ }
+
+ if ( nIDInd == -1 || bReplace )
+ {
+ if ( nIDInd == -1 )
+ {
+ nIDInd = aSeq.getLength();
+ aSeq.realloc( nIDInd + 1 );
+ }
+
+ aSeq[nIDInd].realloc( aEntry.getLength() + 1 );
+
+ aSeq[nIDInd][0].First = aIDTag;
+ aSeq[nIDInd][0].Second = sID;
+ sal_Int32 nIndTarget = 1;
+ for ( sal_Int32 nIndOrig = 0;
+ nIndOrig < aEntry.getLength();
+ nIndOrig++ )
+ {
+ if ( !aEntry[nIndOrig].First.equals( aIDTag ) )
+ aSeq[nIDInd][nIndTarget++] = aEntry[nIndOrig];
+ }
+
+ aSeq[nIDInd].realloc( nIndTarget );
+ }
+ else
+ throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+
+ m_pImpl->m_aRelInfo = aSeq;
+ m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
+ m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::removeRelationshipByID( const ::rtl::OUString& sID )
+ throw ( container::NoSuchElementException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
+ for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
+ for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
+ if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Id" ) ) )
+ {
+ if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
+ {
+ sal_Int32 nLength = aSeq.getLength();
+ aSeq[nInd1] = aSeq[nLength-1];
+ aSeq.realloc( nLength - 1 );
+
+ m_pImpl->m_aRelInfo = aSeq;
+ m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
+ m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
+
+ // TODO/LATER: in future the unification of the ID could be checked
+ return;
+ }
+
+ break;
+ }
+
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::insertRelationships( const uno::Sequence< uno::Sequence< beans::StringPair > >& aEntries, ::sal_Bool bReplace )
+ throw ( container::ElementExistException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ ::rtl::OUString aIDTag( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
+ uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
+ uno::Sequence< uno::Sequence< beans::StringPair > > aResultSeq( aSeq.getLength() + aEntries.getLength() );
+ sal_Int32 nResultInd = 0;
+
+ for ( sal_Int32 nIndTarget1 = 0; nIndTarget1 < aSeq.getLength(); nIndTarget1++ )
+ for ( sal_Int32 nIndTarget2 = 0; nIndTarget2 < aSeq[nIndTarget1].getLength(); nIndTarget2++ )
+ if ( aSeq[nIndTarget1][nIndTarget2].First.equals( aIDTag ) )
+ {
+ sal_Int32 nIndSourceSame = -1;
+
+ for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
+ for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
+ {
+ if ( aEntries[nIndSource1][nIndSource2].First.equals( aIDTag ) )
+ {
+ if ( aEntries[nIndSource1][nIndSource2].Second.equals( aSeq[nIndTarget1][nIndTarget2].Second ) )
+ {
+ if ( !bReplace )
+ throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ nIndSourceSame = nIndSource1;
+ }
+
+ break;
+ }
+ }
+
+ if ( nIndSourceSame == -1 )
+ {
+ // no such element in the provided sequence
+ aResultSeq[nResultInd++] = aSeq[nIndTarget1];
+ }
+
+ break;
+ }
+
+ for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
+ {
+ aResultSeq[nResultInd].realloc( aEntries[nIndSource1].getLength() );
+ sal_Bool bHasID = sal_False;
+ sal_Int32 nResInd2 = 1;
+
+ for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
+ if ( aEntries[nIndSource1][nIndSource2].First.equals( aIDTag ) )
+ {
+ aResultSeq[nResultInd][0] = aEntries[nIndSource1][nIndSource2];
+ bHasID = sal_True;
+ }
+ else if ( nResInd2 < aResultSeq[nResultInd].getLength() )
+ aResultSeq[nResultInd][nResInd2++] = aEntries[nIndSource1][nIndSource2];
+ else
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: illegal relation ( no ID )
+
+ if ( !bHasID )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: illegal relations
+
+ nResultInd++;
+ }
+
+ aResultSeq.realloc( nResultInd );
+ m_pImpl->m_aRelInfo = aResultSeq;
+ m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
+ m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::clearRelationships()
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ m_pImpl->m_aRelInfo.realloc( 0 );
+ m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
+ m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
+}
+
+//____________________________________________________________________________________________________
+// XOptimizedStorage
+//____________________________________________________________________________________________________
+//-----------------------------------------------
+void SAL_CALL OStorage::insertRawNonEncrStreamElementDirect(
+ const ::rtl::OUString& /*sStreamName*/,
+ const uno::Reference< io::XInputStream >& /*xInStream*/ )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::NoRawFormatException,
+ container::ElementExistException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ // not implemented currently because there is still no demand
+ // might need to be implemented if direct copying of compressed streams is used
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::insertStreamElementDirect(
+ const ::rtl::OUString& aStreamName,
+ const uno::Reference< io::XInputStream >& xInStream,
+ const uno::Sequence< beans::PropertyValue >& aProps )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::ElementExistException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::insertStreamElementDirect" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
+
+ if ( m_pData->m_bReadOnlyWrap )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
+
+ try
+ {
+ SotElement_Impl* pElement = m_pImpl->FindElement( aStreamName );
+
+ if ( pElement )
+ throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ pElement = OpenStreamElement_Impl( aStreamName, embed::ElementModes::READWRITE, sal_False );
+ OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
+
+ pElement->m_pStream->InsertStreamDirectly( xInStream, aProps );
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::ElementExistException& aElementExistException )
+ {
+ m_pImpl->AddLog( aElementExistException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't insert stream directly!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::copyElementDirectlyTo(
+ const ::rtl::OUString& aElementName,
+ const uno::Reference< embed::XOptimizedStorage >& xDest,
+ const ::rtl::OUString& aNewName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ container::ElementExistException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyElementDirectlyTo" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
+ || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && ( aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) )
+ || aNewName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); // unacceptable name
+
+ try
+ {
+ SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
+ if ( !pElement )
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY );
+ if ( !xNameAccess.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( xNameAccess->hasByName( aNewName ) )
+ throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // let the element be copied directly
+ uno::Reference< embed::XStorage > xStorDest( xDest, uno::UNO_QUERY_THROW );
+ m_pImpl->CopyStorageElement( pElement, xStorDest, aNewName, sal_True );
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::NoSuchElementException& aNoSuchElementException )
+ {
+ m_pImpl->AddLog( aNoSuchElementException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::ElementExistException& aElementExistException )
+ {
+ m_pImpl->AddLog( aElementExistException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy element direcly!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::writeAndAttachToStream( const uno::Reference< io::XStream >& xStream )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::writeAndAttachToStream" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !m_pData->m_bIsRoot )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
+
+ if ( !m_pImpl->m_pSwitchStream )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ try
+ {
+ m_pImpl->m_pSwitchStream->CopyAndSwitchPersistenceTo( xStream );
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't write and attach to stream!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::attachToURL( const ::rtl::OUString& sURL,
+ sal_Bool bReadOnly )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::attachToURL" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !m_pData->m_bIsRoot )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
+
+ if ( !m_pImpl->m_pSwitchStream )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference < ucb::XSimpleFileAccess > xAccess(
+ m_pImpl->m_xFactory->createInstance (
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ),
+ uno::UNO_QUERY_THROW );
+
+ try
+ {
+ if ( bReadOnly )
+ {
+ uno::Reference< io::XInputStream > xInputStream = xAccess->openFileRead( sURL );
+ m_pImpl->m_pSwitchStream->SwitchPersistenceTo( xInputStream );
+ }
+ else
+ {
+ uno::Reference< io::XStream > xStream = xAccess->openFileReadWrite( sURL );
+ m_pImpl->m_pSwitchStream->SwitchPersistenceTo( xStream );
+ }
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't attach to URL!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+}
+
+//-----------------------------------------------
+uno::Any SAL_CALL OStorage::getElementPropertyValue( const ::rtl::OUString& aElementName, const ::rtl::OUString& aPropertyName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ io::IOException,
+ beans::UnknownPropertyException,
+ beans::PropertyVetoException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getElementPropertyValue" );
+
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // TODO: unacceptable name
+
+ try
+ {
+ SotElement_Impl *pElement = m_pImpl->FindElement( aElementName );
+ if ( !pElement )
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // TODO/LATER: Currently it is only implemented for MediaType property of substorages, might be changed in future
+ if ( !pElement->m_bIsStorage || m_pData->m_nStorageType != embed::StorageFormats::PACKAGE || !aPropertyName.equalsAscii( "MediaType" ) )
+ throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !pElement->m_pStorage )
+ m_pImpl->OpenSubStorage( pElement, embed::ElementModes::READ );
+
+ if ( !pElement->m_pStorage )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: general_error
+
+ pElement->m_pStorage->ReadContents();
+ return uno::makeAny( pElement->m_pStorage->m_aMediaType );
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( container::NoSuchElementException& aNoSuchElementException )
+ {
+ m_pImpl->AddLog( aNoSuchElementException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( beans::UnknownPropertyException& aUnknownPropertyException )
+ {
+ m_pImpl->AddLog( aUnknownPropertyException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( beans::PropertyVetoException& aPropertyVetoException )
+ {
+ m_pImpl->AddLog( aPropertyVetoException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't get element property!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::copyStreamElementData( const ::rtl::OUString& aStreamName, const uno::Reference< io::XStream >& xTargetStream )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
+ && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable name
+
+ if ( !xTargetStream.is() )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
+
+ try
+ {
+ uno::Reference< io::XStream > xNonconstRef = xTargetStream;
+ m_pImpl->CloneStreamElement( aStreamName, sal_False, ::rtl::OUString(), xNonconstRef );
+
+ OSL_ENSURE( xNonconstRef == xTargetStream, "The provided stream reference seems not be filled in correctly!\n" );
+ if ( xNonconstRef != xTargetStream )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // if the stream reference is set it must not be changed!
+ }
+ catch( embed::InvalidStorageException& aInvalidStorageException )
+ {
+ m_pImpl->AddLog( aInvalidStorageException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( lang::IllegalArgumentException& aIllegalArgumentException )
+ {
+ m_pImpl->AddLog( aIllegalArgumentException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( packages::WrongPasswordException& aWrongPasswordException )
+ {
+ m_pImpl->AddLog( aWrongPasswordException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( io::IOException& aIOException )
+ {
+ m_pImpl->AddLog( aIOException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
+ {
+ m_pImpl->AddLog( aStorageWrappedTargetException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::RuntimeException& aRuntimeException )
+ {
+ m_pImpl->AddLog( aRuntimeException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+ throw;
+ }
+ catch( uno::Exception& aException )
+ {
+ m_pImpl->AddLog( aException.Message );
+ m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy stream data!" ) ),
+ uno::Reference< io::XInputStream >(),
+ aCaught );
+ }
+
+
+}
+
+//____________________________________________________________________________________________________
+// XHierarchicalStorageAccess
+//____________________________________________________________________________________________________
+
+//-----------------------------------------------
+uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openStreamElementByHierarchicalName( const ::rtl::OUString& aStreamPath, ::sal_Int32 nOpenMode )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aStreamPath.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, sal_True ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
+ && ( nOpenMode & embed::ElementModes::WRITE ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // Access denied
+
+ OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
+ OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
+
+ uno::Reference< embed::XExtendedStorageStream > xResult;
+ if ( aListPath.size() == 1 )
+ {
+ // that must be a direct request for a stream
+ // the transacted version of the stream should be opened
+
+ SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamPath, nOpenMode, sal_False );
+ OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
+
+ xResult = uno::Reference< embed::XExtendedStorageStream >(
+ pElement->m_pStream->GetStream( nOpenMode, sal_True ),
+ uno::UNO_QUERY_THROW );
+ }
+ else
+ {
+ // there are still storages in between
+ if ( !m_pData->m_rHierarchyHolder.is() )
+ m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
+ uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
+
+ xResult = m_pData->m_rHierarchyHolder->GetStreamHierarchically(
+ ( m_pImpl->m_nStorageMode & embed::ElementModes::READWRITE ),
+ aListPath,
+ nOpenMode );
+ }
+
+ if ( !xResult.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return xResult;
+}
+
+//-----------------------------------------------
+uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openEncryptedStreamElementByHierarchicalName( const ::rtl::OUString& aStreamPath, ::sal_Int32 nOpenMode, const ::rtl::OUString& sPassword )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::NoEncryptionException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
+ throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !aStreamPath.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, sal_True ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( !sPassword.getLength() )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 3 );
+
+ if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
+ && ( nOpenMode & embed::ElementModes::WRITE ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // Access denied
+
+ OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
+ OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
+
+ uno::Reference< embed::XExtendedStorageStream > xResult;
+ if ( aListPath.size() == 1 )
+ {
+ // that must be a direct request for a stream
+ // the transacted version of the stream should be opened
+
+ SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamPath, nOpenMode, sal_True );
+ OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
+
+ xResult = uno::Reference< embed::XExtendedStorageStream >(
+ pElement->m_pStream->GetStream( nOpenMode, sPassword, sal_True ),
+ uno::UNO_QUERY_THROW );
+ }
+ else
+ {
+ // there are still storages in between
+ if ( !m_pData->m_rHierarchyHolder.is() )
+ m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
+ uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
+
+ xResult = m_pData->m_rHierarchyHolder->GetStreamHierarchically(
+ ( m_pImpl->m_nStorageMode & embed::ElementModes::READWRITE ),
+ aListPath,
+ nOpenMode,
+ sPassword );
+ }
+
+ if ( !xResult.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return xResult;
+}
+
+//-----------------------------------------------
+void SAL_CALL OStorage::removeStreamElementByHierarchicalName( const ::rtl::OUString& aStreamPath )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ if ( !aStreamPath.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, sal_True ) )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // Access denied
+
+ OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
+ OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
+
+ if ( !m_pData->m_rHierarchyHolder.is() )
+ m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
+ uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
+
+ m_pData->m_rHierarchyHolder->RemoveStreamHierarchically( aListPath );
+}
+
diff --git a/package/source/xstor/xstorage.hxx b/package/source/xstor/xstorage.hxx
new file mode 100644
index 000000000000..f1c50e4d67bd
--- /dev/null
+++ b/package/source/xstor/xstorage.hxx
@@ -0,0 +1,807 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __XSTORAGE_HXX_
+#define __XSTORAGE_HXX_
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/XOptimizedStorage.hpp>
+#include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
+#include <com/sun/star/embed/XStorageRawAccess.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/embed/XTransactionBroadcaster.hpp>
+#include <com/sun/star/embed/XClassifiedObject.hpp>
+#include <com/sun/star/embed/XEncryptionProtectedSource.hpp>
+#include <com/sun/star/embed/XRelationshipAccess.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/StringPair.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/packages/NoEncryptionException.hpp>
+#include <com/sun/star/logging/XSimpleLogRing.hpp>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/interfacecontainer.h>
+
+#include "mutexholder.hxx"
+
+#define RELINFO_NO_INIT 1
+#define RELINFO_READ 2
+#define RELINFO_CHANGED 3
+#define RELINFO_CHANGED_STREAM 4
+#define RELINFO_CHANGED_STREAM_READ 5
+#define RELINFO_BROKEN 6
+#define RELINFO_CHANGED_BROKEN 7
+
+#define STOR_MESS_PRECOMMIT 1
+#define STOR_MESS_COMMITED 2
+#define STOR_MESS_PREREVERT 3
+#define STOR_MESS_REVERTED 4
+
+namespace cppu
+{
+ class OTypeCollection;
+}
+
+//================================================
+// a common implementation for an entry
+
+struct StorInternalData_Impl;
+struct OStorage_Impl;
+struct OWriteStream_Impl;
+
+struct SotElement_Impl
+{
+ ::rtl::OUString m_aName;
+ ::rtl::OUString m_aOriginalName;
+ sal_Bool m_bIsRemoved;
+ sal_Bool m_bIsInserted;
+ sal_Bool m_bIsStorage;
+
+ OStorage_Impl* m_pStorage;
+ OWriteStream_Impl* m_pStream;
+
+public:
+ SotElement_Impl( const ::rtl::OUString& rName, sal_Bool bStor, sal_Bool bNew );
+ ~SotElement_Impl();
+};
+
+#include <list>
+typedef ::std::list< SotElement_Impl* > SotElementList_Impl;
+
+//=========================================================================
+// Main storage implementation
+
+class OStorage;
+
+struct StorageHolder_Impl
+{
+ OStorage* m_pPointer;
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::embed::XStorage > m_xWeakRef;
+
+ StorageHolder_Impl( OStorage* pStorage )
+ : m_pPointer( pStorage )
+ , m_xWeakRef( ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >(
+ (::com::sun::star::embed::XStorage*)pStorage ) )
+ {
+ }
+
+ StorageHolder_Impl( const StorageHolder_Impl& aSH )
+ : m_pPointer( aSH.m_pPointer )
+ , m_xWeakRef( aSH.m_xWeakRef )
+ {
+ }
+};
+
+typedef ::std::list< StorageHolder_Impl > OStorageList_Impl;
+
+class SwitchablePersistenceStream;
+struct OStorage_Impl
+{
+ SotMutexHolderRef m_rMutexRef;
+
+ OStorage* m_pAntiImpl; // only valid if external references exists
+ OStorageList_Impl m_aReadOnlyWrapList; // only valid if readonly external reference exists
+
+ sal_Int32 m_nStorageMode; // open mode ( read/write/trunc/nocreate )
+ sal_Bool m_bIsModified; // only modified elements will be sent to the original content
+ sal_Bool m_bBroadcastModified; // will be set if notification is required
+ sal_Bool m_bCommited; // sending the streams is coordinated by the root storage of the package
+
+ sal_Bool m_bIsRoot; // marks this storage as root storages that manages all commits and reverts
+ sal_Bool m_bListCreated;
+
+
+ SotElementList_Impl m_aChildrenList;
+ SotElementList_Impl m_aDeletedList;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > m_xPackageFolder;
+ ::com::sun::star::uno::Reference< ::com::sun::star::logging::XSimpleLogRing > m_xLogRing;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > m_xPackage;
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;
+
+ // valid only for root storage
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > m_xInputStream; // ??? may be stored in properties
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > m_xStream; // ??? may be stored in properties
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > m_xProperties;
+ sal_Bool m_bHasCommonPassword;
+ ::rtl::OUString m_aCommonPassword;
+
+ // must be empty in case of root storage
+ OStorage_Impl* m_pParent;
+
+ sal_Bool m_bControlMediaType;
+ ::rtl::OUString m_aMediaType;
+ sal_Bool m_bMTFallbackUsed;
+
+ sal_Bool m_bControlVersion;
+ ::rtl::OUString m_aVersion;
+
+ SwitchablePersistenceStream* m_pSwitchStream;
+
+ sal_Int32 m_nStorageType; // the mode in wich the storage is used
+
+ // the _rels substorage that is handled in a special way in embed::StorageFormats::OFOPXML
+ SotElement_Impl* m_pRelStorElement;
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > m_xRelStorage;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > m_aRelInfo;
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > m_xNewRelInfoStream;
+ sal_Int16 m_nRelInfoStatus;
+
+ //////////////////////////////////////////
+ // Constructors
+
+ OStorage_Impl( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xInputStream,
+ sal_Int32 nMode,
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > xProperties,
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory,
+ sal_Int32 nStorageType );
+
+ OStorage_Impl( ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > xStream,
+ sal_Int32 nMode,
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > xProperties,
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory,
+ sal_Int32 nStorageType );
+
+ // constructor for a substorage
+ OStorage_Impl( OStorage_Impl* pParent,
+ sal_Int32 nMode,
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > xPackageFolder,
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > xPackage,
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory,
+ sal_Int32 nStorageType );
+
+ ~OStorage_Impl();
+
+ void AddLog( const ::rtl::OUString& aMessage );
+
+ void SetReadOnlyWrap( OStorage& aStorage );
+ void RemoveReadOnlyWrap( OStorage& aStorage );
+
+ void OpenOwnPackage();
+ void ReadContents();
+ void ReadRelInfoIfNecessary();
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > GetServiceFactory();
+ SotElementList_Impl& GetChildrenList();
+ void GetStorageProperties();
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > GetAllRelationshipsIfAny();
+ void CopyLastCommitTo( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xNewStor );
+ void CopyLastCommitTo( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xNewStor,
+ const ::rtl::OUString& aPass );
+
+ void InsertIntoPackageFolder(
+ const ::rtl::OUString& aName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& xParentPackageFolder );
+
+ void Commit();
+ void Revert();
+
+ ::rtl::OUString GetCommonRootPass() throw ( ::com::sun::star::packages::NoEncryptionException );
+
+ void CopyToStorage( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xDest,
+ sal_Bool bDirect );
+ void CopyStorageElement( SotElement_Impl* pElement,
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > xDest,
+ ::rtl::OUString aName,
+ sal_Bool bDirect );
+
+ void SetModified( sal_Bool bModified );
+
+ SotElement_Impl* FindElement( const ::rtl::OUString& rName );
+
+
+ SotElement_Impl* InsertStream( ::rtl::OUString aName, sal_Bool bEncr );
+ SotElement_Impl* InsertRawStream( ::rtl::OUString aName, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInStream );
+
+ OStorage_Impl* CreateNewStorageImpl( sal_Int32 nStorageMode );
+ SotElement_Impl* InsertStorage( ::rtl::OUString aName, sal_Int32 nStorageMode );
+ SotElement_Impl* InsertElement( ::rtl::OUString aName, sal_Bool bIsStorage );
+
+ void OpenSubStorage( SotElement_Impl* pElement, sal_Int32 nStorageMode );
+ void OpenSubStream( SotElement_Impl* pElement );
+
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > GetElementNames();
+
+ void RemoveElement( SotElement_Impl* pElement );
+ void ClearElement( SotElement_Impl* pElement );
+ void DisposeChildren();
+
+ void CloneStreamElement(
+ const ::rtl::OUString& aStreamName,
+ sal_Bool bPassProvided,
+ const ::rtl::OUString& aPass,
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xTargetStream )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::packages::WrongPasswordException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ void RemoveStreamRelInfo( const ::rtl::OUString& aOriginalName );
+ void CreateRelStorage();
+ void CommitStreamRelInfo( SotElement_Impl* pStreamElement );
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetRelInfoStreamForName( const ::rtl::OUString& aName );
+ void CommitRelInfo( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& xNewPackageFolder );
+
+ static void completeStorageStreamCopy_Impl(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xSource,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xDest,
+ sal_Int32 nStorageType,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > >& aRelInfo );
+
+};
+
+
+class OStorage : public ::com::sun::star::lang::XTypeProvider
+ , public ::com::sun::star::embed::XStorage
+ , public ::com::sun::star::embed::XStorageRawAccess
+ , public ::com::sun::star::embed::XTransactedObject
+ , public ::com::sun::star::embed::XTransactionBroadcaster
+ , public ::com::sun::star::util::XModifiable
+ // , public ::com::sun::star::container::XNameAccess
+ // , public ::com::sun::star::lang::XComponent
+ , public ::com::sun::star::embed::XEncryptionProtectedSource
+ , public ::com::sun::star::beans::XPropertySet
+ , public ::com::sun::star::embed::XOptimizedStorage
+ , public ::com::sun::star::embed::XRelationshipAccess
+ , public ::com::sun::star::embed::XHierarchicalStorageAccess
+ , public ::cppu::OWeakObject
+{
+ OStorage_Impl* m_pImpl;
+ StorInternalData_Impl* m_pData;
+
+protected:
+
+ void Commit_Impl();
+
+ SotElement_Impl* OpenStreamElement_Impl( const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode, sal_Bool bEncr );
+
+ void BroadcastModifiedIfNecessary();
+
+ void BroadcastTransaction( sal_Int8 nMessage );
+
+ void MakeLinkToSubComponent_Impl(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xComponent );
+
+public:
+
+ OStorage( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xInputStream,
+ sal_Int32 nMode,
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > xProperties,
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory,
+ sal_Int32 nStorageType );
+
+ OStorage( ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > xStream,
+ sal_Int32 nMode,
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > xProperties,
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory,
+ sal_Int32 nStorageType );
+
+ OStorage( OStorage_Impl* pImpl, sal_Bool bReadOnlyWrap );
+
+ virtual ~OStorage();
+
+ void SAL_CALL InternalDispose( sal_Bool bNotifyImpl );
+
+ void ChildIsDisposed( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xChild );
+
+ sal_Int32 GetRefCount_Impl() { return m_refCount; }
+
+ //____________________________________________________________________________________________________
+ // XInterface
+ //____________________________________________________________________________________________________
+
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL acquire() throw();
+
+ virtual void SAL_CALL release() throw();
+
+ //____________________________________________________________________________________________________
+ // XTypeProvider
+ //____________________________________________________________________________________________________
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //____________________________________________________________________________________________________
+ // XStorage
+ //____________________________________________________________________________________________________
+
+ virtual void SAL_CALL copyToStorage( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xDest )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > SAL_CALL openStreamElement(
+ const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::packages::WrongPasswordException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > SAL_CALL openEncryptedStreamElement(
+ const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode, const ::rtl::OUString& aPass )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::packages::NoEncryptionException,
+ ::com::sun::star::packages::WrongPasswordException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > SAL_CALL openStorageElement(
+ const ::rtl::OUString& aStorName, sal_Int32 nStorageMode )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > SAL_CALL cloneStreamElement(
+ const ::rtl::OUString& aStreamName )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::packages::WrongPasswordException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > SAL_CALL cloneEncryptedStreamElement(
+ const ::rtl::OUString& aStreamName, const ::rtl::OUString& aPass )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::packages::NoEncryptionException,
+ ::com::sun::star::packages::WrongPasswordException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL copyLastCommitTo(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xTargetStorage )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL copyStorageElementLastCommitTo(
+ const ::rtl::OUString& aStorName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xTargetStorage )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL isStreamElement( const ::rtl::OUString& aElementName )
+ throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL isStorageElement( const ::rtl::OUString& aElementName )
+ throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL removeElement( const ::rtl::OUString& aElementName )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL renameElement( const ::rtl::OUString& rEleName, const ::rtl::OUString& rNewName )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL copyElementTo( const ::rtl::OUString& aElementName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xDest,
+ const ::rtl::OUString& aNewName )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL moveElementTo( const ::rtl::OUString& aElementName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xDest,
+ const ::rtl::OUString& rNewName )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ //____________________________________________________________________________________________________
+ // XStorageRawAccess
+ //____________________________________________________________________________________________________
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getPlainRawStreamElement(
+ const ::rtl::OUString& sStreamName )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getRawEncrStreamElement(
+ const ::rtl::OUString& sStreamName )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::packages::NoEncryptionException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL insertRawEncrStreamElement( const ::rtl::OUString& aStreamName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInStream )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::packages::NoRawFormatException,
+ ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ //____________________________________________________________________________________________________
+ // XTransactedObject
+ //____________________________________________________________________________________________________
+
+ virtual void SAL_CALL commit()
+ throw ( ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL revert()
+ throw ( ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ //____________________________________________________________________________________________________
+ // XTransactionBroadcaster
+ //____________________________________________________________________________________________________
+
+ virtual void SAL_CALL addTransactionListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XTransactionListener >& aListener )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL removeTransactionListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XTransactionListener >& aListener )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ //____________________________________________________________________________________________________
+ // XModifiable
+ //____________________________________________________________________________________________________
+
+ virtual sal_Bool SAL_CALL isModified()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setModified( sal_Bool bModified )
+ throw ( ::com::sun::star::beans::PropertyVetoException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL addModifyListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL removeModifyListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ //____________________________________________________________________________________________________
+ // XNameAccess
+ //____________________________________________________________________________________________________
+
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
+ throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL hasElements()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ //____________________________________________________________________________________________________
+ // XComponent
+ //____________________________________________________________________________________________________
+
+ virtual void SAL_CALL dispose()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL addEventListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL removeEventListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ //____________________________________________________________________________________________________
+ // XEncryptionProtectedSource
+ //____________________________________________________________________________________________________
+
+ virtual void SAL_CALL setEncryptionPassword( const ::rtl::OUString& aPass )
+ throw ( ::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::io::IOException );
+
+ virtual void SAL_CALL removeEncryption()
+ throw ( ::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::io::IOException );
+
+ //____________________________________________________________________________________________________
+ // XPropertySet
+ //____________________________________________________________________________________________________
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue )
+ throw ( ::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::beans::PropertyVetoException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName )
+ throw ( ::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL addPropertyChangeListener(
+ const ::rtl::OUString& aPropertyName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener )
+ throw ( ::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL removePropertyChangeListener(
+ const ::rtl::OUString& aPropertyName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener )
+ throw ( ::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL addVetoableChangeListener(
+ const ::rtl::OUString& PropertyName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw ( ::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw ( ::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ //____________________________________________________________________________________________________
+ // XOptimizedStorage
+ //____________________________________________________________________________________________________
+ virtual void SAL_CALL insertRawNonEncrStreamElementDirect( const ::rtl::OUString& sStreamName, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInStream )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::packages::NoRawFormatException,
+ ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL insertStreamElementDirect( const ::rtl::OUString& sStreamName, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInStream, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL copyElementDirectlyTo( const ::rtl::OUString& sSourceName, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XOptimizedStorage >& xTargetStorage, const ::rtl::OUString& sTargetName )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL writeAndAttachToStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xStream )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL attachToURL( const ::rtl::OUString& sURL, sal_Bool bReadOnly )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Any SAL_CALL getElementPropertyValue( const ::rtl::OUString& sElementName, const ::rtl::OUString& sPropertyName )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::beans::PropertyVetoException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL copyStreamElementData( const ::rtl::OUString& sStreamName, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xTargetStream )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::packages::WrongPasswordException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ //____________________________________________________________________________________________________
+ // XRelationshipAccess
+ //____________________________________________________________________________________________________
+
+ virtual ::sal_Bool SAL_CALL hasByID( const ::rtl::OUString& sID )
+ throw ( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getTargetByID( const ::rtl::OUString& sID )
+ throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getTypeByID( const ::rtl::OUString& sID )
+ throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > SAL_CALL getRelationshipByID( const ::rtl::OUString& sID )
+ throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > SAL_CALL getRelationshipsByType( const ::rtl::OUString& sType )
+ throw ( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > SAL_CALL getAllRelationships( )
+ throw ( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL insertRelationshipByID( const ::rtl::OUString& sID, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair >& aEntry, ::sal_Bool bReplace )
+ throw ( ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL removeRelationshipByID( const ::rtl::OUString& sID )
+ throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL insertRelationships( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > >& aEntries, ::sal_Bool bReplace )
+ throw ( ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL clearRelationships( )
+ throw ( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException);
+
+ //____________________________________________________________________________________________________
+ // XHierarchicalStorageAccess
+ //____________________________________________________________________________________________________
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XExtendedStorageStream > SAL_CALL openStreamElementByHierarchicalName( const ::rtl::OUString& sStreamPath, ::sal_Int32 nOpenMode )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::packages::WrongPasswordException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XExtendedStorageStream > SAL_CALL openEncryptedStreamElementByHierarchicalName( const ::rtl::OUString& sStreamName, ::sal_Int32 nOpenMode, const ::rtl::OUString& sPassword )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::packages::NoEncryptionException,
+ ::com::sun::star::packages::WrongPasswordException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL removeStreamElementByHierarchicalName( const ::rtl::OUString& sElementPath )
+ throw ( ::com::sun::star::embed::InvalidStorageException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::embed::StorageWrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+};
+
+
+#endif
+
diff --git a/package/source/zipapi/ByteChucker.cxx b/package/source/zipapi/ByteChucker.cxx
new file mode 100644
index 000000000000..3b93c4696148
--- /dev/null
+++ b/package/source/zipapi/ByteChucker.cxx
@@ -0,0 +1,112 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ByteChucker.hxx>
+#include <PackageConstants.hxx>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+
+ByteChucker::ByteChucker(Reference<XOutputStream> xOstream)
+: xStream(xOstream)
+, xSeek (xOstream, UNO_QUERY )
+, a1Sequence ( 1 )
+, a2Sequence ( 2 )
+, a4Sequence ( 4 )
+, p1Sequence ( a1Sequence.getArray() )
+, p2Sequence ( a2Sequence.getArray() )
+, p4Sequence ( a4Sequence.getArray() )
+{
+}
+
+ByteChucker::~ByteChucker()
+{
+}
+
+void ByteChucker::WriteBytes( const Sequence< sal_Int8 >& aData )
+ throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ xStream->writeBytes(aData);
+}
+
+sal_Int64 ByteChucker::GetPosition( )
+ throw(IOException, RuntimeException)
+{
+ return xSeek->getPosition();
+}
+
+ByteChucker& ByteChucker::operator << (sal_Int8 nInt8)
+{
+ p1Sequence[0] = nInt8 & 0xFF;
+ WriteBytes( a1Sequence );
+ return *this;
+}
+
+ByteChucker& ByteChucker::operator << (sal_Int16 nInt16)
+{
+ p2Sequence[0] = static_cast< sal_Int8 >((nInt16 >> 0 ) & 0xFF);
+ p2Sequence[1] = static_cast< sal_Int8 >((nInt16 >> 8 ) & 0xFF);
+ WriteBytes( a2Sequence );
+ return *this;
+}
+ByteChucker& ByteChucker::operator << (sal_Int32 nInt32)
+{
+ p4Sequence[0] = static_cast< sal_Int8 >((nInt32 >> 0 ) & 0xFF);
+ p4Sequence[1] = static_cast< sal_Int8 >((nInt32 >> 8 ) & 0xFF);
+ p4Sequence[2] = static_cast< sal_Int8 >((nInt32 >> 16 ) & 0xFF);
+ p4Sequence[3] = static_cast< sal_Int8 >((nInt32 >> 24 ) & 0xFF);
+ WriteBytes( a4Sequence );
+ return *this;
+}
+
+ByteChucker& ByteChucker::operator << (sal_uInt8 nuInt8)
+{
+ p1Sequence[0] = nuInt8 & 0xFF;
+ WriteBytes( a1Sequence );
+ return *this;
+}
+ByteChucker& ByteChucker::operator << (sal_uInt16 nuInt16)
+{
+ p2Sequence[0] = static_cast< sal_Int8 >((nuInt16 >> 0 ) & 0xFF);
+ p2Sequence[1] = static_cast< sal_Int8 >((nuInt16 >> 8 ) & 0xFF);
+ WriteBytes( a2Sequence );
+ return *this;
+}
+ByteChucker& ByteChucker::operator << (sal_uInt32 nuInt32)
+{
+ p4Sequence[0] = static_cast < sal_Int8 > ((nuInt32 >> 0 ) & 0xFF);
+ p4Sequence[1] = static_cast < sal_Int8 > ((nuInt32 >> 8 ) & 0xFF);
+ p4Sequence[2] = static_cast < sal_Int8 > ((nuInt32 >> 16 ) & 0xFF);
+ p4Sequence[3] = static_cast < sal_Int8 > ((nuInt32 >> 24 ) & 0xFF);
+ WriteBytes( a4Sequence );
+ return *this;
+}
diff --git a/package/source/zipapi/ByteGrabber.cxx b/package/source/zipapi/ByteGrabber.cxx
new file mode 100644
index 000000000000..40998c3de70d
--- /dev/null
+++ b/package/source/zipapi/ByteGrabber.cxx
@@ -0,0 +1,191 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ByteGrabber.hxx>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+
+using namespace ::com::sun::star;
+
+/** ByteGrabber implements the >> operators on an XOutputStream. This is
+ * potentially quite slow and may need to be optimised
+ */
+
+ByteGrabber::ByteGrabber(uno::Reference < io::XInputStream > xIstream)
+: xStream(xIstream)
+, xSeek (xIstream, uno::UNO_QUERY )
+, aSequence ( 4 )
+{
+ pSequence = aSequence.getArray();
+}
+
+ByteGrabber::~ByteGrabber()
+{
+}
+
+void ByteGrabber::setInputStream (uno::Reference < io::XInputStream > xNewStream)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ xStream = xNewStream;
+ xSeek = uno::Reference < io::XSeekable > (xNewStream, uno::UNO_QUERY);
+}
+
+// XInputStream chained
+sal_Int32 SAL_CALL ByteGrabber::readBytes( uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nBytesToRead )
+ throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return xStream->readBytes(aData, nBytesToRead );
+}
+
+// XSeekable chained...
+sal_Int64 SAL_CALL ByteGrabber::seek( sal_Int64 location )
+ throw(lang::IllegalArgumentException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if (xSeek.is() )
+ {
+ sal_Int64 nLen = xSeek->getLength();
+ if ( location < 0 || location > nLen )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+ if (location > nLen )
+ location = nLen;
+ xSeek->seek( location );
+ return location;
+ }
+ else
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+sal_Int64 SAL_CALL ByteGrabber::getPosition( )
+ throw(io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if (xSeek.is() )
+ return xSeek->getPosition();
+ else
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+sal_Int64 SAL_CALL ByteGrabber::getLength( )
+ throw(io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if (xSeek.is() )
+ return xSeek->getLength();
+ else
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+ByteGrabber& ByteGrabber::operator >> (sal_Int8& rInt8)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if (xStream->readBytes(aSequence,1) != 1)
+ rInt8 = 0;
+ else
+ rInt8 = aSequence[0] & 0xFF;
+ return *this;
+}
+
+ByteGrabber& ByteGrabber::operator >> (sal_Int16& rInt16)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if (xStream->readBytes ( aSequence, 2) != 2)
+ rInt16 = 0;
+ else
+ {
+ pSequence = aSequence.getConstArray();
+ rInt16 = static_cast <sal_Int16>
+ ( (pSequence[0] & 0xFF)
+ | (pSequence[1] & 0xFF) << 8);
+ }
+ return *this;
+}
+
+ByteGrabber& ByteGrabber::operator >> (sal_Int32& rInt32)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if (xStream->readBytes(aSequence, 4) != 4)
+ rInt32 = 0;
+ else
+ {
+ pSequence = aSequence.getConstArray();
+ rInt32 = static_cast < sal_Int32 >
+ ( (pSequence[0] & 0xFF)
+ | ( pSequence[1] & 0xFF ) << 8
+ | ( pSequence[2] & 0xFF ) << 16
+ | ( pSequence[3] & 0xFF ) << 24 );
+ }
+ return *this;
+}
+
+ByteGrabber& ByteGrabber::operator >> (sal_uInt8& rInt8)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if (xStream->readBytes(aSequence,1) != 1)
+ rInt8 = 0;
+ else
+ rInt8 = static_cast < sal_uInt8 > (aSequence[0] & 0xFF );
+ return *this;
+}
+ByteGrabber& ByteGrabber::operator >> (sal_uInt16& rInt16)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if (xStream->readBytes(aSequence, 2) != 2)
+ rInt16 = 0;
+ else
+ {
+ pSequence = aSequence.getConstArray();
+ rInt16 = static_cast <sal_uInt16>
+ ( (pSequence[0] & 0xFF)
+ | (pSequence[1] & 0xFF) << 8);
+ }
+ return *this;
+}
+ByteGrabber& ByteGrabber::operator >> (sal_uInt32& ruInt32)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if (xStream->readBytes(aSequence, 4) != 4)
+ ruInt32 = 0;
+ else
+ {
+ pSequence = aSequence.getConstArray();
+ ruInt32 = static_cast < sal_uInt32 >
+ ( (pSequence[0] & 0xFF)
+ | ( pSequence[1] & 0xFF ) << 8
+ | ( pSequence[2] & 0xFF ) << 16
+ | ( pSequence[3] & 0xFF ) << 24 );
+ }
+ return *this;
+}
diff --git a/package/source/zipapi/CRC32.cxx b/package/source/zipapi/CRC32.cxx
new file mode 100644
index 000000000000..2ee6b1feea1a
--- /dev/null
+++ b/package/source/zipapi/CRC32.cxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <CRC32.hxx>
+#ifndef _ZLIB_H
+#ifdef SYSTEM_ZLIB
+#include <zlib.h>
+#else
+#include <external/zlib/zlib.h>
+#endif
+#endif
+#include <PackageConstants.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::io;
+
+/** A class to compute the CRC32 value of a data stream
+ */
+
+CRC32::CRC32()
+: nCRC(0)
+{
+}
+CRC32::~CRC32()
+{
+}
+void SAL_CALL CRC32::reset()
+ throw(RuntimeException)
+{
+ nCRC=0;
+}
+sal_Int32 SAL_CALL CRC32::getValue()
+ throw(RuntimeException)
+{
+ return nCRC & 0xFFFFFFFFL;
+}
+/** Update CRC32 with specified sequence of bytes
+ */
+void SAL_CALL CRC32::updateSegment(const Sequence< sal_Int8 > &b,
+ sal_Int32 off,
+ sal_Int32 len)
+ throw(RuntimeException)
+{
+ nCRC = crc32(nCRC, (const unsigned char*)b.getConstArray()+off, len );
+}
+/** Update CRC32 with specified sequence of bytes
+ */
+void SAL_CALL CRC32::update(const Sequence< sal_Int8 > &b)
+ throw(RuntimeException)
+{
+ nCRC = crc32(nCRC, (const unsigned char*)b.getConstArray(),b.getLength());
+}
+
+sal_Int32 SAL_CALL CRC32::updateStream( Reference < XInputStream > & xStream )
+ throw ( RuntimeException )
+{
+ sal_Int32 nLength, nTotal = 0;
+ Sequence < sal_Int8 > aSeq ( n_ConstBufferSize );
+ do
+ {
+ nLength = xStream->readBytes ( aSeq, n_ConstBufferSize );
+ updateSegment ( aSeq, 0, nLength );
+ nTotal += nLength;
+ }
+ while ( nLength == n_ConstBufferSize );
+
+ return nTotal;
+}
diff --git a/package/source/zipapi/Deflater.cxx b/package/source/zipapi/Deflater.cxx
new file mode 100644
index 000000000000..ac12a8cb5831
--- /dev/null
+++ b/package/source/zipapi/Deflater.cxx
@@ -0,0 +1,212 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <Deflater.hxx>
+#ifndef _ZLIB_H
+#ifdef SYSTEM_ZLIB
+#include <zlib.h>
+#else
+#include <external/zlib/zlib.h>
+#endif
+#endif
+#include <com/sun/star/packages/zip/ZipConstants.hpp>
+#include <string.h> // for memset
+
+using namespace com::sun::star::packages::zip::ZipConstants;
+using namespace com::sun::star;
+
+/** Provides general purpose compression using the ZLIB compression
+ * library.
+ */
+
+Deflater::~Deflater(void)
+{
+ end();
+}
+void Deflater::init (sal_Int32 nLevelArg, sal_Int32 nStrategyArg, sal_Bool bNowrap)
+{
+ pStream = new z_stream;
+ /* Memset it to 0...sets zalloc/zfree/opaque to NULL */
+ memset (pStream, 0, sizeof(*pStream));
+
+ switch (deflateInit2(pStream, nLevelArg, Z_DEFLATED, bNowrap? -MAX_WBITS : MAX_WBITS,
+ DEF_MEM_LEVEL, nStrategyArg))
+ {
+ case Z_OK:
+ break;
+ case Z_MEM_ERROR:
+ delete pStream;
+ break;
+ case Z_STREAM_ERROR:
+ delete pStream;
+ break;
+ default:
+ break;
+ }
+}
+
+Deflater::Deflater(sal_Int32 nSetLevel, sal_Bool bNowrap)
+: bFinish(sal_False)
+, bFinished(sal_False)
+, bSetParams(sal_False)
+, nLevel(nSetLevel)
+, nStrategy(DEFAULT_STRATEGY)
+, nOffset(0)
+, nLength(0)
+{
+ init(nSetLevel, DEFAULT_STRATEGY, bNowrap);
+}
+
+sal_Int32 Deflater::doDeflateBytes (uno::Sequence < sal_Int8 > &rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength)
+{
+ sal_Int32 nResult;
+ if (bSetParams)
+ {
+ pStream->next_in = (unsigned char*) sInBuffer.getConstArray() + nOffset;
+ pStream->next_out = (unsigned char*) rBuffer.getArray()+nNewOffset;
+ pStream->avail_in = nLength;
+ pStream->avail_out = nNewLength;
+
+#ifdef SYSTEM_ZLIB
+ nResult = deflateParams(pStream, nLevel, nStrategy);
+#else
+ nResult = z_deflateParams(pStream, nLevel, nStrategy);
+#endif
+ switch (nResult)
+ {
+ case Z_OK:
+ bSetParams = sal_False;
+ nOffset += nLength - pStream->avail_in;
+ nLength = pStream->avail_in;
+ return nNewLength - pStream->avail_out;
+ case Z_BUF_ERROR:
+ bSetParams = sal_False;
+ return 0;
+ default:
+ return 0;
+ }
+ }
+ else
+ {
+ pStream->next_in = (unsigned char*) sInBuffer.getConstArray() + nOffset;
+ pStream->next_out = (unsigned char*) rBuffer.getArray()+nNewOffset;
+ pStream->avail_in = nLength;
+ pStream->avail_out = nNewLength;
+
+#ifdef SYSTEM_ZLIB
+ nResult = deflate(pStream, bFinish ? Z_FINISH : Z_NO_FLUSH);
+#else
+ nResult = z_deflate(pStream, bFinish ? Z_FINISH : Z_NO_FLUSH);
+#endif
+ switch (nResult)
+ {
+ case Z_STREAM_END:
+ bFinished = sal_True;
+ case Z_OK:
+ nOffset += nLength - pStream->avail_in;
+ nLength = pStream->avail_in;
+ return nNewLength - pStream->avail_out;
+ case Z_BUF_ERROR:
+ bSetParams = sal_False;
+ return 0;
+ default:
+ return 0;
+ }
+ }
+}
+
+void SAL_CALL Deflater::setInputSegment( const uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
+{
+ OSL_ASSERT( !(nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > rBuffer.getLength()));
+
+ sInBuffer = rBuffer;
+ nOffset = nNewOffset;
+ nLength = nNewLength;
+}
+void SAL_CALL Deflater::setLevel( sal_Int32 nNewLevel )
+{
+ if ((nNewLevel < 0 || nNewLevel > 9) && nNewLevel != DEFAULT_COMPRESSION)
+ {
+ // do error handling
+ }
+ if (nNewLevel != nLevel)
+ {
+ nLevel = nNewLevel;
+ bSetParams = sal_True;
+ }
+}
+sal_Bool SAL_CALL Deflater::needsInput( )
+{
+ return nLength <=0;
+}
+void SAL_CALL Deflater::finish( )
+{
+ bFinish = sal_True;
+}
+sal_Bool SAL_CALL Deflater::finished( )
+{
+ return bFinished;
+}
+sal_Int32 SAL_CALL Deflater::doDeflateSegment( uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
+{
+ OSL_ASSERT( !(nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > rBuffer.getLength()));
+ return doDeflateBytes(rBuffer, nNewOffset, nNewLength);
+}
+sal_Int32 SAL_CALL Deflater::getTotalIn( )
+{
+ return pStream->total_in;
+}
+sal_Int32 SAL_CALL Deflater::getTotalOut( )
+{
+ return pStream->total_out;
+}
+void SAL_CALL Deflater::reset( )
+{
+#ifdef SYSTEM_ZLIB
+ deflateReset(pStream);
+#else
+ z_deflateReset(pStream);
+#endif
+ bFinish = sal_False;
+ bFinished = sal_False;
+ nOffset = nLength = 0;
+}
+void SAL_CALL Deflater::end( )
+{
+ if (pStream != NULL)
+ {
+#ifdef SYSTEM_ZLIB
+ deflateEnd(pStream);
+#else
+ z_deflateEnd(pStream);
+#endif
+ delete pStream;
+ }
+ pStream = NULL;
+}
diff --git a/package/source/zipapi/EntryInputStream.cxx b/package/source/zipapi/EntryInputStream.cxx
new file mode 100644
index 000000000000..671ef7381f9d
--- /dev/null
+++ b/package/source/zipapi/EntryInputStream.cxx
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <EntryInputStream.hxx>
+#include <com/sun/star/packages/zip/ZipConstants.hpp>
+#include <rtl/cipher.h>
+#include <rtl/digest.h>
+#include <memory.h> // for memcpy
+
+using namespace rtl;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::packages::zip;
+using namespace com::sun::star::packages::zip::ZipConstants;
+
+/** Provides access to the compressed data in a zipfile.
+ *
+ * 04/12/00 - uncompresses the stream into memory and seeks on it 'in memory'
+ * This and the ZipPackageBuffer used in the ZipOutputStream are memory hogs
+ * and will hopefully be replaced eventually
+ *
+ * Acts on the same underlying XInputStream as both the full Zip File and other
+ * EntryInputStreams, and thus must maintain its current position in the stream and
+ * seek to it before performing any reads.
+ */
+
+EntryInputStream::EntryInputStream( Reference < io::XInputStream > xNewInput,
+ const ZipEntry & rNewEntry,
+ const vos::ORef < EncryptionData > &xEncryptData,
+ sal_Bool bGetRawStream)
+: xStream( xNewInput )
+, xSeek( xNewInput, UNO_QUERY )
+, aEntry (rNewEntry )
+, nCurrent( 0 )
+, bHaveInMemory ( sal_False )
+, aInflater( sal_True )
+, aBuffer( 0 )
+, xEncryptionData (xEncryptData)
+, bRawStream (bGetRawStream)
+{
+ if (bGetRawStream)
+ {
+ nUncompressedSize = aEntry.nMethod == DEFLATED ? aEntry.nCompressedSize : aEntry.nSize;
+ nEnd = aEntry.nOffset + nUncompressedSize;
+ }
+ else
+ {
+ nEnd = aEntry.nMethod == DEFLATED ? aEntry.nOffset + aEntry.nCompressedSize : aEntry.nOffset + aEntry.nSize;
+ nUncompressedSize = aEntry.nSize;
+ }
+}
+void EntryInputStream::readIntoMemory()
+ throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, RuntimeException)
+{
+ if (!bHaveInMemory)
+ {
+ Sequence < sal_Int8 > aReadBuffer;
+ xSeek->seek(aEntry.nOffset);
+ sal_Int32 nSize = aEntry.nMethod == DEFLATED ? aEntry.nCompressedSize : aEntry.nSize;
+
+ if (nSize <0)
+ throw io::BufferSizeExceededException(::rtl::OUString(), *this);
+
+ xStream->readBytes( aReadBuffer, nSize ); // Now it holds the raw stuff from disk
+
+ if (xEncryptionData->aSalt.getLength())
+ {
+ // Have salt, will travel
+ Sequence < sal_uInt8 > aDerivedKey (16);
+ rtlCipherError aResult;
+ Sequence < sal_Int8 > aDecryptBuffer;
+
+ // Get the key
+ rtl_digest_PBKDF2 ( aDerivedKey.getArray(), 16,
+ reinterpret_cast < const sal_uInt8 * > (xEncryptionData->aKey.getConstArray()),
+ xEncryptionData->aKey.getLength(),
+ xEncryptionData->aSalt.getConstArray(),
+ xEncryptionData->aSalt.getLength(),
+ xEncryptionData->nIterationCount );
+
+ rtlCipher aCipher = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream);
+ aResult = rtl_cipher_init( aCipher, rtl_Cipher_DirectionDecode,
+ aDerivedKey.getConstArray(),
+ aDerivedKey.getLength(),
+ xEncryptionData->aInitVector.getConstArray(),
+ xEncryptionData->aInitVector.getLength());
+ OSL_ASSERT (aResult == rtl_Cipher_E_None);
+ aDecryptBuffer.realloc ( nSize );
+ aResult = rtl_cipher_decode ( aCipher,
+ aReadBuffer.getConstArray(),
+ nSize,
+ reinterpret_cast < sal_uInt8 * > (aDecryptBuffer.getArray()),
+ nSize);
+ OSL_ASSERT (aResult == rtl_Cipher_E_None);
+ aReadBuffer = aDecryptBuffer; // Now it holds the decrypted data
+ }
+ if (bRawStream || aEntry.nMethod == STORED)
+ aBuffer = aReadBuffer; // bRawStream means the caller doesn't want it decompressed
+ else
+ {
+ aInflater.setInputSegment(aReadBuffer, 0, nSize );
+ aBuffer.realloc( aEntry.nSize );
+ aInflater.doInflate(aBuffer);
+ aInflater.end();
+ }
+ bHaveInMemory = sal_True;
+ }
+}
+EntryInputStream::~EntryInputStream( void )
+{
+}
+
+sal_Int32 SAL_CALL EntryInputStream::readBytes( Sequence< sal_Int8 >& aData,
+ sal_Int32 nBytesToRead )
+ throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, RuntimeException)
+{
+ if (nBytesToRead <0)
+ throw io::BufferSizeExceededException(::rtl::OUString(), *this);
+ if (!bHaveInMemory)
+ readIntoMemory();
+ if (nBytesToRead + nCurrent > nUncompressedSize)
+ nBytesToRead = static_cast < sal_Int32> ( nUncompressedSize - nCurrent );
+
+ aData.realloc( nBytesToRead );
+ memcpy(aData.getArray(), aBuffer.getConstArray() + nCurrent, nBytesToRead);
+ nCurrent+=nBytesToRead;
+
+ return nBytesToRead;
+}
+sal_Int32 SAL_CALL EntryInputStream::readSomeBytes( Sequence< sal_Int8 >& aData,
+ sal_Int32 nMaxBytesToRead )
+ throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, RuntimeException)
+{
+ return readBytes( aData, nMaxBytesToRead );
+}
+void SAL_CALL EntryInputStream::skipBytes( sal_Int32 nBytesToSkip )
+ throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, RuntimeException)
+{
+ if (nBytesToSkip < 0)
+ throw io::BufferSizeExceededException(::rtl::OUString(), *this);
+
+ if (nBytesToSkip + nCurrent > nUncompressedSize)
+ nBytesToSkip = static_cast < sal_Int32 > (nUncompressedSize- nCurrent);
+
+ nCurrent+=nBytesToSkip;
+}
+sal_Int32 SAL_CALL EntryInputStream::available( )
+ throw(io::NotConnectedException, io::IOException, RuntimeException)
+{
+ return static_cast < sal_Int32 > (nUncompressedSize - nCurrent);
+}
+void SAL_CALL EntryInputStream::closeInput( )
+ throw(io::NotConnectedException, io::IOException, RuntimeException)
+{
+}
+
+void SAL_CALL EntryInputStream::seek( sal_Int64 location )
+ throw(lang::IllegalArgumentException, io::IOException, RuntimeException)
+{
+ if (location > nUncompressedSize)
+ location = nUncompressedSize;
+ if (location <0)
+ location = 0;
+ nCurrent = location;
+}
+sal_Int64 SAL_CALL EntryInputStream::getPosition( )
+ throw(io::IOException, RuntimeException)
+{
+ return nCurrent;
+}
+sal_Int64 SAL_CALL EntryInputStream::getLength( )
+ throw(io::IOException, RuntimeException)
+{
+ return nUncompressedSize;
+}
diff --git a/package/source/zipapi/EntryInputStream.hxx b/package/source/zipapi/EntryInputStream.hxx
new file mode 100644
index 000000000000..c04a5dc2d33b
--- /dev/null
+++ b/package/source/zipapi/EntryInputStream.hxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _ENTRY_INPUT_STREAM_HXX
+#define _ENTRY_INPUT_STREAM_HXX
+
+#include <cppuhelper/implbase2.hxx> // helper for implementations
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <Inflater.hxx>
+#include <com/sun/star/packages/zip/ZipEntry.hpp>
+#ifndef _VOS_REF_H_
+#include <vos/ref.hxx>
+#endif
+#ifndef _ENCRYPTION_DATA_HXX
+#include <EncryptionData.hxx>
+#endif
+class EntryInputStream : public cppu::WeakImplHelper2< com::sun::star::io::XInputStream,
+ com::sun::star::io::XSeekable >
+{
+protected:
+ com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xStream;
+ com::sun::star::uno::Reference< com::sun::star::io::XSeekable > xSeek;
+ sal_Int64 nEnd, nCurrent, nUncompressedSize;
+ sal_Bool bRawStream, bHaveInMemory, bEncrypted;
+ com::sun::star::uno::Sequence < sal_Int8 > aBuffer;
+ const vos::ORef < EncryptionData > xEncryptionData;
+ const com::sun::star::packages::zip::ZipEntry aEntry;
+ Inflater aInflater;
+ void readIntoMemory()
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+public:
+ EntryInputStream( com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xInput,
+ const com::sun::star::packages::zip::ZipEntry &rNewEntry,
+ const vos::ORef < EncryptionData > &xEncryptData,
+ sal_Bool bGetRawStream = sal_False);
+ virtual ~EntryInputStream();
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL available( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeInput( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ // XSeekable
+ virtual void SAL_CALL seek( sal_Int64 location )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getPosition( )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getLength( )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ /*
+private:
+ void fill( void );
+ */
+};
+
+#endif
diff --git a/package/source/zipapi/Inflater.cxx b/package/source/zipapi/Inflater.cxx
new file mode 100644
index 000000000000..e95809a35dad
--- /dev/null
+++ b/package/source/zipapi/Inflater.cxx
@@ -0,0 +1,162 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <Inflater.hxx>
+#ifndef _ZLIB_H
+#ifdef SYSTEM_ZLIB
+#include <zlib.h>
+#else
+#include <external/zlib/zlib.h>
+#endif
+#endif
+#include <string.h> // for memset
+
+using namespace com::sun::star::uno;
+
+/** Provides general purpose decompression using the ZLIB library */
+
+Inflater::Inflater(sal_Bool bNoWrap)
+: bFinished(sal_False),
+ bSetParams(sal_False),
+ bNeedDict(sal_False),
+ nOffset(0),
+ nLength(0),
+ nLastInflateError(0),
+ pStream(NULL)
+{
+ pStream = new z_stream;
+ /* memset to 0 to set zalloc/opaque etc */
+ memset (pStream, 0, sizeof(*pStream));
+ sal_Int32 nRes;
+ nRes = inflateInit2(pStream, bNoWrap ? -MAX_WBITS : MAX_WBITS);
+ switch (nRes)
+ {
+ case Z_OK:
+ break;
+ case Z_MEM_ERROR:
+ delete pStream;
+ break;
+ case Z_STREAM_ERROR:
+ delete pStream;
+ break;
+ default:
+ break;
+ }
+}
+
+Inflater::~Inflater()
+{
+ end();
+}
+
+void SAL_CALL Inflater::setInput( const Sequence< sal_Int8 >& rBuffer )
+{
+ sInBuffer = rBuffer;
+ nOffset = 0;
+ nLength = rBuffer.getLength();
+}
+
+sal_Bool SAL_CALL Inflater::needsDictionary( )
+{
+ return bNeedDict;
+}
+
+sal_Bool SAL_CALL Inflater::finished( )
+{
+ return bFinished;
+}
+
+sal_Int32 SAL_CALL Inflater::doInflateSegment( Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
+{
+ if (nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > rBuffer.getLength())
+ {
+ // do error handling
+ }
+ return doInflateBytes(rBuffer, nNewOffset, nNewLength);
+}
+
+void SAL_CALL Inflater::end( )
+{
+ if (pStream != NULL)
+ {
+#ifdef SYSTEM_ZLIB
+ inflateEnd(pStream);
+#else
+ z_inflateEnd(pStream);
+#endif
+ delete pStream;
+ }
+ pStream = NULL;
+}
+
+sal_Int32 Inflater::doInflateBytes (Sequence < sal_Int8 > &rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength)
+{
+ if ( !pStream )
+ {
+ nLastInflateError = Z_STREAM_ERROR;
+ return 0;
+ }
+
+ nLastInflateError = 0;
+
+ pStream->next_in = ( unsigned char* ) ( sInBuffer.getConstArray() + nOffset );
+ pStream->avail_in = nLength;
+ pStream->next_out = reinterpret_cast < unsigned char* > ( rBuffer.getArray() + nNewOffset );
+ pStream->avail_out = nNewLength;
+
+#ifdef SYSTEM_ZLIB
+ sal_Int32 nResult = ::inflate(pStream, Z_PARTIAL_FLUSH);
+#else
+ sal_Int32 nResult = ::z_inflate(pStream, Z_PARTIAL_FLUSH);
+#endif
+
+ switch (nResult)
+ {
+ case Z_STREAM_END:
+ bFinished = sal_True;
+ case Z_OK:
+ nOffset += nLength - pStream->avail_in;
+ nLength = pStream->avail_in;
+ return nNewLength - pStream->avail_out;
+
+ case Z_NEED_DICT:
+ bNeedDict = sal_True;
+ nOffset += nLength - pStream->avail_in;
+ nLength = pStream->avail_in;
+ return 0;
+
+ default:
+ // it is no error, if there is no input or no output
+ if ( nLength && nNewLength )
+ nLastInflateError = nResult;
+ }
+
+ return 0;
+}
+
diff --git a/package/source/zipapi/MemoryByteGrabber.hxx b/package/source/zipapi/MemoryByteGrabber.hxx
new file mode 100644
index 000000000000..8a8d96556bae
--- /dev/null
+++ b/package/source/zipapi/MemoryByteGrabber.hxx
@@ -0,0 +1,177 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _MEMORY_BYTE_GRABBER_HXX_
+#define _MEMORY_BYTE_GRABBER_HXX_
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <string.h>
+
+class MemoryByteGrabber
+{
+protected:
+ const com::sun::star::uno::Sequence < sal_Int8 > maBuffer;
+ const sal_Int8 *mpBuffer;
+ sal_Int32 mnCurrent, mnEnd;
+public:
+ MemoryByteGrabber ( const com::sun::star::uno::Sequence < sal_Int8 > & rBuffer )
+ : maBuffer ( rBuffer )
+ , mpBuffer ( rBuffer.getConstArray() )
+ , mnCurrent ( 0 )
+ , mnEnd ( rBuffer.getLength() )
+ {
+ }
+ MemoryByteGrabber()
+ {
+ }
+ const sal_Int8 * getCurrentPos () { return mpBuffer + mnCurrent; }
+
+ // XInputStream chained
+ sal_Int32 SAL_CALL readBytes( com::sun::star::uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nBytesToRead )
+ throw(com::sun::star::io::NotConnectedException, com::sun::star::io::BufferSizeExceededException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException)
+ {
+ if ( nBytesToRead < 0)
+ throw com::sun::star::io::BufferSizeExceededException();
+
+ if (nBytesToRead + mnCurrent > mnEnd)
+ nBytesToRead = mnEnd - mnCurrent;
+
+ aData.realloc ( nBytesToRead );
+ memcpy ( aData.getArray(), mpBuffer + mnCurrent, nBytesToRead );
+ mnCurrent += nBytesToRead;
+ return nBytesToRead;
+ }
+
+ sal_Int32 SAL_CALL readSomeBytes( com::sun::star::uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nMaxBytesToRead )
+ throw(com::sun::star::io::NotConnectedException, com::sun::star::io::BufferSizeExceededException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException)
+ {
+ return readBytes( aData, nMaxBytesToRead );
+ }
+ void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+ throw(com::sun::star::io::NotConnectedException, com::sun::star::io::BufferSizeExceededException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException)
+ {
+ mnCurrent += nBytesToSkip;
+ }
+ sal_Int32 SAL_CALL available( )
+ throw(com::sun::star::io::NotConnectedException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException)
+ {
+ return mnEnd - mnCurrent;
+ }
+ void SAL_CALL closeInput( )
+ throw(com::sun::star::io::NotConnectedException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException)
+ {
+ }
+
+ // XSeekable chained...
+ sal_Int64 SAL_CALL seek( sal_Int64 location )
+ throw(com::sun::star::lang::IllegalArgumentException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException)
+ {
+ if ( location < 0 || location > mnEnd )
+ throw com::sun::star::lang::IllegalArgumentException ();
+ mnCurrent = static_cast < sal_Int32 > ( location );
+ return mnCurrent;
+ }
+ sal_Int64 SAL_CALL getPosition( )
+ throw(com::sun::star::io::IOException, com::sun::star::uno::RuntimeException)
+ {
+ return mnCurrent;
+ }
+ sal_Int64 SAL_CALL getLength( )
+ throw(com::sun::star::io::IOException, com::sun::star::uno::RuntimeException)
+ {
+ return mnEnd;
+ }
+ MemoryByteGrabber& operator >> (sal_Int8& rInt8)
+ {
+ if (mnCurrent + 1 > mnEnd )
+ rInt8 = 0;
+ else
+ rInt8 = mpBuffer [mnCurrent++] & 0xFF;
+ return *this;
+ }
+ MemoryByteGrabber& operator >> (sal_Int16& rInt16)
+ {
+ if (mnCurrent + 2 > mnEnd )
+ rInt16 = 0;
+ else
+ {
+ rInt16 = mpBuffer[mnCurrent++] & 0xFF;
+ rInt16 |= ( mpBuffer[mnCurrent++] & 0xFF ) << 8;
+ }
+ return *this;
+ }
+ MemoryByteGrabber& operator >> (sal_Int32& rInt32)
+ {
+ if (mnCurrent + 4 > mnEnd )
+ rInt32 = 0;
+ else
+ {
+ rInt32 = mpBuffer[mnCurrent++] & 0xFF;
+ rInt32 |= ( mpBuffer[mnCurrent++] & 0xFF ) << 8;
+ rInt32 |= ( mpBuffer[mnCurrent++] & 0xFF ) << 16;
+ rInt32 |= ( mpBuffer[mnCurrent++] & 0xFF ) << 24;
+ }
+ return *this;
+ }
+
+ MemoryByteGrabber& operator >> (sal_uInt8& rInt8)
+ {
+ if (mnCurrent + 1 > mnEnd )
+ rInt8 = 0;
+ else
+ rInt8 = mpBuffer [mnCurrent++] & 0xFF;
+ return *this;
+ }
+ MemoryByteGrabber& operator >> (sal_uInt16& rInt16)
+ {
+ if (mnCurrent + 2 > mnEnd )
+ rInt16 = 0;
+ else
+ {
+ rInt16 = mpBuffer [mnCurrent++] & 0xFF;
+ rInt16 |= ( mpBuffer [mnCurrent++] & 0xFF ) << 8;
+ }
+ return *this;
+ }
+ MemoryByteGrabber& operator >> (sal_uInt32& rInt32)
+ {
+ if (mnCurrent + 4 > mnEnd )
+ rInt32 = 0;
+ else
+ {
+ rInt32 = mpBuffer [mnCurrent++] & 0xFF;
+ rInt32 |= ( mpBuffer [mnCurrent++] & 0xFF ) << 8;
+ rInt32 |= ( mpBuffer [mnCurrent++] & 0xFF ) << 16;
+ rInt32 |= ( mpBuffer [mnCurrent++] & 0xFF ) << 24;
+ }
+ return *this;
+ }
+};
+
+#endif
diff --git a/package/source/zipapi/XFileStream.cxx b/package/source/zipapi/XFileStream.cxx
new file mode 100644
index 000000000000..9e7156ee82b3
--- /dev/null
+++ b/package/source/zipapi/XFileStream.cxx
@@ -0,0 +1,227 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <XFileStream.hxx>
+#include <EncryptionData.hxx>
+#include <com/sun/star/packages/zip/ZipConstants.hpp>
+#include <PackageConstants.hxx>
+#include <rtl/cipher.h>
+#include <ZipFile.hxx>
+#include <EncryptedDataHeader.hxx>
+#include <com/sun/star/io/XOutputStream.hpp>
+
+using namespace com::sun::star::packages::zip::ZipConstants;
+using namespace com::sun::star::io;
+using namespace com::sun::star::uno;
+using com::sun::star::lang::IllegalArgumentException;
+using ::rtl::OUString;
+
+XFileStream::XFileStream( ZipEntry & rEntry,
+ com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewZipStream,
+ com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewTempStream,
+ const vos::ORef < EncryptionData > &rData,
+ sal_Bool bNewRawStream,
+ sal_Bool bIsEncrypted )
+: maEntry ( rEntry )
+, mxData ( rData )
+, mbRawStream ( bNewRawStream )
+, mbFinished ( sal_False )
+, mxTempIn ( xNewTempStream )
+, mxTempSeek ( xNewTempStream, UNO_QUERY )
+, mxTempOut ( xNewTempStream, UNO_QUERY )
+, mxZipStream ( xNewZipStream )
+, mxZipSeek ( xNewZipStream, UNO_QUERY )
+, maInflater ( sal_True )
+, maCipher ( NULL )
+{
+ mnZipCurrent = maEntry.nOffset;
+ if (mbRawStream)
+ {
+ mnZipSize = maEntry.nMethod == DEFLATED ? maEntry.nCompressedSize : maEntry.nSize;
+ mnZipEnd = maEntry.nOffset + mnZipSize;
+ }
+ else
+ {
+ mnZipSize = maEntry.nSize;
+ mnZipEnd = maEntry.nMethod == DEFLATED ? maEntry.nOffset + maEntry.nCompressedSize : maEntry.nOffset + maEntry.nSize;
+ }
+
+ if ( bIsEncrypted )
+ {
+ sal_Bool bHaveEncryptData = ( !rData.isEmpty() && rData->aSalt.getLength() && rData->aInitVector.getLength() && rData->nIterationCount != 0 ) ? sal_True : sal_False;
+
+ // if we have all the encrypted data, and want a raw stream, then prepend it to the stream, otherwise
+ // make a cipher so we can decrypt it
+ if ( bHaveEncryptData )
+ {
+ if ( !bNewRawStream )
+ ZipFile::StaticGetCipher ( rData, maCipher, sal_True );
+ else
+ {
+ // Put in the EncryptedDataHeader
+ Sequence < sal_Int8 > aEncryptedDataHeader ( n_ConstHeaderSize +
+ rData->aInitVector.getLength() +
+ rData->aSalt.getLength() +
+ rData->aDigest.getLength() );
+ sal_Int8 * pHeader = aEncryptedDataHeader.getArray();
+ ZipFile::StaticFillHeader ( rData, rEntry.nSize, pHeader );
+ mxTempOut->writeBytes ( aEncryptedDataHeader );
+ mnZipSize += mxTempSeek->getPosition();
+ mxTempSeek->seek ( 0 );
+ }
+ }
+ }
+}
+
+XFileStream::~XFileStream()
+{
+ if ( maCipher )
+ rtl_cipher_destroy ( maCipher );
+}
+
+void XFileStream::fill( sal_Int64 nUntil)
+{
+ sal_Int32 nRead;
+ sal_Int64 nPosition = mxTempSeek->getPosition();
+ mxTempSeek->seek ( mxTempSeek->getLength() );
+ maBuffer.realloc ( n_ConstBufferSize );
+
+ while ( mxTempSeek->getLength() < nUntil )
+ {
+ if ( !mbRawStream )
+ {
+ while ( 0 == ( nRead = maInflater.doInflate( maBuffer ) ) )
+ {
+ if ( maInflater.finished() || maInflater.needsDictionary() )
+ {
+ // some error handling ?
+ return;
+ }
+
+ sal_Int64 nDiff = mnZipEnd - mnZipCurrent;
+ if ( nDiff > 0 )
+ {
+ mxZipSeek->seek ( mnZipCurrent );
+ nRead = mxZipStream->readBytes ( maCompBuffer, static_cast < sal_Int32 > ( nDiff < n_ConstBufferSize ? nDiff : n_ConstBufferSize ) );
+ mnZipCurrent += nRead;
+ // maCompBuffer now has the uncompressed data, check if we need to decrypt
+ // before passing to the Inflater
+ if ( maCipher )
+ {
+ Sequence < sal_Int8 > aCryptBuffer ( nRead );
+ rtlCipherError aResult = rtl_cipher_decode ( maCipher,
+ maCompBuffer.getConstArray(),
+ nRead,
+ reinterpret_cast < sal_uInt8 * > (aCryptBuffer.getArray()),
+ nRead);
+ OSL_ASSERT (aResult == rtl_Cipher_E_None);
+ maCompBuffer = aCryptBuffer; // Now it holds the decrypted data
+
+ }
+ maInflater.setInput ( maCompBuffer );
+ }
+ else
+ {
+ // some error handling ?
+ return;
+ }
+ }
+ }
+ else
+ {
+ sal_Int64 nDiff = mnZipEnd - mnZipCurrent;
+ mxZipSeek->seek ( mnZipCurrent );
+ nRead = mxZipStream->readBytes ( maBuffer, static_cast < sal_Int32 > ( nDiff < n_ConstBufferSize ? nDiff : n_ConstBufferSize ) );
+ mnZipCurrent += nRead;
+ }
+ Sequence < sal_Int8 > aTmpBuffer ( maBuffer.getConstArray(), nRead );
+ mxTempOut->writeBytes ( aTmpBuffer );
+ }
+ mxTempSeek->seek ( nPosition );
+}
+
+sal_Int32 SAL_CALL XFileStream::readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ sal_Int64 nPosition = mxTempSeek->getPosition();
+ if ( nPosition + nBytesToRead > mnZipSize )
+ nBytesToRead = static_cast < sal_Int32 > ( mnZipSize - nPosition );
+
+ sal_Int64 nUntil = nBytesToRead + nPosition + n_ConstBufferSize;
+ if (nUntil > mnZipSize )
+ nUntil = mnZipSize;
+ if ( nUntil > mxTempSeek->getLength() )
+ fill ( nUntil );
+ sal_Int32 nRead = mxTempIn->readBytes ( aData, nBytesToRead );
+ return nRead;
+}
+
+sal_Int32 SAL_CALL XFileStream::readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ return readBytes ( aData, nMaxBytesToRead );
+}
+void SAL_CALL XFileStream::skipBytes( sal_Int32 nBytesToSkip )
+ throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ seek ( mxTempSeek->getPosition() + nBytesToSkip );
+}
+
+sal_Int32 SAL_CALL XFileStream::available( )
+ throw( NotConnectedException, IOException, RuntimeException)
+{
+ return static_cast < sal_Int32 > ( mnZipSize - mxTempSeek->getPosition() );
+}
+
+void SAL_CALL XFileStream::closeInput( )
+ throw( NotConnectedException, IOException, RuntimeException)
+{
+}
+void SAL_CALL XFileStream::seek( sal_Int64 location )
+ throw( IllegalArgumentException, IOException, RuntimeException)
+{
+ if ( location > mnZipSize || location < 0 )
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+ if ( location > mxTempSeek->getLength() )
+ {
+ sal_Int64 nUntil = location + n_ConstBufferSize > mnZipSize ? mnZipSize : location + n_ConstBufferSize;
+ fill ( nUntil );
+ }
+ mxTempSeek->seek ( location );
+}
+sal_Int64 SAL_CALL XFileStream::getPosition( )
+ throw(IOException, RuntimeException)
+{
+ return mxTempSeek->getPosition();
+}
+sal_Int64 SAL_CALL XFileStream::getLength( )
+ throw(IOException, RuntimeException)
+{
+ return mnZipSize;
+}
diff --git a/package/source/zipapi/XFileStream.hxx b/package/source/zipapi/XFileStream.hxx
new file mode 100644
index 000000000000..0cf82c5f35cd
--- /dev/null
+++ b/package/source/zipapi/XFileStream.hxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _XFILE_STREAM_HXX
+#define _XFILE_STREAM_HXX
+
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <cppuhelper/implbase2.hxx>
+#ifndef _VOS_REF_H_
+#include <vos/ref.hxx>
+#endif
+#ifndef _INFLATER_HXX
+#include <Inflater.hxx>
+#endif
+#include <ZipEntry.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace io { class XOutputStream; }
+} } }
+class EncryptionData;
+typedef void* rtlCipher;
+class XFileStream : public cppu::WeakImplHelper2
+<
+ com::sun::star::io::XInputStream,
+ com::sun::star::io::XSeekable
+>
+{
+protected:
+ com::sun::star::uno::Reference < com::sun::star::io::XInputStream > mxZipStream;
+ com::sun::star::uno::Reference < com::sun::star::io::XSeekable > mxZipSeek;
+ com::sun::star::uno::Reference < com::sun::star::io::XInputStream > mxTempIn;
+ com::sun::star::uno::Reference < com::sun::star::io::XSeekable > mxTempSeek;
+ com::sun::star::uno::Reference < com::sun::star::io::XOutputStream > mxTempOut;
+ com::sun::star::uno::Sequence < sal_Int8 > maBuffer, maCompBuffer;
+ ZipEntry maEntry;
+ vos::ORef < EncryptionData > mxData;
+ rtlCipher maCipher;
+ Inflater maInflater;
+ sal_Bool mbRawStream, mbFinished;
+ sal_Int64 mnZipCurrent, mnZipEnd, mnZipSize;
+ void fill( sal_Int64 nUntil );
+
+public:
+ XFileStream( ZipEntry & rEntry,
+ com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewZipStream,
+ com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewTempStream,
+ const vos::ORef < EncryptionData > &rData,
+ sal_Bool bRawStream,
+ sal_Bool bIsEncrypted );
+ virtual ~XFileStream();
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL available( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeInput( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ // XSeekable
+ virtual void SAL_CALL seek( sal_Int64 location )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getPosition( )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getLength( )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+};
+#endif
diff --git a/package/source/zipapi/XMemoryStream.cxx b/package/source/zipapi/XMemoryStream.cxx
new file mode 100644
index 000000000000..c5ffe9ac874c
--- /dev/null
+++ b/package/source/zipapi/XMemoryStream.cxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <XMemoryStream.hxx>
+
+using namespace com::sun::star::io;
+using namespace com::sun::star::uno;
+
+XMemoryStream::XMemoryStream ( com::sun::star::uno::Sequence < sal_Int8 > & rNewBuffer )
+: ZipPackageBuffer ( rNewBuffer )
+{
+}
+XMemoryStream::~XMemoryStream(void)
+{
+}
+::com::sun::star::uno::Any SAL_CALL XMemoryStream::queryInterface( const com::sun::star::uno::Type& rType )
+ throw(com::sun::star::uno::RuntimeException)
+{
+ return ::cppu::queryInterface ( rType ,
+ // OWeakObject interfaces
+ reinterpret_cast< XInterface* > ( this ) ,
+ static_cast< XWeak* > ( this ) ,
+ // my interfaces
+ static_cast< XInputStream* > ( this ) ,
+ static_cast< XSeekable* > ( this ) );
+}
diff --git a/package/source/zipapi/XMemoryStream.hxx b/package/source/zipapi/XMemoryStream.hxx
new file mode 100644
index 000000000000..89db08a6c4ed
--- /dev/null
+++ b/package/source/zipapi/XMemoryStream.hxx
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _XMEMORY_STREAM_HXX
+#define _XMEMORY_STREAM_HXX
+
+#include <ZipPackageBuffer.hxx>
+
+class ZipPackage;
+
+class XMemoryStream: public ZipPackageBuffer
+{
+public:
+ XMemoryStream ( com::sun::star::uno::Sequence < sal_Int8 > & rNewBuffer );
+ virtual ~XMemoryStream(void);
+ virtual com::sun::star::uno::Any SAL_CALL queryInterface( const com::sun::star::uno::Type& rType )
+ throw(com::sun::star::uno::RuntimeException);
+};
+#endif
diff --git a/package/source/zipapi/XUnbufferedStream.cxx b/package/source/zipapi/XUnbufferedStream.cxx
new file mode 100644
index 000000000000..a75af35914a1
--- /dev/null
+++ b/package/source/zipapi/XUnbufferedStream.cxx
@@ -0,0 +1,360 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <XUnbufferedStream.hxx>
+#include <EncryptionData.hxx>
+#include <com/sun/star/packages/zip/ZipConstants.hpp>
+#include <com/sun/star/packages/zip/ZipIOException.hpp>
+#include <PackageConstants.hxx>
+#include <rtl/cipher.h>
+#include <ZipFile.hxx>
+#include <EncryptedDataHeader.hxx>
+#include <algorithm>
+#include <string.h>
+
+#include <osl/mutex.hxx>
+
+#if 0
+// for debugging purposes here
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <comphelper/processfactory.hxx>
+using namespace ::com::sun::star;
+#endif
+
+using namespace com::sun::star::packages::zip::ZipConstants;
+using namespace com::sun::star::io;
+using namespace com::sun::star::uno;
+using com::sun::star::lang::IllegalArgumentException;
+using com::sun::star::packages::zip::ZipIOException;
+using ::rtl::OUString;
+
+XUnbufferedStream::XUnbufferedStream( SotMutexHolderRef aMutexHolder,
+ ZipEntry & rEntry,
+ Reference < XInputStream > xNewZipStream,
+ const vos::ORef < EncryptionData > &rData,
+ sal_Int8 nStreamMode,
+ sal_Bool bIsEncrypted,
+ const ::rtl::OUString& aMediaType,
+ sal_Bool bRecoveryMode )
+: maMutexHolder( aMutexHolder.Is() ? aMutexHolder : SotMutexHolderRef( new SotMutexHolder ) )
+, mxZipStream ( xNewZipStream )
+, mxZipSeek ( xNewZipStream, UNO_QUERY )
+, maEntry ( rEntry )
+, mxData ( rData )
+, maCipher ( NULL )
+, maInflater ( sal_True )
+, mbRawStream ( nStreamMode == UNBUFF_STREAM_RAW || nStreamMode == UNBUFF_STREAM_WRAPPEDRAW )
+, mbWrappedRaw ( nStreamMode == UNBUFF_STREAM_WRAPPEDRAW )
+, mbFinished ( sal_False )
+, mnHeaderToRead ( 0 )
+, mnZipCurrent ( 0 )
+, mnZipEnd ( 0 )
+, mnZipSize ( 0 )
+, mnMyCurrent ( 0 )
+, mbCheckCRC( !bRecoveryMode )
+{
+ mnZipCurrent = maEntry.nOffset;
+ if ( mbRawStream )
+ {
+ mnZipSize = maEntry.nMethod == DEFLATED ? maEntry.nCompressedSize : maEntry.nSize;
+ mnZipEnd = maEntry.nOffset + mnZipSize;
+ }
+ else
+ {
+ mnZipSize = maEntry.nSize;
+ mnZipEnd = maEntry.nMethod == DEFLATED ? maEntry.nOffset + maEntry.nCompressedSize : maEntry.nOffset + maEntry.nSize;
+ }
+ sal_Bool bHaveEncryptData = ( !rData.isEmpty() && rData->aSalt.getLength() && rData->aInitVector.getLength() && rData->nIterationCount != 0 ) ? sal_True : sal_False;
+ sal_Bool bMustDecrypt = ( nStreamMode == UNBUFF_STREAM_DATA && bHaveEncryptData && bIsEncrypted ) ? sal_True : sal_False;
+
+ if ( bMustDecrypt )
+ ZipFile::StaticGetCipher ( rData, maCipher, sal_True );
+ if ( bHaveEncryptData && mbWrappedRaw && bIsEncrypted )
+ {
+ // if we have the data needed to decrypt it, but didn't want it decrypted (or
+ // we couldn't decrypt it due to wrong password), then we prepend this
+ // data to the stream
+
+ // Make a buffer big enough to hold both the header and the data itself
+ maHeader.realloc ( n_ConstHeaderSize +
+ rData->aInitVector.getLength() +
+ rData->aSalt.getLength() +
+ rData->aDigest.getLength() +
+ aMediaType.getLength() * sizeof( sal_Unicode ) );
+ sal_Int8 * pHeader = maHeader.getArray();
+ ZipFile::StaticFillHeader ( rData, rEntry.nSize, aMediaType, pHeader );
+ mnHeaderToRead = static_cast < sal_Int16 > ( maHeader.getLength() );
+ }
+}
+
+// allows to read package raw stream
+XUnbufferedStream::XUnbufferedStream( const Reference < XInputStream >& xRawStream,
+ const vos::ORef < EncryptionData > &rData )
+: maMutexHolder( new SotMutexHolder )
+, mxZipStream ( xRawStream )
+, mxZipSeek ( xRawStream, UNO_QUERY )
+, mxData ( rData )
+, maCipher ( NULL )
+, maInflater ( sal_True )
+, mbRawStream ( sal_False )
+, mbWrappedRaw ( sal_False )
+, mbFinished ( sal_False )
+, mnHeaderToRead ( 0 )
+, mnZipCurrent ( 0 )
+, mnZipEnd ( 0 )
+, mnZipSize ( 0 )
+, mnMyCurrent ( 0 )
+, mbCheckCRC( sal_False )
+{
+ // for this scenario maEntry is not set !!!
+ OSL_ENSURE( mxZipSeek.is(), "The stream must be seekable!\n" );
+
+ // skip raw header, it must be already parsed to rData
+ mnZipCurrent = n_ConstHeaderSize + rData->aInitVector.getLength() +
+ rData->aSalt.getLength() + rData->aDigest.getLength();
+
+ try {
+ if ( mxZipSeek.is() )
+ mnZipSize = mxZipSeek->getLength();
+ } catch( Exception& )
+ {
+ // in case of problem the size will stay set to 0
+ }
+
+ mnZipEnd = mnZipCurrent + mnZipSize;
+
+ ZipFile::StaticGetCipher ( rData, maCipher, sal_True );
+}
+
+XUnbufferedStream::~XUnbufferedStream()
+{
+ if ( maCipher )
+ rtl_cipher_destroy ( maCipher );
+}
+
+sal_Int32 SAL_CALL XUnbufferedStream::readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( maMutexHolder->GetMutex() );
+
+ sal_Int32 nRequestedBytes = nBytesToRead;
+ OSL_ENSURE( !mnHeaderToRead || mbWrappedRaw, "Only encrypted raw stream can be provided with header!" );
+ if ( mnMyCurrent + nRequestedBytes > mnZipSize + maHeader.getLength() )
+ nRequestedBytes = static_cast < sal_Int32 > ( mnZipSize + maHeader.getLength() - mnMyCurrent );
+
+ sal_Int32 nRead = 0, nLastRead = 0, nTotal = 0;
+ aData.realloc ( nRequestedBytes );
+ if ( nRequestedBytes )
+ {
+ if ( mbRawStream )
+ {
+ sal_Int64 nDiff = mnZipEnd - mnZipCurrent;
+
+ if ( mbWrappedRaw && mnHeaderToRead )
+ {
+ sal_Int16 nHeadRead = static_cast< sal_Int16 >(( nRequestedBytes > mnHeaderToRead ?
+ mnHeaderToRead : nRequestedBytes ));
+ memcpy ( aData.getArray(), maHeader.getConstArray() + maHeader.getLength() - mnHeaderToRead, nHeadRead );
+ mnHeaderToRead = mnHeaderToRead - nHeadRead;
+
+ if ( nHeadRead < nRequestedBytes )
+ {
+ sal_Int32 nToRead = nRequestedBytes - nHeadRead;
+ nToRead = ( nDiff < nToRead ) ? sal::static_int_cast< sal_Int32 >( nDiff ) : nToRead;
+
+ Sequence< sal_Int8 > aPureData( nToRead );
+ mxZipSeek->seek ( mnZipCurrent );
+ nRead = mxZipStream->readBytes ( aPureData, nToRead );
+ mnZipCurrent += nRead;
+
+ aPureData.realloc( nRead );
+ if ( mbCheckCRC )
+ maCRC.update( aPureData );
+
+ aData.realloc( nHeadRead + nRead );
+
+ sal_Int8* pPureBuffer = aPureData.getArray();
+ sal_Int8* pBuffer = aData.getArray();
+ for ( sal_Int32 nInd = 0; nInd < nRead; nInd++ )
+ pBuffer[ nHeadRead + nInd ] = pPureBuffer[ nInd ];
+ }
+
+ nRead += nHeadRead;
+ }
+ else
+ {
+ mxZipSeek->seek ( mnZipCurrent );
+
+ nRead = mxZipStream->readBytes (
+ aData,
+ static_cast < sal_Int32 > ( nDiff < nRequestedBytes ? nDiff : nRequestedBytes ) );
+
+ mnZipCurrent += nRead;
+
+ aData.realloc( nRead );
+ if ( mbWrappedRaw && mbCheckCRC )
+ maCRC.update( aData );
+ }
+ }
+ else
+ {
+ while ( 0 == ( nLastRead = maInflater.doInflateSegment( aData, nRead, aData.getLength() - nRead ) ) ||
+ ( nRead + nLastRead != nRequestedBytes && mnZipCurrent < mnZipEnd ) )
+ {
+ nRead += nLastRead;
+
+ if ( nRead > nRequestedBytes )
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "Should not be possible to read more then requested!" ) ),
+ Reference< XInterface >() );
+
+ if ( maInflater.finished() || maInflater.getLastInflateError() )
+ throw ZipIOException( OUString( RTL_CONSTASCII_USTRINGPARAM( "The stream seems to be broken!" ) ),
+ Reference< XInterface >() );
+
+ if ( maInflater.needsDictionary() )
+ throw ZipIOException( OUString( RTL_CONSTASCII_USTRINGPARAM( "Dictionaries are not supported!" ) ),
+ Reference< XInterface >() );
+
+ sal_Int32 nDiff = static_cast < sal_Int32 > ( mnZipEnd - mnZipCurrent );
+ if ( nDiff > 0 )
+ {
+ mxZipSeek->seek ( mnZipCurrent );
+ sal_Int32 nToRead = std::min ( nDiff, std::max ( nRequestedBytes, static_cast< sal_Int32 >( 8192 ) ) );
+ sal_Int32 nZipRead = mxZipStream->readBytes ( maCompBuffer, nToRead );
+ if ( nZipRead < nToRead )
+ throw ZipIOException( OUString( RTL_CONSTASCII_USTRINGPARAM( "No expected data!" ) ),
+ Reference< XInterface >() );
+
+ mnZipCurrent += nZipRead;
+ // maCompBuffer now has the data, check if we need to decrypt
+ // before passing to the Inflater
+ if ( maCipher )
+ {
+ if ( mbCheckCRC )
+ maCRC.update( maCompBuffer );
+
+ Sequence < sal_Int8 > aCryptBuffer ( nZipRead );
+ rtlCipherError aResult =
+ rtl_cipher_decode ( maCipher,
+ maCompBuffer.getConstArray(),
+ nZipRead,
+ reinterpret_cast < sal_uInt8 * > (aCryptBuffer.getArray()),
+ nZipRead);
+ if( aResult != rtl_Cipher_E_None ) {
+ OSL_ASSERT (aResult == rtl_Cipher_E_None);
+ }
+ maCompBuffer = aCryptBuffer; // Now it holds the decrypted data
+
+ }
+ maInflater.setInput ( maCompBuffer );
+ }
+ else
+ {
+ throw ZipIOException( OUString( RTL_CONSTASCII_USTRINGPARAM( "The stream seems to be broken!" ) ),
+ Reference< XInterface >() );
+ }
+ }
+ }
+
+ mnMyCurrent += nRead + nLastRead;
+ nTotal = nRead + nLastRead;
+ if ( nTotal < nRequestedBytes)
+ aData.realloc ( nTotal );
+
+ if ( mbCheckCRC && ( !mbRawStream || mbWrappedRaw ) )
+ {
+ if ( !maCipher && !mbWrappedRaw )
+ maCRC.update( aData );
+
+#if 0
+ // for debugging purposes here
+ if ( mbWrappedRaw )
+ {
+ if ( 0 )
+ {
+ uno::Reference< lang::XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+ uno::Reference< ucb::XSimpleFileAccess > xAccess( xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), uno::UNO_QUERY );
+ uno::Reference< io::XOutputStream > xOut = xAccess->openFileWrite( ::rtl::OUString::createFromAscii( "file:///d:/777/Encrypted/picture" ) );
+ xOut->writeBytes( aData );
+ xOut->closeOutput();
+ }
+ }
+#endif
+
+ if ( mnZipSize + maHeader.getLength() == mnMyCurrent && maCRC.getValue() != maEntry.nCrc )
+ throw ZipIOException( OUString( RTL_CONSTASCII_USTRINGPARAM( "The stream seems to be broken!" ) ),
+ Reference< XInterface >() );
+ }
+ }
+
+ return nTotal;
+}
+
+sal_Int32 SAL_CALL XUnbufferedStream::readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ return readBytes ( aData, nMaxBytesToRead );
+}
+void SAL_CALL XUnbufferedStream::skipBytes( sal_Int32 nBytesToSkip )
+ throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ if ( nBytesToSkip )
+ {
+ Sequence < sal_Int8 > aSequence ( nBytesToSkip );
+ readBytes ( aSequence, nBytesToSkip );
+ }
+}
+
+sal_Int32 SAL_CALL XUnbufferedStream::available( )
+ throw( NotConnectedException, IOException, RuntimeException)
+{
+ return static_cast < sal_Int32 > ( mnZipSize - mnMyCurrent );
+}
+
+void SAL_CALL XUnbufferedStream::closeInput( )
+ throw( NotConnectedException, IOException, RuntimeException)
+{
+}
+/*
+void SAL_CALL XUnbufferedStream::seek( sal_Int64 location )
+ throw( IllegalArgumentException, IOException, RuntimeException)
+{
+}
+sal_Int64 SAL_CALL XUnbufferedStream::getPosition( )
+ throw(IOException, RuntimeException)
+{
+ return mnMyCurrent;
+}
+sal_Int64 SAL_CALL XUnbufferedStream::getLength( )
+ throw(IOException, RuntimeException)
+{
+ return mnZipSize;
+}
+*/
diff --git a/package/source/zipapi/XUnbufferedStream.hxx b/package/source/zipapi/XUnbufferedStream.hxx
new file mode 100644
index 000000000000..321ec10b8032
--- /dev/null
+++ b/package/source/zipapi/XUnbufferedStream.hxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _XUNBUFFERED_STREAM_HXX
+#define _XUNBUFFERED_STREAM_HXX
+
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <vos/ref.hxx>
+#include <Inflater.hxx>
+#include <ZipEntry.hxx>
+#include <CRC32.hxx>
+#include <mutexholder.hxx>
+
+#define UNBUFF_STREAM_DATA 0
+#define UNBUFF_STREAM_RAW 1
+#define UNBUFF_STREAM_WRAPPEDRAW 2
+
+class EncryptionData;
+typedef void* rtlCipher;
+class XUnbufferedStream : public cppu::WeakImplHelper1
+<
+ com::sun::star::io::XInputStream
+>
+{
+protected:
+ SotMutexHolderRef maMutexHolder;
+
+ com::sun::star::uno::Reference < com::sun::star::io::XInputStream > mxZipStream;
+ com::sun::star::uno::Reference < com::sun::star::io::XSeekable > mxZipSeek;
+ com::sun::star::uno::Sequence < sal_Int8 > maCompBuffer, maHeader;
+ ZipEntry maEntry;
+ vos::ORef < EncryptionData > mxData;
+ rtlCipher maCipher;
+ Inflater maInflater;
+ sal_Bool mbRawStream, mbWrappedRaw, mbFinished;
+ sal_Int16 mnHeaderToRead;
+ sal_Int64 mnZipCurrent, mnZipEnd, mnZipSize, mnMyCurrent;
+ CRC32 maCRC;
+ sal_Bool mbCheckCRC;
+
+public:
+ XUnbufferedStream(
+ SotMutexHolderRef aMutexHolder,
+ ZipEntry & rEntry,
+ com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewZipStream,
+ const vos::ORef < EncryptionData > &rData,
+ sal_Int8 nStreamMode,
+ sal_Bool bIsEncrypted,
+ const ::rtl::OUString& aMediaType,
+ sal_Bool bRecoveryMode );
+
+ // allows to read package raw stream
+ XUnbufferedStream( const com::sun::star::uno::Reference < com::sun::star::io::XInputStream >& xRawStream,
+ const vos::ORef < EncryptionData > &rData );
+
+
+ virtual ~XUnbufferedStream();
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL available( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeInput( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ // XSeekable
+ /*
+ virtual void SAL_CALL seek( sal_Int64 location )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getPosition( )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getLength( )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ */
+};
+#endif
diff --git a/package/source/zipapi/ZipEnumeration.cxx b/package/source/zipapi/ZipEnumeration.cxx
new file mode 100644
index 000000000000..367c29f6d4a7
--- /dev/null
+++ b/package/source/zipapi/ZipEnumeration.cxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ZipEnumeration.hxx>
+
+/** Provides an Enumeration over the contents of a Zip file */
+
+ZipEnumeration::ZipEnumeration( EntryHash & rNewEntryHash)
+: rEntryHash(rNewEntryHash)
+, aIterator(rEntryHash.begin())
+{
+}
+ZipEnumeration::~ZipEnumeration( void )
+{
+}
+sal_Bool SAL_CALL ZipEnumeration::hasMoreElements()
+{
+ return (aIterator != rEntryHash.end());
+}
+
+const ZipEntry* SAL_CALL ZipEnumeration::nextElement()
+{
+ if (aIterator != rEntryHash.end())
+ return &((*aIterator++).second);
+ else
+ return NULL;
+}
diff --git a/package/source/zipapi/ZipFile.cxx b/package/source/zipapi/ZipFile.cxx
new file mode 100644
index 000000000000..2238cf870d02
--- /dev/null
+++ b/package/source/zipapi/ZipFile.cxx
@@ -0,0 +1,1061 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ZipFile.hxx>
+#include <ZipEnumeration.hxx>
+#include <com/sun/star/packages/zip/ZipConstants.hpp>
+#include <rtl/cipher.h>
+#include <rtl/digest.h>
+/*
+#include <XMemoryStream.hxx>
+#include <XFileStream.hxx>
+*/
+#include <XUnbufferedStream.hxx>
+#include <PackageConstants.hxx>
+#include <EncryptedDataHeader.hxx>
+#include <EncryptionData.hxx>
+#include <MemoryByteGrabber.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+
+#ifndef _CRC32_HXX_
+#include <CRC32.hxx>
+#endif
+
+#include <string.h> // for memcpy
+#include <vector>
+
+#include <comphelper/storagehelper.hxx>
+
+using namespace vos;
+using namespace rtl;
+using namespace com::sun::star;
+using namespace com::sun::star::io;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::packages;
+using namespace com::sun::star::packages::zip;
+using namespace com::sun::star::packages::zip::ZipConstants;
+
+
+/** This class is used to read entries from a zip file
+ */
+ZipFile::ZipFile( Reference < XInputStream > &xInput, const Reference < XMultiServiceFactory > &xNewFactory, sal_Bool bInitialise )
+ throw(IOException, ZipException, RuntimeException)
+: aGrabber(xInput)
+, aInflater (sal_True)
+, xStream(xInput)
+, xSeek(xInput, UNO_QUERY)
+, xFactory ( xNewFactory )
+, bRecoveryMode( sal_False )
+{
+ if (bInitialise)
+ {
+ if ( readCEN() == -1 )
+ {
+ aEntries.clear();
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "stream data looks to be broken" ) ), Reference < XInterface > () );
+ }
+ }
+}
+
+
+
+ZipFile::ZipFile( Reference < XInputStream > &xInput, const Reference < XMultiServiceFactory > &xNewFactory, sal_Bool bInitialise, sal_Bool bForceRecovery, Reference < XProgressHandler > xProgress )
+ throw(IOException, ZipException, RuntimeException)
+: aGrabber(xInput)
+, aInflater (sal_True)
+, xStream(xInput)
+, xSeek(xInput, UNO_QUERY)
+, xFactory ( xNewFactory )
+, xProgressHandler( xProgress )
+, bRecoveryMode( bForceRecovery )
+{
+ if (bInitialise)
+ {
+ if ( bForceRecovery )
+ {
+ recover();
+ }
+ else if ( readCEN() == -1 )
+ {
+ aEntries.clear();
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "stream data looks to be broken" ) ), Reference < XInterface > () );
+ }
+ }
+}
+
+ZipFile::~ZipFile()
+{
+ aEntries.clear();
+}
+
+void ZipFile::setInputStream ( Reference < XInputStream > xNewStream )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ xStream = xNewStream;
+ xSeek = Reference < XSeekable > ( xStream, UNO_QUERY );
+ aGrabber.setInputStream ( xStream );
+}
+
+sal_Bool ZipFile::StaticGetCipher ( const ORef < EncryptionData > & xEncryptionData, rtlCipher &rCipher, sal_Bool bDecode )
+{
+ sal_Bool bResult = sal_False;
+ if ( ! xEncryptionData.isEmpty() )
+ {
+ Sequence < sal_uInt8 > aDerivedKey (16);
+ rtlCipherError aResult;
+ Sequence < sal_Int8 > aDecryptBuffer;
+
+ // Get the key
+ rtl_digest_PBKDF2 ( aDerivedKey.getArray(), 16,
+ reinterpret_cast < const sal_uInt8 * > (xEncryptionData->aKey.getConstArray() ),
+ xEncryptionData->aKey.getLength(),
+ reinterpret_cast < const sal_uInt8 * > ( xEncryptionData->aSalt.getConstArray() ),
+ xEncryptionData->aSalt.getLength(),
+ xEncryptionData->nIterationCount );
+
+ rCipher = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream);
+ aResult = rtl_cipher_init( rCipher, bDecode ? rtl_Cipher_DirectionDecode : rtl_Cipher_DirectionEncode,
+ aDerivedKey.getConstArray(),
+ aDerivedKey.getLength(),
+ reinterpret_cast < const sal_uInt8 * > ( xEncryptionData->aInitVector.getConstArray() ),
+ xEncryptionData->aInitVector.getLength());
+ OSL_ASSERT (aResult == rtl_Cipher_E_None);
+
+ bResult = ( aResult == rtl_Cipher_E_None );
+ }
+
+ return bResult;
+}
+
+void ZipFile::StaticFillHeader ( const ORef < EncryptionData > & rData,
+ sal_Int32 nSize,
+ const ::rtl::OUString& aMediaType,
+ sal_Int8 * & pHeader )
+{
+ // I think it's safe to restrict vector and salt length to 2 bytes !
+ sal_Int16 nIVLength = static_cast < sal_Int16 > ( rData->aInitVector.getLength() );
+ sal_Int16 nSaltLength = static_cast < sal_Int16 > ( rData->aSalt.getLength() );
+ sal_Int16 nDigestLength = static_cast < sal_Int16 > ( rData->aDigest.getLength() );
+ sal_Int16 nMediaTypeLength = static_cast < sal_Int16 > ( aMediaType.getLength() * sizeof( sal_Unicode ) );
+
+ // First the header
+ *(pHeader++) = ( n_ConstHeader >> 0 ) & 0xFF;
+ *(pHeader++) = ( n_ConstHeader >> 8 ) & 0xFF;
+ *(pHeader++) = ( n_ConstHeader >> 16 ) & 0xFF;
+ *(pHeader++) = ( n_ConstHeader >> 24 ) & 0xFF;
+
+ // Then the version
+ *(pHeader++) = ( n_ConstCurrentVersion >> 0 ) & 0xFF;
+ *(pHeader++) = ( n_ConstCurrentVersion >> 8 ) & 0xFF;
+
+ // Then the iteration Count
+ sal_Int32 nIterationCount = rData->nIterationCount;
+ *(pHeader++) = static_cast< sal_Int8 >(( nIterationCount >> 0 ) & 0xFF);
+ *(pHeader++) = static_cast< sal_Int8 >(( nIterationCount >> 8 ) & 0xFF);
+ *(pHeader++) = static_cast< sal_Int8 >(( nIterationCount >> 16 ) & 0xFF);
+ *(pHeader++) = static_cast< sal_Int8 >(( nIterationCount >> 24 ) & 0xFF);
+
+ // Then the size
+ *(pHeader++) = static_cast< sal_Int8 >(( nSize >> 0 ) & 0xFF);
+ *(pHeader++) = static_cast< sal_Int8 >(( nSize >> 8 ) & 0xFF);
+ *(pHeader++) = static_cast< sal_Int8 >(( nSize >> 16 ) & 0xFF);
+ *(pHeader++) = static_cast< sal_Int8 >(( nSize >> 24 ) & 0xFF);
+
+ // Then the salt length
+ *(pHeader++) = static_cast< sal_Int8 >(( nSaltLength >> 0 ) & 0xFF);
+ *(pHeader++) = static_cast< sal_Int8 >(( nSaltLength >> 8 ) & 0xFF);
+
+ // Then the IV length
+ *(pHeader++) = static_cast< sal_Int8 >(( nIVLength >> 0 ) & 0xFF);
+ *(pHeader++) = static_cast< sal_Int8 >(( nIVLength >> 8 ) & 0xFF);
+
+ // Then the digest length
+ *(pHeader++) = static_cast< sal_Int8 >(( nDigestLength >> 0 ) & 0xFF);
+ *(pHeader++) = static_cast< sal_Int8 >(( nDigestLength >> 8 ) & 0xFF);
+
+ // Then the mediatype length
+ *(pHeader++) = static_cast< sal_Int8 >(( nMediaTypeLength >> 0 ) & 0xFF);
+ *(pHeader++) = static_cast< sal_Int8 >(( nMediaTypeLength >> 8 ) & 0xFF);
+
+ // Then the salt content
+ memcpy ( pHeader, rData->aSalt.getConstArray(), nSaltLength );
+ pHeader += nSaltLength;
+
+ // Then the IV content
+ memcpy ( pHeader, rData->aInitVector.getConstArray(), nIVLength );
+ pHeader += nIVLength;
+
+ // Then the digest content
+ memcpy ( pHeader, rData->aDigest.getConstArray(), nDigestLength );
+ pHeader += nDigestLength;
+
+ // Then the mediatype itself
+ memcpy ( pHeader, aMediaType.getStr(), nMediaTypeLength );
+ pHeader += nMediaTypeLength;
+}
+
+sal_Bool ZipFile::StaticFillData ( ORef < EncryptionData > & rData,
+ sal_Int32 &rSize,
+ ::rtl::OUString& aMediaType,
+ Reference < XInputStream > &rStream )
+{
+ sal_Bool bOk = sal_False;
+ const sal_Int32 nHeaderSize = n_ConstHeaderSize - 4;
+ Sequence < sal_Int8 > aBuffer ( nHeaderSize );
+ if ( nHeaderSize == rStream->readBytes ( aBuffer, nHeaderSize ) )
+ {
+ sal_Int16 nPos = 0;
+ sal_Int8 *pBuffer = aBuffer.getArray();
+ sal_Int16 nVersion = pBuffer[nPos++] & 0xFF;
+ nVersion |= ( pBuffer[nPos++] & 0xFF ) << 8;
+ if ( nVersion == n_ConstCurrentVersion )
+ {
+ sal_Int32 nCount = pBuffer[nPos++] & 0xFF;
+ nCount |= ( pBuffer[nPos++] & 0xFF ) << 8;
+ nCount |= ( pBuffer[nPos++] & 0xFF ) << 16;
+ nCount |= ( pBuffer[nPos++] & 0xFF ) << 24;
+ rData->nIterationCount = nCount;
+
+ rSize = pBuffer[nPos++] & 0xFF;
+ rSize |= ( pBuffer[nPos++] & 0xFF ) << 8;
+ rSize |= ( pBuffer[nPos++] & 0xFF ) << 16;
+ rSize |= ( pBuffer[nPos++] & 0xFF ) << 24;
+
+ sal_Int16 nSaltLength = pBuffer[nPos++] & 0xFF;
+ nSaltLength |= ( pBuffer[nPos++] & 0xFF ) << 8;
+ sal_Int16 nIVLength = ( pBuffer[nPos++] & 0xFF );
+ nIVLength |= ( pBuffer[nPos++] & 0xFF ) << 8;
+ sal_Int16 nDigestLength = pBuffer[nPos++] & 0xFF;
+ nDigestLength |= ( pBuffer[nPos++] & 0xFF ) << 8;
+
+ sal_Int16 nMediaTypeLength = pBuffer[nPos++] & 0xFF;
+ nMediaTypeLength |= ( pBuffer[nPos++] & 0xFF ) << 8;
+
+ if ( nSaltLength == rStream->readBytes ( aBuffer, nSaltLength ) )
+ {
+ rData->aSalt.realloc ( nSaltLength );
+ memcpy ( rData->aSalt.getArray(), aBuffer.getConstArray(), nSaltLength );
+ if ( nIVLength == rStream->readBytes ( aBuffer, nIVLength ) )
+ {
+ rData->aInitVector.realloc ( nIVLength );
+ memcpy ( rData->aInitVector.getArray(), aBuffer.getConstArray(), nIVLength );
+ if ( nDigestLength == rStream->readBytes ( aBuffer, nDigestLength ) )
+ {
+ rData->aDigest.realloc ( nDigestLength );
+ memcpy ( rData->aDigest.getArray(), aBuffer.getConstArray(), nDigestLength );
+
+ if ( nMediaTypeLength == rStream->readBytes ( aBuffer, nMediaTypeLength ) )
+ {
+ aMediaType = ::rtl::OUString( (sal_Unicode*)aBuffer.getConstArray(),
+ nMediaTypeLength / sizeof( sal_Unicode ) );
+ bOk = sal_True;
+ }
+ }
+ }
+ }
+ }
+ }
+ return bOk;
+}
+
+Reference< XInputStream > ZipFile::StaticGetDataFromRawStream( const Reference< XInputStream >& xStream,
+ const ORef < EncryptionData > &rData )
+ throw ( packages::WrongPasswordException, ZipIOException, RuntimeException )
+{
+ if ( rData.isEmpty() )
+ throw ZipIOException( OUString::createFromAscii( "Encrypted stream without encryption data!\n" ),
+ Reference< XInterface >() );
+
+ if ( !rData->aKey.getLength() )
+ throw packages::WrongPasswordException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ Reference< XSeekable > xSeek( xStream, UNO_QUERY );
+ if ( !xSeek.is() )
+ throw ZipIOException( OUString::createFromAscii( "The stream must be seekable!\n" ),
+ Reference< XInterface >() );
+
+
+ // if we have a digest, then this file is an encrypted one and we should
+ // check if we can decrypt it or not
+ OSL_ENSURE( rData->aDigest.getLength(), "Can't detect password correctness without digest!\n" );
+ if ( rData->aDigest.getLength() )
+ {
+ sal_Int32 nSize = sal::static_int_cast< sal_Int32 >( xSeek->getLength() );
+ nSize = nSize > n_ConstDigestLength ? n_ConstDigestLength : nSize;
+
+ // skip header
+ xSeek->seek( n_ConstHeaderSize + rData->aInitVector.getLength() +
+ rData->aSalt.getLength() + rData->aDigest.getLength() );
+
+ // Only want to read enough to verify the digest
+ Sequence < sal_Int8 > aReadBuffer ( nSize );
+
+ xStream->readBytes( aReadBuffer, nSize );
+
+ if ( !StaticHasValidPassword( aReadBuffer, rData ) )
+ throw packages::WrongPasswordException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ return new XUnbufferedStream ( xStream, rData );
+}
+
+sal_Bool ZipFile::StaticHasValidPassword( const Sequence< sal_Int8 > &aReadBuffer, const ORef < EncryptionData > &rData )
+{
+ if ( !rData.isValid() || !rData->aKey.getLength() )
+ return sal_False;
+
+ sal_Bool bRet = sal_False;
+ sal_Int32 nSize = aReadBuffer.getLength();
+
+ // make a temporary cipher
+ rtlCipher aCipher;
+ StaticGetCipher ( rData, aCipher, sal_True );
+
+ Sequence < sal_Int8 > aDecryptBuffer ( nSize );
+ rtlDigest aDigest = rtl_digest_createSHA1();
+ rtlDigestError aDigestResult;
+ Sequence < sal_uInt8 > aDigestSeq ( RTL_DIGEST_LENGTH_SHA1 );
+ rtlCipherError aResult = rtl_cipher_decode ( aCipher,
+ aReadBuffer.getConstArray(),
+ nSize,
+ reinterpret_cast < sal_uInt8 * > (aDecryptBuffer.getArray()),
+ nSize);
+ if(aResult != rtl_Cipher_E_None ) {
+ OSL_ASSERT ( aResult == rtl_Cipher_E_None);
+ }
+
+ aDigestResult = rtl_digest_updateSHA1 ( aDigest,
+ static_cast < const void * > ( aDecryptBuffer.getConstArray() ), nSize );
+ OSL_ASSERT ( aDigestResult == rtl_Digest_E_None );
+
+ aDigestResult = rtl_digest_getSHA1 ( aDigest, aDigestSeq.getArray(), RTL_DIGEST_LENGTH_SHA1 );
+ OSL_ASSERT ( aDigestResult == rtl_Digest_E_None );
+
+ // If we don't have a digest, then we have to assume that the password is correct
+ if ( rData->aDigest.getLength() != 0 &&
+ ( aDigestSeq.getLength() != rData->aDigest.getLength() ||
+ 0 != rtl_compareMemory ( aDigestSeq.getConstArray(),
+ rData->aDigest.getConstArray(),
+ aDigestSeq.getLength() ) ) )
+ {
+ // We should probably tell the user that the password they entered was wrong
+ }
+ else
+ bRet = sal_True;
+
+ rtl_digest_destroySHA1 ( aDigest );
+
+ return bRet;
+}
+
+sal_Bool ZipFile::hasValidPassword ( ZipEntry & rEntry, const ORef < EncryptionData > &rData )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ sal_Bool bRet = sal_False;
+ if ( rData->aKey.getLength() )
+ {
+ xSeek->seek( rEntry.nOffset );
+ sal_Int32 nSize = rEntry.nMethod == DEFLATED ? rEntry.nCompressedSize : rEntry.nSize;
+
+ // Only want to read enough to verify the digest
+ nSize = nSize > n_ConstDigestLength ? n_ConstDigestLength : nSize;
+ Sequence < sal_Int8 > aReadBuffer ( nSize );
+
+ xStream->readBytes( aReadBuffer, nSize );
+
+ bRet = StaticHasValidPassword( aReadBuffer, rData );
+ }
+ return bRet;
+}
+
+#if 0
+Reference < XInputStream > ZipFile::createFileStream(
+ ZipEntry & rEntry,
+ const ORef < EncryptionData > &rData,
+ sal_Bool bRawStream,
+ sal_Bool bIsEncrypted )
+{
+ static OUString sServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) );
+ Reference < XInputStream > xTempStream = Reference < XInputStream > ( xFactory->createInstance ( sServiceName ), UNO_QUERY );
+ return new XFileStream ( rEntry, xStream, xTempStream, rData, bRawStream, bIsEncrypted );
+}
+Reference < XInputStream > ZipFile::createMemoryStream(
+ ZipEntry & rEntry,
+ const ORef < EncryptionData > &rData,
+ sal_Bool bRawStream,
+ sal_Bool bIsEncrypted )
+{
+ sal_Int32 nUncompressedSize, nEnd;
+ if (bRawStream)
+ {
+ nUncompressedSize = rEntry.nMethod == DEFLATED ? rEntry.nCompressedSize : rEntry.nSize;
+ nEnd = rEntry.nOffset + nUncompressedSize;
+ }
+ else
+ {
+ nUncompressedSize = rEntry.nSize;
+ nEnd = rEntry.nMethod == DEFLATED ? rEntry.nOffset + rEntry.nCompressedSize : rEntry.nOffset + rEntry.nSize;
+ }
+ sal_Int32 nSize = rEntry.nMethod == DEFLATED ? rEntry.nCompressedSize : rEntry.nSize;
+ Sequence < sal_Int8 > aReadBuffer ( nSize ), aDecryptBuffer, aWriteBuffer;
+ rtlCipher aCipher;
+
+ // If the encryption key is zero, we need to return the raw stream. First check if
+ // we have the salt. If we have the salt, then check if we have the encryption key
+ // if not, return rawStream instead.
+
+ sal_Bool bHaveEncryptData = ( !rData.isEmpty() && rData->aSalt.getLength() && rData->aInitVector.getLength() && rData->nIterationCount != 0 ) ? sal_True : sal_False;
+ sal_Bool bMustDecrypt = ( !bRawStream && bHaveEncryptData && bIsEncrypted ) ? sal_True : sal_False;
+
+ if ( bMustDecrypt )
+ {
+ StaticGetCipher ( rData, aCipher, sal_True );
+ aDecryptBuffer.realloc ( nSize );
+ }
+
+ if ( nSize <0 )
+ throw IOException ( );
+
+ xSeek->seek( rEntry.nOffset );
+ xStream->readBytes( aReadBuffer, nSize ); // Now it holds the raw stuff from disk
+
+ if ( bMustDecrypt )
+ {
+ rtlCipherError aResult = rtl_cipher_decode ( aCipher,
+ aReadBuffer.getConstArray(),
+ nSize,
+ reinterpret_cast < sal_uInt8 * > (aDecryptBuffer.getArray()),
+ nSize);
+ OSL_ASSERT (aResult == rtl_Cipher_E_None);
+ aReadBuffer = aDecryptBuffer; // Now it holds the decrypted data
+ }
+ if (bRawStream || rEntry.nMethod == STORED)
+ aWriteBuffer = aReadBuffer; // bRawStream means the caller doesn't want it decompressed
+ else
+ {
+ aInflater.setInputSegment( aReadBuffer, 0, nSize );
+ aWriteBuffer.realloc( nUncompressedSize );
+ aInflater.doInflate( aWriteBuffer );
+ aInflater.reset();
+ }
+
+ if ( bHaveEncryptData && !bMustDecrypt && bIsEncrypted )
+ {
+ // if we have the data needed to decrypt it, but didn't want it decrypted (or
+ // we couldn't decrypt it due to wrong password), then we prepend this
+ // data to the stream
+
+ // Make a buffer big enough to hold both the header and the data itself
+ Sequence < sal_Int8 > aEncryptedDataHeader ( n_ConstHeaderSize +
+ rData->aInitVector.getLength() +
+ rData->aSalt.getLength() +
+ rData->aDigest.getLength() +
+ aWriteBuffer.getLength() );
+ sal_Int8 * pHeader = aEncryptedDataHeader.getArray();
+ StaticFillHeader ( rData, rEntry.nSize, pHeader );
+ memcpy ( pHeader, aWriteBuffer.getConstArray(), aWriteBuffer.getLength() );
+
+ // dump old buffer and point aWriteBuffer to the new one with the header
+ aWriteBuffer = aEncryptedDataHeader;
+ }
+ return Reference < XInputStream > ( new XMemoryStream ( aWriteBuffer ) );
+}
+#endif
+Reference < XInputStream > ZipFile::createUnbufferedStream(
+ SotMutexHolderRef aMutexHolder,
+ ZipEntry & rEntry,
+ const ORef < EncryptionData > &rData,
+ sal_Int8 nStreamMode,
+ sal_Bool bIsEncrypted,
+ ::rtl::OUString aMediaType )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ return new XUnbufferedStream ( aMutexHolder, rEntry, xStream, rData, nStreamMode, bIsEncrypted, aMediaType, bRecoveryMode );
+}
+
+
+ZipEnumeration * SAL_CALL ZipFile::entries( )
+{
+ return new ZipEnumeration ( aEntries );
+}
+
+Reference< XInputStream > SAL_CALL ZipFile::getInputStream( ZipEntry& rEntry,
+ const vos::ORef < EncryptionData > &rData,
+ sal_Bool bIsEncrypted,
+ SotMutexHolderRef aMutexHolder )
+ throw(IOException, ZipException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( rEntry.nOffset <= 0 )
+ readLOC( rEntry );
+
+ // We want to return a rawStream if we either don't have a key or if the
+ // key is wrong
+
+ sal_Bool bNeedRawStream = rEntry.nMethod == STORED;
+
+ // if we have a digest, then this file is an encrypted one and we should
+ // check if we can decrypt it or not
+ if ( bIsEncrypted && !rData.isEmpty() && rData->aDigest.getLength() )
+ bNeedRawStream = !hasValidPassword ( rEntry, rData );
+
+ return createUnbufferedStream ( aMutexHolder,
+ rEntry,
+ rData,
+ bNeedRawStream ? UNBUFF_STREAM_RAW : UNBUFF_STREAM_DATA,
+ bIsEncrypted );
+}
+
+Reference< XInputStream > SAL_CALL ZipFile::getDataStream( ZipEntry& rEntry,
+ const vos::ORef < EncryptionData > &rData,
+ sal_Bool bIsEncrypted,
+ SotMutexHolderRef aMutexHolder )
+ throw ( packages::WrongPasswordException,
+ IOException,
+ ZipException,
+ RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( rEntry.nOffset <= 0 )
+ readLOC( rEntry );
+
+ // An exception must be thrown in case stream is encrypted and
+ // there is no key or the key is wrong
+ sal_Bool bNeedRawStream = sal_False;
+ if ( bIsEncrypted )
+ {
+ // in case no digest is provided there is no way
+ // to detect password correctness
+ if ( rData.isEmpty() )
+ throw ZipException( OUString::createFromAscii( "Encrypted stream without encryption data!\n" ),
+ Reference< XInterface >() );
+
+ // if we have a digest, then this file is an encrypted one and we should
+ // check if we can decrypt it or not
+ OSL_ENSURE( rData->aDigest.getLength(), "Can't detect password correctness without digest!\n" );
+ if ( rData->aDigest.getLength() && !hasValidPassword ( rEntry, rData ) )
+ throw packages::WrongPasswordException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+ else
+ bNeedRawStream = ( rEntry.nMethod == STORED );
+
+ return createUnbufferedStream ( aMutexHolder,
+ rEntry,
+ rData,
+ bNeedRawStream ? UNBUFF_STREAM_RAW : UNBUFF_STREAM_DATA,
+ bIsEncrypted );
+}
+
+Reference< XInputStream > SAL_CALL ZipFile::getRawData( ZipEntry& rEntry,
+ const vos::ORef < EncryptionData > &rData,
+ sal_Bool bIsEncrypted,
+ SotMutexHolderRef aMutexHolder )
+ throw(IOException, ZipException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( rEntry.nOffset <= 0 )
+ readLOC( rEntry );
+
+ return createUnbufferedStream ( aMutexHolder, rEntry, rData, UNBUFF_STREAM_RAW, bIsEncrypted );
+}
+
+Reference< XInputStream > SAL_CALL ZipFile::getWrappedRawStream(
+ ZipEntry& rEntry,
+ const vos::ORef < EncryptionData > &rData,
+ const ::rtl::OUString& aMediaType,
+ SotMutexHolderRef aMutexHolder )
+ throw ( packages::NoEncryptionException,
+ IOException,
+ ZipException,
+ RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( rData.isEmpty() )
+ throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( rEntry.nOffset <= 0 )
+ readLOC( rEntry );
+
+ return createUnbufferedStream ( aMutexHolder, rEntry, rData, UNBUFF_STREAM_WRAPPEDRAW, sal_True, aMediaType );
+}
+
+sal_Bool ZipFile::readLOC( ZipEntry &rEntry )
+ throw(IOException, ZipException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ sal_Int32 nTestSig, nTime, nCRC, nSize, nCompressedSize;
+ sal_Int16 nVersion, nFlag, nHow, nPathLen, nExtraLen;
+ sal_Int32 nPos = -rEntry.nOffset;
+
+ aGrabber.seek(nPos);
+ aGrabber >> nTestSig;
+
+ if (nTestSig != LOCSIG)
+ throw ZipIOException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Invalid LOC header (bad signature") ), Reference < XInterface > () );
+ aGrabber >> nVersion;
+ aGrabber >> nFlag;
+ aGrabber >> nHow;
+ aGrabber >> nTime;
+ aGrabber >> nCRC;
+ aGrabber >> nCompressedSize;
+ aGrabber >> nSize;
+ aGrabber >> nPathLen;
+ aGrabber >> nExtraLen;
+ rEntry.nOffset = static_cast < sal_Int32 > (aGrabber.getPosition()) + nPathLen + nExtraLen;
+
+ // read always in UTF8, some tools seem not to set UTF8 bit
+ uno::Sequence < sal_Int8 > aNameBuffer( nPathLen );
+ sal_Int32 nRead = aGrabber.readBytes( aNameBuffer, nPathLen );
+ if ( nRead < aNameBuffer.getLength() )
+ aNameBuffer.realloc( nRead );
+
+ ::rtl::OUString sLOCPath = rtl::OUString::intern( (sal_Char *) aNameBuffer.getArray(),
+ aNameBuffer.getLength(),
+ RTL_TEXTENCODING_UTF8 );
+
+ if ( rEntry.nPathLen == -1 ) // the file was created
+ {
+ rEntry.nPathLen = nPathLen;
+ rEntry.sPath = sLOCPath;
+ }
+
+ // the method can be reset for internal use so it is not checked
+ sal_Bool bBroken = rEntry.nVersion != nVersion
+ || rEntry.nFlag != nFlag
+ || rEntry.nTime != nTime
+ || rEntry.nPathLen != nPathLen
+ || !rEntry.sPath.equals( sLOCPath );
+
+ if ( bBroken && !bRecoveryMode )
+ throw ZipIOException( OUString( RTL_CONSTASCII_USTRINGPARAM( "The stream seems to be broken!" ) ),
+ Reference< XInterface >() );
+
+ return sal_True;
+}
+
+sal_Int32 ZipFile::findEND( )
+ throw(IOException, ZipException, RuntimeException)
+{
+ // this method is called in constructor only, no need for mutex
+ sal_Int32 nLength, nPos, nEnd;
+ Sequence < sal_Int8 > aBuffer;
+ try
+ {
+ nLength = static_cast <sal_Int32 > (aGrabber.getLength());
+ if (nLength == 0 || nLength < ENDHDR)
+ return -1;
+ nPos = nLength - ENDHDR - ZIP_MAXNAMELEN;
+ nEnd = nPos >= 0 ? nPos : 0 ;
+
+ aGrabber.seek( nEnd );
+ aGrabber.readBytes ( aBuffer, nLength - nEnd );
+
+ const sal_Int8 *pBuffer = aBuffer.getConstArray();
+
+ nPos = nLength - nEnd - ENDHDR;
+ while ( nPos >= 0 )
+ {
+ if (pBuffer[nPos] == 'P' && pBuffer[nPos+1] == 'K' && pBuffer[nPos+2] == 5 && pBuffer[nPos+3] == 6 )
+ return nPos + nEnd;
+ nPos--;
+ }
+ }
+ catch ( IllegalArgumentException& )
+ {
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Zip END signature not found!") ), Reference < XInterface > () );
+ }
+ catch ( NotConnectedException& )
+ {
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Zip END signature not found!") ), Reference < XInterface > () );
+ }
+ catch ( BufferSizeExceededException& )
+ {
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Zip END signature not found!") ), Reference < XInterface > () );
+ }
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Zip END signature not found!") ), Reference < XInterface > () );
+}
+
+sal_Int32 ZipFile::readCEN()
+ throw(IOException, ZipException, RuntimeException)
+{
+ // this method is called in constructor only, no need for mutex
+ sal_Int32 nCenLen, nCenPos = -1, nCenOff, nEndPos, nLocPos;
+ sal_uInt16 nCount, nTotal;
+
+ try
+ {
+ nEndPos = findEND();
+ if (nEndPos == -1)
+ return -1;
+ aGrabber.seek(nEndPos + ENDTOT);
+ aGrabber >> nTotal;
+ aGrabber >> nCenLen;
+ aGrabber >> nCenOff;
+
+ if ( nTotal * CENHDR > nCenLen )
+ throw ZipException(OUString( RTL_CONSTASCII_USTRINGPARAM ( "invalid END header (bad entry count)") ), Reference < XInterface > () );
+
+ if ( nTotal > ZIP_MAXENTRIES )
+ throw ZipException(OUString( RTL_CONSTASCII_USTRINGPARAM ( "too many entries in ZIP File") ), Reference < XInterface > () );
+
+ if ( nCenLen < 0 || nCenLen > nEndPos )
+ throw ZipException(OUString( RTL_CONSTASCII_USTRINGPARAM ( "Invalid END header (bad central directory size)") ), Reference < XInterface > () );
+
+ nCenPos = nEndPos - nCenLen;
+
+ if ( nCenOff < 0 || nCenOff > nCenPos )
+ throw ZipException(OUString( RTL_CONSTASCII_USTRINGPARAM ( "Invalid END header (bad central directory size)") ), Reference < XInterface > () );
+
+ nLocPos = nCenPos - nCenOff;
+ aGrabber.seek( nCenPos );
+ Sequence < sal_Int8 > aCENBuffer ( nCenLen );
+ sal_Int64 nRead = aGrabber.readBytes ( aCENBuffer, nCenLen );
+ if ( static_cast < sal_Int64 > ( nCenLen ) != nRead )
+ throw ZipException ( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Error reading CEN into memory buffer!") ), Reference < XInterface > () );
+
+ MemoryByteGrabber aMemGrabber ( aCENBuffer );
+
+ ZipEntry aEntry;
+ sal_Int32 nTestSig;
+ sal_Int16 nCommentLen;
+
+ for (nCount = 0 ; nCount < nTotal; nCount++)
+ {
+ aMemGrabber >> nTestSig;
+ if ( nTestSig != CENSIG )
+ throw ZipException(OUString( RTL_CONSTASCII_USTRINGPARAM ( "Invalid CEN header (bad signature)") ), Reference < XInterface > () );
+
+ aMemGrabber.skipBytes ( 2 );
+ aMemGrabber >> aEntry.nVersion;
+
+ if ( ( aEntry.nVersion & 1 ) == 1 )
+ throw ZipException(OUString( RTL_CONSTASCII_USTRINGPARAM ( "Invalid CEN header (encrypted entry)") ), Reference < XInterface > () );
+
+ aMemGrabber >> aEntry.nFlag;
+ aMemGrabber >> aEntry.nMethod;
+
+ if ( aEntry.nMethod != STORED && aEntry.nMethod != DEFLATED)
+ throw ZipException(OUString( RTL_CONSTASCII_USTRINGPARAM ( "Invalid CEN header (bad compression method)") ), Reference < XInterface > () );
+
+ aMemGrabber >> aEntry.nTime;
+ aMemGrabber >> aEntry.nCrc;
+ aMemGrabber >> aEntry.nCompressedSize;
+ aMemGrabber >> aEntry.nSize;
+ aMemGrabber >> aEntry.nPathLen;
+ aMemGrabber >> aEntry.nExtraLen;
+ aMemGrabber >> nCommentLen;
+ aMemGrabber.skipBytes ( 8 );
+ aMemGrabber >> aEntry.nOffset;
+
+ aEntry.nOffset += nLocPos;
+ aEntry.nOffset *= -1;
+
+ if ( aEntry.nPathLen < 0 )
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "unexpected name length" ) ), Reference < XInterface > () );
+
+ if ( nCommentLen < 0 )
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "unexpected comment length" ) ), Reference < XInterface > () );
+
+ if ( aEntry.nExtraLen < 0 )
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "unexpected extra header info length") ), Reference < XInterface > () );
+
+ // read always in UTF8, some tools seem not to set UTF8 bit
+ aEntry.sPath = rtl::OUString::intern ( (sal_Char *) aMemGrabber.getCurrentPos(),
+ aEntry.nPathLen,
+ RTL_TEXTENCODING_UTF8 );
+
+ if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( aEntry.sPath, sal_True ) )
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Zip entry has an invalid name.") ), Reference < XInterface > () );
+
+ aMemGrabber.skipBytes( aEntry.nPathLen + aEntry.nExtraLen + nCommentLen );
+ aEntries[aEntry.sPath] = aEntry;
+ }
+
+ if (nCount != nTotal)
+ throw ZipException(OUString( RTL_CONSTASCII_USTRINGPARAM ( "Count != Total") ), Reference < XInterface > () );
+ }
+ catch ( IllegalArgumentException & )
+ {
+ // seek can throw this...
+ nCenPos = -1; // make sure we return -1 to indicate an error
+ }
+ return nCenPos;
+}
+
+sal_Int32 ZipFile::recover()
+ throw(IOException, ZipException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ sal_Int32 nLength;
+ Sequence < sal_Int8 > aBuffer;
+ Sequence < sal_Int32 > aHeaderOffsets;
+
+ try
+ {
+ nLength = static_cast <sal_Int32 > (aGrabber.getLength());
+ if (nLength == 0 || nLength < ENDHDR)
+ return -1;
+
+ aGrabber.seek( 0 );
+
+ for( sal_Int32 nGenPos = 0; aGrabber.readBytes( aBuffer, 32000 ) && aBuffer.getLength() > 30; )
+ {
+ const sal_Int8 *pBuffer = aBuffer.getConstArray();
+ sal_Int32 nBufSize = aBuffer.getLength();
+
+ sal_Int32 nPos = 0;
+ while( nPos < nBufSize - 16 )
+ {
+ if ( nPos < nBufSize - 30 && pBuffer[nPos] == 'P' && pBuffer[nPos+1] == 'K' && pBuffer[nPos+2] == 3 && pBuffer[nPos+3] == 4 )
+ {
+ ZipEntry aEntry;
+ MemoryByteGrabber aMemGrabber ( Sequence< sal_Int8 >( ((sal_Int8*)(&(pBuffer[nPos+4]))), 26 ) );
+
+ aMemGrabber >> aEntry.nVersion;
+ if ( ( aEntry.nVersion & 1 ) != 1 )
+ {
+ aMemGrabber >> aEntry.nFlag;
+ aMemGrabber >> aEntry.nMethod;
+
+ if ( aEntry.nMethod == STORED || aEntry.nMethod == DEFLATED )
+ {
+ aMemGrabber >> aEntry.nTime;
+ aMemGrabber >> aEntry.nCrc;
+ aMemGrabber >> aEntry.nCompressedSize;
+ aMemGrabber >> aEntry.nSize;
+ aMemGrabber >> aEntry.nPathLen;
+ aMemGrabber >> aEntry.nExtraLen;
+
+ sal_Int32 nDescrLength =
+ ( aEntry.nMethod == DEFLATED && ( aEntry.nFlag & 8 ) ) ?
+ 16 : 0;
+
+
+ // This is a quick fix for OOo1.1RC
+ // For OOo2.0 the whole package must be switched to unsigned values
+ if ( aEntry.nCompressedSize < 0 ) aEntry.nCompressedSize = 0x7FFFFFFF;
+ if ( aEntry.nSize < 0 ) aEntry.nSize = 0x7FFFFFFF;
+ if ( aEntry.nPathLen < 0 ) aEntry.nPathLen = 0x7FFF;
+ if ( aEntry.nExtraLen < 0 ) aEntry.nExtraLen = 0x7FFF;
+ // End of quick fix
+
+ sal_Int32 nDataSize = ( aEntry.nMethod == DEFLATED ) ? aEntry.nCompressedSize : aEntry.nSize;
+ sal_Int32 nBlockLength = nDataSize + aEntry.nPathLen + aEntry.nExtraLen + 30 + nDescrLength;
+ if ( aEntry.nPathLen >= 0 && aEntry.nExtraLen >= 0
+ && ( nGenPos + nPos + nBlockLength ) <= nLength )
+ {
+ // read always in UTF8, some tools seem not to set UTF8 bit
+ if( nPos + 30 + aEntry.nPathLen <= nBufSize )
+ aEntry.sPath = OUString ( (sal_Char *) &pBuffer[nPos + 30],
+ aEntry.nPathLen,
+ RTL_TEXTENCODING_UTF8 );
+ else
+ {
+ Sequence < sal_Int8 > aFileName;
+ aGrabber.seek( nGenPos + nPos + 30 );
+ aGrabber.readBytes( aFileName, aEntry.nPathLen );
+ aEntry.sPath = OUString ( (sal_Char *) aFileName.getArray(),
+ aFileName.getLength(),
+ RTL_TEXTENCODING_UTF8 );
+ aEntry.nPathLen = static_cast< sal_Int16 >(aFileName.getLength());
+ }
+
+ aEntry.nOffset = nGenPos + nPos + 30 + aEntry.nPathLen + aEntry.nExtraLen;
+
+ if ( ( aEntry.nSize || aEntry.nCompressedSize ) && !checkSizeAndCRC( aEntry ) )
+ {
+ aEntry.nCrc = 0;
+ aEntry.nCompressedSize = 0;
+ aEntry.nSize = 0;
+ }
+
+ if ( aEntries.find( aEntry.sPath ) == aEntries.end() )
+ aEntries[aEntry.sPath] = aEntry;
+ }
+ }
+ }
+
+ nPos += 4;
+ }
+ else if (pBuffer[nPos] == 'P' && pBuffer[nPos+1] == 'K' && pBuffer[nPos+2] == 7 && pBuffer[nPos+3] == 8 )
+ {
+ sal_Int32 nCompressedSize, nSize, nCRC32;
+ MemoryByteGrabber aMemGrabber ( Sequence< sal_Int8 >( ((sal_Int8*)(&(pBuffer[nPos+4]))), 12 ) );
+ aMemGrabber >> nCRC32;
+ aMemGrabber >> nCompressedSize;
+ aMemGrabber >> nSize;
+
+ for( EntryHash::iterator aIter = aEntries.begin(); aIter != aEntries.end(); aIter++ )
+ {
+ ZipEntry aTmp = (*aIter).second;
+
+ // this is a broken package, accept this block not only for DEFLATED streams
+ if( (*aIter).second.nFlag & 8 )
+ {
+ sal_Int32 nStreamOffset = nGenPos + nPos - nCompressedSize;
+ if ( nStreamOffset == (*aIter).second.nOffset && nCompressedSize > (*aIter).second.nCompressedSize )
+ {
+ // only DEFLATED blocks need to be checked
+ sal_Bool bAcceptBlock = ( (*aIter).second.nMethod == STORED && nCompressedSize == nSize );
+
+ if ( !bAcceptBlock )
+ {
+ sal_Int32 nRealSize = 0, nRealCRC = 0;
+ getSizeAndCRC( nStreamOffset, nCompressedSize, &nRealSize, &nRealCRC );
+ bAcceptBlock = ( nRealSize == nSize && nRealCRC == nCRC32 );
+ }
+
+ if ( bAcceptBlock )
+ {
+ (*aIter).second.nCrc = nCRC32;
+ (*aIter).second.nCompressedSize = nCompressedSize;
+ (*aIter).second.nSize = nSize;
+ }
+ }
+#if 0
+// for now ignore clearly broken streams
+ else if( !(*aIter).second.nCompressedSize )
+ {
+ (*aIter).second.nCrc = nCRC32;
+ sal_Int32 nRealStreamSize = nGenPos + nPos - (*aIter).second.nOffset;
+ (*aIter).second.nCompressedSize = nGenPos + nPos - (*aIter).second.nOffset;
+ (*aIter).second.nSize = nSize;
+ }
+#endif
+ }
+ }
+
+ nPos += 4;
+ }
+ else
+ nPos++;
+ }
+
+ nGenPos += nPos;
+ aGrabber.seek( nGenPos );
+ }
+
+ return 0;
+ }
+ catch ( IllegalArgumentException& )
+ {
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Zip END signature not found!") ), Reference < XInterface > () );
+ }
+ catch ( NotConnectedException& )
+ {
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Zip END signature not found!") ), Reference < XInterface > () );
+ }
+ catch ( BufferSizeExceededException& )
+ {
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Zip END signature not found!") ), Reference < XInterface > () );
+ }
+}
+
+sal_Bool ZipFile::checkSizeAndCRC( const ZipEntry& aEntry )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ sal_Int32 nSize = 0, nCRC = 0;
+
+ if( aEntry.nMethod == STORED )
+ return ( getCRC( aEntry.nOffset, aEntry.nSize ) == aEntry.nCrc );
+
+ getSizeAndCRC( aEntry.nOffset, aEntry.nCompressedSize, &nSize, &nCRC );
+ return ( aEntry.nSize == nSize && aEntry.nCrc == nCRC );
+}
+
+sal_Int32 ZipFile::getCRC( sal_Int32 nOffset, sal_Int32 nSize )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ Sequence < sal_Int8 > aBuffer;
+ CRC32 aCRC;
+ sal_Int32 nBlockSize = ::std::min( nSize, static_cast< sal_Int32 >( 32000 ) );
+
+ aGrabber.seek( nOffset );
+ for ( int ind = 0;
+ aGrabber.readBytes( aBuffer, nBlockSize ) && ind * nBlockSize < nSize;
+ ind++ )
+ {
+ aCRC.updateSegment( aBuffer, 0, ::std::min( nBlockSize, nSize - ind * nBlockSize ) );
+ }
+
+ return aCRC.getValue();
+}
+
+void ZipFile::getSizeAndCRC( sal_Int32 nOffset, sal_Int32 nCompressedSize, sal_Int32 *nSize, sal_Int32 *nCRC )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ Sequence < sal_Int8 > aBuffer;
+ CRC32 aCRC;
+ sal_Int32 nRealSize = 0;
+ Inflater aInflaterLocal( sal_True );
+ sal_Int32 nBlockSize = ::std::min( nCompressedSize, static_cast< sal_Int32 >( 32000 ) );
+
+ aGrabber.seek( nOffset );
+ for ( int ind = 0;
+ !aInflaterLocal.finished() && aGrabber.readBytes( aBuffer, nBlockSize ) && ind * nBlockSize < nCompressedSize;
+ ind++ )
+ {
+ Sequence < sal_Int8 > aData( nBlockSize );
+ sal_Int32 nLastInflated = 0;
+ sal_Int32 nInBlock = 0;
+
+ aInflaterLocal.setInput( aBuffer );
+ do
+ {
+ nLastInflated = aInflaterLocal.doInflateSegment( aData, 0, nBlockSize );
+ aCRC.updateSegment( aData, 0, nLastInflated );
+ nInBlock += nLastInflated;
+ } while( !aInflater.finished() && nLastInflated );
+
+ nRealSize += nInBlock;
+ }
+
+ if( aInflaterLocal.finished() )
+ {
+ *nSize = nRealSize;
+ *nCRC = aCRC.getValue();
+ }
+ else
+ *nSize = *nCRC = 0;
+}
diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx
new file mode 100644
index 000000000000..16457ec12493
--- /dev/null
+++ b/package/source/zipapi/ZipOutputStream.cxx
@@ -0,0 +1,429 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ZipOutputStream.hxx>
+#include <com/sun/star/packages/zip/ZipConstants.hpp>
+#include <osl/time.h>
+#include <EncryptionData.hxx>
+#include <PackageConstants.hxx>
+#include <ZipEntry.hxx>
+#include <ZipFile.hxx>
+#include <vos/ref.hxx>
+#include <com/sun/star/io/XOutputStream.hpp>
+
+#include <comphelper/storagehelper.hxx>
+
+using namespace rtl;
+using namespace com::sun::star::io;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::packages;
+using namespace com::sun::star::packages::zip;
+using namespace com::sun::star::packages::zip::ZipConstants;
+
+/** This class is used to write Zip files
+ */
+ZipOutputStream::ZipOutputStream( Reference < XOutputStream > &xOStream )
+: xStream(xOStream)
+, aBuffer(n_ConstBufferSize)
+, aDeflater(DEFAULT_COMPRESSION, sal_True)
+, aChucker(xOStream)
+, pCurrentEntry(NULL)
+, nMethod(DEFLATED)
+, bFinished(sal_False)
+, bEncryptCurrentEntry(sal_False)
+
+
+{
+}
+
+ZipOutputStream::~ZipOutputStream( void )
+{
+ for (sal_Int32 i = 0, nEnd = aZipList.size(); i < nEnd; i++)
+ delete aZipList[i];
+}
+
+void SAL_CALL ZipOutputStream::setMethod( sal_Int32 nNewMethod )
+ throw(RuntimeException)
+{
+ nMethod = static_cast < sal_Int16 > (nNewMethod);
+}
+void SAL_CALL ZipOutputStream::setLevel( sal_Int32 nNewLevel )
+ throw(RuntimeException)
+{
+ aDeflater.setLevel( nNewLevel);
+}
+
+void SAL_CALL ZipOutputStream::putNextEntry( ZipEntry& rEntry,
+ vos::ORef < EncryptionData > &xEncryptData,
+ sal_Bool bEncrypt)
+ throw(IOException, RuntimeException)
+{
+ if (pCurrentEntry != NULL)
+ closeEntry();
+ if (rEntry.nTime == -1)
+ rEntry.nTime = getCurrentDosTime();
+ if (rEntry.nMethod == -1)
+ rEntry.nMethod = nMethod;
+ rEntry.nVersion = 20;
+ rEntry.nFlag = 1 << 11;
+ if (rEntry.nSize == -1 || rEntry.nCompressedSize == -1 ||
+ rEntry.nCrc == -1)
+ rEntry.nFlag |= 8;
+
+ if (bEncrypt)
+ {
+ bEncryptCurrentEntry = sal_True;
+
+ ZipFile::StaticGetCipher( xEncryptData, aCipher, sal_False );
+
+ aDigest = rtl_digest_createSHA1();
+ mnDigested = 0;
+ rEntry.nFlag |= 1 << 4;
+ pCurrentEncryptData = xEncryptData.getBodyPtr();
+ }
+ sal_Int32 nLOCLength = writeLOC(rEntry);
+ rEntry.nOffset = static_cast < sal_Int32 > (aChucker.GetPosition()) - nLOCLength;
+ aZipList.push_back( &rEntry );
+ pCurrentEntry = &rEntry;
+}
+
+void SAL_CALL ZipOutputStream::closeEntry( )
+ throw(IOException, RuntimeException)
+{
+ ZipEntry *pEntry = pCurrentEntry;
+ if (pEntry)
+ {
+ switch (pEntry->nMethod)
+ {
+ case DEFLATED:
+ aDeflater.finish();
+ while (!aDeflater.finished())
+ doDeflate();
+ if ((pEntry->nFlag & 8) == 0)
+ {
+ if (pEntry->nSize != aDeflater.getTotalIn())
+ {
+ OSL_ENSURE(false,"Invalid entry size");
+ }
+ if (pEntry->nCompressedSize != aDeflater.getTotalOut())
+ {
+ //VOS_DEBUG_ONLY("Invalid entry compressed size");
+ // Different compression strategies make the merit of this
+ // test somewhat dubious
+ pEntry->nCompressedSize = aDeflater.getTotalOut();
+ }
+ if (pEntry->nCrc != aCRC.getValue())
+ {
+ OSL_ENSURE(false,"Invalid entry CRC-32");
+ }
+ }
+ else
+ {
+ pEntry->nSize = aDeflater.getTotalIn();
+ pEntry->nCompressedSize = aDeflater.getTotalOut();
+ pEntry->nCrc = aCRC.getValue();
+ if ( bEncryptCurrentEntry )
+ pEntry->nSize = pEntry->nCompressedSize;
+ writeEXT(*pEntry);
+ }
+ aDeflater.reset();
+ aCRC.reset();
+ break;
+ case STORED:
+ if (!((pEntry->nFlag & 8) == 0))
+ OSL_ENSURE ( false, "Serious error, one of compressed size, size or CRC was -1 in a STORED stream");
+ break;
+ default:
+ OSL_ENSURE(false,"Invalid compression method");
+ break;
+ }
+
+ if (bEncryptCurrentEntry)
+ {
+ rtlDigestError aDigestResult;
+ aEncryptionBuffer.realloc ( 0 );
+ bEncryptCurrentEntry = sal_False;
+ rtl_cipher_destroy ( aCipher );
+ pCurrentEncryptData->aDigest.realloc ( RTL_DIGEST_LENGTH_SHA1 );
+ aDigestResult = rtl_digest_getSHA1 ( aDigest,
+ reinterpret_cast < sal_uInt8 * > ( pCurrentEncryptData->aDigest.getArray() ),
+ RTL_DIGEST_LENGTH_SHA1 );
+ OSL_ASSERT( aDigestResult == rtl_Digest_E_None );
+ rtl_digest_destroySHA1 ( aDigest );
+ }
+ pCurrentEntry = NULL;
+ }
+}
+
+void SAL_CALL ZipOutputStream::write( const Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
+ throw(IOException, RuntimeException)
+{
+ switch (pCurrentEntry->nMethod)
+ {
+ case DEFLATED:
+ if (!aDeflater.finished())
+ {
+ aDeflater.setInputSegment(rBuffer, nNewOffset, nNewLength);
+ while (!aDeflater.needsInput())
+ doDeflate();
+ if (!bEncryptCurrentEntry)
+ aCRC.updateSegment(rBuffer, nNewOffset, nNewLength);
+ }
+ break;
+ case STORED:
+ {
+ Sequence < sal_Int8 > aTmpBuffer ( rBuffer.getConstArray(), nNewLength );
+ aChucker.WriteBytes( aTmpBuffer );
+ }
+ break;
+ }
+}
+
+void SAL_CALL ZipOutputStream::rawWrite( Sequence< sal_Int8 >& rBuffer, sal_Int32 /*nNewOffset*/, sal_Int32 nNewLength )
+ throw(IOException, RuntimeException)
+{
+ Sequence < sal_Int8 > aTmpBuffer ( rBuffer.getConstArray(), nNewLength );
+ aChucker.WriteBytes( aTmpBuffer );
+}
+
+void SAL_CALL ZipOutputStream::rawCloseEntry( )
+ throw(IOException, RuntimeException)
+{
+ if ( pCurrentEntry->nMethod == DEFLATED && ( pCurrentEntry->nFlag & 8 ) )
+ writeEXT(*pCurrentEntry);
+ pCurrentEntry = NULL;
+}
+
+void SAL_CALL ZipOutputStream::finish( )
+ throw(IOException, RuntimeException)
+{
+ if (bFinished)
+ return;
+
+ if (pCurrentEntry != NULL)
+ closeEntry();
+
+ if (aZipList.size() < 1)
+ OSL_ENSURE(false,"Zip file must have at least one entry!\n");
+
+ sal_Int32 nOffset= static_cast < sal_Int32 > (aChucker.GetPosition());
+ for (sal_Int32 i =0, nEnd = aZipList.size(); i < nEnd; i++)
+ writeCEN( *aZipList[i] );
+ writeEND( nOffset, static_cast < sal_Int32 > (aChucker.GetPosition()) - nOffset);
+ bFinished = sal_True;
+ xStream->flush();
+}
+
+void ZipOutputStream::doDeflate()
+{
+ sal_Int32 nLength = aDeflater.doDeflateSegment(aBuffer, 0, aBuffer.getLength());
+ sal_Int32 nOldLength = aBuffer.getLength();
+
+ if ( nLength > 0 )
+ {
+ Sequence < sal_Int8 > aTmpBuffer ( aBuffer.getConstArray(), nLength );
+ const void *pTmpBuffer = static_cast < const void * > ( aTmpBuffer.getConstArray() );
+ if (bEncryptCurrentEntry)
+ {
+ // Need to update our digest before encryption...
+ rtlDigestError aDigestResult = rtl_Digest_E_None;
+ sal_Int16 nDiff = n_ConstDigestLength - mnDigested;
+ if ( nDiff )
+ {
+ sal_Int16 nEat = static_cast < sal_Int16 > ( nDiff > nLength ? nLength : nDiff );
+ aDigestResult = rtl_digest_updateSHA1 ( aDigest, pTmpBuffer, nEat );
+ mnDigested = mnDigested + nEat;
+ }
+ OSL_ASSERT( aDigestResult == rtl_Digest_E_None );
+
+ aEncryptionBuffer.realloc ( nLength );
+
+ rtlCipherError aCipherResult;
+ aCipherResult = rtl_cipher_encode ( aCipher, pTmpBuffer,
+ nLength, reinterpret_cast < sal_uInt8 * > (aEncryptionBuffer.getArray()), nLength );
+ OSL_ASSERT( aCipherResult == rtl_Cipher_E_None );
+
+ aChucker.WriteBytes( aEncryptionBuffer );
+ aCRC.update ( aEncryptionBuffer );
+ aEncryptionBuffer.realloc ( nOldLength );
+ }
+ else
+ aChucker.WriteBytes ( aTmpBuffer );
+ }
+}
+void ZipOutputStream::writeEND(sal_uInt32 nOffset, sal_uInt32 nLength)
+ throw(IOException, RuntimeException)
+{
+ aChucker << ENDSIG;
+ aChucker << static_cast < sal_Int16 > ( 0 );
+ aChucker << static_cast < sal_Int16 > ( 0 );
+ aChucker << static_cast < sal_Int16 > ( aZipList.size() );
+ aChucker << static_cast < sal_Int16 > ( aZipList.size() );
+ aChucker << nLength;
+ aChucker << nOffset;
+ aChucker << static_cast < sal_Int16 > ( 0 );
+}
+void ZipOutputStream::writeCEN( const ZipEntry &rEntry )
+ throw(IOException, RuntimeException)
+{
+ if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( rEntry.sPath, sal_True ) )
+ throw IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected character is used in file name." ) ), Reference< XInterface >() );
+
+ ::rtl::OString sUTF8Name = ::rtl::OUStringToOString( rEntry.sPath, RTL_TEXTENCODING_UTF8 );
+ sal_Int16 nNameLength = static_cast < sal_Int16 > ( sUTF8Name.getLength() );
+
+ aChucker << CENSIG;
+ aChucker << rEntry.nVersion;
+ aChucker << rEntry.nVersion;
+ if (rEntry.nFlag & (1 << 4) )
+ {
+ // If it's an encrypted entry, we pretend its stored plain text
+ ZipEntry *pEntry = const_cast < ZipEntry * > ( &rEntry );
+ pEntry->nFlag &= ~(1 <<4 );
+ aChucker << rEntry.nFlag;
+ aChucker << static_cast < sal_Int16 > ( STORED );
+ }
+ else
+ {
+ aChucker << rEntry.nFlag;
+ aChucker << rEntry.nMethod;
+ }
+ aChucker << static_cast < sal_uInt32> ( rEntry.nTime );
+ aChucker << static_cast < sal_uInt32> ( rEntry.nCrc );
+ aChucker << rEntry.nCompressedSize;
+ aChucker << rEntry.nSize;
+ aChucker << nNameLength;
+ aChucker << static_cast < sal_Int16> (0);
+ aChucker << static_cast < sal_Int16> (0);
+ aChucker << static_cast < sal_Int16> (0);
+ aChucker << static_cast < sal_Int16> (0);
+ aChucker << static_cast < sal_Int32> (0);
+ aChucker << rEntry.nOffset;
+
+ Sequence < sal_Int8 > aSequence( (sal_Int8*)sUTF8Name.getStr(), sUTF8Name.getLength() );
+ aChucker.WriteBytes( aSequence );
+}
+void ZipOutputStream::writeEXT( const ZipEntry &rEntry )
+ throw(IOException, RuntimeException)
+{
+ aChucker << EXTSIG;
+ aChucker << static_cast < sal_uInt32> ( rEntry.nCrc );
+ aChucker << rEntry.nCompressedSize;
+ aChucker << rEntry.nSize;
+}
+
+sal_Int32 ZipOutputStream::writeLOC( const ZipEntry &rEntry )
+ throw(IOException, RuntimeException)
+{
+ if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( rEntry.sPath, sal_True ) )
+ throw IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected character is used in file name." ) ), Reference< XInterface >() );
+
+ ::rtl::OString sUTF8Name = ::rtl::OUStringToOString( rEntry.sPath, RTL_TEXTENCODING_UTF8 );
+ sal_Int16 nNameLength = static_cast < sal_Int16 > ( sUTF8Name.getLength() );
+
+ aChucker << LOCSIG;
+ aChucker << rEntry.nVersion;
+
+ if (rEntry.nFlag & (1 << 4) )
+ {
+ // If it's an encrypted entry, we pretend its stored plain text
+ sal_Int16 nTmpFlag = rEntry.nFlag;
+ nTmpFlag &= ~(1 <<4 );
+ aChucker << nTmpFlag;
+ aChucker << static_cast < sal_Int16 > ( STORED );
+ }
+ else
+ {
+ aChucker << rEntry.nFlag;
+ aChucker << rEntry.nMethod;
+ }
+
+ aChucker << static_cast < sal_uInt32 > (rEntry.nTime);
+ if ((rEntry.nFlag & 8) == 8 )
+ {
+ aChucker << static_cast < sal_Int32 > (0);
+ aChucker << static_cast < sal_Int32 > (0);
+ aChucker << static_cast < sal_Int32 > (0);
+ }
+ else
+ {
+ aChucker << static_cast < sal_uInt32 > (rEntry.nCrc);
+ aChucker << rEntry.nCompressedSize;
+ aChucker << rEntry.nSize;
+ }
+ aChucker << nNameLength;
+ aChucker << static_cast < sal_Int16 > (0);
+
+ Sequence < sal_Int8 > aSequence( (sal_Int8*)sUTF8Name.getStr(), sUTF8Name.getLength() );
+ aChucker.WriteBytes( aSequence );
+
+ return LOCHDR + nNameLength;
+}
+sal_uInt32 ZipOutputStream::getCurrentDosTime( )
+{
+ oslDateTime aDateTime;
+ TimeValue aTimeValue;
+ osl_getSystemTime ( &aTimeValue );
+ osl_getDateTimeFromTimeValue( &aTimeValue, &aDateTime);
+
+ sal_uInt32 nYear = static_cast <sal_uInt32> (aDateTime.Year);
+
+ if (nYear>1980)
+ nYear-=1980;
+ else if (nYear>80)
+ nYear-=80;
+ sal_uInt32 nResult = static_cast < sal_uInt32>( ( ( ( aDateTime.Day) +
+ ( 32 * (aDateTime.Month)) +
+ ( 512 * nYear ) ) << 16) |
+ ( ( aDateTime.Seconds/2) +
+ ( 32 * aDateTime.Minutes) +
+ ( 2048 * static_cast <sal_uInt32 > (aDateTime.Hours) ) ) );
+ return nResult;
+}
+/*
+
+ This is actually never used, so I removed it, but thought that the
+ implementation details may be useful in the future...mtg 20010307
+
+ I stopped using the time library and used the OSL version instead, but
+ it might still be useful to have this code here..
+
+void ZipOutputStream::dosDateToTMDate ( tm &rTime, sal_uInt32 nDosDate)
+{
+ sal_uInt32 nDate = static_cast < sal_uInt32 > (nDosDate >> 16);
+ rTime.tm_mday = static_cast < sal_uInt32 > ( nDate & 0x1F);
+ rTime.tm_mon = static_cast < sal_uInt32 > ( ( ( (nDate) & 0x1E0)/0x20)-1);
+ rTime.tm_year = static_cast < sal_uInt32 > ( ( (nDate & 0x0FE00)/0x0200)+1980);
+
+ rTime.tm_hour = static_cast < sal_uInt32 > ( (nDosDate & 0xF800)/0x800);
+ rTime.tm_min = static_cast < sal_uInt32 > ( (nDosDate & 0x7E0)/0x20);
+ rTime.tm_sec = static_cast < sal_uInt32 > ( 2 * (nDosDate & 0x1F) );
+}
+*/
+
diff --git a/package/source/zipapi/makefile.mk b/package/source/zipapi/makefile.mk
new file mode 100644
index 000000000000..a9548ace659b
--- /dev/null
+++ b/package/source/zipapi/makefile.mk
@@ -0,0 +1,59 @@
+#*************************************************************************
+#
+# 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=package
+TARGET=zipapi
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+.IF "$(L10N_framework)"==""
+#CFLAGS+=/Ob0 /Od
+.IF "$(SYSTEM_ZLIB)" == "YES"
+CFLAGS+=-DSYSTEM_ZLIB
+.ENDIF
+SLOFILES= \
+ $(SLO)$/CRC32.obj \
+ $(SLO)$/ByteChucker.obj \
+ $(SLO)$/ByteGrabber.obj \
+ $(SLO)$/Inflater.obj \
+ $(SLO)$/Deflater.obj \
+ $(SLO)$/ZipEnumeration.obj \
+ $(SLO)$/ZipFile.obj \
+ $(SLO)$/ZipOutputStream.obj \
+ $(SLO)$/XUnbufferedStream.obj
+
+.ENDIF # L10N_framework
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/package/source/zippackage/ContentInfo.hxx b/package/source/zippackage/ContentInfo.hxx
new file mode 100644
index 000000000000..6d88d17e3780
--- /dev/null
+++ b/package/source/zippackage/ContentInfo.hxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _CONTENT_INFO_HXX_
+#define _CONTENT_INFO_HXX_
+
+#include <com/sun/star/container/XNameContainer.hpp>
+#ifndef _COM_SUN_STAR_LANG_XUNOTUNNEl_HPP_
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#endif
+#include <ZipPackageFolder.hxx>
+#include <ZipPackageStream.hxx>
+
+namespace com { namespace sun { namespace star { namespace packages {
+class ContentInfo : public cppu::OWeakObject
+{
+public:
+ com::sun::star::uno::Reference < com::sun::star::lang::XUnoTunnel > xTunnel;
+ bool bFolder;
+ union
+ {
+ ZipPackageFolder *pFolder;
+ ZipPackageStream *pStream;
+ };
+ ContentInfo ( ZipPackageStream * pNewStream )
+ : xTunnel ( pNewStream )
+ , bFolder ( false )
+ , pStream ( pNewStream )
+ {
+ }
+ ContentInfo ( ZipPackageFolder * pNewFolder )
+ : xTunnel ( pNewFolder )
+ , bFolder ( true )
+ , pFolder ( pNewFolder )
+ {
+ }
+ virtual ~ContentInfo ()
+ {
+ if ( bFolder )
+ pFolder->releaseUpwardRef();
+ else
+ pStream->clearParent();
+ }
+};
+} } } }
+#endif
diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx
new file mode 100644
index 000000000000..9ba26e0100c5
--- /dev/null
+++ b/package/source/zippackage/ZipPackage.cxx
@@ -0,0 +1,1719 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ZipPackage.hxx>
+#include <ZipPackageSink.hxx>
+#include <ZipEnumeration.hxx>
+#include <ZipPackageStream.hxx>
+#include <ZipPackageFolder.hxx>
+#include <ZipOutputStream.hxx>
+#include <ZipPackageBuffer.hxx>
+#include <ZipFile.hxx>
+#include <PackageConstants.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/packages/zip/ZipConstants.hpp>
+#include <com/sun/star/packages/manifest/XManifestReader.hpp>
+#include <com/sun/star/packages/manifest/XManifestWriter.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/ucb/IOErrorCode.hpp>
+#include <ucbhelper/content.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/io/XActiveDataStreamer.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/embed/UseBackupException.hpp>
+#include <com/sun/star/embed/StorageFormats.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <ContentInfo.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <rtl/uri.hxx>
+#include <rtl/random.h>
+#include <rtl/logfile.hxx>
+#include <osl/time.h>
+#include <osl/file.hxx>
+#include "com/sun/star/io/XAsyncOutputMonitor.hpp"
+
+#include <memory>
+#include <vector>
+
+#include <ucbhelper/contentbroker.hxx>
+#include <ucbhelper/fileidentifierconverter.hxx>
+#include <comphelper/seekableinput.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <comphelper/ofopxmlhelper.hxx>
+#include <comphelper/documentconstants.hxx>
+
+using namespace rtl;
+using namespace std;
+using namespace osl;
+using namespace cppu;
+using namespace ucbhelper;
+using namespace com::sun::star;
+using namespace com::sun::star::io;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::util;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::task;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::packages;
+using namespace com::sun::star::container;
+using namespace com::sun::star::packages::zip;
+using namespace com::sun::star::packages::manifest;
+using namespace com::sun::star::packages::zip::ZipConstants;
+
+#define LOGFILE_AUTHOR "mg115289"
+
+
+namespace {
+
+sal_Bool isLocalFile_Impl( ::rtl::OUString aURL )
+{
+ ::rtl::OUString aSystemPath;
+ ContentBroker* pBroker = ContentBroker::get();
+ if ( !pBroker )
+ {
+ ::rtl::OUString aRet;
+ if ( FileBase::getSystemPathFromFileURL( aURL, aRet ) == FileBase::E_None )
+ aSystemPath = aRet;
+ }
+ else
+ {
+ uno::Reference< XContentProviderManager > xManager =
+ pBroker->getContentProviderManagerInterface();
+ try
+ {
+ aSystemPath = getSystemPathFromFileURL( xManager, aURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ return ( aSystemPath.getLength() != 0 );
+}
+
+}
+
+//===========================================================================
+
+class ActiveDataStreamer : public ::cppu::WeakImplHelper1< XActiveDataStreamer >
+{
+ uno::Reference< XStream > mStream;
+public:
+
+ virtual uno::Reference< XStream > SAL_CALL getStream()
+ throw( RuntimeException )
+ { return mStream; }
+
+ virtual void SAL_CALL setStream( const uno::Reference< XStream >& stream )
+ throw( RuntimeException )
+ { mStream = stream; }
+};
+
+class DummyInputStream : public ::cppu::WeakImplHelper1< XInputStream >
+{
+ virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >&, sal_Int32 )
+ throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+ { return 0; }
+
+ virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >&, sal_Int32 )
+ throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+ { return 0; }
+
+ virtual void SAL_CALL skipBytes( sal_Int32 )
+ throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+ {}
+
+ virtual sal_Int32 SAL_CALL available()
+ throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+ { return 0; }
+
+ virtual void SAL_CALL closeInput()
+ throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+ {}
+};
+
+//===========================================================================
+
+ZipPackage::ZipPackage (const uno::Reference < XMultiServiceFactory > &xNewFactory)
+: m_aMutexHolder( new SotMutexHolder )
+, m_bHasEncryptedEntries ( sal_False )
+, m_bHasNonEncryptedEntries ( sal_False )
+, m_bInconsistent ( sal_False )
+, m_bUseManifest ( sal_True )
+, m_bForceRecovery ( sal_False )
+, m_bMediaTypeFallbackUsed ( sal_False )
+, m_nFormat( embed::StorageFormats::PACKAGE ) // package is the default format
+, m_bAllowRemoveOnInsert( sal_True )
+, m_eMode ( e_IMode_None )
+, m_xFactory( xNewFactory )
+, m_pRootFolder( NULL )
+, m_pZipFile( NULL )
+{
+ m_xRootFolder = m_pRootFolder = new ZipPackageFolder( m_xFactory, m_nFormat, m_bAllowRemoveOnInsert );
+}
+
+ZipPackage::~ZipPackage( void )
+{
+ delete m_pZipFile;
+
+ // All folders and streams contain pointers to their parents, when a parent diappeares
+ // it should disconnect all the children from itself during destruction automatically.
+ // So there is no need in explicit m_pRootFolder->releaseUpwardRef() call here any more
+ // since m_pRootFolder has no parent and cleaning of it's children will be done automatically
+ // during m_pRootFolder dieing by refcount.
+
+#if 0
+ // As all folders and streams contain references to their parents,
+ // we must remove these references so that they will be deleted when
+ // the hash_map of the root folder is cleared, releasing all subfolders
+ // and substreams which in turn release theirs, etc. When m_xRootFolder is
+ // released when this destructor completes, the folder tree should be
+ // deleted fully (and automagically).
+
+ m_pRootFolder->releaseUpwardRef();
+#endif
+}
+
+void ZipPackage::parseManifest()
+{
+ if ( m_nFormat == embed::StorageFormats::PACKAGE )
+ {
+ sal_Bool bManifestParsed = sal_False;
+ const OUString sMeta ( RTL_CONSTASCII_USTRINGPARAM ( "META-INF" ) );
+ if ( m_xRootFolder->hasByName( sMeta ) )
+ {
+ const OUString sManifest (RTL_CONSTASCII_USTRINGPARAM( "manifest.xml") );
+
+ try {
+ uno::Reference< XUnoTunnel > xTunnel;
+ Any aAny = m_xRootFolder->getByName( sMeta );
+ aAny >>= xTunnel;
+ uno::Reference< XNameContainer > xMetaInfFolder( xTunnel, UNO_QUERY );
+ if ( xMetaInfFolder.is() && xMetaInfFolder->hasByName( sManifest ) )
+ {
+ aAny = xMetaInfFolder->getByName( sManifest );
+ aAny >>= xTunnel;
+ uno::Reference < XActiveDataSink > xSink (xTunnel, UNO_QUERY);
+ if (xSink.is())
+ {
+ OUString sManifestReader ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.manifest.ManifestReader" ) );
+ uno::Reference < XManifestReader > xReader (m_xFactory->createInstance( sManifestReader ), UNO_QUERY );
+ if ( xReader.is() )
+ {
+ const OUString sPropFullPath ( RTL_CONSTASCII_USTRINGPARAM ( "FullPath" ) );
+ const OUString sPropVersion ( RTL_CONSTASCII_USTRINGPARAM ( "Version" ) );
+ const OUString sPropMediaType ( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) );
+ const OUString sPropInitialisationVector ( RTL_CONSTASCII_USTRINGPARAM ( "InitialisationVector" ) );
+ const OUString sPropSalt ( RTL_CONSTASCII_USTRINGPARAM ( "Salt" ) );
+ const OUString sPropIterationCount ( RTL_CONSTASCII_USTRINGPARAM ( "IterationCount" ) );
+ const OUString sPropSize ( RTL_CONSTASCII_USTRINGPARAM ( "Size" ) );
+ const OUString sPropDigest ( RTL_CONSTASCII_USTRINGPARAM ( "Digest" ) );
+
+ Sequence < Sequence < PropertyValue > > aManifestSequence = xReader->readManifestSequence ( xSink->getInputStream() );
+ sal_Int32 nLength = aManifestSequence.getLength();
+ const Sequence < PropertyValue > *pSequence = aManifestSequence.getConstArray();
+ ZipPackageStream *pStream = NULL;
+ ZipPackageFolder *pFolder = NULL;
+
+ for (sal_Int32 i = 0; i < nLength ; i++, pSequence++)
+ {
+ OUString sPath, sMediaType, sVersion;
+ const PropertyValue *pValue = pSequence->getConstArray();
+ const Any *pSalt = NULL, *pVector = NULL, *pCount = NULL, *pSize = NULL, *pDigest = NULL;
+ for (sal_Int32 j = 0, nNum = pSequence->getLength(); j < nNum; j++ )
+ {
+ if (pValue[j].Name.equals( sPropFullPath ) )
+ pValue[j].Value >>= sPath;
+ else if (pValue[j].Name.equals( sPropVersion ) )
+ pValue[j].Value >>= sVersion;
+ else if (pValue[j].Name.equals( sPropMediaType ) )
+ pValue[j].Value >>= sMediaType;
+ else if (pValue[j].Name.equals( sPropSalt ) )
+ pSalt = &(pValue[j].Value);
+ else if (pValue[j].Name.equals( sPropInitialisationVector ) )
+ pVector = &(pValue[j].Value);
+ else if (pValue[j].Name.equals( sPropIterationCount ) )
+ pCount = &(pValue[j].Value);
+ else if (pValue[j].Name.equals( sPropSize ) )
+ pSize = &(pValue[j].Value);
+ else if (pValue[j].Name.equals( sPropDigest ) )
+ pDigest = &(pValue[j].Value);
+ }
+
+ if (sPath.getLength() && hasByHierarchicalName ( sPath ) )
+ {
+ aAny = getByHierarchicalName( sPath );
+ uno::Reference < XUnoTunnel > xUnoTunnel;
+ aAny >>= xUnoTunnel;
+ sal_Int64 nTest=0;
+ if ((nTest = xUnoTunnel->getSomething(ZipPackageFolder::static_getImplementationId())) != 0)
+ {
+ pFolder = reinterpret_cast < ZipPackageFolder* > ( nTest );
+ pFolder->SetMediaType ( sMediaType );
+ pFolder->SetVersion ( sVersion );
+ }
+ else
+ {
+ pStream = reinterpret_cast < ZipPackageStream* > ( xUnoTunnel->getSomething(ZipPackageStream::static_getImplementationId()));
+ pStream->SetMediaType ( sMediaType );
+ pStream->SetFromManifest( sal_True );
+
+ if (pSalt && pVector && pCount && pSize)
+ {
+ Sequence < sal_uInt8 > aSequence;
+ sal_Int32 nCount = 0, nSize = 0;
+ pStream->SetToBeEncrypted ( sal_True );
+
+ *pSalt >>= aSequence;
+ pStream->setSalt ( aSequence );
+
+ *pVector >>= aSequence;
+ pStream->setInitialisationVector ( aSequence );
+
+ *pCount >>= nCount;
+ pStream->setIterationCount ( nCount );
+
+ *pSize >>= nSize;
+ pStream->setSize ( nSize );
+
+ if ( pDigest )
+ {
+ *pDigest >>= aSequence;
+ pStream->setDigest ( aSequence );
+ }
+
+ pStream->SetToBeCompressed ( sal_True );
+ pStream->SetToBeEncrypted ( sal_True );
+ pStream->SetIsEncrypted ( sal_True );
+ if ( !m_bHasEncryptedEntries
+ && pStream->getName().equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "content.xml" ) ) ) )
+ m_bHasEncryptedEntries = sal_True;
+ }
+ else
+ m_bHasNonEncryptedEntries = sal_True;
+ }
+ }
+ }
+
+ bManifestParsed = sal_True;
+ }
+ else
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No manifes parser!" ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ // now hide the manifest.xml file from user
+ xMetaInfFolder->removeByName( sManifest );
+ }
+ }
+ catch( Exception& )
+ {
+ if ( !m_bForceRecovery )
+ throw;
+ }
+ }
+
+ if ( !bManifestParsed && !m_bForceRecovery )
+ throw ZipIOException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Could not parse manifest.xml\n" ) ),
+ uno::Reference< uno::XInterface >() );
+
+ const OUString sMimetype ( RTL_CONSTASCII_USTRINGPARAM ( "mimetype" ) );
+ if ( m_xRootFolder->hasByName( sMimetype ) )
+ {
+ // get mediatype from the "mimetype" stream
+ ::rtl::OUString aPackageMediatype;
+ uno::Reference< lang::XUnoTunnel > xMimeTypeTunnel;
+ m_xRootFolder->getByName( sMimetype ) >>= xMimeTypeTunnel;
+ uno::Reference < io::XActiveDataSink > xMimeSink( xMimeTypeTunnel, UNO_QUERY );
+ if ( xMimeSink.is() )
+ {
+ uno::Reference< io::XInputStream > xMimeInStream = xMimeSink->getInputStream();
+ if ( xMimeInStream.is() )
+ {
+ // Mediatypes longer than 1024 symbols should not appear here
+ uno::Sequence< sal_Int8 > aData( 1024 );
+ sal_Int32 nRead = xMimeInStream->readBytes( aData, 1024 );
+ if ( nRead > aData.getLength() )
+ nRead = aData.getLength();
+
+ if ( nRead )
+ aPackageMediatype = ::rtl::OUString( (sal_Char*)aData.getConstArray(), nRead, RTL_TEXTENCODING_ASCII_US );
+ }
+ }
+
+
+ if ( !bManifestParsed )
+ {
+ // the manifest.xml could not be successfuly parsed, this is an inconsistent package
+ if ( aPackageMediatype.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "application/vnd." ) ) == 0 )
+ {
+ // accept only types that look similar to own mediatypes
+ m_pRootFolder->SetMediaType( aPackageMediatype );
+ m_bMediaTypeFallbackUsed = sal_True;
+ }
+ }
+ else if ( !m_bForceRecovery )
+ {
+ // the mimetype stream should contain the information from manifest.xml
+ if ( !m_pRootFolder->GetMediaType().equals( aPackageMediatype ) )
+ throw ZipIOException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "mimetype conflicts with manifest.xml\n" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+
+ m_xRootFolder->removeByName( sMimetype );
+ }
+
+ m_bInconsistent = m_pRootFolder->LookForUnexpectedODF12Streams( ::rtl::OUString() );
+
+ sal_Bool bODF12AndOlder = ( m_pRootFolder->GetVersion().compareTo( ODFVER_012_TEXT ) >= 0 );
+ if ( !m_bForceRecovery && bODF12AndOlder && m_bInconsistent )
+ {
+ // this is an ODF1.2 document that contains streams not referred in the manifest.xml;
+ // in case of ODF1.2 documents without version in manifest.xml the property IsInconsistent
+ // should be checked later
+ throw ZipIOException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "there are streams not referred in manifest.xml\n" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+
+ // in case it is a correct ODF1.2 document, the version must be set
+ // and the META-INF folder is reserved for package format
+ if ( bODF12AndOlder )
+ m_xRootFolder->removeByName( sMeta );
+ }
+}
+
+void ZipPackage::parseContentType()
+{
+ if ( m_nFormat == embed::StorageFormats::OFOPXML )
+ {
+ const ::rtl::OUString aContentTypes( RTL_CONSTASCII_USTRINGPARAM ( "[Content_Types].xml" ) );
+ try {
+ // the content type must exist in OFOPXML format!
+ if ( !m_xRootFolder->hasByName( aContentTypes ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong format!" ) ),
+ uno::Reference< uno::XInterface >() );
+
+ uno::Reference< lang::XUnoTunnel > xTunnel;
+ uno::Any aAny = m_xRootFolder->getByName( aContentTypes );
+ aAny >>= xTunnel;
+ uno::Reference < io::XActiveDataSink > xSink( xTunnel, UNO_QUERY );
+ if ( xSink.is() )
+ {
+ uno::Reference< io::XInputStream > xInStream = xSink->getInputStream();
+ if ( xInStream.is() )
+ {
+ sal_Int32 nInd = 0;
+ // here aContentTypeInfo[0] - Defaults, and aContentTypeInfo[1] - Overrides
+ uno::Sequence< uno::Sequence< beans::StringPair > > aContentTypeInfo =
+ ::comphelper::OFOPXMLHelper::ReadContentTypeSequence( xInStream, m_xFactory );
+
+ if ( aContentTypeInfo.getLength() != 2 )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // set the implicit types fist
+ for ( nInd = 0; nInd < aContentTypeInfo[0].getLength(); nInd++ )
+ m_pRootFolder->setChildStreamsTypeByExtension( aContentTypeInfo[0][nInd] );
+
+ // now set the explicit types
+ for ( nInd = 0; nInd < aContentTypeInfo[1].getLength(); nInd++ )
+ {
+ ::rtl::OUString aPath;
+ if ( aContentTypeInfo[1][nInd].First.toChar() == (sal_Unicode)'/' )
+ aPath = aContentTypeInfo[1][nInd].First.copy( 1 );
+ else
+ aPath = aContentTypeInfo[1][nInd].First;
+
+ if ( aPath.getLength() && hasByHierarchicalName( aPath ) )
+ {
+ uno::Any aIterAny = getByHierarchicalName( aPath );
+ uno::Reference < lang::XUnoTunnel > xIterTunnel;
+ aIterAny >>= xIterTunnel;
+ sal_Int64 nTest = xIterTunnel->getSomething( ZipPackageStream::static_getImplementationId() );
+ if ( nTest != 0 )
+ {
+ // this is a package stream, in OFOPXML format only streams can have mediatype
+ ZipPackageStream *pStream = reinterpret_cast < ZipPackageStream* > ( nTest );
+ pStream->SetMediaType( aContentTypeInfo[1][nInd].Second );
+ }
+ }
+ }
+ }
+ }
+
+ m_xRootFolder->removeByName( aContentTypes );
+ }
+ catch( uno::Exception& )
+ {
+ if ( !m_bForceRecovery )
+ throw;
+ }
+ }
+}
+
+void ZipPackage::getZipFileContents()
+{
+ auto_ptr < ZipEnumeration > pEnum ( m_pZipFile->entries() );
+ ZipPackageStream *pPkgStream;
+ ZipPackageFolder *pPkgFolder, *pCurrent;
+ OUString sTemp, sDirName;
+ sal_Int32 nOldIndex, nIndex, nStreamIndex;
+ FolderHash::iterator aIter;
+
+ while (pEnum->hasMoreElements())
+ {
+ nIndex = nOldIndex = 0;
+ pCurrent = m_pRootFolder;
+ const ZipEntry & rEntry = *pEnum->nextElement();
+ OUString rName = rEntry.sPath;
+
+ if ( m_bForceRecovery )
+ {
+ // the PKZIP Application note version 6.2 does not allows to use '\' as separator
+ // unfortunately it is used by some implementations, so we have to support it in recovery mode
+ rName = rName.replace( '\\', '/' );
+ }
+
+ nStreamIndex = rName.lastIndexOf ( '/' );
+ if ( nStreamIndex != -1 )
+ {
+ sDirName = rName.copy ( 0, nStreamIndex);
+ aIter = m_aRecent.find ( sDirName );
+ if ( aIter != m_aRecent.end() )
+ pCurrent = (*aIter).second;
+ }
+
+ if ( pCurrent == m_pRootFolder )
+ {
+ while ( (nIndex = rName.indexOf('/', nOldIndex) ) != -1 )
+ {
+ sTemp = rName.copy ( nOldIndex, nIndex - nOldIndex );
+ if (nIndex == nOldIndex)
+ break;
+ if ( !pCurrent->hasByName( sTemp ) )
+ {
+ pPkgFolder = new ZipPackageFolder( m_xFactory, m_nFormat, m_bAllowRemoveOnInsert );
+ pPkgFolder->setName( sTemp );
+ pPkgFolder->doSetParent( pCurrent, sal_True );
+ pCurrent = pPkgFolder;
+ }
+ else
+ pCurrent = pCurrent->doGetByName(sTemp).pFolder;
+ nOldIndex = nIndex+1;
+ }
+ if ( nStreamIndex != -1 && sDirName.getLength() )
+ m_aRecent [ sDirName ] = pCurrent;
+ }
+ if ( rName.getLength() -1 != nStreamIndex )
+ {
+ nStreamIndex++;
+ sTemp = rName.copy( nStreamIndex, rName.getLength() - nStreamIndex);
+ pPkgStream = new ZipPackageStream( *this, m_xFactory, m_bAllowRemoveOnInsert );
+ pPkgStream->SetPackageMember( sal_True );
+ pPkgStream->setZipEntryOnLoading( rEntry );
+ pPkgStream->setName( sTemp );
+ pPkgStream->doSetParent( pCurrent, sal_True );
+ }
+ }
+
+ if ( m_nFormat == embed::StorageFormats::PACKAGE )
+ parseManifest();
+ else if ( m_nFormat == embed::StorageFormats::OFOPXML )
+ parseContentType();
+}
+
+// XInitialization
+void SAL_CALL ZipPackage::initialize( const Sequence< Any >& aArguments )
+ throw(Exception, RuntimeException)
+{
+ RTL_LOGFILE_TRACE_AUTHOR ( "package", LOGFILE_AUTHOR, "{ ZipPackage::initialize" );
+ sal_Bool bBadZipFile = sal_False, bHaveZipFile = sal_True;
+ uno::Reference< XProgressHandler > xProgressHandler;
+ beans::NamedValue aNamedValue;
+
+ if ( aArguments.getLength() )
+ {
+ for( int ind = 0; ind < aArguments.getLength(); ind++ )
+ {
+ OUString aParamUrl;
+ if ( (aArguments[ind] >>= aParamUrl))
+ {
+ m_eMode = e_IMode_URL;
+ try
+ {
+ sal_Int32 nParam = aParamUrl.indexOf( '?' );
+ if ( nParam >= 0 )
+ {
+ m_aURL = aParamUrl.copy( 0, nParam );
+ OUString aParam = aParamUrl.copy( nParam + 1 );
+
+ sal_Int32 nIndex = 0;
+ do
+ {
+ ::rtl::OUString aCommand = aParam.getToken( 0, '&', nIndex );
+ if ( aCommand.equals( OUString::createFromAscii( "repairpackage" ) ) )
+ {
+ m_bForceRecovery = sal_True;
+ break;
+ }
+ else if ( aCommand.equals( OUString::createFromAscii( "purezip" ) ) )
+ {
+ m_nFormat = embed::StorageFormats::ZIP;
+ m_pRootFolder->setPackageFormat_Impl( m_nFormat );
+ break;
+ }
+ else if ( aCommand.equals( OUString::createFromAscii( "ofopxml" ) ) )
+ {
+ m_nFormat = embed::StorageFormats::OFOPXML;
+ m_pRootFolder->setPackageFormat_Impl( m_nFormat );
+ break;
+ }
+ }
+ while ( nIndex >= 0 );
+ }
+ else
+ m_aURL = aParamUrl;
+
+ Content aContent ( m_aURL, uno::Reference < XCommandEnvironment >() );
+ Any aAny = aContent.getPropertyValue( OUString::createFromAscii( "Size" ) );
+ sal_uInt64 aSize = 0;
+ // kind of optimisation: treat empty files as nonexistent files
+ // and write to such files directly. Note that "Size" property is optional.
+ bool bHasSizeProperty = aAny >>= aSize;
+ if( !bHasSizeProperty || ( bHasSizeProperty && aSize ) )
+ {
+ uno::Reference < XActiveDataSink > xSink = new ZipPackageSink;
+ if (aContent.openStream ( xSink ) )
+ m_xContentStream = xSink->getInputStream();
+ }
+ else
+ bHaveZipFile = sal_False;
+ }
+ catch (com::sun::star::uno::Exception&)
+ {
+ // Exception derived from uno::Exception thrown. This probably
+ // means the file doesn't exist...we'll create it at
+ // commitChanges time
+ bHaveZipFile = sal_False;
+ }
+ }
+ else if ( (aArguments[ind] >>= m_xStream ) )
+ {
+ // a writable stream can implement both XStream & XInputStream
+ m_eMode = e_IMode_XStream;
+ m_xContentStream = m_xStream->getInputStream();
+ }
+ else if ( (aArguments[ind] >>= m_xContentStream) )
+ {
+ m_eMode = e_IMode_XInputStream;
+ }
+ else if ( ( aArguments[ind] >>= aNamedValue ) )
+ {
+ if ( aNamedValue.Name.equalsAscii( "RepairPackage" ) )
+ aNamedValue.Value >>= m_bForceRecovery;
+ else if ( aNamedValue.Name.equalsAscii( "PackageFormat" ) )
+ {
+ // setting this argument to true means Package format
+ // setting it to false means plain Zip format
+
+ sal_Bool bPackFormat = sal_True;
+ aNamedValue.Value >>= bPackFormat;
+ if ( !bPackFormat )
+ m_nFormat = embed::StorageFormats::ZIP;
+
+ m_pRootFolder->setPackageFormat_Impl( m_nFormat );
+ }
+ else if ( aNamedValue.Name.equalsAscii( "StorageFormat" ) )
+ {
+ ::rtl::OUString aFormatName;
+ sal_Int32 nFormatID = 0;
+ if ( aNamedValue.Value >>= aFormatName )
+ {
+ if ( aFormatName.equals( PACKAGE_STORAGE_FORMAT_STRING ) )
+ m_nFormat = embed::StorageFormats::PACKAGE;
+ else if ( aFormatName.equals( ZIP_STORAGE_FORMAT_STRING ) )
+ m_nFormat = embed::StorageFormats::ZIP;
+ else if ( aFormatName.equals( OFOPXML_STORAGE_FORMAT_STRING ) )
+ m_nFormat = embed::StorageFormats::OFOPXML;
+ else
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+ }
+ else if ( aNamedValue.Value >>= nFormatID )
+ {
+ if ( nFormatID != embed::StorageFormats::PACKAGE
+ && nFormatID != embed::StorageFormats::ZIP
+ && nFormatID != embed::StorageFormats::OFOPXML )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ m_nFormat = nFormatID;
+ }
+ else
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ m_pRootFolder->setPackageFormat_Impl( m_nFormat );
+ }
+ else if ( aNamedValue.Name.equalsAscii( "AllowRemoveOnInsert" ) )
+ {
+ aNamedValue.Value >>= m_bAllowRemoveOnInsert;
+ m_pRootFolder->setRemoveOnInsertMode_Impl( m_bAllowRemoveOnInsert );
+ }
+
+ // for now the progress handler is not used, probably it will never be
+ // if ( aNamedValue.Name.equalsAscii( "ProgressHandler" )
+ }
+ else
+ {
+ // The URL is not acceptable
+ throw com::sun::star::uno::Exception ( OUString( RTL_CONSTASCII_USTRINGPARAM ( OSL_LOG_PREFIX "Bad arguments." ) ),
+ static_cast < ::cppu::OWeakObject * > ( this ) );
+ }
+ }
+
+ try
+ {
+ if (m_xContentStream.is())
+ {
+ // the stream must be seekable, if it is not it will be wrapped
+ m_xContentStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( m_xContentStream, m_xFactory );
+ m_xContentSeek = uno::Reference < XSeekable > ( m_xContentStream, UNO_QUERY );
+ if ( ! m_xContentSeek.is() )
+ throw com::sun::star::uno::Exception ( OUString( RTL_CONSTASCII_USTRINGPARAM ( OSL_LOG_PREFIX "The package component _requires_ an XSeekable interface!" ) ),
+ static_cast < ::cppu::OWeakObject * > ( this ) );
+
+ if ( !m_xContentSeek->getLength() )
+ bHaveZipFile = sal_False;
+ }
+ else
+ bHaveZipFile = sal_False;
+ }
+ catch (com::sun::star::uno::Exception&)
+ {
+ // Exception derived from uno::Exception thrown. This probably
+ // means the file doesn't exist...we'll create it at
+ // commitChanges time
+ bHaveZipFile = sal_False;
+ }
+ if ( bHaveZipFile )
+ {
+ try
+ {
+ m_pZipFile = new ZipFile ( m_xContentStream, m_xFactory, sal_True, m_bForceRecovery, xProgressHandler );
+ getZipFileContents();
+ }
+ catch ( IOException & )
+ {
+ bBadZipFile = sal_True;
+ }
+ catch ( ZipException & )
+ {
+ bBadZipFile = sal_True;
+ }
+ catch ( Exception & )
+ {
+ if( m_pZipFile ) { delete m_pZipFile; m_pZipFile = NULL; }
+ throw;
+ }
+
+ if ( bBadZipFile )
+ {
+ // clean up the memory, and tell the UCB about the error
+ if( m_pZipFile ) { delete m_pZipFile; m_pZipFile = NULL; }
+
+ throw com::sun::star::packages::zip::ZipIOException (
+ OUString( RTL_CONSTASCII_USTRINGPARAM ( OSL_LOG_PREFIX "Bad Zip File." ) ),
+ static_cast < ::cppu::OWeakObject * > ( this ) );
+ }
+ }
+ }
+
+ RTL_LOGFILE_TRACE_AUTHOR ( "package", LOGFILE_AUTHOR, "} ZipPackage::initialize" );
+}
+
+Any SAL_CALL ZipPackage::getByHierarchicalName( const OUString& aName )
+ throw(NoSuchElementException, RuntimeException)
+{
+ OUString sTemp, sDirName;
+ sal_Int32 nOldIndex, nIndex, nStreamIndex;
+ FolderHash::iterator aIter;
+
+ if ( (nIndex = aName.getLength() ) == 1 && *aName.getStr() == '/' )
+ return makeAny ( uno::Reference < XUnoTunnel > (m_pRootFolder) );
+ else
+ {
+ nStreamIndex = aName.lastIndexOf ( '/' );
+ bool bFolder = nStreamIndex == nIndex-1;
+ if ( nStreamIndex != -1 )
+ {
+ sDirName = aName.copy ( 0, nStreamIndex);
+ aIter = m_aRecent.find ( sDirName );
+ if ( aIter != m_aRecent.end() )
+ {
+ if ( bFolder )
+ {
+ sal_Int32 nDirIndex = aName.lastIndexOf ( '/', nStreamIndex );
+ sTemp = aName.copy ( nDirIndex == -1 ? 0 : nDirIndex+1, nStreamIndex-nDirIndex-1 );
+ if ( sTemp == (*aIter).second->getName() )
+ return makeAny ( uno::Reference < XUnoTunnel > ( (*aIter).second ) );
+ else
+ m_aRecent.erase ( aIter );
+ }
+ else
+ {
+ sTemp = aName.copy ( nStreamIndex + 1 );
+ if ( (*aIter).second->hasByName( sTemp ) )
+ return (*aIter).second->getByName( sTemp );
+ else
+ m_aRecent.erase( aIter );
+ }
+ }
+ }
+ else
+ {
+ if ( m_pRootFolder->hasByName ( aName ) )
+ return m_pRootFolder->getByName ( aName );
+ }
+ nOldIndex = 0;
+ ZipPackageFolder * pCurrent = m_pRootFolder;
+ ZipPackageFolder * pPrevious = NULL;
+ while ( ( nIndex = aName.indexOf('/', nOldIndex)) != -1)
+ {
+ sTemp = aName.copy (nOldIndex, nIndex - nOldIndex);
+ if ( nIndex == nOldIndex )
+ break;
+ if ( pCurrent->hasByName( sTemp ) )
+ {
+ pPrevious = pCurrent;
+ pCurrent = pCurrent->doGetByName(sTemp).pFolder;
+ }
+ else
+ throw NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ nOldIndex = nIndex+1;
+ }
+ if ( bFolder )
+ {
+ if (nStreamIndex != -1 )
+ m_aRecent[sDirName] = pPrevious;
+ return makeAny ( uno::Reference < XUnoTunnel > ( pCurrent ) );
+ }
+ else
+ {
+ sTemp = aName.copy( nOldIndex, aName.getLength() - nOldIndex);
+ if ( pCurrent->hasByName ( sTemp ) )
+ {
+ if (nStreamIndex != -1 )
+ m_aRecent[sDirName] = pCurrent;
+ return pCurrent->getByName( sTemp );
+ }
+ else
+ throw NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+ }
+}
+
+sal_Bool SAL_CALL ZipPackage::hasByHierarchicalName( const OUString& aName )
+ throw(RuntimeException)
+{
+ OUString sTemp, sDirName;
+ sal_Int32 nOldIndex, nIndex, nStreamIndex;
+ FolderHash::iterator aIter;
+
+ if ( (nIndex = aName.getLength() ) == 1 && *aName.getStr() == '/' )
+ return sal_True;
+ else
+ {
+ nStreamIndex = aName.lastIndexOf ( '/' );
+ bool bFolder = nStreamIndex == nIndex-1;
+ if ( nStreamIndex != -1 )
+ {
+ sDirName = aName.copy ( 0, nStreamIndex);
+ aIter = m_aRecent.find ( sDirName );
+ if ( aIter != m_aRecent.end() )
+ {
+ if ( bFolder )
+ {
+ sal_Int32 nDirIndex = aName.lastIndexOf ( '/', nStreamIndex );
+ sTemp = aName.copy ( nDirIndex == -1 ? 0 : nDirIndex+1, nStreamIndex-nDirIndex-1 );
+ if ( sTemp == (*aIter).second->getName() )
+ return sal_True;
+ else
+ m_aRecent.erase ( aIter );
+ }
+ else
+ {
+ sTemp = aName.copy ( nStreamIndex + 1 );
+ if ( (*aIter).second->hasByName( sTemp ) )
+ return sal_True;
+ else
+ m_aRecent.erase( aIter );
+ }
+ }
+ }
+ else
+ {
+ if ( m_pRootFolder->hasByName ( aName ) )
+ return sal_True;
+ }
+ ZipPackageFolder * pCurrent = m_pRootFolder;
+ ZipPackageFolder * pPrevious = NULL;
+ nOldIndex = 0;
+ while ( ( nIndex = aName.indexOf('/', nOldIndex)) != -1)
+ {
+ sTemp = aName.copy (nOldIndex, nIndex - nOldIndex);
+ if ( nIndex == nOldIndex )
+ break;
+ if ( pCurrent->hasByName( sTemp ) )
+ {
+ pPrevious = pCurrent;
+ pCurrent = pCurrent->doGetByName( sTemp ).pFolder;
+ }
+ else
+ return sal_False;
+ nOldIndex = nIndex+1;
+ }
+ if ( bFolder )
+ {
+ m_aRecent[sDirName] = pPrevious;
+ return sal_True;
+ }
+ else
+ {
+ sTemp = aName.copy( nOldIndex, aName.getLength() - nOldIndex);
+
+ if ( pCurrent->hasByName( sTemp ) )
+ {
+ m_aRecent[sDirName] = pCurrent;
+ return sal_True;
+ }
+ }
+ return sal_False;
+ }
+}
+
+// XSingleServiceFactory
+uno::Reference< XInterface > SAL_CALL ZipPackage::createInstance( )
+ throw(Exception, RuntimeException)
+{
+ uno::Reference < XInterface > xRef = *(new ZipPackageStream ( *this, m_xFactory, m_bAllowRemoveOnInsert ));
+ return xRef;
+}
+uno::Reference< XInterface > SAL_CALL ZipPackage::createInstanceWithArguments( const Sequence< Any >& aArguments )
+ throw(Exception, RuntimeException)
+{
+ sal_Bool bArg = sal_False;
+ uno::Reference < XInterface > xRef;
+ if ( aArguments.getLength() )
+ aArguments[0] >>= bArg;
+ if (bArg)
+ xRef = *new ZipPackageFolder ( m_xFactory, m_nFormat, m_bAllowRemoveOnInsert );
+ else
+ xRef = *new ZipPackageStream ( *this, m_xFactory, m_bAllowRemoveOnInsert );
+
+ return xRef;
+}
+
+void ZipPackage::WriteMimetypeMagicFile( ZipOutputStream& aZipOut )
+{
+ const OUString sMime ( RTL_CONSTASCII_USTRINGPARAM ( "mimetype" ) );
+ if (m_xRootFolder->hasByName( sMime ) )
+ m_xRootFolder->removeByName( sMime );
+
+ ZipEntry * pEntry = new ZipEntry;
+ sal_Int32 nBufferLength = m_pRootFolder->GetMediaType( ).getLength();
+ OString sMediaType = OUStringToOString( m_pRootFolder->GetMediaType(), RTL_TEXTENCODING_ASCII_US );
+ Sequence< sal_Int8 > aType( (sal_Int8*)sMediaType.getStr(),
+ nBufferLength );
+
+
+ pEntry->sPath = sMime;
+ pEntry->nMethod = STORED;
+ pEntry->nSize = pEntry->nCompressedSize = nBufferLength;
+ pEntry->nTime = ZipOutputStream::getCurrentDosTime();
+
+ CRC32 aCRC32;
+ aCRC32.update( aType );
+ pEntry->nCrc = aCRC32.getValue();
+
+ try
+ {
+ vos::ORef < EncryptionData > xEmpty;
+ aZipOut.putNextEntry( *pEntry, xEmpty );
+ aZipOut.write( aType, 0, nBufferLength );
+ aZipOut.closeEntry();
+ }
+ catch ( ::com::sun::star::io::IOException & r )
+ {
+ VOS_ENSURE( 0, "Error adding mimetype to the ZipOutputStream" );
+ throw WrappedTargetException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM ( OSL_LOG_PREFIX "Error adding mimetype to the ZipOutputStream!" ) ),
+ static_cast < OWeakObject * > ( this ),
+ makeAny( r ) );
+ }
+}
+
+void ZipPackage::WriteManifest( ZipOutputStream& aZipOut, const vector< Sequence < PropertyValue > >& aManList )
+{
+ // Write the manifest
+ uno::Reference < XOutputStream > xManOutStream;
+ OUString sManifestWriter( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.manifest.ManifestWriter" ) );
+ uno::Reference < XManifestWriter > xWriter ( m_xFactory->createInstance( sManifestWriter ), UNO_QUERY );
+ if ( xWriter.is() )
+ {
+ ZipEntry * pEntry = new ZipEntry;
+ ZipPackageBuffer *pBuffer = new ZipPackageBuffer( n_ConstBufferSize );
+ xManOutStream = uno::Reference < XOutputStream > (*pBuffer, UNO_QUERY);
+
+ pEntry->sPath = OUString( RTL_CONSTASCII_USTRINGPARAM ( "META-INF/manifest.xml") );
+ pEntry->nMethod = DEFLATED;
+ pEntry->nCrc = pEntry->nSize = pEntry->nCompressedSize = -1;
+ pEntry->nTime = ZipOutputStream::getCurrentDosTime();
+
+ // Convert vector into a Sequence
+ Sequence < Sequence < PropertyValue > > aManifestSequence ( aManList.size() );
+ Sequence < PropertyValue > * pSequence = aManifestSequence.getArray();
+ for (vector < Sequence < PropertyValue > >::const_iterator aIter = aManList.begin(), aEnd = aManList.end();
+ aIter != aEnd;
+ aIter++, pSequence++)
+ *pSequence= (*aIter);
+ xWriter->writeManifestSequence ( xManOutStream, aManifestSequence );
+
+ sal_Int32 nBufferLength = static_cast < sal_Int32 > ( pBuffer->getPosition() );
+ pBuffer->realloc( nBufferLength );
+
+ // the manifest.xml is never encrypted - so pass an empty reference
+ vos::ORef < EncryptionData > xEmpty;
+ aZipOut.putNextEntry( *pEntry, xEmpty );
+ aZipOut.write( pBuffer->getSequence(), 0, nBufferLength );
+ aZipOut.closeEntry();
+ }
+ else
+ {
+ VOS_ENSURE ( 0, "Couldn't get a ManifestWriter!" );
+ IOException aException;
+ throw WrappedTargetException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM ( OSL_LOG_PREFIX "Couldn't get a ManifestWriter!" ) ),
+ static_cast < OWeakObject * > ( this ),
+ makeAny( aException ) );
+ }
+}
+
+void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< Sequence < PropertyValue > >& aManList )
+{
+ const OUString sFullPath ( RTL_CONSTASCII_USTRINGPARAM ( "FullPath" ) );
+ const OUString sMediaType ( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) );
+
+ ZipEntry* pEntry = new ZipEntry;
+ ZipPackageBuffer *pBuffer = new ZipPackageBuffer( n_ConstBufferSize );
+ uno::Reference< io::XOutputStream > xConTypeOutStream( *pBuffer, UNO_QUERY );
+
+ pEntry->sPath = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "[Content_Types].xml") );
+ pEntry->nMethod = DEFLATED;
+ pEntry->nCrc = pEntry->nSize = pEntry->nCompressedSize = -1;
+ pEntry->nTime = ZipOutputStream::getCurrentDosTime();
+
+ // Convert vector into a Sequence
+ // TODO/LATER: use Defaulst entries in future
+ uno::Sequence< beans::StringPair > aDefaultsSequence;
+ uno::Sequence< beans::StringPair > aOverridesSequence( aManList.size() );
+ sal_Int32 nSeqLength = 0;
+ for ( vector< uno::Sequence< beans::PropertyValue > >::const_iterator aIter = aManList.begin(),
+ aEnd = aManList.end();
+ aIter != aEnd;
+ aIter++)
+ {
+ ::rtl::OUString aPath;
+ ::rtl::OUString aType;
+ OSL_ENSURE( (*aIter)[PKG_MNFST_MEDIATYPE].Name.equals( sMediaType ) && (*aIter)[PKG_MNFST_FULLPATH].Name.equals( sFullPath ),
+ "The mediatype sequence format is wrong!\n" );
+ (*aIter)[PKG_MNFST_MEDIATYPE].Value >>= aType;
+ if ( aType.getLength() )
+ {
+ // only nonempty type makes sence here
+ nSeqLength++;
+ (*aIter)[PKG_MNFST_FULLPATH].Value >>= aPath;
+ aOverridesSequence[nSeqLength-1].First = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ) + aPath;
+ aOverridesSequence[nSeqLength-1].Second = aType;
+ }
+ }
+ aOverridesSequence.realloc( nSeqLength );
+
+ ::comphelper::OFOPXMLHelper::WriteContentSequence(
+ xConTypeOutStream, aDefaultsSequence, aOverridesSequence, m_xFactory );
+
+ sal_Int32 nBufferLength = static_cast < sal_Int32 > ( pBuffer->getPosition() );
+ pBuffer->realloc( nBufferLength );
+
+ // there is no encryption in this format currently
+ vos::ORef < EncryptionData > xEmpty;
+ aZipOut.putNextEntry( *pEntry, xEmpty );
+ aZipOut.write( pBuffer->getSequence(), 0, nBufferLength );
+ aZipOut.closeEntry();
+}
+
+void ZipPackage::ConnectTo( const uno::Reference< io::XInputStream >& xInStream )
+{
+ m_xContentSeek.set( xInStream, uno::UNO_QUERY_THROW );
+ m_xContentStream = xInStream;
+
+ // seek back to the beginning of the temp file so we can read segments from it
+ m_xContentSeek->seek( 0 );
+ if ( m_pZipFile )
+ m_pZipFile->setInputStream( m_xContentStream );
+ else
+ m_pZipFile = new ZipFile ( m_xContentStream, m_xFactory, sal_False );
+}
+
+uno::Reference< io::XInputStream > ZipPackage::writeTempFile()
+{
+ // In case the target local file does not exist or empty
+ // write directly to it otherwize create a temporary file to write to.
+ // If a temporary file is created it is returned back by the method.
+ // If the data written directly, xComponentStream will be switched here
+
+ sal_Bool bUseTemp = sal_True;
+ uno::Reference < io::XInputStream > xResult;
+ uno::Reference < io::XInputStream > xTempIn;
+
+ uno::Reference < io::XOutputStream > xTempOut;
+ uno::Reference< io::XActiveDataStreamer > xSink;
+
+ if ( m_eMode == e_IMode_URL && !m_pZipFile && isLocalFile_Impl( m_aURL ) )
+ {
+ xSink = openOriginalForOutput();
+ if( xSink.is() )
+ {
+ uno::Reference< io::XStream > xStr = xSink->getStream();
+ if( xStr.is() )
+ {
+ xTempOut = xStr->getOutputStream();
+ if( xTempOut.is() )
+ bUseTemp = sal_False;
+ }
+ }
+ }
+ else if ( m_eMode == e_IMode_XStream && !m_pZipFile )
+ {
+ // write directly to an empty stream
+ xTempOut = m_xStream->getOutputStream();
+ if( xTempOut.is() )
+ bUseTemp = sal_False;
+ }
+
+ if( bUseTemp )
+ {
+ // create temporary file
+ const OUString sServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) );
+ uno::Reference < io::XStream > xTempFile( m_xFactory->createInstance ( sServiceName ), UNO_QUERY_THROW );
+ xTempOut.set( xTempFile->getOutputStream(), UNO_SET_THROW );
+ xTempIn.set( xTempFile->getInputStream(), UNO_SET_THROW );
+ }
+
+ // Hand it to the ZipOutputStream:
+ ZipOutputStream aZipOut ( xTempOut );
+ aZipOut.setMethod(DEFLATED);
+ aZipOut.setLevel(DEFAULT_COMPRESSION);
+
+ try
+ {
+ if ( m_nFormat == embed::StorageFormats::PACKAGE )
+ {
+ // Remove the old manifest.xml file as the
+ // manifest will be re-generated and the
+ // META-INF directory implicitly created if does not exist
+ const OUString sMeta ( RTL_CONSTASCII_USTRINGPARAM ( "META-INF" ) );
+
+ if ( m_xRootFolder->hasByName( sMeta ) )
+ {
+ const OUString sManifest (RTL_CONSTASCII_USTRINGPARAM( "manifest.xml") );
+
+ uno::Reference< XUnoTunnel > xTunnel;
+ Any aAny = m_xRootFolder->getByName( sMeta );
+ aAny >>= xTunnel;
+ uno::Reference< XNameContainer > xMetaInfFolder( xTunnel, UNO_QUERY );
+ if ( xMetaInfFolder.is() && xMetaInfFolder->hasByName( sManifest ) )
+ xMetaInfFolder->removeByName( sManifest );
+ }
+
+ // Write a magic file with mimetype
+ WriteMimetypeMagicFile( aZipOut );
+ }
+ else if ( m_nFormat == embed::StorageFormats::OFOPXML )
+ {
+ // Remove the old [Content_Types].xml file as the
+ // file will be re-generated
+
+ const ::rtl::OUString aContentTypes( RTL_CONSTASCII_USTRINGPARAM ( "[Content_Types].xml" ) );
+
+ if ( m_xRootFolder->hasByName( aContentTypes ) )
+ m_xRootFolder->removeByName( aContentTypes );
+ }
+
+ // Create a vector to store data for the manifest.xml file
+ vector < Sequence < PropertyValue > > aManList;
+
+ const OUString sMediaType ( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) );
+ const OUString sVersion ( RTL_CONSTASCII_USTRINGPARAM ( "Version" ) );
+ const OUString sFullPath ( RTL_CONSTASCII_USTRINGPARAM ( "FullPath" ) );
+
+ if ( m_nFormat == embed::StorageFormats::PACKAGE )
+ {
+ Sequence < PropertyValue > aPropSeq ( PKG_SIZE_NOENCR_MNFST );
+ aPropSeq [PKG_MNFST_MEDIATYPE].Name = sMediaType;
+ aPropSeq [PKG_MNFST_MEDIATYPE].Value <<= m_pRootFolder->GetMediaType( );
+ aPropSeq [PKG_MNFST_VERSION].Name = sVersion;
+ aPropSeq [PKG_MNFST_VERSION].Value <<= m_pRootFolder->GetVersion( );
+ aPropSeq [PKG_MNFST_FULLPATH].Name = sFullPath;
+ aPropSeq [PKG_MNFST_FULLPATH].Value <<= OUString ( RTL_CONSTASCII_USTRINGPARAM ( "/" ) );
+
+ aManList.push_back( aPropSeq );
+ }
+
+ // Get a random number generator and seed it with current timestamp
+ // This will be used to generate random salt and initialisation vectors
+ // for encrypted streams
+ TimeValue aTime;
+ osl_getSystemTime( &aTime );
+ rtlRandomPool aRandomPool = rtl_random_createPool ();
+ rtl_random_addBytes ( aRandomPool, &aTime, 8 );
+
+
+ // call saveContents (it will recursively save sub-directories
+ OUString aEmptyString;
+ m_pRootFolder->saveContents( aEmptyString, aManList, aZipOut, m_aEncryptionKey, aRandomPool );
+
+ // Clean up random pool memory
+ rtl_random_destroyPool ( aRandomPool );
+
+ if( m_bUseManifest && m_nFormat == embed::StorageFormats::PACKAGE )
+ {
+ WriteManifest( aZipOut, aManList );
+ }
+ else if( m_nFormat == embed::StorageFormats::OFOPXML )
+ {
+ WriteContentTypes( aZipOut, aManList );
+ }
+
+ aZipOut.finish();
+
+ if( bUseTemp )
+ xResult = xTempIn;
+
+ // Update our References to point to the new temp file
+ if( !bUseTemp )
+ {
+ // the case when the original contents were written directly
+ xTempOut->flush();
+
+ // in case the stream is based on a file it will implement the following interface
+ // the call should be used to be sure that the contents are written to the file system
+ uno::Reference< io::XAsyncOutputMonitor > asyncOutputMonitor( xTempOut, uno::UNO_QUERY );
+ if ( asyncOutputMonitor.is() )
+ asyncOutputMonitor->waitForCompletion();
+
+ // no need to postpone switching to the new stream since the target was written directly
+ uno::Reference< io::XInputStream > xNewStream;
+ if ( m_eMode == e_IMode_URL )
+ xNewStream = xSink->getStream()->getInputStream();
+ else if ( m_eMode == e_IMode_XStream && m_xStream.is() )
+ xNewStream = m_xStream->getInputStream();
+
+ if ( xNewStream.is() )
+ ConnectTo( xNewStream );
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ if( bUseTemp )
+ {
+ // no information loss appeares, thus no special handling is required
+ uno::Any aCaught( ::cppu::getCaughtException() );
+
+ // it is allowed to throw WrappedTargetException
+ WrappedTargetException aException;
+ if ( aCaught >>= aException )
+ throw aException;
+
+ throw WrappedTargetException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM ( OSL_LOG_PREFIX "Problem writing the original content!" ) ),
+ static_cast < OWeakObject * > ( this ),
+ aCaught );
+ }
+ else
+ {
+ // the document is written directly, although it was empty it is important to notify that the writing has failed
+ // TODO/LATER: let the package be able to recover in this situation
+ ::rtl::OUString aErrTxt( RTL_CONSTASCII_USTRINGPARAM ( OSL_LOG_PREFIX "This package is unusable!" ) );
+ embed::UseBackupException aException( aErrTxt, uno::Reference< uno::XInterface >(), ::rtl::OUString() );
+ throw WrappedTargetException( aErrTxt,
+ static_cast < OWeakObject * > ( this ),
+ makeAny ( aException ) );
+ }
+ }
+
+ return xResult;
+}
+
+uno::Reference< XActiveDataStreamer > ZipPackage::openOriginalForOutput()
+{
+ // open and truncate the original file
+ Content aOriginalContent (m_aURL, uno::Reference < XCommandEnvironment >() );
+ uno::Reference< XActiveDataStreamer > xSink = new ActiveDataStreamer;
+
+ if ( m_eMode == e_IMode_URL )
+ {
+ try
+ {
+ sal_Bool bTruncSuccess = sal_False;
+
+ try
+ {
+ Exception aDetect;
+ sal_Int64 aSize = 0;
+ Any aAny = aOriginalContent.setPropertyValue( OUString::createFromAscii( "Size" ), makeAny( aSize ) );
+ if( !( aAny >>= aDetect ) )
+ bTruncSuccess = sal_True;
+ }
+ catch( Exception& )
+ {
+ }
+
+ if( !bTruncSuccess )
+ {
+ // the file is not accessible
+ // just try to write an empty stream to it
+
+ uno::Reference< XInputStream > xTempIn = new DummyInputStream; //uno::Reference< XInputStream >( xTempOut, UNO_QUERY );
+ aOriginalContent.writeStream( xTempIn , sal_True );
+ }
+
+ OpenCommandArgument2 aArg;
+ aArg.Mode = OpenMode::DOCUMENT;
+ aArg.Priority = 0; // unused
+ aArg.Sink = xSink;
+ aArg.Properties = Sequence< Property >( 0 ); // unused
+
+ aOriginalContent.executeCommand( OUString::createFromAscii( "open" ), makeAny( aArg ) );
+ }
+ catch( Exception& )
+ {
+ // seems to be nonlocal file
+ // temporary file mechanics should be used
+ }
+ }
+
+ return xSink;
+}
+
+// XChangesBatch
+void SAL_CALL ZipPackage::commitChanges()
+ throw(WrappedTargetException, RuntimeException)
+{
+ // lock the component for the time of commiting
+ ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
+
+ if ( m_eMode == e_IMode_XInputStream )
+ {
+ IOException aException;
+ throw WrappedTargetException( OUString( RTL_CONSTASCII_USTRINGPARAM ( OSL_LOG_PREFIX "This package is read only!" ) ),
+ static_cast < OWeakObject * > ( this ), makeAny ( aException ) );
+ }
+
+ RTL_LOGFILE_TRACE_AUTHOR ( "package", LOGFILE_AUTHOR, "{ ZipPackage::commitChanges" );
+
+ // first the writeTempFile is called, if it returns a stream the stream should be written to the target
+ // if no stream was returned, the file was written directly, nothing should be done
+
+ uno::Reference< io::XInputStream > xTempInStream = writeTempFile();
+ if ( xTempInStream.is() )
+ {
+ uno::Reference< io::XSeekable > xTempSeek( xTempInStream, uno::UNO_QUERY_THROW );
+
+ try
+ {
+ xTempSeek->seek( 0 );
+ }
+ catch( uno::Exception& r )
+ {
+ throw WrappedTargetException( OUString( RTL_CONSTASCII_USTRINGPARAM ( OSL_LOG_PREFIX "Temporary file should be seekable!" ) ),
+ static_cast < OWeakObject * > ( this ), makeAny ( r ) );
+ }
+
+ // connect to the temporary stream
+ ConnectTo( xTempInStream );
+
+ if ( m_eMode == e_IMode_XStream )
+ {
+ // First truncate our output stream
+ uno::Reference < XOutputStream > xOutputStream;
+
+ // preparation for copy step
+ try
+ {
+ xOutputStream = m_xStream->getOutputStream();
+ uno::Reference < XTruncate > xTruncate ( xOutputStream, UNO_QUERY );
+ if ( !xTruncate.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // after successful truncation the original file contents are already lost
+ xTruncate->truncate();
+ }
+ catch( uno::Exception& r )
+ {
+ throw WrappedTargetException( OUString( RTL_CONSTASCII_USTRINGPARAM ( OSL_LOG_PREFIX "This package is read only!" ) ),
+ static_cast < OWeakObject * > ( this ), makeAny ( r ) );
+ }
+
+ try
+ {
+ // then copy the contents of the tempfile to our output stream
+ ::comphelper::OStorageHelper::CopyInputToOutput( xTempInStream, xOutputStream );
+ xOutputStream->flush();
+ uno::Reference< io::XAsyncOutputMonitor > asyncOutputMonitor(
+ xOutputStream, uno::UNO_QUERY);
+ if (asyncOutputMonitor.is()) {
+ asyncOutputMonitor->waitForCompletion();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ // if anything goes wrong in this block the target file becomes corrupted
+ // so an exception should be thrown as a notification about it
+ // and the package must disconnect from the stream
+ DisconnectFromTargetAndThrowException_Impl( xTempInStream );
+ }
+ }
+ else if ( m_eMode == e_IMode_URL )
+ {
+ uno::Reference< XOutputStream > aOrigFileStream;
+ sal_Bool bCanBeCorrupted = sal_False;
+
+ if( isLocalFile_Impl( m_aURL ) )
+ {
+ // write directly in case of local file
+ uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xSimpleAccess(
+ m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
+ uno::UNO_QUERY );
+ OSL_ENSURE( xSimpleAccess.is(), "Can't instatiate SimpleFileAccess service!\n" );
+ uno::Reference< io::XTruncate > xOrigTruncate;
+ if ( xSimpleAccess.is() )
+ {
+ try
+ {
+ aOrigFileStream = xSimpleAccess->openFileWrite( m_aURL );
+ xOrigTruncate = uno::Reference< io::XTruncate >( aOrigFileStream, uno::UNO_QUERY_THROW );
+ // after successful truncation the file is already corrupted
+ xOrigTruncate->truncate();
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ if( xOrigTruncate.is() )
+ {
+ try
+ {
+ ::comphelper::OStorageHelper::CopyInputToOutput( xTempInStream, aOrigFileStream );
+ aOrigFileStream->closeOutput();
+ }
+ catch( uno::Exception& )
+ {
+ try {
+ aOrigFileStream->closeOutput();
+ } catch ( uno::Exception& ) {}
+
+ aOrigFileStream = uno::Reference< XOutputStream >();
+ // the original file can already be corrupted
+ bCanBeCorrupted = sal_True;
+ }
+ }
+ }
+
+ if( !aOrigFileStream.is() )
+ {
+ try
+ {
+ uno::Reference < XPropertySet > xPropSet ( xTempInStream, UNO_QUERY );
+ OSL_ENSURE( xPropSet.is(), "This is a temporary file that must implement XPropertySet!\n" );
+ if ( !xPropSet.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ OUString sTargetFolder = m_aURL.copy ( 0, m_aURL.lastIndexOf ( static_cast < sal_Unicode > ( '/' ) ) );
+ Content aContent ( sTargetFolder, uno::Reference < XCommandEnvironment > () );
+
+ OUString sTempURL;
+ Any aAny = xPropSet->getPropertyValue ( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Uri" ) ) );
+ aAny >>= sTempURL;
+
+ TransferInfo aInfo;
+ aInfo.NameClash = NameClash::OVERWRITE;
+ aInfo.MoveData = sal_False;
+ aInfo.SourceURL = sTempURL;
+ aInfo.NewTitle = rtl::Uri::decode ( m_aURL.copy ( 1 + m_aURL.lastIndexOf ( static_cast < sal_Unicode > ( '/' ) ) ),
+ rtl_UriDecodeWithCharset,
+ RTL_TEXTENCODING_UTF8 );
+ aAny <<= aInfo;
+
+ // if the file is still not corrupted, it can become after the next step
+ aContent.executeCommand ( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "transfer" ) ), aAny );
+ }
+ catch (::com::sun::star::uno::Exception& r)
+ {
+ if ( bCanBeCorrupted )
+ DisconnectFromTargetAndThrowException_Impl( xTempInStream );
+
+ throw WrappedTargetException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM ( OSL_LOG_PREFIX "This package may be read only!" ) ),
+ static_cast < OWeakObject * > ( this ),
+ makeAny ( r ) );
+ }
+ }
+ }
+ }
+
+ // after successful storing it can be set to false
+ m_bMediaTypeFallbackUsed = sal_False;
+
+ RTL_LOGFILE_TRACE_AUTHOR ( "package", LOGFILE_AUTHOR, "} ZipPackage::commitChanges" );
+}
+
+void ZipPackage::DisconnectFromTargetAndThrowException_Impl( const uno::Reference< io::XInputStream >& xTempStream )
+{
+ m_xStream = uno::Reference< io::XStream >( xTempStream, uno::UNO_QUERY );
+ if ( m_xStream.is() )
+ m_eMode = e_IMode_XStream;
+ else
+ m_eMode = e_IMode_XInputStream;
+
+ ::rtl::OUString aTempURL;
+ try {
+ uno::Reference< beans::XPropertySet > xTempFile( xTempStream, uno::UNO_QUERY_THROW );
+ uno::Any aUrl = xTempFile->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
+ aUrl >>= aTempURL;
+ xTempFile->setPropertyValue( ::rtl::OUString::createFromAscii( "RemoveFile" ),
+ uno::makeAny( sal_False ) );
+ }
+ catch ( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "These calls are pretty simple, they should not fail!\n" );
+ }
+
+ ::rtl::OUString aErrTxt( RTL_CONSTASCII_USTRINGPARAM ( OSL_LOG_PREFIX "This package is read only!" ) );
+ embed::UseBackupException aException( aErrTxt, uno::Reference< uno::XInterface >(), aTempURL );
+ throw WrappedTargetException( aErrTxt,
+ static_cast < OWeakObject * > ( this ),
+ makeAny ( aException ) );
+}
+
+sal_Bool SAL_CALL ZipPackage::hasPendingChanges( )
+ throw(RuntimeException)
+{
+ return sal_False;
+}
+Sequence< ElementChange > SAL_CALL ZipPackage::getPendingChanges( )
+ throw(RuntimeException)
+{
+ return Sequence < ElementChange > ();
+}
+
+/**
+ * Function to create a new component instance; is needed by factory helper implementation.
+ * @param xMgr service manager to if the components needs other component instances
+ */
+uno::Reference < XInterface >SAL_CALL ZipPackage_createInstance(
+ const uno::Reference< XMultiServiceFactory > & xMgr )
+{
+ return uno::Reference< XInterface >( *new ZipPackage(xMgr) );
+}
+
+OUString ZipPackage::static_getImplementationName()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.comp.ZipPackage" ) );
+}
+
+Sequence< OUString > ZipPackage::static_getSupportedServiceNames()
+{
+ Sequence< OUString > aNames(1);
+ aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.Package" ) );
+ return aNames;
+}
+sal_Bool SAL_CALL ZipPackage::static_supportsService( OUString const & rServiceName )
+{
+ return rServiceName == getSupportedServiceNames()[0];
+}
+
+OUString ZipPackage::getImplementationName()
+ throw (RuntimeException)
+{
+ return static_getImplementationName();
+}
+
+Sequence< OUString > ZipPackage::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return static_getSupportedServiceNames();
+}
+sal_Bool SAL_CALL ZipPackage::supportsService( OUString const & rServiceName )
+ throw (RuntimeException)
+{
+ return static_supportsService ( rServiceName );
+}
+uno::Reference < XSingleServiceFactory > ZipPackage::createServiceFactory( uno::Reference < XMultiServiceFactory > const & rServiceFactory )
+{
+ return cppu::createSingleFactory (rServiceFactory,
+ static_getImplementationName(),
+ ZipPackage_createInstance,
+ static_getSupportedServiceNames());
+}
+
+// XUnoTunnel
+Sequence< sal_Int8 > ZipPackage::getUnoTunnelImplementationId( void )
+ throw (RuntimeException)
+{
+ static ::cppu::OImplementationId * pId = 0;
+ if (! pId)
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static ::cppu::OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+
+sal_Int64 SAL_CALL ZipPackage::getSomething( const Sequence< sal_Int8 >& aIdentifier )
+ throw(RuntimeException)
+{
+ if (aIdentifier.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), aIdentifier.getConstArray(), 16 ) )
+ return reinterpret_cast < sal_Int64 > ( this );
+ return 0;
+}
+
+uno::Reference< XPropertySetInfo > SAL_CALL ZipPackage::getPropertySetInfo( )
+ throw(RuntimeException)
+{
+ return uno::Reference < XPropertySetInfo > ();
+}
+void SAL_CALL ZipPackage::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
+ throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ if ( m_nFormat != embed::StorageFormats::PACKAGE )
+ throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("HasEncryptedEntries") )
+ ||aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("HasNonEncryptedEntries") )
+ ||aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("IsInconsistent") )
+ ||aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("MediaTypeFallbackUsed") ) )
+ throw PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("EncryptionKey") ) )
+ {
+ if (!( aValue >>= m_aEncryptionKey ) )
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
+ }
+ else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("UseManifest") ) )
+ {
+ if (!( aValue >>= m_bUseManifest ) )
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
+ }
+ else
+ throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+Any SAL_CALL ZipPackage::getPropertyValue( const OUString& PropertyName )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ // TODO/LATER: Activate the check when zip-ucp is ready
+ // if ( m_nFormat != embed::StorageFormats::PACKAGE )
+ // throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ Any aAny;
+ if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "EncryptionKey" ) ) )
+ {
+ aAny <<= m_aEncryptionKey;
+ return aAny;
+ }
+ else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "HasEncryptedEntries" ) ) )
+ {
+ aAny <<= m_bHasEncryptedEntries;
+ return aAny;
+ }
+ else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "HasNonEncryptedEntries" ) ) )
+ {
+ aAny <<= m_bHasNonEncryptedEntries;
+ return aAny;
+ }
+ else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "IsInconsistent" ) ) )
+ {
+ aAny <<= m_bInconsistent;
+ return aAny;
+ }
+ else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "UseManifest" ) ) )
+ {
+ aAny <<= m_bUseManifest;
+ return aAny;
+ }
+ else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "MediaTypeFallbackUsed" ) ) )
+ {
+ aAny <<= m_bMediaTypeFallbackUsed;
+ return aAny;
+ }
+ throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+void SAL_CALL ZipPackage::addPropertyChangeListener( const OUString& /*aPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*xListener*/ )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+void SAL_CALL ZipPackage::removePropertyChangeListener( const OUString& /*aPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*aListener*/ )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+void SAL_CALL ZipPackage::addVetoableChangeListener( const OUString& /*PropertyName*/, const uno::Reference< XVetoableChangeListener >& /*aListener*/ )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+void SAL_CALL ZipPackage::removeVetoableChangeListener( const OUString& /*PropertyName*/, const uno::Reference< XVetoableChangeListener >& /*aListener*/ )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
diff --git a/package/source/zippackage/ZipPackageBuffer.cxx b/package/source/zippackage/ZipPackageBuffer.cxx
new file mode 100644
index 000000000000..e6468c8539f0
--- /dev/null
+++ b/package/source/zippackage/ZipPackageBuffer.cxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ZipPackageBuffer.hxx>
+#include <string.h> // for memcpy
+
+using namespace ::com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::io;
+using com::sun::star::lang::IllegalArgumentException;
+
+ZipPackageBuffer::ZipPackageBuffer(sal_Int64 nNewBufferSize )
+: m_nBufferSize (nNewBufferSize)
+, m_nEnd(0)
+, m_nCurrent(0)
+, m_bMustInitBuffer ( sal_True )
+{
+}
+ZipPackageBuffer::~ZipPackageBuffer(void)
+{
+}
+
+sal_Int32 SAL_CALL ZipPackageBuffer::readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ if (nBytesToRead < 0)
+ throw BufferSizeExceededException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), *this );
+
+ if (nBytesToRead + m_nCurrent > m_nEnd)
+ nBytesToRead = static_cast < sal_Int32 > (m_nEnd - m_nCurrent);
+
+ aData.realloc ( nBytesToRead );
+ memcpy(aData.getArray(), m_aBuffer.getConstArray() + m_nCurrent, nBytesToRead);
+ m_nCurrent +=nBytesToRead;
+ return nBytesToRead;
+}
+
+sal_Int32 SAL_CALL ZipPackageBuffer::readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ return readBytes(aData, nMaxBytesToRead);
+}
+void SAL_CALL ZipPackageBuffer::skipBytes( sal_Int32 nBytesToSkip )
+ throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ if (nBytesToSkip < 0)
+ throw BufferSizeExceededException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), *this );
+
+ if (nBytesToSkip + m_nCurrent > m_nEnd)
+ nBytesToSkip = static_cast < sal_Int32 > (m_nEnd - m_nCurrent);
+
+ m_nCurrent+=nBytesToSkip;
+}
+sal_Int32 SAL_CALL ZipPackageBuffer::available( )
+ throw(NotConnectedException, IOException, RuntimeException)
+{
+ return static_cast < sal_Int32 > (m_nEnd - m_nCurrent);
+}
+void SAL_CALL ZipPackageBuffer::closeInput( )
+ throw(NotConnectedException, IOException, RuntimeException)
+{
+}
+void SAL_CALL ZipPackageBuffer::writeBytes( const Sequence< sal_Int8 >& aData )
+ throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ sal_Int64 nDataLen = aData.getLength(), nCombined = m_nEnd + nDataLen;
+
+ if ( nCombined > m_nBufferSize)
+ {
+ do
+ m_nBufferSize *=2;
+ while (nCombined > m_nBufferSize);
+ m_aBuffer.realloc(static_cast < sal_Int32 > (m_nBufferSize));
+ m_bMustInitBuffer = sal_False;
+ }
+ else if (m_bMustInitBuffer)
+ {
+ m_aBuffer.realloc ( static_cast < sal_Int32 > ( m_nBufferSize ) );
+ m_bMustInitBuffer = sal_False;
+ }
+ memcpy( m_aBuffer.getArray() + m_nCurrent, aData.getConstArray(), static_cast < sal_Int32 > (nDataLen));
+ m_nCurrent+=nDataLen;
+ if (m_nCurrent>m_nEnd)
+ m_nEnd = m_nCurrent;
+}
+void SAL_CALL ZipPackageBuffer::flush( )
+ throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+}
+void SAL_CALL ZipPackageBuffer::closeOutput( )
+ throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+}
+void SAL_CALL ZipPackageBuffer::seek( sal_Int64 location )
+ throw( IllegalArgumentException, IOException, RuntimeException)
+{
+ if ( location > m_nEnd || location < 0 )
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+ m_nCurrent = location;
+}
+sal_Int64 SAL_CALL ZipPackageBuffer::getPosition( )
+ throw(IOException, RuntimeException)
+{
+ return m_nCurrent;
+}
+sal_Int64 SAL_CALL ZipPackageBuffer::getLength( )
+ throw(IOException, RuntimeException)
+{
+ return m_nEnd;
+}
diff --git a/package/source/zippackage/ZipPackageEntry.cxx b/package/source/zippackage/ZipPackageEntry.cxx
new file mode 100644
index 000000000000..7514e7b6f55a
--- /dev/null
+++ b/package/source/zippackage/ZipPackageEntry.cxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ZipPackageEntry.hxx>
+#include <com/sun/star/packages/zip/ZipConstants.hpp>
+#include <osl/diagnose.h>
+
+#include <ZipPackageFolder.hxx>
+#include <ZipPackageStream.hxx>
+#include <ContentInfo.hxx>
+
+#include <comphelper/storagehelper.hxx>
+
+using namespace rtl;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::packages::zip;
+using namespace com::sun::star::packages::zip::ZipConstants;
+
+ZipPackageEntry::ZipPackageEntry ( bool bNewFolder )
+: mbIsFolder ( bNewFolder )
+, mbAllowRemoveOnInsert( sal_True )
+, pParent ( NULL )
+{
+}
+
+ZipPackageEntry::~ZipPackageEntry()
+{
+ // When the entry is destroyed it must be already disconnected from the parent
+ OSL_ENSURE( !pParent, "The parent must be disconnected already! Memory corruption is possible!\n" );
+}
+
+// XChild
+OUString SAL_CALL ZipPackageEntry::getName( )
+ throw(RuntimeException)
+{
+ return msName;
+}
+void SAL_CALL ZipPackageEntry::setName( const OUString& aName )
+ throw(RuntimeException)
+{
+ if ( pParent && msName.getLength() && pParent->hasByName ( msName ) )
+ pParent->removeByName ( msName );
+
+ // unfortunately no other exception than RuntimeException can be thrown here
+ // usually the package is used through storage implementation, the problem should be detected there
+ if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( aName, sal_True ) )
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected character is used in file name." ) ), Reference< XInterface >() );
+
+ msName = aName;
+
+ if ( pParent )
+ pParent->doInsertByName ( this, sal_False );
+}
+Reference< XInterface > SAL_CALL ZipPackageEntry::getParent( )
+ throw(RuntimeException)
+{
+ // return Reference< XInterface >( xParent, UNO_QUERY );
+ return Reference< XInterface >( static_cast< ::cppu::OWeakObject* >( pParent ), UNO_QUERY );
+}
+
+void ZipPackageEntry::doSetParent ( ZipPackageFolder * pNewParent, sal_Bool bInsert )
+{
+ // xParent = pParent = pNewParent;
+ pParent = pNewParent;
+ if ( bInsert && msName.getLength() && !pNewParent->hasByName ( msName ) )
+ pNewParent->doInsertByName ( this, sal_False );
+}
+
+void SAL_CALL ZipPackageEntry::setParent( const Reference< XInterface >& xNewParent )
+ throw(NoSupportException, RuntimeException)
+{
+ sal_Int64 nTest(0);
+ Reference < XUnoTunnel > xTunnel ( xNewParent, UNO_QUERY );
+ if ( !xNewParent.is() || ( nTest = xTunnel->getSomething ( ZipPackageFolder::static_getImplementationId () ) ) == 0 )
+ throw NoSupportException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ ZipPackageFolder *pNewParent = reinterpret_cast < ZipPackageFolder * > ( nTest );
+
+ if ( pNewParent != pParent )
+ {
+ if ( pParent && msName.getLength() && pParent->hasByName ( msName ) && mbAllowRemoveOnInsert )
+ pParent->removeByName( msName );
+ doSetParent ( pNewParent, sal_True );
+ }
+}
+ //XPropertySet
+Reference< beans::XPropertySetInfo > SAL_CALL ZipPackageEntry::getPropertySetInfo( )
+ throw(RuntimeException)
+{
+ return Reference < beans::XPropertySetInfo > ();
+}
+void SAL_CALL ZipPackageEntry::addPropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< beans::XPropertyChangeListener >& /*xListener*/ )
+ throw(beans::UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+void SAL_CALL ZipPackageEntry::removePropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< beans::XPropertyChangeListener >& /*aListener*/ )
+ throw(beans::UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+void SAL_CALL ZipPackageEntry::addVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< beans::XVetoableChangeListener >& /*aListener*/ )
+ throw(beans::UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+void SAL_CALL ZipPackageEntry::removeVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< beans::XVetoableChangeListener >& /*aListener*/ )
+ throw(beans::UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
diff --git a/package/source/zippackage/ZipPackageEntry.hxx b/package/source/zippackage/ZipPackageEntry.hxx
new file mode 100644
index 000000000000..767d84511a12
--- /dev/null
+++ b/package/source/zippackage/ZipPackageEntry.hxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _ZIP_PACKAGE_ENTRY_HXX
+#define _ZIP_PACKAGE_ENTRY_HXX
+
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#ifndef _COM_SUN_STAR_LANG_XPSERVICEINFO_HPP_
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#endif
+#include <ZipEntry.hxx>
+#include <cppuhelper/implbase5.hxx>
+
+class ZipPackageFolder;
+
+class ZipPackageEntry : public cppu::WeakImplHelper5
+<
+ com::sun::star::container::XNamed,
+ com::sun::star::container::XChild,
+ com::sun::star::lang::XUnoTunnel,
+ com::sun::star::beans::XPropertySet,
+ com::sun::star::lang::XServiceInfo
+>
+{
+protected:
+ ::rtl::OUString msName;
+ bool mbIsFolder:1;
+ bool mbAllowRemoveOnInsert:1;
+ // com::sun::star::uno::Reference < com::sun::star::container::XNameContainer > xParent;
+ ::rtl::OUString sMediaType;
+ ZipPackageFolder * pParent;
+public:
+ ZipEntry aEntry;
+ ZipPackageEntry ( bool bNewFolder = sal_False );
+ virtual ~ZipPackageEntry( void );
+
+ ::rtl::OUString & GetMediaType () { return sMediaType; }
+ void SetMediaType ( const ::rtl::OUString & sNewType) { sMediaType = sNewType; }
+ void doSetParent ( ZipPackageFolder * pNewParent, sal_Bool bInsert );
+ bool IsFolder ( ) { return mbIsFolder; }
+ ZipPackageFolder* GetParent ( ) { return pParent; }
+ void SetFolder ( bool bSetFolder ) { mbIsFolder = bSetFolder; }
+
+ void clearParent ( void )
+ {
+ // xParent.clear();
+ pParent = NULL;
+ }
+ // XNamed
+ virtual ::rtl::OUString SAL_CALL getName( )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setName( const ::rtl::OUString& aName )
+ throw(::com::sun::star::uno::RuntimeException);
+ // XChild
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getParent( )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setParent( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& Parent )
+ throw(::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
+ // XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
+ throw(::com::sun::star::uno::RuntimeException) = 0;
+ // XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) = 0;
+ virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) = 0;
+ virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+};
+#endif
diff --git a/package/source/zippackage/ZipPackageFolder.cxx b/package/source/zippackage/ZipPackageFolder.cxx
new file mode 100644
index 000000000000..f0c4a11d22f4
--- /dev/null
+++ b/package/source/zippackage/ZipPackageFolder.cxx
@@ -0,0 +1,811 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ZipPackageFolder.hxx>
+#include <ZipFile.hxx>
+#include <ZipOutputStream.hxx>
+#include <ZipPackageStream.hxx>
+#include <PackageConstants.hxx>
+#include <ZipPackageFolderEnumeration.hxx>
+#include <com/sun/star/packages/zip/ZipConstants.hpp>
+#include <com/sun/star/embed/StorageFormats.hpp>
+#include <vos/diagnose.hxx>
+#include <osl/time.h>
+#include <rtl/digest.h>
+#include <ContentInfo.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <EncryptedDataHeader.hxx>
+#include <rtl/random.h>
+#include <memory>
+
+using namespace com::sun::star::packages::zip::ZipConstants;
+using namespace com::sun::star::packages::zip;
+using namespace com::sun::star::container;
+using namespace com::sun::star::packages;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::io;
+using namespace cppu;
+using namespace rtl;
+using namespace std;
+using namespace ::com::sun::star;
+using vos::ORef;
+
+Sequence < sal_Int8 > ZipPackageFolder::aImplementationId = Sequence < sal_Int8 > ();
+
+ZipPackageFolder::ZipPackageFolder ( const Reference< XMultiServiceFactory >& xFactory,
+ sal_Int32 nFormat,
+ sal_Bool bAllowRemoveOnInsert )
+: m_xFactory( xFactory )
+, m_nFormat( nFormat )
+{
+ OSL_ENSURE( m_xFactory.is(), "No factory is provided to the package folder!" );
+
+ this->mbAllowRemoveOnInsert = bAllowRemoveOnInsert;
+
+ SetFolder ( sal_True );
+ aEntry.nVersion = -1;
+ aEntry.nFlag = 0;
+ aEntry.nMethod = STORED;
+ aEntry.nTime = -1;
+ aEntry.nCrc = 0;
+ aEntry.nCompressedSize = 0;
+ aEntry.nSize = 0;
+ aEntry.nOffset = -1;
+ if ( !aImplementationId.getLength() )
+ {
+ aImplementationId = getImplementationId();
+ }
+}
+
+
+ZipPackageFolder::~ZipPackageFolder()
+{
+}
+
+sal_Bool ZipPackageFolder::LookForUnexpectedODF12Streams( const ::rtl::OUString& aPath )
+{
+ sal_Bool bHasUnexpected = sal_False;
+
+ for ( ContentHash::const_iterator aCI = maContents.begin(), aEnd = maContents.end();
+ !bHasUnexpected && aCI != aEnd;
+ aCI++)
+ {
+ const OUString &rShortName = (*aCI).first;
+ const ContentInfo &rInfo = *(*aCI).second;
+
+ if ( rInfo.bFolder )
+ {
+ if ( aPath.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF/" ) ) ) )
+ {
+ // META-INF is not allowed to contain subfolders
+ bHasUnexpected = sal_True;
+ }
+ else
+ {
+ OUString sOwnPath = aPath + rShortName + OUString( RTL_CONSTASCII_USTRINGPARAM ( "/" ) );
+ bHasUnexpected = rInfo.pFolder->LookForUnexpectedODF12Streams( sOwnPath );
+ }
+ }
+ else
+ {
+ if ( aPath.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF/" ) ) ) )
+ {
+ if ( !rShortName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "manifest.xml" ) ) )
+ && rShortName.indexOf( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "signatures" ) ) ) == -1 )
+ {
+ // a stream from META-INF with unexpected name
+ bHasUnexpected = sal_True;
+ }
+
+ // streams from META-INF with expected names are allowed not to be registered in manifest.xml
+ }
+ else if ( !rInfo.pStream->IsFromManifest() )
+ {
+ // the stream is not in META-INF and ist notregistered in manifest.xml,
+ // check whether it is an internal part of the package format
+ if ( aPath.getLength()
+ || !rShortName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "mimetype" ) ) ) )
+ {
+ // if it is not "mimetype" from the root it is not a part of the package
+ bHasUnexpected = sal_True;
+ }
+ }
+ }
+ }
+
+ return bHasUnexpected;
+}
+
+void ZipPackageFolder::setChildStreamsTypeByExtension( const beans::StringPair& aPair )
+{
+ ::rtl::OUString aExt;
+ if ( aPair.First.toChar() == (sal_Unicode)'.' )
+ aExt = aPair.First;
+ else
+ aExt = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) ) + aPair.First;
+
+ for ( ContentHash::const_iterator aCI = maContents.begin(), aEnd = maContents.end();
+ aCI != aEnd;
+ aCI++)
+ {
+ const OUString &rShortName = (*aCI).first;
+ const ContentInfo &rInfo = *(*aCI).second;
+
+ if ( rInfo.bFolder )
+ rInfo.pFolder->setChildStreamsTypeByExtension( aPair );
+ else
+ {
+ sal_Int32 nPathLength = rShortName.getLength();
+ sal_Int32 nExtLength = aExt.getLength();
+ if ( nPathLength >= nExtLength && rShortName.match( aExt, nPathLength - nExtLength ) )
+ rInfo.pStream->SetMediaType( aPair.Second );
+ }
+ }
+}
+
+void ZipPackageFolder::copyZipEntry( ZipEntry &rDest, const ZipEntry &rSource)
+{
+ rDest.nVersion = rSource.nVersion;
+ rDest.nFlag = rSource.nFlag;
+ rDest.nMethod = rSource.nMethod;
+ rDest.nTime = rSource.nTime;
+ rDest.nCrc = rSource.nCrc;
+ rDest.nCompressedSize = rSource.nCompressedSize;
+ rDest.nSize = rSource.nSize;
+ rDest.nOffset = rSource.nOffset;
+ rDest.sPath = rSource.sPath;
+ rDest.nPathLen = rSource.nPathLen;
+ rDest.nExtraLen = rSource.nExtraLen;
+}
+
+ // XNameContainer
+void SAL_CALL ZipPackageFolder::insertByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ if (hasByName(aName))
+ throw ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ else
+ {
+ Reference < XUnoTunnel > xRef;
+ aElement >>= xRef;
+ if ( ( aElement >>= xRef ) )
+ {
+ sal_Int64 nTest;
+ ZipPackageEntry *pEntry;
+ if ( ( nTest = xRef->getSomething ( ZipPackageFolder::static_getImplementationId() ) ) != 0 )
+ {
+ ZipPackageFolder *pFolder = reinterpret_cast < ZipPackageFolder * > ( nTest );
+ pEntry = static_cast < ZipPackageEntry * > ( pFolder );
+ }
+ else if ( ( nTest = xRef->getSomething ( ZipPackageStream::static_getImplementationId() ) ) != 0 )
+ {
+ ZipPackageStream *pStream = reinterpret_cast < ZipPackageStream * > ( nTest );
+ pEntry = static_cast < ZipPackageEntry * > ( pStream );
+ }
+ else
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
+
+ if (pEntry->getName() != aName )
+ pEntry->setName (aName);
+ doInsertByName ( pEntry, sal_True );
+ }
+ else
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
+ }
+}
+void SAL_CALL ZipPackageFolder::removeByName( const OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ContentHash::iterator aIter = maContents.find ( Name );
+ if ( aIter == maContents.end() )
+ throw NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ maContents.erase( aIter );
+}
+ // XEnumerationAccess
+Reference< XEnumeration > SAL_CALL ZipPackageFolder::createEnumeration( )
+ throw(RuntimeException)
+{
+ return Reference < XEnumeration> (new ZipPackageFolderEnumeration(maContents));
+}
+ // XElementAccess
+Type SAL_CALL ZipPackageFolder::getElementType( )
+ throw(RuntimeException)
+{
+ return ::getCppuType ((const Reference< XUnoTunnel > *) 0);
+}
+sal_Bool SAL_CALL ZipPackageFolder::hasElements( )
+ throw(RuntimeException)
+{
+ return maContents.size() > 0;
+}
+ // XNameAccess
+ContentInfo& ZipPackageFolder::doGetByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ContentHash::iterator aIter = maContents.find ( aName );
+ if ( aIter == maContents.end())
+ throw NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ return *(*aIter).second;
+}
+Any SAL_CALL ZipPackageFolder::getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ return makeAny ( doGetByName ( aName ).xTunnel );
+}
+Sequence< OUString > SAL_CALL ZipPackageFolder::getElementNames( )
+ throw(RuntimeException)
+{
+ sal_uInt32 i=0, nSize = maContents.size();
+ Sequence < OUString > aSequence ( nSize );
+ OUString *pNames = aSequence.getArray();
+ for ( ContentHash::const_iterator aIterator = maContents.begin(), aEnd = maContents.end();
+ aIterator != aEnd;
+ ++i, ++aIterator)
+ pNames[i] = (*aIterator).first;
+ return aSequence;
+}
+sal_Bool SAL_CALL ZipPackageFolder::hasByName( const OUString& aName )
+ throw(RuntimeException)
+{
+ return maContents.find ( aName ) != maContents.end ();
+}
+ // XNameReplace
+void SAL_CALL ZipPackageFolder::replaceByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ if ( hasByName( aName ) )
+ removeByName( aName );
+ else
+ throw NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ insertByName(aName, aElement);
+}
+
+static void ImplSetStoredData( ZipEntry & rEntry, Reference < XInputStream> & rStream )
+{
+ // It's very annoying that we have to do this, but lots of zip packages
+ // don't allow data descriptors for STORED streams, meaning we have to
+ // know the size and CRC32 of uncompressed streams before we actually
+ // write them !
+ CRC32 aCRC32;
+ rEntry.nMethod = STORED;
+ rEntry.nCompressedSize = rEntry.nSize = aCRC32.updateStream ( rStream );
+ rEntry.nCrc = aCRC32.getValue();
+}
+
+void ZipPackageFolder::saveContents(OUString &rPath, std::vector < Sequence < PropertyValue > > &rManList, ZipOutputStream & rZipOut, Sequence < sal_Int8 > &rEncryptionKey, rtlRandomPool &rRandomPool)
+ throw(RuntimeException)
+{
+ sal_Bool bWritingFailed = sal_False;
+ ZipPackageFolder *pFolder = NULL;
+ ZipPackageStream *pStream = NULL;
+ const OUString sMediaTypeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) );
+ const OUString sVersionProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Version" ) );
+ const OUString sFullPathProperty ( RTL_CONSTASCII_USTRINGPARAM ( "FullPath" ) );
+ const OUString sInitialisationVectorProperty ( RTL_CONSTASCII_USTRINGPARAM ( "InitialisationVector" ) );
+ const OUString sSaltProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Salt" ) );
+ const OUString sIterationCountProperty ( RTL_CONSTASCII_USTRINGPARAM ( "IterationCount" ) );
+ const OUString sSizeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Size" ) );
+ const OUString sDigestProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Digest" ) );
+
+ sal_Bool bHaveEncryptionKey = rEncryptionKey.getLength() ? sal_True : sal_False;
+
+ if ( maContents.begin() == maContents.end() && rPath.getLength() && m_nFormat != embed::StorageFormats::OFOPXML )
+ {
+ // it is an empty subfolder, use workaround to store it
+ ZipEntry* pTempEntry = new ZipEntry();
+ ZipPackageFolder::copyZipEntry ( *pTempEntry, aEntry );
+ pTempEntry->nPathLen = (sal_Int16)( ::rtl::OUStringToOString( rPath, RTL_TEXTENCODING_UTF8 ).getLength() );
+ pTempEntry->nExtraLen = -1;
+ pTempEntry->sPath = rPath;
+
+ try
+ {
+ vos::ORef < EncryptionData > aEmptyEncr;
+ rZipOut.putNextEntry ( *pTempEntry, aEmptyEncr, sal_False );
+ rZipOut.rawCloseEntry();
+ }
+ catch ( ZipException& )
+ {
+ VOS_ENSURE( 0, "Error writing ZipOutputStream" );
+ bWritingFailed = sal_True;
+ }
+ catch ( IOException& )
+ {
+ VOS_ENSURE( 0, "Error writing ZipOutputStream" );
+ bWritingFailed = sal_True;
+ }
+ }
+
+ for ( ContentHash::const_iterator aCI = maContents.begin(), aEnd = maContents.end();
+ aCI != aEnd;
+ aCI++)
+ {
+ const OUString &rShortName = (*aCI).first;
+ const ContentInfo &rInfo = *(*aCI).second;
+
+ Sequence < PropertyValue > aPropSet (PKG_SIZE_NOENCR_MNFST);
+ PropertyValue *pValue = aPropSet.getArray();
+
+ if ( rInfo.bFolder )
+ pFolder = rInfo.pFolder;
+ else
+ pStream = rInfo.pStream;
+
+ if ( rInfo.bFolder )
+ {
+ OUString sTempName = rPath + rShortName + OUString( RTL_CONSTASCII_USTRINGPARAM ( "/" ) );
+
+ pValue[PKG_MNFST_MEDIATYPE].Name = sMediaTypeProperty;
+ pValue[PKG_MNFST_MEDIATYPE].Value <<= pFolder->GetMediaType();
+ pValue[PKG_MNFST_VERSION].Name = sVersionProperty;
+ pValue[PKG_MNFST_VERSION].Value <<= pFolder->GetVersion();
+ pValue[PKG_MNFST_FULLPATH].Name = sFullPathProperty;
+ pValue[PKG_MNFST_FULLPATH].Value <<= sTempName;
+
+ pFolder->saveContents( sTempName, rManList, rZipOut, rEncryptionKey, rRandomPool);
+ }
+ else
+ {
+ // if pTempEntry is necessary, it will be released and passed to the ZipOutputStream
+ // and be deleted in the ZipOutputStream destructor
+ auto_ptr < ZipEntry > pAutoTempEntry ( new ZipEntry );
+ ZipEntry* pTempEntry = pAutoTempEntry.get();
+
+ // In case the entry we are reading is also the entry we are writing, we will
+ // store the ZipEntry data in pTempEntry
+
+ ZipPackageFolder::copyZipEntry ( *pTempEntry, pStream->aEntry );
+ pTempEntry->sPath = rPath + rShortName;
+ pTempEntry->nPathLen = (sal_Int16)( ::rtl::OUStringToOString( pTempEntry->sPath, RTL_TEXTENCODING_UTF8 ).getLength() );
+
+ sal_Bool bToBeEncrypted = pStream->IsToBeEncrypted() && (bHaveEncryptionKey || pStream->HasOwnKey());
+ sal_Bool bToBeCompressed = bToBeEncrypted ? sal_True : pStream->IsToBeCompressed();
+
+ pValue[PKG_MNFST_MEDIATYPE].Name = sMediaTypeProperty;
+ pValue[PKG_MNFST_MEDIATYPE].Value <<= pStream->GetMediaType( );
+ pValue[PKG_MNFST_VERSION].Name = sVersionProperty;
+ pValue[PKG_MNFST_VERSION].Value <<= ::rtl::OUString(); // no version is stored for streams currently
+ pValue[PKG_MNFST_FULLPATH].Name = sFullPathProperty;
+ pValue[PKG_MNFST_FULLPATH].Value <<= pTempEntry->sPath;
+
+
+ OSL_ENSURE( pStream->GetStreamMode() != PACKAGE_STREAM_NOTSET, "Unacceptable ZipPackageStream mode!" );
+
+ sal_Bool bRawStream = sal_False;
+ if ( pStream->GetStreamMode() == PACKAGE_STREAM_DETECT )
+ bRawStream = pStream->ParsePackageRawStream();
+ else if ( pStream->GetStreamMode() == PACKAGE_STREAM_RAW )
+ bRawStream = sal_True;
+
+ sal_Bool bTransportOwnEncrStreamAsRaw = sal_False;
+ // During the storing the original size of the stream can be changed
+ // TODO/LATER: get rid of this hack
+ sal_Int32 nOwnStreamOrigSize = bRawStream ? pStream->GetMagicalHackSize() : pStream->getSize();
+
+ sal_Bool bUseNonSeekableAccess = sal_False;
+ Reference < XInputStream > xStream;
+ if ( !pStream->IsPackageMember() && !bRawStream && !bToBeEncrypted && bToBeCompressed )
+ {
+ // the stream is not a package member, not a raw stream,
+ // it should not be encrypted and it should be compressed,
+ // in this case nonseekable access can be used
+
+ xStream = pStream->GetOwnStreamNoWrap();
+ Reference < XSeekable > xSeek ( xStream, UNO_QUERY );
+
+ bUseNonSeekableAccess = ( xStream.is() && !xSeek.is() );
+ }
+
+ if ( !bUseNonSeekableAccess )
+ {
+ xStream = pStream->getRawData();
+
+ if ( !xStream.is() )
+ {
+ VOS_ENSURE( 0, "ZipPackageStream didn't have a stream associated with it, skipping!" );
+ bWritingFailed = sal_True;
+ continue;
+ }
+
+ Reference < XSeekable > xSeek ( xStream, UNO_QUERY );
+ try
+ {
+ if ( xSeek.is() )
+ {
+ // If the stream is a raw one, then we should be positioned
+ // at the beginning of the actual data
+ if ( !bToBeCompressed || bRawStream )
+ {
+ // The raw stream can neither be encrypted nor connected
+ OSL_ENSURE( !bRawStream || !bToBeCompressed && !bToBeEncrypted, "The stream is already encrypted!\n" );
+ xSeek->seek ( bRawStream ? pStream->GetMagicalHackPos() : 0 );
+ ImplSetStoredData ( *pTempEntry, xStream );
+
+ // TODO/LATER: Get rid of hacks related to switching of Flag Method and Size properties!
+ }
+ else if ( bToBeEncrypted )
+ {
+ // this is the correct original size
+ pTempEntry->nSize = static_cast < sal_Int32 > ( xSeek->getLength() );
+ nOwnStreamOrigSize = pTempEntry->nSize;
+ }
+
+ xSeek->seek ( 0 );
+ }
+ else
+ {
+ // Okay, we don't have an xSeekable stream. This is possibly bad.
+ // check if it's one of our own streams, if it is then we know that
+ // each time we ask for it we'll get a new stream that will be
+ // at position zero...otherwise, assert and skip this stream...
+ if ( pStream->IsPackageMember() )
+ {
+ // if the password has been changed than the stream should not be package member any more
+ if ( pStream->IsEncrypted() && pStream->IsToBeEncrypted() )
+ {
+ // Should be handled close to the raw stream handling
+ bTransportOwnEncrStreamAsRaw = sal_True;
+ pTempEntry->nMethod = STORED;
+
+ // TODO/LATER: get rid of this situation
+ // this size should be different from the one that will be stored in manifest.xml
+ // it is used in storing algorithms and after storing the correct size will be set
+ pTempEntry->nSize = pTempEntry->nCompressedSize;
+ }
+ }
+ else
+ {
+ VOS_ENSURE( 0, "The package component requires that every stream either be FROM a package or it must support XSeekable!" );
+ continue;
+ }
+ }
+ }
+ catch ( Exception& )
+ {
+ VOS_ENSURE( 0, "The stream provided to the package component has problems!" );
+ bWritingFailed = sal_True;
+ continue;
+ }
+
+ if ( bToBeEncrypted || bRawStream || bTransportOwnEncrStreamAsRaw )
+ {
+ if ( bToBeEncrypted && !bTransportOwnEncrStreamAsRaw )
+ {
+ Sequence < sal_uInt8 > aSalt ( 16 ), aVector ( 8 );
+ rtl_random_getBytes ( rRandomPool, aSalt.getArray(), 16 );
+ rtl_random_getBytes ( rRandomPool, aVector.getArray(), 8 );
+ sal_Int32 nIterationCount = 1024;
+
+ if ( !pStream->HasOwnKey() )
+ pStream->setKey ( rEncryptionKey );
+
+ pStream->setInitialisationVector ( aVector );
+ pStream->setSalt ( aSalt );
+ pStream->setIterationCount ( nIterationCount );
+ }
+
+ // last property is digest, which is inserted later if we didn't have
+ // a magic header
+ aPropSet.realloc(PKG_SIZE_ENCR_MNFST);
+
+ pValue = aPropSet.getArray();
+ pValue[PKG_MNFST_INIVECTOR].Name = sInitialisationVectorProperty;
+ pValue[PKG_MNFST_INIVECTOR].Value <<= pStream->getInitialisationVector();
+ pValue[PKG_MNFST_SALT].Name = sSaltProperty;
+ pValue[PKG_MNFST_SALT].Value <<= pStream->getSalt();
+ pValue[PKG_MNFST_ITERATION].Name = sIterationCountProperty;
+ pValue[PKG_MNFST_ITERATION].Value <<= pStream->getIterationCount ();
+
+ // Need to store the uncompressed size in the manifest
+ OSL_ENSURE( nOwnStreamOrigSize >= 0, "The stream size was not correctly initialized!\n" );
+ pValue[PKG_MNFST_UCOMPSIZE].Name = sSizeProperty;
+ pValue[PKG_MNFST_UCOMPSIZE].Value <<= nOwnStreamOrigSize;
+
+ if ( bRawStream || bTransportOwnEncrStreamAsRaw )
+ {
+ pValue[PKG_MNFST_DIGEST].Name = sDigestProperty;
+ pValue[PKG_MNFST_DIGEST].Value <<= pStream->getDigest();
+ }
+ }
+ }
+
+ // If the entry is already stored in the zip file in the format we
+ // want for this write...copy it raw
+ if ( !bUseNonSeekableAccess
+ && ( bRawStream || bTransportOwnEncrStreamAsRaw
+ || ( pStream->IsPackageMember() && !bToBeEncrypted
+ && ( ( pStream->aEntry.nMethod == DEFLATED && bToBeCompressed )
+ || ( pStream->aEntry.nMethod == STORED && !bToBeCompressed ) ) ) ) )
+ {
+ // If it's a PackageMember, then it's an unbuffered stream and we need
+ // to get a new version of it as we can't seek backwards.
+ if ( pStream->IsPackageMember() )
+ {
+ xStream = pStream->getRawData();
+ if ( !xStream.is() )
+ {
+ // Make sure that we actually _got_ a new one !
+ VOS_ENSURE( 0, "ZipPackageStream didn't have a stream associated with it, skipping!" );
+ continue;
+ }
+ }
+
+ try
+ {
+ if ( bRawStream )
+ xStream->skipBytes( pStream->GetMagicalHackPos() );
+
+ rZipOut.putNextEntry ( *pTempEntry, pStream->getEncryptionData(), sal_False );
+ // the entry is provided to the ZipOutputStream that will delete it
+ pAutoTempEntry.release();
+
+ Sequence < sal_Int8 > aSeq ( n_ConstBufferSize );
+ sal_Int32 nLength;
+
+ do
+ {
+ nLength = xStream->readBytes( aSeq, n_ConstBufferSize );
+ rZipOut.rawWrite(aSeq, 0, nLength);
+ }
+ while ( nLength == n_ConstBufferSize );
+
+ rZipOut.rawCloseEntry();
+ }
+ catch ( ZipException& )
+ {
+ VOS_ENSURE( 0, "Error writing ZipOutputStream" );
+ bWritingFailed = sal_True;
+ }
+ catch ( IOException& )
+ {
+ VOS_ENSURE( 0, "Error writing ZipOutputStream" );
+ bWritingFailed = sal_True;
+ }
+ }
+ else
+ {
+ // This stream is defenitly not a raw stream
+
+ // If nonseekable access is used the stream should be at the beginning and
+ // is useless after the storing. Thus if the storing fails the package should
+ // be thrown away ( as actually it is done currently )!
+ // To allow to reuse the package after the error, the optimization must be removed!
+
+ // If it's a PackageMember, then our previous reference held a 'raw' stream
+ // so we need to re-get it, unencrypted, uncompressed and positioned at the
+ // beginning of the stream
+ if ( pStream->IsPackageMember() )
+ {
+ xStream = pStream->getInputStream();
+ if ( !xStream.is() )
+ {
+ // Make sure that we actually _got_ a new one !
+ VOS_ENSURE( 0, "ZipPackageStream didn't have a stream associated with it, skipping!" );
+ continue;
+ }
+ }
+
+ if ( bToBeCompressed )
+ {
+ pTempEntry->nMethod = DEFLATED;
+ pTempEntry->nCrc = pTempEntry->nCompressedSize = pTempEntry->nSize = -1;
+ }
+
+ try
+ {
+ rZipOut.putNextEntry ( *pTempEntry, pStream->getEncryptionData(), bToBeEncrypted);
+ // the entry is provided to the ZipOutputStream that will delete it
+ pAutoTempEntry.release();
+
+ sal_Int32 nLength;
+ Sequence < sal_Int8 > aSeq (n_ConstBufferSize);
+ do
+ {
+ nLength = xStream->readBytes(aSeq, n_ConstBufferSize);
+ rZipOut.write(aSeq, 0, nLength);
+ }
+ while ( nLength == n_ConstBufferSize );
+
+ rZipOut.closeEntry();
+ }
+ catch ( ZipException& )
+ {
+ VOS_ENSURE( 0, "Error writing ZipOutputStream" );
+ bWritingFailed = sal_True;
+ }
+ catch ( IOException& )
+ {
+ VOS_ENSURE( 0, "Error writing ZipOutputStream" );
+ bWritingFailed = sal_True;
+ }
+
+ if ( bToBeEncrypted )
+ {
+ pValue[PKG_MNFST_DIGEST].Name = sDigestProperty;
+ pValue[PKG_MNFST_DIGEST].Value <<= pStream->getDigest();
+ pStream->SetIsEncrypted ( sal_True );
+ }
+ }
+
+ if( !bWritingFailed )
+ {
+ if ( !pStream->IsPackageMember() )
+ {
+ pStream->CloseOwnStreamIfAny();
+ pStream->SetPackageMember ( sal_True );
+ }
+
+ if ( bRawStream )
+ {
+ // the raw stream was integrated and now behaves
+ // as usual encrypted stream
+ pStream->SetToBeEncrypted( sal_True );
+ }
+
+ // Remove hacky bit from entry flags
+ if ( pTempEntry->nFlag & ( 1 << 4 ) )
+ {
+ pTempEntry->nFlag &= ~( 1 << 4 );
+ pTempEntry->nMethod = STORED;
+ }
+
+ // Then copy it back afterwards...
+ ZipPackageFolder::copyZipEntry ( pStream->aEntry, *pTempEntry );
+
+ // TODO/LATER: get rid of this hack ( the encrypted stream size property is changed during saving )
+ if ( pStream->IsEncrypted() )
+ pStream->setSize( nOwnStreamOrigSize );
+
+ pStream->aEntry.nOffset *= -1;
+ }
+ }
+
+ // folder can have a mediatype only in package format
+ if ( m_nFormat == embed::StorageFormats::PACKAGE || ( m_nFormat == embed::StorageFormats::OFOPXML && !rInfo.bFolder ) )
+ rManList.push_back( aPropSet );
+ }
+
+ if( bWritingFailed )
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+void ZipPackageFolder::releaseUpwardRef( void )
+{
+ // Now it is possible that a package folder is disconnected from the package before removing of the folder.
+ // Such a scenario is used in storage implementation. When a new version of a folder is provided the old
+ // one is retrieved, removed from the package but preserved for the error handling.
+ // In this scenario the referencing to the parent is not really useful, since it requires disposing.
+
+ // Actually there is no need in having a reference to the parent, it even make things more complicated and
+ // requires disposing mechanics. Using of a simple pointer seems to be easier solution and also a safe enough.
+
+ clearParent();
+
+#if 0
+ for ( ContentHash::const_iterator aCI = maContents.begin();
+ aCI!=maContents.end();
+ aCI++)
+ {
+ ContentInfo &rInfo = * (*aCI).second;
+ if ( rInfo.bFolder )// && ! rInfo.pFolder->HasReleased () )
+ rInfo.pFolder->releaseUpwardRef();
+ else //if ( !rInfo.bFolder && !rInfo.pStream->HasReleased() )
+ rInfo.pStream->clearParent();
+ }
+ clearParent();
+
+ VOS_ENSURE ( m_refCount == 1, "Ref-count is not 1!" );
+#endif
+}
+
+sal_Int64 SAL_CALL ZipPackageFolder::getSomething( const Sequence< sal_Int8 >& aIdentifier )
+ throw(RuntimeException)
+{
+ sal_Int64 nMe = 0;
+ if ( aIdentifier.getLength() == 16 &&
+ 0 == rtl_compareMemory(static_getImplementationId().getConstArray(), aIdentifier.getConstArray(), 16 ) )
+ nMe = reinterpret_cast < sal_Int64 > ( this );
+ return nMe;
+}
+void SAL_CALL ZipPackageFolder::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
+ throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("MediaType")))
+ {
+ // TODO/LATER: activate when zip ucp is ready
+ // if ( m_nFormat != embed::StorageFormats::PACKAGE )
+ // throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ aValue >>= sMediaType;
+ }
+ else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Version")))
+ aValue >>= m_sVersion;
+ else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Size") ) )
+ aValue >>= aEntry.nSize;
+ else
+ throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+Any SAL_CALL ZipPackageFolder::getPropertyValue( const OUString& PropertyName )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) )
+ {
+ // TODO/LATER: activate when zip ucp is ready
+ // if ( m_nFormat != embed::StorageFormats::PACKAGE )
+ // throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return makeAny ( sMediaType );
+ }
+ else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Version" ) ) )
+ return makeAny( m_sVersion );
+ else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Size" ) ) )
+ return makeAny ( aEntry.nSize );
+ else
+ throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+void ZipPackageFolder::doInsertByName ( ZipPackageEntry *pEntry, sal_Bool bSetParent )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ try
+ {
+ if ( pEntry->IsFolder() )
+ maContents[pEntry->getName()] = new ContentInfo ( static_cast < ZipPackageFolder *> ( pEntry ) );
+ else
+ maContents[pEntry->getName()] = new ContentInfo ( static_cast < ZipPackageStream *> ( pEntry ) );
+ }
+ catch(const uno::Exception& rEx)
+ {
+ (void)rEx;
+ throw;
+ }
+ if ( bSetParent )
+ pEntry->setParent ( *this );
+}
+OUString ZipPackageFolder::getImplementationName()
+ throw (RuntimeException)
+{
+ return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "ZipPackageFolder" ) );
+}
+
+Sequence< OUString > ZipPackageFolder::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ Sequence< OUString > aNames(1);
+ aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.PackageFolder" ) );
+ return aNames;
+}
+sal_Bool SAL_CALL ZipPackageFolder::supportsService( OUString const & rServiceName )
+ throw (RuntimeException)
+{
+ return rServiceName == getSupportedServiceNames()[0];
+}
diff --git a/package/source/zippackage/ZipPackageFolderEnumeration.cxx b/package/source/zippackage/ZipPackageFolderEnumeration.cxx
new file mode 100644
index 000000000000..562e42d9e266
--- /dev/null
+++ b/package/source/zippackage/ZipPackageFolderEnumeration.cxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ZipPackageFolderEnumeration.hxx>
+#include <ContentInfo.hxx>
+
+using namespace com::sun::star;
+using rtl::OUString;
+
+ZipPackageFolderEnumeration::ZipPackageFolderEnumeration ( ContentHash &rInput)
+: rContents (rInput)
+, aIterator (rContents.begin())
+{
+}
+
+ZipPackageFolderEnumeration::~ZipPackageFolderEnumeration( void )
+{
+}
+
+sal_Bool SAL_CALL ZipPackageFolderEnumeration::hasMoreElements( )
+ throw(uno::RuntimeException)
+{
+ return (aIterator != rContents.end() );
+}
+uno::Any SAL_CALL ZipPackageFolderEnumeration::nextElement( )
+ throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ uno::Any aAny;
+ if (aIterator == rContents.end() )
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ aAny <<= (*aIterator).second->xTunnel;
+ aIterator++;
+ return aAny;
+}
+
+OUString ZipPackageFolderEnumeration::getImplementationName()
+ throw (uno::RuntimeException)
+{
+ return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "ZipPackageFolderEnumeration" ) );
+}
+
+uno::Sequence< OUString > ZipPackageFolderEnumeration::getSupportedServiceNames()
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< OUString > aNames(1);
+ aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.PackageFolderEnumeration" ) );
+ return aNames;
+}
+sal_Bool SAL_CALL ZipPackageFolderEnumeration::supportsService( OUString const & rServiceName )
+ throw (uno::RuntimeException)
+{
+ return rServiceName == getSupportedServiceNames()[0];
+}
diff --git a/package/source/zippackage/ZipPackageFolderEnumeration.hxx b/package/source/zippackage/ZipPackageFolderEnumeration.hxx
new file mode 100644
index 000000000000..bea038d684f3
--- /dev/null
+++ b/package/source/zippackage/ZipPackageFolderEnumeration.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _ZIP_PACKAGE_FOLDER_ENUMERATION_HXX
+#define _ZIP_PACKAGE_FOLDER_ENUMERATION_HXX
+
+#include <cppuhelper/implbase2.hxx> // helper for implementations
+#include <com/sun/star/container/XEnumeration.hpp>
+#ifndef _COM_SUN_STAR_LANG_XPSERVICEINFO_HPP_
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#endif
+#ifndef _HASH_MAPS_HXX
+#include <HashMaps.hxx>
+#endif
+
+class ZipPackageFolderEnumeration : public cppu::WeakImplHelper2
+<
+ com::sun::star::container::XEnumeration,
+ com::sun::star::lang::XServiceInfo
+>
+{
+protected:
+ ContentHash& rContents;
+ ContentHash::const_iterator aIterator;
+public:
+ //ZipPackageFolderEnumeration (std::hash_map < rtl::OUString, com::sun::star::uno::Reference < com::sun::star::container::XNamed >, hashFunc, eqFunc > &rInput);
+ ZipPackageFolderEnumeration (ContentHash &rInput);
+ virtual ~ZipPackageFolderEnumeration( void );
+
+ // XEnumeration
+ virtual sal_Bool SAL_CALL hasMoreElements( )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL nextElement( )
+ throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+};
+#endif
diff --git a/package/source/zippackage/ZipPackageSink.cxx b/package/source/zippackage/ZipPackageSink.cxx
new file mode 100644
index 000000000000..9a42138a5cb1
--- /dev/null
+++ b/package/source/zippackage/ZipPackageSink.cxx
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <ZipPackageSink.hxx>
+
+ZipPackageSink::ZipPackageSink(void)
+: xStream ( com::sun::star::uno::Reference < com::sun::star::io::XInputStream > (NULL))
+{
+}
+ZipPackageSink::~ZipPackageSink(void)
+{
+}
+void SAL_CALL ZipPackageSink::setInputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ xStream = aStream;
+}
+::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL ZipPackageSink::getInputStream( )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return xStream;
+}
diff --git a/package/source/zippackage/ZipPackageSink.hxx b/package/source/zippackage/ZipPackageSink.hxx
new file mode 100644
index 000000000000..95dac72a836b
--- /dev/null
+++ b/package/source/zippackage/ZipPackageSink.hxx
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _ZIP_PACKAGE_SINK_HXX
+#define _ZIP_PACKAGE_SINK_HXX
+
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+class ZipPackageSink : public ::cppu::WeakImplHelper1
+<
+ com::sun::star::io::XActiveDataSink
+>
+{
+protected:
+ com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xStream;
+public:
+ ZipPackageSink();
+ virtual ~ZipPackageSink();
+ virtual void SAL_CALL setInputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream( )
+ throw(::com::sun::star::uno::RuntimeException);
+};
+#endif
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
new file mode 100644
index 000000000000..6343607c8711
--- /dev/null
+++ b/package/source/zippackage/ZipPackageStream.cxx
@@ -0,0 +1,797 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <com/sun/star/packages/zip/ZipConstants.hpp>
+#include <com/sun/star/embed/StorageFormats.hpp>
+#include <com/sun/star/packages/zip/ZipIOException.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+
+
+#include <ZipPackageStream.hxx>
+#include <ZipPackage.hxx>
+#include <ZipFile.hxx>
+#include <EncryptedDataHeader.hxx>
+#include <vos/diagnose.hxx>
+#include "wrapstreamforshare.hxx"
+
+#include <comphelper/seekableinput.hxx>
+#include <comphelper/storagehelper.hxx>
+
+#include <PackageConstants.hxx>
+
+using namespace com::sun::star::packages::zip::ZipConstants;
+using namespace com::sun::star::packages::zip;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star;
+using namespace cppu;
+using namespace rtl;
+
+Sequence < sal_Int8 > ZipPackageStream::aImplementationId = Sequence < sal_Int8 > ();
+
+
+ZipPackageStream::ZipPackageStream ( ZipPackage & rNewPackage,
+ const Reference< XMultiServiceFactory >& xFactory,
+ sal_Bool bAllowRemoveOnInsert )
+: m_xFactory( xFactory )
+, rZipPackage(rNewPackage)
+, bToBeCompressed ( sal_True )
+, bToBeEncrypted ( sal_False )
+, bHaveOwnKey ( sal_False )
+, bIsEncrypted ( sal_False )
+, xEncryptionData ( )
+, m_nStreamMode( PACKAGE_STREAM_NOTSET )
+, m_nMagicalHackPos( 0 )
+, m_nMagicalHackSize( 0 )
+, m_bHasSeekable( sal_False )
+, m_bCompressedIsSetFromOutside( sal_False )
+, m_bFromManifest( sal_False )
+{
+ OSL_ENSURE( m_xFactory.is(), "No factory is provided to ZipPackageStream!\n" );
+
+ this->mbAllowRemoveOnInsert = bAllowRemoveOnInsert;
+
+ SetFolder ( sal_False );
+ aEntry.nVersion = -1;
+ aEntry.nFlag = 0;
+ aEntry.nMethod = -1;
+ aEntry.nTime = -1;
+ aEntry.nCrc = -1;
+ aEntry.nCompressedSize = -1;
+ aEntry.nSize = -1;
+ aEntry.nOffset = -1;
+ aEntry.nPathLen = -1;
+ aEntry.nExtraLen = -1;
+
+ if ( !aImplementationId.getLength() )
+ {
+ aImplementationId = getImplementationId();
+ }
+}
+
+ZipPackageStream::~ZipPackageStream( void )
+{
+}
+
+void ZipPackageStream::setZipEntryOnLoading( const ZipEntry &rInEntry)
+{
+ aEntry.nVersion = rInEntry.nVersion;
+ aEntry.nFlag = rInEntry.nFlag;
+ aEntry.nMethod = rInEntry.nMethod;
+ aEntry.nTime = rInEntry.nTime;
+ aEntry.nCrc = rInEntry.nCrc;
+ aEntry.nCompressedSize = rInEntry.nCompressedSize;
+ aEntry.nSize = rInEntry.nSize;
+ aEntry.nOffset = rInEntry.nOffset;
+ aEntry.sPath = rInEntry.sPath;
+ aEntry.nPathLen = rInEntry.nPathLen;
+ aEntry.nExtraLen = rInEntry.nExtraLen;
+
+ if ( aEntry.nMethod == STORED )
+ bToBeCompressed = sal_False;
+}
+
+//--------------------------------------------------------------------------
+void ZipPackageStream::CloseOwnStreamIfAny()
+{
+ if ( xStream.is() )
+ {
+ xStream->closeInput();
+ xStream = uno::Reference< io::XInputStream >();
+ m_bHasSeekable = sal_False;
+ }
+}
+
+//--------------------------------------------------------------------------
+uno::Reference< io::XInputStream >& ZipPackageStream::GetOwnSeekStream()
+{
+ if ( !m_bHasSeekable && xStream.is() )
+ {
+ // The package component requires that every stream either be FROM a package or it must support XSeekable!
+ // The only exception is a nonseekable stream that is provided only for storing, if such a stream
+ // is accessed before commit it MUST be wrapped.
+ // Wrap the stream in case it is not seekable
+ xStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( xStream, m_xFactory );
+ Reference< io::XSeekable > xSeek( xStream, UNO_QUERY );
+ if ( !xSeek.is() )
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "The stream must support XSeekable!" ) ),
+ Reference< XInterface >() );
+
+ m_bHasSeekable = sal_True;
+ }
+
+ return xStream;
+}
+
+//--------------------------------------------------------------------------
+uno::Reference< io::XInputStream > ZipPackageStream::GetRawEncrStreamNoHeaderCopy()
+{
+ if ( m_nStreamMode != PACKAGE_STREAM_RAW || !GetOwnSeekStream().is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( xEncryptionData.isEmpty() )
+ throw ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Encrypted stream without encryption data!\n" ) ),
+ Reference< XInterface >() );
+
+ uno::Reference< io::XSeekable > xSeek( GetOwnSeekStream(), UNO_QUERY );
+ if ( !xSeek.is() )
+ throw ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "The stream must be seekable!\n" ) ),
+ Reference< XInterface >() );
+
+ // skip header
+ xSeek->seek( n_ConstHeaderSize + xEncryptionData->aInitVector.getLength() +
+ xEncryptionData->aSalt.getLength() + xEncryptionData->aDigest.getLength() );
+
+ // create temporary stream
+ uno::Reference < io::XOutputStream > xTempOut(
+ m_xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
+ uno::UNO_QUERY );
+ uno::Reference < io::XInputStream > xTempIn( xTempOut, UNO_QUERY );
+ uno::Reference < io::XSeekable > xTempSeek( xTempOut, UNO_QUERY );
+ if ( !xTempOut.is() || !xTempIn.is() || !xTempSeek.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // copy the raw stream to the temporary file starting from the current position
+ ::comphelper::OStorageHelper::CopyInputToOutput( GetOwnSeekStream(), xTempOut );
+ xTempOut->closeOutput();
+ xTempSeek->seek( 0 );
+
+ return xTempIn;
+}
+
+//--------------------------------------------------------------------------
+Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream( sal_Bool bAddHeaderForEncr )
+{
+ if ( m_nStreamMode != PACKAGE_STREAM_DATA || !GetOwnSeekStream().is() || (bAddHeaderForEncr && !bToBeEncrypted) )
+ throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ Sequence< sal_Int8 > aKey;
+
+ if ( bToBeEncrypted )
+ {
+ aKey = ( xEncryptionData.isEmpty() || !bHaveOwnKey ) ? rZipPackage.getEncryptionKey() :
+ xEncryptionData->aKey;
+ if ( !aKey.getLength() )
+ throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ try
+ {
+ // create temporary file
+ uno::Reference < io::XStream > xTempStream(
+ m_xFactory->createInstance ( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
+ uno::UNO_QUERY );
+ if ( !xTempStream.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // create a package based on it
+ ZipPackage* pPackage = new ZipPackage( m_xFactory );
+ Reference< XSingleServiceFactory > xPackageAsFactory( static_cast< XSingleServiceFactory* >( pPackage ) );
+ if ( !xPackageAsFactory.is() )
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ Sequence< Any > aArgs( 1 );
+ aArgs[0] <<= xTempStream;
+ pPackage->initialize( aArgs );
+
+ // create a new package stream
+ Reference< XDataSinkEncrSupport > xNewPackStream( xPackageAsFactory->createInstance(), UNO_QUERY );
+ if ( !xNewPackStream.is() )
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ xNewPackStream->setDataStream( static_cast< io::XInputStream* >(
+ new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() ) ) );
+
+ Reference< XPropertySet > xNewPSProps( xNewPackStream, UNO_QUERY );
+ if ( !xNewPSProps.is() )
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // copy all the properties of this stream to the new stream
+ xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ), makeAny( sMediaType ) );
+ xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) ), makeAny( bToBeCompressed ) );
+ if ( bToBeEncrypted )
+ {
+ xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionKey" ) ), makeAny( aKey ) );
+ xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Encrypted" ) ), makeAny( sal_True ) );
+ }
+
+ // insert a new stream in the package
+ Reference< XUnoTunnel > xTunnel;
+ Any aRoot = pPackage->getByHierarchicalName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ) );
+ aRoot >>= xTunnel;
+ Reference< container::XNameContainer > xRootNameContainer( xTunnel, UNO_QUERY );
+ if ( !xRootNameContainer.is() )
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ Reference< XUnoTunnel > xNPSTunnel( xNewPackStream, UNO_QUERY );
+ xRootNameContainer->insertByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "dummy" ) ), makeAny( xNPSTunnel ) );
+
+ // commit the temporary package
+ pPackage->commitChanges();
+
+ // get raw stream from the temporary package
+ Reference< io::XInputStream > xInRaw;
+ if ( bAddHeaderForEncr )
+ xInRaw = xNewPackStream->getRawStream();
+ else
+ xInRaw = xNewPackStream->getPlainRawStream();
+
+ // create another temporary file
+ uno::Reference < io::XOutputStream > xTempOut(
+ m_xFactory->createInstance ( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
+ uno::UNO_QUERY );
+ uno::Reference < io::XInputStream > xTempIn( xTempOut, UNO_QUERY );
+ uno::Reference < io::XSeekable > xTempSeek( xTempOut, UNO_QUERY );
+ if ( !xTempOut.is() || !xTempIn.is() || !xTempSeek.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // copy the raw stream to the temporary file
+ ::comphelper::OStorageHelper::CopyInputToOutput( xInRaw, xTempOut );
+ xTempOut->closeOutput();
+ xTempSeek->seek( 0 );
+
+ // close raw stream, package stream and folder
+ xInRaw = Reference< io::XInputStream >();
+ xNewPSProps = Reference< XPropertySet >();
+ xNPSTunnel = Reference< XUnoTunnel >();
+ xNewPackStream = Reference< XDataSinkEncrSupport >();
+ xTunnel = Reference< XUnoTunnel >();
+ xRootNameContainer = Reference< container::XNameContainer >();
+
+ // return the stream representing the first temporary file
+ return xTempIn;
+ }
+ catch ( RuntimeException& )
+ {
+ throw;
+ }
+ catch ( Exception& )
+ {
+ }
+
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+//--------------------------------------------------------------------------
+sal_Bool ZipPackageStream::ParsePackageRawStream()
+{
+ OSL_ENSURE( GetOwnSeekStream().is(), "A stream must be provided!\n" );
+
+ if ( !GetOwnSeekStream().is() )
+ return sal_False;
+
+ sal_Bool bOk = sal_False;
+
+ vos::ORef < EncryptionData > xTempEncrData;
+ sal_Int32 nMagHackSize = 0;
+ Sequence < sal_Int8 > aHeader ( 4 );
+
+ try
+ {
+ if ( GetOwnSeekStream()->readBytes ( aHeader, 4 ) == 4 )
+ {
+ const sal_Int8 *pHeader = aHeader.getConstArray();
+ sal_uInt32 nHeader = ( pHeader [0] & 0xFF ) |
+ ( pHeader [1] & 0xFF ) << 8 |
+ ( pHeader [2] & 0xFF ) << 16 |
+ ( pHeader [3] & 0xFF ) << 24;
+ if ( nHeader == n_ConstHeader )
+ {
+ // this is one of our god-awful, but extremely devious hacks, everyone cheer
+ xTempEncrData = new EncryptionData;
+
+ ::rtl::OUString aMediaType;
+ if ( ZipFile::StaticFillData ( xTempEncrData, nMagHackSize, aMediaType, GetOwnSeekStream() ) )
+ {
+ // We'll want to skip the data we've just read, so calculate how much we just read
+ // and remember it
+ m_nMagicalHackPos = n_ConstHeaderSize + xTempEncrData->aSalt.getLength()
+ + xTempEncrData->aInitVector.getLength()
+ + xTempEncrData->aDigest.getLength()
+ + aMediaType.getLength() * sizeof( sal_Unicode );
+ m_nMagicalHackSize = nMagHackSize;
+ sMediaType = aMediaType;
+
+ bOk = sal_True;
+ }
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ if ( !bOk )
+ {
+ // the provided stream is not a raw stream
+ return sal_False;
+ }
+
+ xEncryptionData = xTempEncrData;
+ SetIsEncrypted ( sal_True );
+ // it's already compressed and encrypted
+ bToBeEncrypted = bToBeCompressed = sal_False;
+
+ return sal_True;
+}
+
+void ZipPackageStream::SetPackageMember( sal_Bool bNewValue )
+{
+ if ( bNewValue )
+ {
+ m_nStreamMode = PACKAGE_STREAM_PACKAGEMEMBER;
+ m_nMagicalHackPos = 0;
+ m_nMagicalHackSize = 0;
+ }
+ else if ( m_nStreamMode == PACKAGE_STREAM_PACKAGEMEMBER )
+ m_nStreamMode = PACKAGE_STREAM_NOTSET; // must be reset
+}
+
+// XActiveDataSink
+//--------------------------------------------------------------------------
+void SAL_CALL ZipPackageStream::setInputStream( const Reference< io::XInputStream >& aStream )
+ throw(RuntimeException)
+{
+ // if seekable access is required the wrapping will be done on demand
+ xStream = aStream;
+ m_bHasSeekable = sal_False;
+ SetPackageMember ( sal_False );
+ aEntry.nTime = -1;
+ m_nStreamMode = PACKAGE_STREAM_DETECT;
+}
+
+//--------------------------------------------------------------------------
+Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawData()
+ throw(RuntimeException)
+{
+ try
+ {
+ if (IsPackageMember())
+ {
+ if ( !xEncryptionData.isEmpty() && !bHaveOwnKey )
+ xEncryptionData->aKey = rZipPackage.getEncryptionKey();
+ return rZipPackage.getZipFile().getRawData( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() );
+ }
+ else if ( GetOwnSeekStream().is() )
+ {
+ return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
+ }
+ else
+ return Reference < io::XInputStream > ();
+ }
+ catch (ZipException &)//rException)
+ {
+ VOS_ENSURE( 0, "ZipException thrown");//rException.Message);
+ return Reference < io::XInputStream > ();
+ }
+ catch (Exception &)
+ {
+ VOS_ENSURE( 0, "Exception is thrown during stream wrapping!\n");
+ return Reference < io::XInputStream > ();
+ }
+}
+
+//--------------------------------------------------------------------------
+Reference< io::XInputStream > SAL_CALL ZipPackageStream::getInputStream( )
+ throw(RuntimeException)
+{
+ try
+ {
+ if (IsPackageMember())
+ {
+ if ( !xEncryptionData.isEmpty() && !bHaveOwnKey )
+ xEncryptionData->aKey = rZipPackage.getEncryptionKey();
+ return rZipPackage.getZipFile().getInputStream( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() );
+ }
+ else if ( GetOwnSeekStream().is() )
+ {
+ return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
+ }
+ else
+ return Reference < io::XInputStream > ();
+ }
+ catch (ZipException &)//rException)
+ {
+ VOS_ENSURE( 0,"ZipException thrown");//rException.Message);
+ return Reference < io::XInputStream > ();
+ }
+ catch (Exception &)
+ {
+ VOS_ENSURE( 0, "Exception is thrown during stream wrapping!\n");
+ return Reference < io::XInputStream > ();
+ }
+}
+
+// XDataSinkEncrSupport
+//--------------------------------------------------------------------------
+Reference< io::XInputStream > SAL_CALL ZipPackageStream::getDataStream()
+ throw ( packages::WrongPasswordException,
+ io::IOException,
+ RuntimeException )
+{
+ // There is no stream attached to this object
+ if ( m_nStreamMode == PACKAGE_STREAM_NOTSET )
+ return Reference< io::XInputStream >();
+
+ // this method can not be used together with old approach
+ if ( m_nStreamMode == PACKAGE_STREAM_DETECT )
+ throw packages::zip::ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !xEncryptionData.isEmpty() && !bHaveOwnKey )
+ xEncryptionData->aKey = rZipPackage.getEncryptionKey();
+
+ if (IsPackageMember())
+ {
+ if ( !xEncryptionData.isEmpty() && !bHaveOwnKey )
+ xEncryptionData->aKey = rZipPackage.getEncryptionKey();
+
+ return rZipPackage.getZipFile().getDataStream( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() );
+ }
+ else if ( m_nStreamMode == PACKAGE_STREAM_RAW )
+ return ZipFile::StaticGetDataFromRawStream( GetOwnSeekStream(), xEncryptionData );
+ else if ( GetOwnSeekStream().is() )
+ {
+ return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
+ }
+ else
+ return uno::Reference< io::XInputStream >();
+}
+
+//--------------------------------------------------------------------------
+Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawStream()
+ throw ( packages::NoEncryptionException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ // There is no stream attached to this object
+ if ( m_nStreamMode == PACKAGE_STREAM_NOTSET )
+ return Reference< io::XInputStream >();
+
+ // this method can not be used together with old approach
+ if ( m_nStreamMode == PACKAGE_STREAM_DETECT )
+ throw packages::zip::ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if (IsPackageMember())
+ {
+ if ( !bIsEncrypted || xEncryptionData.isEmpty() )
+ throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return rZipPackage.getZipFile().getWrappedRawStream( aEntry, xEncryptionData, sMediaType, rZipPackage.GetSharedMutexRef() );
+ }
+ else if ( GetOwnSeekStream().is() )
+ {
+ if ( m_nStreamMode == PACKAGE_STREAM_RAW )
+ {
+ return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
+ }
+ else if ( m_nStreamMode == PACKAGE_STREAM_DATA && bToBeEncrypted )
+ return TryToGetRawFromDataStream( sal_True );
+ }
+
+ throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+//--------------------------------------------------------------------------
+void SAL_CALL ZipPackageStream::setDataStream( const Reference< io::XInputStream >& aStream )
+ throw ( io::IOException,
+ RuntimeException )
+{
+ setInputStream( aStream );
+ m_nStreamMode = PACKAGE_STREAM_DATA;
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL ZipPackageStream::setRawStream( const Reference< io::XInputStream >& aStream )
+ throw ( packages::EncryptionNotAllowedException,
+ packages::NoRawFormatException,
+ io::IOException,
+ RuntimeException)
+{
+ // wrap the stream in case it is not seekable
+ Reference< io::XInputStream > xNewStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( aStream, m_xFactory );
+ Reference< io::XSeekable > xSeek( xNewStream, UNO_QUERY );
+ if ( !xSeek.is() )
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "The stream must support XSeekable!" ) ),
+ Reference< XInterface >() );
+
+ xSeek->seek( 0 );
+ Reference< io::XInputStream > xOldStream = xStream;
+ xStream = xNewStream;
+ if ( !ParsePackageRawStream() )
+ {
+ xStream = xOldStream;
+ throw packages::NoRawFormatException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ // the raw stream MUST have seekable access
+ m_bHasSeekable = sal_True;
+
+ SetPackageMember ( sal_False );
+ aEntry.nTime = -1;
+ m_nStreamMode = PACKAGE_STREAM_RAW;
+}
+
+//--------------------------------------------------------------------------
+uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getPlainRawStream()
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ // There is no stream attached to this object
+ if ( m_nStreamMode == PACKAGE_STREAM_NOTSET )
+ return Reference< io::XInputStream >();
+
+ // this method can not be used together with old approach
+ if ( m_nStreamMode == PACKAGE_STREAM_DETECT )
+ throw packages::zip::ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if (IsPackageMember())
+ {
+ return rZipPackage.getZipFile().getRawData( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() );
+ }
+ else if ( GetOwnSeekStream().is() )
+ {
+ if ( m_nStreamMode == PACKAGE_STREAM_RAW )
+ {
+ // the header should not be returned here
+ return GetRawEncrStreamNoHeaderCopy();
+ }
+ else if ( m_nStreamMode == PACKAGE_STREAM_DATA )
+ return TryToGetRawFromDataStream( sal_False );
+ }
+
+ return Reference< io::XInputStream >();
+}
+
+// XUnoTunnel
+
+//--------------------------------------------------------------------------
+sal_Int64 SAL_CALL ZipPackageStream::getSomething( const Sequence< sal_Int8 >& aIdentifier )
+ throw(RuntimeException)
+{
+ sal_Int64 nMe = 0;
+ if ( aIdentifier.getLength() == 16 &&
+ 0 == rtl_compareMemory( static_getImplementationId().getConstArray(), aIdentifier.getConstArray(), 16 ) )
+ nMe = reinterpret_cast < sal_Int64 > ( this );
+ return nMe;
+}
+
+// XPropertySet
+//--------------------------------------------------------------------------
+void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("MediaType")))
+ {
+ if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE && rZipPackage.getFormat() != embed::StorageFormats::OFOPXML )
+ throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( aValue >>= sMediaType )
+ {
+ if (sMediaType.getLength() > 0)
+ {
+ if ( sMediaType.indexOf (OUString( RTL_CONSTASCII_USTRINGPARAM ( "text" ) ) ) != -1
+ || sMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM ( "application/vnd.sun.star.oleobject" ) ) ) )
+ bToBeCompressed = sal_True;
+ else if ( !m_bCompressedIsSetFromOutside )
+ bToBeCompressed = sal_False;
+ }
+ }
+ else
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "MediaType must be a string!\n" ) ),
+ Reference< XInterface >(),
+ 2 );
+
+ }
+ else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Size") ) )
+ {
+ if ( !( aValue >>= aEntry.nSize ) )
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for Size property!\n" ) ),
+ Reference< XInterface >(),
+ 2 );
+ }
+ else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Encrypted") ) )
+ {
+ if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE )
+ throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ sal_Bool bEnc = sal_False;
+ if ( aValue >>= bEnc )
+ {
+ // In case of new raw stream, the stream must not be encrypted on storing
+ if ( bEnc && m_nStreamMode == PACKAGE_STREAM_RAW )
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Raw stream can not be encrypted on storing" ) ),
+ Reference< XInterface >(),
+ 2 );
+
+ bToBeEncrypted = bEnc;
+ if ( bToBeEncrypted && xEncryptionData.isEmpty())
+ xEncryptionData = new EncryptionData;
+ }
+ else
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for Encrypted property!\n" ) ),
+ Reference< XInterface >(),
+ 2 );
+
+ }
+ else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("EncryptionKey") ) )
+ {
+ if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE )
+ throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ Sequence < sal_Int8 > aNewKey;
+
+ if ( !( aValue >>= aNewKey ) )
+ {
+ OUString sTempString;
+ if ( ( aValue >>= sTempString ) )
+ {
+ sal_Int32 nPathLength = sTempString.getLength();
+ Sequence < sal_Int8 > aSequence ( nPathLength );
+ sal_Int8 *pArray = aSequence.getArray();
+ const sal_Unicode *pChar = sTempString.getStr();
+ for ( sal_Int16 i = 0; i < nPathLength; i++)
+ pArray[i] = static_cast < const sal_Int8 > (pChar[i]);
+ aNewKey = aSequence;
+ }
+ else
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for EncryptionKey property!\n" ) ),
+ Reference< XInterface >(),
+ 2 );
+ }
+
+ if ( aNewKey.getLength() )
+ {
+ if ( xEncryptionData.isEmpty())
+ xEncryptionData = new EncryptionData;
+
+ xEncryptionData->aKey = aNewKey;
+ // In case of new raw stream, the stream must not be encrypted on storing
+ bHaveOwnKey = sal_True;
+ if ( m_nStreamMode != PACKAGE_STREAM_RAW )
+ bToBeEncrypted = sal_True;
+ }
+ else
+ bHaveOwnKey = sal_False;
+ }
+ else if (aPropertyName.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "Compressed" ) ) )
+ {
+ sal_Bool bCompr = sal_False;
+
+ if ( aValue >>= bCompr )
+ {
+ // In case of new raw stream, the stream must not be encrypted on storing
+ if ( bCompr && m_nStreamMode == PACKAGE_STREAM_RAW )
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Raw stream can not be encrypted on storing" ) ),
+ Reference< XInterface >(),
+ 2 );
+
+ bToBeCompressed = bCompr;
+ m_bCompressedIsSetFromOutside = sal_True;
+ }
+ else
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for Compressed property!\n" ) ),
+ Reference< XInterface >(),
+ 2 );
+ }
+ else
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+//--------------------------------------------------------------------------
+Any SAL_CALL ZipPackageStream::getPropertyValue( const OUString& PropertyName )
+ throw(beans::UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ Any aAny;
+ if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) )
+ {
+ aAny <<= sMediaType;
+ return aAny;
+ }
+ else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Size" ) ) )
+ {
+ aAny <<= aEntry.nSize;
+ return aAny;
+ }
+ else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Encrypted" ) ) )
+ {
+ aAny <<= ( m_nStreamMode == PACKAGE_STREAM_RAW ) ? sal_True : bToBeEncrypted;
+ return aAny;
+ }
+ else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "WasEncrypted" ) ) )
+ {
+ aAny <<= bIsEncrypted;
+ return aAny;
+ }
+ else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Compressed" ) ) )
+ {
+ aAny <<= bToBeCompressed;
+ return aAny;
+ }
+ else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "EncryptionKey" ) ) )
+ {
+ aAny <<= xEncryptionData.isEmpty () ? Sequence < sal_Int8 > () : xEncryptionData->aKey;
+ return aAny;
+ }
+ else
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+//--------------------------------------------------------------------------
+void ZipPackageStream::setSize (const sal_Int32 nNewSize)
+{
+ if (aEntry.nCompressedSize != nNewSize )
+ aEntry.nMethod = DEFLATED;
+ aEntry.nSize = nNewSize;
+}
+//--------------------------------------------------------------------------
+OUString ZipPackageStream::getImplementationName()
+ throw (RuntimeException)
+{
+ return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "ZipPackageStream" ) );
+}
+
+//--------------------------------------------------------------------------
+Sequence< OUString > ZipPackageStream::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ Sequence< OUString > aNames(1);
+ aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.PackageStream" ) );
+ return aNames;
+}
+//--------------------------------------------------------------------------
+sal_Bool SAL_CALL ZipPackageStream::supportsService( OUString const & rServiceName )
+ throw (RuntimeException)
+{
+ return rServiceName == getSupportedServiceNames()[0];
+}
+
diff --git a/package/source/zippackage/ZipPackageStream.hxx b/package/source/zippackage/ZipPackageStream.hxx
new file mode 100644
index 000000000000..a0d5fad6e4da
--- /dev/null
+++ b/package/source/zippackage/ZipPackageStream.hxx
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _ZIP_PACKAGE_STREAM_HXX
+#define _ZIP_PACKAGE_STREAM_HXX
+
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/packages/XDataSinkEncrSupport.hpp>
+#include <ZipPackageEntry.hxx>
+#ifndef _VOS_REF_H_
+#include <vos/ref.hxx>
+#endif
+#include <EncryptionData.hxx>
+#ifndef _CPPUHELPER_IMPLBASE2_HXX
+#include <cppuhelper/implbase2.hxx>
+#endif
+#include <mutexholder.hxx>
+
+#define PACKAGE_STREAM_NOTSET 0
+#define PACKAGE_STREAM_PACKAGEMEMBER 1
+#define PACKAGE_STREAM_DETECT 2
+#define PACKAGE_STREAM_DATA 3
+#define PACKAGE_STREAM_RAW 4
+
+class ZipPackage;
+struct ZipEntry;
+class ZipPackageStream : public cppu::ImplInheritanceHelper2
+<
+ ZipPackageEntry,
+ ::com::sun::star::io::XActiveDataSink,
+ ::com::sun::star::packages::XDataSinkEncrSupport
+>
+{
+ static com::sun::star::uno::Sequence < sal_Int8 > aImplementationId;
+protected:
+ com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xStream;
+ const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > m_xFactory;
+ ZipPackage &rZipPackage;
+ sal_Bool bToBeCompressed, bToBeEncrypted, bHaveOwnKey, bIsEncrypted;
+ vos::ORef < EncryptionData > xEncryptionData;
+
+ sal_uInt8 m_nStreamMode;
+ sal_uInt32 m_nMagicalHackPos;
+ sal_uInt32 m_nMagicalHackSize;
+
+ sal_Bool m_bHasSeekable;
+
+ sal_Bool m_bCompressedIsSetFromOutside;
+
+ sal_Bool m_bFromManifest;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& GetOwnSeekStream();
+
+public:
+ sal_Bool HasOwnKey () const { return bHaveOwnKey;}
+ sal_Bool IsToBeCompressed () const { return bToBeCompressed;}
+ sal_Bool IsToBeEncrypted () const { return bToBeEncrypted;}
+ sal_Bool IsEncrypted () const { return bIsEncrypted;}
+ sal_Bool IsPackageMember () const { return m_nStreamMode == PACKAGE_STREAM_PACKAGEMEMBER;}
+
+ sal_Bool IsFromManifest() const { return m_bFromManifest; }
+ void SetFromManifest( sal_Bool bValue ) { m_bFromManifest = bValue; }
+
+ vos::ORef < EncryptionData > & getEncryptionData ()
+ { return xEncryptionData;}
+ const com::sun::star::uno::Sequence < sal_Int8 >& getKey () const
+ { return xEncryptionData->aKey;}
+ const com::sun::star::uno::Sequence < sal_uInt8 >& getInitialisationVector () const
+ { return xEncryptionData->aInitVector;}
+ const com::sun::star::uno::Sequence < sal_uInt8 >& getDigest () const
+ { return xEncryptionData->aDigest;}
+ const com::sun::star::uno::Sequence < sal_uInt8 >& getSalt () const
+ { return xEncryptionData->aSalt;}
+ sal_Int32 getIterationCount () const
+ { return xEncryptionData->nIterationCount;}
+ sal_Int32 getSize () const
+ { return aEntry.nSize;}
+
+ sal_uInt8 GetStreamMode() const { return m_nStreamMode; }
+ sal_uInt32 GetMagicalHackPos() const { return m_nMagicalHackPos; }
+ sal_uInt32 GetMagicalHackSize() const { return m_nMagicalHackSize; }
+
+ void SetToBeCompressed (sal_Bool bNewValue) { bToBeCompressed = bNewValue;}
+ void SetIsEncrypted (sal_Bool bNewValue) { bIsEncrypted = bNewValue;}
+ void SetToBeEncrypted (sal_Bool bNewValue)
+ {
+ bToBeEncrypted = bNewValue;
+ if ( bToBeEncrypted && xEncryptionData.isEmpty())
+ xEncryptionData = new EncryptionData;
+ else if ( !bToBeEncrypted && !xEncryptionData.isEmpty() )
+ xEncryptionData.unbind();
+ }
+ void SetPackageMember (sal_Bool bNewValue);
+ void setKey (const com::sun::star::uno::Sequence < sal_Int8 >& rNewKey )
+ { xEncryptionData->aKey = rNewKey;}
+ void setInitialisationVector (const com::sun::star::uno::Sequence < sal_uInt8 >& rNewVector )
+ { xEncryptionData->aInitVector = rNewVector;}
+ void setSalt (const com::sun::star::uno::Sequence < sal_uInt8 >& rNewSalt )
+ { xEncryptionData->aSalt = rNewSalt;}
+ void setDigest (const com::sun::star::uno::Sequence < sal_uInt8 >& rNewDigest )
+ { xEncryptionData->aDigest = rNewDigest;}
+ void setIterationCount (const sal_Int32 nNewCount)
+ { xEncryptionData->nIterationCount = nNewCount;}
+ void setSize (const sal_Int32 nNewSize);
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetOwnStreamNoWrap() { return xStream; }
+
+ void CloseOwnStreamIfAny();
+
+ ZipPackageStream ( ZipPackage & rNewPackage,
+ const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory >& xFactory,
+ sal_Bool bAllowRemoveOnInsert );
+ virtual ~ZipPackageStream( void );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetRawEncrStreamNoHeaderCopy();
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > TryToGetRawFromDataStream(
+ sal_Bool bAddHeaderForEncr );
+
+ sal_Bool ParsePackageRawStream();
+
+ void setZipEntryOnLoading( const ZipEntry &rInEntry);
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getRawData()
+ throw(::com::sun::star::uno::RuntimeException);
+
+ static ::com::sun::star::uno::Sequence < sal_Int8 >& static_getImplementationId()
+ {
+ return aImplementationId;
+ }
+
+ // XActiveDataSink
+ virtual void SAL_CALL setInputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream( )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XDataSinkEncrSupport
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getDataStream()
+ throw ( ::com::sun::star::packages::WrongPasswordException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getRawStream()
+ throw ( ::com::sun::star::packages::NoEncryptionException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL setDataStream(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
+ throw ( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL setRawStream(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
+ throw ( ::com::sun::star::packages::EncryptionNotAllowedException,
+ ::com::sun::star::packages::NoRawFormatException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getPlainRawStream()
+ throw ( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ // XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XPropertySet
+ virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw (::com::sun::star::uno::RuntimeException);
+};
+#endif
diff --git a/package/source/zippackage/makefile.mk b/package/source/zippackage/makefile.mk
new file mode 100644
index 000000000000..4bab1649b491
--- /dev/null
+++ b/package/source/zippackage/makefile.mk
@@ -0,0 +1,63 @@
+#*************************************************************************
+#
+# 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=package
+TARGET=zippackage
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.IF "$(L10N_framework)"==""
+
+# --- Files --------------------------------------------------------
+# the following flag un-inlines function calls and disables optimisations
+#CFLAGS+=/Ob0 /Od
+
+SLOFILES= \
+ $(SLO)$/ZipPackage.obj \
+ $(SLO)$/ZipPackageBuffer.obj \
+ $(SLO)$/ZipPackageEntry.obj \
+ $(SLO)$/ZipPackageFolder.obj \
+ $(SLO)$/ZipPackageFolderEnumeration.obj \
+ $(SLO)$/ZipPackageSink.obj \
+ $(SLO)$/ZipPackageStream.obj \
+ $(SLO)$/wrapstreamforshare.obj \
+ $(SLO)$/zipfileaccess.obj
+
+# $(SLO)$/InteractionRequest.obj \
+# $(SLO)$/InteractionContinuation.obj
+
+.ENDIF # L10N_framework
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/package/source/zippackage/wrapstreamforshare.cxx b/package/source/zippackage/wrapstreamforshare.cxx
new file mode 100644
index 000000000000..d3d2eb84d1b7
--- /dev/null
+++ b/package/source/zippackage/wrapstreamforshare.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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <osl/diagnose.h>
+
+#include "wrapstreamforshare.hxx"
+
+using namespace ::com::sun::star;
+
+
+WrapStreamForShare::WrapStreamForShare( const uno::Reference< io::XInputStream >& xInStream,
+ const SotMutexHolderRef& rMutexRef )
+: m_rMutexRef( rMutexRef )
+, m_xInStream( xInStream )
+, m_nCurPos( 0 )
+{
+ m_xSeekable = uno::Reference< io::XSeekable >( m_xInStream, uno::UNO_QUERY );
+ if ( !m_rMutexRef.Is() || !m_xInStream.is() || !m_xSeekable.is() )
+ {
+ OSL_ENSURE( sal_False, "Wrong initialization of wrapping stream!\n" );
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+}
+
+WrapStreamForShare::~WrapStreamForShare()
+{
+}
+
+// XInputStream
+sal_Int32 SAL_CALL WrapStreamForShare::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( !m_xInStream.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ m_xSeekable->seek( m_nCurPos );
+
+ sal_Int32 nRead = m_xInStream->readBytes( aData, nBytesToRead );
+ m_nCurPos += nRead;
+
+ return nRead;
+}
+
+sal_Int32 SAL_CALL WrapStreamForShare::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( !m_xInStream.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ m_xSeekable->seek( m_nCurPos );
+
+ sal_Int32 nRead = m_xInStream->readSomeBytes( aData, nMaxBytesToRead );
+ m_nCurPos += nRead;
+
+ return nRead;
+}
+
+void SAL_CALL WrapStreamForShare::skipBytes( sal_Int32 nBytesToSkip )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( !m_xInStream.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ m_xSeekable->seek( m_nCurPos );
+
+ m_xInStream->skipBytes( nBytesToSkip );
+ m_nCurPos = m_xSeekable->getPosition();
+}
+
+sal_Int32 SAL_CALL WrapStreamForShare::available()
+ throw ( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( !m_xInStream.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return m_xInStream->available();
+}
+
+void SAL_CALL WrapStreamForShare::closeInput()
+ throw ( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( !m_xInStream.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // the package is the owner so it will close the stream
+ // m_xInStream->closeInput();
+ m_xInStream = uno::Reference< io::XInputStream >();
+ m_xSeekable = uno::Reference< io::XSeekable >();
+}
+
+// XSeekable
+void SAL_CALL WrapStreamForShare::seek( sal_Int64 location )
+ throw ( lang::IllegalArgumentException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( !m_xInStream.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // let stream implementation do all the checking
+ m_xSeekable->seek( location );
+
+ m_nCurPos = m_xSeekable->getPosition();
+}
+
+sal_Int64 SAL_CALL WrapStreamForShare::getPosition()
+ throw ( io::IOException,
+ uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( !m_xInStream.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return m_nCurPos;
+}
+
+sal_Int64 SAL_CALL WrapStreamForShare::getLength()
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
+
+ if ( !m_xInStream.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return m_xSeekable->getLength();
+}
+
diff --git a/package/source/zippackage/wrapstreamforshare.hxx b/package/source/zippackage/wrapstreamforshare.hxx
new file mode 100644
index 000000000000..c799e3ac9b92
--- /dev/null
+++ b/package/source/zippackage/wrapstreamforshare.hxx
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _WRAPSTREAMFORSHARE_HXX_
+#define _WRAPSTREAMFORSHARE_HXX_
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <cppuhelper/implbase2.hxx>
+
+#include <mutexholder.hxx>
+
+class WrapStreamForShare : public cppu::WeakImplHelper2 < ::com::sun::star::io::XInputStream
+ , ::com::sun::star::io::XSeekable >
+{
+protected:
+ SotMutexHolderRef m_rMutexRef;
+ ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > m_xInStream;
+ ::com::sun::star::uno::Reference < ::com::sun::star::io::XSeekable > m_xSeekable;
+
+ sal_Int64 m_nCurPos;
+
+public:
+ WrapStreamForShare( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInStream,
+ const SotMutexHolderRef& rMutexRef );
+ virtual ~WrapStreamForShare();
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL available( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeInput( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+
+ //XSeekable
+ virtual void SAL_CALL seek( sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getPosition() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getLength() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+};
+
+#endif
+
diff --git a/package/source/zippackage/zipfileaccess.cxx b/package/source/zippackage/zipfileaccess.cxx
new file mode 100644
index 000000000000..9acae56ad68a
--- /dev/null
+++ b/package/source/zippackage/zipfileaccess.cxx
@@ -0,0 +1,492 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_package.hxx"
+#include <com/sun/star/lang/DisposedException.hpp>
+#ifndef _COM_SUN_STAR_LANG_INVALIDARGUMENTEXCEPTION_HPP_
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#endif
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+
+#include <zipfileaccess.hxx>
+#include <ZipEnumeration.hxx>
+#include <ZipPackageSink.hxx>
+#include <EncryptionData.hxx>
+
+#include <ucbhelper/content.hxx>
+
+#include <memory>
+
+
+using namespace ::com::sun::star;
+
+// ----------------------------------------------------------------
+OZipFileAccess::OZipFileAccess( const uno::Reference< lang::XMultiServiceFactory >& xFactory )
+: m_aMutexHolder( new SotMutexHolder )
+, m_xFactory( xFactory )
+, m_pZipFile( NULL )
+, m_pListenersContainer( NULL )
+, m_bDisposed( sal_False )
+{
+ if ( !xFactory.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+// ----------------------------------------------------------------
+OZipFileAccess::~OZipFileAccess()
+{
+ {
+ ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
+ if ( !m_bDisposed )
+ {
+ try {
+ m_refCount++; // dispose will use refcounting so the further distruction must be avoided
+ dispose();
+ } catch( uno::Exception& )
+ {}
+ }
+ }
+}
+
+// ----------------------------------------------------------------
+uno::Sequence< ::rtl::OUString > OZipFileAccess::GetPatternsFromString_Impl( const ::rtl::OUString& aString )
+{
+ if ( !aString.getLength() )
+ return uno::Sequence< ::rtl::OUString >();
+
+ uno::Sequence< ::rtl::OUString > aPattern( 1 );
+ sal_Int32 nInd = 0;
+
+ const sal_Unicode* pString = aString.getStr();
+ while( *pString )
+ {
+ if ( *pString == (sal_Unicode)'\\' )
+ {
+ pString++;
+
+ if ( *pString == (sal_Unicode)'\\' )
+ {
+ aPattern[nInd] += ::rtl::OUString::valueOf( (sal_Unicode)'\\' );
+ pString++;
+ }
+ else if ( *pString == (sal_Unicode)'*' )
+ {
+ aPattern[nInd] += ::rtl::OUString::valueOf( (sal_Unicode)'*' );
+ pString++;
+ }
+ else
+ {
+ OSL_ENSURE( sal_False, "The backslash is not guarded!\n" );
+ aPattern[nInd] += ::rtl::OUString::valueOf( (sal_Unicode)'\\' );
+ }
+ }
+ else if ( *pString == (sal_Unicode)'*' )
+ {
+ aPattern.realloc( ( ++nInd ) + 1 );
+ pString++;
+ }
+ else
+ {
+ aPattern[nInd] += ::rtl::OUString::valueOf( *pString );
+ pString++;
+ }
+ }
+
+ return aPattern;
+}
+
+// ----------------------------------------------------------------
+sal_Bool OZipFileAccess::StringGoodForPattern_Impl( const ::rtl::OUString& aString,
+ const uno::Sequence< ::rtl::OUString >& aPattern )
+{
+ sal_Int32 nInd = aPattern.getLength() - 1;
+ if ( nInd < 0 )
+ return sal_False;
+
+ if ( nInd == 0 )
+ {
+ if ( !aPattern[0].getLength() )
+ return sal_True;
+
+ return aString.equals( aPattern[0] );
+ }
+
+ sal_Int32 nBeginInd = aPattern[0].getLength();
+ sal_Int32 nEndInd = aString.getLength() - aPattern[nInd].getLength();
+ if ( nEndInd >= nBeginInd
+ && ( nEndInd == aString.getLength() || aString.copy( nEndInd ).equals( aPattern[nInd] ) )
+ && ( nBeginInd == 0 || aString.copy( 0, nBeginInd ).equals( aPattern[0] ) ) )
+ {
+ for ( sal_Int32 nCurInd = aPattern.getLength() - 2; nCurInd > 0; nCurInd-- )
+ {
+ if ( !aPattern[nCurInd].getLength() )
+ continue;
+
+ if ( nEndInd == nBeginInd )
+ return sal_False;
+
+ // check that search does not use nEndInd position
+ sal_Int32 nLastInd = aString.lastIndexOf( aPattern[nCurInd], nEndInd - 1 );
+
+ if ( nLastInd == -1 )
+ return sal_False;
+
+ if ( nLastInd < nBeginInd )
+ return sal_False;
+
+ nEndInd = nLastInd;
+ }
+
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+// XInitialization
+// ----------------------------------------------------------------
+void SAL_CALL OZipFileAccess::initialize( const uno::Sequence< uno::Any >& aArguments )
+ throw ( uno::Exception,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( m_pZipFile )
+ throw uno::Exception( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // initialization is allowed only one time
+
+ if ( !aArguments.getLength() )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ OSL_ENSURE( aArguments.getLength() == 1, "Too meny arguments are provided, only the first one will be used!\n" );
+
+ ::rtl::OUString aParamURL;
+ uno::Reference< io::XStream > xStream;
+ uno::Reference< io::XSeekable > xSeekable;
+
+ if ( ( aArguments[0] >>= aParamURL ) )
+ {
+ ::ucbhelper::Content aContent ( aParamURL, uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
+ uno::Reference < io::XActiveDataSink > xSink = new ZipPackageSink;
+ if ( aContent.openStream ( xSink ) )
+ {
+ m_xContentStream = xSink->getInputStream();
+ xSeekable = uno::Reference< io::XSeekable >( m_xContentStream, uno::UNO_QUERY );
+ }
+ }
+ else if ( (aArguments[0] >>= xStream ) )
+ {
+ // a writable stream can implement both XStream & XInputStream
+ m_xContentStream = xStream->getInputStream();
+ xSeekable = uno::Reference< io::XSeekable >( xStream, uno::UNO_QUERY );
+ }
+ else if ( !( aArguments[0] >>= m_xContentStream ) )
+ {
+ xSeekable = uno::Reference< io::XSeekable >( m_xContentStream, uno::UNO_QUERY );
+ }
+ else
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+
+ if ( !m_xContentStream.is() )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !xSeekable.is() )
+ {
+ // TODO: after fwkbugfix02 is integrated a helper class can be used to make the stream seekable
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ // TODO: in case xSeekable is implemented on separated XStream implementation a wrapper is required
+ m_pZipFile = new ZipFile(
+ m_xContentStream,
+ m_xFactory,
+ sal_True );
+}
+
+// XNameAccess
+// ----------------------------------------------------------------
+uno::Any SAL_CALL OZipFileAccess::getByName( const ::rtl::OUString& aName )
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !m_pZipFile )
+ throw io::NotConnectedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ EntryHash::iterator aIter = m_pZipFile->GetEntryHash().find( aName );
+ if ( aIter == m_pZipFile->GetEntryHash().end() )
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< io::XInputStream > xEntryStream( m_pZipFile->getDataStream( (*aIter).second,
+ new EncryptionData(),
+ sal_False,
+ m_aMutexHolder ) );
+
+ if ( !xEntryStream.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return uno::makeAny ( xEntryStream );
+}
+
+// ----------------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL OZipFileAccess::getElementNames()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !m_pZipFile )
+ throw io::NotConnectedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Sequence< ::rtl::OUString > aNames( m_pZipFile->GetEntryHash().size() );
+ sal_Int32 nLen = 0;
+
+ for ( EntryHash::iterator aIter = m_pZipFile->GetEntryHash().begin(); aIter != m_pZipFile->GetEntryHash().end(); aIter++ )
+ {
+ if ( aNames.getLength() < ++nLen )
+ {
+ OSL_ENSURE( sal_False, "The size must be the same!\n" );
+ aNames.realloc( nLen );
+ }
+
+ aNames[nLen-1] = (*aIter).second.sPath;
+ }
+
+ if ( aNames.getLength() != nLen )
+ {
+ OSL_ENSURE( sal_False, "The size must be the same!\n" );
+ aNames.realloc( nLen );
+ }
+
+ return aNames;
+}
+
+// ----------------------------------------------------------------
+sal_Bool SAL_CALL OZipFileAccess::hasByName( const ::rtl::OUString& aName )
+ throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !m_pZipFile )
+ throw io::NotConnectedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ EntryHash::iterator aIter = m_pZipFile->GetEntryHash().find( aName );
+
+ return ( aIter != m_pZipFile->GetEntryHash().end() );
+}
+
+// ----------------------------------------------------------------
+uno::Type SAL_CALL OZipFileAccess::getElementType()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !m_pZipFile )
+ throw io::NotConnectedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return getCppuType( ( const uno::Reference< io::XInputStream >* )NULL );
+}
+
+// ----------------------------------------------------------------
+sal_Bool SAL_CALL OZipFileAccess::hasElements()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !m_pZipFile )
+ throw io::NotConnectedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return ( m_pZipFile->GetEntryHash().size() != 0 );
+}
+
+// XZipFileAccess
+// ----------------------------------------------------------------
+uno::Reference< io::XInputStream > SAL_CALL OZipFileAccess::getStreamByPattern( const ::rtl::OUString& aPatternString )
+ throw ( container::NoSuchElementException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !m_pZipFile )
+ throw io::NotConnectedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // Code to compare strings by patterns
+ uno::Sequence< ::rtl::OUString > aPattern = GetPatternsFromString_Impl( aPatternString );
+
+ for ( EntryHash::iterator aIter = m_pZipFile->GetEntryHash().begin(); aIter != m_pZipFile->GetEntryHash().end(); aIter++ )
+ {
+ if ( StringGoodForPattern_Impl( (*aIter).second.sPath, aPattern ) )
+ {
+ uno::Reference< io::XInputStream > xEntryStream( m_pZipFile->getDataStream( (*aIter).second,
+ new EncryptionData(),
+ sal_False,
+ m_aMutexHolder ) );
+
+ if ( !xEntryStream.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ return xEntryStream;
+ }
+ }
+
+ throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+// XComponent
+// ----------------------------------------------------------------
+void SAL_CALL OZipFileAccess::dispose()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( m_pListenersContainer )
+ {
+ lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
+ m_pListenersContainer->disposeAndClear( aSource );
+ delete m_pListenersContainer;
+ m_pListenersContainer = NULL;
+ }
+
+ if ( m_pZipFile )
+ {
+ delete m_pZipFile;
+ m_pZipFile = NULL;
+ }
+
+ if ( m_xContentStream.is() )
+ try {
+ m_xContentStream->closeInput();
+ } catch( uno::Exception& )
+ {}
+
+ m_bDisposed = sal_True;
+}
+
+// ----------------------------------------------------------------
+void SAL_CALL OZipFileAccess::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( !m_pListenersContainer )
+ m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutexHolder->GetMutex() );
+ m_pListenersContainer->addInterface( xListener );
+}
+
+// ----------------------------------------------------------------
+void SAL_CALL OZipFileAccess::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if ( m_pListenersContainer )
+ m_pListenersContainer->removeInterface( xListener );
+}
+
+//-------------------------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL OZipFileAccess::impl_staticGetSupportedServiceNames()
+{
+ uno::Sequence< ::rtl::OUString > aRet(2);
+ aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.packages.zip.ZipFileAccess");
+ aRet[1] = ::rtl::OUString::createFromAscii("com.sun.star.comp.packages.zip.ZipFileAccess");
+ return aRet;
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OZipFileAccess::impl_staticGetImplementationName()
+{
+ return ::rtl::OUString::createFromAscii("com.sun.star.comp.package.zip.ZipFileAccess");
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< uno::XInterface > SAL_CALL OZipFileAccess::impl_staticCreateSelfInstance(
+ const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
+{
+ return uno::Reference< uno::XInterface >( *new OZipFileAccess( xServiceManager ) );
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OZipFileAccess::getImplementationName()
+ throw ( uno::RuntimeException )
+{
+ return impl_staticGetImplementationName();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL OZipFileAccess::supportsService( const ::rtl::OUString& ServiceName )
+ throw ( uno::RuntimeException )
+{
+ uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();
+
+ for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
+ if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
+ return sal_True;
+
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL OZipFileAccess::getSupportedServiceNames()
+ throw ( uno::RuntimeException )
+{
+ return impl_staticGetSupportedServiceNames();
+}
+
diff --git a/package/util/exports.dxp b/package/util/exports.dxp
new file mode 100644
index 000000000000..9630d7e06768
--- /dev/null
+++ b/package/util/exports.dxp
@@ -0,0 +1,3 @@
+component_getImplementationEnvironment
+component_writeInfo
+component_getFactory
diff --git a/package/util/makefile.mk b/package/util/makefile.mk
new file mode 100644
index 000000000000..20732c102007
--- /dev/null
+++ b/package/util/makefile.mk
@@ -0,0 +1,77 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+# 2 == Unicode
+MAJOR_VERSION=2
+
+PRJ=..
+PRJNAME=package
+TARGET=package
+
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+NO_BSYMBOLIC=TRUE
+
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.IF "$(L10N_framework)"==""
+
+# --- General ----------------------------------------------------
+
+LIB1TARGET= $(SLB)$/$(TARGET).lib
+LIB1FILES= \
+ $(SLB)$/zipapi.lib \
+ $(SLB)$/zippackage.lib \
+ $(SLB)$/manifest.lib
+
+# --- Shared-Library -----------------------------------------------
+
+SHL1TARGET=$(TARGET)$(MAJOR_VERSION)
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=$(SOLARENV)$/src$/component.map
+
+SHL1STDLIBS=\
+ $(CPPULIB) \
+ $(UCBHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(SALLIB) \
+ $(ZLIB3RDLIB)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1LIBS=$(LIB1TARGET)
+DEF1NAME=$(SHL1TARGET)
+
+.ENDIF # L10N_framework
+
+# --- Targets ----------------------------------------------------------
+
+.INCLUDE : target.mk
+