Ver código fonte

Use BinaryPrimitives in Pack (#1305)

Rob Hague 1 ano atrás
pai
commit
54a001adea
1 arquivos alterados com 75 adições e 64 exclusões
  1. 75 64
      src/Renci.SshNet/Common/Pack.cs

+ 75 - 64
src/Renci.SshNet/Common/Pack.cs

@@ -1,4 +1,9 @@
-namespace Renci.SshNet.Common
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
+using System;
+using System.Buffers.Binary;
+#endif
+
+namespace Renci.SshNet.Common
 {
     /// <summary>
     /// Provides convenience methods for conversion to and from both Big Endian and Little Endian.
@@ -12,24 +17,13 @@
         /// <returns>Converted <see cref="ushort" />.</returns>
         internal static ushort LittleEndianToUInt16(byte[] buffer)
         {
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
+            return BinaryPrimitives.ReadUInt16LittleEndian(buffer);
+#else
             ushort n = buffer[0];
             n |= (ushort) (buffer[1] << 8);
             return n;
-        }
-
-        /// <summary>
-        /// Converts little endian bytes into number.
-        /// </summary>
-        /// <param name="buffer">The buffer.</param>
-        /// <param name="offset">The buffer offset.</param>
-        /// <returns>Converted <see cref="uint" />.</returns>
-        internal static uint LittleEndianToUInt32(byte[] buffer, int offset)
-        {
-            uint n = buffer[offset];
-            n |= (uint) buffer[offset + 1] << 8;
-            n |= (uint) buffer[offset + 2] << 16;
-            n |= (uint) buffer[offset + 3] << 24;
-            return n;
+#endif
         }
 
         /// <summary>
@@ -39,11 +33,15 @@
         /// <returns>Converted <see cref="uint" />.</returns>
         internal static uint LittleEndianToUInt32(byte[] buffer)
         {
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
+            return BinaryPrimitives.ReadUInt32LittleEndian(buffer);
+#else
             uint n = buffer[0];
             n |= (uint) buffer[1] << 8;
             n |= (uint) buffer[2] << 16;
             n |= (uint) buffer[3] << 24;
             return n;
+#endif
         }
 
         /// <summary>
@@ -53,6 +51,9 @@
         /// <returns>Converted <see cref="ulong" />.</returns>
         internal static ulong LittleEndianToUInt64(byte[] buffer)
         {
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
+            return BinaryPrimitives.ReadUInt64LittleEndian(buffer);
+#else
             ulong n = buffer[0];
             n |= (ulong) buffer[1] << 8;
             n |= (ulong) buffer[2] << 16;
@@ -62,6 +63,7 @@
             n |= (ulong) buffer[6] << 48;
             n |= (ulong) buffer[7] << 56;
             return n;
+#endif
         }
 
         /// <summary>
@@ -80,10 +82,14 @@
         /// </summary>
         /// <param name="value">The number to convert.</param>
         /// <param name="buffer">The buffer.</param>
-        internal static void UInt16ToLittleEndian(ushort value, byte[] buffer)
+        private static void UInt16ToLittleEndian(ushort value, byte[] buffer)
         {
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
+            BinaryPrimitives.WriteUInt16LittleEndian(buffer, value);
+#else
             buffer[0] = (byte) (value & 0x00FF);
             buffer[1] = (byte) ((value & 0xFF00) >> 8);
+#endif
         }
 
         /// <summary>
@@ -102,26 +108,16 @@
         /// </summary>
         /// <param name="value">The number to convert.</param>
         /// <param name="buffer">The buffer.</param>
-        internal static void UInt32ToLittleEndian(uint value, byte[] buffer)
+        private static void UInt32ToLittleEndian(uint value, byte[] buffer)
         {
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
+            BinaryPrimitives.WriteUInt32LittleEndian(buffer, value);
+#else
             buffer[0] = (byte) (value & 0x000000FF);
             buffer[1] = (byte) ((value & 0x0000FF00) >> 8);
             buffer[2] = (byte) ((value & 0x00FF0000) >> 16);
             buffer[3] = (byte) ((value & 0xFF000000) >> 24);
-        }
-
-        /// <summary>
-        /// Populates buffer with little endian number representation.
-        /// </summary>
-        /// <param name="value">The number to convert.</param>
-        /// <param name="buffer">The buffer.</param>
-        /// <param name="offset">The buffer offset.</param>
-        internal static void UInt32ToLittleEndian(uint value, byte[] buffer, int offset)
-        {
-            buffer[offset] = (byte) (value & 0x000000FF);
-            buffer[offset + 1] = (byte) ((value & 0x0000FF00) >> 8);
-            buffer[offset + 2] = (byte) ((value & 0x00FF0000) >> 16);
-            buffer[offset + 3] = (byte) ((value & 0xFF000000) >> 24);
+#endif
         }
 
         /// <summary>
@@ -140,8 +136,11 @@
         /// </summary>
         /// <param name="value">The number to convert.</param>
         /// <param name="buffer">The buffer.</param>
-        internal static void UInt64ToLittleEndian(ulong value, byte[] buffer)
+        private static void UInt64ToLittleEndian(ulong value, byte[] buffer)
         {
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
+            BinaryPrimitives.WriteUInt64LittleEndian(buffer, value);
+#else
             buffer[0] = (byte) (value & 0x00000000000000FF);
             buffer[1] = (byte) ((value & 0x000000000000FF00) >> 8);
             buffer[2] = (byte) ((value & 0x0000000000FF0000) >> 16);
@@ -150,41 +149,41 @@
             buffer[5] = (byte) ((value & 0x0000FF0000000000) >> 40);
             buffer[6] = (byte) ((value & 0x00FF000000000000) >> 48);
             buffer[7] = (byte) ((value & 0xFF00000000000000) >> 56);
+#endif
         }
 
         internal static byte[] UInt16ToBigEndian(ushort value)
         {
             var buffer = new byte[2];
-            UInt16ToBigEndian(value, buffer);
+            UInt16ToBigEndian(value, buffer, offset: 0);
             return buffer;
         }
 
-        internal static void UInt16ToBigEndian(ushort value, byte[] buffer)
-        {
-            buffer[0] = (byte) (value >> 8);
-            buffer[1] = (byte) (value & 0x00FF);
-        }
-
         internal static void UInt16ToBigEndian(ushort value, byte[] buffer, int offset)
         {
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
+            BinaryPrimitives.WriteUInt16BigEndian(buffer.AsSpan(offset), value);
+#else
             buffer[offset] = (byte) (value >> 8);
             buffer[offset + 1] = (byte) (value & 0x00FF);
+#endif
         }
 
         internal static void UInt32ToBigEndian(uint value, byte[] buffer)
         {
-            buffer[0] = (byte) ((value & 0xFF000000) >> 24);
-            buffer[1] = (byte) ((value & 0x00FF0000) >> 16);
-            buffer[2] = (byte) ((value & 0x0000FF00) >> 8);
-            buffer[3] = (byte) (value & 0x000000FF);
+            UInt32ToBigEndian(value, buffer, offset: 0);
         }
 
         internal static void UInt32ToBigEndian(uint value, byte[] buffer, int offset)
         {
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
+            BinaryPrimitives.WriteUInt32BigEndian(buffer.AsSpan(offset), value);
+#else
             buffer[offset++] = (byte) ((value & 0xFF000000) >> 24);
             buffer[offset++] = (byte) ((value & 0x00FF0000) >> 16);
             buffer[offset++] = (byte) ((value & 0x0000FF00) >> 8);
             buffer[offset] = (byte) (value & 0x000000FF);
+#endif
         }
 
         internal static byte[] UInt32ToBigEndian(uint value)
@@ -194,24 +193,27 @@
             return buffer;
         }
 
-        /// <summary>
-        /// Returns the specified 64-bit unsigned integer value as an array of bytes.
-        /// </summary>
-        /// <param name="value">The number to convert.</param>
-        /// <returns>An array of bytes with length 8.</returns>
         internal static byte[] UInt64ToBigEndian(ulong value)
         {
-            return new[]
-                {
-                    (byte) ((value & 0xFF00000000000000) >> 56),
-                    (byte) ((value & 0x00FF000000000000) >> 48),
-                    (byte) ((value & 0x0000FF0000000000) >> 40),
-                    (byte) ((value & 0x000000FF00000000) >> 32),
-                    (byte) ((value & 0x00000000FF000000) >> 24),
-                    (byte) ((value & 0x0000000000FF0000) >> 16),
-                    (byte) ((value & 0x000000000000FF00) >> 8),
-                    (byte) (value & 0x00000000000000FF)
-                };
+            var buffer = new byte[8];
+            UInt64ToBigEndian(value, buffer, offset: 0);
+            return buffer;
+        }
+
+        private static void UInt64ToBigEndian(ulong value, byte[] buffer, int offset)
+        {
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
+            BinaryPrimitives.WriteUInt64BigEndian(buffer.AsSpan(offset), value);
+#else
+            buffer[offset++] = (byte) ((value & 0xFF00000000000000) >> 56);
+            buffer[offset++] = (byte) ((value & 0x00FF000000000000) >> 48);
+            buffer[offset++] = (byte) ((value & 0x0000FF0000000000) >> 40);
+            buffer[offset++] = (byte) ((value & 0x000000FF00000000) >> 32);
+            buffer[offset++] = (byte) ((value & 0x00000000FF000000) >> 24);
+            buffer[offset++] = (byte) ((value & 0x0000000000FF0000) >> 16);
+            buffer[offset++] = (byte) ((value & 0x000000000000FF00) >> 8);
+            buffer[offset] = (byte) (value & 0x00000000000000FF);
+#endif
         }
 
         /// <summary>
@@ -221,7 +223,11 @@
         /// <returns>Converted <see cref="ushort" />.</returns>
         internal static ushort BigEndianToUInt16(byte[] buffer)
         {
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
+            return BinaryPrimitives.ReadUInt16BigEndian(buffer);
+#else
             return (ushort) (buffer[0] << 8 | buffer[1]);
+#endif
         }
 
         /// <summary>
@@ -232,10 +238,14 @@
         /// <returns>Converted <see cref="uint" />.</returns>
         internal static uint BigEndianToUInt32(byte[] buffer, int offset)
         {
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
+            return BinaryPrimitives.ReadUInt32BigEndian(buffer.AsSpan(offset));
+#else
             return (uint) buffer[offset + 0] << 24 |
                    (uint) buffer[offset + 1] << 16 |
                    (uint) buffer[offset + 2] << 8 |
                    buffer[offset + 3];
+#endif
         }
 
         /// <summary>
@@ -245,10 +255,7 @@
         /// <returns>Converted <see cref="uint" />.</returns>
         internal static uint BigEndianToUInt32(byte[] buffer)
         {
-            return (uint) buffer[0] << 24 |
-                   (uint) buffer[1] << 16 |
-                   (uint) buffer[2] << 8 |
-                   buffer[3];
+            return BigEndianToUInt32(buffer, offset: 0);
         }
 
         /// <summary>
@@ -258,6 +265,9 @@
         /// <returns>Converted <see cref="ulong" />.</returns>
         internal static ulong BigEndianToUInt64(byte[] buffer)
         {
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
+            return BinaryPrimitives.ReadUInt64BigEndian(buffer);
+#else
             return (ulong) buffer[0] << 56 |
                    (ulong) buffer[1] << 48 |
                    (ulong) buffer[2] << 40 |
@@ -266,6 +276,7 @@
                    (ulong) buffer[5] << 16 |
                    (ulong) buffer[6] << 8 |
                    buffer[7];
+#endif
         }
     }
 }