Click here to Skip to main content
12,819,913 members (29,895 online)
Click here to Skip to main content
Add your own
alternative version


50 bookmarked
Posted 31 Jan 2003

Zlib compression / decompression wrapper as ISequentialStream

, 31 Jan 2003
Rate this:
Please Sign up or sign in to vote.
This article discusses wrapping compression and decompression behind a ISeqentialStream interface
<!-- Download Links --> <!-- Article image -->

Sample Image - zlibstream.jpg

<!-- Add the rest of your HTML here -->


I have been looking for a compression library that can compress XML fragments on the fly from the IStream interface and decompress it back. There are several file compression libraries, most based on zlib , but I needed custom storage such as compressed streams inside structured storage files.

This is a first shot at wrapping zlib compression library behind a COM IStream interface. I provide a pure ATL C++ implementation and a simple demo COM based implementation. Both take an IStream as an initializer and compress/decompress on the fly on the Read and Write methods.

Using the code

I hope this will be usefull for more people than me. I haven't tried this with MSXML SAX Parser yet but as I understand it the SAX Parser should bot need more than the ISequentialStream interface and thus should work fine with this implementation.

These are the classes found in the header file zlibistream.h

// ZSequentialStreamBase , base class for the implementaion classes
// Implementation classes for ISequentialStream interfaces, constrained to
// either writing or reading. Template class T needs to provide implementaion
// for overridable member functions FillBuffer and EmptyBuffer.
// template<class T, int bufferSize=16384> class ZReadSequentialStreamImpl;
// template<class T, int bufferSize=16384> class ZWriteSequentialStreamImpl;
// Implementation of read and write sequential streams based on implementation
// classes above. These classe overrides the FillBuffer and EmptyBuffer by
// reading from or writing to a user supplied stream.
// template<int bufferSize=16384> class ZReadSequentialStreamT;
// template<int bufferSize=16384> class ZWriteSequentialStreamT;
// Convenience typedef's for stackbased classes (no AddRef(), Release() or QI)
// typedef CComObjectStack<ZWriteSequentialStreamT<> > ZWriteSequentialStream;
// typedef CComObjectStack<ZReadSequentialStreamT<> > ZReadSequentialStream;

The following snippets shows how to use the C++ wrapper on an IStream

// Writing to a stream
CComPtr<IStream> spStm;
... // get an IStream for writing to storage

// Use zlib sequential stream implementation for writing (compression)
ZWriteSequentialStream zw;
zw.Initialize(spStm); // initialize for writing to the IStream
zw.Write((void*)buffer, bufLen, &cb);

// Reading from a stream
CComPtr<IStream> spStm;
... // get an IStream for reading from storage

// Use zlib sequential stream implementation for reading (decompression)
ZReadSequentialStream zr;
zr.Initialize(spStm); // initialize for reading from the IStream
zr.Read((void*)buffer, bufLen, &cb);

The following snippets shows how to use the COM wrapper on an IStream

// Writing to a stream
CComPtr<IStream> spStm;
... // get an IStream for writing to storage

// Use COM wrapper for writing (compression)
CComPtr<IZWriteSeqStream> spWrite;
if (SUCCEEDED(spWrite.CoCreateInstance(__uuidof(ZWriteSeqStream))))
    CComQIPtr<ISequentialStream> spSeq = spWrite;
    spSeq->Write((void*)buffer, bufLen, &cb);


// Reading from a stream
CComPtr<IStream> spStm;
... // get an IStream for reading from storage

// Use COM wrapper for reading (decompression)
CComPtr<IZReadSeqStream> spRead;
if (SUCCEEDED(spRead.CoCreateInstance(__uuidof(ZReadSeqStream))))
    CComQIPtr<ISequentialStream> spSeq = spRead;
    spSeq->Read((void*)buffer, bufLen, &cb);


Points of Interest

The only problem, so far, was to synchronize the zstream buffer in zlib so the data is available for the Read and Write IStream functions.

The demo project includes a static library for zlib 1.1.4


zlib web site


