namespace Universal;

public class UnionHelper
{
    public static void GetByteUnion(byte input, out bool[] bits)
    {
        bits = new bool[8];

        for (int i = 0; i < 8; i++)
            bits[i] = Convert.ToBoolean((input >> i) & 0b01);
    }

    public static void GetByteUnion(byte input, out byte[] bits)
    {
        bits = new byte[8];

        for (int i = 0; i < 8; i++)
            bits[i] = (byte)((input >> i) & 0b01);
    }
}

public class StructHelper
{
    public static byte[] StructToBytes<T>(T structObj) where T : struct
    {
        int size = Marshal.SizeOf(structObj);
        IntPtr buffer = Marshal.AllocHGlobal(size);
        try
        {
            Marshal.StructureToPtr(structObj, buffer, false);
            byte[] bytes = new byte[size];
            Marshal.Copy(buffer, bytes, 0, size);
            return bytes;
        }
        finally
        {
            Marshal.FreeHGlobal(buffer);
        }
    }

    public static T BytesToStruct<T>(byte[] bytes) where T : struct
    {
        int size = Marshal.SizeOf<T>();
        IntPtr buffer = Marshal.AllocHGlobal(size);
        try
        {
            Marshal.Copy(bytes, 0, buffer, size);
            return Marshal.PtrToStructure<T>(buffer);
        }
        finally
        {
            Marshal.FreeHGlobal(buffer);
        }
    }

    public static byte[] Ushorts2Bytes(ushort[] src, bool reverse = false)
    {

        int count = src.Length;
        byte[] dest = new byte[count << 1];
        if (reverse)
        {
            for (int i = 0; i < count; i++)
            {
                dest[i * 2] = (byte)(src[i] >> 8);
                dest[i * 2 + 1] = (byte)(src[i] >> 0);
            }
        }
        else
        {
            for (int i = 0; i < count; i++)
            {
                dest[i * 2] = (byte)(src[i] >> 0);
                dest[i * 2 + 1] = (byte)(src[i] >> 8);
            }
        }
        return dest;
    }
    public static ushort[] Bytes2Ushorts(byte[] src, bool reverse = false)
    {
        int len = src.Length;

        byte[] srcPlus = new byte[len + 1];
        src.CopyTo(srcPlus, 0);
        int count = len >> 1;

        if (len % 2 != 0)
        {
            count += 1;
        }

        ushort[] dest = new ushort[count];
        if (reverse)
        {
            for (int i = 0; i < count; i++)
            {
                dest[i] = (ushort)(srcPlus[i * 2] << 8 | srcPlus[2 * i + 1] & 0xff);
            }
        }
        else
        {
            for (int i = 0; i < count; i++)
            {
                dest[i] = (ushort)(srcPlus[i * 2] & 0xff | srcPlus[2 * i + 1] << 8);
            }
        }

        return dest;
    }

}