Skip to content

Commit

Permalink
Fix BitFieldType-Parser and wrote tests for it
Browse files Browse the repository at this point in the history
  • Loading branch information
patrick-dmxc committed Sep 25, 2024
1 parent 67240aa commit 4e9782d
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 39 deletions.
24 changes: 22 additions & 2 deletions RDMSharp/Metadata/DataTree.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace RDMSharp.Metadata
{
Expand Down Expand Up @@ -53,8 +54,27 @@ public bool Equals(DataTree other)
return Name == other.Name &&
Index == other.Index &&
EqualityComparer<object>.Default.Equals(Value, other.Value) &&
EqualityComparer<DataTree[]>.Default.Equals(Children, other.Children) &&
EqualityComparer<DataTreeIssue[]>.Default.Equals(Issues, other.Issues);
compairArrays(this, other);

bool compairArrays(DataTree _this, DataTree other)
{
if (_this.Children != null)
{
if (!_this.Children.SequenceEqual(other.Children))
return false;
}
else if (other.Children != null)
return false;
if (_this.Issues != null)
{
if (!_this.Issues.SequenceEqual(other.Issues))
return false;
}
else if (other.Issues != null)
return false;

return true;
}
}

public override int GetHashCode()
Expand Down
82 changes: 46 additions & 36 deletions RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;

