Introduction
In my previous project, I had to include an option for making backup of the data. Since I didn't want to use some external tools (such as pkzip), I've decided to include a compression library by myself.
I've checked zlib and libbzip2. Eventually, I had to use bzip2 since I need small backup file and this library give better compression results
To make life simple, I made 2 classes to handle usage of compression/decompression
Using the code
class CBZ2Base
{
protected:
CBZ2Base(char* pWriteBuffer,unsigned int nWriteBufferSize);
protected:
bz_stream m_Stream;
char* m_pWriteBuffer;
unsigned int m_nWriteBufferSize;
};
The base class is
CBZ2Base
. The main classes (
CBZ2Compress,CBZ2Decompress
) are derived from the base class. It contains a private variable (
m_Stream
) to handle bzip2 library.
class CBZ2Compress : CBZ2Base
{
public:
CBZ2Compress(char* pWriteBuffer,unsigned int nWriteBufferSize,
int nBlockSize=9,int nWorkFactor=30);
virtual ~CBZ2Compress();
public:
unsigned int Compress();
protected:
virtual unsigned int OnCompressRead(char* &pBuffer)=0;
virtual void OnCompressWrite(const char* pBuffer,unsigned int nLength)=0;
};
class CBZ2Decompress : CBZ2Base
{
public:
CBZ2Decompress(char* pWriteBuffer,unsigned int nWriteBufferSize,
int nSmall=false);
virtual ~CBZ2Decompress();
public:
unsigned int Decompress();
protected:
virtual unsigned int OnDecompressRead(char* &pBuffer)=0;
virtual void OnDecompressWrite(const char* pBuffer,
unsigned int nLength)=0;
};
You need to allocate a buffer for the output data and pass it to the constructor. Each class contains two virtual functions for reading and writing of data. You need to override them and use your own code to fill the buffer when reading and handling the buffer when writing.
A simple code to handle file compressing:
class CMyCompression : public CBZ2Compress
{
public:
CMyCompression() : CBZ2Compress(m_szWriteBuffer,sizeof(m_szWriteBuffer))
{
}
BOOL Start(LPCTSTR szSource,LPCTSTR szTarget)
{
BOOL bResult=FALSE;
if (m_fileSource.Open(szSource,CFile::modeRead))
{
if (m_fileTarget.Open(szTarget,
CFile::modeCreate|CFile::modeWrite))
{
bResult=(Compress()>0);
m_fileTarget.Close();
}
m_fileSource.Close();
}
return bResult;
}
protected:
virtual unsigned int OnCompressRead(char *&pBuffer)
{
return m_fileSource.Read(pBuffer=m_szReadBuffer,
sizeof(m_szReadBuffer));
}
void OnCompressWrite(const char *pBuffer, unsigned int nLength)
{
m_fileTarget.Write(pBuffer,nLength);
}
private:
CFile m_fileSource,m_fileTarget;
char m_szReadBuffer[4096],m_szWriteBuffer[4096];
};
void main()
{
CMyCompression a;
a.Start(_T("test.tmp"),_T("test.bz2"));
}
Similar code will be used for decompressing
The included file contains a static library with both classes. There is also a simple demo to compress/decompress a file. You can check the demo source code to learn some more about using the classes.
Copyright
You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) You are allowed to modify the source code in any way you want. I would appreciate any acknowledgment from you regarding the usage of the classes