summary refs log tree commit diff
path: root/crypto/src/util
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-09-03 00:36:40 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-09-03 00:36:40 +0700
commitaa5f3f0929c50fc942325f18ed7ae48129d4c992 (patch)
tree0382f7336cb55c4a01bd38782d7694d1cb094921 /crypto/src/util
parentClean up tests (diff)
downloadBouncyCastle.NET-ed25519-aa5f3f0929c50fc942325f18ed7ae48129d4c992.tar.xz
Stream modernization
Diffstat (limited to 'crypto/src/util')
-rw-r--r--crypto/src/util/io/BaseOutputStream.cs8
-rw-r--r--crypto/src/util/io/FilterStream.cs42
-rw-r--r--crypto/src/util/io/LimitedInputStream.cs56
-rw-r--r--crypto/src/util/io/PushbackStream.cs36
-rw-r--r--crypto/src/util/io/Streams.cs53
-rw-r--r--crypto/src/util/io/TeeInputStream.cs25
-rw-r--r--crypto/src/util/io/TeeOutputStream.cs19
-rw-r--r--crypto/src/util/zlib/ZInputStream.cs26
-rw-r--r--crypto/src/util/zlib/ZOutputStream.cs74
9 files changed, 217 insertions, 122 deletions
diff --git a/crypto/src/util/io/BaseOutputStream.cs b/crypto/src/util/io/BaseOutputStream.cs
index d9a5b92d6..dad9b19a4 100644
--- a/crypto/src/util/io/BaseOutputStream.cs
+++ b/crypto/src/util/io/BaseOutputStream.cs
@@ -10,6 +10,9 @@ namespace Org.BouncyCastle.Utilities.IO
         public sealed override bool CanSeek { get { return false; } }
         public sealed override bool CanWrite { get { return true; } }
 
+#if NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public override void CopyTo(Stream destination, int bufferSize) { throw new NotSupportedException(); }
+#endif
         public override void Flush() {}
         public sealed override long Length { get { throw new NotSupportedException(); } }
         public sealed override long Position
@@ -35,10 +38,5 @@ namespace Org.BouncyCastle.Utilities.IO
         {
             Write(buffer, 0, buffer.Length);
         }
-
-        public override void WriteByte(byte value)
-        {
-            Write(new byte[]{ value }, 0, 1);
-        }
     }
 }
diff --git a/crypto/src/util/io/FilterStream.cs b/crypto/src/util/io/FilterStream.cs
index 0db82ec88..d9bcbb8ef 100644
--- a/crypto/src/util/io/FilterStream.cs
+++ b/crypto/src/util/io/FilterStream.cs
@@ -15,15 +15,6 @@ namespace Org.BouncyCastle.Utilities.IO
 
             this.s = s;
         }
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing)
-            {
-                s.Dispose();
-            }
-
-            base.Dispose(disposing);
-        }
         public override bool CanRead
         {
             get { return s.CanRead; }
@@ -36,6 +27,10 @@ namespace Org.BouncyCastle.Utilities.IO
         {
             get { return s.CanWrite; }
         }
+        public override void Flush()
+        {
+            s.Flush();
+        }
         public override long Length
         {
             get { return s.Length; }
@@ -45,9 +40,13 @@ namespace Org.BouncyCastle.Utilities.IO
             get { return s.Position; }
             set { s.Position = value; }
         }
-        public override void Flush()
+        public override int Read(byte[] buffer, int offset, int count)
         {
-            s.Flush();
+            return s.Read(buffer, offset, count);
+        }
+        public override int ReadByte()
+        {
+            return s.ReadByte();
         }
         public override long Seek(long offset, SeekOrigin origin)
         {
@@ -57,14 +56,6 @@ namespace Org.BouncyCastle.Utilities.IO
         {
             s.SetLength(value);
         }
-        public override int Read(byte[] buffer, int offset, int count)
-        {
-            return s.Read(buffer, offset, count);
-        }
-        public override int ReadByte()
-        {
-            return s.ReadByte();
-        }
         public override void Write(byte[] buffer, int offset, int count)
         {
             s.Write(buffer, offset, count);
@@ -73,5 +64,18 @@ namespace Org.BouncyCastle.Utilities.IO
         {
             s.WriteByte(value);
         }
+        protected void Detach(bool disposing)
+        {
+            base.Dispose(disposing);
+        }
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing)
+            {
+                s.Dispose();
+            }
+
+            base.Dispose(disposing);
+        }
     }
 }
