diff options
Diffstat (limited to 'package/source')
-rw-r--r-- | package/source/zipapi/ZipOutputEntry.cxx | 175 | ||||
-rw-r--r-- | package/source/zipapi/ZipOutputStream.cxx | 156 | ||||
-rw-r--r-- | package/source/zippackage/ZipPackage.cxx | 21 | ||||
-rw-r--r-- | package/source/zippackage/ZipPackageFolder.cxx | 6 | ||||
-rw-r--r-- | package/source/zippackage/ZipPackageStream.cxx | 12 |
5 files changed, 184 insertions, 186 deletions
diff --git a/package/source/zipapi/ZipOutputEntry.cxx b/package/source/zipapi/ZipOutputEntry.cxx index a3e3cc8bb72f..4e2f6d45a25b 100644 --- a/package/source/zipapi/ZipOutputEntry.cxx +++ b/package/source/zipapi/ZipOutputEntry.cxx @@ -24,9 +24,11 @@ #include <osl/time.h> +#include <ByteChucker.hxx> #include <PackageConstants.hxx> #include <ZipEntry.hxx> #include <ZipFile.hxx> +#include <ZipOutputStream.hxx> #include <ZipPackageStream.hxx> using namespace com::sun::star; @@ -37,43 +39,24 @@ using namespace com::sun::star::packages::zip::ZipConstants; /** This class is used to deflate Zip entries */ ZipOutputEntry::ZipOutputEntry( const uno::Reference< uno::XComponentContext >& rxContext, - ByteChucker& rChucker, + ZipOutputStream* pOutputStream, ZipEntry& rEntry, ZipPackageStream* pStream, bool bEncrypt) : m_aDeflateBuffer(n_ConstBufferSize) , m_aDeflater(DEFAULT_COMPRESSION, true) -, m_rChucker(rChucker) +, m_pZipOutputStream(pOutputStream) , m_pCurrentEntry(&rEntry) , m_nDigested(0) -, m_bEncryptCurrentEntry(false) +, m_bEncryptCurrentEntry(bEncrypt) , m_pCurrentStream(NULL) { - if (rEntry.nTime == -1) - rEntry.nTime = getCurrentDosTime(); - if (rEntry.nMethod == -1) - rEntry.nMethod = DEFLATED; - rEntry.nVersion = 20; - rEntry.nFlag = 1 << 11; - if (rEntry.nSize == -1 || rEntry.nCompressedSize == -1 || - rEntry.nCrc == -1) + if (m_bEncryptCurrentEntry) { - rEntry.nSize = rEntry.nCompressedSize = 0; - rEntry.nFlag |= 8; - } - - if (bEncrypt) - { - m_bEncryptCurrentEntry = true; - m_xCipherContext = ZipFile::StaticGetCipher( rxContext, pStream->GetEncryptionData(), true ); m_xDigestContext = ZipFile::StaticGetDigestContextForChecksum( rxContext, pStream->GetEncryptionData() ); - m_nDigested = 0; - rEntry.nFlag |= 1 << 4; m_pCurrentStream = pStream; } - sal_Int32 nLOCLength = writeLOC(rEntry); - rEntry.nOffset = m_rChucker.GetPosition() - nLOCLength; } ZipOutputEntry::~ZipOutputEntry( void ) @@ -117,7 +100,6 @@ void SAL_CALL ZipOutputEntry::closeEntry( ) pEntry->nCompressedSize = m_aDeflater.getTotalOut(); } pEntry->nCrc = m_aCRC.getValue(); - writeEXT(*pEntry); } m_aDeflater.reset(); m_aCRC.reset(); @@ -170,27 +152,12 @@ void SAL_CALL ZipOutputEntry::write( const Sequence< sal_Int8 >& rBuffer, sal_In case STORED: { Sequence < sal_Int8 > aTmpBuffer ( rBuffer.getConstArray(), nNewLength ); - m_rChucker.WriteBytes( aTmpBuffer ); + m_pZipOutputStream->getChucker().WriteBytes( aTmpBuffer ); } break; } } -void SAL_CALL ZipOutputEntry::rawWrite( Sequence< sal_Int8 >& rBuffer, sal_Int32 /*nNewOffset*/, sal_Int32 nNewLength ) - throw(IOException, RuntimeException) -{ - Sequence < sal_Int8 > aTmpBuffer ( rBuffer.getConstArray(), nNewLength ); - m_rChucker.WriteBytes( aTmpBuffer ); -} - -void SAL_CALL ZipOutputEntry::rawCloseEntry( ) - throw(IOException, RuntimeException) -{ - if ( m_pCurrentEntry->nMethod == DEFLATED && ( m_pCurrentEntry->nFlag & 8 ) ) - writeEXT(*m_pCurrentEntry); - m_pCurrentEntry = NULL; -} - void ZipOutputEntry::doDeflate() { sal_Int32 nLength = m_aDeflater.doDeflateSegment(m_aDeflateBuffer, 0, m_aDeflateBuffer.getLength()); @@ -213,7 +180,7 @@ void ZipOutputEntry::doDeflate() // FIXME64: uno::Sequence not 64bit safe. uno::Sequence< sal_Int8 > aEncryptionBuffer = m_xCipherContext->convertWithCipherContext( aTmpBuffer ); - m_rChucker.WriteBytes( aEncryptionBuffer ); + m_pZipOutputStream->getChucker().WriteBytes( aEncryptionBuffer ); // the sizes as well as checksum for encrypted streams is calculated here m_pCurrentEntry->nCompressedSize += aEncryptionBuffer.getLength(); @@ -222,7 +189,7 @@ void ZipOutputEntry::doDeflate() } else { - m_rChucker.WriteBytes ( aTmpBuffer ); + m_pZipOutputStream->getChucker().WriteBytes ( aTmpBuffer ); } } @@ -232,7 +199,7 @@ void ZipOutputEntry::doDeflate() uno::Sequence< sal_Int8 > aEncryptionBuffer = m_xCipherContext->finalizeCipherContextAndDispose(); if ( aEncryptionBuffer.getLength() ) { - m_rChucker.WriteBytes( aEncryptionBuffer ); + m_pZipOutputStream->getChucker().WriteBytes( aEncryptionBuffer ); // the sizes as well as checksum for encrypted streams is calculated hier m_pCurrentEntry->nCompressedSize += aEncryptionBuffer.getLength(); @@ -242,126 +209,4 @@ void ZipOutputEntry::doDeflate() } } -static sal_uInt32 getTruncated( sal_Int64 nNum, bool *pIsTruncated ) -{ - if( nNum >= 0xffffffff ) - { - *pIsTruncated = true; - return 0xffffffff; - } - else - return static_cast< sal_uInt32 >( nNum ); -} - -void ZipOutputEntry::writeEXT( const ZipEntry &rEntry ) - throw(IOException, RuntimeException) -{ - bool bWrite64Header = false; - - m_rChucker << EXTSIG; - m_rChucker << static_cast < sal_uInt32> ( rEntry.nCrc ); - m_rChucker << getTruncated( rEntry.nCompressedSize, &bWrite64Header ); - m_rChucker << getTruncated( rEntry.nSize, &bWrite64Header ); - - if( bWrite64Header ) - { - // FIXME64: need to append a ZIP64 header instead of throwing - // We're about to silently lose people's data - which they are - // unlikely to appreciate so fail instead: - throw IOException( "File contains streams that are too large." ); - } -} - -sal_Int32 ZipOutputEntry::writeLOC( const ZipEntry &rEntry ) - throw(IOException, RuntimeException) -{ - if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( rEntry.sPath, true ) ) - throw IOException("Unexpected character is used in file name." ); - - OString sUTF8Name = OUStringToOString( rEntry.sPath, RTL_TEXTENCODING_UTF8 ); - sal_Int16 nNameLength = static_cast < sal_Int16 > ( sUTF8Name.getLength() ); - - m_rChucker << LOCSIG; - m_rChucker << rEntry.nVersion; - - if (rEntry.nFlag & (1 << 4) ) - { - // If it's an encrypted entry, we pretend its stored plain text - sal_Int16 nTmpFlag = rEntry.nFlag; - nTmpFlag &= ~(1 <<4 ); - m_rChucker << nTmpFlag; - m_rChucker << static_cast < sal_Int16 > ( STORED ); - } - else - { - m_rChucker << rEntry.nFlag; - m_rChucker << rEntry.nMethod; - } - - bool bWrite64Header = false; - - m_rChucker << static_cast < sal_uInt32 > (rEntry.nTime); - if ((rEntry.nFlag & 8) == 8 ) - { - m_rChucker << static_cast < sal_Int32 > (0); - m_rChucker << static_cast < sal_Int32 > (0); - m_rChucker << static_cast < sal_Int32 > (0); - } - else - { - m_rChucker << static_cast < sal_uInt32 > (rEntry.nCrc); - m_rChucker << getTruncated( rEntry.nCompressedSize, &bWrite64Header ); - m_rChucker << getTruncated( rEntry.nSize, &bWrite64Header ); - } - m_rChucker << nNameLength; - m_rChucker << static_cast < sal_Int16 > (0); - - if( bWrite64Header ) - { - // FIXME64: need to append a ZIP64 header instead of throwing - // We're about to silently lose people's data - which they are - // unlikely to appreciate so fail instead: - throw IOException( "File contains streams that are too large." ); - } - - Sequence < sal_Int8 > aSequence( (sal_Int8*)sUTF8Name.getStr(), sUTF8Name.getLength() ); - m_rChucker.WriteBytes( aSequence ); - - return LOCHDR + nNameLength; -} -sal_uInt32 ZipOutputEntry::getCurrentDosTime( ) -{ - oslDateTime aDateTime; - TimeValue aTimeValue; - osl_getSystemTime ( &aTimeValue ); - osl_getDateTimeFromTimeValue( &aTimeValue, &aDateTime); - - // at year 2108, there is an overflow - // -> some decision needs to be made - // how to handle the ZIP file format (just overflow?) - - // if the current system time is before 1980, - // then the time traveller will have to make a decision - // how to handle the ZIP file format before it is invented - // (just underflow?) - - assert(aDateTime.Year > 1980 && aDateTime.Year < 2108); - - sal_uInt32 nYear = static_cast <sal_uInt32> (aDateTime.Year); - - if (nYear>=1980) - nYear-=1980; - else if (nYear>=80) - { - nYear-=80; - } - sal_uInt32 nResult = static_cast < sal_uInt32>( ( ( ( aDateTime.Day) + - ( 32 * (aDateTime.Month)) + - ( 512 * nYear ) ) << 16) | - ( ( aDateTime.Seconds/2) + - ( 32 * aDateTime.Minutes) + - ( 2048 * static_cast <sal_uInt32 > (aDateTime.Hours) ) ) ); - return nResult; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx index 7cd5acdb5c7b..29c19c42667a 100644 --- a/package/source/zipapi/ZipOutputStream.cxx +++ b/package/source/zipapi/ZipOutputStream.cxx @@ -23,8 +23,11 @@ #include <com/sun/star/io/XOutputStream.hpp> #include <comphelper/storagehelper.hxx> +#include <osl/time.h> + #include <PackageConstants.hxx> #include <ZipEntry.hxx> +#include <ZipPackageStream.hxx> using namespace com::sun::star; using namespace com::sun::star::io; @@ -37,6 +40,7 @@ ZipOutputStream::ZipOutputStream( const uno::Reference < io::XOutputStream > &xO : m_xStream(xOStream) , m_aChucker(xOStream) , m_bFinished(false) +, m_pCurrentEntry(NULL) { } @@ -46,9 +50,45 @@ ZipOutputStream::~ZipOutputStream( void ) delete m_aZipList[i]; } -void ZipOutputStream::addEntry( ZipEntry *pZipEntry ) +void ZipOutputStream::putNextEntry( ZipEntry& rEntry, bool bEncrypt ) + throw(IOException, RuntimeException) +{ + assert(!m_pCurrentEntry && "Forgot to close an entry before putNextEntry()?"); + if (rEntry.nTime == -1) + rEntry.nTime = getCurrentDosTime(); + if (rEntry.nMethod == -1) + rEntry.nMethod = DEFLATED; + rEntry.nVersion = 20; + rEntry.nFlag = 1 << 11; + if (rEntry.nSize == -1 || rEntry.nCompressedSize == -1 || + rEntry.nCrc == -1) + { + rEntry.nSize = rEntry.nCompressedSize = 0; + rEntry.nFlag |= 8; + } + if (bEncrypt) + { + rEntry.nFlag |= 1 << 4; + } + + sal_Int32 nLOCLength = writeLOC(rEntry); + rEntry.nOffset = m_aChucker.GetPosition() - nLOCLength; + m_aZipList.push_back( &rEntry ); + m_pCurrentEntry = &rEntry; +} + +void ZipOutputStream::rawWrite( Sequence< sal_Int8 >& rBuffer, sal_Int32 /*nNewOffset*/, sal_Int32 nNewLength ) + throw(IOException, RuntimeException) +{ + m_aChucker.WriteBytes( Sequence< sal_Int8 >(rBuffer.getConstArray(), nNewLength) ); +} + +void ZipOutputStream::rawCloseEntry() + throw(IOException, RuntimeException) { - m_aZipList.push_back( pZipEntry ); + if ( m_pCurrentEntry->nMethod == DEFLATED && ( m_pCurrentEntry->nFlag & 8 ) ) + writeEXT(*m_pCurrentEntry); + m_pCurrentEntry = NULL; } void ZipOutputStream::finish( ) @@ -148,4 +188,116 @@ void ZipOutputStream::writeCEN( const ZipEntry &rEntry ) m_aChucker.WriteBytes( aSequence ); } +void ZipOutputStream::writeEXT( const ZipEntry &rEntry ) + throw(IOException, RuntimeException) +{ + bool bWrite64Header = false; + + m_aChucker << EXTSIG; + m_aChucker << static_cast < sal_uInt32> ( rEntry.nCrc ); + m_aChucker << getTruncated( rEntry.nCompressedSize, &bWrite64Header ); + m_aChucker << getTruncated( rEntry.nSize, &bWrite64Header ); + + if( bWrite64Header ) + { + // FIXME64: need to append a ZIP64 header instead of throwing + // We're about to silently lose people's data - which they are + // unlikely to appreciate so fail instead: + throw IOException( "File contains streams that are too large." ); + } +} + +sal_Int32 ZipOutputStream::writeLOC( const ZipEntry &rEntry ) + throw(IOException, RuntimeException) +{ + if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( rEntry.sPath, true ) ) + throw IOException("Unexpected character is used in file name." ); + + OString sUTF8Name = OUStringToOString( rEntry.sPath, RTL_TEXTENCODING_UTF8 ); + sal_Int16 nNameLength = static_cast < sal_Int16 > ( sUTF8Name.getLength() ); + + m_aChucker << LOCSIG; + m_aChucker << rEntry.nVersion; + + if (rEntry.nFlag & (1 << 4) ) + { + // If it's an encrypted entry, we pretend its stored plain text + sal_Int16 nTmpFlag = rEntry.nFlag; + nTmpFlag &= ~(1 <<4 ); + m_aChucker << nTmpFlag; + m_aChucker << static_cast < sal_Int16 > ( STORED ); + } + else + { + m_aChucker << rEntry.nFlag; + m_aChucker << rEntry.nMethod; + } + + bool bWrite64Header = false; + + m_aChucker << static_cast < sal_uInt32 > (rEntry.nTime); + if ((rEntry.nFlag & 8) == 8 ) + { + m_aChucker << static_cast < sal_Int32 > (0); + m_aChucker << static_cast < sal_Int32 > (0); + m_aChucker << static_cast < sal_Int32 > (0); + } + else + { + m_aChucker << static_cast < sal_uInt32 > (rEntry.nCrc); + m_aChucker << getTruncated( rEntry.nCompressedSize, &bWrite64Header ); + m_aChucker << getTruncated( rEntry.nSize, &bWrite64Header ); + } + m_aChucker << nNameLength; + m_aChucker << static_cast < sal_Int16 > (0); + + if( bWrite64Header ) + { + // FIXME64: need to append a ZIP64 header instead of throwing + // We're about to silently lose people's data - which they are + // unlikely to appreciate so fail instead: + throw IOException( "File contains streams that are too large." ); + } + + Sequence < sal_Int8 > aSequence( (sal_Int8*)sUTF8Name.getStr(), sUTF8Name.getLength() ); + m_aChucker.WriteBytes( aSequence ); + + return LOCHDR + nNameLength; +} + +sal_uInt32 ZipOutputStream::getCurrentDosTime() +{ + oslDateTime aDateTime; + TimeValue aTimeValue; + osl_getSystemTime ( &aTimeValue ); + osl_getDateTimeFromTimeValue( &aTimeValue, &aDateTime); + + // at year 2108, there is an overflow + // -> some decision needs to be made + // how to handle the ZIP file format (just overflow?) + + // if the current system time is before 1980, + // then the time traveller will have to make a decision + // how to handle the ZIP file format before it is invented + // (just underflow?) + + assert(aDateTime.Year > 1980 && aDateTime.Year < 2108); + + sal_uInt32 nYear = static_cast <sal_uInt32> (aDateTime.Year); + + if (nYear>=1980) + nYear-=1980; + else if (nYear>=80) + { + nYear-=80; + } + sal_uInt32 nResult = static_cast < sal_uInt32>( ( ( ( aDateTime.Day) + + ( 32 * (aDateTime.Month)) + + ( 512 * nYear ) ) << 16) | + ( ( aDateTime.Seconds/2) + + ( 32 * aDateTime.Minutes) + + ( 2048 * static_cast <sal_uInt32 > (aDateTime.Hours) ) ) ); + return nResult; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx index a631cabb14ba..a05320a48951 100644 --- a/package/source/zippackage/ZipPackage.cxx +++ b/package/source/zippackage/ZipPackage.cxx @@ -989,7 +989,7 @@ void ZipPackage::WriteMimetypeMagicFile( ZipOutputStream& aZipOut ) pEntry->sPath = sMime; pEntry->nMethod = STORED; pEntry->nSize = pEntry->nCompressedSize = nBufferLength; - pEntry->nTime = ZipOutputEntry::getCurrentDosTime(); + pEntry->nTime = ZipOutputStream::getCurrentDosTime(); CRC32 aCRC32; aCRC32.update( aType ); @@ -997,10 +997,11 @@ void ZipPackage::WriteMimetypeMagicFile( ZipOutputStream& aZipOut ) try { - ZipOutputEntry aZipEntry(m_xContext, aZipOut.getChucker(), *pEntry, NULL); + aZipOut.putNextEntry(*pEntry); + ZipOutputEntry aZipEntry(m_xContext, &aZipOut, *pEntry, NULL); aZipEntry.write(aType, 0, nBufferLength); aZipEntry.closeEntry(); - aZipOut.addEntry(pEntry); + aZipOut.rawCloseEntry(); } catch ( const ::com::sun::star::io::IOException & r ) { @@ -1023,7 +1024,7 @@ void ZipPackage::WriteManifest( ZipOutputStream& aZipOut, const vector< uno::Seq pEntry->nMethod = DEFLATED; pEntry->nCrc = -1; pEntry->nSize = pEntry->nCompressedSize = -1; - pEntry->nTime = ZipOutputEntry::getCurrentDosTime(); + pEntry->nTime = ZipOutputStream::getCurrentDosTime(); // Convert vector into a uno::Sequence uno::Sequence < uno::Sequence < PropertyValue > > aManifestSequence ( aManList.size() ); @@ -1040,10 +1041,11 @@ void ZipPackage::WriteManifest( ZipOutputStream& aZipOut, const vector< uno::Seq pBuffer->realloc( nBufferLength ); // the manifest.xml is never encrypted - so pass an empty reference - ZipOutputEntry aZipEntry(m_xContext, aZipOut.getChucker(), *pEntry, NULL); + aZipOut.putNextEntry(*pEntry); + ZipOutputEntry aZipEntry(m_xContext, &aZipOut, *pEntry, NULL); aZipEntry.write(pBuffer->getSequence(), 0, nBufferLength); aZipEntry.closeEntry(); - aZipOut.addEntry(pEntry); + aZipOut.rawCloseEntry(); } void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< uno::Sequence < PropertyValue > >& aManList ) @@ -1056,7 +1058,7 @@ void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< uno: pEntry->nMethod = DEFLATED; pEntry->nCrc = -1; pEntry->nSize = pEntry->nCompressedSize = -1; - pEntry->nTime = ZipOutputEntry::getCurrentDosTime(); + pEntry->nTime = ZipOutputStream::getCurrentDosTime(); // Convert vector into a uno::Sequence // TODO/LATER: use Defaulst entries in future @@ -1091,10 +1093,11 @@ void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< uno: pBuffer->realloc( nBufferLength ); // there is no encryption in this format currently - ZipOutputEntry aZipEntry(m_xContext, aZipOut.getChucker(), *pEntry, NULL); + aZipOut.putNextEntry(*pEntry); + ZipOutputEntry aZipEntry(m_xContext, &aZipOut, *pEntry, NULL); aZipEntry.write(pBuffer->getSequence(), 0, nBufferLength); aZipEntry.closeEntry(); - aZipOut.addEntry(pEntry); + aZipOut.rawCloseEntry(); } void ZipPackage::ConnectTo( const uno::Reference< io::XInputStream >& xInStream ) diff --git a/package/source/zippackage/ZipPackageFolder.cxx b/package/source/zippackage/ZipPackageFolder.cxx index c2e5a4fa2f9a..a6b2e5c139a7 100644 --- a/package/source/zippackage/ZipPackageFolder.cxx +++ b/package/source/zippackage/ZipPackageFolder.cxx @@ -21,7 +21,6 @@ #include <ZipPackageFolder.hxx> #include <ZipFile.hxx> -#include <ZipOutputEntry.hxx> #include <ZipOutputStream.hxx> #include <ZipPackageStream.hxx> #include <PackageConstants.hxx> @@ -338,9 +337,8 @@ void ZipPackageFolder::saveContents( try { - ZipOutputEntry aZipEntry(m_xContext, rZipOut.getChucker(), *pTempEntry, NULL, false); - aZipEntry.rawCloseEntry(); - rZipOut.addEntry(pTempEntry); + rZipOut.putNextEntry( *pTempEntry ); + rZipOut.rawCloseEntry(); } catch ( ZipException& ) { diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx index a4651d78b298..7547e9cf0dc5 100644 --- a/package/source/zippackage/ZipPackageStream.cxx +++ b/package/source/zippackage/ZipPackageStream.cxx @@ -674,7 +674,7 @@ bool ZipPackageStream::saveChild( if ( bRawStream ) xStream->skipBytes( m_nMagicalHackPos ); - ZipOutputEntry aZipEntry(m_xContext, rZipOut.getChucker(), *pTempEntry, this, false); + rZipOut.putNextEntry(*pTempEntry); // the entry is provided to the ZipOutputStream that will delete it pAutoTempEntry.release(); @@ -684,12 +684,11 @@ bool ZipPackageStream::saveChild( do { nLength = xStream->readBytes( aSeq, n_ConstBufferSize ); - aZipEntry.rawWrite(aSeq, 0, nLength); + rZipOut.rawWrite(aSeq, 0, nLength); } while ( nLength == n_ConstBufferSize ); - aZipEntry.rawCloseEntry(); - rZipOut.addEntry(pTempEntry); + rZipOut.rawCloseEntry(); } catch ( ZipException& ) { @@ -732,7 +731,8 @@ bool ZipPackageStream::saveChild( try { - ZipOutputEntry aZipEntry(m_xContext, rZipOut.getChucker(), *pTempEntry, this, bToBeEncrypted); + rZipOut.putNextEntry(*pTempEntry, bToBeEncrypted); + ZipOutputEntry aZipEntry(m_xContext, &rZipOut, *pTempEntry, this, bToBeEncrypted); // the entry is provided to the ZipOutputStream that will delete it pAutoTempEntry.release(); @@ -746,7 +746,7 @@ bool ZipPackageStream::saveChild( while ( nLength == n_ConstBufferSize ); aZipEntry.closeEntry(); - rZipOut.addEntry(pTempEntry); + rZipOut.rawCloseEntry(); } catch ( ZipException& ) { |