Files

114 lines
3.9 KiB
C#
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
using System;
using System.Collections;
namespace DTS.Serialization.IRIGCH10.Utils
{
/// <summary>
/// helper class for getting BCD values as defined in chapter 10 for things like dates,
/// also contains 16/32 bit checksum functions
/// </summary>
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;
}
/// <summary>
/// computes a 16 bit checksum per ch10
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
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;
}
/// <summary>
/// computes a 32 bit checksum per ch 10,
/// we use this currently for data packet checksums
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 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
/// </summary>
/// <param name="ba"></param>
/// <param name="startIndex"></param>
/// <param name="endIndex"></param>
/// <returns></returns>
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++;
}
}
}
}