/UltimaXNA/UltimaXNA/Data/BitStream.cs
http://ultimaxna.googlecode.com/ · C# · 1555 lines · 458 code · 94 blank · 1003 comment · 85 complexity · 4bf1e7cad4dc25c984dc71780fae90a9 MD5 · raw file
Large files are truncated click here to view the full file
- //*****************************************************************************
- // 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.IO;
- using System.Text;
- using System.Collections.Specialized;
- using System.Resources;
- using System.Globalization;
- using System.ComponentModel;
- using System.Reflection;
- using System.Net.Sockets;
- using System.Security.Cryptography;
-
- namespace BKSystem.IO
- {
- /// <summary>
- /// Creates a stream for reading and writing variable-length data.
- /// </summary>
- /// <remarks>
- /// <b><font color="red">Notes to Callers:</font></b> Make sure to
- /// include the "BitStream.resx" resource file in projects using the
- /// <see cref="BitStream"/> class.<br></br>
- /// <br></br>
- /// [20051201]: Fixed problem with <c>public virtual void Write(ulong bits, int bitIndex, int count)</c>
- /// and <c>public virtual int Read(out ulong bits, int bitIndex, int count)</c> methods.<br></br>
- /// <br></br>
- /// [20051127]: Added <c>public virtual void WriteTo(Stream bits);</c> to write
- /// the contents of the current <b>bit</b> stream to another stream.<br></br>
- /// <br></br>
- /// [20051125]: Added the following implicit operators to allow type casting
- /// instances of the <see cref="BitStream"/> class to and from other types
- /// of <see cref="Stream"/> objects:<br></br>
- /// <br></br>
- /// <c>public static implicit operator BitStream(MemoryStream bits);</c><br></br>
- /// <c>public static implicit operator MemoryStream(BitStream bits);</c><br></br>
- /// <c>public static implicit operator BitStream(FileStream bits);</c><br></br>
- /// <c>public static implicit operator BitStream(BufferedStream bits);</c><br></br>
- /// <c>public static implicit operator BufferedStream(BitStream bits);</c><br></br>
- /// <c>public static implicit operator BitStream(NetworkStream bits);</c><br></br>
- /// <c>public static implicit operator BitStream(CryptoStream bits);</c><br></br>
- /// <br></br>
- /// [20051124]: Added <c>public virtual <see cref="byte"/> [] ToByteArray();</c> method.<br></br>
- /// <br></br>
- /// [20051124]: The <c>public override <see cref="int"/> ReadByte();</c> and
- /// <c>public override void WriteByte(<see cref="byte"/> value)</c> method are now
- /// supported by the <see cref="BitStream"/> class.<br></br>
- /// <br></br>
- /// [20051123]: Added <c>public BitStream(<see cref="Stream"/> bits);</c> contructor.<br></br>
- /// <br></br>
- /// </remarks>
- /// <seealso cref="BitStream"/>
- /// <seealso cref="Stream"/>
- /// <seealso cref="int"/>
- /// <seealso cref="byte"/>
- public class BitStream : Stream
- {
-
- #region Nested Classes [20051116]
-
- #region private sealed class BitStreamResources [20051116]
- /// <summary>
- /// Manages reading resources on behalf of the <see cref="BitStream"/>
- /// class.
- /// </summary>
- /// <remarks>
- /// <b><font color="red">Notes to Callers:</font></b> Make sure to
- /// include the "BitStream.resx" resource file in projects using the
- /// <see cref="BitStream"/> class.
- /// </remarks>
- private sealed class BitStreamResources
- {
-
- #region Fields [20051116]
- /// <summary>
- /// The <see cref="ResourceManager"/> object.
- /// </summary>
- /// <remarks>
- /// .
- /// </remarks>
- private static ResourceManager _resman;
- /// <summary>
- /// An <see cref="Object"/> used to lock access to
- /// <see cref="BitStream"/> resources while the current
- /// <see cref="ResourceManager"/> is busy.
- /// </summary>
- /// <remarks>
- /// .
- /// </remarks>
- private static object _oResManLock;
- /// <summary>
- /// A <see cref="Boolean"/> value specifying whether a resource is
- /// currently being loaded.
- /// </summary>
- /// <remarks>
- /// .
- /// </remarks>
- /// <seealso cref="Boolean"/>
- private static bool _blnLoadingResource;
-
- #endregion
-
-
- #region Methods [20051116]
- /// <summary>
- /// Initialises the resource manager.
- /// </summary>
- /// <remarks>
- /// .
- /// </remarks>
- private static void InitialiseResourceManager()
- {
- if (_resman == null)
- {
- lock (typeof(BitStreamResources))
- {
- if (_resman == null)
- {
- _oResManLock = new object();
- _resman = new ResourceManager("BKSystem.IO.BitStream", typeof(BitStream).Assembly);
- }
- }
- }
- }
- /// <summary>
- /// Gets the specified string resource.
- /// </summary>
- /// <remarks>
- /// .
- /// </remarks>
- /// <param name="name">
- /// A <see cref="String"/> representing the specified resource.
- /// </param>
- /// <returns>
- /// A <see cref="String"/> representing the contents of the specified
- /// resource.
- /// </returns>
- /// <seealso cref="String"/>
- public static string GetString(string name)
- {
- string str;
- if (_resman == null)
- InitialiseResourceManager();
-
- lock (_oResManLock)
- {
- if (_blnLoadingResource)
- return ("The resource manager was unable to load the resource: " + name);
-
- _blnLoadingResource = true;
- str = _resman.GetString(name, null);
- _blnLoadingResource = false;
- }
- return str;
- }
-
- #endregion
-
- }
-
- #endregion
-
- #endregion
-
-
- #region Constants [20051116]
- /// <summary>
- /// An <see cref="Int32"/> value defining the number of bits
- /// in a <see cref="Byte"/> value type.
- /// </summary>
- /// <remarks>
- /// This field is constant.
- /// </remarks>
- /// <seealso cref="Int32"/>
- /// <seealso cref="Byte"/>
- private const int SizeOfByte = 8;
- /// <summary>
- /// An <see cref="Int32"/> value defining the number of bits
- /// in a <see cref="Char"/> value type.
- /// </summary>
- /// <remarks>
- /// This field is constant.
- /// </remarks>
- /// <seealso cref="Int32"/>
- /// <seealso cref="Char"/>
- private const int SizeOfChar = 128;
- /// <summary>
- /// An <see cref="Int32"/> value defining the number of bits
- /// in a <see cref="UInt16"/> value type.
- /// </summary>
- /// <remarks>
- /// This field is constant.
- /// </remarks>
- /// <seealso cref="Int32"/>
- /// <seealso cref="UInt16"/>
- private const int SizeOfUInt16 = 16;
- /// <summary>
- /// An <see cref="Int32"/> value defining the number of bits
- /// in a <see cref="UInt32"/> value type.
- /// </summary>
- /// <remarks>
- /// This field is constant.
- /// </remarks>
- /// <seealso cref="Int32"/>
- /// <seealso cref="UInt32"/>
- private const int SizeOfUInt32 = 32;
- /// <summary>
- /// An <see cref="Int32"/> value defining the number of bits
- /// in a <see cref="Single"/> value type.
- /// </summary>
- /// <remarks>
- /// This field is constant.
- /// </remarks>
- /// <seealso cref="Int32"/>
- /// <seealso cref="Single"/>
- private const int SizeOfSingle = 32;
- /// <summary>
- /// An <see cref="Int32"/> value defining the number of bits
- /// in a <see cref="UInt64"/> value type.
- /// </summary>
- /// <remarks>
- /// This field is constant.
- /// </remarks>
- /// <seealso cref="Int32"/>
- /// <seealso cref="UInt64"/>
- private const int SizeOfUInt64 = 64;
- /// <summary>
- /// An <see cref="Int32"/> value defining the number of bits
- /// in a <see cref="Double"/> value type.
- /// </summary>
- /// <remarks>
- /// This field is constant.
- /// </remarks>
- /// <seealso cref="Int32"/>
- /// <seealso cref="Double"/>
- private const int SizeOfDouble = 64;
- /// <summary>
- /// An <see cref="UInt32"/> value defining the number of bits
- /// per element in the internal buffer.
- /// </summary>
- /// <remarks>
- /// This field is constant.
- /// </remarks>
- /// <seealso cref="UInt32"/>
- private const uint BitBuffer_SizeOfElement = SizeOfUInt32;
- /// <summary>
- /// An <see cref="Int32"/> value defining the number of bit
- /// shifts equivalent to the number of bits per element in the
- /// internal buffer.
- /// </summary>
- /// <remarks>
- /// This field is constant.
- /// </remarks>
- /// <seealso cref="Int32"/>
- private const int BitBuffer_SizeOfElement_Shift = 5;
- /// <summary>
- /// An <see cref="UInt32"/> value defining the equivalent of
- /// a divisor in bitwise <b>AND</b> operations emulating
- /// modulo calculations.
- /// </summary>
- /// <remarks>
- /// This field is constant.
- /// </remarks>
- /// <seealso cref="UInt32"/>
- private const uint BitBuffer_SizeOfElement_Mod = 31;
- /// <summary>
- /// An <see cref="UInt32"/> array defining a series of values
- /// useful in generating bit masks in read and write operations.
- /// </summary>
- /// <remarks>
- /// This field is static.
- /// </remarks>
- private static uint[] BitMaskHelperLUT = new uint[]
- {
- 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]
- /// <summary>
- /// A <see cref="Boolean"/> value specifying whether the current
- /// stream is able to process data.
- /// </summary>
- /// <remarks>
- /// This field is set to <b>true</b> by default.
- /// </remarks>
- /// <seealso cref="Boolean"/>
- private bool _blnIsOpen = true;
- /// <summary>
- /// An array of <see cref="UInt32"/> values specifying the internal
- /// bit buffer for the current stream.
- /// </summary>
- /// <remarks>
- /// .
- /// </remarks>
- /// <seealso cref="UInt32"/>
- private uint[] _auiBitBuffer;
- /// <summary>
- /// An <see cref="UInt32"/> value specifying the current length of the
- /// internal bit buffer for the current stream.
- /// </summary>
- /// <remarks>
- /// .
- /// </remarks>
- /// <seealso cref="UInt32"/>
- private uint _uiBitBuffer_Length;
- /// <summary>
- /// An <see cref="UInt32"/> value specifying the current elemental index
- /// of the internal bit buffer for the current stream.
- /// </summary>
- /// <remarks>
- /// .
- /// </remarks>
- /// <seealso cref="UInt32"/>
- private uint _uiBitBuffer_Index;
- /// <summary>
- /// An <see cref="UInt32"/> value specifying the current bit index for the
- /// current element of the internal bit buffer for the current stream.
- /// </summary>
- /// <remarks>
- /// .
- /// </remarks>
- /// <seealso cref="UInt32"/>
- private uint _uiBitBuffer_BitIndex;
- /// <summary>
- /// An <see cref="IFormatProvider"/> object specifying the format specifier
- /// for the current stream.
- /// </summary>
- /// <remarks>
- /// This field is set to <b><see cref="CultureInfo.InvariantCulture"/></b>
- /// by default.
- /// </remarks>
- /// <see cref="IFormatProvider"/>
- /// <see cref="CultureInfo.InvariantCulture"/>
- private static IFormatProvider _ifp = (IFormatProvider)CultureInfo.InvariantCulture;
-
- #endregion
-
-
- #region Properties [20051116]
- /// <summary>
- /// Gets the length of this stream in <b>bits</b>.
- /// </summary>
- /// <exception cref="System.ObjectDisposedException">
- /// The current stream is closed.
- /// </exception>
- /// <remarks>
- /// .
- /// </remarks>
- /// <value>
- /// An <see cref="Int64"/> value specifying the length of this stream in
- /// <b>bits</b>.
- /// </value>
- /// <seealso cref="Int64"/>
- public override long Length
- {
- get
- {
- if (!_blnIsOpen)
- throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
-
- return (long)_uiBitBuffer_Length;
- }
- }
- /// <summary>
- /// Gets the maximum number of <b>8-bit</b> values required to store this
- /// stream.
- /// </summary>
- /// <exception cref="System.ObjectDisposedException">
- /// The current stream is closed.
- /// </exception>
- /// <remarks>
- /// .
- /// </remarks>
- /// <example>
- /// <font face="Courier New">
- /// <font color="green">
- /// // This property can be used in conjunction with the <see cref="Read(byte [], int, int)"/> method<br></br>
- /// // to read the entire stream into a <see cref="Byte"/> array.<br></br>
- /// </font>
- /// :<br></br>
- /// BitStream bstrm = <font color="blue">new</font> BitStream();<br></br>
- /// :<br></br>
- /// :<br></br>
- /// <font color="blue">byte</font> [] abytBuffer = <font color="blue">new byte</font> [bstrm.Length8];<br></br>
- /// <font color="blue">int</font> iBitsRead = Read(abytBuffer, 0, (<font color="blue">int</font>)bstrm.Length8);<br></br>
- /// :<br></br>
- /// </font>
- /// </example>
- /// <value>
- /// An <see cref="Int64"/> value specifying the maximum number of
- /// <b>8-bit</b> values required to store this stream.
- /// </value>
- /// <seealso cref="Read(byte [], int, int)"/>
- /// <seealso cref="Byte"/>
- /// <seealso cref="Int64"/>
- public virtual long Length8
- {
- get
- {
- if (!_blnIsOpen)
- throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
-
- return (long)(_uiBitBuffer_Length >> 3) + (long)((_uiBitBuffer_Length & 7) > 0 ? 1 : 0);
- }
- }
- /// <summary>
- /// Gets the maximum number of <b>16-bit</b> values required to store this
- /// stream.
- /// </summary>
- /// <exception cref="System.ObjectDisposedException">
- /// The current stream is closed.
- /// </exception>
- /// <remarks>
- /// .
- /// </remarks>
- /// <example>
- /// <font face="Courier New">
- /// <font color="green">
- /// // This property can be used in conjunction with the <see cref="Read(short [], int, int)"/> method<br></br>
- /// // to read the entire stream into an <see cref="Int16"/> array.<br></br>
- /// </font>
- /// :<br></br>
- /// BitStream bstrm = <font color="blue">new</font> BitStream();<br></br>
- /// :<br></br>
- /// :<br></br>
- /// <font color="blue">short</font> [] asBuffer = <font color="blue">new short</font> [bstrm.Length16];<br></br>
- /// <font color="blue">int</font> iBitsRead = Read(asBuffer, 0, (<font color="blue">int</font>)bstrm.Length16);<br></br>
- /// :<br></br>
- /// </font>
- /// </example>
- /// <value>
- /// An <see cref="Int64"/> value specifying the maximum number of
- /// <b>16-bit</b> values required to store this stream.
- /// </value>
- /// <seealso cref="Read(short [], int, int)"/>
- /// <seealso cref="Int16"/>
- /// <seealso cref="Int64"/>
- public virtual long Length16
- {
- get
- {
- if (!_blnIsOpen)
- throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
-
- return (long)(_uiBitBuffer_Length >> 4) + (long)((_uiBitBuffer_Length & 15) > 0 ? 1 : 0);
- }
- }
- /// <summary>
- /// Gets the maximum number of <b>32-bit</b> values required to store this
- /// stream.
- /// </summary>
- /// <exception cref="System.ObjectDisposedException">
- /// The current stream is closed.
- /// </exception>
- /// <remarks>
- /// .
- /// </remarks>
- /// <example>
- /// <font face="Courier New">
- /// <font color="green">
- /// // This property can be used in conjunction with the <see cref="Read(int [], int, int)"/> method<br></br>
- /// // to read the entire stream into an <see cref="Int32"/> array.<br></br>
- /// </font>
- /// :<br></br>
- /// BitStream bstrm = <font color="blue">new</font> BitStream();<br></br>
- /// :<br></br>
- /// :<br></br>
- /// <font color="blue">int</font> [] aiBuffer = <font color="blue">new int</font> [bstrm.Length32];<br></br>
- /// <font color="blue">int</font> iBitsRead = Read(aiBuffer, 0, (<font color="blue">int</font>)bstrm.Length32);<br></br>
- /// :<br></br>
- /// </font>
- /// </example>
- /// <value>
- /// An <see cref="Int64"/> value specifying the maximum number of
- /// <b>32-bit</b> values required to store this stream.
- /// </value>
- /// <seealso cref="Read(int [], int, int)"/>
- /// <seealso cref="Int32"/>
- /// <seealso cref="Int64"/>
- public virtual long Length32
- {
- get
- {
- if (!_blnIsOpen)
- throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
-
- return (long)(_uiBitBuffer_Length >> 5) + (long)((_uiBitBuffer_Length & 31) > 0 ? 1 : 0);
- }
- }
- /// <summary>
- /// Gets the maximum number of <b>64-bit</b> values required to store this
- /// stream.
- /// </summary>
- /// <exception cref="System.ObjectDisposedException">
- /// The current stream is closed.
- /// </exception>
- /// <remarks>
- /// .
- /// </remarks>
- /// <example>
- /// <font face="Courier New">
- /// <font color="green">
- /// // This property can be used in conjunction with the <see cref="Read(long [], int, int)"/> method<br></br>
- /// // to read the entire stream into an <see cref="Int64"/> array.<br></br>
- /// </font>
- /// :<br></br>
- /// BitStream bstrm = <font color="blue">new</font> BitStream();<br></br>
- /// :<br></br>
- /// :<br></br>
- /// <font color="blue">long</font> [] alBuffer = <font color="blue">new long</font> [bstrm.Length64];<br></br>
- /// <font color="blue">int</font> iBitsRead = Read(alBuffer, 0, (<font color="blue">int</font>)bstrm.Length64);<br></br>
- /// :<br></br>
- /// </font>
- /// </example>
- /// <value>
- /// An <see cref="Int64"/> value specifying the maximum number of
- /// <b>64-bit</b> values required to store this stream.
- /// </value>
- /// <seealso cref="Read(long [], int, int)"/>
- /// <seealso cref="Int64"/>
- public virtual long Length64
- {
- get
- {
- if (!_blnIsOpen)
- throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
-
- return (long)(_uiBitBuffer_Length >> 6) + (long)((_uiBitBuffer_Length & 63) > 0 ? 1 : 0);
- }
- }
- /// <summary>
- /// Gets the number of <b>bits</b> allocatated to this stream.
- /// </summary>
- /// <exception cref="System.ObjectDisposedException">
- /// The current stream is closed.
- /// </exception>
- /// <remarks>
- /// .
- /// </remarks>
- /// <value>
- /// An <see cref="Int64"/> value specifying the number of <b>bits</b>
- /// allocated to this stream.
- /// </value>
- public virtual long Capacity
- {
- get
- {
- if (!_blnIsOpen)
- throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
-
- return ((long)_auiBitBuffer.Length) << BitBuffer_SizeOfElement_Shift;
- }
- }
- /// <summary>
- /// Gets or sets the current <b>bit</b> position within this stream.
- /// </summary>
- /// <exception cref="System.ObjectDisposedException">
- /// The current stream is closed.
- /// </exception>
- /// <exception cref="System.ArgumentOutOfRangeException">
- /// The position is set to a negative value or position + 1 is geater than
- /// <see cref="Length"/>.
- /// </exception>
- /// <remarks>
- /// .
- /// </remarks>
- /// <value>
- /// An <see cref="Int64"/> value specifying the current <b>position</b>
- /// within this stream.
- /// </value>
- /// <seealso cref="Length"/>
- /// <seealso cref="Int64"/>
- public override long Position
- {
- get
- {
- if (!_blnIsOpen)
- throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
-
- uint uiPosition = (_uiBitBuffer_Index << BitBuffer_SizeOfElement_Shift) + _uiBitBuffer_BitIndex;
- return (long)uiPosition;
- }
- set
- {
- if (!_blnIsOpen)
- throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
-
- if (value < 0)
- throw new ArgumentOutOfRangeException("value", BitStreamResources.GetString("ArgumentOutOfRange_NegativePosition"));
-
- uint uiRequestedPosition = (uint)value;
-
- if (_uiBitBuffer_Length < uiRequestedPosition + 1)
- throw new ArgumentOutOfRangeException("value", BitStreamResources.GetString("ArgumentOutOfRange_InvalidPosition"));
-
- _uiBitBuffer_Index = uiRequestedPosition >> BitBuffer_SizeOfElement_Shift;
- if ((uiRequestedPosition & BitBuffer_SizeOfElement_Mod) > 0)
- _uiBitBuffer_BitIndex = (uiRequestedPosition & BitBuffer_SizeOfElement_Mod);
- else
- _uiBitBuffer_BitIndex = 0;
- }
- }
- /// <summary>
- /// Gets a value indicating whether the current stream supports reading.
- /// </summary>
- /// <remarks>
- /// .
- /// </remarks>
- /// <value>
- /// A <see cref="Boolean"/> value indicating whether the current stream
- /// supports reading.
- /// </value>
- /// <seealso cref="Boolean"/>
- public override bool CanRead
- {
- get { return _blnIsOpen; }
- }
- /// <summary>
- /// Gets a value indicating whether the current stream supports seeking.
- /// </summary>
- /// <remarks>
- /// This method always returns <b>false</b>. To set the position within
- /// the current stream use the <see cref="Position"/> property instead.
- /// </remarks>
- /// <value>
- /// A <see cref="Boolean"/> value indicating whether the current stream
- /// supports seeking.
- /// </value>
- /// <seealso cref="Position"/>
- /// <seealso cref="Boolean"/>
- public override bool CanSeek
- {
- get { return false; }
- }
- /// <summary>
- /// Gets a value indicating whether the current stream supports writing.
- /// </summary>
- /// <remarks>
- /// .
- /// </remarks>
- /// <value>
- /// A <see cref="Boolean"/> value indicating whether the current stream
- /// supports writing.
- /// </value>
- /// <seealso cref="Boolean"/>
- public override bool CanWrite
- {
- get { return _blnIsOpen; }
- }
- /// <summary>
- /// Gets a value indicating whether the current stream supports setting
- /// its length.
- /// </summary>
- /// <remarks>
- /// This field always returns <b>false</b>. All write operations at the
- /// end of the <b>BitStream</b> expand the <b>BitStream</b> automatically.
- /// </remarks>
- /// <value>
- /// A <see cref="Boolean"/> value indicating whether the current stream
- /// supports setting its length.
- /// </value>
- /// <see cref="Boolean"/>
- public static bool CanSetLength
- {
- get { return false; }
- }
- /// <summary>
- /// Gets a value indicating whether the current stream supports the flush
- /// operation.
- /// </summary>
- /// <remarks>
- /// This field always returns <b>false</b>. Since any data written to a
- /// <b>BitStream</b> is written into RAM, flush operations become
- /// redundant.
- /// </remarks>
- /// <value>
- /// A <see cref="Boolean"/> value indicating whether the current stream
- /// supports the flush operation.
- /// </value>
- /// <seealso cref="Boolean"/>
- public static bool CanFlush
- {
- get { return false; }
- }
-
- #endregion
-
-
- #region ctors/dtors [20051123]
- /// <summary>
- /// Initialises a new instance of the <see cref="BitStream"/> class
- /// with an expandable capacity initialised to one.
- /// </summary>
- /// <remarks>
- /// .
- /// </remarks>
- /// <seealso cref="BitStream"/>
- public BitStream()
- {
- // Initialise the bit buffer with 1 UInt32
- _auiBitBuffer = new uint[1];
- }
- /// <summary>
- /// Initialises a new instance of the <see cref="BitStream"/> class
- /// with an expandable capacity initialised to the specified capacity in
- /// <b>bits</b>.
- /// </summary>
- /// <exception cref="System.ArgumentOutOfRangeException">
- /// <i>capacity</i> is negative or zero.
- /// </exception>
- /// <remarks>
- /// .
- /// </remarks>
- /// <param name="capacity">
- /// An <see cref="Int64"/> specifying the initial size of the internal
- /// bit buffer in <b>bits</b>.
- /// </param>
- /// <seealso cref="BitStream"/>
- public BitStream(long capacity)
- {
- if (capacity <= 0)
- throw new ArgumentOutOfRangeException(BitStreamResources.GetString("ArgumentOutOfRange_NegativeOrZeroCapacity"));
-
- _auiBitBuffer = new uint[(capacity >> BitBuffer_SizeOfElement_Shift) + ((capacity & BitBuffer_SizeOfElement_Mod) > 0 ? 1 : 0)];
- }
- /// <summary>
- /// Initialises a new instance of the <see cref="BitStream"/> class
- /// with the <b>bits</b> provided by the specified <see cref="Stream"/>.
- /// </summary>
- /// <exception cref="System.ArgumentNullException">
- /// <i>bits</i> is a null reference (<b>Nothing</b> in Visual Basic).
- /// </exception>
- /// <remarks>
- /// Added [20051122].
- /// </remarks>
- /// <param name="bits">
- /// A <see cref="Stream"/> object containing the specified <b>bits</b>.
- /// </param>
- /// <seealso cref="BitStream"/>
- /// <seealso cref="Stream"/>
- public BitStream(Stream bits)
- : this()
- {
- if (bits == null)
- throw new ArgumentNullException("bits", BitStreamResources.GetString("ArgumentNull_BitBuffer"));
-
- // 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]
- /// <summary>
- /// Writes the <b>bits</b> contained in an <see cref="UInt32"/> value to
- /// the current stream.
- /// </summary>
- /// <exception cref="System.ObjectDisposedException">
- /// The current stream is closed.
- /// </exception>
- /// <exception cref="System.ArgumentOutOfRangeException">
- /// <i>bitIndex</i> or <i>count</i> is negative.
- /// </exception>
- /// <exception cref="System.ArgumentException">
- /// <i>bitIndex</i> subtracted from the number of <b>bits</b> in a
- /// <see cref="UInt32"/> is less than <i>count</i>.
- /// </exception>
- /// <remarks>
- /// All write operations at the end of the <b>BitStream</b> expand the
- /// <b>BitStream</b>.
- /// </remarks>
- /// <param name="bits">
- /// An <see cref="UInt32"/> value specifying the <b>bits</b> to write data
- /// from.
- /// </param>
- /// <param name="bitIndex">
- /// An <see cref="UInt32"/> value specifying the little-endian <b>bit</b>
- /// index to begin writing from.
- /// </param>
- /// <param name="count">
- /// An <see cref="UInt32"/> value specifying the maximum number of
- /// <b>bits</b> to write.
- /// </param>
- /// <seealso cref="UInt32"/>
- 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)
- {
- if (uiBitBuffer_FreeBits >= count)
- UpdateLengthForWrite(count);
- else
- UpdateLengthForWrite(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]
- /// <summary>
- /// Writes the <b>bit</b> represented by a <see cref="Boolean"/> value to
- /// the current stream.
- /// </summary>
- /// <remarks>
- /// All write operations at the end of the <b>BitStream</b> expand the
- /// <b>BitStream</b>.
- /// </remarks>
- /// <param name="bit">
- /// A <see cref="Boolean"/> value representing the <b>bit</b> to write data
- /// from.
- /// </param>
- /// <seealso cref="Boolean"/>
- public virtual void Write(bool bit)
- {
- if (!_blnIsOpen)
- throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
-
- // Convert the bool to UInt32
- uint uiBit = (uint)(bit ? 1 : 0);
- uint uiBitIndex = 0;
- uint uiCount = 1;
-
- Write(ref uiBit, ref uiBitIndex, ref uiCount);
- }
- /// <summary>
- /// Writes the <b>bits</b> contained in a <see cref="Boolean"/> buffer to
- /// the current stream.
- /// </summary>
- /// <exception cref="System.ObjectDisposedException">
- /// The current stream is closed.
- /// </exception>
- /// <exception cref="System.ArgumentNullException">
- /// <i>bits</i> is a null reference (<b>Nothing</b> in Visual Basic).
- /// </exception>
- /// <remarks>
- /// All write operations at the end of the <b>BitStream</b> expand the
- /// <b>BitStream</b>.
- /// </remarks>
- /// <param name="bits">
- /// A <see cref="Boolean"/> array specifying the buffer to write data from.
- /// </param>
- /// <seealso cref="Boolean"/>
- public virtual void Write(bool[] bits)
- {
- if (!_blnIsOpen)
- throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
- if (bits == null)
- throw new ArgumentNullException("bits", BitStreamResources.GetString("ArgumentNull_BitBuffer"));
-
- Write(bits, 0, bits.Length);
- }
- /// <summary>
- /// Writes the <b>bits</b> contained in a <see cref="Boolean"/> buffer to
- /// the current stream.
- /// </summary>
- /// <exception cref="System.ObjectDisposedException">
- /// The current stream is closed.
- /// </exception>
- /// <exception cref="System.ArgumentNullException">
- /// <i>bits</i> is a null reference (<b>Nothing</b> in Visual Basic).
- /// </exception>
- /// <exception cref="System.ArgumentOutOfRangeException">
- /// <i>offset</i> or <i>count</i> is negative.
- /// </exception>
- /// <exception cref="System.ArgumentException">
- /// <i>offset</i> subtracted from the buffer length is less than <i>count</i>.
- /// </exception>
- /// <remarks>
- /// All write operations at the end of the <b>BitStream</b> expand the
- /// <b>BitStream</b>.
- /// </remarks>
- /// <param name="bits">
- /// A <see cref="Boolean"/> array specifying the buffer to write data from.
- /// </param>
- /// <param name="offset">
- /// An <see cref="Int32"/> value specifying the <see cref="Boolean"/>
- /// offset to begin writing from.
- /// </param>
- /// <param name="count">
- /// An <see cref="Int32"/> value specifying the maximum number of
- /// <see cref="Boolean"/> values to write.
- /// </param>
- /// <seealso cref="Boolean"/>
- /// <seealso cref="Int32"/>
- public virtual void Write(bool[] bits, int offset, int count)
- {
- if (!_blnIsOpen)
- throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
- if (bits == null)
- throw new ArgumentNullException("bits", BitStreamResources.GetString("ArgumentNull_BitBuffer"));
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", BitStreamResources.GetString("ArgumentOutOfRange_NegativeParameter"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", BitStreamResources.GetString("ArgumentOutOfRange_NegativeParameter"));
- if (count > (bits.Length - offset))
- throw new ArgumentException(BitStreamResources.GetString("Argument_InvalidCountOrOffset"));
-
- int iEndIndex = offset + count;
- for (int iBitCounter = offset; iBitCounter < iEndIndex; iBitCounter++)
- Write(bits[iBitCounter]);
- }
-
- #endregion
-
-
- #region 8-Bit Writes [20051124]
- /// <summary>
- /// Writes the <b>bits</b> contained in a <see cref="Byte"/> value to
- /// the current stream.
- /// </summary>
- /// <remarks>
- /// All write operations at the end of the <b>BitStream</b> expand the
- /// <b>BitStream</b>.
- /// </remarks>
- /// <param name="bits">
- /// A <see cref="Byte"/> value specifying the <b>bits</b> to write data
- /// from.
- /// </param>
- /// <seealso cref="Byte"/>
- public virtual void Write(byte bits)
- {
- Write(bits, 0, SizeOfByte);
- }
- /// <summary>
- /// Writes the <b>bits</b> contained in a <see cref="Byte"/> value to
- /// the current stream.
- /// </summary>
- /// <exception cref="System.ObjectDisposedException">
- /// The current stream is closed.
- /// </exception>
- /// <exception cref="System.ArgumentOutOfRangeException">
- /// <i>bitIndex</i> or <i>count</i> is negative.
- /// </exception>
- /// <exception cref="System.ArgumentException">
- /// <i>bitIndex</i> subtracted from the number of <b>bits</b> in a
- /// <see cref="Byte"/> is less than <i>count</i>.
- /// </exception>
- /// <remarks>
- /// All write operations at the end of the <b>BitStream</b> expand the
- /// <b>BitStream</b>.
- /// </remarks>
- /// <param name="bits">
- /// A <see cref="Byte"/> value specifying the <b>bits</b> to write data
- /// from.
- /// </param>
- /// <param name="bitIndex">
- /// An <see cref="Int32"/> value specifying the little-endian <b>bit</b>
- /// index to begin writing from.
- /// </param>
- /// <param name="count">
- /// An <see cref="Int32"/> value specifying the maximum number of
- /// <b>bits</b> to write.
- /// </param>
- /// <seealso cref="Byte"/>
- /// <seealso cref="Int32"/>
- public virtual void Write(byte bits, int bitIndex, int count)
- {
- if (!_blnIsOpen)
- throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
- if (bitIndex < 0)
- throw new ArgumentOutOfRangeException("bitIndex", BitStreamResources.GetString("ArgumentOutOfRange_NegativeParameter"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", BitStreamResources.GetString("ArgumentOutOfRange_NegativeParameter"));
- if (count > (SizeOfByte - bitIndex))
- throw new ArgumentException(BitStreamResources.GetString("Argument_InvalidCountOrBitIndex_Byte"));
-
- uint uiBits = (uint)bits;
- uint uiBitIndex = (uint)bitIndex;
- uint uiCount = (uint)count;
-
- Write(ref uiBits, ref uiBitIndex, ref uiCount);
- }
- /// <summary>
- /// Writes the <b>bits</b> contained in a <see cref="Byte"/> buffer to
- /// the current stream.
- /// </summary>
- /// <exception cref="System.ObjectDisposedException">
- /// The current stream is closed.
- /// </exception>
- /// <exception cref="ArgumentNullException">
- /// <i>bits</i> is a null reference (<b>Nothing</b> in Visual Basic).
- /// </exception>
- /// <remarks>
- /// All write operations at the end of the <b>BitStream</b> expand the
- /// <b>BitStream</b>.
- /// </remarks>
- /// <param name="bits">
- /// A <see cref="Byte"/> array specifying the buffer to write data from.
- /// </param>
- /// <seealso cref="Byte"/>
- public virtual void Write(byte[] bits)
- {
- if (!_blnIsOpen)
- throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
- if (bits == null)
- throw new ArgumentNullException("bits", BitStreamResources.GetString("ArgumentNull_BitBuffer"));
-
- Write(bits, 0, bits.Length);
- }
- /// <summary>
- /// Writes the <b>bits</b> contained in a <see cref="Byte"/> buffer to
- /// the current stream.
- /// </summary>
- /// <exception cref="System.ObjectDisposedException">
- /// The current stream is closed.
- /// </exception>
- /// <exception cref="System.ArgumentNullException">
- /// <i>bits</i> is a null reference (<b>Nothing</b> in Visual Basic).
- /// </exception>
- /// <exception cref="System.ArgumentOutOfRangeException">
- /// <i>offset</i> or <i>count</i> is negative.
- /// </exception>
- /// <exception cref="System.ArgumentException">
- /// <i>offset</i> subtracted from the buffer length is less than <i>count</i>.
- /// </exception>
- /// <remarks>
- /// All write operations at the end of the <b>BitStream</b> expand the
- /// <b>BitStream</b>.
- /// </remarks>
- /// <param name="bits">
- /// A <see cref="Byte"/> array specifying the buffer to write data from.
- /// </param>
- /// <param name="offset">
- /// An <see cref="Int32"/> value specifying the <see cref="Byte"/> offset
- /// to begin writing from.
- /// </param>
- /// <param name="count">
- /// An <see cref="Int32"/> value specifying the maximum number of
- /// <see cref="Byte"/> values to write.
- /// </param>
- /// <seealso cref="Byte"/>
- /// <seealso cref="Int32"/>
- public override void Write(byte[] bits, int offset, int count)
- {
- if (!_blnIsOpen)
- throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
- if (bits == null)
- throw new ArgumentNullException("bits", BitStreamResources.GetString("ArgumentNull_BitBuffer"));
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", BitStreamResources.GetString("ArgumentOutOfRange_NegativeParameter"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", BitStreamResources.GetString("ArgumentOutOfRange_NegativeParameter"));
- if (count > (bits.Length - offset))
- throw new ArgumentException(BitStreamResources.GetString("Argument_InvalidCountOrOffset"));
-
- int iEndIndex = offset + count;
- for (int iByteCounter = offset; iByteCounter < iEndIndex; iByteCounter++)
- Write(bits[iByteCounter]);
- }
- /// <summary>
- /// Writes the <b>bits</b> contained in an <see cref="SByte"/> value to
- /// the current stream.
- /// </summary>
- /// <remarks>
- /// All write operations at the end of the <b>BitStream</b> expand the
- /// <b>BitStream</b>.
- /// </remarks>
- /// <param name="bits">
- /// An <see cref="SByte"/> value specifying the <b>bits</b> to write data
- /// from.
- /// </param>
- /// <seealso cref="SByte"/>
-
- public virtual void Write(sbyte bits)
- {
- Write(bits, 0, SizeOfByte);
- }
- /// <summary>
- /// Writes the <b>bits</b> contained in an <see cref="SByte"/> value to
- /// the current stream.
- /// </summary>
- /// <remarks>
- /// All write operations at the end of the <b>BitStream</b> expand the
- /// <b>BitStream</b>.
- /// </remarks>
- /// <param name="bits">
- /// An <see cref="SByte"/> value specifying the <b>bits</b> to write data
- /// from.
- /// </param>
- /// <param name="bitIndex">
- /// An <see cref="Int32"/> value specifying the little-endian <b>bit</b>
- /// index to begin writing from.
- /// </param>
- /// <param name="count">…