//***************************************************************************** // Copyright � 2005, Bill Koukoutsis // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // Neither the name of the ORGANIZATION nor the names of its contributors may // be used to endorse or promote products derived from this software without // specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. //***************************************************************************** using System; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; using System.Globalization; using System.Net.Sockets; using System.Security.Cryptography; #pragma warning disable CS3021 // Type or member does not need a CLSCompliant attribute because the assembly does not have a CLSCompliant attribute namespace Vision.Core.Utils { /// /// Creates a stream for reading and writing variable-length data. /// /// /// Notes to Callers: Make sure to /// include the "BitStream.resx" resource file in projects using the /// class.

///

/// [20051201]: Fixed problem with public virtual void Write(ulong bits, int bitIndex, int count) /// and public virtual int Read(out ulong bits, int bitIndex, int count) methods.

///

/// [20051127]: Added public virtual void WriteTo(Stream bits); to write /// the contents of the current bit stream to another stream.

///

/// [20051125]: Added the following implicit operators to allow type casting /// instances of the class to and from other types /// of objects:

///

/// public static implicit operator BitStream(MemoryStream bits);

/// public static implicit operator MemoryStream(BitStream bits);

/// public static implicit operator BitStream(FileStream bits);

/// public static implicit operator BitStream(BufferedStream bits);

/// public static implicit operator BufferedStream(BitStream bits);

/// public static implicit operator BitStream(NetworkStream bits);

/// public static implicit operator BitStream(CryptoStream bits);

///

/// [20051124]: Added public virtual [] ToByteArray(); method.

///

/// [20051124]: The public override ReadByte(); and /// public override void WriteByte( value) method are now /// supported by the class.

///

/// [20051123]: Added public BitStream( bits); contructor.

///

///
/// /// /// /// [SuppressMessage("ReSharper", "UnusedMember.Global")] [SuppressMessage("ReSharper", "SuggestVarOrType_SimpleTypes")] [SuppressMessage("ReSharper", "IdentifierTypo")] [SuppressMessage("ReSharper", "SuggestVarOrType_Elsewhere")] [SuppressMessage("ReSharper", "SuggestVarOrType_BuiltInTypes")] [SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "CommentTypo")] [SuppressMessage("ReSharper", "VirtualMemberCallInConstructor")] [SuppressMessage("ReSharper", "RedundantAssignment")] public class BitStream : Stream { #region Constants [20051116] /// /// An value defining the number of bits /// in a value type. /// /// /// This field is constant. /// /// /// private const int SizeOfByte = 8; /// /// An value defining the number of bits /// in a value type. /// /// /// This field is constant. /// /// /// private const int SizeOfChar = 128; /// /// An value defining the number of bits /// in a value type. /// /// /// This field is constant. /// /// /// private const int SizeOfUInt16 = 16; /// /// An value defining the number of bits /// in a value type. /// /// /// This field is constant. /// /// /// private const int SizeOfUInt32 = 32; /// /// An value defining the number of bits /// in a value type. /// /// /// This field is constant. /// /// /// private const int SizeOfSingle = 32; /// /// An value defining the number of bits /// in a value type. /// /// /// This field is constant. /// /// /// private const int SizeOfUInt64 = 64; /// /// An value defining the number of bits /// in a value type. /// /// /// This field is constant. /// /// /// private const int SizeOfDouble = 64; /// /// An value defining the number of bits /// per element in the internal buffer. /// /// /// This field is constant. /// /// private const uint BitBuffer_SizeOfElement = SizeOfUInt32; /// /// An value defining the number of bit /// shifts equivalent to the number of bits per element in the /// internal buffer. /// /// /// This field is constant. /// /// private const int BitBuffer_SizeOfElement_Shift = 5; /// /// An value defining the equivalent of /// a divisor in bitwise AND operations emulating /// modulo calculations. /// /// /// This field is constant. /// /// private const uint BitBuffer_SizeOfElement_Mod = 31; /// /// An array defining a series of values /// useful in generating bit masks in read and write operations. /// /// /// This field is static. /// private static readonly uint [] BitMaskHelperLUT = { 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF, }; #endregion #region Fields [20051114] /// /// A value specifying whether the current /// stream is able to process data. /// /// /// This field is set to true by default. /// /// private bool _blnIsOpen = true; /// /// An array of values specifying the internal /// bit buffer for the current stream. /// /// /// . /// /// private uint [] _auiBitBuffer; /// /// An value specifying the current length of the /// internal bit buffer for the current stream. /// /// /// . /// /// private uint _uiBitBuffer_Length; /// /// An value specifying the current elemental index /// of the internal bit buffer for the current stream. /// /// /// . /// /// private uint _uiBitBuffer_Index; /// /// An value specifying the current bit index for the /// current element of the internal bit buffer for the current stream. /// /// /// . /// /// private uint _uiBitBuffer_BitIndex; /// /// An object specifying the format specifier /// for the current stream. /// /// /// This field is set to /// by default. /// /// /// private static readonly IFormatProvider _ifp = CultureInfo.InvariantCulture; #endregion #region Properties [20051116] /// /// Gets the length of this stream in bits. /// /// /// The current stream is closed. /// /// /// . /// /// /// An value specifying the length of this stream in /// bits. /// /// public override long Length { get { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); return _uiBitBuffer_Length; } } /// /// Gets the maximum number of 8-bit values required to store this /// stream. /// /// /// The current stream is closed. /// /// /// . /// /// /// /// /// // This property can be used in conjunction with the method

/// // to read the entire stream into a array.

///
/// :

/// BitStream bstrm = new BitStream();

/// :

/// :

/// byte [] abytBuffer = new byte [bstrm.Length8];

/// int iBitsRead = Read(abytBuffer, 0, (int)bstrm.Length8);

/// :

///
///
/// /// An value specifying the maximum number of /// 8-bit values required to store this stream. /// /// /// /// public virtual long Length8 { get { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); return (_uiBitBuffer_Length >> 3) + ((_uiBitBuffer_Length & 7) > 0 ? 1 : 0); } } /// /// Gets the maximum number of 16-bit values required to store this /// stream. /// /// /// The current stream is closed. /// /// /// . /// /// /// /// /// // This property can be used in conjunction with the method

/// // to read the entire stream into an array.

///
/// :

/// BitStream bstrm = new BitStream();

/// :

/// :

/// short [] asBuffer = new short [bstrm.Length16];

/// int iBitsRead = Read(asBuffer, 0, (int)bstrm.Length16);

/// :

///
///
/// /// An value specifying the maximum number of /// 16-bit values required to store this stream. /// /// /// /// public virtual long Length16 { get { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); return (_uiBitBuffer_Length >> 4) + ((_uiBitBuffer_Length & 15) > 0 ? 1 : 0); } } /// /// Gets the maximum number of 32-bit values required to store this /// stream. /// /// /// The current stream is closed. /// /// /// . /// /// /// /// /// // This property can be used in conjunction with the method

/// // to read the entire stream into an array.

///
/// :

/// BitStream bstrm = new BitStream();

/// :

/// :

/// int [] aiBuffer = new int [bstrm.Length32];

/// int iBitsRead = Read(aiBuffer, 0, (int)bstrm.Length32);

/// :

///
///
/// /// An value specifying the maximum number of /// 32-bit values required to store this stream. /// /// /// /// public virtual long Length32 { get { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); return (_uiBitBuffer_Length >> 5) + ((_uiBitBuffer_Length & 31) > 0 ? 1 : 0); } } /// /// Gets the maximum number of 64-bit values required to store this /// stream. /// /// /// The current stream is closed. /// /// /// . /// /// /// /// /// // This property can be used in conjunction with the method

/// // to read the entire stream into an array.

///
/// :

/// BitStream bstrm = new BitStream();

/// :

/// :

/// long [] alBuffer = new long [bstrm.Length64];

/// int iBitsRead = Read(alBuffer, 0, (int)bstrm.Length64);

/// :

