/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the 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 <com/sun/star/xml/crypto/DigestID.hpp>
#include <com/sun/star/xml/crypto/CipherID.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 <rtl/instance.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;

namespace { struct lcl_CachedImplId : public rtl::Static< Sequence < sal_Int8 >, lcl_CachedImplId > {}; }

const ::com::sun::star::uno::Sequence < sal_Int8 >& ZipPackageStream::static_getImplementationId()
{
    return lcl_CachedImplId::get();
}

ZipPackageStream::ZipPackageStream ( ZipPackage & rNewPackage,
									const uno::Reference< XMultiServiceFactory >& xFactory,
									sal_Bool bAllowRemoveOnInsert ) 
: m_xFactory( xFactory )
, rZipPackage( rNewPackage )
, bToBeCompressed ( sal_True )
, bToBeEncrypted ( sal_False )
, bHaveOwnKey ( sal_False )
, bIsEncrypted ( sal_False )
, m_nImportedStartKeyAlgorithm( 0 )
, m_nImportedEncryptionAlgorithm( 0 )
, m_nImportedChecksumAlgorithm( 0 )
, m_nImportedDerivedKeySize( 0 )
, m_nStreamMode( PACKAGE_STREAM_NOTSET )
, m_nMagicalHackPos( 0 )
, m_nMagicalHackSize( 0 )
, m_bHasSeekable( sal_False )
, m_bCompressedIsSetFromOutside( sal_False )
, m_bFromManifest( sal_False )
, m_bUseWinEncoding( 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;

	Sequence < sal_Int8 > &rCachedImplId = lcl_CachedImplId::get();
	if ( !rCachedImplId.getLength() )
	    rCachedImplId = 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 );
		uno::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!" ) ),
									uno::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 ( m_xBaseEncryptionData.is() )
		throw ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Encrypted stream without encryption data!\n" ) ),
							uno::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" ) ),
							uno::Reference< XInterface >() );

	// skip header
	xSeek->seek( n_ConstHeaderSize + getInitialisationVector().getLength() + 
					getSalt().getLength() + getDigest().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;
}

//--------------------------------------------------------------------------
sal_Int32 ZipPackageStream::GetEncryptionAlgorithm() const
{
    return m_nImportedEncryptionAlgorithm ? m_nImportedEncryptionAlgorithm : rZipPackage.GetEncAlgID();
}

//--------------------------------------------------------------------------
sal_Int32 ZipPackageStream::GetBlockSize() const
{
    return GetEncryptionAlgorithm() == ::com::sun::star::xml::crypto::CipherID::AES_CBC_W3C_PADDING ? 16 : 8;
}

//--------------------------------------------------------------------------
::rtl::Reference< EncryptionData > ZipPackageStream::GetEncryptionData( bool bUseWinEncoding )
{
    ::rtl::Reference< EncryptionData > xResult;
    if ( m_xBaseEncryptionData.is() )
        xResult = new EncryptionData( 
            *m_xBaseEncryptionData,
            GetEncryptionKey( bUseWinEncoding ),
            GetEncryptionAlgorithm(),
            m_nImportedChecksumAlgorithm ? m_nImportedChecksumAlgorithm : rZipPackage.GetChecksumAlgID(),
            m_nImportedDerivedKeySize ? m_nImportedDerivedKeySize : rZipPackage.GetDefaultDerivedKeySize(),
            GetStartKeyGenID() );

    return xResult;
}

//--------------------------------------------------------------------------
void ZipPackageStream::SetBaseEncryptionData( const ::rtl::Reference< BaseEncryptionData >& xData )
{
    m_xBaseEncryptionData = xData;
}

//--------------------------------------------------------------------------
uno::Sequence< sal_Int8 > ZipPackageStream::GetEncryptionKey( bool bUseWinEncoding )
{
    uno::Sequence< sal_Int8 > aResult;
    sal_Int32 nKeyGenID = GetStartKeyGenID();
    bUseWinEncoding = ( bUseWinEncoding || m_bUseWinEncoding );

    if ( bHaveOwnKey && m_aStorageEncryptionKeys.getLength() )
    {
        ::rtl::OUString aNameToFind;
        if ( nKeyGenID == xml::crypto::DigestID::SHA256 )
            aNameToFind = PACKAGE_ENCRYPTIONDATA_SHA256UTF8;
        else if ( nKeyGenID == xml::crypto::DigestID::SHA1 )
        {
            aNameToFind = bUseWinEncoding ? PACKAGE_ENCRYPTIONDATA_SHA1MS1252 : PACKAGE_ENCRYPTIONDATA_SHA1UTF8;
        }
        else
            throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No expected key is provided!" ) ), uno::Reference< uno::XInterface >() );

        for ( sal_Int32 nInd = 0; nInd < m_aStorageEncryptionKeys.getLength(); nInd++ )
            if ( m_aStorageEncryptionKeys[nInd].Name.equals( aNameToFind ) )
                m_aStorageEncryptionKeys[nInd].Value >>= aResult;

        // empty keys are not allowed here
        // so it is not important whether there is no key, or the key is empty, it is an error
        if ( !aResult.getLength() )
            throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No expected key is provided!" ) ), uno::Reference< uno::XInterface >() );
    }
    else
        aResult = m_aEncryptionKey;

    if ( !aResult.getLength() || !bHaveOwnKey )
        aResult = rZipPackage.GetEncryptionKey();

    return aResult;
}

