using System; using System.Collections; namespace DTS.Serialization.IRIGCH10.Utils { /// /// helper class for getting BCD values as defined in chapter 10 for things like dates, /// also contains 16/32 bit checksum functions /// public abstract class Utils { public static byte[] GetBCDBytes(int value) { if (value < 0 || value > 9999) { throw new ArgumentOutOfRangeException("value must be between 0, 9999"); } var bcd = 0; for (var digit = 0; digit < 4; ++digit) { var nibble = value % 10; bcd |= nibble << (digit * 4); value /= 10; } return new byte[] { (byte)(bcd & 0xff), (byte)((bcd >> 8) & 0xff) }; } public static ushort GetCheckSum8(byte[] bytes) { ushort crc = 0; foreach (var v in bytes) { crc += v; } return crc; } /// /// computes a 16 bit checksum per ch10 /// /// /// public static ushort GetCheckSum16(byte[] bytes) { //we might want to pad with a 0 byte or drop a byte if odd number of bytes? //currently we only use this for packet headers, which are always of a set length, this //is just here for sanity System.Diagnostics.Trace.Assert(0 == bytes.Length % 2, "requires even length incoming data"); ushort crc = 0; var uints = new ushort[bytes.Length / 2]; Buffer.BlockCopy(bytes, 0, uints, 0, bytes.Length); for (var i = 0; i < uints.Length; i++) { crc += uints[i]; } return crc; } /// /// computes a 32 bit checksum per ch 10, /// we use this currently for data packet checksums /// /// /// public static uint GetCheckSum32(byte[] bytes) { //most packets should be filled in after the data portion with filler bytes to have //a length divisible by 4, this is just a sanity check System.Diagnostics.Trace.Assert(0 == bytes.Length % 4); uint crc = 0; var uints = new uint[bytes.Length / 4]; Buffer.BlockCopy(bytes, 0, uints, 0, bytes.Length); for (var i = 0; i < uints.Length; i++) { crc += uints[i]; } return crc; } /// /// returns an int given a bitarray and the starting and stopping point for bits of interest /// This allows you to return an int from 1-4 bytes /// /// /// /// /// public static int BitArrayToInt32(BitArray ba, int startIndex, int endIndex) { var n = 0; var bit = 0; for (var i = startIndex; i <= endIndex; i++) { if (ba.Get(i)) { n |= 1 << bit; } bit++; } return n; } public static void SetBits(BitArray b, uint value, int startIndex, int endIndex) { var ba = new BitArray(BitConverter.GetBytes(value)); var bit = 0; for (var i = startIndex; i <= endIndex; i++) { b.Set(i, ba.Get(bit)); bit++; } } } }