Symbian
Symbian Developer Library

SYMBIAN OS V9.4

Feedback

[Index] [Previous] [Next]


How to use EZLib

Introduction

This document describes how to use the EZLib library to compress and decompress files, file archive, and memory streams. The files can be compressed to ZIP and GZIP formats and decompressed from the same using the EZLib library.

EZLib is a compression library based on Version 1.2.3 of Zlib. Zlib is a freeware library available to download from the Zlib website. It is written in C and hence exports a C interface. EZLib provides C++ wrapper classes that encapsulate the functionality of Zlib. These classes simplify the use of the compression library.

EZLib allows clients to compress and decompress data from files and buffers. These tasks are performed iteratively by calling the compression or decompression functions until the required task is complete. Clients must respond to callbacks from the library to provide information and resources required to complete the task.

The EZLib library supports two file formats as shown below:

[Top]


Compression and decompression of memory streams

The CEZCompressor class provides memory stream compression and decompression functions, while performing integrity checks on the compressed/uncompressed data.

Compression of memory streams

The compression of memory streams can be performed in single or multiple steps based on the size of the buffer. Compression is done for a small buffer in a single step by calling the CompressL() function for small memory bits. Larger memory buffers can be compressed by repeatedly calling the DeflateL() function until the entire buffer is compressed to the target buffer.

Decompression of memory streams

The decompression of memory streams can be performed using the DecompressL() function or by calling InflateL() repeatedly until the source data is decompressed to the target buffer.

[Top]


Compression and decompression of files

Compression and decompression can be performed on two file formats:

How-to zip and unzip files

The compression of a file into a zip file can be achieved by specifying the input and output files, together with other compression parameters as shown in the example code below. The CEZFileBufferManager class provides functions that accept the input and output files as parameters and converts the data into buffers for MEZBufferManager class to manage it internally. Then this buffer is passed with other compression parameters to the object of the CEZCompressor class. The client then calls the DeflateL() function iteratively until the zip file is created.

/*
 * Compresses the file into a Zip file using the EZlib component. 
 * It is assumed that the input and output file names are contained in a 
 * provided ini file.
 */


void CEZlibEZipTests::DoEZlibDeflateL()
    {

    //Open input file
_LIT(KInputFile, "c:\\private\\E80000B7\\zip\\input\\Ezlib.doc");
TFileName inputFile(KInputFile);
    RFile input;
    err = input.Open(iRfs, inputFile, EFileStream | EFileRead | EFileShareExclusive);
    if(err != KErrNone)
        {
        INFO_PRINTF1(KOpenFileError);
        User::Leave(err);
        }   
    
    CleanupClosePushL(input);

    //open output file

_LIT(KOutputFile, "c:\\private\\E80000B7\\zip\\input\\Ezlib.zip");
TFileName outputFile(KOutputFile);
    RFile output;
    err = output.Replace(iRfs, outputFile, EFileStream | EFileWrite | EFileShareExclusive);
    if(err != KErrNone)
        {
        INFO_PRINTF1(KCreateFileError);
        User::Leave(err);
        }   
        CleanupClosePushL(output);

    CEZFileBufferManager *bufferManager = CEZFileBufferManager::NewLC(input, output);   
    CEZCompressor *compressor = CEZCompressor::NewLC(*bufferManager, aLevel, aWindowBits, aMemLevel, aStrategy);

    while(compressor->DeflateL())
        {       
        }   
    
    CleanupStack::PopAndDestroy(4);
    
    CEZFileBufferManager *bufferManager = CEZFileBufferManager::NewLC(input, output);   
    CEZCompressor *compressor = CEZCompressor::NewLC(*bufferManager, aLevel, aWindowBits, aMemLevel, aStrategy);

    
    while(compressor->DeflateL())
        {       
        }   
        
    }
    
    
    

The decompression of the zip file is performed similarly by passing the input and output file to an instance of the CEZFileBufferManager class. This converts the data into memory streams, internally managed by the MEZBufferManager class. The buffer is then passed to the object of the CEZDecompressor class. The client then calls the InflateL() function repeatedly until the decompression is complete. The following code demonstrates the decompression scenario.

