update dev300-m58
[ooovba.git] / package / source / zippackage / ZipPackageStream.cxx
blobc82759b3e037e6a6db90382d59bb382982c77f30
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ZipPackageStream.cxx,v $
10 * $Revision: 1.51 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_package.hxx"
33 #include <com/sun/star/packages/zip/ZipConstants.hpp>
34 #include <com/sun/star/packages/zip/ZipIOException.hpp>
35 #include <com/sun/star/io/XInputStream.hpp>
36 #include <com/sun/star/io/XOutputStream.hpp>
37 #include <com/sun/star/io/XStream.hpp>
38 #include <com/sun/star/io/XSeekable.hpp>
41 #include <ZipPackageStream.hxx>
42 #include <ZipPackage.hxx>
43 #include <ZipFile.hxx>
44 #include <EncryptedDataHeader.hxx>
45 #include <vos/diagnose.hxx>
46 #include "wrapstreamforshare.hxx"
48 #include <comphelper/seekableinput.hxx>
49 #include <comphelper/storagehelper.hxx>
51 #include <PackageConstants.hxx>
53 using namespace com::sun::star::packages::zip::ZipConstants;
54 using namespace com::sun::star::packages::zip;
55 using namespace com::sun::star::uno;
56 using namespace com::sun::star::lang;
57 using namespace com::sun::star;
58 using namespace cppu;
59 using namespace rtl;
61 Sequence < sal_Int8 > ZipPackageStream::aImplementationId = Sequence < sal_Int8 > ();
64 ZipPackageStream::ZipPackageStream ( ZipPackage & rNewPackage,
65 const Reference< XMultiServiceFactory >& xFactory,
66 sal_Bool bAllowRemoveOnInsert )
67 : m_xFactory( xFactory )
68 , rZipPackage(rNewPackage)
69 , bToBeCompressed ( sal_True )
70 , bToBeEncrypted ( sal_False )
71 , bHaveOwnKey ( sal_False )
72 , bIsEncrypted ( sal_False )
73 , xEncryptionData ( )
74 , m_nStreamMode( PACKAGE_STREAM_NOTSET )
75 , m_nMagicalHackPos( 0 )
76 , m_nMagicalHackSize( 0 )
77 , m_bHasSeekable( sal_False )
78 , m_bCompressedIsSetFromOutside( sal_False )
80 OSL_ENSURE( m_xFactory.is(), "No factory is provided to ZipPackageStream!\n" );
82 this->mbAllowRemoveOnInsert = bAllowRemoveOnInsert;
84 SetFolder ( sal_False );
85 aEntry.nVersion = -1;
86 aEntry.nFlag = 0;
87 aEntry.nMethod = -1;
88 aEntry.nTime = -1;
89 aEntry.nCrc = -1;
90 aEntry.nCompressedSize = -1;
91 aEntry.nSize = -1;
92 aEntry.nOffset = -1;
93 aEntry.nNameLen = -1;
94 aEntry.nExtraLen = -1;
96 if ( !aImplementationId.getLength() )
98 aImplementationId = getImplementationId();
102 ZipPackageStream::~ZipPackageStream( void )
106 void ZipPackageStream::setZipEntryOnLoading( const ZipEntry &rInEntry)
108 aEntry.nVersion = rInEntry.nVersion;
109 aEntry.nFlag = rInEntry.nFlag;
110 aEntry.nMethod = rInEntry.nMethod;
111 aEntry.nTime = rInEntry.nTime;
112 aEntry.nCrc = rInEntry.nCrc;
113 aEntry.nCompressedSize = rInEntry.nCompressedSize;
114 aEntry.nSize = rInEntry.nSize;
115 aEntry.nOffset = rInEntry.nOffset;
116 aEntry.sName = rInEntry.sName;
117 aEntry.nNameLen = rInEntry.nNameLen;
118 aEntry.nExtraLen = rInEntry.nExtraLen;
120 if ( aEntry.nMethod == STORED )
121 bToBeCompressed = sal_False;
124 //--------------------------------------------------------------------------
125 void ZipPackageStream::CloseOwnStreamIfAny()
127 if ( xStream.is() )
129 xStream->closeInput();
130 xStream = uno::Reference< io::XInputStream >();
131 m_bHasSeekable = sal_False;
135 //--------------------------------------------------------------------------
136 uno::Reference< io::XInputStream >& ZipPackageStream::GetOwnSeekStream()
138 if ( !m_bHasSeekable && xStream.is() )
140 // The package component requires that every stream either be FROM a package or it must support XSeekable!
141 // The only exception is a nonseekable stream that is provided only for storing, if such a stream
142 // is accessed before commit it MUST be wrapped.
143 // Wrap the stream in case it is not seekable
144 xStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( xStream, m_xFactory );
145 Reference< io::XSeekable > xSeek( xStream, UNO_QUERY );
146 if ( !xSeek.is() )
147 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "The stream must support XSeekable!" ) ),
148 Reference< XInterface >() );
150 m_bHasSeekable = sal_True;
153 return xStream;
156 //--------------------------------------------------------------------------
157 uno::Reference< io::XInputStream > ZipPackageStream::GetRawEncrStreamNoHeaderCopy()
159 if ( m_nStreamMode != PACKAGE_STREAM_RAW || !GetOwnSeekStream().is() )
160 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
162 if ( xEncryptionData.isEmpty() )
163 throw ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Encrypted stream without encryption data!\n" ) ),
164 Reference< XInterface >() );
166 uno::Reference< io::XSeekable > xSeek( GetOwnSeekStream(), UNO_QUERY );
167 if ( !xSeek.is() )
168 throw ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "The stream must be seekable!\n" ) ),
169 Reference< XInterface >() );
171 // skip header
172 xSeek->seek( n_ConstHeaderSize + xEncryptionData->aInitVector.getLength() +
173 xEncryptionData->aSalt.getLength() + xEncryptionData->aDigest.getLength() );
175 // create temporary stream
176 uno::Reference < io::XOutputStream > xTempOut(
177 m_xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
178 uno::UNO_QUERY );
179 uno::Reference < io::XInputStream > xTempIn( xTempOut, UNO_QUERY );
180 uno::Reference < io::XSeekable > xTempSeek( xTempOut, UNO_QUERY );
181 if ( !xTempOut.is() || !xTempIn.is() || !xTempSeek.is() )
182 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
184 // copy the raw stream to the temporary file starting from the current position
185 ::comphelper::OStorageHelper::CopyInputToOutput( GetOwnSeekStream(), xTempOut );
186 xTempOut->closeOutput();
187 xTempSeek->seek( 0 );
189 return xTempIn;
192 //--------------------------------------------------------------------------
193 Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream( sal_Bool bAddHeaderForEncr )
195 if ( m_nStreamMode != PACKAGE_STREAM_DATA || !GetOwnSeekStream().is() || (bAddHeaderForEncr && !bToBeEncrypted) )
196 throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
198 Sequence< sal_Int8 > aKey;
200 if ( bToBeEncrypted )
202 aKey = ( xEncryptionData.isEmpty() || !bHaveOwnKey ) ? rZipPackage.getEncryptionKey() :
203 xEncryptionData->aKey;
204 if ( !aKey.getLength() )
205 throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
210 // create temporary file
211 uno::Reference < io::XStream > xTempStream(
212 m_xFactory->createInstance ( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
213 uno::UNO_QUERY );
214 if ( !xTempStream.is() )
215 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
217 // create a package based on it
218 ZipPackage* pPackage = new ZipPackage( m_xFactory );
219 Reference< XSingleServiceFactory > xPackageAsFactory( static_cast< XSingleServiceFactory* >( pPackage ) );
220 if ( !xPackageAsFactory.is() )
221 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
223 Sequence< Any > aArgs( 1 );
224 aArgs[0] <<= xTempStream;
225 pPackage->initialize( aArgs );
227 // create a new package stream
228 Reference< XDataSinkEncrSupport > xNewPackStream( xPackageAsFactory->createInstance(), UNO_QUERY );
229 if ( !xNewPackStream.is() )
230 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
232 xNewPackStream->setDataStream( static_cast< io::XInputStream* >(
233 new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() ) ) );
235 Reference< XPropertySet > xNewPSProps( xNewPackStream, UNO_QUERY );
236 if ( !xNewPSProps.is() )
237 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
239 // copy all the properties of this stream to the new stream
240 xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ), makeAny( sMediaType ) );
241 xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) ), makeAny( bToBeCompressed ) );
242 if ( bToBeEncrypted )
244 xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionKey" ) ), makeAny( aKey ) );
245 xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Encrypted" ) ), makeAny( sal_True ) );
248 // insert a new stream in the package
249 Reference< XUnoTunnel > xTunnel;
250 Any aRoot = pPackage->getByHierarchicalName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ) );
251 aRoot >>= xTunnel;
252 Reference< container::XNameContainer > xRootNameContainer( xTunnel, UNO_QUERY );
253 if ( !xRootNameContainer.is() )
254 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
256 Reference< XUnoTunnel > xNPSTunnel( xNewPackStream, UNO_QUERY );
257 xRootNameContainer->insertByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "dummy" ) ), makeAny( xNPSTunnel ) );
259 // commit the temporary package
260 pPackage->commitChanges();
262 // get raw stream from the temporary package
263 Reference< io::XInputStream > xInRaw;
264 if ( bAddHeaderForEncr )
265 xInRaw = xNewPackStream->getRawStream();
266 else
267 xInRaw = xNewPackStream->getPlainRawStream();
269 // create another temporary file
270 uno::Reference < io::XOutputStream > xTempOut(
271 m_xFactory->createInstance ( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
272 uno::UNO_QUERY );
273 uno::Reference < io::XInputStream > xTempIn( xTempOut, UNO_QUERY );
274 uno::Reference < io::XSeekable > xTempSeek( xTempOut, UNO_QUERY );
275 if ( !xTempOut.is() || !xTempIn.is() || !xTempSeek.is() )
276 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
278 // copy the raw stream to the temporary file
279 ::comphelper::OStorageHelper::CopyInputToOutput( xInRaw, xTempOut );
280 xTempOut->closeOutput();
281 xTempSeek->seek( 0 );
283 // close raw stream, package stream and folder
284 xInRaw = Reference< io::XInputStream >();
285 xNewPSProps = Reference< XPropertySet >();
286 xNPSTunnel = Reference< XUnoTunnel >();
287 xNewPackStream = Reference< XDataSinkEncrSupport >();
288 xTunnel = Reference< XUnoTunnel >();
289 xRootNameContainer = Reference< container::XNameContainer >();
291 // return the stream representing the first temporary file
292 return xTempIn;
294 catch ( RuntimeException& )
296 throw;
298 catch ( Exception& )
302 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
305 //--------------------------------------------------------------------------
306 sal_Bool ZipPackageStream::ParsePackageRawStream()
308 OSL_ENSURE( GetOwnSeekStream().is(), "A stream must be provided!\n" );
310 if ( !GetOwnSeekStream().is() )
311 return sal_False;
313 sal_Bool bOk = sal_False;
315 vos::ORef < EncryptionData > xTempEncrData;
316 sal_Int32 nMagHackSize = 0;
317 Sequence < sal_Int8 > aHeader ( 4 );
319 try
321 if ( GetOwnSeekStream()->readBytes ( aHeader, 4 ) == 4 )
323 const sal_Int8 *pHeader = aHeader.getConstArray();
324 sal_uInt32 nHeader = ( pHeader [0] & 0xFF ) |
325 ( pHeader [1] & 0xFF ) << 8 |
326 ( pHeader [2] & 0xFF ) << 16 |
327 ( pHeader [3] & 0xFF ) << 24;
328 if ( nHeader == n_ConstHeader )
330 // this is one of our god-awful, but extremely devious hacks, everyone cheer
331 xTempEncrData = new EncryptionData;
333 ::rtl::OUString aMediaType;
334 if ( ZipFile::StaticFillData ( xTempEncrData, nMagHackSize, aMediaType, GetOwnSeekStream() ) )
336 // We'll want to skip the data we've just read, so calculate how much we just read
337 // and remember it
338 m_nMagicalHackPos = n_ConstHeaderSize + xTempEncrData->aSalt.getLength()
339 + xTempEncrData->aInitVector.getLength()
340 + xTempEncrData->aDigest.getLength()
341 + aMediaType.getLength() * sizeof( sal_Unicode );
342 m_nMagicalHackSize = nMagHackSize;
343 sMediaType = aMediaType;
345 bOk = sal_True;
350 catch( Exception& )
354 if ( !bOk )
356 // the provided stream is not a raw stream
357 return sal_False;
360 xEncryptionData = xTempEncrData;
361 SetIsEncrypted ( sal_True );
362 // it's already compressed and encrypted
363 bToBeEncrypted = bToBeCompressed = sal_False;
365 return sal_True;
368 void ZipPackageStream::SetPackageMember( sal_Bool bNewValue )
370 if ( bNewValue )
372 m_nStreamMode = PACKAGE_STREAM_PACKAGEMEMBER;
373 m_nMagicalHackPos = 0;
374 m_nMagicalHackSize = 0;
376 else if ( m_nStreamMode == PACKAGE_STREAM_PACKAGEMEMBER )
377 m_nStreamMode = PACKAGE_STREAM_NOTSET; // must be reset
380 // XActiveDataSink
381 //--------------------------------------------------------------------------
382 void SAL_CALL ZipPackageStream::setInputStream( const Reference< io::XInputStream >& aStream )
383 throw(RuntimeException)
385 // if seekable access is required the wrapping will be done on demand
386 xStream = aStream;
387 m_bHasSeekable = sal_False;
388 SetPackageMember ( sal_False );
389 aEntry.nTime = -1;
390 m_nStreamMode = PACKAGE_STREAM_DETECT;
393 //--------------------------------------------------------------------------
394 Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawData()
395 throw(RuntimeException)
399 if (IsPackageMember())
401 if ( !xEncryptionData.isEmpty() && !bHaveOwnKey )
402 xEncryptionData->aKey = rZipPackage.getEncryptionKey();
403 return rZipPackage.getZipFile().getRawData( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() );
405 else if ( GetOwnSeekStream().is() )
407 return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
409 else
410 return Reference < io::XInputStream > ();
412 catch (ZipException &)//rException)
414 VOS_ENSURE( 0, "ZipException thrown");//rException.Message);
415 return Reference < io::XInputStream > ();
417 catch (Exception &)
419 VOS_ENSURE( 0, "Exception is thrown during stream wrapping!\n");
420 return Reference < io::XInputStream > ();
424 //--------------------------------------------------------------------------
425 Reference< io::XInputStream > SAL_CALL ZipPackageStream::getInputStream( )
426 throw(RuntimeException)
430 if (IsPackageMember())
432 if ( !xEncryptionData.isEmpty() && !bHaveOwnKey )
433 xEncryptionData->aKey = rZipPackage.getEncryptionKey();
434 return rZipPackage.getZipFile().getInputStream( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() );
436 else if ( GetOwnSeekStream().is() )
438 return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
440 else
441 return Reference < io::XInputStream > ();
443 catch (ZipException &)//rException)
445 VOS_ENSURE( 0,"ZipException thrown");//rException.Message);
446 return Reference < io::XInputStream > ();
448 catch (Exception &)
450 VOS_ENSURE( 0, "Exception is thrown during stream wrapping!\n");
451 return Reference < io::XInputStream > ();
455 // XDataSinkEncrSupport
456 //--------------------------------------------------------------------------
457 Reference< io::XInputStream > SAL_CALL ZipPackageStream::getDataStream()
458 throw ( packages::WrongPasswordException,
459 io::IOException,
460 RuntimeException )
462 // There is no stream attached to this object
463 if ( m_nStreamMode == PACKAGE_STREAM_NOTSET )
464 return Reference< io::XInputStream >();
466 // this method can not be used together with old approach
467 if ( m_nStreamMode == PACKAGE_STREAM_DETECT )
468 throw packages::zip::ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
470 if ( !xEncryptionData.isEmpty() && !bHaveOwnKey )
471 xEncryptionData->aKey = rZipPackage.getEncryptionKey();
473 if (IsPackageMember())
475 if ( !xEncryptionData.isEmpty() && !bHaveOwnKey )
476 xEncryptionData->aKey = rZipPackage.getEncryptionKey();
478 return rZipPackage.getZipFile().getDataStream( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() );
480 else if ( m_nStreamMode == PACKAGE_STREAM_RAW )
481 return ZipFile::StaticGetDataFromRawStream( GetOwnSeekStream(), xEncryptionData );
482 else if ( GetOwnSeekStream().is() )
484 return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
486 else
487 return uno::Reference< io::XInputStream >();
490 //--------------------------------------------------------------------------
491 Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawStream()
492 throw ( packages::NoEncryptionException,
493 io::IOException,
494 uno::RuntimeException )
496 // There is no stream attached to this object
497 if ( m_nStreamMode == PACKAGE_STREAM_NOTSET )
498 return Reference< io::XInputStream >();
500 // this method can not be used together with old approach
501 if ( m_nStreamMode == PACKAGE_STREAM_DETECT )
502 throw packages::zip::ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
504 if (IsPackageMember())
506 if ( !bIsEncrypted || xEncryptionData.isEmpty() )
507 throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
509 return rZipPackage.getZipFile().getWrappedRawStream( aEntry, xEncryptionData, sMediaType, rZipPackage.GetSharedMutexRef() );
511 else if ( GetOwnSeekStream().is() )
513 if ( m_nStreamMode == PACKAGE_STREAM_RAW )
515 return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
517 else if ( m_nStreamMode == PACKAGE_STREAM_DATA && bToBeEncrypted )
518 return TryToGetRawFromDataStream( sal_True );
521 throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
525 //--------------------------------------------------------------------------
526 void SAL_CALL ZipPackageStream::setDataStream( const Reference< io::XInputStream >& aStream )
527 throw ( io::IOException,
528 RuntimeException )
530 setInputStream( aStream );
531 m_nStreamMode = PACKAGE_STREAM_DATA;
534 //--------------------------------------------------------------------------
535 void SAL_CALL ZipPackageStream::setRawStream( const Reference< io::XInputStream >& aStream )
536 throw ( packages::EncryptionNotAllowedException,
537 packages::NoRawFormatException,
538 io::IOException,
539 RuntimeException)
541 // wrap the stream in case it is not seekable
542 Reference< io::XInputStream > xNewStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( aStream, m_xFactory );
543 Reference< io::XSeekable > xSeek( xNewStream, UNO_QUERY );
544 if ( !xSeek.is() )
545 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "The stream must support XSeekable!" ) ),
546 Reference< XInterface >() );
548 xSeek->seek( 0 );
549 Reference< io::XInputStream > xOldStream = xStream;
550 xStream = xNewStream;
551 if ( !ParsePackageRawStream() )
553 xStream = xOldStream;
554 throw packages::NoRawFormatException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
557 // the raw stream MUST have seekable access
558 m_bHasSeekable = sal_True;
560 SetPackageMember ( sal_False );
561 aEntry.nTime = -1;
562 m_nStreamMode = PACKAGE_STREAM_RAW;
565 //--------------------------------------------------------------------------
566 uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getPlainRawStream()
567 throw ( io::IOException,
568 uno::RuntimeException )
570 // There is no stream attached to this object
571 if ( m_nStreamMode == PACKAGE_STREAM_NOTSET )
572 return Reference< io::XInputStream >();
574 // this method can not be used together with old approach
575 if ( m_nStreamMode == PACKAGE_STREAM_DETECT )
576 throw packages::zip::ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
578 if (IsPackageMember())
580 return rZipPackage.getZipFile().getRawData( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() );
582 else if ( GetOwnSeekStream().is() )
584 if ( m_nStreamMode == PACKAGE_STREAM_RAW )
586 // the header should not be returned here
587 return GetRawEncrStreamNoHeaderCopy();
589 else if ( m_nStreamMode == PACKAGE_STREAM_DATA )
590 return TryToGetRawFromDataStream( sal_False );
593 return Reference< io::XInputStream >();
596 // XUnoTunnel
598 //--------------------------------------------------------------------------
599 sal_Int64 SAL_CALL ZipPackageStream::getSomething( const Sequence< sal_Int8 >& aIdentifier )
600 throw(RuntimeException)
602 sal_Int64 nMe = 0;
603 if ( aIdentifier.getLength() == 16 &&
604 0 == rtl_compareMemory( static_getImplementationId().getConstArray(), aIdentifier.getConstArray(), 16 ) )
605 nMe = reinterpret_cast < sal_Int64 > ( this );
606 return nMe;
609 // XPropertySet
610 //--------------------------------------------------------------------------
611 void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
612 throw(beans::UnknownPropertyException, beans::PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
614 if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("MediaType")))
616 if ( rZipPackage.getFormat() != PACKAGE_FORMAT && rZipPackage.getFormat() != OFOPXML_FORMAT )
617 throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
619 if ( aValue >>= sMediaType )
621 if (sMediaType.getLength() > 0)
623 if ( sMediaType.indexOf (OUString( RTL_CONSTASCII_USTRINGPARAM ( "text" ) ) ) != -1
624 || sMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM ( "application/vnd.sun.star.oleobject" ) ) ) )
625 bToBeCompressed = sal_True;
626 else if ( !m_bCompressedIsSetFromOutside )
627 bToBeCompressed = sal_False;
630 else
631 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "MediaType must be a string!\n" ) ),
632 Reference< XInterface >(),
633 2 );
636 else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Size") ) )
638 if ( !( aValue >>= aEntry.nSize ) )
639 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for Size property!\n" ) ),
640 Reference< XInterface >(),
641 2 );
643 else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Encrypted") ) )
645 if ( rZipPackage.getFormat() != PACKAGE_FORMAT )
646 throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
648 sal_Bool bEnc = sal_False;
649 if ( aValue >>= bEnc )
651 // In case of new raw stream, the stream must not be encrypted on storing
652 if ( bEnc && m_nStreamMode == PACKAGE_STREAM_RAW )
653 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Raw stream can not be encrypted on storing" ) ),
654 Reference< XInterface >(),
655 2 );
657 bToBeEncrypted = bEnc;
658 if ( bToBeEncrypted && xEncryptionData.isEmpty())
659 xEncryptionData = new EncryptionData;
661 else
662 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for Encrypted property!\n" ) ),
663 Reference< XInterface >(),
664 2 );
667 else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("EncryptionKey") ) )
669 if ( rZipPackage.getFormat() != PACKAGE_FORMAT )
670 throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
672 Sequence < sal_Int8 > aNewKey;
674 if ( !( aValue >>= aNewKey ) )
676 OUString sTempString;
677 if ( ( aValue >>= sTempString ) )
679 sal_Int32 nNameLength = sTempString.getLength();
680 Sequence < sal_Int8 > aSequence ( nNameLength );
681 sal_Int8 *pArray = aSequence.getArray();
682 const sal_Unicode *pChar = sTempString.getStr();
683 for ( sal_Int16 i = 0; i < nNameLength; i++)
684 pArray[i] = static_cast < const sal_Int8 > (pChar[i]);
685 aNewKey = aSequence;
687 else
688 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for EncryptionKey property!\n" ) ),
689 Reference< XInterface >(),
690 2 );
693 if ( aNewKey.getLength() )
695 if ( xEncryptionData.isEmpty())
696 xEncryptionData = new EncryptionData;
698 xEncryptionData->aKey = aNewKey;
699 // In case of new raw stream, the stream must not be encrypted on storing
700 bHaveOwnKey = sal_True;
701 if ( m_nStreamMode != PACKAGE_STREAM_RAW )
702 bToBeEncrypted = sal_True;
704 else
705 bHaveOwnKey = sal_False;
707 else if (aPropertyName.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "Compressed" ) ) )
709 sal_Bool bCompr = sal_False;
711 if ( aValue >>= bCompr )
713 // In case of new raw stream, the stream must not be encrypted on storing
714 if ( bCompr && m_nStreamMode == PACKAGE_STREAM_RAW )
715 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Raw stream can not be encrypted on storing" ) ),
716 Reference< XInterface >(),
717 2 );
719 bToBeCompressed = bCompr;
720 m_bCompressedIsSetFromOutside = sal_True;
722 else
723 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for Compressed property!\n" ) ),
724 Reference< XInterface >(),
725 2 );
727 else
728 throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
731 //--------------------------------------------------------------------------
732 Any SAL_CALL ZipPackageStream::getPropertyValue( const OUString& PropertyName )
733 throw(beans::UnknownPropertyException, WrappedTargetException, RuntimeException)
735 Any aAny;
736 if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) )
738 aAny <<= sMediaType;
739 return aAny;
741 else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Size" ) ) )
743 aAny <<= aEntry.nSize;
744 return aAny;
746 else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Encrypted" ) ) )
748 aAny <<= ( m_nStreamMode == PACKAGE_STREAM_RAW ) ? sal_True : bToBeEncrypted;
749 return aAny;
751 else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "WasEncrypted" ) ) )
753 aAny <<= bIsEncrypted;
754 return aAny;
756 else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Compressed" ) ) )
758 aAny <<= bToBeCompressed;
759 return aAny;
761 else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "EncryptionKey" ) ) )
763 aAny <<= xEncryptionData.isEmpty () ? Sequence < sal_Int8 > () : xEncryptionData->aKey;
764 return aAny;
766 else
767 throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
770 //--------------------------------------------------------------------------
771 void ZipPackageStream::setSize (const sal_Int32 nNewSize)
773 if (aEntry.nCompressedSize != nNewSize )
774 aEntry.nMethod = DEFLATED;
775 aEntry.nSize = nNewSize;
777 //--------------------------------------------------------------------------
778 OUString ZipPackageStream::getImplementationName()
779 throw (RuntimeException)
781 return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "ZipPackageStream" ) );
784 //--------------------------------------------------------------------------
785 Sequence< OUString > ZipPackageStream::getSupportedServiceNames()
786 throw (RuntimeException)
788 Sequence< OUString > aNames(1);
789 aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.PackageStream" ) );
790 return aNames;
792 //--------------------------------------------------------------------------
793 sal_Bool SAL_CALL ZipPackageStream::supportsService( OUString const & rServiceName )
794 throw (RuntimeException)
796 return rServiceName == getSupportedServiceNames()[0];