You are viewing our Forum Archives. To view or take place in current topics click here.
C# BitCollection
Posted:

C# BitCollectionPosted:

Experiment5X
  • TTG Senior
Status: Offline
Joined: Aug 14, 200915Year Member
Posts: 1,291
Reputation Power: 65
Status: Offline
Joined: Aug 14, 200915Year Member
Posts: 1,291
Reputation Power: 65
I made this because in a lot of the modding programs I have been making recently, I needed to handle bits, and I noticed that the BitArray class by Microsoft sucks, so I decided to make this one. I haven't tested it much so there may be some bugs. I am actually really proud of it because it's the first time I have ever needed to use an Indexer, and I used interafaces, with help from google, lol.

Edit: Fixed some bugs, and added implicit conversions.

Code:

//Created by Experiment5X, with ALOT of help from Google.
using System;
using System.Collections.Generic;
using System.Text;

namespace System.Collections.Bits
{
    /// <summary>
    /// Collection of bits. False = 0, True = 1.
    /// </summary>
    class BitCollection : IEnumerable, IEnumerator
    {
        bool[] bits;
        int position = 0;

        /// <summary>
        /// The Collection of bits in the bit Collection. Where False = 0, and True = 1.
        /// </summary>
        /// <param name="index">The index of the bit to access</param>
        /// <returns>A b0o0o0o0o0o0o0lean</returns>
        public bool this[int index]
        {
            get { return bits[index]; }
            set { bits[index] = value; }
        }

        //Thanks to http://support.microsoft.com/kb/322022
        #region Interafce Crap
        /// <summary>Returns a bool indicating whether the next postion exists.</summary>
        public bool MoveNext()
        {
            position++;
            return (position < bits.Length);
        }
        /// <summary>
        /// Resets the postion to zero.
        /// </summary>
        public void Reset()
        { position = 0; }
        /// <summary>
        /// Returns the System.Object at the current position.
        /// </summary>
        public object Current
        {
            get { return bits[position]; }
        }
        /// <summary>
        /// Returns an enumerator that iterates through the System.Collection.Bits.BitCollection.
        /// </summary>
        public IEnumerator GetEnumerator()
        {
            return (IEnumerator)this;
        }
        #endregion

        #region Constructors
        /// <summary>
        /// Create a new collection of Bits
        /// </summary>
        /// <param name="length">Length, in bits, of the new collection</param>
        /// <param name="defaultValue">Default value of the bits</param>
        public BitCollection(int length, bool defaultValue)
        {
            bits = new bool[length];
            if (defaultValue)
                for (int i = 0; i < bits.Length; i++)
                    bits[i] = true;
            Fix();
        }
        /// <summary>
        /// Create a new collection of bits
        /// </summary>
        /// <param name="toUse">Byte that will be stored in the Bit Collection</param>
        public BitCollection(byte toUse)
        {
            char[] _bits = Convert.ToString(toUse, 2).ToCharArray();
            bits = GetBits(_bits);
            Fix();
            Reverse();
        }
        /// <summary>
        /// Create a new collection of bits
        /// </summary>
        /// <param name="toUse">Signed Int16 that will be stored in the Bit Collection</param>
        public BitCollection(short toUse)
        {
            char[] _bits = Convert.ToString(toUse, 2).ToCharArray();
            bits = GetBits(_bits);
            Fix();
            Reverse();
        }
        /// <summary>
        /// Create a new collection of bits
        /// </summary>
        /// <param name="toUse">Unsigned Int16 that will be stored in the Bit Collection</param>
        public BitCollection(ushort toUse)
        {
            char[] _bits = Convert.ToString(toUse, 2).ToCharArray();
            bits = GetBits(_bits);
            Fix();
            Reverse();
        }
        /// <summary>
        /// Create a new collection of bits
        /// </summary>
        /// <param name="toUse">Signed Int32 that will be stored in the Bit Collection</param>
        public BitCollection(int toUse)
        {
            char[] _bits = Convert.ToString(toUse, 2).ToCharArray();
            bits = GetBits(_bits);
            Fix();
            Reverse();
        }
        /// <summary>
        /// Create a new collection of bits
        /// </summary>
        /// <param name="toUse">Unsigned Int32 that will be stored in the Bit Collection</param>
        public BitCollection(uint toUse)
        {
            char[] _bits = Convert.ToString(toUse, 2).ToCharArray();
            bits = GetBits(_bits);
            Fix();
            Reverse();
        }
        /// <summary>
        /// Create a new collection of bits
        /// </summary>
        /// <param name="toUse">Signed Int64 that will be stored in the Bit Collection</param>
        public BitCollection(long toUse)
        {
            char[] _bits = Convert.ToString(toUse, 2).ToCharArray();
            bits = GetBits(_bits);
            Fix();
            Reverse();
        }
        /// <summary>
        /// Create a new collection of bits
        /// </summary>
        /// <param name="toUse">Unsigned Int64 that will be stored in the Bit Collection</param>
        public BitCollection(ulong toUse)
        {
            char[] _bits = UlongToString(toUse).ToCharArray();
            Array.Reverse(_bits);
            bits = GetBits(_bits);
            Fix();
            Reverse();
        }
        #endregion

