1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_package.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <com/sun/star/packages/zip/ZipConstants.hpp> 32*cdf0e10cSrcweir #include <com/sun/star/io/XOutputStream.hpp> 33*cdf0e10cSrcweir #include <comphelper/storagehelper.hxx> 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #include <osl/time.h> 36*cdf0e10cSrcweir 37*cdf0e10cSrcweir #include <EncryptionData.hxx> 38*cdf0e10cSrcweir #include <PackageConstants.hxx> 39*cdf0e10cSrcweir #include <ZipEntry.hxx> 40*cdf0e10cSrcweir #include <ZipFile.hxx> 41*cdf0e10cSrcweir #include <ZipPackageStream.hxx> 42*cdf0e10cSrcweir #include <ZipOutputStream.hxx> 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir using namespace rtl; 45*cdf0e10cSrcweir using namespace com::sun::star; 46*cdf0e10cSrcweir using namespace com::sun::star::io; 47*cdf0e10cSrcweir using namespace com::sun::star::uno; 48*cdf0e10cSrcweir using namespace com::sun::star::packages; 49*cdf0e10cSrcweir using namespace com::sun::star::packages::zip; 50*cdf0e10cSrcweir using namespace com::sun::star::packages::zip::ZipConstants; 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir /** This class is used to write Zip files 53*cdf0e10cSrcweir */ 54*cdf0e10cSrcweir ZipOutputStream::ZipOutputStream( const uno::Reference< lang::XMultiServiceFactory >& xFactory, 55*cdf0e10cSrcweir const uno::Reference < XOutputStream > &xOStream ) 56*cdf0e10cSrcweir : m_xFactory( xFactory ) 57*cdf0e10cSrcweir , xStream(xOStream) 58*cdf0e10cSrcweir , m_aDeflateBuffer(n_ConstBufferSize) 59*cdf0e10cSrcweir , aDeflater(DEFAULT_COMPRESSION, sal_True) 60*cdf0e10cSrcweir , aChucker(xOStream) 61*cdf0e10cSrcweir , pCurrentEntry(NULL) 62*cdf0e10cSrcweir , nMethod(DEFLATED) 63*cdf0e10cSrcweir , bFinished(sal_False) 64*cdf0e10cSrcweir , bEncryptCurrentEntry(sal_False) 65*cdf0e10cSrcweir , m_pCurrentStream(NULL) 66*cdf0e10cSrcweir { 67*cdf0e10cSrcweir } 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir ZipOutputStream::~ZipOutputStream( void ) 70*cdf0e10cSrcweir { 71*cdf0e10cSrcweir for (sal_Int32 i = 0, nEnd = aZipList.size(); i < nEnd; i++) 72*cdf0e10cSrcweir delete aZipList[i]; 73*cdf0e10cSrcweir } 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir void SAL_CALL ZipOutputStream::setMethod( sal_Int32 nNewMethod ) 76*cdf0e10cSrcweir throw(RuntimeException) 77*cdf0e10cSrcweir { 78*cdf0e10cSrcweir nMethod = static_cast < sal_Int16 > (nNewMethod); 79*cdf0e10cSrcweir } 80*cdf0e10cSrcweir void SAL_CALL ZipOutputStream::setLevel( sal_Int32 nNewLevel ) 81*cdf0e10cSrcweir throw(RuntimeException) 82*cdf0e10cSrcweir { 83*cdf0e10cSrcweir aDeflater.setLevel( nNewLevel); 84*cdf0e10cSrcweir } 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir void SAL_CALL ZipOutputStream::putNextEntry( ZipEntry& rEntry, 87*cdf0e10cSrcweir ZipPackageStream* pStream, 88*cdf0e10cSrcweir sal_Bool bEncrypt) 89*cdf0e10cSrcweir throw(IOException, RuntimeException) 90*cdf0e10cSrcweir { 91*cdf0e10cSrcweir if (pCurrentEntry != NULL) 92*cdf0e10cSrcweir closeEntry(); 93*cdf0e10cSrcweir if (rEntry.nTime == -1) 94*cdf0e10cSrcweir rEntry.nTime = getCurrentDosTime(); 95*cdf0e10cSrcweir if (rEntry.nMethod == -1) 96*cdf0e10cSrcweir rEntry.nMethod = nMethod; 97*cdf0e10cSrcweir rEntry.nVersion = 20; 98*cdf0e10cSrcweir rEntry.nFlag = 1 << 11; 99*cdf0e10cSrcweir if (rEntry.nSize == -1 || rEntry.nCompressedSize == -1 || 100*cdf0e10cSrcweir rEntry.nCrc == -1) 101*cdf0e10cSrcweir { 102*cdf0e10cSrcweir rEntry.nSize = rEntry.nCompressedSize = 0; 103*cdf0e10cSrcweir rEntry.nFlag |= 8; 104*cdf0e10cSrcweir } 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir if (bEncrypt) 107*cdf0e10cSrcweir { 108*cdf0e10cSrcweir bEncryptCurrentEntry = sal_True; 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir m_xCipherContext = ZipFile::StaticGetCipher( m_xFactory, pStream->GetEncryptionData(), true ); 111*cdf0e10cSrcweir m_xDigestContext = ZipFile::StaticGetDigestContextForChecksum( m_xFactory, pStream->GetEncryptionData() ); 112*cdf0e10cSrcweir mnDigested = 0; 113*cdf0e10cSrcweir rEntry.nFlag |= 1 << 4; 114*cdf0e10cSrcweir m_pCurrentStream = pStream; 115*cdf0e10cSrcweir } 116*cdf0e10cSrcweir sal_Int32 nLOCLength = writeLOC(rEntry); 117*cdf0e10cSrcweir rEntry.nOffset = static_cast < sal_Int32 > (aChucker.GetPosition()) - nLOCLength; 118*cdf0e10cSrcweir aZipList.push_back( &rEntry ); 119*cdf0e10cSrcweir pCurrentEntry = &rEntry; 120*cdf0e10cSrcweir } 121*cdf0e10cSrcweir 122*cdf0e10cSrcweir void SAL_CALL ZipOutputStream::closeEntry( ) 123*cdf0e10cSrcweir throw(IOException, RuntimeException) 124*cdf0e10cSrcweir { 125*cdf0e10cSrcweir ZipEntry *pEntry = pCurrentEntry; 126*cdf0e10cSrcweir if (pEntry) 127*cdf0e10cSrcweir { 128*cdf0e10cSrcweir switch (pEntry->nMethod) 129*cdf0e10cSrcweir { 130*cdf0e10cSrcweir case DEFLATED: 131*cdf0e10cSrcweir aDeflater.finish(); 132*cdf0e10cSrcweir while (!aDeflater.finished()) 133*cdf0e10cSrcweir doDeflate(); 134*cdf0e10cSrcweir if ((pEntry->nFlag & 8) == 0) 135*cdf0e10cSrcweir { 136*cdf0e10cSrcweir if (pEntry->nSize != aDeflater.getTotalIn()) 137*cdf0e10cSrcweir { 138*cdf0e10cSrcweir OSL_ENSURE(false,"Invalid entry size"); 139*cdf0e10cSrcweir } 140*cdf0e10cSrcweir if (pEntry->nCompressedSize != aDeflater.getTotalOut()) 141*cdf0e10cSrcweir { 142*cdf0e10cSrcweir //VOS_DEBUG_ONLY("Invalid entry compressed size"); 143*cdf0e10cSrcweir // Different compression strategies make the merit of this 144*cdf0e10cSrcweir // test somewhat dubious 145*cdf0e10cSrcweir pEntry->nCompressedSize = aDeflater.getTotalOut(); 146*cdf0e10cSrcweir } 147*cdf0e10cSrcweir if (pEntry->nCrc != aCRC.getValue()) 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir OSL_ENSURE(false,"Invalid entry CRC-32"); 150*cdf0e10cSrcweir } 151*cdf0e10cSrcweir } 152*cdf0e10cSrcweir else 153*cdf0e10cSrcweir { 154*cdf0e10cSrcweir if ( !bEncryptCurrentEntry ) 155*cdf0e10cSrcweir { 156*cdf0e10cSrcweir pEntry->nSize = aDeflater.getTotalIn(); 157*cdf0e10cSrcweir pEntry->nCompressedSize = aDeflater.getTotalOut(); 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir pEntry->nCrc = aCRC.getValue(); 160*cdf0e10cSrcweir writeEXT(*pEntry); 161*cdf0e10cSrcweir } 162*cdf0e10cSrcweir aDeflater.reset(); 163*cdf0e10cSrcweir aCRC.reset(); 164*cdf0e10cSrcweir break; 165*cdf0e10cSrcweir case STORED: 166*cdf0e10cSrcweir if (!((pEntry->nFlag & 8) == 0)) 167*cdf0e10cSrcweir OSL_ENSURE ( false, "Serious error, one of compressed size, size or CRC was -1 in a STORED stream"); 168*cdf0e10cSrcweir break; 169*cdf0e10cSrcweir default: 170*cdf0e10cSrcweir OSL_ENSURE(false,"Invalid compression method"); 171*cdf0e10cSrcweir break; 172*cdf0e10cSrcweir } 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir if (bEncryptCurrentEntry) 175*cdf0e10cSrcweir { 176*cdf0e10cSrcweir bEncryptCurrentEntry = sal_False; 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir m_xCipherContext.clear(); 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir uno::Sequence< sal_Int8 > aDigestSeq; 181*cdf0e10cSrcweir if ( m_xDigestContext.is() ) 182*cdf0e10cSrcweir { 183*cdf0e10cSrcweir aDigestSeq = m_xDigestContext->finalizeDigestAndDispose(); 184*cdf0e10cSrcweir m_xDigestContext.clear(); 185*cdf0e10cSrcweir } 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir if ( m_pCurrentStream ) 188*cdf0e10cSrcweir m_pCurrentStream->setDigest( aDigestSeq ); 189*cdf0e10cSrcweir } 190*cdf0e10cSrcweir pCurrentEntry = NULL; 191*cdf0e10cSrcweir m_pCurrentStream = NULL; 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir } 194*cdf0e10cSrcweir 195*cdf0e10cSrcweir void SAL_CALL ZipOutputStream::write( const Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength ) 196*cdf0e10cSrcweir throw(IOException, RuntimeException) 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir switch (pCurrentEntry->nMethod) 199*cdf0e10cSrcweir { 200*cdf0e10cSrcweir case DEFLATED: 201*cdf0e10cSrcweir if (!aDeflater.finished()) 202*cdf0e10cSrcweir { 203*cdf0e10cSrcweir aDeflater.setInputSegment(rBuffer, nNewOffset, nNewLength); 204*cdf0e10cSrcweir while (!aDeflater.needsInput()) 205*cdf0e10cSrcweir doDeflate(); 206*cdf0e10cSrcweir if (!bEncryptCurrentEntry) 207*cdf0e10cSrcweir aCRC.updateSegment(rBuffer, nNewOffset, nNewLength); 208*cdf0e10cSrcweir } 209*cdf0e10cSrcweir break; 210*cdf0e10cSrcweir case STORED: 211*cdf0e10cSrcweir { 212*cdf0e10cSrcweir Sequence < sal_Int8 > aTmpBuffer ( rBuffer.getConstArray(), nNewLength ); 213*cdf0e10cSrcweir aChucker.WriteBytes( aTmpBuffer ); 214*cdf0e10cSrcweir } 215*cdf0e10cSrcweir break; 216*cdf0e10cSrcweir } 217*cdf0e10cSrcweir } 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir void SAL_CALL ZipOutputStream::rawWrite( Sequence< sal_Int8 >& rBuffer, sal_Int32 /*nNewOffset*/, sal_Int32 nNewLength ) 220*cdf0e10cSrcweir throw(IOException, RuntimeException) 221*cdf0e10cSrcweir { 222*cdf0e10cSrcweir Sequence < sal_Int8 > aTmpBuffer ( rBuffer.getConstArray(), nNewLength ); 223*cdf0e10cSrcweir aChucker.WriteBytes( aTmpBuffer ); 224*cdf0e10cSrcweir } 225*cdf0e10cSrcweir 226*cdf0e10cSrcweir void SAL_CALL ZipOutputStream::rawCloseEntry( ) 227*cdf0e10cSrcweir throw(IOException, RuntimeException) 228*cdf0e10cSrcweir { 229*cdf0e10cSrcweir if ( pCurrentEntry->nMethod == DEFLATED && ( pCurrentEntry->nFlag & 8 ) ) 230*cdf0e10cSrcweir writeEXT(*pCurrentEntry); 231*cdf0e10cSrcweir pCurrentEntry = NULL; 232*cdf0e10cSrcweir } 233*cdf0e10cSrcweir 234*cdf0e10cSrcweir void SAL_CALL ZipOutputStream::finish( ) 235*cdf0e10cSrcweir throw(IOException, RuntimeException) 236*cdf0e10cSrcweir { 237*cdf0e10cSrcweir if (bFinished) 238*cdf0e10cSrcweir return; 239*cdf0e10cSrcweir 240*cdf0e10cSrcweir if (pCurrentEntry != NULL) 241*cdf0e10cSrcweir closeEntry(); 242*cdf0e10cSrcweir 243*cdf0e10cSrcweir if (aZipList.size() < 1) 244*cdf0e10cSrcweir OSL_ENSURE(false,"Zip file must have at least one entry!\n"); 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir sal_Int32 nOffset= static_cast < sal_Int32 > (aChucker.GetPosition()); 247*cdf0e10cSrcweir for (sal_Int32 i =0, nEnd = aZipList.size(); i < nEnd; i++) 248*cdf0e10cSrcweir writeCEN( *aZipList[i] ); 249*cdf0e10cSrcweir writeEND( nOffset, static_cast < sal_Int32 > (aChucker.GetPosition()) - nOffset); 250*cdf0e10cSrcweir bFinished = sal_True; 251*cdf0e10cSrcweir xStream->flush(); 252*cdf0e10cSrcweir } 253*cdf0e10cSrcweir 254*cdf0e10cSrcweir void ZipOutputStream::doDeflate() 255*cdf0e10cSrcweir { 256*cdf0e10cSrcweir sal_Int32 nLength = aDeflater.doDeflateSegment(m_aDeflateBuffer, 0, m_aDeflateBuffer.getLength()); 257*cdf0e10cSrcweir 258*cdf0e10cSrcweir if ( nLength > 0 ) 259*cdf0e10cSrcweir { 260*cdf0e10cSrcweir uno::Sequence< sal_Int8 > aTmpBuffer( m_aDeflateBuffer.getConstArray(), nLength ); 261*cdf0e10cSrcweir if ( bEncryptCurrentEntry && m_xDigestContext.is() && m_xCipherContext.is() ) 262*cdf0e10cSrcweir { 263*cdf0e10cSrcweir // Need to update our digest before encryption... 264*cdf0e10cSrcweir sal_Int32 nDiff = n_ConstDigestLength - mnDigested; 265*cdf0e10cSrcweir if ( nDiff ) 266*cdf0e10cSrcweir { 267*cdf0e10cSrcweir sal_Int32 nEat = ::std::min( nLength, nDiff ); 268*cdf0e10cSrcweir uno::Sequence< sal_Int8 > aTmpSeq( aTmpBuffer.getConstArray(), nEat ); 269*cdf0e10cSrcweir m_xDigestContext->updateDigest( aTmpSeq ); 270*cdf0e10cSrcweir mnDigested = mnDigested + static_cast< sal_Int16 >( nEat ); 271*cdf0e10cSrcweir } 272*cdf0e10cSrcweir 273*cdf0e10cSrcweir uno::Sequence< sal_Int8 > aEncryptionBuffer = m_xCipherContext->convertWithCipherContext( aTmpBuffer ); 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir aChucker.WriteBytes( aEncryptionBuffer ); 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir // the sizes as well as checksum for encrypted streams is calculated here 278*cdf0e10cSrcweir pCurrentEntry->nCompressedSize += aEncryptionBuffer.getLength(); 279*cdf0e10cSrcweir pCurrentEntry->nSize = pCurrentEntry->nCompressedSize; 280*cdf0e10cSrcweir aCRC.update( aEncryptionBuffer ); 281*cdf0e10cSrcweir } 282*cdf0e10cSrcweir else 283*cdf0e10cSrcweir { 284*cdf0e10cSrcweir aChucker.WriteBytes ( aTmpBuffer ); 285*cdf0e10cSrcweir } 286*cdf0e10cSrcweir } 287*cdf0e10cSrcweir 288*cdf0e10cSrcweir if ( aDeflater.finished() && bEncryptCurrentEntry && m_xDigestContext.is() && m_xCipherContext.is() ) 289*cdf0e10cSrcweir { 290*cdf0e10cSrcweir uno::Sequence< sal_Int8 > aEncryptionBuffer = m_xCipherContext->finalizeCipherContextAndDispose(); 291*cdf0e10cSrcweir if ( aEncryptionBuffer.getLength() ) 292*cdf0e10cSrcweir { 293*cdf0e10cSrcweir aChucker.WriteBytes( aEncryptionBuffer ); 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir // the sizes as well as checksum for encrypted streams is calculated hier 296*cdf0e10cSrcweir pCurrentEntry->nCompressedSize += aEncryptionBuffer.getLength(); 297*cdf0e10cSrcweir pCurrentEntry->nSize = pCurrentEntry->nCompressedSize; 298*cdf0e10cSrcweir aCRC.update( aEncryptionBuffer ); 299*cdf0e10cSrcweir } 300*cdf0e10cSrcweir } 301*cdf0e10cSrcweir } 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir void ZipOutputStream::writeEND(sal_uInt32 nOffset, sal_uInt32 nLength) 304*cdf0e10cSrcweir throw(IOException, RuntimeException) 305*cdf0e10cSrcweir { 306*cdf0e10cSrcweir aChucker << ENDSIG; 307*cdf0e10cSrcweir aChucker << static_cast < sal_Int16 > ( 0 ); 308*cdf0e10cSrcweir aChucker << static_cast < sal_Int16 > ( 0 ); 309*cdf0e10cSrcweir aChucker << static_cast < sal_Int16 > ( aZipList.size() ); 310*cdf0e10cSrcweir aChucker << static_cast < sal_Int16 > ( aZipList.size() ); 311*cdf0e10cSrcweir aChucker << nLength; 312*cdf0e10cSrcweir aChucker << nOffset; 313*cdf0e10cSrcweir aChucker << static_cast < sal_Int16 > ( 0 ); 314*cdf0e10cSrcweir } 315*cdf0e10cSrcweir void ZipOutputStream::writeCEN( const ZipEntry &rEntry ) 316*cdf0e10cSrcweir throw(IOException, RuntimeException) 317*cdf0e10cSrcweir { 318*cdf0e10cSrcweir if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( rEntry.sPath, sal_True ) ) 319*cdf0e10cSrcweir throw IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected character is used in file name." ) ), uno::Reference< XInterface >() ); 320*cdf0e10cSrcweir 321*cdf0e10cSrcweir ::rtl::OString sUTF8Name = ::rtl::OUStringToOString( rEntry.sPath, RTL_TEXTENCODING_UTF8 ); 322*cdf0e10cSrcweir sal_Int16 nNameLength = static_cast < sal_Int16 > ( sUTF8Name.getLength() ); 323*cdf0e10cSrcweir 324*cdf0e10cSrcweir aChucker << CENSIG; 325*cdf0e10cSrcweir aChucker << rEntry.nVersion; 326*cdf0e10cSrcweir aChucker << rEntry.nVersion; 327*cdf0e10cSrcweir if (rEntry.nFlag & (1 << 4) ) 328*cdf0e10cSrcweir { 329*cdf0e10cSrcweir // If it's an encrypted entry, we pretend its stored plain text 330*cdf0e10cSrcweir ZipEntry *pEntry = const_cast < ZipEntry * > ( &rEntry ); 331*cdf0e10cSrcweir pEntry->nFlag &= ~(1 <<4 ); 332*cdf0e10cSrcweir aChucker << rEntry.nFlag; 333*cdf0e10cSrcweir aChucker << static_cast < sal_Int16 > ( STORED ); 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir else 336*cdf0e10cSrcweir { 337*cdf0e10cSrcweir aChucker << rEntry.nFlag; 338*cdf0e10cSrcweir aChucker << rEntry.nMethod; 339*cdf0e10cSrcweir } 340*cdf0e10cSrcweir aChucker << static_cast < sal_uInt32> ( rEntry.nTime ); 341*cdf0e10cSrcweir aChucker << static_cast < sal_uInt32> ( rEntry.nCrc ); 342*cdf0e10cSrcweir aChucker << rEntry.nCompressedSize; 343*cdf0e10cSrcweir aChucker << rEntry.nSize; 344*cdf0e10cSrcweir aChucker << nNameLength; 345*cdf0e10cSrcweir aChucker << static_cast < sal_Int16> (0); 346*cdf0e10cSrcweir aChucker << static_cast < sal_Int16> (0); 347*cdf0e10cSrcweir aChucker << static_cast < sal_Int16> (0); 348*cdf0e10cSrcweir aChucker << static_cast < sal_Int16> (0); 349*cdf0e10cSrcweir aChucker << static_cast < sal_Int32> (0); 350*cdf0e10cSrcweir aChucker << rEntry.nOffset; 351*cdf0e10cSrcweir 352*cdf0e10cSrcweir Sequence < sal_Int8 > aSequence( (sal_Int8*)sUTF8Name.getStr(), sUTF8Name.getLength() ); 353*cdf0e10cSrcweir aChucker.WriteBytes( aSequence ); 354*cdf0e10cSrcweir } 355*cdf0e10cSrcweir void ZipOutputStream::writeEXT( const ZipEntry &rEntry ) 356*cdf0e10cSrcweir throw(IOException, RuntimeException) 357*cdf0e10cSrcweir { 358*cdf0e10cSrcweir aChucker << EXTSIG; 359*cdf0e10cSrcweir aChucker << static_cast < sal_uInt32> ( rEntry.nCrc ); 360*cdf0e10cSrcweir aChucker << rEntry.nCompressedSize; 361*cdf0e10cSrcweir aChucker << rEntry.nSize; 362*cdf0e10cSrcweir } 363*cdf0e10cSrcweir 364*cdf0e10cSrcweir sal_Int32 ZipOutputStream::writeLOC( const ZipEntry &rEntry ) 365*cdf0e10cSrcweir throw(IOException, RuntimeException) 366*cdf0e10cSrcweir { 367*cdf0e10cSrcweir if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( rEntry.sPath, sal_True ) ) 368*cdf0e10cSrcweir throw IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected character is used in file name." ) ), uno::Reference< XInterface >() ); 369*cdf0e10cSrcweir 370*cdf0e10cSrcweir ::rtl::OString sUTF8Name = ::rtl::OUStringToOString( rEntry.sPath, RTL_TEXTENCODING_UTF8 ); 371*cdf0e10cSrcweir sal_Int16 nNameLength = static_cast < sal_Int16 > ( sUTF8Name.getLength() ); 372*cdf0e10cSrcweir 373*cdf0e10cSrcweir aChucker << LOCSIG; 374*cdf0e10cSrcweir aChucker << rEntry.nVersion; 375*cdf0e10cSrcweir 376*cdf0e10cSrcweir if (rEntry.nFlag & (1 << 4) ) 377*cdf0e10cSrcweir { 378*cdf0e10cSrcweir // If it's an encrypted entry, we pretend its stored plain text 379*cdf0e10cSrcweir sal_Int16 nTmpFlag = rEntry.nFlag; 380*cdf0e10cSrcweir nTmpFlag &= ~(1 <<4 ); 381*cdf0e10cSrcweir aChucker << nTmpFlag; 382*cdf0e10cSrcweir aChucker << static_cast < sal_Int16 > ( STORED ); 383*cdf0e10cSrcweir } 384*cdf0e10cSrcweir else 385*cdf0e10cSrcweir { 386*cdf0e10cSrcweir aChucker << rEntry.nFlag; 387*cdf0e10cSrcweir aChucker << rEntry.nMethod; 388*cdf0e10cSrcweir } 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir aChucker << static_cast < sal_uInt32 > (rEntry.nTime); 391*cdf0e10cSrcweir if ((rEntry.nFlag & 8) == 8 ) 392*cdf0e10cSrcweir { 393*cdf0e10cSrcweir aChucker << static_cast < sal_Int32 > (0); 394*cdf0e10cSrcweir aChucker << static_cast < sal_Int32 > (0); 395*cdf0e10cSrcweir aChucker << static_cast < sal_Int32 > (0); 396*cdf0e10cSrcweir } 397*cdf0e10cSrcweir else 398*cdf0e10cSrcweir { 399*cdf0e10cSrcweir aChucker << static_cast < sal_uInt32 > (rEntry.nCrc); 400*cdf0e10cSrcweir aChucker << rEntry.nCompressedSize; 401*cdf0e10cSrcweir aChucker << rEntry.nSize; 402*cdf0e10cSrcweir } 403*cdf0e10cSrcweir aChucker << nNameLength; 404*cdf0e10cSrcweir aChucker << static_cast < sal_Int16 > (0); 405*cdf0e10cSrcweir 406*cdf0e10cSrcweir Sequence < sal_Int8 > aSequence( (sal_Int8*)sUTF8Name.getStr(), sUTF8Name.getLength() ); 407*cdf0e10cSrcweir aChucker.WriteBytes( aSequence ); 408*cdf0e10cSrcweir 409*cdf0e10cSrcweir return LOCHDR + nNameLength; 410*cdf0e10cSrcweir } 411*cdf0e10cSrcweir sal_uInt32 ZipOutputStream::getCurrentDosTime( ) 412*cdf0e10cSrcweir { 413*cdf0e10cSrcweir oslDateTime aDateTime; 414*cdf0e10cSrcweir TimeValue aTimeValue; 415*cdf0e10cSrcweir osl_getSystemTime ( &aTimeValue ); 416*cdf0e10cSrcweir osl_getDateTimeFromTimeValue( &aTimeValue, &aDateTime); 417*cdf0e10cSrcweir 418*cdf0e10cSrcweir sal_uInt32 nYear = static_cast <sal_uInt32> (aDateTime.Year); 419*cdf0e10cSrcweir 420*cdf0e10cSrcweir if (nYear>1980) 421*cdf0e10cSrcweir nYear-=1980; 422*cdf0e10cSrcweir else if (nYear>80) 423*cdf0e10cSrcweir nYear-=80; 424*cdf0e10cSrcweir sal_uInt32 nResult = static_cast < sal_uInt32>( ( ( ( aDateTime.Day) + 425*cdf0e10cSrcweir ( 32 * (aDateTime.Month)) + 426*cdf0e10cSrcweir ( 512 * nYear ) ) << 16) | 427*cdf0e10cSrcweir ( ( aDateTime.Seconds/2) + 428*cdf0e10cSrcweir ( 32 * aDateTime.Minutes) + 429*cdf0e10cSrcweir ( 2048 * static_cast <sal_uInt32 > (aDateTime.Hours) ) ) ); 430*cdf0e10cSrcweir return nResult; 431*cdf0e10cSrcweir } 432*cdf0e10cSrcweir /* 433*cdf0e10cSrcweir 434*cdf0e10cSrcweir This is actually never used, so I removed it, but thought that the 435*cdf0e10cSrcweir implementation details may be useful in the future...mtg 20010307 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir I stopped using the time library and used the OSL version instead, but 438*cdf0e10cSrcweir it might still be useful to have this code here.. 439*cdf0e10cSrcweir 440*cdf0e10cSrcweir void ZipOutputStream::dosDateToTMDate ( tm &rTime, sal_uInt32 nDosDate) 441*cdf0e10cSrcweir { 442*cdf0e10cSrcweir sal_uInt32 nDate = static_cast < sal_uInt32 > (nDosDate >> 16); 443*cdf0e10cSrcweir rTime.tm_mday = static_cast < sal_uInt32 > ( nDate & 0x1F); 444*cdf0e10cSrcweir rTime.tm_mon = static_cast < sal_uInt32 > ( ( ( (nDate) & 0x1E0)/0x20)-1); 445*cdf0e10cSrcweir rTime.tm_year = static_cast < sal_uInt32 > ( ( (nDate & 0x0FE00)/0x0200)+1980); 446*cdf0e10cSrcweir 447*cdf0e10cSrcweir rTime.tm_hour = static_cast < sal_uInt32 > ( (nDosDate & 0xF800)/0x800); 448*cdf0e10cSrcweir rTime.tm_min = static_cast < sal_uInt32 > ( (nDosDate & 0x7E0)/0x20); 449*cdf0e10cSrcweir rTime.tm_sec = static_cast < sal_uInt32 > ( 2 * (nDosDate & 0x1F) ); 450*cdf0e10cSrcweir } 451*cdf0e10cSrcweir */ 452*cdf0e10cSrcweir 453