123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- #pragma once
- #include "fwd.h"
- #include "input.h"
- #include "output.h"
- #include "buffered.h"
- #include <util/system/defaults.h>
- #include <util/generic/ptr.h>
- #include <util/generic/yexception.h>
- /**
- * @addtogroup Streams_Archs
- * @{
- */
- struct TZLibError: public yexception {
- };
- struct TZLibCompressorError: public TZLibError {
- };
- struct TZLibDecompressorError: public TZLibError {
- };
- namespace ZLib {
- enum StreamType: ui8 {
- Auto = 0, /**< Auto detect format. Can be used for decompression only. */
- ZLib = 1,
- GZip = 2,
- Raw = 3,
- Invalid = 4
- };
- enum {
- ZLIB_BUF_LEN = 8 * 1024
- };
- } // namespace ZLib
- /**
- * Non-buffered ZLib decompressing stream.
- *
- * Please don't use `TZLibDecompress` if you read text data from stream using
- * `ReadLine`, it is VERY slow (approx 10 times slower, according to synthetic
- * benchmark). For fast buffered ZLib stream reading use `TBufferedZLibDecompress`
- * aka `TZDecompress`.
- */
- class TZLibDecompress: public IInputStream {
- public:
- TZLibDecompress(IZeroCopyInput* input, ZLib::StreamType type = ZLib::Auto, TStringBuf dict = {});
- TZLibDecompress(IInputStream* input, ZLib::StreamType type = ZLib::Auto, size_t buflen = ZLib::ZLIB_BUF_LEN,
- TStringBuf dict = {});
- /**
- * Allows/disallows multiple sequential compressed streams. Allowed by default.
- *
- * If multiple streams are allowed, their decompressed content will be concatenated.
- * If multiple streams are disabled, then only first stream is decompressed. After that end
- * of IInputStream will have happen, i.e. method Read() will return 0.
- *
- * @param allowMultipleStreams - flag to allow (true) or disable (false) multiple streams.
- */
- void SetAllowMultipleStreams(bool allowMultipleStreams);
- ~TZLibDecompress() override;
- protected:
- size_t DoRead(void* buf, size_t size) override;
- public:
- class TImpl;
- THolder<TImpl> Impl_;
- };
- /**
- * Non-buffered ZLib compressing stream.
- */
- class TZLibCompress: public IOutputStream {
- public:
- struct TParams {
- inline TParams(IOutputStream* out)
- : Out(out)
- , Type(ZLib::ZLib)
- , CompressionLevel(6)
- , BufLen(ZLib::ZLIB_BUF_LEN)
- {
- }
- inline TParams& SetType(ZLib::StreamType type) noexcept {
- Type = type;
- return *this;
- }
- inline TParams& SetCompressionLevel(size_t level) noexcept {
- CompressionLevel = level;
- return *this;
- }
- inline TParams& SetBufLen(size_t buflen) noexcept {
- BufLen = buflen;
- return *this;
- }
- inline TParams& SetDict(const TStringBuf dict) noexcept {
- Dict = dict;
- return *this;
- }
- IOutputStream* Out;
- ZLib::StreamType Type;
- size_t CompressionLevel;
- size_t BufLen;
- TStringBuf Dict;
- };
- inline TZLibCompress(const TParams& params) {
- Init(params);
- }
- inline TZLibCompress(IOutputStream* out, ZLib::StreamType type) {
- Init(TParams(out).SetType(type));
- }
- inline TZLibCompress(IOutputStream* out, ZLib::StreamType type, size_t compression_level) {
- Init(TParams(out).SetType(type).SetCompressionLevel(compression_level));
- }
- inline TZLibCompress(IOutputStream* out, ZLib::StreamType type, size_t compression_level, size_t buflen) {
- Init(TParams(out).SetType(type).SetCompressionLevel(compression_level).SetBufLen(buflen));
- }
- ~TZLibCompress() override;
- private:
- void Init(const TParams& opts);
- void DoWrite(const void* buf, size_t size) override;
- void DoFlush() override;
- void DoFinish() override;
- public:
- class TImpl;
- /** To allow inline constructors. */
- struct TDestruct {
- static void Destroy(TImpl* impl);
- };
- THolder<TImpl, TDestruct> Impl_;
- };
- /**
- * Buffered ZLib decompressing stream.
- *
- * Supports efficient `ReadLine` calls and similar "reading in small pieces"
- * usage patterns.
- */
- class TBufferedZLibDecompress: public TBuffered<TZLibDecompress> {
- public:
- template <class T>
- inline TBufferedZLibDecompress(T* in, ZLib::StreamType type = ZLib::Auto, size_t buf = 1 << 13)
- : TBuffered<TZLibDecompress>(buf, in, type)
- {
- }
- ~TBufferedZLibDecompress() override;
- };
- /** @} */
|