namespace Syroot.Worms.Core
{
///
/// Represents extension methods for instances.
///
internal static class ByteExtensions
{
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
///
/// Returns the current byte with the bit at the set (being 1).
///
/// The extended instance.
/// The 0-based index of the bit to enable.
/// The current byte with the bit enabled.
internal static byte EnableBit(this byte self, int index)
{
return (byte)(self | (1 << index));
}
///
/// Returns the current byte with the bit at the cleared (being 0).
///
/// The extended instance.
/// The 0-based index of the bit to disable.
/// The current byte with the bit disabled.
internal static byte DisableBit(this byte self, int index)
{
return (byte)(self & ~(1 << index));
}
///
/// Returns a value indicating whether the bit at the in the current byte is enabled
/// or disabled.
///
/// The extended instance.
/// The 0-based index of the bit to check.
/// true when the bit is set; otherwise false.
internal static bool GetBit(this byte self, int index)
{
return (self & (1 << index)) != 0;
}
///
/// Returns the current byte with all bits rotated in the given , where positive
/// directions rotate left and negative directions rotate right.
///
/// The extended instance.
/// The direction in which to rotate, where positive directions rotate left.
/// The current byte with the bits rotated.
internal static byte RotateBits(this byte self, int direction)
{
int bits = sizeof(byte) * 8;
if (direction > 0)
{
return (byte)((self << direction) | (self >> (bits - direction)));
}
else if (direction < 0)
{
direction = -direction;
return (byte)((self >> direction) | (self << (bits - direction)));
}
return self;
}
///
/// Returns the current byte with the bit at the enabled or disabled, according to
/// .
///
/// The extended instance.
/// The 0-based index of the bit to enable or disable.
/// true to enable the bit; otherwise false.
/// The current byte with the bit enabled or disabled.
internal static byte SetBit(this byte self, int index, bool enable)
{
if (enable)
{
return EnableBit(self, index);
}
else
{
return DisableBit(self, index);
}
}
///
/// Returns the current byte with the bit at the enabled when it is disabled or
/// disabled when it is enabled.
///
/// The extended instance.
/// The 0-based index of the bit to toggle.
/// The current byte with the bit toggled.
internal static byte ToggleBit(this byte self, int index)
{
if (GetBit(self, index))
{
return DisableBit(self, index);
}
else
{
return EnableBit(self, index);
}
}
///
/// Returns an instance represented by the given number of .
///
/// The extended instance.
/// The number of least significant bits which are used to store the
/// value.
/// The decoded .
internal static byte DecodeByte(this byte self, int bits)
{
return DecodeByte(self, bits, 0);
}
///
/// Returns an instance represented by the given number of , starting
/// at the .
///
/// The extended instance.
/// The number of least significant bits which are used to store the
/// value.
/// The first bit of the encoded value.
/// The decoded .
internal static byte DecodeByte(this byte self, int bits, int firstBit)
{
// Shift to the first bit and keep only the required bits.
return (byte)((self >> firstBit) & ((1 << bits) - 1));
}
///
/// Returns an instance represented by the given number of .
///
/// The extended instance.
/// The number of least significant bits which are used to store the
/// value.
/// The decoded .
internal static sbyte DecodeSByte(this byte self, int bits)
{
return DecodeSByte(self, bits, 0);
}
///
/// Returns an instance represented by the given number of , starting
/// at the .
///
/// The extended instance.
/// The number of least significant bits which are used to store the
/// value.
/// The first bit of the encoded value.
/// The decoded .
internal static sbyte DecodeSByte(this byte self, int bits, int firstBit)
{
self >>= firstBit;
int absMask = 1 << bits;
byte abs = (byte)(self & (absMask - 1));
if (abs.GetBit(bits - 1))
{
return (sbyte)(abs - absMask);
}
else
{
return (sbyte)abs;
}
}
///
/// Returns the current byte with the given set into the given number of
/// .
///
/// The extended instance.
/// The number of bits which are used to store the value.
/// The current byte with the value encoded into it.
internal static byte Encode(this byte self, byte value, int bits)
{
return Encode(self, value, bits, 0);
}
///
/// Returns the current byte with the given set into the given number of
/// starting at .
///
/// The extended instance.
/// The number of bits which are used to store the value.
/// The first bit used for the encoded value.
/// The current byte with the value encoded into it.
internal static byte Encode(this byte self, byte value, int bits, int firstBit)
{
// Clear the bits required for the value and fit it into them by truncating.
int mask = ((1 << bits) - 1) << firstBit;
self &= (byte)~mask;
value = (byte)((value << firstBit) & mask);
// Set the value.
return (byte)(self | value);
}
///
/// Returns the current byte with the given set into the given number of
/// .
///
/// The extended instance.
/// The number of bits which are used to store the value.
/// The current byte with the value encoded into it.
internal static byte Encode(this byte self, sbyte value, int bits)
{
return Encode(self, value, bits, 0);
}
///
/// Returns the current byte with the given set into the given number of
/// starting at .
///
/// The extended instance.
/// The number of bits which are used to store the value.
/// The first bit used for the encoded value.
/// The current byte with the value encoded into it.
internal static byte Encode(this byte self, sbyte value, int bits, int firstBit)
{
// Set the value as a normal byte, but then fix the sign.
self = Encode(self, (byte)value, bits, firstBit);
return self.SetBit(bits + firstBit - 1, value < 0);
}
}
}