//--------------------------------------------------------------------------
sal_Int32 ZipPackageStream::GetStartKeyGenID()
{
    // generally should all the streams use the same Start Key
    // but if raw copy without password takes place, we should preserve the imported algorithm
    return m_nImportedStartKeyAlgorithm ? m_nImportedStartKeyAlgorithm : rZipPackage.GetStartKeyGenID();
}

//--------------------------------------------------------------------------
uno::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 = GetEncryptionKey();
		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 );
		uno::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
		uno::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() ) ) );
	
		uno::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( ENCRYPTION_KEY_PROPERTY ) ), makeAny( aKey ) );
			xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Encrypted" ) ), makeAny( sal_True ) );
		}

		// insert a new stream in the package
		uno::Reference< XUnoTunnel > xTunnel;
		Any aRoot = pPackage->getByHierarchicalName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ) );
		aRoot >>= xTunnel;
		uno::Reference< container::XNameContainer > xRootNameContainer( xTunnel, UNO_QUERY );
		if ( !xRootNameContainer.is() )
			throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
	
		uno::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
		uno::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 = uno::Reference< io::XInputStream >();
		xNewPSProps = uno::Reference< XPropertySet >();
		xNPSTunnel = uno::Reference< XUnoTunnel >();
		xNewPackStream = uno::Reference< XDataSinkEncrSupport >();
		xTunnel = uno::Reference< XUnoTunnel >();
		xRootNameContainer = uno::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;

	::rtl::Reference< BaseEncryptionData > 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 BaseEncryptionData;
	
				::rtl::OUString aMediaType;
                sal_Int32 nEncAlgorithm = 0;
                sal_Int32 nChecksumAlgorithm = 0;
                sal_Int32 nDerivedKeySize = 0;
                sal_Int32 nStartKeyGenID = 0;
				if ( ZipFile::StaticFillData( xTempEncrData, nEncAlgorithm, nChecksumAlgorithm, nDerivedKeySize, nStartKeyGenID, 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->m_aSalt.getLength() 
														+ xTempEncrData->m_aInitVector.getLength()
														+ xTempEncrData->m_aDigest.getLength()
														+ aMediaType.getLength() * sizeof( sal_Unicode );
                    m_nImportedEncryptionAlgorithm = nEncAlgorithm;
                    m_nImportedChecksumAlgorithm = nChecksumAlgorithm;
                    m_nImportedDerivedKeySize = nDerivedKeySize;
                    m_nImportedStartKeyAlgorithm = nStartKeyGenID;
					m_nMagicalHackSize = nMagHackSize;
					sMediaType = aMediaType;
	
					bOk = sal_True;
				}
			}
		}
	}
	catch( Exception& )
	{
	}

	if ( !bOk )
	{
		// the provided stream is not a raw stream
		return sal_False;
	}

	m_xBaseEncryptionData = 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 uno::Reference< io::XInputStream >& aStream ) 
		throw( RuntimeException )
{
	// if seekable access is required the wrapping will be done on demand
	xStream = aStream;
    m_nImportedEncryptionAlgorithm = 0;
	m_bHasSeekable = sal_False;
	SetPackageMember ( sal_False );
	aEntry.nTime = -1;
	m_nStreamMode = PACKAGE_STREAM_DETECT;
}

//--------------------------------------------------------------------------
uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawData()
		throw( RuntimeException )
{
	try
	{
		if ( IsPackageMember() )
		{
			return rZipPackage.getZipFile().getRawData( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() );
		}
		else if ( GetOwnSeekStream().is() )
		{
			return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
		}
		else
			return uno::Reference < io::XInputStream > ();
	}
	catch ( ZipException & )//rException )
	{
		VOS_ENSURE( 0, "ZipException thrown" );//rException.Message );
		return uno::Reference < io::XInputStream > ();
	}
	catch ( Exception & )
	{
		VOS_ENSURE( 0, "Exception is thrown during stream wrapping!\n" );
		return uno::Reference < io::XInputStream > ();
	}
}