///
///
/// /// An value specifying the maximum number of /// 64-bit values required to store this stream. /// /// /// public virtual long Length64 { get { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); return (_uiBitBuffer_Length >> 6) + ((_uiBitBuffer_Length & 63) > 0 ? 1 : 0); } } /// /// Gets the number of bits allocatated to this stream. /// /// /// The current stream is closed. /// /// /// . /// /// /// An value specifying the number of bits /// allocated to this stream. /// public virtual long Capacity { get { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); return ((long)_auiBitBuffer.Length) << BitBuffer_SizeOfElement_Shift; } } /// /// Gets or sets the current bit position within this stream. /// /// /// The current stream is closed. /// /// /// The position is set to a negative value or position + 1 is geater than /// . /// /// /// . /// /// /// An value specifying the current position /// within this stream. /// /// /// public override long Position { get { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); uint uiPosition = (_uiBitBuffer_Index << BitBuffer_SizeOfElement_Shift) + _uiBitBuffer_BitIndex; return uiPosition; } set { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(value < 0) throw new ArgumentOutOfRangeException(nameof(value), "Position must be greater than or equal to zero."); uint uiRequestedPosition = (uint)value; if(_uiBitBuffer_Length < uiRequestedPosition + 1) throw new ArgumentOutOfRangeException(nameof(value), "Position must be less than or equal to the Bit Stream Length - 1."); _uiBitBuffer_Index = uiRequestedPosition >> BitBuffer_SizeOfElement_Shift; if((uiRequestedPosition & BitBuffer_SizeOfElement_Mod) > 0) _uiBitBuffer_BitIndex = (uiRequestedPosition & BitBuffer_SizeOfElement_Mod); else _uiBitBuffer_BitIndex = 0; } } /// /// Gets a value indicating whether the current stream supports reading. /// /// /// . /// /// /// A value indicating whether the current stream /// supports reading. /// /// public override bool CanRead { get { return _blnIsOpen; } } /// /// Gets a value indicating whether the current stream supports seeking. /// /// /// This method always returns false. To set the position within /// the current stream use the property instead. /// /// /// A value indicating whether the current stream /// supports seeking. /// /// /// public override bool CanSeek { get { return false; } } /// /// Gets a value indicating whether the current stream supports writing. /// /// /// . /// /// /// A value indicating whether the current stream /// supports writing. /// /// public override bool CanWrite { get { return _blnIsOpen; } } /// /// Gets a value indicating whether the current stream supports setting /// its length. /// /// /// This field always returns false. All write operations at the /// end of the BitStream expand the BitStream automatically. /// /// /// A value indicating whether the current stream /// supports setting its length. /// /// public static bool CanSetLength { get { return false; } } /// /// Gets a value indicating whether the current stream supports the flush /// operation. /// /// /// This field always returns false. Since any data written to a /// BitStream is written into RAM, flush operations become /// redundant. /// /// /// A value indicating whether the current stream /// supports the flush operation. /// /// public static bool CanFlush { get { return false; } } #endregion #region ctors/dtors [20051123] /// /// Initialises a new instance of the class /// with an expandable capacity initialised to one. /// /// /// . /// /// public BitStream() { // Initialise the bit buffer with 1 UInt32 _auiBitBuffer = new uint[1]; } /// /// Initialises a new instance of the class /// with an expandable capacity initialised to the specified capacity in /// bits. /// /// /// capacity is negative or zero. /// /// /// . /// /// /// An specifying the initial size of the internal /// bit buffer in bits. /// /// public BitStream(long capacity) { if(capacity <= 0) throw new ArgumentOutOfRangeException(nameof(capacity), "Capacity must be greater than zero."); _auiBitBuffer = new uint[(capacity >> BitBuffer_SizeOfElement_Shift) + ((capacity & BitBuffer_SizeOfElement_Mod) > 0 ? 1 : 0)]; } /// /// Initialises a new instance of the class /// with the bits provided by the specified . /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// Added [20051122]. /// /// /// A object containing the specified bits. /// /// /// public BitStream(Stream bits) : this() { if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); // Write the stream to the internal buffer using a temporary byte buffer byte [] abytBits = new byte [bits.Length]; long lCurrentPos = bits.Position; bits.Position = 0; bits.Read(abytBits, 0, (int)bits.Length); bits.Position = lCurrentPos; Write(abytBits, 0, (int)bits.Length); } #endregion #region Methods [20051201] #region Write [20051201] #region Generic Writes [20051115] /// /// Writes the bits contained in an value to /// the current stream. /// /// /// The current stream is closed. /// /// /// bitIndex or count is negative. /// /// /// bitIndex subtracted from the number of bits in a /// is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// /// An value specifying the little-endian bit /// index to begin writing from. /// /// /// An value specifying the maximum number of /// bits to write. /// /// private void Write(ref uint bits, ref uint bitIndex, ref uint count) { // Calculate the current position uint uiBitBuffer_Position = (_uiBitBuffer_Index << BitBuffer_SizeOfElement_Shift) + _uiBitBuffer_BitIndex; // Detemine the last element in the bit buffer uint uiBitBuffer_LastElementIndex = (_uiBitBuffer_Length >> BitBuffer_SizeOfElement_Shift); // Clalculate this values end index uint uiValue_EndIndex = bitIndex + count; // Clear out unwanted bits in value int iValue_BitsToShift = (int)bitIndex; uint uiValue_BitMask = (BitMaskHelperLUT[count] << iValue_BitsToShift); bits &= uiValue_BitMask; // Position the bits in value uint uiBitBuffer_FreeBits = BitBuffer_SizeOfElement - _uiBitBuffer_BitIndex; iValue_BitsToShift = (int)(uiBitBuffer_FreeBits - uiValue_EndIndex); uint uiValue_Indexed;// = 0; if(iValue_BitsToShift < 0) uiValue_Indexed = bits >> Math.Abs(iValue_BitsToShift); else uiValue_Indexed = bits << iValue_BitsToShift; // Clear current bits in bit buffer that are at same indices // (only if overwriting) if(_uiBitBuffer_Length >= (uiBitBuffer_Position + 1)) { int iBitBuffer_BitsToShift = (int)(uiBitBuffer_FreeBits - count); uint uiBitBuffer_BitMask;// = 0; if(iBitBuffer_BitsToShift < 0) uiBitBuffer_BitMask = uint.MaxValue ^ (BitMaskHelperLUT[count] >> Math.Abs(iBitBuffer_BitsToShift)); else uiBitBuffer_BitMask = uint.MaxValue ^ (BitMaskHelperLUT[count] << iBitBuffer_BitsToShift); _auiBitBuffer[_uiBitBuffer_Index] &= uiBitBuffer_BitMask; // Is this the last element of the bit buffer? if(uiBitBuffer_LastElementIndex == _uiBitBuffer_Index) { uint uiBitBuffer_NewLength;// = 0; if(uiBitBuffer_FreeBits >= count) uiBitBuffer_NewLength = uiBitBuffer_Position + count; else uiBitBuffer_NewLength = uiBitBuffer_Position + uiBitBuffer_FreeBits; if(uiBitBuffer_NewLength > _uiBitBuffer_Length) { uint uiBitBuffer_ExtraBits = uiBitBuffer_NewLength - _uiBitBuffer_Length; UpdateLengthForWrite(uiBitBuffer_ExtraBits); } } } else // Not overwrinting any bits: _uiBitBuffer_Length < (uiBitBuffer_Position + 1) { UpdateLengthForWrite(uiBitBuffer_FreeBits >= count ? count : uiBitBuffer_FreeBits); } // Write value _auiBitBuffer[_uiBitBuffer_Index] |= uiValue_Indexed; if(uiBitBuffer_FreeBits >= count) UpdateIndicesForWrite(count); else // Some bits in value did not fit // in current bit buffer element { UpdateIndicesForWrite(uiBitBuffer_FreeBits); uint uiValue_RemainingBits = count - uiBitBuffer_FreeBits; uint uiValue_StartIndex = bitIndex; Write(ref bits, ref uiValue_StartIndex, ref uiValue_RemainingBits); } } #endregion #region 1-Bit Writes [20051116] /// /// Writes the bit represented by a value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// A value representing the bit to write data /// from. /// /// public virtual void Write(bool bit) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); // Convert the bool to UInt32 uint uiBit = (uint)(bit ? 1 : 0); uint uiBitIndex = 0; uint uiCount = 1; Write(ref uiBit, ref uiBitIndex, ref uiCount); } /// /// Writes the bits contained in a buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// A array specifying the buffer to write data from. /// /// public virtual void Write(bool [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); Write(bits, 0, bits.Length); } /// /// Writes the bits contained in a buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// A array specifying the buffer to write data from. /// /// /// An value specifying the /// offset to begin writing from. /// /// /// An value specifying the maximum number of /// values to write. /// /// /// public virtual void Write(bool [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; for(int iBitCounter = offset; iBitCounter < iEndIndex; iBitCounter++) Write(bits[iBitCounter]); } #endregion #region 8-Bit Writes [20051124] /// /// Writes the bits contained in a value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// A value specifying the bits to write data /// from. /// /// public virtual void Write(byte bits) { Write(bits, 0, SizeOfByte); } /// /// Writes the bits contained in a value to /// the current stream. /// /// /// The current stream is closed. /// /// /// bitIndex or count is negative. /// /// /// bitIndex subtracted from the number of bits in a /// is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// A value specifying the bits to write data /// from. /// /// /// An value specifying the little-endian bit /// index to begin writing from. /// /// /// An value specifying the maximum number of /// bits to write. /// /// /// public virtual void Write(byte bits, int bitIndex, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bitIndex < 0) throw new ArgumentOutOfRangeException(nameof(bitIndex), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (SizeOfByte - bitIndex)) throw new ArgumentException("count + bitIndex exceeds the length of the 8-bit value."); uint uiBits = bits; uint uiBitIndex = (uint)bitIndex; uint uiCount = (uint)count; Write(ref uiBits, ref uiBitIndex, ref uiCount); } /// /// Writes the bits contained in a buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// A array specifying the buffer to write data from. /// /// public virtual void Write(byte [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); Write(bits, 0, bits.Length); } /// /// Writes the bits contained in a buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// A array specifying the buffer to write data from. /// /// /// An value specifying the offset /// to begin writing from. /// /// /// An value specifying the maximum number of /// values to write. /// /// /// public override void Write(byte [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; for(int iByteCounter = offset; iByteCounter < iEndIndex; iByteCounter++) Write(bits[iByteCounter]); } /// /// Writes the bits contained in an value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// public virtual void Write(sbyte bits) { Write(bits, 0, SizeOfByte); } /// /// Writes the bits contained in an value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// /// An value specifying the little-endian bit /// index to begin writing from. /// /// /// An value specifying the maximum number of /// bits to write. /// /// /// public virtual void Write(sbyte bits, int bitIndex, int count) { // Convert the value to a byte byte bytBits = (byte)bits; Write(bytBits, bitIndex, count); } /// /// Writes the bits contained in an buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// A array specifying the buffer to write data from. /// /// public virtual void Write(sbyte [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); Write(bits, 0, bits.Length); } /// /// Writes the bits contained in an buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An array specifying the buffer to write data from. /// /// /// An value specifying the offset /// to begin writing from. /// /// /// An value specifying the maximum number of /// values to write. /// /// /// public virtual void Write(sbyte [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); byte [] abytBits = new byte [count]; Buffer.BlockCopy(bits, offset, abytBits, 0, count); Write(abytBits, 0, count); } /// /// Writes a byte to the current stream at the current position. /// /// /// All write operations at the end of the BitStream expand the /// BitStream.

///

