using System;
namespace PKHeX.Core;
///
/// Utility logic for dealing with bitflags in a byte array.
///
public static class FlagUtil
{
///
/// Gets the requested from the byte at .
///
/// Buffer to read
/// Offset of the byte
/// Bit to read
public static bool GetFlag(ReadOnlySpan arr, int offset, int bitIndex)
{
bitIndex &= 7; // ensure the bit access is 0-7
return ((arr[offset] >> bitIndex) & 1) != 0;
}
public static bool GetFlag(ReadOnlySpan arr, int index) => GetFlag(arr, index >> 3, index);
///
/// Sets the requested value to the byte at .
///
/// Buffer to modify
/// Offset of the byte
/// Bit to write
/// Bit flag value to set
public static void SetFlag(Span arr, int offset, int bitIndex, bool value)
{
bitIndex &= 7; // ensure the bit access is 0-7
var current = arr[offset] & ~(1 << bitIndex);
var newValue = current | ((value ? 1 : 0) << bitIndex);
arr[offset] = (byte)newValue;
}
public static void SetFlag(Span arr, int index, bool value) => SetFlag(arr, index >> 3, index, value);
public static bool[] GetBitFlagArray(ReadOnlySpan data, int count)
{
var result = new bool[count];
GetBitFlagArray(data, result);
return result;
}
public static void GetBitFlagArray(ReadOnlySpan data, Span result)
{
for (int i = 0; i < result.Length; i++)
result[i] = (data[i >> 3] & (1 << (i & 7))) != 0;
}
public static bool[] GetBitFlagArray(ReadOnlySpan data) => GetBitFlagArray(data, data.Length << 3);
public static void SetBitFlagArray(Span data, ReadOnlySpan value)
{
for (int i = 0; i < value.Length; i++)
{
var ofs = i >> 3;
var mask = (1 << (i & 7));
if (value[i])
data[ofs] |= (byte)mask;
else
data[ofs] &= (byte)~mask;
}
}
}