mirror of
https://github.com/evopro-ag/Sharp7Reactive.git
synced 2025-12-17 12:12:51 +00:00
Switch ReadFromBuffer to span
This commit is contained in:
@@ -9,7 +9,7 @@ internal abstract class ConverterTestBase
|
|||||||
|
|
||||||
public static MethodInfo CreateReadMethod(ConverterTestCase tc)
|
public static MethodInfo CreateReadMethod(ConverterTestCase tc)
|
||||||
{
|
{
|
||||||
var convertMi = typeof(ValueConverter).GetMethod(nameof(ValueConverter.ReadFromBuffer));
|
var convertMi = typeof(ConverterTestBase).GetMethod(nameof(ReadFromBuffer));
|
||||||
var convert = convertMi!.MakeGenericMethod(tc.Value.GetType());
|
var convert = convertMi!.MakeGenericMethod(tc.Value.GetType());
|
||||||
return convert;
|
return convert;
|
||||||
}
|
}
|
||||||
@@ -67,12 +67,17 @@ internal abstract class ConverterTestBase
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This helper method exists, since I could not manage to invoke a generic method
|
/// This helper method exists, since I could not manage to invoke a generic method
|
||||||
/// accepring a Span<T> as parameter.
|
/// with a Span<T> parameter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void WriteToBuffer<TValue>(byte[] buffer, TValue value, VariableAddress address)
|
public static void WriteToBuffer<TValue>(byte[] buffer, TValue value, VariableAddress address) =>
|
||||||
{
|
|
||||||
ValueConverter.WriteToBuffer(buffer, value, address);
|
ValueConverter.WriteToBuffer(buffer, value, address);
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
|
/// This helper method exists, since I could not manage to invoke a generic method
|
||||||
|
/// with a Span<T> parameter.
|
||||||
|
/// </summary>
|
||||||
|
public static TValue ReadFromBuffer<TValue>(byte[] buffer, VariableAddress address) =>
|
||||||
|
ValueConverter.ReadFromBuffer<TValue>(buffer, address);
|
||||||
|
|
||||||
public record ConverterTestCase(object Value, string Address, byte[] Data)
|
public record ConverterTestCase(object Value, string Address, byte[] Data)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -143,42 +143,40 @@ internal static class ValueConverter
|
|||||||
{
|
{
|
||||||
return address.Type switch
|
return address.Type switch
|
||||||
{
|
{
|
||||||
DbType.String => ParseString(),
|
DbType.String => ParseString(buffer),
|
||||||
DbType.WString => ParseWString(),
|
DbType.WString => ParseWString(buffer),
|
||||||
DbType.Byte => Encoding.ASCII.GetString(buffer.ToArray()),
|
DbType.Byte => Encoding.ASCII.GetString(buffer),
|
||||||
_ => throw new DataTypeMissmatchException($"Cannot read string from {address.Type}", typeof(string), address)
|
_ => throw new DataTypeMissmatchException($"Cannot read string from {address.Type}", typeof(string), address)
|
||||||
};
|
};
|
||||||
|
|
||||||
string ParseString()
|
string ParseString(Span<byte> data)
|
||||||
{
|
{
|
||||||
// First byte is maximal length
|
// First byte is maximal length
|
||||||
// Second byte is actual length
|
// Second byte is actual length
|
||||||
// https://support.industry.siemens.com/cs/mdm/109747174?c=94063831435&lc=de-DE
|
// https://support.industry.siemens.com/cs/mdm/109747174?c=94063831435&lc=de-DE
|
||||||
|
|
||||||
var length = Math.Min(address.Length, buffer[1]);
|
var length = Math.Min(address.Length, data[1]);
|
||||||
|
|
||||||
return Encoding.ASCII.GetString(buffer, 2, length);
|
return Encoding.ASCII.GetString(data.Slice(2, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
string ParseWString()
|
string ParseWString(Span<byte> data)
|
||||||
{
|
{
|
||||||
// First 2 bytes are maximal length
|
// First 2 bytes are maximal length
|
||||||
// Second 2 bytes are actual length
|
// Second 2 bytes are actual length
|
||||||
// https://support.industry.siemens.com/cs/mdm/109747174?c=94063855243&lc=de-DE
|
// https://support.industry.siemens.com/cs/mdm/109747174?c=94063855243&lc=de-DE
|
||||||
|
|
||||||
// the length of the string is two bytes per
|
// the length of the string is two bytes per character
|
||||||
var length = Math.Min(address.Length, BinaryPrimitives.ReadUInt16BigEndian(buffer.AsSpan(2, 2))) * 2;
|
var length = Math.Min(address.Length, BinaryPrimitives.ReadUInt16BigEndian(data.Slice(2, 2))) * 2;
|
||||||
|
|
||||||
return Encoding.BigEndianUnicode.GetString(buffer, 4, length);
|
return Encoding.BigEndianUnicode.GetString(data.Slice(4, length));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
public static TValue ReadFromBuffer<TValue>(byte[] buffer, VariableAddress address)
|
public static TValue ReadFromBuffer<TValue>(Span<byte> buffer, VariableAddress address)
|
||||||
{
|
{
|
||||||
// Todo: Change to Span<byte> when switched to newer .net
|
|
||||||
|
|
||||||
if (buffer.Length < address.BufferLength)
|
if (buffer.Length < address.BufferLength)
|
||||||
throw new ArgumentException($"Buffer must be at least {address.BufferLength} bytes long for {address}", nameof(buffer));
|
throw new ArgumentException($"Buffer must be at least {address.BufferLength} bytes long for {address}", nameof(buffer));
|
||||||
|
|
||||||
@@ -204,7 +202,7 @@ internal static class ValueConverter
|
|||||||
writeFunc(buffer, address, value);
|
writeFunc(buffer, address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate object ReadFunc(byte[] data, VariableAddress address);
|
delegate object ReadFunc(Span<byte> data, VariableAddress address);
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
private struct UInt32SingleMap
|
private struct UInt32SingleMap
|
||||||
|
|||||||
Reference in New Issue
Block a user