zlib.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #pragma once
  2. #include "fwd.h"
  3. #include "input.h"
  4. #include "output.h"
  5. #include "buffered.h"
  6. #include <util/system/defaults.h>
  7. #include <util/generic/ptr.h>
  8. #include <util/generic/yexception.h>
  9. /**
  10. * @addtogroup Streams_Archs
  11. * @{
  12. */
  13. struct TZLibError: public yexception {
  14. };
  15. struct TZLibCompressorError: public TZLibError {
  16. };
  17. struct TZLibDecompressorError: public TZLibError {
  18. };
  19. namespace ZLib {
  20. enum StreamType: ui8 {
  21. Auto = 0, /**< Auto detect format. Can be used for decompression only. */
  22. ZLib = 1,
  23. GZip = 2,
  24. Raw = 3,
  25. Invalid = 4
  26. };
  27. enum {
  28. ZLIB_BUF_LEN = 8 * 1024
  29. };
  30. } // namespace ZLib
  31. /**
  32. * Non-buffered ZLib decompressing stream.
  33. *
  34. * Please don't use `TZLibDecompress` if you read text data from stream using
  35. * `ReadLine`, it is VERY slow (approx 10 times slower, according to synthetic
  36. * benchmark). For fast buffered ZLib stream reading use `TBufferedZLibDecompress`
  37. * aka `TZDecompress`.
  38. */
  39. class TZLibDecompress: public IInputStream {
  40. public:
  41. TZLibDecompress(IZeroCopyInput* input, ZLib::StreamType type = ZLib::Auto, TStringBuf dict = {});
  42. TZLibDecompress(IInputStream* input, ZLib::StreamType type = ZLib::Auto, size_t buflen = ZLib::ZLIB_BUF_LEN,
  43. TStringBuf dict = {});
  44. /**
  45. * Allows/disallows multiple sequential compressed streams. Allowed by default.
  46. *
  47. * If multiple streams are allowed, their decompressed content will be concatenated.
  48. * If multiple streams are disabled, then only first stream is decompressed. After that end
  49. * of IInputStream will have happen, i.e. method Read() will return 0.
  50. *
  51. * @param allowMultipleStreams - flag to allow (true) or disable (false) multiple streams.
  52. */
  53. void SetAllowMultipleStreams(bool allowMultipleStreams);
  54. ~TZLibDecompress() override;
  55. protected:
  56. size_t DoRead(void* buf, size_t size) override;
  57. public:
  58. class TImpl;
  59. THolder<TImpl> Impl_;
  60. };
  61. /**
  62. * Non-buffered ZLib compressing stream.
  63. */
  64. class TZLibCompress: public IOutputStream {
  65. public:
  66. struct TParams {
  67. inline TParams(IOutputStream* out)
  68. : Out(out)
  69. , Type(ZLib::ZLib)
  70. , CompressionLevel(6)
  71. , BufLen(ZLib::ZLIB_BUF_LEN)
  72. {
  73. }
  74. inline TParams& SetType(ZLib::StreamType type) noexcept {
  75. Type = type;
  76. return *this;
  77. }
  78. inline TParams& SetCompressionLevel(size_t level) noexcept {
  79. CompressionLevel = level;
  80. return *this;
  81. }
  82. inline TParams& SetBufLen(size_t buflen) noexcept {
  83. BufLen = buflen;
  84. return *this;
  85. }
  86. inline TParams& SetDict(const TStringBuf dict) noexcept {
  87. Dict = dict;
  88. return *this;
  89. }
  90. IOutputStream* Out;
  91. ZLib::StreamType Type;
  92. size_t CompressionLevel;
  93. size_t BufLen;
  94. TStringBuf Dict;
  95. };
  96. inline TZLibCompress(const TParams& params) {
  97. Init(params);
  98. }
  99. inline TZLibCompress(IOutputStream* out, ZLib::StreamType type) {
  100. Init(TParams(out).SetType(type));
  101. }
  102. inline TZLibCompress(IOutputStream* out, ZLib::StreamType type, size_t compression_level) {
  103. Init(TParams(out).SetType(type).SetCompressionLevel(compression_level));
  104. }
  105. inline TZLibCompress(IOutputStream* out, ZLib::StreamType type, size_t compression_level, size_t buflen) {
  106. Init(TParams(out).SetType(type).SetCompressionLevel(compression_level).SetBufLen(buflen));
  107. }
  108. ~TZLibCompress() override;
  109. private:
  110. void Init(const TParams& opts);
  111. void DoWrite(const void* buf, size_t size) override;
  112. void DoFlush() override;
  113. void DoFinish() override;
  114. public:
  115. class TImpl;
  116. /** To allow inline constructors. */
  117. struct TDestruct {
  118. static void Destroy(TImpl* impl);
  119. };
  120. THolder<TImpl, TDestruct> Impl_;
  121. };
  122. /**
  123. * Buffered ZLib decompressing stream.
  124. *
  125. * Supports efficient `ReadLine` calls and similar "reading in small pieces"
  126. * usage patterns.
  127. */
  128. class TBufferedZLibDecompress: public TBuffered<TZLibDecompress> {
  129. public:
  130. template <class T>
  131. inline TBufferedZLibDecompress(T* in, ZLib::StreamType type = ZLib::Auto, size_t buf = 1 << 13)
  132. : TBuffered<TZLibDecompress>(buf, in, type)
  133. {
  134. }
  135. ~TBufferedZLibDecompress() override;
  136. };
  137. /** @} */