summary refs log tree commit diff
path: root/Crypto/src/util/zlib/ZOutputStream.cs
diff options
context:
space:
mode:
authorOren Novotny <oren@novotny.org>2014-02-26 10:08:50 -0500
committerOren Novotny <oren@novotny.org>2014-02-26 10:08:50 -0500
commit176743ab5faec2dd275b5efd3a2dd62c610f237a (patch)
tree1d2e50c534a479d749c266d7c52434d8f17f86aa /Crypto/src/util/zlib/ZOutputStream.cs
parentAdd git files (diff)
downloadBouncyCastle.NET-ed25519-654c26abd79e9451e5a9bd108f1358bc2849fdbf.tar.xz
Add BouncyCastle PCL files v1.7.0
Diffstat (limited to 'Crypto/src/util/zlib/ZOutputStream.cs')
-rw-r--r--Crypto/src/util/zlib/ZOutputStream.cs220
1 files changed, 220 insertions, 0 deletions
diff --git a/Crypto/src/util/zlib/ZOutputStream.cs b/Crypto/src/util/zlib/ZOutputStream.cs
new file mode 100644
index 000000000..7ea7cbb33
--- /dev/null
+++ b/Crypto/src/util/zlib/ZOutputStream.cs
@@ -0,0 +1,220 @@
+/*
+Copyright (c) 2001 Lapo Luchini.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS
+OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * This program is based on zlib-1.1.3, so all credit should go authors
+ * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+ * and contributors of zlib.
+ */
+/* This file is a port of jzlib v1.0.7, com.jcraft.jzlib.ZOutputStream.java
+ */
+
+using System;
+using System.Diagnostics;
+using System.IO;
+
+namespace Org.BouncyCastle.Utilities.Zlib
+{
+	public class ZOutputStream
+		: Stream
+	{
+		private const int BufferSize = 512;
+
+		protected ZStream z = new ZStream();
+		protected int flushLevel = JZlib.Z_NO_FLUSH;
+		// TODO Allow custom buf
+		protected byte[] buf = new byte[BufferSize];
+		protected byte[] buf1 = new byte[1];
+		protected bool compress;
+
+		protected Stream output;
+		protected bool closed;
+
+		public ZOutputStream(Stream output)
+			: base()
+		{
+			Debug.Assert(output.CanWrite);
+
+			this.output = output;
+			this.z.inflateInit();
+			this.compress = false;
+		}
+
+		public ZOutputStream(Stream output, int level)
+			: this(output, level, false)
+		{
+		}
+
+		public ZOutputStream(Stream output, int level, bool nowrap)
+			: base()
+		{
+			Debug.Assert(output.CanWrite);
+
+			this.output = output;
+			this.z.deflateInit(level, nowrap);
+			this.compress = true;
+		}
+
+		public sealed override bool CanRead { get { return false; } }
+        public sealed override bool CanSeek { get { return false; } }
+        public sealed override bool CanWrite { get { return !closed; } }
+
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing)
+            {
+                if (this.closed)
+                    return;
+
+                try
+                {
+                    try
+                    {
+                        Finish();
+                    }
+                    catch (IOException)
+                    {
+                        // Ignore
+                    }
+                }
+                finally
+                {
+                    this.closed = true;
+                    End();
+                    output.Dispose();
+                    output = null;
+                }
+            }
+		}
+
+		public virtual void End()
+		{
+			if (z == null)
+				return;
+			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 err = compress
+					?	z.deflate(JZlib.Z_FINISH)
+					:	z.inflate(JZlib.Z_FINISH);
+
+				if (err != JZlib.Z_STREAM_END && err != JZlib.Z_OK)
+					// TODO
+//					throw new ZStreamException((compress?"de":"in")+"flating: "+z.msg);
+					throw new IOException((compress ? "de" : "in") + "flating: " + z.msg);
+
+				int count = buf.Length - z.avail_out;
+				if (count > 0)
+				{
+					output.Write(buf, 0, count);
+				}
+			}
+			while (z.avail_in > 0 || z.avail_out == 0);
+
+			Flush();
+		}
+
+		public override void Flush()
+		{
+			output.Flush();
+		}
+
+		public virtual int FlushMode
+		{
+			get { return flushLevel; }
+			set { this.flushLevel = value; }
+		}
+
+        public sealed override long Length { get { throw new NotSupportedException(); } }
+        public sealed override long Position
+        {
+            get { throw new NotSupportedException(); }
+            set { throw new NotSupportedException(); }
+        }
+        public sealed override int Read(byte[] buffer, int offset, int count) { throw new NotSupportedException(); }
+        public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); }
+        public sealed override void SetLength(long value) { throw new NotSupportedException(); }
+
+		public virtual long TotalIn
+		{
+			get { return z.total_in; }
+		}
+
+		public virtual long TotalOut
+		{
+			get { return z.total_out; }
+		}
+
+		public override void Write(byte[] b, int off, int len)
+		{
+			if (len == 0)
+				return;
+
+			z.next_in = b;
+			z.next_in_index = off;
+			z.avail_in = len;
+
+			do
+			{
+				z.next_out = buf;
+				z.next_out_index = 0;
+				z.avail_out = buf.Length;
+
+				int err = compress
+					?	z.deflate(flushLevel)
+					:	z.inflate(flushLevel);
+
+				if (err != JZlib.Z_OK)
+					// TODO
+//					throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg);
+					throw new IOException((compress ? "de" : "in") + "flating: " + z.msg);
+
+				output.Write(buf, 0, buf.Length - z.avail_out);
+			}
+			while (z.avail_in > 0 || z.avail_out == 0);
+		}
+
+		public override void WriteByte(byte b)
+		{
+			buf1[0] = b;
+			Write(buf1, 0, 1);
+		}
+	}
+}