/* Decompresses the file contained in a Zip file using the EZlib component. 
 * It is assumed that the input and output file names are contained in a 
 * provided ini file.
 */

void CEZlibEZipTests::DoEZlibInflateL()
    {
//Open input file
_LIT(KInputFile, "c:\\private\\E80000B7\\zip\\input\\Ezlib.zip");
TFileName inputFile(KInputFile);
    RFile input;
    err = input.Open(iRfs, inputFile, EFileStream | EFileRead | EFileShareExclusive);
    if(err != KErrNone)
        {
        INFO_PRINTF1(KOpenFileError);
        User::Leave(err);
        }   
    
    CleanupClosePushL(input);

    //open output file

_LIT(KOutputFile, "c:\\private\\E80000B7\\zip\\input\\Ezlib.doc");
TFileName outputFile(KOutputFile);
    RFile output;
    err = output.Replace(iRfs, OutputFile, EFileStream | EFileWrite | EFileShareExclusive);
    if(err != KErrNone)
        {
        INFO_PRINTF1(KCreateFileError);
        User::Leave(err);
        }   
        CleanupClosePushL(output);


CEZFileBufferManager *bufferManager = CEZFileBufferManager::NewLC(input, Output);   
CEZDecompressor *decompressor = CEZDecompressor::NewLC(*bufferManager, aWindowBits);


    while(decompressor->InflateL())
        {       
        }   
        
    CleanupStack::PopAndDestroy(4);
    }

How-to compress a file to a GZip file

The process of compressing a file to a Gzip file can be carried out by passing the uncompressed file along with the name of the target GZip file to an instance of the CEZFileToGZip class. The client then uses the DeflateL() function to compress the file to the required format. The code below explains the compression procedure.

/*
 * Compresses a file to a GZip file using the EZlib component. If 
 * input and output file names are not specified then it is assumed that 
 * the file names are contained in a provided ini file.
 */
void CEZlibEZipTests::DoEZlibGZipDeflateL()
    {
    
    //Open input file
_LIT(KInputFile, "c:\\private\\E80000B7\\zip\\input\\Ezlib.doc");
TFileName inputFile(KInputFile);
    RFile input;
    err = input.Open(iRfs, inputFile, EFileStream | EFileRead | EFileShareExclusive);
    if(err != KErrNone)
        {
        INFO_PRINTF1(KOpenFileError);
        User::Leave(err);
        }   
    
    CleanupClosePushL(input);

    //open output file

_LIT(KOutputFile, "c:\\private\\E80000B7\\zip\\input\\Ezlib.gz");
TFileName outputFile(KOutputFile);
    RFile output;
    err = output.Replace(iRfs, OutputFile, EFileStream | EFileWrite | EFileShareExclusive);
    if(err != KErrNone)
        {
        INFO_PRINTF1(KCreateFileError);
        User::Leave(err);
        }   
        CleanupClosePushL(output);

    
    CEZFileToGZip *compressor = CEZFileToGZip::NewLC(iRfs, iOutputFileLocation, iInputFile);

    
    while(compressor->DeflateL())
        {       
        }   
    
        
    CleanupStack::PopAndDestroy(2);
    }

How-to decompress a GZip file

Decompressing a file contained in the GZip format can be performed by passing the GZip file and the input file name to the constructor of the CEZGZipToFile class. The client then calls the InflateL() function repeatedly until the decompression is complete.

/*
 * Decompresses the file contained in a GZip file using the EZlib component. If 
 * input and output file names are not specified then it is assumed that 
 * the file names are contained in a provided ini file.
 */