diff --git a/crypto/src/util/io/LimitedInputStream.cs b/crypto/src/util/io/LimitedInputStream.cs
new file mode 100644
index 000000000..d6616eff5
--- /dev/null
+++ b/crypto/src/util/io/LimitedInputStream.cs
@@ -0,0 +1,56 @@
+using Org.BouncyCastle.Utilities.Zlib;
+using System;
+using System.IO;
+
+namespace Org.BouncyCastle.Utilities.IO
+{
+    internal class LimitedInputStream
+        : BaseInputStream
+    {
+        private readonly Stream m_stream;
+        private long m_limit;
+
+        internal LimitedInputStream(Stream stream, long limit)
+        {
+            this.m_stream = stream;
+            this.m_limit = limit;
+        }
+
+        internal long CurrentLimit => m_limit;
+
+        public override int Read(byte[] buffer, int offset, int count)
+        {
+            int numRead = m_stream.Read(buffer, offset, count);
+            if (numRead > 0)
+            {
+                if ((m_limit -= numRead) < 0)
+                    throw new StreamOverflowException("Data Overflow");
+            }
+            return numRead;
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public override int Read(Span<byte> buffer)
+        {
+            int numRead = m_stream.Read(buffer);
+            if (numRead > 0)
+            {
+                if ((m_limit -= numRead) < 0)
+                    throw new StreamOverflowException("Data Overflow");
+            }
+            return numRead;
+        }
+#endif
+
+        public override int ReadByte()
+        {
+            int b = m_stream.ReadByte();
+            if (b >= 0)
+            {
+                if (--m_limit < 0)
+                    throw new StreamOverflowException("Data Overflow");
+            }
+            return b;
+        }
+    }
+}
diff --git a/crypto/src/util/io/PushbackStream.cs b/crypto/src/util/io/PushbackStream.cs
index 2ceb64361..15ba70501 100644
--- a/crypto/src/util/io/PushbackStream.cs
+++ b/crypto/src/util/io/PushbackStream.cs
@@ -13,7 +13,20 @@ namespace Org.BouncyCastle.Utilities.IO
 		{
 		}
 
-		public override int Read(byte[] buffer, int offset, int count)
+#if NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public override void CopyTo(Stream destination, int bufferSize)
+        {
+			if (m_buf != -1)
+			{
+				destination.WriteByte((byte)m_buf);
+                m_buf = -1;
+            }
+
+            s.CopyTo(destination, bufferSize);
+        }
+#endif
+
+        public override int Read(byte[] buffer, int offset, int count)
 		{
 			Streams.ValidateBufferArguments(buffer, offset, count);
 
@@ -27,10 +40,27 @@ namespace Org.BouncyCastle.Utilities.IO
 				return 1;
 			}
 
-			return base.Read(buffer, offset, count);
+			return s.Read(buffer, offset, count);
 		}
 
