diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-09-03 00:36:40 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-09-03 00:36:40 +0700 |
commit | aa5f3f0929c50fc942325f18ed7ae48129d4c992 (patch) | |
tree | 0382f7336cb55c4a01bd38782d7694d1cb094921 /crypto/src/util/io | |
parent | Clean up tests (diff) | |
download | BouncyCastle.NET-ed25519-aa5f3f0929c50fc942325f18ed7ae48129d4c992.tar.xz |
Stream modernization
Diffstat (limited to 'crypto/src/util/io')
-rw-r--r-- | crypto/src/util/io/BaseOutputStream.cs | 8 | ||||
-rw-r--r-- | crypto/src/util/io/FilterStream.cs | 42 | ||||
-rw-r--r-- | crypto/src/util/io/LimitedInputStream.cs | 56 | ||||
-rw-r--r-- | crypto/src/util/io/PushbackStream.cs | 36 | ||||
-rw-r--r-- | crypto/src/util/io/Streams.cs | 53 | ||||
-rw-r--r-- | crypto/src/util/io/TeeInputStream.cs | 25 | ||||
-rw-r--r-- | crypto/src/util/io/TeeOutputStream.cs | 19 |
7 files changed, 169 insertions, 70 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); |