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); } } }