Skip to content

Commit

Permalink
Fix writing nested classes
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Oleksy authored and admo committed Oct 4, 2018
1 parent 370fd6b commit de08439
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 12 deletions.
25 changes: 25 additions & 0 deletions S7.Net.UnitTest/S7NetTestsAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,31 @@ public async Task Test_Async_ReadAndWriteClass()
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>
Expand Down
25 changes: 25 additions & 0 deletions S7.Net.UnitTest/S7NetTestsSync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,31 @@ public void T31_ReadClassWithNestedClassAfterBit()
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()
{
Expand Down
5 changes: 3 additions & 2 deletions S7.Net/PlcAsynchronous.cs
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,9 @@ public async Task WriteStructAsync(object structValue, int db, int startByteAdr
/// <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)
Expand Down
18 changes: 8 additions & 10 deletions S7.Net/Types/Class.cs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ public static double FromBytes(object sourceClass, byte[] bytes, double numBytes
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;
Expand Down Expand Up @@ -282,7 +282,7 @@ private static void ToBytes(object propertyValue, byte[] bytes, ref double numBy
bytes2 = Single.ToByteArray((float)propertyValue);
break;
default:
bytes2 = ToBytes(propertyValue);
numBytes = ToBytes(propertyValue, bytes, numBytes);
break;
}

Expand All @@ -297,19 +297,17 @@ private static void ToBytes(object propertyValue, byte[] bytes, ref double numBy
bytes[bytePos + bCnt] = bytes2[bCnt];
numBytes += bytes2.Length;
}

return numBytes;
}

/// <summary>
/// Creates a byte array depending on the struct type.
/// </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)
{
Expand All @@ -319,15 +317,15 @@ public static byte[] ToBytes(object sourceClass)
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;
}
}
}

0 comments on commit de08439

Please sign in to comment.