65.9K
CodeProject 正在变化。 阅读更多。
Home

Zlib 压缩/解压缩包装器,作为 ISequentialStream

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.17/5 (12投票s)

2003年2月1日

1分钟阅读

viewsIcon

108640

downloadIcon

3057

本文讨论了将压缩和解压缩包装在 ISeqentialStream 接口后面

Sample Image - zlibstream.jpg

引言

我一直在寻找一个压缩库,能够动态地从 IStream 接口压缩 XML 片段并解压缩它们。 有许多文件压缩库,大多数基于 zlib,但我需要自定义存储,例如结构化存储文件中的压缩流。

这是将 zlib 压缩库包装在 COM IStream 接口后面的首次尝试。 我提供了一个纯 ATL C++ 实现和一个简单的基于 COM 的实现。 两者都将 IStream 作为初始化器,并在 ReadWrite 方法上动态压缩/解压缩。

使用代码

我希望这对更多人有用。 我还没有尝试过使用 MSXML SAX 解析器,但据我了解,SAX 解析器应该只需要 ISequentialStream 接口,因此应该可以很好地与此实现一起工作。

这些类包含在头文件 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;
//

以下代码片段演示了如何在 IStream 上使用 C++ 包装器

// 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);
zw.Cleanup();


// 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);
zr.Cleanup();

以下代码片段演示了如何在 IStream 上使用 COM 包装器

// 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))))
{
    spWrite->Initialize(CComVariant(spStm));
    CComQIPtr<ISequentialStream> spSeq = spWrite;
    spSeq->Write((void*)buffer, bufLen, &cb);

    //cleanup
    spWrite.Release();
}


// 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))))
{
    spRead->Initialize(CComVariant(spStm));
    CComQIPtr<ISequentialStream> spSeq = spRead;
    spSeq->Read((void*)buffer, bufLen, &cb);

    //cleanup
    spRead.Release();
}

关注点

到目前为止,唯一的问题是同步 zlib 中的 zstream 缓冲区,以便数据可用于 ReadWrite IStream 函数。

演示项目包含 zlib 1.1.4 的静态库

链接

zlib 网站

历史

2003.01.24 首次实现

© . All rights reserved.