Symbian
Symbian Developer Library

SYMBIAN OS V9.4

Feedback

[Index] [Previous] [Next]


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:

[Top]


Description

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.

[Top]


Class summary

Related APIs

[Top]


Build

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.

[Top]


Example code


bld.inf

// 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

// 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

// 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

// 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;
    }