-		public override int ReadByte()
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public override int Read(Span<byte> buffer)
+        {
+			if (m_buf != -1)
+			{
+                if (buffer.IsEmpty)
+                    return 0;
+
+                buffer[0] = (byte)m_buf;
+                m_buf = -1;
+                return 1;
+            }
+
+            return s.Read(buffer);
+        }
+#endif
+
+        public override int ReadByte()
 		{
 			if (m_buf != -1)
 			{
diff --git a/crypto/src/util/io/Streams.cs b/crypto/src/util/io/Streams.cs
index e1da47fcd..c23332909 100644
--- a/crypto/src/util/io/Streams.cs
+++ b/crypto/src/util/io/Streams.cs
@@ -13,10 +13,7 @@ namespace Org.BouncyCastle.Utilities.IO
 
 		public static void Drain(Stream inStr)
 		{
-			byte[] bs = new byte[BufferSize];
-			while (inStr.Read(bs, 0, bs.Length) > 0)
-			{
-			}
+			inStr.CopyTo(Stream.Null, BufferSize);
 		}
 
         /// <summary>Write the full contents of inStr to the destination stream outStr.</summary>
@@ -25,7 +22,7 @@ namespace Org.BouncyCastle.Utilities.IO
         /// <exception cref="IOException">In case of IO failure.</exception>
         public static void PipeAll(Stream inStr, Stream outStr)
 		{
-            PipeAll(inStr, outStr, BufferSize);
+			inStr.CopyTo(outStr, BufferSize);
         }
 
         /// <summary>Write the full contents of inStr to the destination stream outStr.</summary>
@@ -35,12 +32,7 @@ namespace Org.BouncyCastle.Utilities.IO
         /// <exception cref="IOException">In case of IO failure.</exception>
         public static void PipeAll(Stream inStr, Stream outStr, int bufferSize)
         {
-            byte[] bs = new byte[bufferSize];
-            int numRead;
-			while ((numRead = inStr.Read(bs, 0, bs.Length)) > 0)
-			{
-				outStr.Write(bs, 0, numRead);
-			}
+            inStr.CopyTo(outStr, bufferSize);
 		}
 
 		/// <summary>
@@ -60,17 +52,9 @@ namespace Org.BouncyCastle.Utilities.IO
 		/// <exception cref="IOException"></exception>
 		public static long PipeAllLimited(Stream inStr, long limit, Stream outStr)
 		{
-			byte[] bs = new byte[BufferSize];
-			long total = 0;
-			int numRead;
-			while ((numRead = inStr.Read(bs, 0, bs.Length)) > 0)
-			{
-                if ((limit - total) < numRead)
-					throw new StreamOverflowException("Data Overflow");
-                total += numRead;
-                outStr.Write(bs, 0, numRead);
-			}
-			return total;
+			var limited = new LimitedInputStream(inStr, limit);
+            limited.CopyTo(outStr, BufferSize);
+			return limit - limited.CurrentLimit;
 		}
 
 		public static byte[] ReadAll(Stream inStr)
@@ -105,7 +89,22 @@ namespace Org.BouncyCastle.Utilities.IO
 			return totalRead;
 		}
 
-		public static void ValidateBufferArguments(byte[] buffer, int offset, int count)
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public static int ReadFully(Stream inStr, Span<byte> buffer)
+        {
+            int totalRead = 0;
+            while (totalRead < buffer.Length)
+            {
+                int numRead = inStr.Read(buffer[totalRead..]);
+                if (numRead < 1)
+                    break;
+                totalRead += numRead;
+            }
+            return totalRead;
+        }
+#endif
+
+        public static void ValidateBufferArguments(byte[] buffer, int offset, int count)
         {
 			if (buffer == null)
 				throw new ArgumentNullException("buffer");
@@ -120,6 +119,14 @@ namespace Org.BouncyCastle.Utilities.IO
         /// <exception cref="IOException"></exception>
         public static int WriteBufTo(MemoryStream buf, byte[] output, int offset)
         {
+#if NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            if (buf.TryGetBuffer(out var buffer))
+            {
+				buffer.CopyTo(output, offset);
+				return buffer.Count;
+            }
+#endif
+
 			int size = Convert.ToInt32(buf.Length);
             buf.WriteTo(new MemoryStream(output, offset, size));
             return size;
diff --git a/crypto/src/util/io/TeeInputStream.cs b/crypto/src/util/io/TeeInputStream.cs
index 73ea8fed0..3d45bb4f1 100644
--- a/crypto/src/util/io/TeeInputStream.cs
+++ b/crypto/src/util/io/TeeInputStream.cs
@@ -18,7 +18,6 @@ namespace Org.BouncyCastle.Utilities.IO
 			this.tee = tee;
 		}
 
-#if PORTABLE
         protected override void Dispose(bool disposing)
         {
             if (disposing)
@@ -28,14 +27,6 @@ namespace Org.BouncyCastle.Utilities.IO
             }
             base.Dispose(disposing);
         }
-#else
-        public override void Close()
-		{
-            Platform.Dispose(input);
-            Platform.Dispose(tee);
-            base.Close();
-		}
-#endif
 
         public override int Read(byte[] buffer, int offset, int count)
 		{
@@ -49,7 +40,21 @@ namespace Org.BouncyCastle.Utilities.IO
 			return i;
 		}
 
-		public override int ReadByte()
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public override int Read(Span<byte> buffer)
+        {
+            int i = input.Read(buffer);
+
+            if (i > 0)
+            {
+				tee.Write(buffer[..i]);
+            }
+
+            return i;
+        }
+#endif
+
+        public override int ReadByte()
 		{
 			int i = input.ReadByte();
 
diff --git a/crypto/src/util/io/TeeOutputStream.cs b/crypto/src/util/io/TeeOutputStream.cs
index 5f447b18b..fc213ae55 100644
--- a/crypto/src/util/io/TeeOutputStream.cs
+++ b/crypto/src/util/io/TeeOutputStream.cs
@@ -18,7 +18,6 @@ namespace Org.BouncyCastle.Utilities.IO
 			this.tee = tee;
 		}
 
-#if PORTABLE
         protected override void Dispose(bool disposing)
         {
             if (disposing)
@@ -28,14 +27,6 @@ namespace Org.BouncyCastle.Utilities.IO
             }
             base.Dispose(disposing);
         }
