Skip to content

Commit d3ff29b

Browse files
committed
Nearly fixed #96.
1 parent 5ebde44 commit d3ff29b

File tree

3 files changed

+160
-7
lines changed

3 files changed

+160
-7
lines changed

src/SparkplugNet.Tests/Payloads/SparkplugPayloadConverterTestVersionB.cs

Lines changed: 114 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,7 +1909,10 @@ public void TestPropertySetConversion()
19091909
[TestMethod]
19101910
public void TestConvertVersionBPayloadFromProtoWithNegativeValues()
19111911
{
1912-
var value = -2;
1912+
var value1 = -1;
1913+
var value2 = -2;
1914+
var value3 = -3;
1915+
var value4 = -4;
19131916
var timestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero);
19141917
var bodyData = new byte[] { 1, 2, 3, 4 };
19151918
var metrics = new List<VersionBProtoBufPayload.Metric>
@@ -1922,17 +1925,68 @@ public void TestConvertVersionBPayloadFromProtoWithNegativeValues()
19221925
IsHistorical = true,
19231926
IsTransient = true,
19241927
IsNull = false,
1928+
DataType = (uint?)VersionBData.DataType.Int8,
1929+
IntValue = unchecked((uint)value1)
1930+
},
1931+
new()
1932+
{
1933+
Name = "Test2",
1934+
Timestamp = (ulong)timestamp.ToUnixTimeMilliseconds(),
1935+
Alias = 3,
1936+
IsHistorical = true,
1937+
IsTransient = true,
1938+
IsNull = false,
19251939
DataType = (uint?)VersionBData.DataType.Int16,
1926-
IntValue = unchecked((uint)value)
1940+
IntValue = unchecked((uint)value2)
1941+
},
1942+
new()
1943+
{
1944+
Name = "Test3",
1945+
Timestamp = (ulong)timestamp.ToUnixTimeMilliseconds(),
1946+
Alias = 4,
1947+
IsHistorical = true,
1948+
IsTransient = true,
1949+
IsNull = false,
1950+
DataType = (uint?)VersionBData.DataType.Int32,
1951+
IntValue = unchecked((uint)value3)
1952+
},
1953+
new()
1954+
{
1955+
Name = "Test4",
1956+
Timestamp = (ulong)timestamp.ToUnixTimeMilliseconds(),
1957+
Alias = 5,
1958+
IsHistorical = true,
1959+
IsTransient = true,
1960+
IsNull = false,
1961+
DataType = (uint?)VersionBData.DataType.Int64,
1962+
LongValue = unchecked((ulong)value4)
19271963
}
19281964
};
19291965
var convertedMetrics = new List<VersionBData.Metric>
19301966
{
1931-
new("Test1", VersionBData.DataType.Int16, (short)-2, timestamp)
1967+
new("Test1", VersionBData.DataType.Int8, (sbyte)value1, timestamp)
19321968
{
19331969
Alias = 2,
19341970
IsHistorical = true,
19351971
IsTransient = true
1972+
},
1973+
new("Test2", VersionBData.DataType.Int16, (short)value2, timestamp)
1974+
{
1975+
Alias = 3,
1976+
IsHistorical = true,
1977+
IsTransient = true
1978+
},
1979+
new("Test3", VersionBData.DataType.Int32, (int)value3, timestamp)
1980+
{
1981+
Alias = 4,
1982+
IsHistorical = true,
1983+
IsTransient = true
1984+
},
1985+
new("Test4", VersionBData.DataType.Int64, (long)value4, timestamp)
1986+
{
1987+
Alias = 5,
1988+
IsHistorical = true,
1989+
IsTransient = true
19361990
}
19371991
};
19381992
var oldPayload = new VersionBProtoBufPayload
@@ -1965,17 +2019,38 @@ public void TestConvertVersionBPayloadFromProtoWithNegativeValues()
19652019
[TestMethod]
19662020
public void TestConvertVersionBPayloadToProtoWithNegativeValues()
19672021
{
1968-
var value = -1;
2022+
var value1 = -1;
2023+
var value2 = -2;
2024+
var value3 = -3;
2025+
var value4 = -4;
19692026
var timestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero);
19702027
var bodyData = new byte[] { 1, 2, 3, 4 };
19712028

