<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.1" />

ZInputStream

public class ZInputStream : BaseInputStream
using Org.BouncyCastle.Utilities.IO; using System.IO; namespace Org.BouncyCastle.Utilities.Zlib { public class ZInputStream : BaseInputStream { private const int BufferSize = 4096; protected ZStream z; protected int flushLevel; protected byte[] buf = new byte[4096]; protected byte[] buf1 = new byte[1]; protected bool compress; protected Stream input; protected bool closed; private bool nomoreinput; public virtual int FlushMode { get { return flushLevel; } set { flushLevel = value; } } public virtual long TotalIn => z.total_in; public virtual long TotalOut => z.total_out; private static ZStream GetDefaultZStream(bool nowrap) { ZStream zStream = new ZStream(); zStream.inflateInit(nowrap); return zStream; } public ZInputStream(Stream input) : this(input, false) { } public ZInputStream(Stream input, bool nowrap) : this(input, GetDefaultZStream(nowrap)) { } public ZInputStream(Stream input, ZStream z) { if (z == null) z = new ZStream(); if (z.istate == null && z.dstate == null) z.inflateInit(); this.input = input; compress = (z.istate == null); this.z = z; this.z.next_in = buf; this.z.next_in_index = 0; this.z.avail_in = 0; } public ZInputStream(Stream input, int level) : this(input, level, false) { } public ZInputStream(Stream input, int level, bool nowrap) { this.input = input; compress = true; z = new ZStream(); z.deflateInit(level, nowrap); z.next_in = buf; z.next_in_index = 0; z.avail_in = 0; } protected void Detach(bool disposing) { if (disposing) ImplDisposing(false); base.Dispose(disposing); } protected override void Dispose(bool disposing) { if (disposing) ImplDisposing(true); base.Dispose(disposing); } private void ImplDisposing(bool disposeInput) { if (!closed) { closed = true; if (disposeInput) input.Dispose(); } } public override int Read(byte[] buffer, int offset, int count) { Streams.ValidateBufferArguments(buffer, offset, count); if (count == 0) return 0; z.next_out = buffer; z.next_out_index = offset; z.avail_out = count; int num; do { if (z.avail_in == 0 && !nomoreinput) { z.next_in_index = 0; z.avail_in = input.Read(buf, 0, buf.Length); if (z.avail_in <= 0) { z.avail_in = 0; nomoreinput = true; } } num = (compress ? z.deflate(flushLevel) : z.inflate(flushLevel)); if (nomoreinput && num == -5) return 0; if (num != 0 && num != 1) throw new IOException((compress ? "de" : "in") + "flating: " + z.msg); if ((nomoreinput || num == 1) && z.avail_out == count) return 0; } while (z.avail_out == count && num == 0); return count - z.avail_out; } public override int ReadByte() { if (Read(buf1, 0, 1) <= 0) return -1; return buf1[0]; } } }