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

ZOutputStream

using Org.BouncyCastle.Utilities.IO; using System.IO; namespace Org.BouncyCastle.Utilities.Zlib { public class ZOutputStream : BaseOutputStream { 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 output; protected bool closed; 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 ZOutputStream(Stream output) : this(output, false) { } public ZOutputStream(Stream output, bool nowrap) : this(output, GetDefaultZStream(nowrap)) { } public ZOutputStream(Stream output, ZStream z) { if (z == null) z = new ZStream(); if (z.istate == null && z.dstate == null) z.inflateInit(); this.output = output; compress = (z.istate == null); this.z = z; } public ZOutputStream(Stream output, int level) : this(output, level, false) { } public ZOutputStream(Stream output, int level, bool nowrap) { this.output = output; compress = true; z = new ZStream(); z.deflateInit(level, nowrap); } 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 disposeOutput) { if (!closed) try { Finish(); } catch (IOException) { } finally { closed = true; End(); if (disposeOutput) output.Dispose(); output = null; } } public virtual void End() { if (z != null) { if (compress) z.deflateEnd(); else z.inflateEnd(); z.free(); z = null; } } public virtual void Finish() { do { z.next_out = buf; z.next_out_index = 0; z.avail_out = buf.Length; int num = compress ? z.deflate(4) : z.inflate(4); if (num != 1 && num != 0) throw new IOException((compress ? "de" : "in") + "flating: " + z.msg); int num2 = buf.Length - z.avail_out; if (num2 > 0) output.Write(buf, 0, num2); } while (z.avail_in > 0 || z.avail_out == 0); Flush(); } public override void Flush() { output.Flush(); } public override void Write(byte[] buffer, int offset, int count) { Streams.ValidateBufferArguments(buffer, offset, count); if (count == 0) return; z.next_in = buffer; z.next_in_index = offset; z.avail_in = count; while (true) { z.next_out = buf; z.next_out_index = 0; z.avail_out = buf.Length; if ((compress ? z.deflate(flushLevel) : z.inflate(flushLevel)) != 0) break; output.Write(buf, 0, buf.Length - z.avail_out); if (z.avail_in <= 0 && z.avail_out != 0) return; } throw new IOException((compress ? "de" : "in") + "flating: " + z.msg); } public override void WriteByte(byte value) { buf1[0] = value; Write(buf1, 0, 1); } } }