Skip to content

Commit

Permalink
Decoding name now also supports strings without padding nulls. (#194)
Browse files Browse the repository at this point in the history
#193 non-breaking

Co-authored-by: Menno Lodder <menno@lodder>
  • Loading branch information
mennolodder and Menno Lodder authored Jan 14, 2024
1 parent 24bcfaf commit f07713c
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public LegoWirelessMessage Decode(byte hubId, in Span<byte> data)

var message = informationType switch
{
PortModeInformationType.Name => new PortModeInformationForNameMessage(portId, mode, Encoding.ASCII.GetString(payload.Slice(0, payload.IndexOf<byte>(0x00)))),
// Here the specs say to use the length field and just pick the remainder of the bytes, no termination.
PortModeInformationType.Name => new PortModeInformationForNameMessage(portId, mode, ParseStringIgnoringTrainingNullCharacters(payload)),
PortModeInformationType.Raw => new PortModeInformationForRawMessage(portId, mode, RawMin: BitConverter.ToSingle(payload.Slice(0, 4)), RawMax: BitConverter.ToSingle(payload.Slice(4, 4))),
PortModeInformationType.Pct => new PortModeInformationForPctMessage(portId, mode, PctMin: BitConverter.ToSingle(payload.Slice(0, 4)), PctMax: BitConverter.ToSingle(payload.Slice(4, 4))),
PortModeInformationType.SI => new PortModeInformationForSIMessage(portId, mode, SIMin: BitConverter.ToSingle(payload.Slice(0, 4)), SIMax: BitConverter.ToSingle(payload.Slice(4, 4))),
Expand All @@ -34,6 +35,18 @@ public LegoWirelessMessage Decode(byte hubId, in Span<byte> data)
return message;
}

private static string ParseStringIgnoringTrainingNullCharacters(Span<byte> data)
{
// Most devices pad the name with 0x00
var firstNullCharIndex = data.IndexOf<byte>(0x00);
var dataToDecode = data;
if (firstNullCharIndex != -1) {
// Trim everything after the last 0x00.
dataToDecode = data.Slice(0, firstNullCharIndex);
}

return Encoding.ASCII.GetString(dataToDecode);
}
private PortModeInformationMessage DecodeMapping(byte portId, byte mode, in Span<byte> data)
=> new PortModeInformationForMappingMessage(
portId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public class PortModeInformationEncoderTest
[InlineData("11-00-44-00-03-00-41-50-4F-53-00-00-00-00-00-00-00", 0x00, 0x03, PortModeInformationType.Name, "APOS")]
[InlineData("11-00-44-00-04-00-4C-4F-41-44-00-00-00-00-00-00-00", 0x00, 0x04, PortModeInformationType.Name, "LOAD")]
[InlineData("11-00-44-00-05-00-43-41-4C-49-42-00-00-00-00-00-00", 0x00, 0x05, PortModeInformationType.Name, "CALIB")]
// WeDo 2.0 actually uses full name length
[InlineData("11-00-44-00-00-00-4C-50-46-32-2D-4D-4D-4F-54-4F-52", 0x00, 0x00, PortModeInformationType.Name, "LPF2-MMOTOR")]
public void PortModeInformationEncoder_Decode_Name(string data, byte expectedPort, byte expectedMode, PortModeInformationType expectedType, string expectedText)
{
var message = Decode<PortModeInformationForNameMessage>(data);
Expand Down

0 comments on commit f07713c

Please sign in to comment.