Skip to content

Commit 54a001a

Browse files
authored
Use BinaryPrimitives in Pack (#1305)
1 parent 379e3dd commit 54a001a

File tree

1 file changed

+75
-64
lines changed

1 file changed

+75
-64
lines changed

src/Renci.SshNet/Common/Pack.cs

Lines changed: 75 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
namespace Renci.SshNet.Common
1+
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
2+
using System;
3+
using System.Buffers.Binary;
4+
#endif
5+
6+
namespace Renci.SshNet.Common
27
{
38
/// <summary>
49
/// Provides convenience methods for conversion to and from both Big Endian and Little Endian.
@@ -12,24 +17,13 @@ internal static class Pack
1217
/// <returns>Converted <see cref="ushort" />.</returns>
1318
internal static ushort LittleEndianToUInt16(byte[] buffer)
1419
{
20+
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
21+
return BinaryPrimitives.ReadUInt16LittleEndian(buffer);
22+
#else
1523
ushort n = buffer[0];
1624
n |= (ushort) (buffer[1] << 8);
1725
return n;
18-
}
19-
20-
/// <summary>
21-
/// Converts little endian bytes into number.
22-
/// </summary>
23-
/// <param name="buffer">The buffer.</param>
24-
/// <param name="offset">The buffer offset.</param>
25-
/// <returns>Converted <see cref="uint" />.</returns>
26-
internal static uint LittleEndianToUInt32(byte[] buffer, int offset)
27-
{
28-
uint n = buffer[offset];
29-
n |= (uint) buffer[offset + 1] << 8;
30-
n |= (uint) buffer[offset + 2] << 16;
31-
n |= (uint) buffer[offset + 3] << 24;
32-
return n;
26+
#endif
3327
}
3428

3529
/// <summary>
@@ -39,11 +33,15 @@ internal static uint LittleEndianToUInt32(byte[] buffer, int offset)
3933
/// <returns>Converted <see cref="uint" />.</returns>
4034
internal static uint LittleEndianToUInt32(byte[] buffer)
4135
{
36+
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
37+
return BinaryPrimitives.ReadUInt32LittleEndian(buffer);
38+
#else
4239
uint n = buffer[0];
4340
n |= (uint) buffer[1] << 8;
4441
n |= (uint) buffer[2] << 16;
4542
n |= (uint) buffer[3] << 24;
4643
return n;
44+
#endif
4745
}
4846

4947
/// <summary>
@@ -53,6 +51,9 @@ internal static uint LittleEndianToUInt32(byte[] buffer)
5351
/// <returns>Converted <see cref="ulong" />.</returns>
5452
internal static ulong LittleEndianToUInt64(byte[] buffer)
5553
{
54+
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
55+
return BinaryPrimitives.ReadUInt64LittleEndian(buffer);
56+
#else
5657
ulong n = buffer[0];
5758
n |= (ulong) buffer[1] << 8;
5859
n |= (ulong) buffer[2] << 16;
@@ -62,6 +63,7 @@ internal static ulong LittleEndianToUInt64(byte[] buffer)
6263
n |= (ulong) buffer[6] << 48;
6364
n |= (ulong) buffer[7] << 56;
6465
return n;
66+
#endif
6567
}
6668

6769
/// <summary>
@@ -80,10 +82,14 @@ internal static byte[] UInt16ToLittleEndian(ushort value)
8082
/// </summary>
8183
/// <param name="value">The number to convert.</param>
8284
/// <param name="buffer">The buffer.</param>
83-
internal static void UInt16ToLittleEndian(ushort value, byte[] buffer)
85+
private static void UInt16ToLittleEndian(ushort value, byte[] buffer)
8486
{
87+
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
88+
BinaryPrimitives.WriteUInt16LittleEndian(buffer, value);
89+
#else
8590
buffer[0] = (byte) (value & 0x00FF);
8691
buffer[1] = (byte) ((value & 0xFF00) >> 8);
92+
#endif
8793
}
8894

8995
/// <summary>
@@ -102,26 +108,16 @@ internal static byte[] UInt32ToLittleEndian(uint value)
102108
/// </summary>
103109
/// <param name="value">The number to convert.</param>
104110
/// <param name="buffer">The buffer.</param>
105-
internal static void UInt32ToLittleEndian(uint value, byte[] buffer)
111+
private static void UInt32ToLittleEndian(uint value, byte[] buffer)
106112
{
113+
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
114+
BinaryPrimitives.WriteUInt32LittleEndian(buffer, value);
115+
#else
107116
buffer[0] = (byte) (value & 0x000000FF);
108117
buffer[1] = (byte) ((value & 0x0000FF00) >> 8);
109118
buffer[2] = (byte) ((value & 0x00FF0000) >> 16);
110119
buffer[3] = (byte) ((value & 0xFF000000) >> 24);
111-
}
112-
113-
/// <summary>
114-
/// Populates buffer with little endian number representation.
115-
/// </summary>
116-
/// <param name="value">The number to convert.</param>
117-
/// <param name="buffer">The buffer.</param>
118-
/// <param name="offset">The buffer offset.</param>
119-
internal static void UInt32ToLittleEndian(uint value, byte[] buffer, int offset)
120-
{
121-
buffer[offset] = (byte) (value & 0x000000FF);
122-
buffer[offset + 1] = (byte) ((value & 0x0000FF00) >> 8);
123-
buffer[offset + 2] = (byte) ((value & 0x00FF0000) >> 16);
124-
buffer[offset + 3] = (byte) ((value & 0xFF000000) >> 24);
120+
#endif
125121
}
126122

127123
/// <summary>
@@ -140,8 +136,11 @@ internal static byte[] UInt64ToLittleEndian(ulong value)
140136
/// </summary>
141137
/// <param name="value">The number to convert.</param>
142138
/// <param name="buffer">The buffer.</param>
143-
internal static void UInt64ToLittleEndian(ulong value, byte[] buffer)
139+
private static void UInt64ToLittleEndian(ulong value, byte[] buffer)
144140
{
141+
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
142+
BinaryPrimitives.WriteUInt64LittleEndian(buffer, value);
143+
#else
145144
buffer[0] = (byte) (value & 0x00000000000000FF);
146145
buffer[1] = (byte) ((value & 0x000000000000FF00) >> 8);
147146
buffer[2] = (byte) ((value & 0x0000000000FF0000) >> 16);
@@ -150,41 +149,41 @@ internal static void UInt64ToLittleEndian(ulong value, byte[] buffer)
150149
buffer[5] = (byte) ((value & 0x0000FF0000000000) >> 40);
151150
buffer[6] = (byte) ((value & 0x00FF000000000000) >> 48);
152151
buffer[7] = (byte) ((value & 0xFF00000000000000) >> 56);
152+
#endif
153153
}
154154

155155
internal static byte[] UInt16ToBigEndian(ushort value)
156156
{
157157
var buffer = new byte[2];
158-
UInt16ToBigEndian(value, buffer);
158+
UInt16ToBigEndian(value, buffer, offset: 0);
159159
return buffer;
160160
}
161161

162-
internal static void UInt16ToBigEndian(ushort value, byte[] buffer)
163-
{
164-
buffer[0] = (byte) (value >> 8);
165-
buffer[1] = (byte) (value & 0x00FF);
166-
}
167-
168162
internal static void UInt16ToBigEndian(ushort value, byte[] buffer, int offset)
169163
{
164+
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
165+
BinaryPrimitives.WriteUInt16BigEndian(buffer.AsSpan(offset), value);
166+
#else
170167
buffer[offset] = (byte) (value >> 8);
171168
buffer[offset + 1] = (byte) (value & 0x00FF);
169+
#endif
172170
}
173171

174172
internal static void UInt32ToBigEndian(uint value, byte[] buffer)
175173
{
176-
buffer[0] = (byte) ((value & 0xFF000000) >> 24);
177-
buffer[1] = (byte) ((value & 0x00FF0000) >> 16);
178-
buffer[2] = (byte) ((value & 0x0000FF00) >> 8);
179-
buffer[3] = (byte) (value & 0x000000FF);
174+
UInt32ToBigEndian(value, buffer, offset: 0);
180175
}
181176

182177
internal static void UInt32ToBigEndian(uint value, byte[] buffer, int offset)
183178
{
179+
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
180+
BinaryPrimitives.WriteUInt32BigEndian(buffer.AsSpan(offset), value);
181+
#else
184182
buffer[offset++] = (byte) ((value & 0xFF000000) >> 24);
185183
buffer[offset++] = (byte) ((value & 0x00FF0000) >> 16);
186184
buffer[offset++] = (byte) ((value & 0x0000FF00) >> 8);
187185
buffer[offset] = (byte) (value & 0x000000FF);
186+
#endif
188187
}
189188

190189
internal static byte[] UInt32ToBigEndian(uint value)
@@ -194,24 +193,27 @@ internal static byte[] UInt32ToBigEndian(uint value)
194193
return buffer;
195194
}
196195

197-
/// <summary>
198-
/// Returns the specified 64-bit unsigned integer value as an array of bytes.
199-
/// </summary>
200-
/// <param name="value">The number to convert.</param>
201-
/// <returns>An array of bytes with length 8.</returns>
202196
internal static byte[] UInt64ToBigEndian(ulong value)
203197
{
204-
return new[]
205-
{
206-
(byte) ((value & 0xFF00000000000000) >> 56),
207-
(byte) ((value & 0x00FF000000000000) >> 48),
208-
(byte) ((value & 0x0000FF0000000000) >> 40),
209-
(byte) ((value & 0x000000FF00000000) >> 32),
210-
(byte) ((value & 0x00000000FF000000) >> 24),
211-
(byte) ((value & 0x0000000000FF0000) >> 16),
212-
(byte) ((value & 0x000000000000FF00) >> 8),
213-
(byte) (value & 0x00000000000000FF)
214-
};
198+
var buffer = new byte[8];
199+
UInt64ToBigEndian(value, buffer, offset: 0);
200+
return buffer;
201+
}
202+
203+
private static void UInt64ToBigEndian(ulong value, byte[] buffer, int offset)
204+
{
205+
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
206+
BinaryPrimitives.WriteUInt64BigEndian(buffer.AsSpan(offset), value);
207+
#else
208+
buffer[offset++] = (byte) ((value & 0xFF00000000000000) >> 56);
209+
buffer[offset++] = (byte) ((value & 0x00FF000000000000) >> 48);
210+
buffer[offset++] = (byte) ((value & 0x0000FF0000000000) >> 40);
211+
buffer[offset++] = (byte) ((value & 0x000000FF00000000) >> 32);
212+
buffer[offset++] = (byte) ((value & 0x00000000FF000000) >> 24);
213+
buffer[offset++] = (byte) ((value & 0x0000000000FF0000) >> 16);
214+
buffer[offset++] = (byte) ((value & 0x000000000000FF00) >> 8);
215+
buffer[offset] = (byte) (value & 0x00000000000000FF);
216+
#endif
215217
}
216218

217219
/// <summary>
@@ -221,7 +223,11 @@ internal static byte[] UInt64ToBigEndian(ulong value)
221223
/// <returns>Converted <see cref="ushort" />.</returns>
222224
internal static ushort BigEndianToUInt16(byte[] buffer)
223225
{
226+
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
227+
return BinaryPrimitives.ReadUInt16BigEndian(buffer);
228+
#else
224229
return (ushort) (buffer[0] << 8 | buffer[1]);
230+
#endif
225231
}
226232

227233
/// <summary>
@@ -232,10 +238,14 @@ internal static ushort BigEndianToUInt16(byte[] buffer)
232238
/// <returns>Converted <see cref="uint" />.</returns>
233239
internal static uint BigEndianToUInt32(byte[] buffer, int offset)
234240
{
241+
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
242+
return BinaryPrimitives.ReadUInt32BigEndian(buffer.AsSpan(offset));
243+
#else
235244
return (uint) buffer[offset + 0] << 24 |
236245
(uint) buffer[offset + 1] << 16 |
237246
(uint) buffer[offset + 2] << 8 |
238247
buffer[offset + 3];
248+
#endif
239249
}
240250

241251
/// <summary>
@@ -245,10 +255,7 @@ internal static uint BigEndianToUInt32(byte[] buffer, int offset)
245255
/// <returns>Converted <see cref="uint" />.</returns>
246256
internal static uint BigEndianToUInt32(byte[] buffer)
247257
{
248-
return (uint) buffer[0] << 24 |
249-
(uint) buffer[1] << 16 |
250-
(uint) buffer[2] << 8 |
251-
buffer[3];
258+
return BigEndianToUInt32(buffer, offset: 0);
252259
}
253260

254261
/// <summary>
@@ -258,6 +265,9 @@ internal static uint BigEndianToUInt32(byte[] buffer)
258265
/// <returns>Converted <see cref="ulong" />.</returns>
259266
internal static ulong BigEndianToUInt64(byte[] buffer)
260267
{
268+
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
269+
return BinaryPrimitives.ReadUInt64BigEndian(buffer);
270+
#else
261271
return (ulong) buffer[0] << 56 |
262272
(ulong) buffer[1] << 48 |
263273
(ulong) buffer[2] << 40 |
@@ -266,6 +276,7 @@ internal static ulong BigEndianToUInt64(byte[] buffer)
266276
(ulong) buffer[5] << 16 |
267277
(ulong) buffer[6] << 8 |
268278
buffer[7];
279+
#endif
269280
}
270281
}
271282
}

0 commit comments

Comments
 (0)