123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- using System;
- using System.Collections.Generic;
- using S7.Net.Types;
- namespace S7.Net.Protocol
- {
- internal static class Serialization
- {
- public static ushort GetWordAt(IList<byte> buf, int index)
- {
- return (ushort)((buf[index] << 8) + buf[index]);
- }
- public static byte[] SerializeDataItem(DataItem dataItem)
- {
- if (dataItem.Value == null)
- {
- throw new Exception($"DataItem.Value is null, cannot serialize. StartAddr={dataItem.StartByteAdr} VarType={dataItem.VarType}");
- }
- if (dataItem.Value is string s)
- return dataItem.VarType switch
- {
- VarType.S7String => S7String.ToByteArray(s, dataItem.Count),
- VarType.S7WString => S7WString.ToByteArray(s, dataItem.Count),
- _ => Types.String.ToByteArray(s, dataItem.Count)
- };
- if (dataItem.VarType == VarType.Date)
- {
- return Date.ToByteArray((System.DateTime)dataItem.Value);
- }
- return SerializeValue(dataItem.Value);
- }
- public static byte[] SerializeValue(object value)
- {
- switch (value.GetType().Name)
- {
- case "Boolean":
- return new[] { (byte)((bool)value ? 1 : 0) };
- case "Byte":
- return Types.Byte.ToByteArray((byte)value);
- case "Int16":
- return Types.Int.ToByteArray((Int16)value);
- case "UInt16":
- return Types.Word.ToByteArray((UInt16)value);
- case "Int32":
- return Types.DInt.ToByteArray((Int32)value);
- case "UInt32":
- return Types.DWord.ToByteArray((UInt32)value);
- case "Single":
- return Types.Real.ToByteArray((float)value);
- case "Double":
- return Types.LReal.ToByteArray((double)value);
- case "DateTime":
- return Types.DateTime.ToByteArray((System.DateTime)value);
- case "Byte[]":
- return (byte[])value;
- case "Int16[]":
- return Types.Int.ToByteArray((Int16[])value);
- case "UInt16[]":
- return Types.Word.ToByteArray((UInt16[])value);
- case "Int32[]":
- return Types.DInt.ToByteArray((Int32[])value);
- case "UInt32[]":
- return Types.DWord.ToByteArray((UInt32[])value);
- case "Single[]":
- return Types.Real.ToByteArray((float[])value);
- case "Double[]":
- return Types.LReal.ToByteArray((double[])value);
- case "String":
- // Hack: This is backwards compatible with the old code, but functionally it's broken
- // if the consumer does not pay attention to string length.
- var stringVal = (string)value;
- return Types.String.ToByteArray(stringVal, stringVal.Length);
- case "DateTime[]":
- return Types.DateTime.ToByteArray((System.DateTime[])value);
- case "DateTimeLong[]":
- return Types.DateTimeLong.ToByteArray((System.DateTime[])value);
- default:
- throw new InvalidVariableTypeException();
- }
- }
- public static void SetAddressAt(ByteArray buffer, int index, int startByte, byte bitNumber)
- {
- var start = startByte * 8 + bitNumber;
- buffer[index + 2] = (byte)start;
- start >>= 8;
- buffer[index + 1] = (byte)start;
- start >>= 8;
- buffer[index] = (byte)start;
- }
- public static void SetWordAt(ByteArray buffer, int index, ushort value)
- {
- buffer[index] = (byte)(value >> 8);
- buffer[index + 1] = (byte)value;
- }
- }
- }
|