        /// <summary>
        /// The amount of elements in the Bit Collection
        /// </summary>
        public int Length
        {
            get { return bits.Length; }
        }

        /// <summary>
        /// Reverse the order of the Bit Collection
        /// </summary>
        public void Reverse()
        {
            Array.Reverse(bits);
        }

        #region Conversions
        /// <summary>
        /// Convert the bits into a byte array that is equal to the bits
        /// </summary>
        /// <returns>A byte array, silly.</returns>
        public byte[] ToByteArray()
        {
            Fix();
            return PrivateToByteArray();
        }

        /// <summary>
        /// Convert the bits into a byte that is equal to the bits
        /// </summary>
        /// <returns>A byte</returns>
        public byte ToByte()
        {
            Fix();
            if (bits.Length > 8) throw new OverflowException();
            byte[] _bits = PrivateToByteArray();
            return _bits[0];
        }

        /// <summary>
        /// Convert the bits into a signed Int16 that is equal to the bits
        /// </summary>
        /// <returns>A short</returns>
        public short ToInt16()
        {
            Fix();
            if (bits.Length > 16) throw new OverflowException();
            return BitConverter.ToInt16(PrivateToByteArray(), 0);
        }

        /// <summary>
        /// Convert the bits into a unsigned Int16 that is equal to the bits
        /// </summary>
        /// <returns>A ushort</returns>
        public ushort ToUInt16()
        {
            Fix();
            if (bits.Length > 16) throw new OverflowException();
            return BitConverter.ToUInt16(PrivateToByteArray(), 0);
        }

        /// <summary>
        /// Convert the bits into a signed Int32 that is equal to the bits
        /// </summary>
        /// <returns>An int</returns>
        public int ToInt32()
        {
            Fix();
            if (bits.Length > 32) throw new OverflowException();
            return BitConverter.ToInt32(PrivateToByteArray(), 0);
        }

        /// <summary>
        /// Convert the bits into a unsigned Int32 that is equal to the bits
        /// </summary>
        /// <returns>A uint</returns>
        public uint ToUInt32()
        {
            Fix();
            if (bits.Length > 32) throw new OverflowException();
            return BitConverter.ToUInt32(PrivateToByteArray(), 0);
        }

        /// <summary>
        /// Convert the bits into a signed Int64 that is equal to the bits
        /// </summary>
        /// <returns>A long</returns>
        public long ToInt64()
        {
            Fix();
            if (bits.Length > 64) throw new OverflowException();
            return BitConverter.ToInt64(PrivateToByteArray(), 0);
        }

