From 8df1a9c8cb71e6667cd63a4100f2f6caf96cde4c Mon Sep 17 00:00:00 2001 From: Serge Camille Date: Mon, 4 Oct 2021 18:53:13 +0200 Subject: [PATCH 1/2] Add unit test for ReadClass uint32 bug. https://github.com/S7NetPlus/s7netplus/issues/414 --- S7.Net.UnitTest/TypeTests/ClassTests.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/S7.Net.UnitTest/TypeTests/ClassTests.cs b/S7.Net.UnitTest/TypeTests/ClassTests.cs index ba99c2cc..03cbe449 100644 --- a/S7.Net.UnitTest/TypeTests/ClassTests.cs +++ b/S7.Net.UnitTest/TypeTests/ClassTests.cs @@ -17,6 +17,19 @@ public void GetClassSizeTest() Assert.AreEqual(Class.GetClassSize(new TestClassUnevenSize(3, 17)), 10); } + /// + /// Ensure Uint32 is correctly parsed through ReadClass functions. Adresses issue https://github.com/S7NetPlus/s7netplus/issues/414 + /// + [TestMethod] + public void TestUint32Read() + { + var result = new TestUint32(); + var data = new byte[4] { 0, 0, 0, 5 }; + var bytesRead = Class.FromBytes(result, data); + Assert.AreEqual(bytesRead, data.Length); + Assert.AreEqual(5u, result.Value1); + } + private class TestClassUnevenSize { public bool Bool { get; set; } @@ -29,5 +42,10 @@ public TestClassUnevenSize(int byteCount, int bitCount) Bools = new bool[bitCount]; } } + + private class TestUint32 + { + public uint Value1 { get; set; } + } } } From 12281ec8020dfad274a84ece094eee60ef5b4940 Mon Sep 17 00:00:00 2001 From: Serge Camille Date: Mon, 4 Oct 2021 18:59:05 +0200 Subject: [PATCH 2/2] Fix ReadClass for Uint32 Use consistent DWord conversion for both Int32 and UInt32. Unfortunately there is no Span or even a FromByteArray function accepting a offset, so just use the same Array.Copy falls used for double. --- S7.Net/Types/Class.cs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/S7.Net/Types/Class.cs b/S7.Net/Types/Class.cs index 0dd78fa3..225f3f8c 100644 --- a/S7.Net/Types/Class.cs +++ b/S7.Net/Types/Class.cs @@ -153,11 +153,9 @@ public static double GetClassSize(object instance, double numBytes = 0.0, bool i numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) numBytes++; - // hier auswerten - uint sourceUInt = DWord.FromBytes(bytes[(int)numBytes + 3], - bytes[(int)numBytes + 2], - bytes[(int)numBytes + 1], - bytes[(int)numBytes + 0]); + var wordBuffer = new byte[4]; + Array.Copy(bytes, (int)numBytes, wordBuffer, 0, wordBuffer.Length); + uint sourceUInt = DWord.FromByteArray(wordBuffer); value = sourceUInt.ConvertToInt(); numBytes += 4; break; @@ -165,12 +163,9 @@ public static double GetClassSize(object instance, double numBytes = 0.0, bool i numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) numBytes++; - // hier auswerten - value = DWord.FromBytes( - bytes[(int)numBytes], - bytes[(int)numBytes + 1], - bytes[(int)numBytes + 2], - bytes[(int)numBytes + 3]); + var wordBuffer2 = new byte[4]; + Array.Copy(bytes, (int)numBytes, wordBuffer2, 0, wordBuffer2.Length); + value = DWord.FromByteArray(wordBuffer2); numBytes += 4; break; case "Single":