--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/compressionlibs/ziplib/src/ezlib/gzip.cpp Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,597 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <ezgzip.h>
+#include "libzcore.h"
+
+const TUint8 EZGZipFile::ID1 = 31;
+const TUint8 EZGZipFile::ID2 = 139;
+
+/**
+Constructor
+*/
+EXPORT_C TEZGZipHeader::TEZGZipHeader() : iId1(EZGZipFile::ID1), iId2(EZGZipFile::ID2), iCompressionMethod(8), iFlags(0), iTime(0),
+ iExtraFlags(0), iOs(255), iXlen(0), iExtra(NULL), iFname(NULL), iComment(NULL), iCrc(0)
+ {
+
+ }
+
+/**
+Destructor
+*/
+EXPORT_C TEZGZipHeader::~TEZGZipHeader()
+ {
+ delete iExtra;
+ delete iFname;
+ delete iComment;
+ }
+
+/**
+Constructor
+*/
+EXPORT_C TEZGZipTrailer::TEZGZipTrailer() : iCrc32(0), iSize(0)
+ {
+
+ }
+
+/**
+Constructor
+
+@param aCrc the CRC to use for archive checking
+@param aSize the size of the trailer
+*/
+EXPORT_C TEZGZipTrailer::TEZGZipTrailer(TInt32 aCrc, TInt32 aSize) : iCrc32(aCrc), iSize(aSize)
+ {
+
+ }
+
+//--------------------------------------------------------------------------------------------------------
+
+/**
+Read the zip header from the specified zip file into the TEZGZipHeader object
+
+@param aFile the zip file to read from
+@param aHeader the target header object
+@leave KEZlibErrBadGZipHeader invalid zip header
+@leave ... Any of the system wide error codes
+*/
+EXPORT_C void EZGZipFile::ReadHeaderL(RFile &aFile, TEZGZipHeader &aHeader)
+ {
+ TInt obligatoryData = sizeof(aHeader.iId1) + sizeof(aHeader.iId2) + sizeof(aHeader.iCompressionMethod) +
+ sizeof(aHeader.iFlags) + sizeof(aHeader.iTime) + sizeof(aHeader.iExtraFlags) + sizeof(aHeader.iOs);
+
+ TPtr8 des(&aHeader.iId1,0,obligatoryData);
+ TInt err = aFile.Read(des);
+ if (err != KErrNone || (des.Size() != obligatoryData))
+ User::Leave(KEZlibErrBadGZipHeader);
+
+ if (aHeader.iId1 != ID1 || aHeader.iId2 != ID2)
+ User::Leave(KEZlibErrBadGZipHeader);
+
+ if (aHeader.iFlags & (1 << EFExtra)) // then the extra bit is set
+ {
+ des.Set(REINTERPRET_CAST(TUint8 *,&aHeader.iXlen),0,sizeof(aHeader.iXlen));
+ err = aFile.Read(des);
+ if (err != KErrNone || des.Size() != sizeof(aHeader.iXlen) || aHeader.iXlen < 0)
+ User::Leave(KEZlibErrBadGZipHeader);
+
+ aHeader.iExtra = HBufC8::NewMaxL(aHeader.iXlen);
+ TPtr8 des = aHeader.iExtra->Des();
+ err = aFile.Read(des);
+ if (err != KErrNone || des.Size() != aHeader.iXlen)
+ User::Leave(KEZlibErrBadGZipHeader);
+ }
+
+ if (aHeader.iFlags & (1 << EFName)) // then read in filename
+ ReadStringIntoDescriptorL(aFile,&aHeader.iFname);
+
+ if (aHeader.iFlags & (1 << EFComment)) // then read in comment
+ ReadStringIntoDescriptorL(aFile,&aHeader.iComment);
+
+ if (aHeader.iFlags & (1 << EFHcrc))
+ {
+ des.Set(REINTERPRET_CAST(TUint8*,&aHeader.iCrc),0,sizeof(aHeader.iCrc));
+ err = aFile.Read(des);
+ if (err != KErrNone || des.Size() != sizeof(aHeader.iCrc))
+ User::Leave(KEZlibErrBadGZipHeader);
+ }
+ }
+
+/**
+Write the zip header to the specified file
+
+@param aFile the file to write to
+@param aHeader the header object to write to the file
+@leave ... Any of the system wide error codes
+*/
+EXPORT_C void EZGZipFile::WriteHeaderL(RFile &aFile, TEZGZipHeader &aHeader)
+ {
+ TInt obligatoryData = sizeof(aHeader.iId1) + sizeof(aHeader.iId2) + sizeof(aHeader.iCompressionMethod) +
+ sizeof(aHeader.iFlags) + sizeof(aHeader.iTime) + sizeof(aHeader.iExtraFlags) + sizeof(aHeader.iOs);
+
+ TPtrC8 des(&aHeader.iId1,obligatoryData);
+ User::LeaveIfError(aFile.Write(des));
+ TBuf8<1> null(1);
+ null[0] = '\0';
+
+ if (aHeader.iFlags & (1 << EFExtra)) // then the extra bit is set
+ {
+ des.Set(REINTERPRET_CAST(TUint8 *,&aHeader.iXlen),sizeof(aHeader.iXlen));
+ User::LeaveIfError(aFile.Write(des));
+
+ User::LeaveIfError(aFile.Write(*aHeader.iExtra));
+ }
+
+ if (aHeader.iFlags & (1 << EFName)) // then read in filename
+ {
+ User::LeaveIfError(aFile.Write(*aHeader.iFname));
+ User::LeaveIfError(aFile.Write(null));
+ }
+
+ if (aHeader.iFlags & (1 << EFComment)) // then read in comment
+ {
+ User::LeaveIfError(aFile.Write(*aHeader.iComment));
+ User::LeaveIfError(aFile.Write(null));
+ }
+
+ if (aHeader.iFlags & (1 << EFHcrc))
+ {
+ des.Set(REINTERPRET_CAST(TUint8*,&aHeader.iCrc),sizeof(aHeader.iCrc));
+ User::LeaveIfError(aFile.Write(des));
+ }
+ }
+
+void EZGZipFile::ReadStringIntoDescriptorL(RFile &aFile, HBufC8 **aDes)
+ {
+ TInt i, err;
+ CArrayFixFlat<TUint8> *bytes = new (ELeave) CArrayFixFlat<TUint8>(16);
+ CleanupStack::PushL(bytes);
+ TBuf8<1> ch;
+ while ((err = aFile.Read(ch)) == KErrNone)
+ {
+ if (ch.Length() != 1)
+ User::Leave(KEZlibErrBadGZipHeader);
+ else if (ch[0] != '\0')
+ bytes->AppendL(*ch.Ptr());
+ else
+ break;
+ }
+
+ if (err != KErrNone)
+ User::Leave(KEZlibErrBadGZipHeader);
+
+ *aDes = HBufC8::NewMaxL(bytes->Count());
+
+ for (i = 0; i < bytes->Count(); i++)
+ (*aDes)->Des()[i] = (*bytes)[i];
+
+ CleanupStack::PopAndDestroy(); // delete bytes
+ }
+
+/**
+Read the zip trailer from the specified zip file into the TEZGZipTrailer object
+
+@param aFile the zip file to read from
+@param aTrailer the target trailer object
+@leave KEZlibErrBadGZipTrailer invalid zip trailer
+@leave ... Any of the system wide error codes
+*/
+EXPORT_C void EZGZipFile::ReadTrailerL(RFile &aFile, TEZGZipTrailer &aTrailer)
+ {
+ TPtr8 des(REINTERPRET_CAST(TUint8*,&aTrailer.iCrc32),0,sizeof(TEZGZipTrailer));
+
+ TInt err = aFile.Read(des);
+ if (err != KErrNone || des.Size() != sizeof(TEZGZipTrailer))
+ User::Leave(KEZlibErrBadGZipTrailer);
+ }
+
+/**
+Write the zip trailer to the specified file
+
+@param aFile the file to write to
+@param aTrailer the trailer object to write to the file
+@leave ... Any of the system wide error codes
+*/
+EXPORT_C void EZGZipFile::WriteTrailerL(RFile &aFile, TEZGZipTrailer &aTrailer)
+ {
+ TPtrC8 des(REINTERPRET_CAST(TUint8*,&aTrailer.iCrc32),sizeof(TEZGZipTrailer));
+ User::LeaveIfError(aFile.Write(des));
+ }
+
+/**
+Find the zip trailer within the specified file, and read it into the TEZGZipTrailer object
+
+@param aRfs file server session
+@param aFname the file to read from
+@param aTrailer the target trailer object
+@leave KEZlibErrBadGZipHeader Invalid zip header
+@leave ... Any of the system wide error codes
+*/
+EXPORT_C void EZGZipFile::LocateAndReadTrailerL(RFs &aRfs, const TDesC &aFname, TEZGZipTrailer &aTrailer)
+ {
+ TInt fileSize;
+
+ RFile file;
+
+ User::LeaveIfError(file.Open(aRfs,aFname,EFileStream | EFileRead | EFileShareAny));
+ CleanupClosePushL(file);
+
+ TUint8 magic[2];
+ TPtr8 des(magic,0,sizeof(TUint8) * 2);
+ User::LeaveIfError(file.Read(des));
+ if (magic[0] != ID1 || magic[1] != ID2)
+ User::Leave(KEZlibErrBadGZipHeader);
+
+ User::LeaveIfError(file.Size(fileSize));
+ TInt sizePos = fileSize - (sizeof (TInt32) * 2);
+ User::LeaveIfError(file.Seek(ESeekStart,sizePos));
+
+ des.Set(REINTERPRET_CAST(TUint8 *,&aTrailer),0,sizeof(TInt32)*2);
+
+ User::LeaveIfError(file.Read(des));
+
+ CleanupStack::PopAndDestroy();
+ }
+
+/**
+@deprecated Interface is deprecated because it is unsafe as it may leave. It is available for backward compatibility reasons only.
+@see EZGZipFile::IsGzipFileL
+*/
+EXPORT_C TBool EZGZipFile::IsGzipFile(RFs &aRfs, const TDesC &aFname)
+ {
+ TBool retBool = true;
+ TRAPD(errCode, retBool = IsGzipFileL(aRfs, aFname));
+ if(errCode != KErrNone)
+ {
+ retBool = false;
+ }
+ return retBool;
+ }
+
+/**
+Determine if the given file is a valid zip file
+
+@param aRfs file server session
+@param aFname name of the file to check
+@leave ... Any of the system wide error codes
+@return ETrue if the file is valid zip file, EFalse otherwise
+*/
+EXPORT_C TBool EZGZipFile::IsGzipFileL(RFs &aRfs, const TDesC &aFname)
+ {
+ TUint8 ids[2];
+ RFile file;
+
+ User::LeaveIfError(file.Open(aRfs,aFname,EFileStream | EFileRead | EFileShareAny));
+ CleanupClosePushL(file);
+
+ TPtr8 des(ids,0,sizeof(TUint8) * 2);
+
+ User::LeaveIfError(file.Read(des));
+ CleanupStack::PopAndDestroy();
+ return (ids[0] == ID1 && ids[1] == ID2);
+ }
+
+//--------------------------------------------------------------------------------------------------------
+
+
+CEZFileToGzipBM::CEZFileToGzipBM(RFile &aInput, RFile &aOutput) : CEZFileBufferManager(aInput,aOutput)
+ {
+ iCrc = crc32_r(iCrc,NULL,0);
+ }
+
+
+CEZFileToGzipBM* CEZFileToGzipBM::NewLC(RFile &aInput, RFile &aOutput, TInt aBufferSize)
+ {
+ CEZFileToGzipBM *bm = new (ELeave) CEZFileToGzipBM(aInput,aOutput);
+ CleanupStack::PushL(bm);
+ bm->ConstructL(aBufferSize);
+ return bm;
+ }
+
+CEZFileToGzipBM* CEZFileToGzipBM::NewL(RFile &aInput, RFile &aOutput, TInt aBufferSize)
+ {
+ CEZFileToGzipBM *bm = new (ELeave) CEZFileToGzipBM(aInput,aOutput);
+ CleanupStack::PushL(bm);
+ bm->ConstructL(aBufferSize);
+ CleanupStack::Pop();
+ return bm;
+ }
+
+void CEZFileToGzipBM::NeedInputL(CEZZStream &aZStream)
+ {
+ CEZFileBufferManager::NeedInputL(aZStream);
+ iCrc = crc32_r(iCrc,iInputDescriptor.Ptr(),iInputDescriptor.Size());
+ }
+
+void CEZFileToGzipBM::InitializeL(CEZZStream &aZStream)
+ {
+ CEZFileBufferManager::InitializeL(aZStream);
+ iCrc = crc32_r(iCrc,iInputDescriptor.Ptr(),iInputDescriptor.Size());
+ }
+
+//--------------------------------------------------------------------------------------------------------
+
+
+CEZGzipToFileBM::CEZGzipToFileBM(RFile &aInput, RFile &aOutput) : CEZFileBufferManager(aInput,aOutput)
+ {
+ iCrc = crc32_r(iCrc,NULL,0);
+ }
+
+CEZGzipToFileBM* CEZGzipToFileBM::NewLC(RFile &aInput, RFile &aOutput, TInt aBufferSize)
+ {
+ CEZGzipToFileBM *bm = new (ELeave) CEZGzipToFileBM(aInput,aOutput);
+ CleanupStack::PushL(bm);
+ bm->ConstructL(aBufferSize);
+ return bm;
+ }
+
+CEZGzipToFileBM* CEZGzipToFileBM::NewL(RFile &aInput, RFile &aOutput, TInt aBufferSize)
+ {
+ CEZGzipToFileBM *bm = new (ELeave) CEZGzipToFileBM(aInput,aOutput);
+ CleanupStack::PushL(bm);
+ bm->ConstructL(aBufferSize);
+ CleanupStack::Pop();
+ return bm;
+ }
+
+void CEZGzipToFileBM::NeedOutputL(CEZZStream &aZStream)
+ {
+ TPtrC8 od = aZStream.OutputDescriptor();
+ iCrc = crc32_r(iCrc,od.Ptr(),od.Size());
+ CEZFileBufferManager::NeedOutputL(aZStream);
+ }
+
+void CEZGzipToFileBM::FinalizeL(CEZZStream &aZStream)
+ {
+ TPtrC8 od = aZStream.OutputDescriptor();
+ iCrc = crc32_r(iCrc,od.Ptr(),od.Size());
+ CEZFileBufferManager::FinalizeL(aZStream);
+ }
+
+
+//--------------------------------------------------------------------------------------------------------
+CEZGZipToFile::CEZGZipToFile() : iDecompressor(NULL), iBufferManager(NULL)
+ {
+
+ }
+
+CEZGZipToFile::~CEZGZipToFile()
+ {
+ delete iDecompressor;
+ delete iBufferManager;
+ iGZipFile.Close();
+ }
+
+/**
+Creates a new CEZGZipToFile object and leaves it on the CleanupStack
+
+@param aRfs open file server session
+@param aGzFileName name of the file to be de-compressed
+@param aOutput the target file to hold the un-compressed data
+@param aBufferSize required size of buffers
+@return a pointer to the new CEZGZipToFile object, left on the CleanupStack
+*/
+EXPORT_C CEZGZipToFile* CEZGZipToFile::NewLC(RFs &aRfs, const TDesC &aGzFileName, RFile &aOutput, TInt aBufferSize)
+ {
+ CEZGZipToFile* dec = new (ELeave) CEZGZipToFile;
+ CleanupStack::PushL(dec);
+ dec->ConstructL(aRfs,aGzFileName,aOutput,aBufferSize);
+ return dec;
+ }
+
+/**
+Creates a new CEZGZipToFile object
+
+@param aRfs open file server session
+@param aGzFileName name of the file to be de-compressed
+@param aOutput the target file to hold the un-compressed data
+@param aBufferSize required size of buffers
+@return a pointer to the new CEZGZipToFile object
+*/
+EXPORT_C CEZGZipToFile* CEZGZipToFile::NewL(RFs &aRfs, const TDesC &aGzFileName, RFile &aOutput, TInt aBufferSize)
+ {
+ CEZGZipToFile* dec = new (ELeave) CEZGZipToFile;
+ CleanupStack::PushL(dec);
+ dec->ConstructL(aRfs,aGzFileName,aOutput,aBufferSize);
+ CleanupStack::Pop();
+ return dec;
+ }
+
+/**
+Quits the current de-compression operation and restarts with the specified arguments
+
+@param aRfs open file server session
+@param aGzFileName name of the file to be de-compressed
+@param aOutput the target file to hold the un-compressed data
+@param aBufferSize required size of buffers
+@leave ... Any of the system wide error codes
+*/
+EXPORT_C void CEZGZipToFile::ResetL(RFs &aRfs, const TDesC &aGzFileName, RFile &aOutput, TInt aBufferSize)
+ {
+ delete iBufferManager;
+ iBufferManager = NULL;
+ InitialiseBufManL(aRfs,aGzFileName,aOutput,aBufferSize);
+ iDecompressor->ResetL(*iBufferManager);
+ }
+
+/**
+De-compresses the current zip file in stages. The function needs to called again until the de-compression
+is finalised, in which case it will return EFalse - for example...
+
+@code
+while ( decompressor->InflateL() )
+ {
+ // No action required
+ }
+@endcode
+
+@leave KEZlibErrBadGZipCrc Invalid CRC check
+@leave ... Any of the system wide error codes
+@return ETrue if the de-compression is not complete, and function must be called again
+@return EFalse if the de-compression is finalised
+*/
+EXPORT_C TBool CEZGZipToFile::InflateL()
+ {
+ TBool keepGoing = iDecompressor->InflateL();
+
+ if (!keepGoing)
+ {
+ if (iBufferManager->Crc() != iTrailer.iCrc32)
+ {
+ User::Leave(KEZlibErrBadGZipCrc);
+
+ }
+ iGZipFile.Close();
+ }
+
+ return keepGoing;
+ }
+
+void CEZGZipToFile::InitialiseBufManL(RFs &aRfs, const TDesC &aGzFileName, RFile &aOutput, TInt aBufferSize)
+ {
+ EZGZipFile::LocateAndReadTrailerL(aRfs,aGzFileName,iTrailer);
+ User::LeaveIfError(iGZipFile.Open(aRfs,aGzFileName,EFileStream | EFileRead | EFileShareAny));
+ EZGZipFile::ReadHeaderL(iGZipFile,iHeader);
+ iBufferManager = CEZGzipToFileBM::NewL(iGZipFile,aOutput,aBufferSize);
+ }
+
+void CEZGZipToFile::ConstructL(RFs &aRfs, const TDesC &aGzFileName, RFile &aOutput, TInt aBufferSize)
+ {
+ InitialiseBufManL(aRfs,aGzFileName,aOutput,aBufferSize);
+
+ // this is a special zlib modification to stop it choking when it can't find the normal zlib stream header.
+
+ iDecompressor = CEZDecompressor::NewL(*iBufferManager,-CEZDecompressor::EMaxWBits);
+ }
+
+
+//--------------------------------------------------------------------------------------------------------
+
+
+CEZFileToGZip::CEZFileToGZip() : iCompressor(NULL), iBufferManager(NULL)
+ {
+
+ }
+
+CEZFileToGZip::~CEZFileToGZip()
+ {
+ delete iCompressor;
+ delete iBufferManager;
+ iGZipFile.Close();
+ }
+
+/**
+Creates a new CEZFileToGZip object and leaves it on the CleanupStack
+
+@param aRfs open file server session
+@param aGzFileName the name of the target zip file
+@param aInput the file to compress
+@param aBufferSize required size of buffers
+@return a pointer to the new CEZFileToGZip object, left on the CleanupStack
+*/
+EXPORT_C CEZFileToGZip* CEZFileToGZip::NewLC(RFs &aRfs, const TDesC &aGzFileName, RFile &aInput, TInt aBufferSize)
+ {
+ CEZFileToGZip* com = new (ELeave) CEZFileToGZip;
+ CleanupStack::PushL(com);
+ com->ConstructL(aRfs,aGzFileName,aInput,aBufferSize);
+ return com;
+ }
+
+/**
+Creates a new CEZFileToGZip object and leaves it on the CleanupStack
+
+@param aRfs open file server session
+@param aGzFileName the name of the target zip file
+@param aInput the file to compress
+@param aBufferSize required size of buffers
+@return a pointer to the new CEZFileToGZip object, left on the CleanupStack
+*/
+EXPORT_C CEZFileToGZip* CEZFileToGZip::NewL(RFs &aRfs, const TDesC &aGzFileName, RFile &aInput, TInt aBufferSize)
+ {
+ CEZFileToGZip* com = new (ELeave) CEZFileToGZip;
+ CleanupStack::PushL(com);
+ com->ConstructL(aRfs,aGzFileName,aInput,aBufferSize);
+ CleanupStack::Pop();
+ return com;
+ }
+
+/**
+Quits the current compression operation and restarts with the specified arguments
+
+@param aRfs open file server session
+@param aGzFileName the name of the target zip file
+@param aInput the file to compress
+@param aBufferSize required size of buffers
+@leave ... Any of the system wide error codes
+*/
+EXPORT_C void CEZFileToGZip::ResetL(RFs &aRfs, const TDesC &aGzFileName, RFile &aInput, TInt aBufferSize)
+ {
+ delete iBufferManager;
+ iBufferManager = NULL;
+ InitialiseBufManL(aRfs,aGzFileName,aInput,aBufferSize);
+ iCompressor->ResetL(*iBufferManager);
+ }
+
+/**
+Compresses the current file in stages. The function needs to called again until the compression
+is finalised, in which case it will return EFalse - for example...
+
+@code
+while ( compressor->DeflateL() )
+ {
+ // No action required
+ }
+@endcode
+
+@leave ... Any of the system wide error codes
+@return ETrue if the compression is not complete, and function must be called again
+@return EFalse if the compression is finalised
+*/
+EXPORT_C TBool CEZFileToGZip::DeflateL()
+ {
+ TBool keepgoing = iCompressor->DeflateL();
+ if (!keepgoing)
+ {
+ TEZGZipTrailer trailer(iBufferManager->Crc(), iUncompressedDataSize);
+ EZGZipFile::WriteTrailerL(iGZipFile, trailer);
+ iGZipFile.Close();
+ }
+
+ return keepgoing;
+ }
+
+void CEZFileToGZip::InitialiseBufManL(RFs &aRfs, const TDesC &aGzFileName, RFile &aInput, TInt aBufferSize)
+ {
+ User::LeaveIfError(aInput.Size(iUncompressedDataSize));
+ TInt err;
+
+ err = iGZipFile.Create(aRfs, aGzFileName,EFileStream | EFileWrite | EFileShareExclusive);
+ if (err == KErrAlreadyExists)
+ User::LeaveIfError(iGZipFile.Open(aRfs,aGzFileName,EFileStream | EFileWrite | EFileShareExclusive));
+ else
+ User::LeaveIfError(err);
+
+ EZGZipFile::WriteHeaderL(iGZipFile,iHeader);
+ iBufferManager = CEZFileToGzipBM::NewL(aInput,iGZipFile,aBufferSize);
+ }
+
+void CEZFileToGZip::ConstructL(RFs &aRfs, const TDesC &aGzFileName, RFile &aInput, TInt aBufferSize)
+ {
+ InitialiseBufManL(aRfs,aGzFileName,aInput,aBufferSize);
+
+ // this is a special zlib modification to stop zlib writing out its normal zlib stream header.
+
+ iCompressor = CEZCompressor::NewL(*iBufferManager,CEZCompressor::EDefaultCompression,-CEZCompressor::EMaxWBits);
+ }