//--------------------------------------------------------------------------
uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getInputStream() 
		throw( RuntimeException )
{
	try
	{
		if ( IsPackageMember() )
		{
			return rZipPackage.getZipFile().getInputStream( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() );
		}
		else if ( GetOwnSeekStream().is() )
		{
			return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
		}
		else
			return uno::Reference < io::XInputStream > ();
	}
	catch ( ZipException & )//rException )
	{
		VOS_ENSURE( 0,"ZipException thrown" );//rException.Message );
		return uno::Reference < io::XInputStream > ();
	}
	catch ( Exception & )
	{
		VOS_ENSURE( 0, "Exception is thrown during stream wrapping!\n" );
		return uno::Reference < io::XInputStream > ();
	}
}

// XDataSinkEncrSupport
//--------------------------------------------------------------------------
uno::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 uno::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() )
	{
        uno::Reference< io::XInputStream > xResult;
        try
        {
		    xResult = rZipPackage.getZipFile().getDataStream( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() );
        }
        catch( packages::WrongPasswordException& )
        {
            // workaround for the encrypted documents generated with the old OOo1.x bug.
            if ( rZipPackage.GetStartKeyGenID() == xml::crypto::DigestID::SHA1 && !m_bUseWinEncoding )
            {
                xResult = rZipPackage.getZipFile().getDataStream( aEntry, GetEncryptionData( true ), bIsEncrypted, rZipPackage.GetSharedMutexRef() );
                m_bUseWinEncoding = true;
            }
            else
                throw;
        }
        return xResult;
	}
	else if ( m_nStreamMode == PACKAGE_STREAM_RAW )
		return ZipFile::StaticGetDataFromRawStream( m_xFactory, GetOwnSeekStream(), GetEncryptionData() );
	else if ( GetOwnSeekStream().is() )
	{
		return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
	}
	else
		return uno::Reference< io::XInputStream >();
}

//--------------------------------------------------------------------------
uno::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 uno::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 || !GetEncryptionData().is() )
			throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );

		return rZipPackage.getZipFile().getWrappedRawStream( aEntry, GetEncryptionData(), 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 uno::Reference< io::XInputStream >& aStream )
		throw ( io::IOException,
				RuntimeException )
{
	setInputStream( aStream );
	m_nStreamMode = PACKAGE_STREAM_DATA;
}

//--------------------------------------------------------------------------
void SAL_CALL ZipPackageStream::setRawStream( const uno::Reference< io::XInputStream >& aStream )
		throw ( packages::EncryptionNotAllowedException,
				packages::NoRawFormatException,
				io::IOException,
				RuntimeException )
{
	// wrap the stream in case it is not seekable
	uno::Reference< io::XInputStream > xNewStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( aStream, m_xFactory );
	uno::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!" ) ),
									uno::Reference< XInterface >() );

	xSeek->seek( 0 );
	uno::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 uno::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, GetEncryptionData(), 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 uno::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" ) ),
											uno::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" ) ),
											uno::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" ) ),
												uno::Reference< XInterface >(),
												2 );

			bToBeEncrypted = bEnc;
			if ( bToBeEncrypted && !m_xBaseEncryptionData.is() )
				m_xBaseEncryptionData = new BaseEncryptionData;
		}
		else
			throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for Encrypted property!\n" ) ),
											uno::Reference< XInterface >(),
											2 );

	}
	else if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ENCRYPTION_KEY_PROPERTY ) ) )
	{
		if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE )
			throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );

		uno::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" ) ),
												uno::Reference< XInterface >(),
												2 );
		}

		if ( aNewKey.getLength() )
		{
			if ( !m_xBaseEncryptionData.is() )
				m_xBaseEncryptionData = new BaseEncryptionData;

			m_aEncryptionKey = 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;
            m_aEncryptionKey.realloc( 0 );
        }

        m_aStorageEncryptionKeys.realloc( 0 );
	}
	else if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ) )
	{
		if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE )
			throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );

		uno::Sequence< beans::NamedValue > aKeys;
		if ( !( aValue >>= aKeys ) )
		{
				throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for StorageEncryptionKeys property!\n" ) ),
												uno::Reference< XInterface >(),
												2 );
		}

		if ( aKeys.getLength() )
		{
			if ( !m_xBaseEncryptionData.is() )
				m_xBaseEncryptionData = new BaseEncryptionData;

			m_aStorageEncryptionKeys = aKeys;

			// 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;
            m_aStorageEncryptionKeys.realloc( 0 );
        }

        m_aEncryptionKey.realloc( 0 );
	}
	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" ) ),
												uno::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" ) ),
											uno::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( ENCRYPTION_KEY_PROPERTY ) ) )
	{
		aAny <<= m_aEncryptionKey;
		return aAny;
	}
	else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ) )
	{
		aAny <<= m_aStorageEncryptionKeys;
		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];
}

