Use BinaryPrimitives

This commit is contained in:
Peter Butzhammer
2024-02-06 17:47:00 +01:00
parent b87480c4f9
commit baef1afac1

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Linq; using System.Buffers.Binary;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
using Sharp7.Rx.Enums; using Sharp7.Rx.Enums;
@@ -10,18 +11,15 @@ namespace Sharp7.Rx
public static TValue ConvertToType<TValue>(byte[] buffer, S7VariableAddress address) public static TValue ConvertToType<TValue>(byte[] buffer, S7VariableAddress address)
{ {
if (typeof(TValue) == typeof(bool)) if (typeof(TValue) == typeof(bool))
{ return (TValue) (object) (((buffer[0] >> address.Bit) & 1) > 0);
return (TValue) (object) Convert.ToBoolean(buffer[0] & (1 << address.Bit));
}
if (typeof(TValue) == typeof(int)) if (typeof(TValue) == typeof(int))
{ {
if (address.Length == 2) if (address.Length == 2)
return (TValue)(object)((buffer[0] << 8) + buffer[1]); return (TValue) (object) BinaryPrimitives.ReadInt16BigEndian(buffer);
if (address.Length == 4) if (address.Length == 4)
{ {
Array.Reverse(buffer); return (TValue) (object) BinaryPrimitives.ReadInt32BigEndian(buffer);
return (TValue)(object)BitConverter.ToInt32(buffer,0);
} }
throw new InvalidOperationException($"length must be 2 or 4 but is {address.Length}"); 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)) if (typeof(TValue) == typeof(long))
{ {
Array.Reverse(buffer); return (TValue) (object) BinaryPrimitives.ReadInt64BigEndian(buffer);
return (TValue)(object)BitConverter.ToInt64(buffer,0);
} }
if (typeof(TValue) == typeof(ulong)) if (typeof(TValue) == typeof(ulong))
{ {
Array.Reverse(buffer); return (TValue) (object) BinaryPrimitives.ReadUInt64BigEndian(buffer);
return (TValue)(object)BitConverter.ToUInt64(buffer, 0);
} }
if (typeof(TValue) == typeof(short)) 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)) if (typeof(TValue) == typeof(byte) || typeof(TValue) == typeof(char))
{ {
return (TValue)(object)buffer[0]; return (TValue) (object) buffer[0];
} }
if (typeof(TValue) == typeof(byte[])) if (typeof(TValue) == typeof(byte[]))
{ {
return (TValue)(object)buffer; return (TValue) (object) buffer;
} }
if (typeof(TValue) == typeof(double) || typeof(TValue) == typeof(float)) if (typeof(TValue) == typeof(double) || typeof(TValue) == typeof(float))
{ {
var d = BitConverter.ToSingle(buffer.Reverse().ToArray(),0); var d = new UInt32SingleMap
return (TValue)(object)d; {
UInt32 = BinaryPrimitives.ReadUInt32BigEndian(buffer)
};
return (TValue) (object) d.Single;
} }
if (typeof(TValue) == typeof(string)) 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 // 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]); var length = Math.Min(address.Length, buffer[1]);
return (TValue) (object) Encoding.ASCII.GetString(buffer, 2, length); return (TValue) (object) Encoding.ASCII.GetString(buffer, 2, length);
} }
else else
@@ -78,5 +77,12 @@ namespace Sharp7.Rx
throw new InvalidOperationException(string.Format("type '{0}' not supported.", typeof(TValue))); 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;
}
} }
} }