From d1a25047e4b6a0dc1243b79dd3a992a4f88a7d9b Mon Sep 17 00:00:00 2001 From: Jacob Slusser Date: Sun, 10 Dec 2023 18:17:35 -0800 Subject: [PATCH] Reduces heap allocations for the some byte[] uses --- src/Renci.SshNet/Common/SshData.cs | 4 ++-- src/Renci.SshNet/Common/SshDataStream.cs | 28 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/Renci.SshNet/Common/SshData.cs b/src/Renci.SshNet/Common/SshData.cs index 4e7ff0438..f63a6bcb2 100644 --- a/src/Renci.SshNet/Common/SshData.cs +++ b/src/Renci.SshNet/Common/SshData.cs @@ -221,7 +221,7 @@ protected ushort ReadUInt16() /// Attempt to read past the end of the stream. protected uint ReadUInt32() { - return Pack.BigEndianToUInt32(ReadBytes(4)); + return _stream.ReadUInt32(); } /// @@ -233,7 +233,7 @@ protected uint ReadUInt32() /// Attempt to read past the end of the stream. protected ulong ReadUInt64() { - return Pack.BigEndianToUInt64(ReadBytes(8)); + return _stream.ReadUInt64(); } /// diff --git a/src/Renci.SshNet/Common/SshDataStream.cs b/src/Renci.SshNet/Common/SshDataStream.cs index 6bad5f21f..715ef29e4 100644 --- a/src/Renci.SshNet/Common/SshDataStream.cs +++ b/src/Renci.SshNet/Common/SshDataStream.cs @@ -188,8 +188,14 @@ public BigInteger ReadBigInt() /// public uint ReadUInt32() { +#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER + Span span = stackalloc byte[4]; + ReadBytes(span); + return System.Buffers.Binary.BinaryPrimitives.ReadUInt32BigEndian(span); +#else var data = ReadBytes(4); return Pack.BigEndianToUInt32(data); +#endif // NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER } /// @@ -200,8 +206,14 @@ public uint ReadUInt32() /// public ulong ReadUInt64() { +#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER + Span span = stackalloc byte[8]; + ReadBytes(span); + return System.Buffers.Binary.BinaryPrimitives.ReadUInt64BigEndian(span); +#else var data = ReadBytes(8); return Pack.BigEndianToUInt64(data); +#endif // NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER } /// @@ -264,5 +276,21 @@ private byte[] ReadBytes(int length) return data; } + +#if NETSTANDARD2_1 || NET6_0_OR_GREATER + /// + /// Reads data into the specified . + /// + /// The buffer to read into. + /// is larger than the total of bytes available. + private void ReadBytes(Span buffer) + { + var bytesRead = Read(buffer); + if (bytesRead < buffer.Length) + { + throw new ArgumentOutOfRangeException(nameof(buffer), string.Format(CultureInfo.InvariantCulture, "The requested length ({0}) is greater than the actual number of bytes read ({1}).", buffer.Length, bytesRead)); + } + } +#endif // NETSTANDARD2_1 || NET6_0_OR_GREATER } }