1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ZipPackageStream.cxx,v $
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
;
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
)
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
);
90 aEntry
.nCompressedSize
= -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()
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
);
147 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"The stream must support XSeekable!" ) ),
148 Reference
< XInterface
>() );
150 m_bHasSeekable
= sal_True
;
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
);
168 throw ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"The stream must be seekable!\n" ) ),
169 Reference
< XInterface
>() );
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" ) ) ),
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 );
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" ) ) ),
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( "/" ) ) );
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();
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" ) ) ),
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
294 catch ( RuntimeException
& )
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() )
313 sal_Bool bOk
= sal_False
;
315 vos::ORef
< EncryptionData
> xTempEncrData
;
316 sal_Int32 nMagHackSize
= 0;
317 Sequence
< sal_Int8
> aHeader ( 4 );
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
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
;
356 // the provided stream is not a raw stream
360 xEncryptionData
= xTempEncrData
;
361 SetIsEncrypted ( sal_True
);
362 // it's already compressed and encrypted
363 bToBeEncrypted
= bToBeCompressed
= sal_False
;
368 void ZipPackageStream::SetPackageMember( sal_Bool 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
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
387 m_bHasSeekable
= sal_False
;
388 SetPackageMember ( sal_False
);
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() );
410 return Reference
< io::XInputStream
> ();
412 catch (ZipException
&)//rException)
414 VOS_ENSURE( 0, "ZipException thrown");//rException.Message);
415 return Reference
< io::XInputStream
> ();
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() );
441 return Reference
< io::XInputStream
> ();
443 catch (ZipException
&)//rException)
445 VOS_ENSURE( 0,"ZipException thrown");//rException.Message);
446 return Reference
< io::XInputStream
> ();
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
,
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() );
487 return uno::Reference
< io::XInputStream
>();
490 //--------------------------------------------------------------------------
491 Reference
< io::XInputStream
> SAL_CALL
ZipPackageStream::getRawStream()
492 throw ( packages::NoEncryptionException
,
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
,
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
,
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
);
545 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"The stream must support XSeekable!" ) ),
546 Reference
< XInterface
>() );
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
);
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
>();
598 //--------------------------------------------------------------------------
599 sal_Int64 SAL_CALL
ZipPackageStream::getSomething( const Sequence
< sal_Int8
>& aIdentifier
)
600 throw(RuntimeException
)
603 if ( aIdentifier
.getLength() == 16 &&
604 0 == rtl_compareMemory( static_getImplementationId().getConstArray(), aIdentifier
.getConstArray(), 16 ) )
605 nMe
= reinterpret_cast < sal_Int64
> ( this );
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
;
631 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"MediaType must be a string!\n" ) ),
632 Reference
< XInterface
>(),
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
>(),
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
>(),
657 bToBeEncrypted
= bEnc
;
658 if ( bToBeEncrypted
&& xEncryptionData
.isEmpty())
659 xEncryptionData
= new EncryptionData
;
662 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Wrong type for Encrypted property!\n" ) ),
663 Reference
< XInterface
>(),
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
]);
688 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Wrong type for EncryptionKey property!\n" ) ),
689 Reference
< XInterface
>(),
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
;
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
>(),
719 bToBeCompressed
= bCompr
;
720 m_bCompressedIsSetFromOutside
= sal_True
;
723 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Wrong type for Compressed property!\n" ) ),
724 Reference
< XInterface
>(),
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
)
736 if (PropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) )
741 else if (PropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Size" ) ) )
743 aAny
<<= aEntry
.nSize
;
746 else if (PropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Encrypted" ) ) )
748 aAny
<<= ( m_nStreamMode
== PACKAGE_STREAM_RAW
) ? sal_True
: bToBeEncrypted
;
751 else if (PropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "WasEncrypted" ) ) )
753 aAny
<<= bIsEncrypted
;
756 else if (PropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Compressed" ) ) )
758 aAny
<<= bToBeCompressed
;
761 else if (PropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "EncryptionKey" ) ) )
763 aAny
<<= xEncryptionData
.isEmpty () ? Sequence
< sal_Int8
> () : xEncryptionData
->aKey
;
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" ) );
792 //--------------------------------------------------------------------------
793 sal_Bool SAL_CALL
ZipPackageStream::supportsService( OUString
const & rServiceName
)
794 throw (RuntimeException
)
796 return rServiceName
== getSupportedServiceNames()[0];