Fix writing nested classes

This commit is contained in:
Adam Oleksy
2018-09-26 14:38:12 +02:00
committed by Adam Oleksy
parent 370fd6b3d9
commit de084394a6
4 changed files with 61 additions and 12 deletions

View File

@@ -160,6 +160,31 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
}
[TestMethod]
public async Task Test_Async_ReadAndWriteNestedClass()
{
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
TestClassWithNestedClass tc = new TestClassWithNestedClass
{
BitVariable00 = true,
BitVariable01 = new TestClassInnerWithBool { BitVariable00 = true },
ByteVariable02 = new TestClassInnerWithByte { ByteVariable00 = 128 },
BitVariable03 = true,
ShortVariable04 = new TestClassInnerWithShort { ShortVarialbe00 = -15000 }
};
await plc.WriteClassAsync(tc, DB4);
TestClassWithNestedClass tc2 = new TestClassWithNestedClass();
// Values that are read from a class are stored inside the class itself, that is passed by reference
await plc.ReadClassAsync(tc2, DB4);
Assert.AreEqual(tc.BitVariable00, tc2.BitVariable00);
Assert.AreEqual(tc.BitVariable01.BitVariable00, tc2.BitVariable01.BitVariable00);
Assert.AreEqual(tc.ByteVariable02.ByteVariable00, tc2.ByteVariable02.ByteVariable00);
Assert.AreEqual(tc.BitVariable03, tc2.BitVariable03);
Assert.AreEqual(tc.ShortVariable04.ShortVarialbe00, tc2.ShortVariable04.ShortVarialbe00);
}
/// <summary>
/// Read/Write a struct that has the same properties of a DB with the same field in the same order
/// </summary>

View File

@@ -718,6 +718,31 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc.ShortVariable04.ShortVarialbe00, tc2.ShortVariable04.ShortVarialbe00);
}
[TestMethod]
public void T32_ReadAndWriteNestedClass()
{
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
TestClassWithNestedClass tc = new TestClassWithNestedClass
{
BitVariable00 = true,
BitVariable01 = new TestClassInnerWithBool { BitVariable00 = true },
ByteVariable02 = new TestClassInnerWithByte { ByteVariable00 = 128 },
BitVariable03 = true,
ShortVariable04 = new TestClassInnerWithShort { ShortVarialbe00 = -15000 }
};
plc.WriteClass(tc, DB4);
TestClassWithNestedClass tc2 = new TestClassWithNestedClass();
// Values that are read from a class are stored inside the class itself, that is passed by reference
plc.ReadClass(tc2, DB4);
Assert.AreEqual(tc.BitVariable00, tc2.BitVariable00);
Assert.AreEqual(tc.BitVariable01.BitVariable00, tc2.BitVariable01.BitVariable00);
Assert.AreEqual(tc.ByteVariable02.ByteVariable00, tc2.ByteVariable02.ByteVariable00);
Assert.AreEqual(tc.BitVariable03, tc2.BitVariable03);
Assert.AreEqual(tc.ShortVariable04.ShortVarialbe00, tc2.ShortVariable04.ShortVarialbe00);
}
[TestMethod, ExpectedException(typeof(PlcException))]
public void T18_ReadStructThrowsIfPlcIsNotConnected()
{

View File

@@ -370,8 +370,9 @@ namespace S7.Net
/// <returns>A task that represents the asynchronous write operation.</returns>
public async Task WriteClassAsync(object classValue, int db, int startByteAdr = 0)
{
var bytes = Types.Class.ToBytes(classValue).ToList();
await WriteBytesAsync(DataType.DataBlock, db, startByteAdr, bytes.ToArray());
byte[] bytes = new byte[(int)Class.GetClassSize(classValue)];
Types.Class.ToBytes(classValue, bytes);
await WriteBytesAsync(DataType.DataBlock, db, startByteAdr, bytes);
}
private async Task<byte[]> ReadBytesWithSingleRequestAsync(DataType dataType, int db, int startByteAdr, int count)

View File

@@ -239,7 +239,7 @@ namespace S7.Net.Types
return numBytes;
}
private static void ToBytes(object propertyValue, byte[] bytes, ref double numBytes)
private static double SetBytesFromProperty(object propertyValue, byte[] bytes, double numBytes)
{
int bytePos = 0;
int bitPos = 0;
@@ -282,7 +282,7 @@ namespace S7.Net.Types
bytes2 = Single.ToByteArray((float)propertyValue);
break;
default:
bytes2 = ToBytes(propertyValue);
numBytes = ToBytes(propertyValue, bytes, numBytes);
break;
}
@@ -297,6 +297,8 @@ namespace S7.Net.Types
bytes[bytePos + bCnt] = bytes2[bCnt];
numBytes += bytes2.Length;
}
return numBytes;
}
/// <summary>
@@ -304,12 +306,8 @@ namespace S7.Net.Types
/// </summary>
/// <param name="sourceClass">The struct object</param>
/// <returns>A byte array or null if fails.</returns>
public static byte[] ToBytes(object sourceClass)
public static double ToBytes(object sourceClass, byte[] bytes, double numBytes = 0.0)
{
int size = (int)GetClassSize(sourceClass);
byte[] bytes = new byte[size];
double numBytes = 0.0;
var properties = GetAccessableProperties(sourceClass.GetType());
foreach (var property in properties)
{
@@ -319,15 +317,15 @@ namespace S7.Net.Types
Type elementType = property.PropertyType.GetElementType();
for (int i = 0; i < array.Length && numBytes < bytes.Length; i++)
{
ToBytes(array.GetValue(i), bytes, ref numBytes);
numBytes = SetBytesFromProperty(array.GetValue(i), bytes, numBytes);
}
}
else
{
ToBytes(property.GetValue(sourceClass, null), bytes, ref numBytes);
numBytes = SetBytesFromProperty(property.GetValue(sourceClass, null), bytes, numBytes);
}
}
return bytes;
return numBytes;
}
}
}