using System; namespace SharpModbus { public static class ModbusUtils { public static ushort CRC16(byte[] bytes, int offset, int count) { ushort crc = 0xFFFF; for (int pos = 0; pos < count; pos++) { crc ^= (ushort)bytes[pos + offset]; for (int i = 8; i > 0; i--) { if ((crc & 0x0001) != 0) { crc >>= 1; crc ^= 0xA001; } else crc >>= 1; } } return crc; } public static byte EncodeBool(bool value) { return (byte)(value ? 0xFF : 0x00); } public static bool DecodeBool(byte value) { return (value != 0x00); } public static byte[] EncodeBools(bool[] bools) { var count = BytesForBools(bools.Length); var bytes = new byte[count]; for (var i = 0; i < count; i++) { bytes[i] = 0; } for (var i = 0; i < bools.Length; i++) { var v = bools[i]; if (v) { var bi = i / 8; bytes[bi] |= (byte)(1 << (i % 8)); } } return bytes; } public static byte[] EncodeWords(ushort[] words) { var count = 2 * words.Length; var bytes = new byte[count]; for (var i = 0; i < count; i++) { bytes[i] = 0; } for (var i = 0; i < words.Length; i++) { bytes[2 * i + 0] = (byte)((words[i] >> 8) & 0xff); bytes[2 * i + 1] = (byte)((words[i] >> 0) & 0xff); } return bytes; } public static bool[] DecodeBools(byte[] packet, int offset, ushort count) { var bools = new bool[count]; var bytes = BytesForBools(count); for (var i = 0; i < bytes; i++) { var bits = count >= 8 ? 8 : count % 8; var b = packet[offset + i]; ByteToBools(b, bools, bools.Length - count, bits); count -= (ushort)bits; } return bools; } public static ushort[] DecodeWords(byte[] packet, int offset, ushort count) { var results = new ushort[count]; for (int i = 0; i < count; i++) { results[i] = (ushort)(packet[offset + 2 * i] << 8 | packet[offset + 2 * i + 1]); } return results; } private static void ByteToBools(byte b, bool[] bools, int offset, int count) { for (int i = 0; i < count; i++) bools[offset + i] = ((b >> i) & 0x01) == 1; } public static byte BytesForWords(int count) { return (byte)(2 * count); } public static byte BytesForBools(int count) { return (byte)(count == 0 ? 0 : (count - 1) / 8 + 1); } public static byte High(int value) { return (byte)((value >> 8) & 0xff); } public static byte Low(int value) { return (byte)((value >> 0) & 0xff); } public static ushort GetUShort(byte bh, byte bl) { return (ushort)( ((bh << 8) & 0xFF00) | (bl & 0xff) ); } public static ushort GetUShort(byte[] bytes, int offset) { return (ushort)( ((bytes[offset + 0] << 8) & 0xFF00) | (bytes[offset + 1] & 0xff) ); } public static ushort GetUShortLittleEndian(byte[] bytes, int offset) { return (ushort)( ((bytes[offset + 1] << 8) & 0xFF00) | (bytes[offset + 0] & 0xff) ); } public static void Copy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int count) { for (var i = 0; i < count; i++) dst[dstOffset + i] = src[srcOffset + i]; } public static bool[] Clone(bool[] values) { var clone = new bool[values.Length]; for (var i = 0; i < values.Length; i++) clone[i] = values[i]; return clone; } public static ushort[] Clone(ushort[] values) { var clone = new ushort[values.Length]; for (var i = 0; i < values.Length; i++) clone[i] = values[i]; return clone; } } }