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
{
private static Encoding stringEncoding = Encoding.ASCII;
///
/// The Encoding used when serializing and deserializing S7String (Encoding.ASCII by default)
///
/// StringEncoding must not be null
public static Encoding StringEncoding
{
get => stringEncoding;
set => stringEncoding = value ?? throw new ArgumentNullException(nameof(StringEncoding));
}
///
/// 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 StringEncoding.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 characters) allocated in PLC for the string.
/// 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 > 254) throw new ArgumentException($"The maximum string length supported is 254.");
var bytes = StringEncoding.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;
}
}
}