mirror of
https://github.com/S7NetPlus/s7netplus.git
synced 2026-02-17 14:28:25 +08:00
Rename StringEx to S7String.
This name is already somewhat used in code and gives this a better name.
This commit is contained in:
@@ -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<PlcException>(() => StringEx.FromByteArray(new byte[] { 3, 5, 0, 1, 2 }));
|
||||
Assert.ThrowsException<PlcException>(() => 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<ArgumentException>(() => StringEx.ToByteArray("Abc", 2));
|
||||
Assert.ThrowsException<ArgumentException>(() => 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);
|
||||
}
|
||||
}
|
||||
@@ -169,14 +169,14 @@
|
||||
LReal,
|
||||
|
||||
/// <summary>
|
||||
/// String variable type (variable)
|
||||
/// Char Array / C-String variable type (variable)
|
||||
/// </summary>
|
||||
String,
|
||||
|
||||
/// <summary>
|
||||
/// String variable type (variable)
|
||||
/// S7 String variable type (variable)
|
||||
/// </summary>
|
||||
StringEx,
|
||||
S7String,
|
||||
|
||||
/// <summary>
|
||||
/// Timer variable type
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
69
S7.Net/Types/S7String.cs
Normal file
69
S7.Net/Types/S7String.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
public static class S7String
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts S7 bytes to a string
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="T:string"/> to S7 string with 2-byte header.
|
||||
/// </summary>
|
||||
/// <param name="value">The string to convert to byte array.</param>
|
||||
/// <param name="reservedLength">The length (in bytes) allocated in PLC for string excluding header.</param>
|
||||
/// <returns>A <see cref="T:byte[]" /> containing the string header and string value with a maximum length of <paramref name="reservedLength"/> + 2.</returns>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
public class String
|
||||
{
|
||||
|
||||
@@ -1,70 +1,15 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="S7String"/>
|
||||
[Obsolete("Please use S7String class")]
|
||||
public static class StringEx
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts S7 bytes to a string
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <returns></returns>
|
||||
public static string FromByteArray(byte[] bytes)
|
||||
{
|
||||
if (bytes.Length < 2)
|
||||
{
|
||||
throw new PlcException(ErrorCode.ReadData, "Malformed S7 String / too short");
|
||||
}
|
||||
/// <inheritdoc cref="S7String.FromByteArray(byte[])"/>
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="T:string"/> to S7 string with 2-byte header.
|
||||
/// </summary>
|
||||
/// <param name="value">The string to convert to byte array.</param>
|
||||
/// <param name="reservedLength">The length (in bytes) allocated in PLC for string excluding header.</param>
|
||||
/// <returns>A <see cref="T:byte[]" /> containing the string header and string value with a maximum length of <paramref name="reservedLength"/> + 2.</returns>
|
||||
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;
|
||||
}
|
||||
/// <inheritdoc cref="S7String.ToByteArray(string, int)"/>
|
||||
public static byte[] ToByteArray(string value, int reservedLength) => S7String.ToByteArray(value, reservedLength);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user