namespace RDMSharp.Metadata.JSON.OneOfTypes
{
public class BitFieldType : CommonPropertiesForNamed
{
[JsonConstructor]
public BitFieldType(string name,
string displayName,
string notes,
string[] resources,
string type,
ushort size,
bool? valueForUnspecified,
BitType[] bits) : base()
{
if (!"bitField".Equals(type))
throw new ArgumentException($"Argument {nameof(type)} has to be \"bitField\"");
if (size % 8 != 0)
throw new ArgumentOutOfRangeException($"Argument {nameof(size)} has to be a multiple of 8");

Name = name;
DisplayName = displayName;
Notes = notes;
Resources = resources;
Type = type;
Size = size;
ValueForUnspecified = valueForUnspecified;
Bits = bits;
}

[JsonPropertyName("name")]
[JsonPropertyOrder(1)]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override string Name { get; }

[JsonPropertyName("displayName")]
[JsonPropertyOrder(2)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string DisplayName { get; }

[JsonPropertyName("notes")]
[JsonPropertyOrder(4)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Notes { get; }

[JsonPropertyName("resources")]
[JsonPropertyOrder(5)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
Expand All @@ -63,11 +40,40 @@ public BitFieldType(string name,
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyOrder(32)]
public bool? ValueForUnspecified { get; }

[JsonPropertyName("bits")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyOrder(41)]
public BitType[] Bits { get; }

[JsonConstructor]
public BitFieldType(string name,
string displayName,
string notes,
string[] resources,
string type,
ushort size,
bool? valueForUnspecified,
BitType[] bits) : base()
{
if (!"bitField".Equals(type))
throw new ArgumentException($"Argument {nameof(type)} has to be \"bitField\"");
if (size % 8 != 0)
throw new ArgumentOutOfRangeException($"Argument {nameof(size)} has to be a multiple of 8");

Name = name;
DisplayName = displayName;
Notes = notes;
Resources = resources;
Type = type;
Size = size;
ValueForUnspecified = valueForUnspecified;
Bits = bits;
}
public BitFieldType(string name, ushort size, BitType[] bits) : this(name, null, null, null, "bitField", size, null, bits)
{
}

public override PDL GetDataLength()
{
return new PDL((uint)(Size / 8));
Expand All @@ -94,10 +100,10 @@ public override byte[] ParsePayloadToData(DataTree dataTree)
BitType bit = Bits.FirstOrDefault(b=>b.Name== bitDataTree.Name);
if (bit == null)
throw new ArithmeticException($"Can't find matching BitType {bitDataTree.Name}");
if (bitDataTree.Index != bit.Index)
if (Bits[bitDataTree.Index] != bit)
throw new ArithmeticException($"The given DataTree {nameof(bitDataTree.Index)}({bitDataTree.Index}) not match BitType {nameof(bit.Index)}({bit.Index})");
if (bitDataTree.Value is not bool value)
throw new ArithmeticException($"DataTree VAlue is not bool");
throw new ArithmeticException($"DataTree Value is not bool");

data[bit.Index] = value;
}
Expand All @@ -110,15 +116,19 @@ public override DataTree ParseDataToPayload(ref byte[] data)
List<DataTreeIssue> issueList = new List<DataTreeIssue>();
int byteCount = (Size / 8);
if (byteCount != data.Length)
{
issueList.Add(new DataTreeIssue($"Data length not match given Size/8 ({byteCount})"));

byte[] cloneData = new byte[byteCount];
Array.Copy(data, cloneData, data.Length);
data = cloneData;
}
bool[] bools = Tools.DataToBoolArray(ref data, this.Size);
foreach (BitType bitType in Bits)
bitDataTrees.Add(new DataTree(bitType.Name, bitType.Index, bools[bitType.Index]));

data = data.Skip(byteCount).ToArray();

return new DataTree(this.Name, 0, bitDataTrees.OrderBy(b=>b.Index), issueList.Count != 0 ? issueList.ToArray() : null);
for (uint i = 0; i < Bits.Length; i++)
{
BitType bitType = Bits[i];
bitDataTrees.Add(new DataTree(bitType.Name, i, bools[bitType.Index]));
}
return new DataTree(this.Name, 0, children: bitDataTrees.OrderBy(b=>b.Index).ToArray(), issueList.Count != 0 ? issueList.ToArray() : null);
}
}
}
}
5 changes: 4 additions & 1 deletion RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ public BitType(string name,
Index = index;
Reserved = reserved;
ValueIfReserved = valueIfReserved;
}
public BitType(string name, ushort index) : this(name, null, null, null, "bit", index, null, null)
{
}

[JsonPropertyName("name")]
[JsonPropertyName("name")]
[JsonPropertyOrder(1)]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override string Name { get; }
Expand Down
40 changes: 40 additions & 0 deletions RDMSharpTests/Metadata/JSON/TestBitFieldType.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using RDMSharp.Metadata;
using RDMSharp.Metadata.JSON.OneOfTypes;
using RDMSharp.RDM;

Expand All @@ -23,6 +24,45 @@ public void TestMany()

Assert.Throws(typeof(ArgumentException), () => bitFieldType = new BitFieldType("NAME", "DISPLAY_NAME", "NOTES", null, "botField", 16, false, bitTypes));
Assert.Throws(typeof(ArgumentOutOfRangeException), () => bitFieldType = new BitFieldType("NAME", "DISPLAY_NAME", "NOTES", null, "bitField", 7, false, bitTypes));


bitTypes = new BitType[3];
bitTypes[0] = new BitType("NAME11", 2);
bitTypes[1] = new BitType("NAME22", 4);
bitTypes[2] = new BitType("NAME33", 15);
bitFieldType = new BitFieldType("NAME_BIT_FIELD", 16, bitTypes);
var dataTree= new DataTree(bitFieldType.Name,0,new DataTree[] { new DataTree(bitTypes[0].Name, 0, true), new DataTree(bitTypes[1].Name, 1, true), new DataTree(bitTypes[2].Name, 2, true), });

DoParseDataTest(bitFieldType, dataTree, new byte[] { 0b00010100, 0b10000000 });
}
private void DoParseDataTest(BitFieldType bitFieldType, DataTree dataTree, byte[] expectedData, string message = null)
{
Assert.Multiple(() =>
{
Assert.That(dataTree.Value, Is.Null);
Assert.That(dataTree.Children, Is.Not.Null);
var data = new byte[0];
Assert.DoesNotThrow(() => data = bitFieldType.ParsePayloadToData(dataTree), message);
Assert.That(data, Is.EqualTo(expectedData), message);
byte[] clonaData = new byte[data.Length];
Array.Copy(data, clonaData, clonaData.Length);
var parsedDataTree = bitFieldType.ParseDataToPayload(ref clonaData);
Assert.That(clonaData, Has.Length.EqualTo(0), message);
Assert.That(parsedDataTree, Is.EqualTo(dataTree), message);
Assert.That(parsedDataTree.Value, Is.Null);
//Test for short Data & PDL Issue
clonaData = new byte[data.Length - 1];
Array.Copy(data, clonaData, clonaData.Length);
Assert.DoesNotThrow(() => parsedDataTree = bitFieldType.ParseDataToPayload(ref clonaData));
Assert.That(parsedDataTree.Issues, Is.Not.Null);
Assert.That(parsedDataTree.Value, Is.Null);
Assert.That(parsedDataTree.Children, Is.Not.Null);
Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree("Different Name", dataTree.Index, dataTree.Value)), message);
});
}
}
}

0 comments on commit 4e9782d

Please sign in to comment.