void CEZlibEZipTests::DoEZlibGZipInflateL()
    {
    
    //open output file

_LIT(KOutputFile, "c:\\private\\E80000B7\\zip\\input\\Ezlib.doc");
TFileName outputFile(KOutputFile);
    RFile output;
    err = output.Replace(iRfs, OutputFile, EFileStream | EFileWrite | EFileShareExclusive);
    if(err != KErrNone)
        {
        INFO_PRINTF1(KCreateFileError);
        User::Leave(err);
        }   
        CleanupClosePushL(output);

    CEZGZipToFile *decompressor = CEZGZipToFile::NewLC(iRfs, iInputFileLocation, iOutputFile);

        while(decompressor->InflateL())
        {       
        }   

        
    CleanupStack::PopAndDestroy(2);
    }

[Top]


Decompression of file archive

The decompression of a file archive involves the input file being passed to the constructor of the CZipFile class. Note that the CZipFile is a read only interface and hence does not support compression of files to a zip archive. Furthermore, it does not support multiple zip file archives.

The input archive file is opened to get the properties of all the files in the archive. Each member of the zip archive is accessed through the CZipFileMemberIterator iterator class. This class provides functions to point to the first file in the archive and to move through all the entries in the archive. Once a member file is accessible, its properties can be retrieved by the CZipFileMember class.

The extracted files from the archive is stored in the output folder. If the output folder is not available a new folder is created before the archive is decompressed. The following example code illustrates the decompression of file archive .

/*
 * Decompresses all the files in a Zip Archive using the EZlib 
 * component. If an input filename is not specified it is assumed that the 
 * input file name is contained in a provided ini file.
 */
void CEZlibEZipTests::DoEZlibZipArchiveDecompressL()
    {
    TInt err = KErrNone;
    HBufC8 *outputBuffer = HBufC8::NewLC(outputBufferSize);  
    
    _LIT(KInputFile, "c:\\private\\E80000B7\\zip\\input\\EzlibArchive.zip");
    TFileName inputFile(KInputFile);
    
    RFile input;
    err = input.Open(iRfs, inputFile, EFileStream | EFileRead | EFileShareExclusive);
    if(err != KErrNone)
        {
        INFO_PRINTF1(KOpenFileError);
        User::Leave(err);
        }   
    CleanupClosePushL(input);
        
    CZipFile *zipFile = CZipFile::NewL(iRfs, input);
    CleanupStack::PushL(zipFile);   
    CZipFileMemberIterator *fileMemberIter = zipFile->GetMembersL();

//  iZipArchiveEzlibFolder = GenerateZipArchiveFolderNameL(aInputFileName);
//  iZipArchiveEzlibFolder.Append(KZipArchiveEzlib);
    
    for(TOLDEZIP::CZipFileMember *fileMember = fileMemberIter->NextL(); fileMember != NULL; fileMember = fileMemberIter->NextL())
        {   
        TFileName tmpfilename(*(fileMember->Name()));

        // Check if we have a folder or file
        TPtrC lastChar = tmpfilename.Right(1);
        if(lastChar.Compare(_L("\\")) != 0 && lastChar.Compare(_L("/")) != 0)
            {
            //
            RFile output;
            err = output.Replace(iRfs, tmpfilename, EFileStream | EFileWrite | EFileShareExclusive);
            if(err != KErrNone)
                {
                INFO_PRINTF1(KCreateFileError);
                User::Leave(err);
                }   
            CleanupClosePushL(output);
                    
            TOLDEZIP::RZipFileMemberReaderStream *readerStream;
            zipFile->GetInputStreamL(fileMember, readerStream);
            CleanupStack::PushL(readerStream);
                    
            TPtr8 pOutputBuffer = outputBuffer->Des();            
            do
                {
                err = readerStream->Read(pOutputBuffer, outputBufferSize);
                output.Write(pOutputBuffer);
                } while(err == KErrNone);

            if(err != KErrEof)
                {
                User::Leave(err);
                }
            
            CleanupStack::PopAndDestroy(2);
            }   
        else
            {
            
            TFileName fullPath("c:\\private\\E80000B7\\zip\\input\\");
            fullPath.Append(tmpfilename);
            iRfs.MkDir(fullPath);
            }
        }

    CleanupStack::PopAndDestroy(3);
    }