        /// <summary>
        /// Convert the bits into a unsigned Int64 that is equal to the bits
        /// </summary>
        /// <returns>A ulong</returns>
        public ulong ToUInt64()
        {
            Fix();
            if (bits.Length > 64) throw new OverflowException();
            return BitConverter.ToUInt64(PrivateToByteArray(), 0);
        }
        /// <summary>
        /// Convert the bit collection into a string consisting of ones and zeros.
        /// </summary>
        /// <returns>A string...</returns>
        public override string ToString()
        {
            Fix();
            char[] chars = new char[bits.Length];
            ulong i = 0;
            foreach (bool b in bits)
            {
                chars[i] = (b) ? '1' : '0';
                i++;
            }
            Array.Reverse(chars);
            string toReturn = "";
            foreach (char c in chars)
                toReturn += c.ToString();
            return toReturn;
        }
        #endregion

        #region Operators
        public static implicit operator BitCollection(byte toUse)
        {
            return new BitCollection(toUse);
        }
        public static implicit operator BitCollection(short toUse)
        {
            return new BitCollection(toUse);
        }
        public static implicit operator BitCollection(ushort toUse)
        {
            return new BitCollection(toUse);
        }
        public static implicit operator BitCollection(int toUse)
        {
            return new BitCollection(toUse);
        }
        public static implicit operator BitCollection(uint toUse)
        {
            return new BitCollection(toUse);
        }
        public static implicit operator BitCollection(long toUse)
        {
            return new BitCollection(toUse);
        }
        public static implicit operator BitCollection(ulong toUse)
        {
            return new BitCollection(toUse);
        }
        #endregion

        //For private use
        void Fix()
        {
            List<bool> _bits = new List<bool>();
            _bits.AddRange(bits);
            _bits.Reverse();
            if (bits.Length < 8)
                while (_bits.Count < 8)
                    _bits.Add(false);
            else if (bits.Length < 16)
                while (_bits.Count < 16)
                    _bits.Add(false);
            else if (bits.Length < 32)
                while (_bits.Count < 32)
                    _bits.Add(false);
            else if (bits.Length < 64)
                while (_bits.Count < 64)
                    _bits.Add(false);
            bits = _bits.ToArray();

        }

        //From http://geekswithblogs.net/dbrown/archive/2009/04/05/convert-a-bitarray-to-byte-in-c.aspx
        byte[] PrivateToByteArray()
        {
            int numBytes = bits.Length / 8;
            if (bits.Length % 8 != 0) numBytes++;
            byte[] bytes = new byte[numBytes];
            int byteIndex = 0, bitIndex = 0;
            for (int i = 0; i < bits.Length; i++)
            {
                if (bits[i])
                    bytes[byteIndex] |= (byte)(1 << (7 - bitIndex));
                bitIndex++;
                if (bitIndex == 8)
                {
                    bitIndex = 0;
                    byteIndex++;
                }
            }
            return bytes;
        }

        //For private use
        bool[] GetBits(char[] bitsAsChars)
        {
            Array.Reverse(bitsAsChars);
            List<bool> _bits = new List<bool>();
            foreach (char c in bitsAsChars)
                _bits.Add((c == '1') ? true : false);
            return _bits.ToArray();
        }

        //From http://www.codeproject.com/Messages/2633854/Convert-ulong-to-binary-i-e-ulong-ToBinaryString.aspx
        string UlongToString(ulong value)
        {
            int ulongsize = sizeof(ulong) * 8;
            StringBuilder ret = new StringBuilder(ulongsize);
            for (int i = 0; i < ulongsize; i++)
            {
                ret.Insert(0, value & 0x1);
                value >>= 1;
            }
            return ret.ToString();
        }
    }
}



[ Register or Signin to view external links. ]
[ Register or Signin to view external links. ]
[ Register or Signin to view external links. ]
Jump to:
You are viewing our Forum Archives. To view or take place in current topics click here.