/// Modified [20051124] ///
/// /// The byte to write. /// public override void WriteByte(byte value) { Write(value); } #endregion #region 16-Bit Writes [20051115] /// /// Writes the bits contained in a value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// public virtual void Write(char bits) { Write(bits, 0, SizeOfChar); } /// /// Writes the bits contained in a value to /// the current stream. /// /// /// The current stream is closed. /// /// /// bitIndex or count is negative. /// /// /// bitIndex subtracted from the number of bits in a /// is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// /// An value specifying the little-endian bit /// index to begin writing from. /// /// /// An value specifying the maximum number of /// bits to write. /// /// /// public virtual void Write(char bits, int bitIndex, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bitIndex < 0) throw new ArgumentOutOfRangeException(nameof(bitIndex), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (SizeOfChar - bitIndex)) throw new ArgumentException("count + offset were out of bounds for the BitStream or count is greater than the number of elements from bitIndex to the end of the BitStream."); uint uiBits = bits; uint uiBitIndex = (uint)bitIndex; uint uiCount = (uint)count; Write(ref uiBits, ref uiBitIndex, ref uiCount); } /// /// Writes the bits contained in a buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An array specifying the buffer to write data from. /// /// public virtual void Write(char [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); Write(bits, 0, bits.Length); } /// /// Writes the bits contained in a buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An array specifying the buffer to write data from. /// /// /// An value specifying the offset /// to begin writing from. /// /// /// An value specifying the maximum number of /// values to write. /// /// /// public virtual void Write(char [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; for(int iCharCounter = offset; iCharCounter < iEndIndex; iCharCounter++) Write(bits[iCharCounter]); } /// /// Writes the bits contained in an value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// public virtual void Write(ushort bits) { Write(bits, 0, SizeOfUInt16); } /// /// Writes the bits contained in an value to /// the current stream. /// /// /// The current stream is closed. /// /// /// bitIndex or count is negative. /// /// /// bitIndex subtracted from the number of bits in a /// is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// /// An value specifying the little-endian bit /// index to begin writing from. /// /// /// An value specifying the maximum number of /// bits to write. /// /// /// public virtual void Write(ushort bits, int bitIndex, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bitIndex < 0) throw new ArgumentOutOfRangeException(nameof(bitIndex), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (SizeOfUInt16 - bitIndex)) throw new ArgumentException("count + bitIndex exceeds the length of the 16-bit value."); uint uiBits = bits; uint uiBitIndex = (uint)bitIndex; uint uiCount = (uint)count; Write(ref uiBits, ref uiBitIndex, ref uiCount); } /// /// Writes the bits contained in an buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An array specifying the buffer to write data from. /// /// public virtual void Write(ushort [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); Write(bits, 0, bits.Length); } /// /// Writes the bits contained in an buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An array specifying the buffer to write data from. /// /// /// An value specifying the offset /// to begin writing from. /// /// /// An value specifying the maximum number of /// values to write. /// /// /// public virtual void Write(ushort [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; for(int iUInt16Counter = offset; iUInt16Counter < iEndIndex; iUInt16Counter++) Write(bits[iUInt16Counter]); } /// /// Writes the bits contained in an value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// public virtual void Write(short bits) { Write(bits, 0, SizeOfUInt16); } /// /// Writes the bits contained in an value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// /// An value specifying the little-endian bit /// index to begin writing from. /// /// /// An value specifying the maximum number of /// bits to write. /// /// /// public virtual void Write(short bits, int bitIndex, int count) { // Convert the value to an UInt16 ushort usBits = (ushort)bits; Write(usBits, bitIndex, count); } /// /// Writes the bits contained in an buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An array specifying the buffer to write data from. /// /// public virtual void Write(short [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); Write(bits, 0, bits.Length); } /// /// Writes the bits contained in an buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An array specifying the buffer to write data from. /// /// /// An value specifying the offset /// to begin writing from. /// /// /// An value specifying the maximum number of /// values to write. /// /// /// public virtual void Write(short [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); ushort [] ausBits = new ushort [count]; Buffer.BlockCopy(bits, offset << 1, ausBits, 0, count << 1); Write(ausBits, 0, count); } #endregion #region 32-Bit Writes [20051115] /// /// Writes the bits contained in an value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// [CLSCompliant(false)] public virtual void Write(uint bits) { Write(bits, 0, SizeOfUInt32); } /// /// Writes the bits contained in an value to /// the current stream. /// /// /// The current stream is closed. /// /// /// bitIndex or count is negative. /// /// /// bitIndex subtracted from the number of bits in a /// is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// /// An value specifying the little-endian bit /// index to begin writing from. /// /// /// An value specifying the maximum number of /// bits to write. /// /// /// [CLSCompliant(false)] public virtual void Write(uint bits, int bitIndex, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bitIndex < 0) throw new ArgumentOutOfRangeException(nameof(bitIndex), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (SizeOfUInt32 - bitIndex)) throw new ArgumentException("count + bitIndex exceeds the length of the 32-bit value."); uint uiBitIndex = (uint)bitIndex; uint uiCount = (uint)count; Write(ref bits, ref uiBitIndex, ref uiCount); } /// /// Writes the bits contained in an buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An array specifying the buffer to write data from. /// /// [CLSCompliant(false)] public virtual void Write(uint [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); Write(bits, 0, bits.Length); } /// /// Writes the bits contained in an buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An array specifying the buffer to write data from. /// /// /// An value specifying the offset /// to begin writing from. /// /// /// An value specifying the maximum number of /// values to write. /// /// /// [CLSCompliant(false)] public virtual void Write(uint [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; for(int iUInt32Counter = offset; iUInt32Counter < iEndIndex; iUInt32Counter++) Write(bits[iUInt32Counter]); } /// /// Writes the bits contained in an value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// public virtual void Write(int bits) { Write(bits, 0, SizeOfUInt32); } /// /// Writes the bits contained in an value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// /// An value specifying the little-endian bit /// index to begin writing from. /// /// /// An value specifying the maximum number of /// bits to write. /// /// public virtual void Write(int bits, int bitIndex, int count) { // Convert the value to an UInt32 uint uiBits = (uint)bits; Write(uiBits, bitIndex, count); } /// /// Writes the bits contained in an buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An array specifying the buffer to write data from. /// /// public virtual void Write(int [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); Write(bits, 0, bits.Length); } /// /// Writes the bits contained in an buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An array specifying the buffer to write data from. /// /// /// An value specifying the offset /// to begin writing from. /// /// /// An value specifying the maximum number of /// values to write. /// /// public virtual void Write(int [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); uint [] auiBits = new uint [count]; Buffer.BlockCopy(bits, offset << 2, auiBits, 0, count << 2); Write(auiBits, 0, count); } /// /// Writes the bits contained in a value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// A value specifying the bits to write data /// from. /// /// public virtual void Write(float bits) { Write(bits, 0, SizeOfSingle); } /// /// Writes the bits contained in a value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// /// An value specifying the little-endian bit /// index to begin writing from. /// /// /// An value specifying the maximum number of /// bits to write. /// /// /// public virtual void Write(float bits, int bitIndex, int count) { byte [] abytBits = BitConverter.GetBytes(bits); uint uiBits = abytBits[0] | ((uint)abytBits[1]) << 8 | ((uint)abytBits[2]) << 16 | ((uint)abytBits[3]) << 24; Write(uiBits, bitIndex, count); } /// /// Writes the bits contained in a buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// A array specifying the buffer to write data from. /// /// public virtual void Write(float [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); Write(bits, 0, bits.Length); } /// /// Writes the bits contained in a buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// A array specifying the buffer to write data from. /// /// /// An value specifying the offset /// to begin writing from. /// /// /// An value specifying the maximum number of /// values to write. /// /// /// public virtual void Write(float [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; for(int iSingleCounter = offset; iSingleCounter < iEndIndex; iSingleCounter++) Write(bits[iSingleCounter]); } #endregion #region 64-Bit Writes [20051201] /// /// Writes the bits contained in an value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// [CLSCompliant(false)] public virtual void Write(ulong bits) { Write(bits, 0, SizeOfUInt64); } /// /// Writes the bits contained in an value to /// the current stream. /// /// /// The current stream is closed. /// /// /// bitIndex or count is negative. /// /// /// bitIndex subtracted from the number of bits in a /// is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream.

///