2003.01.24 First implementation


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Jens Nilsson
Web Developer
Sweden Sweden
No Biography provided

You may also be interested in...

Comments and Discussions

GeneralIZWriteSeqStream exists nowhere but in the text of this article Pin
babaa7-Mar-08 2:20
memberbabaa7-Mar-08 2:20 
GeneralRe: IZWriteSeqStream exists nowhere but in the text of this article Pin
babaa7-Mar-08 3:48
memberbabaa7-Mar-08 3:48 
GeneralBigger file handling. Pin
jagatnibas13-Nov-07 12:39
memberjagatnibas13-Nov-07 12:39 
I have a class implementing zlib which works great as long as I keep input stream classes small. But if I give bigger stream it crashes always in this function [in the bold faced code lines.]. At the time of crash I always find m_anWindow {is an chararry} of length 32568. Please give me some ideas how can I handle bigger data.

thanks and regards
--J Smile | :)

* Copies recently decompressed bytes from the output buffer to a "sliding
* window" buffer, preserving a history from which to lift repeated strings. The
* size of the buffer depends on a setting found in the ZLib headers, or, if none
* are present, defaults to 32k. The buffer is circular, so a cursor keeps track
* of the current write position.
* @param nStart the offset into m_anOut from which to start the
* copy (m_nOutTail is the implicit ending offset)
void InflaterInputStream::copyToWindow( int nStart )
// If the sliding window doesn't exist yet, allocate it.
if( null == m_anWindow.GetPointer() )
m_anWindow.setPointer((char*)new byte[ m_nWindowSize ], m_nWindowSize);

int nAvail = m_nWindowSize - m_nWindowTail;
int nCopy = m_nOutTail - nStart;

// If we're being asked to copy bytes across the window's discontinuity, we'll
// need to break the operation into two steps.
if( nCopy > nAvail )
// Copy as many bytes as will fit in the remaining window space.
// System.arraycopy( m_anOut, nStart, m_anWindow, m_nWindowTail, nAvail );
MEMCPY(m_anWindow.GetPointer() + m_nWindowTail, m_anOut.GetPointer() + nStart, nAvail); //To ask

m_nWindowTail = 0;

// Update our totals before completing the copy in the next step.
nStart += nAvail;
nCopy -= nAvail;

// Copy bytes from the output buffer to the sliding window, updating the
// position of the cursor into the circular buffer.

MEMCPY(m_anWindow.GetPointer() + m_nWindowTail, m_anOut.GetPointer()+nStart, nCopy);
m_nWindowTail += nCopy;
QuestionHuge file / incremental support? Pin
NeverShaveYourDuck13-Aug-07 11:13
memberNeverShaveYourDuck13-Aug-07 11:13 
QuestionCan not compile "zlibstream_demo" in VS 2005 Pin
R_PR12-Jul-07 6:53
memberR_PR12-Jul-07 6:53 
QuestionNeed Help: Issue with ZlibCleanup Pin
Dennis Jiang12-Jan-07 23:03
memberDennis Jiang12-Jan-07 23:03 
Generalgreat article! Pin
stefandreilog24-Nov-05 1:15
memberstefandreilog24-Nov-05 1:15 
GeneralIStream with gzFile Pin
Mario Turaccio19-Jul-05 23:20
memberMario Turaccio19-Jul-05 23:20 
GeneralDemo project corrupted. Pin
TW5-Feb-03 0:06
memberTW5-Feb-03 0:06 
GeneralRe: Demo project corrupted. Pin
Jens Nilsson6-Feb-03 12:03
memberJens Nilsson6-Feb-03 12:03 
GeneralRe: Demo project corrupted. Pin
Anonymous6-Feb-03 23:06
sussAnonymous6-Feb-03 23:06 
GeneralRe: Demo project corrupted. Pin
Jens Nilsson7-Feb-03 9:20
memberJens Nilsson7-Feb-03 9:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170308.1 | Last Updated 1 Feb 2003
Article Copyright 2003 by Jens Nilsson
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid