From baef1afac1c88a85d17a2468e164f22bd5185ab3 Mon Sep 17 00:00:00 2001 From: Peter Butzhammer Date: Tue, 6 Feb 2024 17:47:00 +0100 Subject: [PATCH] Use BinaryPrimitives --- Sharp7.Rx/S7ValueConverter.cs | 40 ++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/Sharp7.Rx/S7ValueConverter.cs b/Sharp7.Rx/S7ValueConverter.cs index 9533809..04d8965 100644 --- a/Sharp7.Rx/S7ValueConverter.cs +++ b/Sharp7.Rx/S7ValueConverter.cs @@ -1,5 +1,6 @@ using System; -using System.Linq; +using System.Buffers.Binary; +using System.Runtime.InteropServices; using System.Text; using Sharp7.Rx.Enums; @@ -10,18 +11,15 @@ namespace Sharp7.Rx public static TValue ConvertToType(byte[] buffer, S7VariableAddress address) { if (typeof(TValue) == typeof(bool)) - { - return (TValue) (object) Convert.ToBoolean(buffer[0] & (1 << address.Bit)); - } + return (TValue) (object) (((buffer[0] >> address.Bit) & 1) > 0); if (typeof(TValue) == typeof(int)) { if (address.Length == 2) - return (TValue)(object)((buffer[0] << 8) + buffer[1]); + return (TValue) (object) BinaryPrimitives.ReadInt16BigEndian(buffer); if (address.Length == 4) { - Array.Reverse(buffer); - return (TValue)(object)BitConverter.ToInt32(buffer,0); + return (TValue) (object) BinaryPrimitives.ReadInt32BigEndian(buffer); } throw new InvalidOperationException($"length must be 2 or 4 but is {address.Length}"); @@ -29,35 +27,36 @@ namespace Sharp7.Rx if (typeof(TValue) == typeof(long)) { - Array.Reverse(buffer); - return (TValue)(object)BitConverter.ToInt64(buffer,0); + return (TValue) (object) BinaryPrimitives.ReadInt64BigEndian(buffer); } if (typeof(TValue) == typeof(ulong)) { - Array.Reverse(buffer); - return (TValue)(object)BitConverter.ToUInt64(buffer, 0); + return (TValue) (object) BinaryPrimitives.ReadUInt64BigEndian(buffer); } if (typeof(TValue) == typeof(short)) { - return (TValue)(object)(short)((buffer[0] << 8) + buffer[1]); + return (TValue) (object) BinaryPrimitives.ReadInt16BigEndian(buffer); } if (typeof(TValue) == typeof(byte) || typeof(TValue) == typeof(char)) { - return (TValue)(object)buffer[0]; + return (TValue) (object) buffer[0]; } if (typeof(TValue) == typeof(byte[])) { - return (TValue)(object)buffer; + return (TValue) (object) buffer; } if (typeof(TValue) == typeof(double) || typeof(TValue) == typeof(float)) { - var d = BitConverter.ToSingle(buffer.Reverse().ToArray(),0); - return (TValue)(object)d; + var d = new UInt32SingleMap + { + UInt32 = BinaryPrimitives.ReadUInt32BigEndian(buffer) + }; + return (TValue) (object) d.Single; } if (typeof(TValue) == typeof(string)) @@ -68,7 +67,7 @@ namespace Sharp7.Rx // https://cache.industry.siemens.com/dl/files/480/22506480/att_105176/v1/s7_scl_string_parameterzuweisung_e.pdf var length = Math.Min(address.Length, buffer[1]); - + return (TValue) (object) Encoding.ASCII.GetString(buffer, 2, length); } else @@ -78,5 +77,12 @@ namespace Sharp7.Rx throw new InvalidOperationException(string.Format("type '{0}' not supported.", typeof(TValue))); } + + [StructLayout(LayoutKind.Explicit)] + private struct UInt32SingleMap + { + [FieldOffset(0)] public uint UInt32; + [FieldOffset(0)] public float Single; + } } } \ No newline at end of file