Skip to content

Commit

Permalink
Use BinaryPrimitives in Pack (#1305)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob-Hague authored Feb 6, 2024
1 parent 379e3dd commit 54a001a
Showing 1 changed file with 75 additions and 64 deletions.
139 changes: 75 additions & 64 deletions src/Renci.SshNet/Common/Pack.cs
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -12,24 +17,13 @@ internal static class Pack
/// <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>
Expand All @@ -39,11 +33,15 @@ internal static uint LittleEndianToUInt32(byte[] buffer, int offset)
/// <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>
Expand All @@ -53,6 +51,9 @@ internal static uint LittleEndianToUInt32(byte[] buffer)
/// <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;
Expand All @@ -62,6 +63,7 @@ internal static ulong LittleEndianToUInt64(byte[] buffer)
n |= (ulong) buffer[6] << 48;
n |= (ulong) buffer[7] << 56;
return n;
#endif
}

/// <summary>
Expand All @@ -80,10 +82,14 @@ internal static byte[] UInt16ToLittleEndian(ushort value)
/// </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>
Expand All @@ -102,26 +108,16 @@ internal static byte[] UInt32ToLittleEndian(uint value)
/// </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>
Expand All @@ -140,8 +136,11 @@ internal static byte[] UInt64ToLittleEndian(ulong value)
/// </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);
Expand All @@ -150,41 +149,41 @@ internal static void UInt64ToLittleEndian(ulong value, byte[] buffer)
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)
Expand All @@ -194,24 +193,27 @@ internal static byte[] UInt32ToBigEndian(uint value)
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>
Expand All @@ -221,7 +223,11 @@ internal static byte[] UInt64ToBigEndian(ulong value)
/// <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>
Expand All @@ -232,10 +238,14 @@ internal static ushort BigEndianToUInt16(byte[] buffer)
/// <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>
Expand All @@ -245,10 +255,7 @@ internal static uint BigEndianToUInt32(byte[] buffer, int offset)
/// <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>
Expand All @@ -258,6 +265,9 @@ internal static uint BigEndianToUInt32(byte[] buffer)
/// <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 |
Expand All @@ -266,6 +276,7 @@ internal static ulong BigEndianToUInt64(byte[] buffer)
(ulong) buffer[5] << 16 |
(ulong) buffer[6] << 8 |
buffer[7];
#endif
}
}
}

0 comments on commit 54a001a

Please sign in to comment.