public static String parseS7String(ReadBuffer io, int stringLength, String encoding) {
        try {
            if ("UTF-8".equalsIgnoreCase(encoding)) {
                // This is the maximum number of bytes a string can be long.
                short maxLength = io.readUnsignedShort(8);
                // This is the total length of the string on the PLC (Not necessarily the number of characters read)
                short totalStringLength = io.readUnsignedShort(8);

                final byte[] byteArray = new byte[totalStringLength];
                for (int i = 0; (i < stringLength) && io.hasMore(8); i++) {
                    final byte curByte = io.readByte();
                    if (i < totalStringLength) {
                        byteArray[i] = curByte;
                    } else {
                        // Gobble up the remaining data, which is not added to the string.
                        i++;
                        for (; (i < stringLength) && io.hasMore(8); i++) {
                            io.readByte();
                        }
                        break;
                    }
                }
                return new String(byteArray, StandardCharsets.UTF_8);
            } else if ("UTF-16".equalsIgnoreCase(encoding)) {
                // This is the maximum number of bytes a string can be long.
                int maxLength = io.readUnsignedInt(16);
                // This is the total length of the string on the PLC (Not necessarily the number of characters read)
                int totalStringLength = io.readUnsignedInt(16);

                final byte[] byteArray = new byte[totalStringLength * 2];
                for (int i = 0; (i < stringLength) && io.hasMore(16); i++) {
                    final short curShort = io.readShort(16);
                    if (i < totalStringLength) {
                        byteArray[i * 2] = (byte) (curShort >>> 8);
                        byteArray[(i * 2) + 1] = (byte) (curShort & 0xFF);
                    } else {
                        // Gobble up the remaining data, which is not added to the string.
                        i++;
                        for (; (i < stringLength) && io.hasMore(16); i++) {
                            io.readShort(16);
                        }
                        break;
                    }
                }
                return new String(byteArray, StandardCharsets.UTF_16BE);
            } else {
                throw new PlcRuntimeException("Unsupported string encoding " + encoding);
            }
        } catch (ParseException e) {
            throw new PlcRuntimeException("Error parsing string", e);
        }
    }
Symbol       Meaning
======       =======

@param alarm     Alarm type from PLC.
@param alarmText The text string to be processed.
@param textlists List of texts for indexed replacement.
@return The text string with the replacement values.
@ Beginning of format string
Pv           Process value number (optional)
Typ          Type of process value (optional)
% width      Width of the signaling field on the OP
.precision   Number of decimal places (optional with format = "f")
format       Process value representation mode
@ End of format string
<p>
Type		Meaning
====             =======
B		BOOL
Y		BYTE
C		CHARACTER
W		WORD
I		INTEGER
X		DWORD
D		DINT
R		REAL
<p>
Representation       Format
==============       ======
%[i]d                Decimal signed
%[i]u                Decimal without sign
%[i]x                Hexadecimal
%[i].[y]f            Signed fixed point
%[i]b                Binary
%[i]s                Character string (STRING ANSI)
%t#<Library name>    Access to text library
<p>
General representation:
@@&gt;Associated Value>&gt;Type>&gt;Format>&gt;Library name>@
plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java