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






4.17/5 (12投票s)
2003年2月1日
1分钟阅读

108640

3057
本文讨论了将压缩和解压缩包装在 ISeqentialStream 接口后面
引言
我一直在寻找一个压缩库,能够动态地从 IStream
接口压缩 XML 片段并解压缩它们。 有许多文件压缩库,大多数基于 zlib,但我需要自定义存储,例如结构化存储文件中的压缩流。
这是将 zlib 压缩库包装在 COM IStream
接口后面的首次尝试。 我提供了一个纯 ATL C++ 实现和一个简单的基于 COM 的实现。 两者都将 IStream
作为初始化器,并在 Read
和 Write
方法上动态压缩/解压缩。
使用代码
我希望这对更多人有用。 我还没有尝试过使用 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
缓冲区,以便数据可用于 Read
和 Write
IStream
函数。
演示项目包含 zlib 1.1.4 的静态库
链接
历史
2003.01.24 首次实现