19722029
var metrics = new List<VersionBData.Metric>
19732030
{
1974-
new("Test1", VersionBData.DataType.Int8, (sbyte)-1, timestamp)
2031+
new("Test1", VersionBData.DataType.Int8, (sbyte)value1, timestamp)
19752032
{
19762033
Alias = 1,
19772034
IsHistorical = true,
19782035
IsTransient = true
2036+
},
2037+
new("Test2", VersionBData.DataType.Int16, (short)value2, timestamp)
2038+
{
2039+
Alias = 2,
2040+
IsHistorical = true,
2041+
IsTransient = true
2042+
},
2043+
new("Test3", VersionBData.DataType.Int32, (int)value3, timestamp)
2044+
{
2045+
Alias = 3,
2046+
IsHistorical = true,
2047+
IsTransient = true
2048+
},
2049+
new("Test4", VersionBData.DataType.Int64, (long)value4, timestamp)
2050+
{
2051+
Alias = 4,
2052+
IsHistorical = true,
2053+
IsTransient = true
19792054
}
19802055
};
19812056
var convertedMetrics = new List<VersionBProtoBufPayload.Metric>
@@ -1989,7 +2064,40 @@ public void TestConvertVersionBPayloadToProtoWithNegativeValues()
19892064
IsTransient = true,
19902065
IsNull = false,
19912066
DataType = (uint?)VersionBProtoBuf.DataType.Int8,
1992-
IntValue = unchecked((uint)value)
2067+
IntValue = unchecked((uint)value1)
2068+
},
2069+
new()
2070+
{
2071+
Name = "Test2",
2072+
Timestamp = (ulong)timestamp.ToUnixTimeMilliseconds(),
2073+
Alias = 2,
2074+
IsHistorical = true,
2075+
IsTransient = true,
2076+
IsNull = false,
2077+
DataType = (uint?)VersionBProtoBuf.DataType.Int16,
2078+
IntValue = unchecked((uint)value2)
2079+
},
2080+
new()
2081+
{
2082+
Name = "Test3",
2083+
Timestamp = (ulong)timestamp.ToUnixTimeMilliseconds(),
2084+
Alias = 3,
2085+
IsHistorical = true,
2086+
IsTransient = true,
2087+
IsNull = false,
2088+
DataType = (uint?)VersionBProtoBuf.DataType.Int32,
2089+
IntValue = unchecked((uint)value3)
2090+
},
2091+
new()
2092+
{
2093+
Name = "Test4",
2094+
Timestamp = (ulong)timestamp.ToUnixTimeMilliseconds(),
2095+
Alias = 4,
2096+
IsHistorical = true,
2097+
IsTransient = true,
2098+
IsNull = false,
2099+
DataType = (uint?)VersionBProtoBuf.DataType.Int64,
2100+
LongValue = unchecked((ulong)value4)
19932101
}
19942102
};
19952103
var oldPayload = new VersionBData.Payload

src/SparkplugNet/Core/Extensions/DataTypeExtensions.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,51 @@ internal static class DataTypeExtensions
2727
return default;
2828
}
2929

30+
// Check whether we need to convert from signed to unsigned.
31+
var needToConvertFromSignedToUnsigned =
32+
(objValue is sbyte sbyteVal && sbyteVal < 0) ||
33+
(objValue is short shortVal && shortVal < 0) ||
34+
(objValue is int intVal && intVal < 0) ||
35+
(objValue is long longVal && longVal < 0);
36+
37+
if (needToConvertFromSignedToUnsigned)
38+
{
39+
return unchecked((T)objValue);
40+
}
41+
42+
// Check whether we need to convert from unsigned to signed.
43+
// Check for uint values first.
44+
if (objValue is uint uintVal)
45+
{
46+
var needToConvertFromUnsignedIntToSigned =
47+
(uintVal > sbyte.MaxValue && typeof(T) == typeof(sbyte)) ||
48+
(uintVal > short.MaxValue && typeof(T) == typeof(short)) ||
49+
(uintVal > int.MaxValue && typeof(T) == typeof(int));
50+
51+
if (needToConvertFromUnsignedIntToSigned)
52+
{
53+
var intValue = unchecked((int)uintVal);
54+
return (T)Convert.ChangeType(intValue, typeof(T));
55+
}
56+
}
57+
58+
// Check for ulong values second.
59+
if (objValue is ulong ulongVal)
60+
{
61+
var needToConvertFromUnsignedLongToSigned =
62+
(ulongVal > (ulong)sbyte.MaxValue && typeof(T) == typeof(sbyte)) ||
63+
(ulongVal > (ulong)short.MaxValue && typeof(T) == typeof(short)) ||
64+
(ulongVal > int.MaxValue && typeof(T) == typeof(int)) ||
65+
(ulongVal > long.MaxValue && typeof(T) == typeof(long));
66+
67+
if (needToConvertFromUnsignedLongToSigned)
68+
{
69+
var intValue = unchecked((long)ulongVal);
70+
return (T)Convert.ChangeType(intValue, typeof(T));
71+
}
72+
}
73+
74+
// Regular case.
3075
return objValue is T valueAsT
3176
? valueAsT
3277
: (T)Convert.ChangeType(objValue, typeof(T));

src/SparkplugNet/VersionB/PayloadConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ public static VersionBProtoBuf.ProtoBufPayload.Metric ConvertVersionBMetric(Metr
221221
case VersionBDataTypeEnum.Int64:
222222
case VersionBDataTypeEnum.UInt32:
223223
case VersionBDataTypeEnum.UInt64:
224-
protoMetric.LongValue = metric.Value is not null ? metric.Value.ConvertOrDefaultTo<ulong>() : default;
224+
protoMetric.LongValue = metric.Value.ConvertOrDefaultTo<ulong>();
225225
break;
226226
case VersionBDataTypeEnum.DateTime:
227227
if (metric.Value is null)

0 commit comments

Comments
 (0)