-#else
-        public override void Close()
-		{
-            Platform.Dispose(output);
-            Platform.Dispose(tee);
-            base.Close();
-		}
-#endif
 
         public override void Write(byte[] buffer, int offset, int count)
 		{
@@ -43,7 +34,15 @@ namespace Org.BouncyCastle.Utilities.IO
 			tee.Write(buffer, offset, count);
 		}
 
-		public override void WriteByte(byte value)
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public override void Write(ReadOnlySpan<byte> buffer)
+        {
+            output.Write(buffer);
+            tee.Write(buffer);
+        }
+#endif
+
+        public override void WriteByte(byte value)
 		{
 			output.WriteByte(value);
 			tee.WriteByte(value);
diff --git a/crypto/src/util/zlib/ZInputStream.cs b/crypto/src/util/zlib/ZInputStream.cs
index 3e6fcc1be..0433a0182 100644
--- a/crypto/src/util/zlib/ZInputStream.cs
+++ b/crypto/src/util/zlib/ZInputStream.cs
@@ -116,34 +116,18 @@ namespace Org.BouncyCastle.Utilities.Zlib
             this.z.avail_in = 0;
         }
 
-        /*public int available() throws IOException {
-		return inf.finished() ? 0 : 1;
-		}*/
-
-#if PORTABLE
         protected override void Dispose(bool disposing)
         {
             if (disposing)
             {
-			    if (closed)
-                    return;
-
-                closed = true;
-                Platform.Dispose(input);
+			    if (!closed)
+                {
+                    closed = true;
+                    Platform.Dispose(input);
+                }
             }
             base.Dispose(disposing);
         }
-#else
-        public override void Close()
-        {
-            if (closed)
-                return;
-
-            closed = true;
-            Platform.Dispose(input);
-            base.Close();
-        }
-#endif
 
         public virtual int FlushMode
         {
diff --git a/crypto/src/util/zlib/ZOutputStream.cs b/crypto/src/util/zlib/ZOutputStream.cs
index dcb93f97b..301516e57 100644
--- a/crypto/src/util/zlib/ZOutputStream.cs
+++ b/crypto/src/util/zlib/ZOutputStream.cs
@@ -109,49 +109,61 @@ namespace Org.BouncyCastle.Utilities.Zlib
             this.z.deflateInit(level, nowrap);
         }
 
-#if PORTABLE
-        protected override void Dispose(bool disposing)
+        protected void Detach(bool disposing)
         {
             if (disposing)
             {
-			    if (closed)
-				    return;
-
-                DoClose();
+                if (!closed)
+                {
+                    try
+                    {
+                        try
+                        {
+                            Finish();
+                        }
+                        catch (IOException)
+                        {
+                            // Ignore
+                        }
+                    }
+                    finally
+                    {
+                        this.closed = true;
+                        End();
+                        output = null;
+                    }
+                }
             }
             base.Dispose(disposing);
         }
-#else
-        public override void Close()
-        {
-            if (closed)
-                return;
-
-            DoClose();
-            base.Close();
-        }
-#endif
 
-        private void DoClose()
+        protected override void Dispose(bool disposing)
         {
-            try
+            if (disposing)
             {
-                try
-                {
-                    Finish();
-                }
-                catch (IOException)
+			    if (!closed)
                 {
-                    // Ignore
+                    try
+                    {
+                        try
+                        {
+                            Finish();
+                        }
+                        catch (IOException)
+                        {
+                            // Ignore
+                        }
+                    }
+                    finally
+                    {
+                        this.closed = true;
+                        End();
+                        Platform.Dispose(output);
+                        output = null;
+                    }
                 }
             }
-            finally
-            {
-                this.closed = true;
-                End();
-                Platform.Dispose(output);
-                output = null;
-            }
+            base.Dispose(disposing);
         }
 
         public virtual void End()