|
||
EzlibExample
: Using EZLIB API to compress and
decompress files
This overview describes the example application that demonstrates the
usage of the EZLIB API. The application is located in the folder
examples\SysLibs\EzlibExample
.
This overview contains the following sections:
EZLIB is a utility API used to compress and decompress data. The API is an extension of ZLIB compression library. For more information on ZLIB compression library, refer to RFC1950.
This example application uses the EZLIB API to extract files from a
.zip
and a .gz
file into specified folders, and to
compress a .wav
file into a .gz
file. The application
reads input files and stores the extracted files in
c:\private\E80000B7\
.
The application uses an object of the RFs
class to
open the EzlibZipFolder.zip
file. It reads the properties of each
file in the archive using the CZipFileMember
object and
prints it to the console.
After reading all the properties of each file in the archive, the
application extracts all the files to the specified folder using the
CZipFile::GetInputStreamL()
method.
Other than extracting all the files in the archive, the application
also searches for a specific file using the
CZipFile::CaseInsensitiveMemberL()
method and extracts it.
The application also opens the icon.bmp.gz
file and
extracts its contents to the specified location. The GZip file is represented
by an object of the CEZGZipToFile
class and its contents
are extracted using the CEZGZipToFile::InflateL()
method.
Finally, the application compresses the error.wav
file to
a .gz
file. The GZip file being created is represented by an
object of the CEZFileToGZip
class and the
.wav
file is compressed using the
CEZFileToGZip::DeflateL()
method.
CZipFile
A CZipFile represents a ZIP archive contained in a single file. Multi file zip a...CZipFileMember
Class encapsulating the representation of a compressed file contained in a CZipF...CZipFileMemberIterator
An iterator class for iterating though all the entries in the archive.RZipFileMemberReaderStream
A RZipFileMemberReaderStream represents a input stream for compressed files in t...CEZGZipToFile
A CEZGZipToFile object allows de-compression of a compressed file. The name of t...CEZFileToGZip
A CEZFileToGZip object allows compression of an uncompressed file to a zip file....The Symbian OS build process describes how to build an application.
The EzlibExample
builds an executable file called
ezlibexample.exe
in the standard location
(\epoc32\release\winscw\
<build_variant>
for CodeWarrior). After launching the executable, depending on the emulator you
are using, you may need to navigate using the application launcher or the
eshell
screen to view the console.
// BLD.INF
//
//
// Copyright ©) Symbian Software Ltd 2007. All rights reserved.
//
PRJ_EXPORTS
EzlibZipFolder.zip \epoc32\WINSCW\C\private\E80000B7\zip\input\EzlibZipFolder.zip
icon.bmp.gz \epoc32\WINSCW\C\private\E80000B7\gzip\icon.bmp.gz
error.wav \epoc32\WINSCW\C\private\E80000B7\gzip\error.wav
PRJ_MMPFILES
ezlibexample.mmp
// ezlibexample.mmp
//
// Copyright ©) Symbian Software Ltd 2007. All rights reserved.
//
TARGET ezlibexample.exe
TARGETTYPE exe
UID 0 0xE80000B7
SOURCEPATH .
SOURCE ezlibexample.cpp
USERINCLUDE .
SYSTEMINCLUDE \Epoc32\include
LIBRARY euser.lib estor.lib
LIBRARY efsrv.lib ezip.lib
LIBRARY ezlib.lib
// ezlibexample.h
//
// Copyright ©) Symbian Software Ltd 2007. All rights reserved.
//
/**
@file
Contains CEzlibExample class.
*/
#ifndef __EZLIBEXAMPLE_H__
#define __EZLIBEXAMPLE_H__
#include <zipfile.h>
/**
Demonstrates the use of the Symbian OS Ezlib component
to zip and unzip .GZ files and unzip .ZIP files.
CEzlibExample publicly inherits from CBase, which is the
base class for all classes to be instantiated on the heap.
*/
class CEzlibExample: public CBase
{
public:
static CEzlibExample* NewLC();
~CEzlibExample();
void OpenZipFileL(RFs& aFsSession);
void GetPropertiesL(TFileName& aFileName, RFs& aFsSession);
void ExtractFilesL(const CZipFileMember* aMember, CZipFile* aZipFile, RFs& aFsSession, const TDesC& aOutputPath);
void CompressToGzipFileL(RFs& aFsSession);
void ExtractGzipFileL(RFs& aFsSession);
private:
CEzlibExample();
void ConstructL();
private:
/** Pointer to the console interface */
CConsoleBase* iConsole;
};
#endif //__EZLIBEXAMPLE_H__
// ezlibexample.cpp
//
// Copyright ©) Symbian Software Ltd 2007. All rights reserved.
//
/**
@file
This example program demonstrates the use of the EZLIB API.
The code demonstrates how to
-# Open a ZIP file and get the properties of each file
-# Extract a selected member of the ZIP file and save it to a new file.
-# Save all the members of a ZIP file to a file.
-# Open a GZIP file and extract the contents to a file.
-# Compress a file into a GZIP file.
*/
#include "ezlibexample.h"
#include <e32cons.h>
#include <EZGzip.h>
_LIT(KTitle, "Ezlib example");
_LIT(KTextPressAKey, "\n\nPress any key to step through the example\n");
_LIT(KExit,"\nPress any key to exit the application");
_LIT(KPressAKey,"\nPress any key to continue \n");
_LIT(KProperties,"Press any key to have a look at the properties of the zipped files \n");
_LIT(KDecompress,"Gzip file successfully decompressed\n");
_LIT(KCompress,"\nFile successfully compressed to gzip format and saved\n");
_LIT(KNoFilesFound,"No appropriate files located in this folder.\r\n");
_LIT(KLineSpace, "\r\n");
_LIT(KFileInfo,"\nCompressing file %S");
_LIT(KFileOpen,"\nOpening file: %S\r\n");
_LIT(KFileExtract,"\nExtracting the file %S\n");
_LIT(KFileZipExtract,"\nExtracting files from the zip file %S\n");
_LIT(KInputZipFile, "\\private\\E80000B7\\zip\\input\\EzlibZipFolder.zip");
_LIT(KInputGzipPath, "\\private\\E80000B7\\gzip\\error.wav");
_LIT(KInputGzipFile, "\\private\\E80000B7\\gzip\\icon.bmp.gz");
_LIT(KZipName,"\nName: %S ");
_LIT(KZipCRC32,"\nCRC32: %X ");
_LIT(KZipCSize,"\nCompressed Size: %d");
_LIT(KZipUCSize,"\nUncompressed Size: %d");
_LIT(KOpenedSuccessfully, "%S opened successfully.\n");
_LIT(KExtractZipPathMulti, "\\private\\E80000B7\\zip\\extracts\\");
_LIT(KExtractZipPathSingle, "\\private\\E80000B7\\zip\\extracts\\singlefile\\");
_LIT(KCompressGzipPath, "\\private\\E80000B7\\gzip\\extracts\\");
_LIT(KCompressZipFile, "icon.bmp");
_LIT(KExtractGzipFile, "error.wav");
/**
Allocates and constructs a CEzlibExample object and
leaves it on the cleanup stack.
Initialises all member data to their default values.
*/
CEzlibExample * CEzlibExample::NewLC()
{
CEzlibExample * rep = new(ELeave) CEzlibExample();
CleanupStack::PushL(rep);
rep->ConstructL();
return rep;
}
/**
Constructor
*/
CEzlibExample::CEzlibExample()
{
}
void CEzlibExample::ConstructL()
{
iConsole = Console::NewL(KTitle,TSize(KConsFullScreen,KConsFullScreen));
iConsole->Printf(KTextPressAKey);
iConsole->Getch();
}
/**
Destructor
*/
CEzlibExample::~CEzlibExample()
{
iConsole->Printf(KExit);
iConsole->Getch();
delete iConsole;
}
/**
Gets the properties of each member of the zip file passed to it
and prints it on the console.
@param aFileName Pointer to a file whose properties are to be fetched.
@param aFsSession File server session handle
@leave KZipArchiveError
@leave KZipFileIOError
@leave KCentralDirectoryTrailerNotFound
@leave KCentralDirectoryTrailerInvalid
@leave KMultiDiskArchivesNotSupported
@leave ... A system-wide error code.
*/
void CEzlibExample::GetPropertiesL(TFileName& aFileName, RFs& aFsSession)
{
CZipFile* zipFile = 0;
CZipFileMember* member = 0;
CZipFileMemberIterator* fileMembers;
iConsole->Printf(KFileOpen, &aFileName);
zipFile = CZipFile::NewL(aFsSession, aFileName);
CleanupStack::PushL(zipFile);
iConsole->Printf(KOpenedSuccessfully, &aFileName);
// Search for a file in the zip archive.
// The name of the file to be searched for
// in the zipfile is case-insensitive.
_LIT(KSearchFile, "EzlibZipFolder\\icon.bmp");
member = zipFile->CaseInsensitiveMemberL(KSearchFile);
CleanupStack::PushL(member);
if(member != NULL)
{
// Extract the file that was searched for and found.
ExtractFilesL(member, zipFile, aFsSession, KExtractZipPathSingle);
iConsole->Printf(KFileExtract, &KSearchFile);
}
else
{
iConsole->Printf(KNoFilesFound);
}
CleanupStack::PopAndDestroy(member);
// Gets the iterator used for iterating through the files
// contained in the ZIP file.
fileMembers = zipFile->GetMembersL();
CleanupStack::PushL(fileMembers);
// Moves the entry iterator onto the next
// zip file member contained in the ZIP file
member = fileMembers->NextL();
iConsole->Printf(KFileZipExtract, &aFileName);
iConsole->Printf(KProperties);
iConsole->Getch();
// Get the properties of all the files
while(member != NULL)
{
CleanupStack::PushL(member);
// Retrieve CRC(Cyclic Redundancy Check) value in a compressed file
// contained in a CZipFile archive file.
TUint32 redundencyCode = member->CRC32();
// Retrieve the size of uncompressed file
// contained in a CZipFile archive file.
TUint32 UnCompSize = member->UncompressedSize();
// Retrieve the size of compressed file
// contained in a CZipFile archive file.
TUint32 CompSize = member->CompressedSize();
// Print the properties
// Name of the zipped file
TFileName fileName = *member->Name();
iConsole->Printf(KZipName, &fileName);
// CRC value which will be printed in hexadecimal
iConsole->Printf(KZipCRC32, redundencyCode);
// Size of the compressed file
iConsole->Printf(KZipCSize, CompSize);
// Original size of te file
iConsole->Printf(KZipUCSize,UnCompSize);
// Extract each member in the zip file
ExtractFilesL(member, zipFile, aFsSession, KExtractZipPathMulti);
CleanupStack::PopAndDestroy(member);
member = fileMembers->NextL();
}
CleanupStack::PopAndDestroy(fileMembers);
CleanupStack::PopAndDestroy(zipFile);
}
/**
Extracts and saves the members of a zip file to the
directory passed to the function as aOutputPath.
@param aMember Pointer to CZipFileMember class
@param aZipFile Pointer to CZipFile class
@param aFsSession File server session handle
@param aOutputPath Path where the file needs to be extracted to
@leave ... A system-wide error code.
*/
void CEzlibExample::ExtractFilesL(const CZipFileMember* aMember, CZipFile* aZipFile, RFs& aFsSession, const TDesC& aOutputPath)
{
TInt loop = 0;
// Allocate memory for the retrieved name of a
// compressed file contained in a CZipFile archive file.
HBufC* name = aMember->Name()->AllocLC();
while(loop < name->Length())
{
if((*name)[loop] == '/')
{
name->Des()[loop] = '\\';
}
loop++;
}
// Create the directory to which the files need to be extracted.
TFileName fn;
fn.Append(aOutputPath);
// Append the name of the file to the directory
// where the file would get extracted.
fn.Append(*name);
aFsSession.MkDirAll(fn);
RFile extractedMember;
extractedMember.Replace(aFsSession,fn, EFileShareAny|EFileWrite);
CleanupClosePushL(extractedMember);
RZipFileMemberReaderStream* fileStream;
// Create and return the input stream for a file in the archive.
TInt error = aZipFile->GetInputStreamL(aMember, fileStream);
if(error != KErrNone)
{
_LIT(KCompressionNotSupported, "Error! Compression Method Not Supported");
iConsole->Printf(KCompressionNotSupported);
iConsole->Printf(KLineSpace);
CleanupStack::PopAndDestroy(2,name); //expanded member, name
aFsSession.Delete(fn);
return;
}
CleanupStack::PushL(fileStream);
// Retrieve the size of uncompressed file contained
// in a CZipFile archive file.
TUint16 size = aMember->UncompressedSize();
RBuf8 bytes;
bytes.CreateL(size);
bytes.CleanupClosePushL();
// Read the specified number of bytes of binary data
// from the file at the current position.
User::LeaveIfError(fileStream->Read(bytes,size));
// Write to the file
User::LeaveIfError(extractedMember.Write(bytes));
CleanupStack::PopAndDestroy(4,name); // bytes, fileStream, expanded member and name
}
/**
Opens the icon.bmp.gz file and decompresses it to
the c:\\private\\e80000b7\\gzip\\extracts directory.
@param aFsSession File server session handle
@leave KErrAlreadyExists
@leave ... A system-wide error code.
*/
void CEzlibExample::ExtractGzipFileL(RFs& aFsSession)
{
iConsole->Printf(KPressAKey);
iConsole->Getch();
TFileName gzipInputFileName(KInputGzipFile);
RFile input;
RFile output;
User::LeaveIfError(input.Open(aFsSession, gzipInputFileName, EFileStream | EFileRead | EFileShareAny));
CleanupClosePushL(input);
TFileName outputFile(KCompressGzipPath);
// Append the path to the directory where you want to
// store the uncompressed file.
aFsSession.MkDirAll(outputFile);
outputFile.Append(KCompressZipFile);
// Create and open icon.bmp on
// c:\private\E80000B7\gzip\extracts\ folder.
output.Replace(aFsSession, outputFile, EFileStream | EFileWrite | EFileShareExclusive);
CleanupClosePushL(output);
// icon.bmp.gz file is the input file
TPtrC inputFile = gzipInputFileName;
RBuf uncompressedFile;
uncompressedFile.CreateL(outputFile.Length());
uncompressedFile.CleanupClosePushL();
_LIT(KUfl,"%S");
// Format and copy the filename into the descriptor
uncompressedFile.Format(KUfl,&inputFile);
_LIT(KInfo,"\nDecompressing file %S\n");
iConsole->Printf(KInfo,&inputFile);
CEZGZipToFile *def = CEZGZipToFile::NewLC(aFsSession,uncompressedFile,output);
// Decompress the gzip file
while(def->InflateL())
{
// InflateL decompresses the file in stages.
// It returns false when decompression is complete
}
iConsole->Printf(KDecompress);
CleanupStack::PopAndDestroy(4); // input, output, uncompressedFile, def
}
/**
Compresses the error.wav file into a gzip file and
stores it in the c:\\private\\e80000b7\\gzip\\extracts directory.
@param aFsSession File server session handle
@leave KErrAlreadyExists
@leave ... A system-wide error code.
*/
void CEzlibExample::CompressToGzipFileL(RFs& aFsSession)
{
iConsole->Printf(KPressAKey);
iConsole->Getch();
TFileName inputFileToBeGzipped(KInputGzipPath);
RFile input;
User::LeaveIfError(input.Open(aFsSession, inputFileToBeGzipped, EFileStream | EFileRead | EFileShareAny));
CleanupClosePushL(input);
// Set the output path to the directory where you
// want to store the compressed file.
TFileName outputFile(KCompressGzipPath);
aFsSession.MkDirAll(outputFile);
outputFile.Append(KExtractGzipFile);
iConsole->Printf(KFileInfo, &inputFileToBeGzipped);
// Prevent the length of the descriptor to which data is written,
// from exceeding its maximum length by appending additional length.
const TInt extensionLength = 3;
RBuf compressedFile;
compressedFile.CreateL(outputFile.Length() + extensionLength);
compressedFile.CleanupClosePushL();
_LIT(KAppendExtension,"%S.gz");
// Format and copy the filename into the descriptor
compressedFile.Format(KAppendExtension,&outputFile);
CEZFileToGZip *def = CEZFileToGZip::NewLC(aFsSession, compressedFile, input);
// Compress the file to gzip format
while(def->DeflateL())
{
// DeflateL compresses the file in stages.
// It returns false when compression is complete
}
iConsole->Printf(KCompress);
CleanupStack::PopAndDestroy(3); // def, compressedFile, input
}
LOCAL_C void MainL()
{
// Create an Active Scheduler to handle asychronous calls
CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
CleanupStack::PushL(scheduler);
CActiveScheduler::Install(scheduler);
CEzlibExample * app = CEzlibExample::NewLC();
RFs fsSession;
// Connect to file session
User::LeaveIfError(fsSession.Connect());
// Create the private directory on the writable drive
// i.e. "\private\E80000B7\"
// Note that the number E80000B7 is the process security id
// taken from the 2nd UID specified in the mmp file.
fsSession.CreatePrivatePath(RFs::GetSystemDrive());
// Set the session path to this private directory on the writable drive
fsSession.SetSessionToPrivate(RFs::GetSystemDrive());
// Get the properties of files in the zip file
TBuf<256> inputFileName(KInputZipFile);
app->GetPropertiesL(inputFileName, fsSession);
// Compress a file to gzip format
app->CompressToGzipFileL(fsSession);
// Extract a gzip file
app->ExtractGzipFileL(fsSession);
CleanupStack::PopAndDestroy(2); //app, scheduler
// Close the file session
fsSession.Close();
}
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
CTrapCleanup* cleanup = CTrapCleanup::New();
if(cleanup == NULL)
{
return KErrNoMemory;
}
TRAPD(err, MainL());
if(err != KErrNone)
{
User::Panic(_L("Failed to complete"),err);
}
delete cleanup;
__UHEAP_MARKEND;
return KErrNone;
}