diff --git a/S7.Net.UnitTest/TypeTests/StringExTests.cs b/S7.Net.UnitTest/TypeTests/S7StringTests.cs similarity index 90% rename from S7.Net.UnitTest/TypeTests/StringExTests.cs rename to S7.Net.UnitTest/TypeTests/S7StringTests.cs index aecf905..0bc8ef9 100644 --- a/S7.Net.UnitTest/TypeTests/StringExTests.cs +++ b/S7.Net.UnitTest/TypeTests/S7StringTests.cs @@ -7,7 +7,7 @@ using System.Linq; namespace S7.Net.UnitTest.TypeTests { [TestClass] - public class StringExTests + public class S7StringTests { [TestMethod] public void ReadEmptyStringWithZeroByteLength() @@ -36,7 +36,7 @@ namespace S7.Net.UnitTest.TypeTests [TestMethod] public void ReadMalformedStringSizeLargerThanCapacity() { - Assert.ThrowsException(() => StringEx.FromByteArray(new byte[] { 3, 5, 0, 1, 2 })); + Assert.ThrowsException(() => S7String.FromByteArray(new byte[] { 3, 5, 0, 1, 2 })); } [TestMethod] @@ -102,7 +102,7 @@ namespace S7.Net.UnitTest.TypeTests [TestMethod] public void WriteAbcWithStringLargetThanReservedLength() { - Assert.ThrowsException(() => StringEx.ToByteArray("Abc", 2)); + Assert.ThrowsException(() => S7String.ToByteArray("Abc", 2)); } [TestMethod] @@ -119,16 +119,16 @@ namespace S7.Net.UnitTest.TypeTests private static void AssertFromByteArrayEquals(string expected, params byte[] bytes) { - var convertedString = StringEx.FromByteArray(bytes); + var convertedString = S7String.FromByteArray(bytes); Assert.AreEqual(expected, convertedString); } private static void AssertToByteArrayAndBackEquals(string value, int reservedLength, params byte[] expected) { - var convertedData = StringEx.ToByteArray(value, reservedLength); + var convertedData = S7String.ToByteArray(value, reservedLength); CollectionAssert.AreEqual(expected, convertedData); - var convertedBack = StringEx.FromByteArray(convertedData); + var convertedBack = S7String.FromByteArray(convertedData); Assert.AreEqual(value, convertedBack); } } diff --git a/S7.Net/Enums.cs b/S7.Net/Enums.cs index fdb96ff..c523ad7 100644 --- a/S7.Net/Enums.cs +++ b/S7.Net/Enums.cs @@ -169,14 +169,14 @@ LReal, /// - /// String variable type (variable) + /// Char Array / C-String variable type (variable) /// String, /// - /// String variable type (variable) + /// S7 String variable type (variable) /// - StringEx, + S7String, /// /// Timer variable type diff --git a/S7.Net/PLCHelpers.cs b/S7.Net/PLCHelpers.cs index ae1ff29..f2c757d 100644 --- a/S7.Net/PLCHelpers.cs +++ b/S7.Net/PLCHelpers.cs @@ -122,8 +122,8 @@ namespace S7.Net case VarType.String: return Types.String.FromByteArray(bytes); - case VarType.StringEx: - return StringEx.FromByteArray(bytes); + case VarType.S7String: + return S7String.FromByteArray(bytes); case VarType.Timer: if (varCount == 1) @@ -186,7 +186,7 @@ namespace S7.Net return (varCount < 1) ? 1 : varCount; case VarType.String: return varCount; - case VarType.StringEx: + case VarType.S7String: return varCount + 2; case VarType.Word: case VarType.Timer: diff --git a/S7.Net/Protocol/Serialization.cs b/S7.Net/Protocol/Serialization.cs index b9ac9a5..ceecaa6 100644 --- a/S7.Net/Protocol/Serialization.cs +++ b/S7.Net/Protocol/Serialization.cs @@ -18,8 +18,8 @@ namespace S7.Net.Protocol throw new Exception($"DataItem.Value is null, cannot serialize. StartAddr={dataItem.StartByteAdr} VarType={dataItem.VarType}"); } if (dataItem.Value is string s) - return dataItem.VarType == VarType.StringEx - ? StringEx.ToByteArray(s, dataItem.Count) + return dataItem.VarType == VarType.S7String + ? S7String.ToByteArray(s, dataItem.Count) : Types.String.ToByteArray(s, dataItem.Count); return SerializeValue(dataItem.Value); diff --git a/S7.Net/Types/S7String.cs b/S7.Net/Types/S7String.cs new file mode 100644 index 0000000..6210e53 --- /dev/null +++ b/S7.Net/Types/S7String.cs @@ -0,0 +1,69 @@ +using System; +using System.Text; + +namespace S7.Net.Types +{ + /// + /// Contains the methods to convert from S7 strings to C# strings + /// An S7 String has a preceeding 2 byte header containing its capacity and length + /// + public static class S7String + { + /// + /// Converts S7 bytes to a string + /// + /// + /// + public static string FromByteArray(byte[] bytes) + { + if (bytes.Length < 2) + { + throw new PlcException(ErrorCode.ReadData, "Malformed S7 String / too short"); + } + + int size = bytes[0]; + int length = bytes[1]; + if (length > size) + { + throw new PlcException(ErrorCode.ReadData, "Malformed S7 String / length larger than capacity"); + } + + try + { + return Encoding.ASCII.GetString(bytes, 2, length); + } + catch (Exception e) + { + throw new PlcException(ErrorCode.ReadData, + $"Failed to parse {VarType.S7String} from data. Following fields were read: size: '{size}', actual length: '{length}', total number of bytes (including header): '{bytes.Length}'.", + e); + } + + } + + /// + /// Converts a to S7 string with 2-byte header. + /// + /// The string to convert to byte array. + /// The length (in bytes) allocated in PLC for string excluding header. + /// A containing the string header and string value with a maximum length of + 2. + public static byte[] ToByteArray(string value, int reservedLength) + { + if (value is null) + { + throw new ArgumentNullException(nameof(value)); + } + + if (reservedLength > byte.MaxValue) throw new ArgumentException($"The maximum string length supported is {byte.MaxValue}."); + + var bytes = Encoding.ASCII.GetBytes(value); + if (bytes.Length > reservedLength) throw new ArgumentException($"The provided string length ({bytes.Length} is larger than the specified reserved length ({reservedLength})."); + + var buffer = new byte[2 + reservedLength]; + Array.Copy(bytes, 0, buffer, 2, bytes.Length); + buffer[0] = (byte)reservedLength; + buffer[1] = (byte)bytes.Length; + return buffer; + } + } +} diff --git a/S7.Net/Types/String.cs b/S7.Net/Types/String.cs index aaf3428..3917635 100644 --- a/S7.Net/Types/String.cs +++ b/S7.Net/Types/String.cs @@ -1,7 +1,7 @@ namespace S7.Net.Types { /// - /// Contains the methods to convert from S7 strings to C# strings + /// Contains the methods to convert from S7 Array of Chars (like a const char[N] C-String) to C# strings /// public class String { diff --git a/S7.Net/Types/StringEx.cs b/S7.Net/Types/StringEx.cs index 5f152b2..6c0381a 100644 --- a/S7.Net/Types/StringEx.cs +++ b/S7.Net/Types/StringEx.cs @@ -1,70 +1,15 @@ using System; -using System.Text; namespace S7.Net.Types { - /// - /// Contains the methods to convert from S7 strings to C# strings - /// there are two kinds how strings a send. This one is with a pre of two bytes - /// they contain the length of the string - /// + /// + [Obsolete("Please use S7String class")] public static class StringEx { - /// - /// Converts S7 bytes to a string - /// - /// - /// - public static string FromByteArray(byte[] bytes) - { - if (bytes.Length < 2) - { - throw new PlcException(ErrorCode.ReadData, "Malformed S7 String / too short"); - } + /// + public static string FromByteArray(byte[] bytes) => S7String.FromByteArray(bytes); - int size = bytes[0]; - int length = bytes[1]; - if (length > size) - { - throw new PlcException(ErrorCode.ReadData, "Malformed S7 String / length larger than capacity"); - } - - try - { - return Encoding.ASCII.GetString(bytes, 2, length); - } - catch (Exception e) - { - throw new PlcException(ErrorCode.ReadData, - $"Failed to parse {VarType.StringEx} from data. Following fields were read: size: '{size}', actual length: '{length}', total number of bytes (including header): '{bytes.Length}'.", - e); - } - - } - - /// - /// Converts a to S7 string with 2-byte header. - /// - /// The string to convert to byte array. - /// The length (in bytes) allocated in PLC for string excluding header. - /// A containing the string header and string value with a maximum length of + 2. - public static byte[] ToByteArray(string value, int reservedLength) - { - if (value is null) - { - throw new ArgumentNullException(nameof(value)); - } - - if (reservedLength > byte.MaxValue) throw new ArgumentException($"The maximum string length supported is {byte.MaxValue}."); - - var bytes = Encoding.ASCII.GetBytes(value); - if (bytes.Length > reservedLength) throw new ArgumentException($"The provided string length ({bytes.Length} is larger than the specified reserved length ({reservedLength})."); - - var buffer = new byte[2 + reservedLength]; - Array.Copy(bytes, 0, buffer, 2, bytes.Length); - buffer[0] = (byte)reservedLength; - buffer[1] = (byte)bytes.Length; - return buffer; - } + /// + public static byte[] ToByteArray(string value, int reservedLength) => S7String.ToByteArray(value, reservedLength); } }