/// Fixed [20051201]. ///
/// /// An value specifying the bits to write data /// from. /// /// /// An value specifying the little-endian bit /// index to begin writing from. /// /// /// An value specifying the maximum number of /// bits to write. /// /// /// [CLSCompliant(false)] public virtual void Write(ulong bits, int bitIndex, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bitIndex < 0) throw new ArgumentOutOfRangeException(nameof(bitIndex), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (SizeOfUInt64 - bitIndex)) throw new ArgumentException("count + bitIndex exceeds the length of the 64-bit value."); int iBitIndex1 = (bitIndex >> 5) < 1 ? bitIndex : -1; int iBitIndex2 = (bitIndex + count) > 32 ? (iBitIndex1 < 0 ? bitIndex - 32 : 0) : -1; int iCount1 = iBitIndex1 > -1 ? (iBitIndex1 + count > 32 ? 32 - iBitIndex1 : count) : 0; int iCount2 = iBitIndex2 > -1 ? (iCount1 == 0 ? count : count - iCount1) : 0; if(iCount1 > 0) { uint uiBits1 = (uint)bits; uint uiBitIndex1 = (uint)iBitIndex1; uint uiCount1 = (uint)iCount1; Write(ref uiBits1, ref uiBitIndex1, ref uiCount1); } if(iCount2 > 0) { uint uiBits2 = (uint)(bits >> 32); uint uiBitIndex2 = (uint)iBitIndex2; uint uiCount2 = (uint)iCount2; Write(ref uiBits2, ref uiBitIndex2, ref uiCount2); } } /// /// Writes the bits contained in an buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An array specifying the buffer to write data from. /// /// [CLSCompliant(false)] public virtual void Write(ulong [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); Write(bits, 0, bits.Length); } /// /// Writes the bits contained in an buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An array specifying the buffer to write data from. /// /// /// An value specifying the offset /// to begin writing from. /// /// /// An value specifying the maximum number of /// values to write. /// /// /// [CLSCompliant(false)] public virtual void Write(ulong [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; for(int iUInt64Counter = offset; iUInt64Counter < iEndIndex; iUInt64Counter++) Write(bits[iUInt64Counter]); } /// /// Writes the bits contained in an value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// public virtual void Write(long bits) { Write(bits, 0, SizeOfUInt64); } /// /// Writes the bits contained in an value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An value specifying the bits to write data /// from. /// /// /// An value specifying the little-endian bit /// index to begin writing from. /// /// /// An value specifying the maximum number of /// bits to write. /// /// /// public virtual void Write(long bits, int bitIndex, int count) { // Convert the value to an UInt64 ulong ulBits = (ulong)bits; Write(ulBits, bitIndex, count); } /// /// Writes the bits contained in an buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An array specifying the buffer to write data from. /// /// public virtual void Write(long [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); Write(bits, 0, bits.Length); } /// /// Writes the bits contained in an buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// An array specifying the buffer to write data from. /// /// /// An value specifying the offset /// to begin writing from. /// /// /// An value specifying the maximum number of /// values to write. /// /// /// public virtual void Write(long [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); ulong [] aulBits = new ulong [count]; Buffer.BlockCopy(bits, offset << 4, aulBits, 0, count << 4); Write(aulBits, 0, count); } /// /// Writes the bits contained in a value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// A value specifying the bits to write data /// from. /// /// public virtual void Write(double bits) { Write(bits, 0, SizeOfDouble); } /// /// Writes the bits contained in an value to /// the current stream. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// A value specifying the bits to write data /// from. /// /// /// An value specifying the little-endian bit /// index to begin writing from. /// /// /// An value specifying the maximum number of /// bits to write. /// /// /// public virtual void Write(double bits, int bitIndex, int count) { byte [] abytBits = BitConverter.GetBytes(bits); ulong ulBits = abytBits[0] | ((ulong)abytBits[1]) << 8 | ((ulong)abytBits[2]) << 16 | ((ulong)abytBits[3]) << 24 | ((ulong)abytBits[4]) << 32 | ((ulong)abytBits[5]) << 40 | ((ulong)abytBits[6]) << 48 | ((ulong)abytBits[7]) << 56; Write(ulBits, bitIndex, count); } /// /// Writes the bits contained in a buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// A array specifying the buffer to write data from. /// /// public virtual void Write(double [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); Write(bits, 0, bits.Length); } /// /// Writes the bits contained in a buffer to /// the current stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// All write operations at the end of the BitStream expand the /// BitStream. /// /// /// A array specifying the buffer to write data from. /// /// /// An value specifying the offset /// to begin writing from. /// /// /// An value specifying the maximum number of /// values to write. /// public virtual void Write(double [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; for(int iDoubleCounter = offset; iDoubleCounter < iEndIndex; iDoubleCounter++) Write(bits[iDoubleCounter]); } #endregion #region Miscellaneous /// /// Writes the entire contents of this bit stream to another stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// Added [20051127]

///

/// All write operations at the end of the BitStream expand the /// BitStream. ///
/// /// A object specifying the stream to write this /// bit stream to. /// /// public virtual void WriteTo(Stream bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The Stream cannot be null."); byte [] abytBits = ToByteArray(); bits.Write(abytBits, 0, abytBits.Length); } #endregion #endregion #region Read [20051201] #region Generic Reads [20051115] /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The current stream is closed. /// /// /// bitIndex or count is negative. /// /// /// bitIndex subtracted from the number of bits in a /// is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the bit index at which to /// begin reading. /// /// /// An value specifying the maximum number of bits /// to read. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// private uint Read(ref uint bits, ref uint bitIndex, ref uint count) { // Calculate the current position uint uiBitBuffer_Position = (_uiBitBuffer_Index << BitBuffer_SizeOfElement_Shift) + _uiBitBuffer_BitIndex; // Determine if there are enough bits available to be read from the buffer uint uiActualCount = count; if(_uiBitBuffer_Length < (uiBitBuffer_Position + uiActualCount)) uiActualCount = _uiBitBuffer_Length - uiBitBuffer_Position; // Get current bit buffer element value uint uiValue = _auiBitBuffer[_uiBitBuffer_Index]; int iValue_BitsToShift = (int)(BitBuffer_SizeOfElement - (_uiBitBuffer_BitIndex + uiActualCount)); if(iValue_BitsToShift < 0) { // Clear out unwanted bits in value iValue_BitsToShift = Math.Abs(iValue_BitsToShift); uint uiValue_BitMask = (BitMaskHelperLUT[uiActualCount] >> iValue_BitsToShift); uiValue &= uiValue_BitMask; uiValue <<= iValue_BitsToShift; uint uiRemainingCount = (uint)iValue_BitsToShift; uint uiBitIndex = 0; uint uiValueToAppend = 0; UpdateIndicesForRead(uiActualCount - uiRemainingCount); Read(ref uiValueToAppend, ref uiBitIndex, ref uiRemainingCount); uiValue |= uiValueToAppend; } else { // Clear out unwanted bits in value uint uiValue_BitMask = (BitMaskHelperLUT[uiActualCount] << iValue_BitsToShift); uiValue &= uiValue_BitMask; uiValue >>= iValue_BitsToShift; UpdateIndicesForRead(uiActualCount); } bits = uiValue << (int)bitIndex; return uiActualCount; } #endregion #region 1-Bit Reads [20051116] /// /// Reads the bit contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bit between bitIndex and (bitIndex + count - 1) /// replaced by the bit read from the current stream. /// /// /// An value specifying the number of bits /// written into the value. This can be 1 or zero if the end of the /// current stream is reached before the bit is read. /// /// /// public virtual int Read(out bool bit) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); uint uiBitIndex = 0; uint uiCount = 1; uint uiBit = 0; uint uiBitsRead = Read(ref uiBit, ref uiBitIndex, ref uiCount); bit = Convert.ToBoolean(uiBit); return (int)uiBitsRead; } /// /// Reads the bits contained in the current stream to a /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(bool [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); return Read(bits, 0, bits.Length); } /// /// Reads the bits contained in the current stream to a /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the offset /// at which to begin reading. /// /// /// An value specifying the maximum number of /// values to read. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(bool [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; int iBitsRead = 0; for(int iBitCounter = offset; iBitCounter < iEndIndex; iBitCounter++) iBitsRead += Read(out bits[iBitCounter]); return iBitsRead; } #endregion #region 8-Bit Reads [20051124] /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out byte bits) { return Read(out bits, 0, SizeOfByte); } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The current stream is closed. /// /// /// bitIndex or count is negative. /// /// /// bitIndex subtracted from the number of bits in a /// is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the bit index at which to /// begin reading. /// /// /// An value specifying the maximum number of bits /// to read. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out byte bits, int bitIndex, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bitIndex < 0) throw new ArgumentOutOfRangeException(nameof(bitIndex), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (SizeOfByte - bitIndex)) throw new ArgumentException("count + bitIndex exceeds the length of the 8-bit value."); uint uiBitIndex = (uint)bitIndex; uint uiCount = (uint)count; uint uiBits = 0; uint uiBitsRead = Read(ref uiBits, ref uiBitIndex, ref uiCount); bits = (byte)uiBits; return (int)uiBitsRead; } /// /// Reads the bits contained in the current stream to a /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(byte [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); return Read(bits, 0, bits.Length); } /// /// Reads the bits contained in the current stream to a /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the offset /// at which to begin reading. /// /// /// An value specifying the maximum number of /// values to read. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public override int Read(byte [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; int iBitsRead = 0; for(int iByteCounter = offset; iByteCounter < iEndIndex; iByteCounter++) iBitsRead += Read(out bits[iByteCounter]); return iBitsRead; } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out sbyte bits) { return Read(out bits, 0, SizeOfByte); } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the bit index at which to /// begin reading. /// /// /// An value specifying the maximum number of bits /// to read. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out sbyte bits, int bitIndex, int count) { int iBitsRead = Read(out byte bytBits, bitIndex, count); bits = (sbyte)bytBits; return iBitsRead; } /// /// Reads the bits contained in the current stream to an /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(sbyte [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); return Read(bits, 0, bits.Length); } /// /// Reads the bits contained in the current stream to an /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the offset /// at which to begin reading. /// /// /// An value specifying the maximum number of /// values to read. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(sbyte [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; int iBitsRead = 0; for(int iSByteCounter = offset; iSByteCounter < iEndIndex; iSByteCounter++) iBitsRead += Read(out bits[iSByteCounter]); return iBitsRead; } /// /// Reads a byte from the stream and advances the position within the /// stream by one byte, or returns -1 if at the end of the stream. /// /// /// Modified [20051124] /// /// /// The unsigned byte cast to an Int32, or -1 if at the end of the /// stream. /// public override int ReadByte() { int iBitsRead = Read(out byte bytBits); return iBitsRead == 0 ? -1 : bytBits; } /// /// /// /// Added [20051124]. /// /// /// public virtual byte [] ToByteArray() { // Write this stream's internal buffer to a new byte buffer long lCurrentPos = Position; Position = 0; byte [] abytBits = new byte [Length8]; Read(abytBits, 0, (int)Length8); if(Position != lCurrentPos) Position = lCurrentPos; return abytBits; } #endregion #region 16-Bits Reads [20051115] /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out char bits) { return Read(out bits, 0, SizeOfChar); } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The current stream is closed. /// /// /// bitIndex or count is negative. /// /// /// bitIndex subtracted from the number of bits in a /// is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the bit index at which to /// begin reading. /// /// /// An value specifying the maximum number of bits /// to read. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out char bits, int bitIndex, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bitIndex < 0) throw new ArgumentOutOfRangeException(nameof(bitIndex), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (SizeOfChar - bitIndex)) throw new ArgumentException("count + offset were out of bounds for the BitStream or count is greater than the number of elements from bitIndex to the end of the BitStream."); uint uiBitIndex = (uint)bitIndex; uint uiCount = (uint)count; uint uiBits = 0; uint uiBitsRead = Read(ref uiBits, ref uiBitIndex, ref uiCount); bits = (char)uiBits; return (int)uiBitsRead; } /// /// Reads the bits contained in the current stream to an /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(char [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); return Read(bits, 0, bits.Length); } /// /// Reads the bits contained in the current stream to an /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the offset /// at which to begin reading. /// /// /// An value specifying the maximum number of /// values to read. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(char [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; int iBitsRead = 0; for(int iCharCounter = offset; iCharCounter < iEndIndex; iCharCounter++) iBitsRead += Read(out bits[iCharCounter]); return iBitsRead; } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out ushort bits) { return Read(out bits, 0, SizeOfUInt16); } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The current stream is closed. /// /// /// bitIndex or count is negative. /// /// /// bitIndex subtracted from the number of bits in a /// is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the bit index at which to /// begin reading. /// /// /// An value specifying the maximum number of bits /// to read. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out ushort bits, int bitIndex, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bitIndex < 0) throw new ArgumentOutOfRangeException(nameof(bitIndex), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (SizeOfUInt16 - bitIndex)) throw new ArgumentException("count + bitIndex exceeds the length of the 16-bit value."); uint uiBitIndex = (uint)bitIndex; uint uiCount = (uint)count; uint uiBits = 0; uint uiBitsRead = Read(ref uiBits, ref uiBitIndex, ref uiCount); bits = (ushort)uiBits; return (int)uiBitsRead; } /// /// Reads the bits contained in the current stream to an /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(ushort [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); return Read(bits, 0, bits.Length); } /// /// Reads the bits contained in the current stream to an /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the offset /// at which to begin reading. /// /// /// An value specifying the maximum number of /// values to read. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(ushort [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; int iBitsRead = 0; for(int iUInt16Counter = offset; iUInt16Counter < iEndIndex; iUInt16Counter++) iBitsRead += Read(out bits[iUInt16Counter]); return iBitsRead; } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out short bits) { return Read(out bits, 0, SizeOfUInt16); } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the bit index at which to /// begin reading. /// /// /// An value specifying the maximum number of bits /// to read. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out short bits, int bitIndex, int count) { int iBitsRead = Read(out ushort usBits, bitIndex, count); bits = (short)usBits; return iBitsRead; } /// /// Reads the bits contained in the current stream to an /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(short [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); return Read(bits, 0, bits.Length); } /// /// Reads the bits contained in the current stream to an /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the offset /// at which to begin reading. /// /// /// An value specifying the maximum number of /// values to read. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(short [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; int iBitsRead = 0; for(int iShortCounter = offset; iShortCounter < iEndIndex; iShortCounter++) iBitsRead += Read(out bits[iShortCounter]); return iBitsRead; } #endregion #region 32-Bit Reads [20051115] /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out uint bits) { return Read(out bits, 0, SizeOfUInt32); } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The current stream is closed. /// /// /// bitIndex or count is negative. /// /// /// bitIndex subtracted from the number of bits in a /// is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the bit index at which to /// begin reading. /// /// /// An value specifying the maximum number of bits /// to read. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out uint bits, int bitIndex, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bitIndex < 0) throw new ArgumentOutOfRangeException(nameof(bitIndex), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (SizeOfUInt32 - bitIndex)) throw new ArgumentException("count + bitIndex exceeds the length of the 32-bit value."); uint uiBitIndex = (uint)bitIndex; uint uiCount = (uint)count; uint uiBits = 0; uint uiBitsRead = Read(ref uiBits, ref uiBitIndex, ref uiCount); bits = uiBits; return (int)uiBitsRead; } /// /// Reads the bits contained in the current stream to an /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(uint [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); return Read(bits, 0, bits.Length); } /// /// Reads the bits contained in the current stream to an /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the offset /// at which to begin reading. /// /// /// An value specifying the maximum number of /// values to read. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(uint [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; int iBitsRead = 0; for(int iUInt32Counter = offset; iUInt32Counter < iEndIndex; iUInt32Counter++) iBitsRead += Read(out bits[iUInt32Counter]); return iBitsRead; } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// public virtual int Read(out int bits) { return Read(out bits, 0, SizeOfUInt32); } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the bit index at which to /// begin reading. /// /// /// An value specifying the maximum number of bits /// to read. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// public virtual int Read(out int bits, int bitIndex, int count) { int iBitsRead = Read(out uint uiBits, bitIndex, count); bits = (int)uiBits; return iBitsRead; } /// /// Reads the bits contained in the current stream to an /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// public virtual int Read(int [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); return Read(bits, 0, bits.Length); } /// /// Reads the bits contained in the current stream to a /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the offset /// at which to begin reading. /// /// /// An value specifying the maximum number of /// values to read. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// public virtual int Read(int [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; int iBitsRead = 0; for(int iInt32Counter = offset; iInt32Counter < iEndIndex; iInt32Counter++) iBitsRead += Read(out bits[iInt32Counter]); return iBitsRead; } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out float bits) { return Read(out bits, 0, SizeOfSingle); } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the bit index at which to /// begin reading. /// /// /// An value specifying the maximum number of bits /// to read. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out float bits, int bitIndex, int count) { int uiBitsRead = Read(out int uiBits, bitIndex, count); bits = BitConverter.ToSingle(BitConverter.GetBytes(uiBits), 0); return uiBitsRead; } /// /// Reads the bits contained in the current stream to a /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(float [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); return Read(bits, 0, bits.Length); } /// /// Reads the bits contained in the current stream to a /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the offset /// at which to begin reading. /// /// /// An value specifying the maximum number of /// values to read. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(float [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; int iBitsRead = 0; for(int iSingleCounter = offset; iSingleCounter < iEndIndex; iSingleCounter++) iBitsRead += Read(out bits[iSingleCounter]); return iBitsRead; } #endregion #region 64-bit Reads [20051201] /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning.

