diff --git a/src/ZWave/BinaryExtensions.cs b/src/ZWave/BinaryExtensions.cs index e307948..33421e9 100644 --- a/src/ZWave/BinaryExtensions.cs +++ b/src/ZWave/BinaryExtensions.cs @@ -1,136 +1,18 @@ -namespace ZWave; +using System.Buffers.Binary; + +namespace ZWave; internal static class BinaryExtensions { public static sbyte ToInt8(this byte b) => unchecked((sbyte)b); - public static ushort ToUInt16BE(this ReadOnlySpan bytes) - { - if (bytes.Length > sizeof(ushort)) - { - throw new ArgumentException($"The number of bytes ({bytes.Length}) is more than can fit in an ushort ({sizeof(ushort)}).", nameof(bytes)); - } - - // BitConverter uses the endianness of the machine, so figure out if we have to reverse the bytes. - if (BitConverter.IsLittleEndian) - { - // Note: There is no need to pad since LE would be padded on the right. - Span buffer = stackalloc byte[sizeof(ushort)]; - bytes.CopyTo(buffer); - buffer.Reverse(); - return BitConverter.ToUInt16(buffer); - } - else if (bytes.Length < sizeof(ushort)) - { - // Add padding - Span buffer = stackalloc byte[sizeof(ushort)]; - bytes.CopyTo(buffer.Slice(sizeof(ushort) - bytes.Length)); - return BitConverter.ToUInt16(buffer); - } - else - { - // Perfect size and endianness - return BitConverter.ToUInt16(bytes); - } - } - - public static void WriteBytesBE(this ushort value, Span destination) - { - if (destination.Length != sizeof(ushort)) - { - throw new ArgumentException($"Destination must be of length {sizeof(ushort)}"); - } - - if (!BitConverter.TryWriteBytes(destination, value)) - { - // This really should never happen. - throw new InvalidOperationException($"Value {value} could not be converted to bytes."); - } - - // BitConverter uses the endianness of the machine, so figure out if we have to reverse the bytes. - if (BitConverter.IsLittleEndian) - { - destination.Reverse(); - } - } - - public static uint ToUInt32BE(this ReadOnlySpan bytes) - { - if (bytes.Length > sizeof(uint)) - { - throw new ArgumentException($"The number of bytes ({bytes.Length}) is more than can fit in an uint ({sizeof(uint)}).", nameof(bytes)); - } - - // BitConverter uses the endianness of the machine, so figure out if we have to reverse the bytes. - if (BitConverter.IsLittleEndian) - { - // Note: There is no need to pad since LE would be padded on the right. - Span buffer = stackalloc byte[sizeof(uint)]; - bytes.CopyTo(buffer); - buffer.Reverse(); - return BitConverter.ToUInt32(buffer); - } - else if (bytes.Length < sizeof(uint)) - { - // Add padding - Span buffer = stackalloc byte[sizeof(uint)]; - bytes.CopyTo(buffer.Slice(sizeof(uint) - bytes.Length)); - return BitConverter.ToUInt32(buffer); - } - else - { - // Perfect size and endianness - return BitConverter.ToUInt32(bytes); - } - } - - public static void WriteBytesBE(this uint value, Span destination) - { - if (destination.Length != sizeof(uint)) - { - throw new ArgumentException($"Destination must be of length {sizeof(uint)}"); - } + public static ushort ToUInt16BE(this ReadOnlySpan bytes) => BinaryPrimitives.ReadUInt16BigEndian(bytes); - if (!BitConverter.TryWriteBytes(destination, value)) - { - // This really should never happen. - throw new InvalidOperationException($"Value {value} could not be converted to bytes."); - } + public static void WriteBytesBE(this ushort value, Span destination) => BinaryPrimitives.WriteUInt16BigEndian(destination, value); - // BitConverter uses the endianness of the machine, so figure out if we have to reverse the bytes. - if (BitConverter.IsLittleEndian) - { - destination.Reverse(); - } - } + public static uint ToUInt32BE(this ReadOnlySpan bytes) => BinaryPrimitives.ReadUInt32BigEndian(bytes); - public static int ToInt32BE(this ReadOnlySpan bytes) - { - if (bytes.Length > sizeof(int)) - { - throw new ArgumentException($"The number of bytes ({bytes.Length}) is more than can fit in an int ({sizeof(int)}).", nameof(bytes)); - } + public static void WriteBytesBE(this uint value, Span destination) => BinaryPrimitives.WriteUInt32BigEndian(destination, value); - // BitConverter uses the endianness of the machine, so figure out if we have to reverse the bytes. - if (BitConverter.IsLittleEndian) - { - // Note: There is no need to pad since LE would be padded on the right. - Span buffer = stackalloc byte[sizeof(int)]; - bytes.CopyTo(buffer); - buffer.Reverse(); - return BitConverter.ToInt32(buffer); - } - else if (bytes.Length < sizeof(int)) - { - // Add padding - Span buffer = stackalloc byte[sizeof(int)]; - bytes.CopyTo(buffer.Slice(sizeof(int) - bytes.Length)); - return BitConverter.ToInt32(buffer); - } - else - { - // Perfect size and endianness - return BitConverter.ToInt32(bytes); - } - } + public static int ToInt32BE(this ReadOnlySpan bytes) => BinaryPrimitives.ReadInt32BigEndian(bytes); }