///

/// Fixed [20051201]. ///
/// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out ulong bits) { return Read(out bits, 0, SizeOfUInt64); } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The current stream is closed. /// /// /// bitIndex or count is negative. /// /// /// bitIndex subtracted from the number of bits in a /// is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the bit index at which to /// begin reading. /// /// /// An value specifying the maximum number of bits /// to read. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out ulong bits, int bitIndex, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bitIndex < 0) throw new ArgumentOutOfRangeException(nameof(bitIndex), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (SizeOfUInt64 - bitIndex)) throw new ArgumentException("count + bitIndex exceeds the length of the 64-bit value."); int iBitIndex1 = (bitIndex >> 5) < 1 ? bitIndex : -1; int iBitIndex2 = (bitIndex + count) > 32 ? (iBitIndex1 < 0 ? bitIndex - 32 : 0) : -1; int iCount1 = iBitIndex1 > -1 ? (iBitIndex1 + count > 32 ? 32 - iBitIndex1 : count) : 0; int iCount2 = iBitIndex2 > -1 ? (iCount1 == 0 ? count : count - iCount1) : 0; uint uiBitsRead = 0; uint uiBits1 = 0; uint uiBits2 = 0; if(iCount1 > 0) { uint uiBitIndex1 = (uint)iBitIndex1; uint uiCount1 = (uint)iCount1; uiBitsRead = Read(ref uiBits1, ref uiBitIndex1, ref uiCount1); } if(iCount2 > 0) { uint uiBitIndex2 = (uint)iBitIndex2; uint uiCount2 = (uint)iCount2; uiBitsRead += Read(ref uiBits2, ref uiBitIndex2, ref uiCount2); } bits = ((ulong)uiBits2 << 32) | uiBits1; return (int)uiBitsRead; } /// /// Reads the bits contained in the current stream to an /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(ulong [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); return Read(bits, 0, bits.Length); } /// /// Reads the bits contained in the current stream to an /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the offset /// at which to begin reading. /// /// /// An value specifying the maximum number of /// values to read. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(ulong [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; int iBitsRead = 0; for(int iUInt64Counter = offset; iUInt64Counter < iEndIndex; iUInt64Counter++) iBitsRead += Read(out bits[iUInt64Counter]); return iBitsRead; } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out long bits) { return Read(out bits, 0, SizeOfUInt64); } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the bit index at which to /// begin reading. /// /// /// An value specifying the maximum number of bits /// to read. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out long bits, int bitIndex, int count) { int iBitsRead = Read(out ulong ulBits, bitIndex, count); bits = (long)ulBits; return iBitsRead; } /// /// Reads the bits contained in the current stream to an /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(long [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); return Read(bits, 0, bits.Length); } /// /// Reads the bits contained in the current stream to an /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the offset /// at which to begin reading. /// /// /// An value specifying the maximum number of /// values to read. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(long [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; int iBitsRead = 0; for(int iInt64Counter = offset; iInt64Counter < iEndIndex; iInt64Counter++) iBitsRead += Read(out bits[iInt64Counter]); return iBitsRead; } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out double bits) { return Read(out bits, 0, SizeOfDouble); } /// /// Reads the bits contained in the current stream to a /// value. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// value with the bits between bitIndex and (bitIndex + count - 1) /// replaced by the bits read from the current stream. /// /// /// An value specifying the bit index at which to /// begin reading. /// /// /// An value specifying the maximum number of bits /// to read. /// /// /// An value specifying the number of bits /// written into the value. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(out double bits, int bitIndex, int count) { int iBitsRead = Read(out ulong ulBits, bitIndex, count); bits = BitConverter.ToDouble(BitConverter.GetBytes(ulBits), 0); return iBitsRead; } /// /// Reads the bits contained in the current stream to a /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(double [] bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); return Read(bits, 0, bits.Length); } /// /// Reads the bits contained in the current stream to a /// buffer. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// offset or count is negative. /// /// /// offset subtracted from the buffer length is less than count. /// /// /// The Read method returns zero if the end of the current stream /// is reached. In all other cases, Read always reads at least one /// bit from the current stream before returning. /// /// /// When this method returns, contains the specified /// array with the values between offset and (offset + count - 1) replaced /// by the bits read from the current stream. /// /// /// An value specifying the offset /// at which to begin reading. /// /// /// An value specifying the maximum number of /// values to read. /// /// /// An value specifying the number of bits /// written into the buffer. This can be less than the number of bits /// requested if that number of bits are not currently available, /// or zero if the end of the current stream is reached before any /// bits are read. /// /// /// public virtual int Read(double [] bits, int offset, int count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The bit buffer cannot be null."); if(offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Parameter must be greater than or equal to zero."); if(count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Parameter must be greater than or equal to zero."); if(count > (bits.Length - offset)) throw new ArgumentException("count + offset were out of bounds for the array or count is greater than the number of elements from offset to the end of the array."); int iEndIndex = offset + count; int iBitsRead = 0; for(int iDoubleCounter = offset; iDoubleCounter < iEndIndex; iDoubleCounter++) iBitsRead += Read(out bits[iDoubleCounter]); return iBitsRead; } #endregion #endregion #region Logical Operations [20051115] /// /// Performs a bitwise AND operation on the bits in the /// current stream against the corresponding bits in the specified /// stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// The stream specified by the bits parameter and the current /// stream do not have the same number of bits. /// /// /// . /// /// /// A object with which to perform the bitwise /// AND operation. /// /// /// A object containing the result of the bitwise /// AND operation on the bits in the current stream against /// the corresponding bits in the specified stream. /// /// public virtual BitStream And(BitStream bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The BitStream cannot be null."); if(bits.Length != _uiBitBuffer_Length) throw new ArgumentException("BitStream lengths must be the same."); // Create the new BitStream BitStream bstrmNew = new BitStream(_uiBitBuffer_Length); uint uiWholeUInt32Lengths = _uiBitBuffer_Length >> BitBuffer_SizeOfElement_Shift; uint uiCounter;// = 0; for(uiCounter = 0; uiCounter < uiWholeUInt32Lengths; uiCounter++) bstrmNew._auiBitBuffer[uiCounter] = _auiBitBuffer[uiCounter] & bits._auiBitBuffer[uiCounter]; // Are there any further bits in the buffer? if((_uiBitBuffer_Length & BitBuffer_SizeOfElement_Mod) > 0) { uint uiBitMask = uint.MaxValue << (int)(BitBuffer_SizeOfElement - (_uiBitBuffer_Length & BitBuffer_SizeOfElement_Mod)); bstrmNew._auiBitBuffer[uiCounter] = _auiBitBuffer[uiCounter] & bits._auiBitBuffer[uiCounter] & uiBitMask; } return bstrmNew; } /// /// Performs a bitwise OR operation on the bits in the /// current stream against the corresponding bits in the specified /// stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// The stream specified by the bits parameter and the current /// stream do not have the same number of bits. /// /// /// . /// /// /// A object with which to perform the bitwise /// OR operation. /// /// /// A object containing the result of the bitwise /// OR operation on the bits in the current stream against /// the corresponding bits in the specified stream. /// /// public virtual BitStream Or(BitStream bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The BitStream cannot be null."); if(bits.Length != _uiBitBuffer_Length) throw new ArgumentException("BitStream lengths must be the same."); // Create the new BitStream BitStream bstrmNew = new BitStream(_uiBitBuffer_Length); uint uiWholeUInt32Lengths = _uiBitBuffer_Length >> BitBuffer_SizeOfElement_Shift; uint uiCounter;// = 0; for(uiCounter = 0; uiCounter < uiWholeUInt32Lengths; uiCounter++) bstrmNew._auiBitBuffer[uiCounter] = _auiBitBuffer[uiCounter] | bits._auiBitBuffer[uiCounter]; // Are there any further bits in the buffer? if((_uiBitBuffer_Length & BitBuffer_SizeOfElement_Mod) > 0) { uint uiBitMask = uint.MaxValue << (int)(BitBuffer_SizeOfElement - (_uiBitBuffer_Length & BitBuffer_SizeOfElement_Mod)); bstrmNew._auiBitBuffer[uiCounter] = _auiBitBuffer[uiCounter] | bits._auiBitBuffer[uiCounter] & uiBitMask; } return bstrmNew; } /// /// Performs a bitwise eXclusive OR operation on the /// bits in the current stream against the corresponding bits /// in the specified stream. /// /// /// The current stream is closed. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// The stream specified by the bits parameter and the current /// stream do not have the same number of bits. /// /// /// . /// /// /// A object with which to perform the bitwise /// eXclusive OR operation. /// /// /// A object containing the result of the bitwise /// eXclusive OR operation on the bits in the current /// stream against the corresponding bits in the specified stream. /// /// public virtual BitStream Xor(BitStream bits) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); if(bits == null) throw new ArgumentNullException(nameof(bits), "The BitStream cannot be null."); if(bits.Length != _uiBitBuffer_Length) throw new ArgumentException("BitStream lengths must be the same."); // Create the new BitStream BitStream bstrmNew = new BitStream(_uiBitBuffer_Length); uint uiWholeUInt32Lengths = _uiBitBuffer_Length >> BitBuffer_SizeOfElement_Shift; uint uiCounter;// = 0; for(uiCounter = 0; uiCounter < uiWholeUInt32Lengths; uiCounter++) bstrmNew._auiBitBuffer[uiCounter] = _auiBitBuffer[uiCounter] ^ bits._auiBitBuffer[uiCounter]; // Are there any further bits in the buffer? if((_uiBitBuffer_Length & BitBuffer_SizeOfElement_Mod) > 0) { uint uiBitMask = uint.MaxValue << (int)(BitBuffer_SizeOfElement - (_uiBitBuffer_Length & BitBuffer_SizeOfElement_Mod)); bstrmNew._auiBitBuffer[uiCounter] = _auiBitBuffer[uiCounter] ^ bits._auiBitBuffer[uiCounter] & uiBitMask; } return bstrmNew; } /// /// Performs a bitwise NOT operation on the bits in the /// current stream. /// /// /// The current stream is closed. /// /// /// . /// /// /// A object containing the result of the bitwise /// NOT operation on the bits in the current stream. /// /// public virtual BitStream Not() { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); // Create the new BitStream BitStream bstrmNew = new BitStream(_uiBitBuffer_Length); uint uiWholeUInt32Lengths = _uiBitBuffer_Length >> BitBuffer_SizeOfElement_Shift; uint uiCounter;// = 0; for(uiCounter = 0; uiCounter < uiWholeUInt32Lengths; uiCounter++) bstrmNew._auiBitBuffer[uiCounter] = ~_auiBitBuffer[uiCounter]; // Are there any further bits in the buffer? if((_uiBitBuffer_Length & BitBuffer_SizeOfElement_Mod) > 0) { uint uiBitMask = uint.MaxValue << (int)(BitBuffer_SizeOfElement - (_uiBitBuffer_Length & BitBuffer_SizeOfElement_Mod)); bstrmNew._auiBitBuffer[uiCounter] = ~_auiBitBuffer[uiCounter] & uiBitMask; } return bstrmNew; } #endregion #region Bit Shifting [20051116] /// /// Moves the bits of the current stream to the left /// by the specified number places. /// /// /// The current stream is closed. /// /// /// . /// /// /// An that represents the specified number of places. /// /// /// A object containing the result of left shift /// operation on the bits in the current stream. /// public virtual BitStream ShiftLeft(long count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); // Create a copy of the current stream BitStream bstrmNew = Copy(); uint uiCount = (uint)count; uint uiLength = (uint)bstrmNew.Length; if(uiCount >= uiLength) { // Clear out all bits bstrmNew.Position = 0; for(uint uiBitCounter = 0; uiBitCounter < uiLength; uiBitCounter++) bstrmNew.Write(false); } else // count < Length { for(uint uiBitCounter = 0; uiBitCounter < uiLength - uiCount; uiBitCounter++) { bstrmNew.Position = uiCount + uiBitCounter; bstrmNew.Read(out bool blnBit); bstrmNew.Position = uiBitCounter; bstrmNew.Write(blnBit); } // Clear out the last count bits for(uint uiBitCounter = uiLength - uiCount; uiBitCounter < uiLength; uiBitCounter++) bstrmNew.Write(false); } bstrmNew.Position = 0; return bstrmNew; } /// /// Moves the bits of the current stream to the right /// by the specified number places. /// /// /// The current stream is closed. /// /// /// . /// /// /// An that represents the specified number of places. /// /// /// A object containing the result of right shift /// operation on the bits in the current stream. /// public virtual BitStream ShiftRight(long count) { if(!_blnIsOpen) throw new ObjectDisposedException("Cannot access a closed BitStream."); // Create a copy of the current stream BitStream bstrmNew = Copy(); uint uiCount = (uint)count; uint uiLength = (uint)bstrmNew.Length; if(uiCount >= uiLength) { // Clear out all bits bstrmNew.Position = 0; for(uint uiBitCounter = 0; uiBitCounter < uiLength; uiBitCounter++) bstrmNew.Write(false); } else // count < Length { for(uint uiBitCounter = 0; uiBitCounter < uiLength - uiCount; uiBitCounter++) { bstrmNew.Position = uiBitCounter; bstrmNew.Read(out bool blnBit); bstrmNew.Position = uiBitCounter + uiCount; bstrmNew.Write(blnBit); } // Clear out the first count bits bstrmNew.Position = 0; for(uint uiBitCounter = 0; uiBitCounter < uiCount; uiBitCounter++) bstrmNew.Write(false); } bstrmNew.Position = 0; return bstrmNew; } #endregion #region ToString [2001116] /// /// Returns a that represents the current stream /// in binary notation. /// /// /// . /// /// /// A object representing the current stream /// in binary notation. /// /// public override string ToString() { uint uiWholeUInt32Lengths = _uiBitBuffer_Length >> 5; uint uiCounter;// = 0; int iBitCounter;// = 0; const uint ui1 = 1; StringBuilder sb = new StringBuilder((int)_uiBitBuffer_Length); for(uiCounter = 0; uiCounter < uiWholeUInt32Lengths; uiCounter++) { sb.Append("[" + uiCounter.ToString(_ifp) +"]:{"); for(iBitCounter = 31; iBitCounter >= 0; iBitCounter--) { uint uiBitMask = ui1 << iBitCounter; sb.Append((_auiBitBuffer[uiCounter] & uiBitMask) == uiBitMask ? '1' : '0'); } sb.Append("}\r\n"); } // Are there any further bits in the buffer? if((_uiBitBuffer_Length & 31) > 0) { sb.Append("[" + uiCounter.ToString(_ifp) +"]:{"); int iBitCounterMin = (int)(32 - (_uiBitBuffer_Length & 31)); for(iBitCounter = 31; iBitCounter >= iBitCounterMin; iBitCounter--) { uint uiBitMask = ui1 << iBitCounter; sb.Append((_auiBitBuffer[uiCounter] & uiBitMask) == uiBitMask ? '1' : '0'); } for(iBitCounter = iBitCounterMin - 1; iBitCounter >= 0; iBitCounter--) sb.Append('.'); sb.Append("}\r\n"); } return sb.ToString(); } /// /// Returns a that represents the specified /// value in binary notation. /// /// /// . /// /// /// A value representing the specified value. /// /// /// A object representing the specified value /// in binary notation. /// /// /// public static string ToString(bool bit) { string str = "Boolean{" + (bit ? 1 : 0) + "}"; return str; } /// /// Returns a that represents the specified /// value in binary notation. /// /// /// . /// /// /// A value representing the specified value. /// /// /// A object representing the specified value /// in binary notation. /// /// /// public static string ToString(byte bits) { StringBuilder sb = new StringBuilder(8); const uint ui1 = 1; sb.Append("Byte{"); for(int iBitCounter = 7; iBitCounter >= 0; iBitCounter--) { uint uiBitMask = ui1 << iBitCounter; sb.Append((bits & uiBitMask) == uiBitMask ? '1' : '0'); } sb.Append("}"); return sb.ToString(); } /// /// Returns a that represents the specified /// value in binary notation. /// /// /// . /// /// /// A value representing the specified value. /// /// /// A object representing the specified value /// in binary notation. /// /// /// [CLSCompliant(false)] public static string ToString(sbyte bits) { byte bytBits = (byte)bits; StringBuilder sb = new StringBuilder(8); const uint ui1 = 1; sb.Append("SByte{"); for(int iBitCounter = 7; iBitCounter >= 0; iBitCounter--) { uint uiBitMask = ui1 << iBitCounter; sb.Append((bytBits & uiBitMask) == uiBitMask ? '1' : '0'); } sb.Append("}"); return sb.ToString(); } /// /// Returns a that represents the specified /// value in binary notation. /// /// /// . /// /// /// A value representing the specified value. /// /// /// A object representing the specified value /// in binary notation. /// /// /// public static string ToString(char bits) { StringBuilder sb = new StringBuilder(16); const uint ui1 = 1; sb.Append("Char{"); for(int iBitCounter = 15; iBitCounter >= 0; iBitCounter--) { uint uiBitMask = ui1 << iBitCounter; sb.Append((bits & uiBitMask) == uiBitMask ? '1' : '0'); } sb.Append("}"); return sb.ToString(); } /// /// Returns a that represents the specified /// value in binary notation. /// /// /// . /// /// /// A value representing the specified value. /// /// /// A object representing the specified value /// in binary notation. /// /// /// public static string ToString(ushort bits) { short sBits = (short)bits; StringBuilder sb = new StringBuilder(16); const uint ui1 = 1; sb.Append("UInt16{"); for(int iBitCounter = 15; iBitCounter >= 0; iBitCounter--) { uint uiBitMask = ui1 << iBitCounter; sb.Append((sBits & uiBitMask) == uiBitMask ? '1' : '0'); } sb.Append("}"); return sb.ToString(); } /// /// Returns a that represents the specified /// value in binary notation. /// /// /// . /// /// /// A value representing the specified value. /// /// /// A object representing the specified value /// in binary notation. /// /// /// public static string ToString(short bits) { StringBuilder sb = new StringBuilder(16); const uint ui1 = 1; sb.Append("Int16{"); for(int iBitCounter = 15; iBitCounter >= 0; iBitCounter--) { uint uiBitMask = ui1 << iBitCounter; sb.Append((bits & uiBitMask) == uiBitMask ? '1' : '0'); } sb.Append("}"); return sb.ToString(); } /// /// Returns a that represents the specified /// value in binary notation. /// /// /// . /// /// /// A value representing the specified value. /// /// /// A object representing the specified value /// in binary notation. /// /// /// public static string ToString(uint bits) { StringBuilder sb = new StringBuilder(32); const uint ui1 = 1; sb.Append("UInt32{"); for(int iBitCounter = 31; iBitCounter >= 0; iBitCounter--) { uint uiBitMask = ui1 << iBitCounter; sb.Append((bits & uiBitMask) == uiBitMask ? '1' : '0'); } sb.Append("}"); return sb.ToString(); } /// /// Returns a that represents the specified /// value in binary notation. /// /// /// . /// /// /// A value representing the specified value. /// /// /// A object representing the specified value /// in binary notation. /// /// /// public static string ToString(int bits) { uint uiBits = (uint)bits; StringBuilder sb = new StringBuilder(32); const uint ui1 = 1; sb.Append("Int32{"); for(int iBitCounter = 31; iBitCounter >= 0; iBitCounter--) { uint uiBitMask = ui1 << iBitCounter; sb.Append((uiBits & uiBitMask) == uiBitMask ? '1' : '0'); } sb.Append("}"); return sb.ToString(); } /// /// Returns a that represents the specified /// value in binary notation. /// /// /// . /// /// /// A value representing the specified value. /// /// /// A object representing the specified value /// in binary notation. /// /// /// public static string ToString(ulong bits) { StringBuilder sb = new StringBuilder(64); const ulong ul1 = 1; sb.Append("UInt64{"); for(int iBitCounter = 63; iBitCounter >= 0; iBitCounter--) { ulong ulBitMask = ul1 << iBitCounter; sb.Append((bits & ulBitMask) == ulBitMask ? '1' : '0'); } sb.Append("}"); return sb.ToString(); } /// /// Returns a that represents the specified /// value in binary notation. /// /// /// . /// /// /// A value representing the specified value. /// /// /// A object representing the specified value /// in binary notation. /// /// /// public static string ToString(long bits) { ulong ulBits = (ulong)bits; StringBuilder sb = new StringBuilder(64); const ulong ul1 = 1; sb.Append("Int64{"); for(int iBitCounter = 63; iBitCounter >= 0; iBitCounter--) { ulong ulBitMask = ul1 << iBitCounter; sb.Append((ulBits & ulBitMask) == ulBitMask ? '1' : '0'); } sb.Append("}"); return sb.ToString(); } /// /// Returns a that represents the specified /// value in binary notation. /// /// /// . /// /// /// A value representing the specified value. /// /// /// A object representing the specified value /// in binary notation. /// /// /// public static string ToString(float bits) { byte [] abytBits = BitConverter.GetBytes(bits); uint uiBits = abytBits[0] | ((uint)abytBits[1]) << 8 | ((uint)abytBits[2]) << 16 | ((uint)abytBits[3]) << 24; StringBuilder sb = new StringBuilder(32); const uint ui1 = 1; sb.Append("Single{"); for(int iBitCounter = 31; iBitCounter >= 0; iBitCounter--) { uint uiBitMask = ui1 << iBitCounter; sb.Append((uiBits & uiBitMask) == uiBitMask ? '1' : '0'); } sb.Append("}"); return sb.ToString(); } /// /// Returns a that represents the specified /// value in binary notation. /// /// /// . /// /// /// A value representing the specified value. /// /// /// A object representing the specified value /// in binary notation. /// /// /// public static string ToString(double bits) { byte [] abytBits = BitConverter.GetBytes(bits); ulong ulBits = abytBits[0] | ((ulong)abytBits[1]) << 8 | ((ulong)abytBits[2]) << 16 | ((ulong)abytBits[3]) << 24 | ((ulong)abytBits[4]) << 32 | ((ulong)abytBits[5]) << 40 | ((ulong)abytBits[6]) << 48 | ((ulong)abytBits[7]) << 56; StringBuilder sb = new StringBuilder(64); const ulong ul1 = 1; sb.Append("Double{"); for(int iBitCounter = 63; iBitCounter >= 0; iBitCounter--) { ulong ulBitMask = ul1 << iBitCounter; sb.Append((ulBits & ulBitMask) == ulBitMask ? '1' : '0'); } sb.Append("}"); return sb.ToString(); } #endregion #region General [20051116] #region Private [20051116] /// /// Updates the length of the internal buffer after wrinting to the /// current stream by the specified number of bits. /// /// /// . /// /// /// An value defining the specified /// number of bits. /// /// private void UpdateLengthForWrite(uint bits) { // Increment _uiBitBuffer_Length _uiBitBuffer_Length += bits; } /// /// Updates the internal buffer's bit indices after writing to the /// current stream by the specified number of bits. /// /// /// The internal buffer's bit index is greater than 32. /// /// /// . /// /// /// An value defining the specified /// number of bits. /// /// private void UpdateIndicesForWrite(uint bits) { // Increment _uiBitBuffer_BitIndex _uiBitBuffer_BitIndex += bits; if(_uiBitBuffer_BitIndex == BitBuffer_SizeOfElement) { // Increment _uiBitBuffer_Index _uiBitBuffer_Index++; // Reset the bit index _uiBitBuffer_BitIndex = 0; // Redimension the bit buffer if necessary if(_auiBitBuffer.Length == (_uiBitBuffer_Length >> BitBuffer_SizeOfElement_Shift)) _auiBitBuffer = ReDimPreserve(_auiBitBuffer, (uint)_auiBitBuffer.Length << 1); } else if(_uiBitBuffer_BitIndex > BitBuffer_SizeOfElement) throw new InvalidOperationException("The internal bit buffer's bit index cannot be greater than 32."); } /// /// Updates the internal buffer's bit indices after reading to the /// current stream by the specified number of bits. /// /// /// The internal buffer's bit index is greater than 32. /// /// /// . /// /// /// An value defining the specified /// number of bits. /// /// private void UpdateIndicesForRead(uint bits) { // Increment _uiBitBuffer_BitIndex _uiBitBuffer_BitIndex += bits; if(_uiBitBuffer_BitIndex == BitBuffer_SizeOfElement) { // Increment _uiBitBuffer_Index _uiBitBuffer_Index++; // Reset the bit index _uiBitBuffer_BitIndex = 0; } else if(_uiBitBuffer_BitIndex > BitBuffer_SizeOfElement) throw new InvalidOperationException("The internal bit buffer's bit index cannot be greater than 32."); } /// /// Re-dimensions and preserves the contents of a buffer by the specified /// amount. /// /// /// . /// /// /// An array specifying the buffer to re-dimension. /// /// /// An value specifying the new length of the buffer. /// /// /// An array secifying the re-dimensioned array. /// /// private static uint [] ReDimPreserve(uint [] buffer, uint newLength) { uint [] auiNewBuffer = new uint [newLength]; uint uiBufferLength = (uint)buffer.Length; if(uiBufferLength < newLength) Buffer.BlockCopy(buffer, 0, auiNewBuffer, 0, (int)(uiBufferLength << 2)); else // buffer.Length >= newLength Buffer.BlockCopy(buffer, 0, auiNewBuffer, 0, (int)(newLength << 2)); // Free the previously allocated buffer buffer = null; return auiNewBuffer; } #endregion #region Public [20051116] /// /// Closes the current stream for reading and writing. /// /// /// . /// public override void Close() { _blnIsOpen = false; // Reset indices _uiBitBuffer_Index = 0; _uiBitBuffer_BitIndex = 0; } /// /// Returns the array of unsigned integers from which this stream was /// created. /// /// /// This method works even when the current stream is closed. /// /// /// The integer array from which this stream was created. /// public virtual uint [] GetBuffer() { return _auiBitBuffer; } /// /// Creates a copy of the current stream. /// /// /// This method works even when the current stream is closed. /// /// /// A object representing the copy of the current /// stream. /// /// public virtual BitStream Copy() { BitStream bstrmCopy = new BitStream(Length); Buffer.BlockCopy(_auiBitBuffer, 0, bstrmCopy._auiBitBuffer, 0, bstrmCopy._auiBitBuffer.Length << 2); bstrmCopy._uiBitBuffer_Length = _uiBitBuffer_Length; return bstrmCopy; } #endregion #endregion #region Not Supported [20051116] /// /// Begins an asynchronous read operation. /// /// /// This method is not supported. /// /// /// Notes to Callers: This method is not /// supported, and cannot be used. Asynchronous operations are not /// supported by the class. /// /// /// The buffer to read the data into. /// /// /// The byte offset in buffer at which to begin writing data read /// from the stream. /// /// /// The maximum number of bytes to read. /// /// /// An optional asynchronous callback, to be called when the read is /// complete. /// /// /// A user-provided object that distinguishes this particular asynchronous /// read request from other requests. /// /// /// An that represents the asynchronous read, /// which could still be pending. /// /// /// public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { throw new NotSupportedException("Asynchronous operations are not supported by the BitStream class."); } /// /// Begins an asynchronous write operation. /// /// /// This method is not supported. /// /// /// Notes to Callers: This method is not /// supported, and cannot be used. Asynchronous operations are not /// supported by the class. /// /// /// The buffer to write data from. /// /// /// The byte offset in buffer from which to begin writing. /// /// /// The maximum number of bytes to write. /// /// /// An optional asynchronous callback, to be called when the write is /// complete. /// /// /// A user-provided object that distinguishes this particular asynchronous /// write request from other requests. /// /// /// An that represents the asynchronous write, /// which could still be pending. /// /// /// public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { throw new NotSupportedException("Asynchronous operations are not supported by the BitStream class."); } /// /// Waits for the pending asynchronous read to complete. /// /// /// This method is not supported. /// /// /// Notes to Callers: This method is not /// supported, and cannot be used. Asynchronous operations are not /// supported by the class. /// /// /// The reference to the pending asynchronous request to finish. /// /// /// The number of bytes read from the stream, between zero (0) and the /// number of bytes you requested. Streams only return zero (0) at the /// end of the stream, otherwise, they should block until at least one /// byte is available. /// /// public override int EndRead(IAsyncResult asyncResult) { throw new NotSupportedException("Asynchronous operations are not supported by the BitStream class."); } /// /// Ends an asynchronous write operation. /// /// /// This method is not supported. /// /// /// Notes to Callers: This method is not /// supported, and cannot be used. Asynchronous operations are not /// supported by the class. /// /// /// A reference to the outstanding asynchronous I/O request. /// /// public override void EndWrite(IAsyncResult asyncResult) { throw new NotSupportedException("Asynchronous operations are not supported by the BitStream class."); } /// /// When overridden in a derived class, sets the position within the /// current stream. /// /// /// This method is not supported. /// /// /// Notes to Callers: This method is not /// supported, and cannot be used. To set the position within the current /// stream use the property instead. /// /// /// A byte offset relative to the origin parameter. /// /// /// A value of type indicating the reference point /// used to obtain the new position. /// /// /// The new position within the current stream. /// /// /// public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException("Cannot Seek on a BitStream. Use Position property instead."); } /// /// When overridden in a derived class, sets the length of the current /// stream. /// /// /// This method is not supported. /// /// /// Notes to Callers: This method is not /// supported, and cannot be used. All write operations at the end of the /// BitStream expand the BitStream automatically. /// /// /// The desired length of the current stream in bytes. /// public override void SetLength(long value) { throw new NotSupportedException("Cannot SetLength on a BitStream."); } /// /// When overridden in a derived class, clears all buffers for this stream /// and causes any buffered data to be written to the underlying device. /// /// /// This method is not supported. Since any data written to a /// is written into RAM, this method is /// redundant. /// /// /// Notes to Callers: This method is not /// supported, and cannot be used. /// public override void Flush() { throw new NotSupportedException("Cannot Flush a BitStream"); } #endregion #endregion #region Implicit Operators [20051125] /// /// Converts a object to a new instance of the /// class. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// . /// /// /// A object to convert. /// /// /// A object representing the new instance of the /// class. /// /// /// public static implicit operator BitStream(MemoryStream bits) { if(bits == null) throw new ArgumentNullException(nameof(bits), "The MemoryStream cannot be null."); return new BitStream(bits); } /// /// Converts a object to a new instance of the /// class. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// . /// /// /// A object to convert. /// /// /// A object representing the new instance of /// the class. /// /// /// public static implicit operator MemoryStream(BitStream bits) { if(bits == null) throw new ArgumentNullException(nameof(bits), "The BitStream cannot be null."); return new MemoryStream(bits.ToByteArray()); } /// /// Converts a object to a new instance of the /// class. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// This operator allows implicit casting from an instance of a /// object to a new instance of a /// object. No equivalent operator has been made /// available that allows implicit casting from an instance of a /// object to a new instance of a /// object. /// /// /// A object to convert. /// /// /// A object representing the new instance of the /// class. /// /// /// public static implicit operator BitStream(FileStream bits) { if(bits == null) throw new ArgumentNullException(nameof(bits), "The FileStream cannot be null."); return new BitStream(bits); } /// /// Converts a object to a new instance of the /// class. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// . /// /// /// A object to convert. /// /// /// A object representing the new instance of the /// class. /// /// /// public static implicit operator BitStream(BufferedStream bits) { if(bits == null) throw new ArgumentNullException(nameof(bits), "The BufferedStream cannot be null."); return new BitStream(bits); } /// /// Converts a object to a new instance of the /// class. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// . /// /// /// A object to convert. /// /// /// A object representing the new instance of /// the class. /// /// /// public static implicit operator BufferedStream(BitStream bits) { if(bits == null) throw new ArgumentNullException(nameof(bits), "The BitStream cannot be null."); return new BufferedStream((MemoryStream)bits); } /// /// Converts a object to a new instance of the /// class. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// This operator allows implicit casting from an instance of a /// object to a new instance of a /// object. No equivalent operator has been made /// available that allows implicit casting from an instance of a /// object to a new instance of a /// object. /// /// /// A object to convert. /// /// /// A object representing the new instance of the /// class. /// /// /// public static implicit operator BitStream(NetworkStream bits) { if(bits == null) throw new ArgumentNullException(nameof(bits), "The NetworkStreamStream cannot be null."); return new BitStream(bits); } /// /// Converts a object to a new instance of the /// class. /// /// /// bits is a null reference (Nothing in Visual Basic). /// /// /// This operator allows implicit casting from an instance of a /// object to a new instance of a /// object. No equivalent operator has been made /// available that allows implicit casting from an instance of a /// object to a new instance of a /// object. /// /// /// A object to convert. /// /// /// A object representing the new instance of the /// class. /// /// /// public static implicit operator BitStream(CryptoStream bits) { if(bits == null) throw new ArgumentNullException(nameof(bits), "The CryptoStream cannot be null."); return new BitStream(bits); } #endregion } }