PageRenderTime 56ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/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 files are truncated, but you can click here to view the full file

  1. //*****************************************************************************
  2. // Copyright Š 2005, Bill Koukoutsis
  3. //
  4. // All rights reserved.
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions are met:
  8. //
  9. // Redistributions of source code must retain the above copyright notice, this
  10. // list of conditions and the following disclaimer.
  11. //
  12. // Redistributions in binary form must reproduce the above copyright notice,
  13. // this list of conditions and the following disclaimer in the documentation
  14. // and/or other materials provided with the distribution.
  15. //
  16. // Neither the name of the ORGANIZATION nor the names of its contributors may
  17. // be used to endorse or promote products derived from this software without
  18. // specific prior written permission.
  19. //
  20. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  24. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  25. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  26. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30. // POSSIBILITY OF SUCH DAMAGE.
  31. //*****************************************************************************
  32. using System;
  33. using System.IO;
  34. using System.Text;
  35. using System.Collections.Specialized;
  36. using System.Resources;
  37. using System.Globalization;
  38. using System.ComponentModel;
  39. using System.Reflection;
  40. using System.Net.Sockets;
  41. using System.Security.Cryptography;
  42. namespace BKSystem.IO
  43. {
  44. /// <summary>
  45. /// Creates a stream for reading and writing variable-length data.
  46. /// </summary>
  47. /// <remarks>
  48. /// <b><font color="red">Notes to Callers:</font></b> Make sure to
  49. /// include the "BitStream.resx" resource file in projects using the
  50. /// <see cref="BitStream"/> class.<br></br>
  51. /// <br></br>
  52. /// [20051201]: Fixed problem with <c>public virtual void Write(ulong bits, int bitIndex, int count)</c>
  53. /// and <c>public virtual int Read(out ulong bits, int bitIndex, int count)</c> methods.<br></br>
  54. /// <br></br>
  55. /// [20051127]: Added <c>public virtual void WriteTo(Stream bits);</c> to write
  56. /// the contents of the current <b>bit</b> stream to another stream.<br></br>
  57. /// <br></br>
  58. /// [20051125]: Added the following implicit operators to allow type casting
  59. /// instances of the <see cref="BitStream"/> class to and from other types
  60. /// of <see cref="Stream"/> objects:<br></br>
  61. /// <br></br>
  62. /// <c>public static implicit operator BitStream(MemoryStream bits);</c><br></br>
  63. /// <c>public static implicit operator MemoryStream(BitStream bits);</c><br></br>
  64. /// <c>public static implicit operator BitStream(FileStream bits);</c><br></br>
  65. /// <c>public static implicit operator BitStream(BufferedStream bits);</c><br></br>
  66. /// <c>public static implicit operator BufferedStream(BitStream bits);</c><br></br>
  67. /// <c>public static implicit operator BitStream(NetworkStream bits);</c><br></br>
  68. /// <c>public static implicit operator BitStream(CryptoStream bits);</c><br></br>
  69. /// <br></br>
  70. /// [20051124]: Added <c>public virtual <see cref="byte"/> [] ToByteArray();</c> method.<br></br>
  71. /// <br></br>
  72. /// [20051124]: The <c>public override <see cref="int"/> ReadByte();</c> and
  73. /// <c>public override void WriteByte(<see cref="byte"/> value)</c> method are now
  74. /// supported by the <see cref="BitStream"/> class.<br></br>
  75. /// <br></br>
  76. /// [20051123]: Added <c>public BitStream(<see cref="Stream"/> bits);</c> contructor.<br></br>
  77. /// <br></br>
  78. /// </remarks>
  79. /// <seealso cref="BitStream"/>
  80. /// <seealso cref="Stream"/>
  81. /// <seealso cref="int"/>
  82. /// <seealso cref="byte"/>
  83. public class BitStream : Stream
  84. {
  85. #region Nested Classes [20051116]
  86. #region private sealed class BitStreamResources [20051116]
  87. /// <summary>
  88. /// Manages reading resources on behalf of the <see cref="BitStream"/>
  89. /// class.
  90. /// </summary>
  91. /// <remarks>
  92. /// <b><font color="red">Notes to Callers:</font></b> Make sure to
  93. /// include the "BitStream.resx" resource file in projects using the
  94. /// <see cref="BitStream"/> class.
  95. /// </remarks>
  96. private sealed class BitStreamResources
  97. {
  98. #region Fields [20051116]
  99. /// <summary>
  100. /// The <see cref="ResourceManager"/> object.
  101. /// </summary>
  102. /// <remarks>
  103. /// .
  104. /// </remarks>
  105. private static ResourceManager _resman;
  106. /// <summary>
  107. /// An <see cref="Object"/> used to lock access to
  108. /// <see cref="BitStream"/> resources while the current
  109. /// <see cref="ResourceManager"/> is busy.
  110. /// </summary>
  111. /// <remarks>
  112. /// .
  113. /// </remarks>
  114. private static object _oResManLock;
  115. /// <summary>
  116. /// A <see cref="Boolean"/> value specifying whether a resource is
  117. /// currently being loaded.
  118. /// </summary>
  119. /// <remarks>
  120. /// .
  121. /// </remarks>
  122. /// <seealso cref="Boolean"/>
  123. private static bool _blnLoadingResource;
  124. #endregion
  125. #region Methods [20051116]
  126. /// <summary>
  127. /// Initialises the resource manager.
  128. /// </summary>
  129. /// <remarks>
  130. /// .
  131. /// </remarks>
  132. private static void InitialiseResourceManager()
  133. {
  134. if (_resman == null)
  135. {
  136. lock (typeof(BitStreamResources))
  137. {
  138. if (_resman == null)
  139. {
  140. _oResManLock = new object();
  141. _resman = new ResourceManager("BKSystem.IO.BitStream", typeof(BitStream).Assembly);
  142. }
  143. }
  144. }
  145. }
  146. /// <summary>
  147. /// Gets the specified string resource.
  148. /// </summary>
  149. /// <remarks>
  150. /// .
  151. /// </remarks>
  152. /// <param name="name">
  153. /// A <see cref="String"/> representing the specified resource.
  154. /// </param>
  155. /// <returns>
  156. /// A <see cref="String"/> representing the contents of the specified
  157. /// resource.
  158. /// </returns>
  159. /// <seealso cref="String"/>
  160. public static string GetString(string name)
  161. {
  162. string str;
  163. if (_resman == null)
  164. InitialiseResourceManager();
  165. lock (_oResManLock)
  166. {
  167. if (_blnLoadingResource)
  168. return ("The resource manager was unable to load the resource: " + name);
  169. _blnLoadingResource = true;
  170. str = _resman.GetString(name, null);
  171. _blnLoadingResource = false;
  172. }
  173. return str;
  174. }
  175. #endregion
  176. }
  177. #endregion
  178. #endregion
  179. #region Constants [20051116]
  180. /// <summary>
  181. /// An <see cref="Int32"/> value defining the number of bits
  182. /// in a <see cref="Byte"/> value type.
  183. /// </summary>
  184. /// <remarks>
  185. /// This field is constant.
  186. /// </remarks>
  187. /// <seealso cref="Int32"/>
  188. /// <seealso cref="Byte"/>
  189. private const int SizeOfByte = 8;
  190. /// <summary>
  191. /// An <see cref="Int32"/> value defining the number of bits
  192. /// in a <see cref="Char"/> value type.
  193. /// </summary>
  194. /// <remarks>
  195. /// This field is constant.
  196. /// </remarks>
  197. /// <seealso cref="Int32"/>
  198. /// <seealso cref="Char"/>
  199. private const int SizeOfChar = 128;
  200. /// <summary>
  201. /// An <see cref="Int32"/> value defining the number of bits
  202. /// in a <see cref="UInt16"/> value type.
  203. /// </summary>
  204. /// <remarks>
  205. /// This field is constant.
  206. /// </remarks>
  207. /// <seealso cref="Int32"/>
  208. /// <seealso cref="UInt16"/>
  209. private const int SizeOfUInt16 = 16;
  210. /// <summary>
  211. /// An <see cref="Int32"/> value defining the number of bits
  212. /// in a <see cref="UInt32"/> value type.
  213. /// </summary>
  214. /// <remarks>
  215. /// This field is constant.
  216. /// </remarks>
  217. /// <seealso cref="Int32"/>
  218. /// <seealso cref="UInt32"/>
  219. private const int SizeOfUInt32 = 32;
  220. /// <summary>
  221. /// An <see cref="Int32"/> value defining the number of bits
  222. /// in a <see cref="Single"/> value type.
  223. /// </summary>
  224. /// <remarks>
  225. /// This field is constant.
  226. /// </remarks>
  227. /// <seealso cref="Int32"/>
  228. /// <seealso cref="Single"/>
  229. private const int SizeOfSingle = 32;
  230. /// <summary>
  231. /// An <see cref="Int32"/> value defining the number of bits
  232. /// in a <see cref="UInt64"/> value type.
  233. /// </summary>
  234. /// <remarks>
  235. /// This field is constant.
  236. /// </remarks>
  237. /// <seealso cref="Int32"/>
  238. /// <seealso cref="UInt64"/>
  239. private const int SizeOfUInt64 = 64;
  240. /// <summary>
  241. /// An <see cref="Int32"/> value defining the number of bits
  242. /// in a <see cref="Double"/> value type.
  243. /// </summary>
  244. /// <remarks>
  245. /// This field is constant.
  246. /// </remarks>
  247. /// <seealso cref="Int32"/>
  248. /// <seealso cref="Double"/>
  249. private const int SizeOfDouble = 64;
  250. /// <summary>
  251. /// An <see cref="UInt32"/> value defining the number of bits
  252. /// per element in the internal buffer.
  253. /// </summary>
  254. /// <remarks>
  255. /// This field is constant.
  256. /// </remarks>
  257. /// <seealso cref="UInt32"/>
  258. private const uint BitBuffer_SizeOfElement = SizeOfUInt32;
  259. /// <summary>
  260. /// An <see cref="Int32"/> value defining the number of bit
  261. /// shifts equivalent to the number of bits per element in the
  262. /// internal buffer.
  263. /// </summary>
  264. /// <remarks>
  265. /// This field is constant.
  266. /// </remarks>
  267. /// <seealso cref="Int32"/>
  268. private const int BitBuffer_SizeOfElement_Shift = 5;
  269. /// <summary>
  270. /// An <see cref="UInt32"/> value defining the equivalent of
  271. /// a divisor in bitwise <b>AND</b> operations emulating
  272. /// modulo calculations.
  273. /// </summary>
  274. /// <remarks>
  275. /// This field is constant.
  276. /// </remarks>
  277. /// <seealso cref="UInt32"/>
  278. private const uint BitBuffer_SizeOfElement_Mod = 31;
  279. /// <summary>
  280. /// An <see cref="UInt32"/> array defining a series of values
  281. /// useful in generating bit masks in read and write operations.
  282. /// </summary>
  283. /// <remarks>
  284. /// This field is static.
  285. /// </remarks>
  286. private static uint[] BitMaskHelperLUT = new uint[]
  287. {
  288. 0x00000000,
  289. 0x00000001, 0x00000003, 0x00000007, 0x0000000F,
  290. 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
  291. 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
  292. 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
  293. 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
  294. 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
  295. 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
  296. 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF,
  297. };
  298. #endregion
  299. #region Fields [20051114]
  300. /// <summary>
  301. /// A <see cref="Boolean"/> value specifying whether the current
  302. /// stream is able to process data.
  303. /// </summary>
  304. /// <remarks>
  305. /// This field is set to <b>true</b> by default.
  306. /// </remarks>
  307. /// <seealso cref="Boolean"/>
  308. private bool _blnIsOpen = true;
  309. /// <summary>
  310. /// An array of <see cref="UInt32"/> values specifying the internal
  311. /// bit buffer for the current stream.
  312. /// </summary>
  313. /// <remarks>
  314. /// .
  315. /// </remarks>
  316. /// <seealso cref="UInt32"/>
  317. private uint[] _auiBitBuffer;
  318. /// <summary>
  319. /// An <see cref="UInt32"/> value specifying the current length of the
  320. /// internal bit buffer for the current stream.
  321. /// </summary>
  322. /// <remarks>
  323. /// .
  324. /// </remarks>
  325. /// <seealso cref="UInt32"/>
  326. private uint _uiBitBuffer_Length;
  327. /// <summary>
  328. /// An <see cref="UInt32"/> value specifying the current elemental index
  329. /// of the internal bit buffer for the current stream.
  330. /// </summary>
  331. /// <remarks>
  332. /// .
  333. /// </remarks>
  334. /// <seealso cref="UInt32"/>
  335. private uint _uiBitBuffer_Index;
  336. /// <summary>
  337. /// An <see cref="UInt32"/> value specifying the current bit index for the
  338. /// current element of the internal bit buffer for the current stream.
  339. /// </summary>
  340. /// <remarks>
  341. /// .
  342. /// </remarks>
  343. /// <seealso cref="UInt32"/>
  344. private uint _uiBitBuffer_BitIndex;
  345. /// <summary>
  346. /// An <see cref="IFormatProvider"/> object specifying the format specifier
  347. /// for the current stream.
  348. /// </summary>
  349. /// <remarks>
  350. /// This field is set to <b><see cref="CultureInfo.InvariantCulture"/></b>
  351. /// by default.
  352. /// </remarks>
  353. /// <see cref="IFormatProvider"/>
  354. /// <see cref="CultureInfo.InvariantCulture"/>
  355. private static IFormatProvider _ifp = (IFormatProvider)CultureInfo.InvariantCulture;
  356. #endregion
  357. #region Properties [20051116]
  358. /// <summary>
  359. /// Gets the length of this stream in <b>bits</b>.
  360. /// </summary>
  361. /// <exception cref="System.ObjectDisposedException">
  362. /// The current stream is closed.
  363. /// </exception>
  364. /// <remarks>
  365. /// .
  366. /// </remarks>
  367. /// <value>
  368. /// An <see cref="Int64"/> value specifying the length of this stream in
  369. /// <b>bits</b>.
  370. /// </value>
  371. /// <seealso cref="Int64"/>
  372. public override long Length
  373. {
  374. get
  375. {
  376. if (!_blnIsOpen)
  377. throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
  378. return (long)_uiBitBuffer_Length;
  379. }
  380. }
  381. /// <summary>
  382. /// Gets the maximum number of <b>8-bit</b> values required to store this
  383. /// stream.
  384. /// </summary>
  385. /// <exception cref="System.ObjectDisposedException">
  386. /// The current stream is closed.
  387. /// </exception>
  388. /// <remarks>
  389. /// .
  390. /// </remarks>
  391. /// <example>
  392. /// <font face="Courier New">
  393. /// <font color="green">
  394. /// // This property can be used in conjunction with the <see cref="Read(byte [], int, int)"/> method<br></br>
  395. /// // to read the entire stream into a <see cref="Byte"/> array.<br></br>
  396. /// </font>
  397. /// :<br></br>
  398. /// BitStream bstrm = <font color="blue">new</font> BitStream();<br></br>
  399. /// :<br></br>
  400. /// :<br></br>
  401. /// <font color="blue">byte</font> [] abytBuffer = <font color="blue">new byte</font> [bstrm.Length8];<br></br>
  402. /// <font color="blue">int</font> iBitsRead = Read(abytBuffer, 0, (<font color="blue">int</font>)bstrm.Length8);<br></br>
  403. /// :<br></br>
  404. /// </font>
  405. /// </example>
  406. /// <value>
  407. /// An <see cref="Int64"/> value specifying the maximum number of
  408. /// <b>8-bit</b> values required to store this stream.
  409. /// </value>
  410. /// <seealso cref="Read(byte [], int, int)"/>
  411. /// <seealso cref="Byte"/>
  412. /// <seealso cref="Int64"/>
  413. public virtual long Length8
  414. {
  415. get
  416. {
  417. if (!_blnIsOpen)
  418. throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
  419. return (long)(_uiBitBuffer_Length >> 3) + (long)((_uiBitBuffer_Length & 7) > 0 ? 1 : 0);
  420. }
  421. }
  422. /// <summary>
  423. /// Gets the maximum number of <b>16-bit</b> values required to store this
  424. /// stream.
  425. /// </summary>
  426. /// <exception cref="System.ObjectDisposedException">
  427. /// The current stream is closed.
  428. /// </exception>
  429. /// <remarks>
  430. /// .
  431. /// </remarks>
  432. /// <example>
  433. /// <font face="Courier New">
  434. /// <font color="green">
  435. /// // This property can be used in conjunction with the <see cref="Read(short [], int, int)"/> method<br></br>
  436. /// // to read the entire stream into an <see cref="Int16"/> array.<br></br>
  437. /// </font>
  438. /// :<br></br>
  439. /// BitStream bstrm = <font color="blue">new</font> BitStream();<br></br>
  440. /// :<br></br>
  441. /// :<br></br>
  442. /// <font color="blue">short</font> [] asBuffer = <font color="blue">new short</font> [bstrm.Length16];<br></br>
  443. /// <font color="blue">int</font> iBitsRead = Read(asBuffer, 0, (<font color="blue">int</font>)bstrm.Length16);<br></br>
  444. /// :<br></br>
  445. /// </font>
  446. /// </example>
  447. /// <value>
  448. /// An <see cref="Int64"/> value specifying the maximum number of
  449. /// <b>16-bit</b> values required to store this stream.
  450. /// </value>
  451. /// <seealso cref="Read(short [], int, int)"/>
  452. /// <seealso cref="Int16"/>
  453. /// <seealso cref="Int64"/>
  454. public virtual long Length16
  455. {
  456. get
  457. {
  458. if (!_blnIsOpen)
  459. throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
  460. return (long)(_uiBitBuffer_Length >> 4) + (long)((_uiBitBuffer_Length & 15) > 0 ? 1 : 0);
  461. }
  462. }
  463. /// <summary>
  464. /// Gets the maximum number of <b>32-bit</b> values required to store this
  465. /// stream.
  466. /// </summary>
  467. /// <exception cref="System.ObjectDisposedException">
  468. /// The current stream is closed.
  469. /// </exception>
  470. /// <remarks>
  471. /// .
  472. /// </remarks>
  473. /// <example>
  474. /// <font face="Courier New">
  475. /// <font color="green">
  476. /// // This property can be used in conjunction with the <see cref="Read(int [], int, int)"/> method<br></br>
  477. /// // to read the entire stream into an <see cref="Int32"/> array.<br></br>
  478. /// </font>
  479. /// :<br></br>
  480. /// BitStream bstrm = <font color="blue">new</font> BitStream();<br></br>
  481. /// :<br></br>
  482. /// :<br></br>
  483. /// <font color="blue">int</font> [] aiBuffer = <font color="blue">new int</font> [bstrm.Length32];<br></br>
  484. /// <font color="blue">int</font> iBitsRead = Read(aiBuffer, 0, (<font color="blue">int</font>)bstrm.Length32);<br></br>
  485. /// :<br></br>
  486. /// </font>
  487. /// </example>
  488. /// <value>
  489. /// An <see cref="Int64"/> value specifying the maximum number of
  490. /// <b>32-bit</b> values required to store this stream.
  491. /// </value>
  492. /// <seealso cref="Read(int [], int, int)"/>
  493. /// <seealso cref="Int32"/>
  494. /// <seealso cref="Int64"/>
  495. public virtual long Length32
  496. {
  497. get
  498. {
  499. if (!_blnIsOpen)
  500. throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
  501. return (long)(_uiBitBuffer_Length >> 5) + (long)((_uiBitBuffer_Length & 31) > 0 ? 1 : 0);
  502. }
  503. }
  504. /// <summary>
  505. /// Gets the maximum number of <b>64-bit</b> values required to store this
  506. /// stream.
  507. /// </summary>
  508. /// <exception cref="System.ObjectDisposedException">
  509. /// The current stream is closed.
  510. /// </exception>
  511. /// <remarks>
  512. /// .
  513. /// </remarks>
  514. /// <example>
  515. /// <font face="Courier New">
  516. /// <font color="green">
  517. /// // This property can be used in conjunction with the <see cref="Read(long [], int, int)"/> method<br></br>
  518. /// // to read the entire stream into an <see cref="Int64"/> array.<br></br>
  519. /// </font>
  520. /// :<br></br>
  521. /// BitStream bstrm = <font color="blue">new</font> BitStream();<br></br>
  522. /// :<br></br>
  523. /// :<br></br>
  524. /// <font color="blue">long</font> [] alBuffer = <font color="blue">new long</font> [bstrm.Length64];<br></br>
  525. /// <font color="blue">int</font> iBitsRead = Read(alBuffer, 0, (<font color="blue">int</font>)bstrm.Length64);<br></br>
  526. /// :<br></br>
  527. /// </font>
  528. /// </example>
  529. /// <value>
  530. /// An <see cref="Int64"/> value specifying the maximum number of
  531. /// <b>64-bit</b> values required to store this stream.
  532. /// </value>
  533. /// <seealso cref="Read(long [], int, int)"/>
  534. /// <seealso cref="Int64"/>
  535. public virtual long Length64
  536. {
  537. get
  538. {
  539. if (!_blnIsOpen)
  540. throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
  541. return (long)(_uiBitBuffer_Length >> 6) + (long)((_uiBitBuffer_Length & 63) > 0 ? 1 : 0);
  542. }
  543. }
  544. /// <summary>
  545. /// Gets the number of <b>bits</b> allocatated to this stream.
  546. /// </summary>
  547. /// <exception cref="System.ObjectDisposedException">
  548. /// The current stream is closed.
  549. /// </exception>
  550. /// <remarks>
  551. /// .
  552. /// </remarks>
  553. /// <value>
  554. /// An <see cref="Int64"/> value specifying the number of <b>bits</b>
  555. /// allocated to this stream.
  556. /// </value>
  557. public virtual long Capacity
  558. {
  559. get
  560. {
  561. if (!_blnIsOpen)
  562. throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
  563. return ((long)_auiBitBuffer.Length) << BitBuffer_SizeOfElement_Shift;
  564. }
  565. }
  566. /// <summary>
  567. /// Gets or sets the current <b>bit</b> position within this stream.
  568. /// </summary>
  569. /// <exception cref="System.ObjectDisposedException">
  570. /// The current stream is closed.
  571. /// </exception>
  572. /// <exception cref="System.ArgumentOutOfRangeException">
  573. /// The position is set to a negative value or position + 1 is geater than
  574. /// <see cref="Length"/>.
  575. /// </exception>
  576. /// <remarks>
  577. /// .
  578. /// </remarks>
  579. /// <value>
  580. /// An <see cref="Int64"/> value specifying the current <b>position</b>
  581. /// within this stream.
  582. /// </value>
  583. /// <seealso cref="Length"/>
  584. /// <seealso cref="Int64"/>
  585. public override long Position
  586. {
  587. get
  588. {
  589. if (!_blnIsOpen)
  590. throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
  591. uint uiPosition = (_uiBitBuffer_Index << BitBuffer_SizeOfElement_Shift) + _uiBitBuffer_BitIndex;
  592. return (long)uiPosition;
  593. }
  594. set
  595. {
  596. if (!_blnIsOpen)
  597. throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
  598. if (value < 0)
  599. throw new ArgumentOutOfRangeException("value", BitStreamResources.GetString("ArgumentOutOfRange_NegativePosition"));
  600. uint uiRequestedPosition = (uint)value;
  601. if (_uiBitBuffer_Length < uiRequestedPosition + 1)
  602. throw new ArgumentOutOfRangeException("value", BitStreamResources.GetString("ArgumentOutOfRange_InvalidPosition"));
  603. _uiBitBuffer_Index = uiRequestedPosition >> BitBuffer_SizeOfElement_Shift;
  604. if ((uiRequestedPosition & BitBuffer_SizeOfElement_Mod) > 0)
  605. _uiBitBuffer_BitIndex = (uiRequestedPosition & BitBuffer_SizeOfElement_Mod);
  606. else
  607. _uiBitBuffer_BitIndex = 0;
  608. }
  609. }
  610. /// <summary>
  611. /// Gets a value indicating whether the current stream supports reading.
  612. /// </summary>
  613. /// <remarks>
  614. /// .
  615. /// </remarks>
  616. /// <value>
  617. /// A <see cref="Boolean"/> value indicating whether the current stream
  618. /// supports reading.
  619. /// </value>
  620. /// <seealso cref="Boolean"/>
  621. public override bool CanRead
  622. {
  623. get { return _blnIsOpen; }
  624. }
  625. /// <summary>
  626. /// Gets a value indicating whether the current stream supports seeking.
  627. /// </summary>
  628. /// <remarks>
  629. /// This method always returns <b>false</b>. To set the position within
  630. /// the current stream use the <see cref="Position"/> property instead.
  631. /// </remarks>
  632. /// <value>
  633. /// A <see cref="Boolean"/> value indicating whether the current stream
  634. /// supports seeking.
  635. /// </value>
  636. /// <seealso cref="Position"/>
  637. /// <seealso cref="Boolean"/>
  638. public override bool CanSeek
  639. {
  640. get { return false; }
  641. }
  642. /// <summary>
  643. /// Gets a value indicating whether the current stream supports writing.
  644. /// </summary>
  645. /// <remarks>
  646. /// .
  647. /// </remarks>
  648. /// <value>
  649. /// A <see cref="Boolean"/> value indicating whether the current stream
  650. /// supports writing.
  651. /// </value>
  652. /// <seealso cref="Boolean"/>
  653. public override bool CanWrite
  654. {
  655. get { return _blnIsOpen; }
  656. }
  657. /// <summary>
  658. /// Gets a value indicating whether the current stream supports setting
  659. /// its length.
  660. /// </summary>
  661. /// <remarks>
  662. /// This field always returns <b>false</b>. All write operations at the
  663. /// end of the <b>BitStream</b> expand the <b>BitStream</b> automatically.
  664. /// </remarks>
  665. /// <value>
  666. /// A <see cref="Boolean"/> value indicating whether the current stream
  667. /// supports setting its length.
  668. /// </value>
  669. /// <see cref="Boolean"/>
  670. public static bool CanSetLength
  671. {
  672. get { return false; }
  673. }
  674. /// <summary>
  675. /// Gets a value indicating whether the current stream supports the flush
  676. /// operation.
  677. /// </summary>
  678. /// <remarks>
  679. /// This field always returns <b>false</b>. Since any data written to a
  680. /// <b>BitStream</b> is written into RAM, flush operations become
  681. /// redundant.
  682. /// </remarks>
  683. /// <value>
  684. /// A <see cref="Boolean"/> value indicating whether the current stream
  685. /// supports the flush operation.
  686. /// </value>
  687. /// <seealso cref="Boolean"/>
  688. public static bool CanFlush
  689. {
  690. get { return false; }
  691. }
  692. #endregion
  693. #region ctors/dtors [20051123]
  694. /// <summary>
  695. /// Initialises a new instance of the <see cref="BitStream"/> class
  696. /// with an expandable capacity initialised to one.
  697. /// </summary>
  698. /// <remarks>
  699. /// .
  700. /// </remarks>
  701. /// <seealso cref="BitStream"/>
  702. public BitStream()
  703. {
  704. // Initialise the bit buffer with 1 UInt32
  705. _auiBitBuffer = new uint[1];
  706. }
  707. /// <summary>
  708. /// Initialises a new instance of the <see cref="BitStream"/> class
  709. /// with an expandable capacity initialised to the specified capacity in
  710. /// <b>bits</b>.
  711. /// </summary>
  712. /// <exception cref="System.ArgumentOutOfRangeException">
  713. /// <i>capacity</i> is negative or zero.
  714. /// </exception>
  715. /// <remarks>
  716. /// .
  717. /// </remarks>
  718. /// <param name="capacity">
  719. /// An <see cref="Int64"/> specifying the initial size of the internal
  720. /// bit buffer in <b>bits</b>.
  721. /// </param>
  722. /// <seealso cref="BitStream"/>
  723. public BitStream(long capacity)
  724. {
  725. if (capacity <= 0)
  726. throw new ArgumentOutOfRangeException(BitStreamResources.GetString("ArgumentOutOfRange_NegativeOrZeroCapacity"));
  727. _auiBitBuffer = new uint[(capacity >> BitBuffer_SizeOfElement_Shift) + ((capacity & BitBuffer_SizeOfElement_Mod) > 0 ? 1 : 0)];
  728. }
  729. /// <summary>
  730. /// Initialises a new instance of the <see cref="BitStream"/> class
  731. /// with the <b>bits</b> provided by the specified <see cref="Stream"/>.
  732. /// </summary>
  733. /// <exception cref="System.ArgumentNullException">
  734. /// <i>bits</i> is a null reference (<b>Nothing</b> in Visual Basic).
  735. /// </exception>
  736. /// <remarks>
  737. /// Added [20051122].
  738. /// </remarks>
  739. /// <param name="bits">
  740. /// A <see cref="Stream"/> object containing the specified <b>bits</b>.
  741. /// </param>
  742. /// <seealso cref="BitStream"/>
  743. /// <seealso cref="Stream"/>
  744. public BitStream(Stream bits)
  745. : this()
  746. {
  747. if (bits == null)
  748. throw new ArgumentNullException("bits", BitStreamResources.GetString("ArgumentNull_BitBuffer"));
  749. // Write the stream to the internal buffer using a temporary byte buffer
  750. byte[] abytBits = new byte[bits.Length];
  751. long lCurrentPos = bits.Position;
  752. bits.Position = 0;
  753. bits.Read(abytBits, 0, (int)bits.Length);
  754. bits.Position = lCurrentPos;
  755. Write(abytBits, 0, (int)bits.Length);
  756. }
  757. #endregion
  758. #region Methods [20051201]
  759. #region Write [20051201]
  760. #region Generic Writes [20051115]
  761. /// <summary>
  762. /// Writes the <b>bits</b> contained in an <see cref="UInt32"/> value to
  763. /// the current stream.
  764. /// </summary>
  765. /// <exception cref="System.ObjectDisposedException">
  766. /// The current stream is closed.
  767. /// </exception>
  768. /// <exception cref="System.ArgumentOutOfRangeException">
  769. /// <i>bitIndex</i> or <i>count</i> is negative.
  770. /// </exception>
  771. /// <exception cref="System.ArgumentException">
  772. /// <i>bitIndex</i> subtracted from the number of <b>bits</b> in a
  773. /// <see cref="UInt32"/> is less than <i>count</i>.
  774. /// </exception>
  775. /// <remarks>
  776. /// All write operations at the end of the <b>BitStream</b> expand the
  777. /// <b>BitStream</b>.
  778. /// </remarks>
  779. /// <param name="bits">
  780. /// An <see cref="UInt32"/> value specifying the <b>bits</b> to write data
  781. /// from.
  782. /// </param>
  783. /// <param name="bitIndex">
  784. /// An <see cref="UInt32"/> value specifying the little-endian <b>bit</b>
  785. /// index to begin writing from.
  786. /// </param>
  787. /// <param name="count">
  788. /// An <see cref="UInt32"/> value specifying the maximum number of
  789. /// <b>bits</b> to write.
  790. /// </param>
  791. /// <seealso cref="UInt32"/>
  792. private void Write(ref uint bits, ref uint bitIndex, ref uint count)
  793. {
  794. // Calculate the current position
  795. uint uiBitBuffer_Position = (_uiBitBuffer_Index << BitBuffer_SizeOfElement_Shift) + _uiBitBuffer_BitIndex;
  796. // Detemine the last element in the bit buffer
  797. uint uiBitBuffer_LastElementIndex = (_uiBitBuffer_Length >> BitBuffer_SizeOfElement_Shift);
  798. // Clalculate this values end index
  799. uint uiValue_EndIndex = bitIndex + count;
  800. // Clear out unwanted bits in value
  801. int iValue_BitsToShift = (int)bitIndex;
  802. uint uiValue_BitMask = (BitMaskHelperLUT[count] << iValue_BitsToShift);
  803. bits &= uiValue_BitMask;
  804. // Position the bits in value
  805. uint uiBitBuffer_FreeBits = BitBuffer_SizeOfElement - _uiBitBuffer_BitIndex;
  806. iValue_BitsToShift = (int)(uiBitBuffer_FreeBits - uiValue_EndIndex);
  807. uint uiValue_Indexed = 0;
  808. if (iValue_BitsToShift < 0)
  809. uiValue_Indexed = bits >> Math.Abs(iValue_BitsToShift);
  810. else
  811. uiValue_Indexed = bits << iValue_BitsToShift;
  812. // Clear current bits in bit buffer that are at same indices
  813. // (only if overwriting)
  814. if (_uiBitBuffer_Length >= (uiBitBuffer_Position + 1))
  815. {
  816. int iBitBuffer_BitsToShift = (int)(uiBitBuffer_FreeBits - count);
  817. uint uiBitBuffer_BitMask = 0;
  818. if (iBitBuffer_BitsToShift < 0)
  819. uiBitBuffer_BitMask = uint.MaxValue ^ (BitMaskHelperLUT[count] >> Math.Abs(iBitBuffer_BitsToShift));
  820. else
  821. uiBitBuffer_BitMask = uint.MaxValue ^ (BitMaskHelperLUT[count] << iBitBuffer_BitsToShift);
  822. _auiBitBuffer[_uiBitBuffer_Index] &= uiBitBuffer_BitMask;
  823. // Is this the last element of the bit buffer?
  824. if (uiBitBuffer_LastElementIndex == _uiBitBuffer_Index)
  825. {
  826. uint uiBitBuffer_NewLength = 0;
  827. if (uiBitBuffer_FreeBits >= count)
  828. uiBitBuffer_NewLength = uiBitBuffer_Position + count;
  829. else
  830. uiBitBuffer_NewLength = uiBitBuffer_Position + uiBitBuffer_FreeBits;
  831. if (uiBitBuffer_NewLength > _uiBitBuffer_Length)
  832. {
  833. uint uiBitBuffer_ExtraBits = uiBitBuffer_NewLength - _uiBitBuffer_Length;
  834. UpdateLengthForWrite(uiBitBuffer_ExtraBits);
  835. }
  836. }
  837. }
  838. else // Not overwrinting any bits: _uiBitBuffer_Length < (uiBitBuffer_Position + 1)
  839. {
  840. if (uiBitBuffer_FreeBits >= count)
  841. UpdateLengthForWrite(count);
  842. else
  843. UpdateLengthForWrite(uiBitBuffer_FreeBits);
  844. }
  845. // Write value
  846. _auiBitBuffer[_uiBitBuffer_Index] |= uiValue_Indexed;
  847. if (uiBitBuffer_FreeBits >= count)
  848. UpdateIndicesForWrite(count);
  849. else // Some bits in value did not fit
  850. // in current bit buffer element
  851. {
  852. UpdateIndicesForWrite(uiBitBuffer_FreeBits);
  853. uint uiValue_RemainingBits = count - uiBitBuffer_FreeBits;
  854. uint uiValue_StartIndex = bitIndex;
  855. Write(ref bits, ref uiValue_StartIndex, ref uiValue_RemainingBits);
  856. }
  857. }
  858. #endregion
  859. #region 1-Bit Writes [20051116]
  860. /// <summary>
  861. /// Writes the <b>bit</b> represented by a <see cref="Boolean"/> value to
  862. /// the current stream.
  863. /// </summary>
  864. /// <remarks>
  865. /// All write operations at the end of the <b>BitStream</b> expand the
  866. /// <b>BitStream</b>.
  867. /// </remarks>
  868. /// <param name="bit">
  869. /// A <see cref="Boolean"/> value representing the <b>bit</b> to write data
  870. /// from.
  871. /// </param>
  872. /// <seealso cref="Boolean"/>
  873. public virtual void Write(bool bit)
  874. {
  875. if (!_blnIsOpen)
  876. throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
  877. // Convert the bool to UInt32
  878. uint uiBit = (uint)(bit ? 1 : 0);
  879. uint uiBitIndex = 0;
  880. uint uiCount = 1;
  881. Write(ref uiBit, ref uiBitIndex, ref uiCount);
  882. }
  883. /// <summary>
  884. /// Writes the <b>bits</b> contained in a <see cref="Boolean"/> buffer to
  885. /// the current stream.
  886. /// </summary>
  887. /// <exception cref="System.ObjectDisposedException">
  888. /// The current stream is closed.
  889. /// </exception>
  890. /// <exception cref="System.ArgumentNullException">
  891. /// <i>bits</i> is a null reference (<b>Nothing</b> in Visual Basic).
  892. /// </exception>
  893. /// <remarks>
  894. /// All write operations at the end of the <b>BitStream</b> expand the
  895. /// <b>BitStream</b>.
  896. /// </remarks>
  897. /// <param name="bits">
  898. /// A <see cref="Boolean"/> array specifying the buffer to write data from.
  899. /// </param>
  900. /// <seealso cref="Boolean"/>
  901. public virtual void Write(bool[] bits)
  902. {
  903. if (!_blnIsOpen)
  904. throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
  905. if (bits == null)
  906. throw new ArgumentNullException("bits", BitStreamResources.GetString("ArgumentNull_BitBuffer"));
  907. Write(bits, 0, bits.Length);
  908. }
  909. /// <summary>
  910. /// Writes the <b>bits</b> contained in a <see cref="Boolean"/> buffer to
  911. /// the current stream.
  912. /// </summary>
  913. /// <exception cref="System.ObjectDisposedException">
  914. /// The current stream is closed.
  915. /// </exception>
  916. /// <exception cref="System.ArgumentNullException">
  917. /// <i>bits</i> is a null reference (<b>Nothing</b> in Visual Basic).
  918. /// </exception>
  919. /// <exception cref="System.ArgumentOutOfRangeException">
  920. /// <i>offset</i> or <i>count</i> is negative.
  921. /// </exception>
  922. /// <exception cref="System.ArgumentException">
  923. /// <i>offset</i> subtracted from the buffer length is less than <i>count</i>.
  924. /// </exception>
  925. /// <remarks>
  926. /// All write operations at the end of the <b>BitStream</b> expand the
  927. /// <b>BitStream</b>.
  928. /// </remarks>
  929. /// <param name="bits">
  930. /// A <see cref="Boolean"/> array specifying the buffer to write data from.
  931. /// </param>
  932. /// <param name="offset">
  933. /// An <see cref="Int32"/> value specifying the <see cref="Boolean"/>
  934. /// offset to begin writing from.
  935. /// </param>
  936. /// <param name="count">
  937. /// An <see cref="Int32"/> value specifying the maximum number of
  938. /// <see cref="Boolean"/> values to write.
  939. /// </param>
  940. /// <seealso cref="Boolean"/>
  941. /// <seealso cref="Int32"/>
  942. public virtual void Write(bool[] bits, int offset, int count)
  943. {
  944. if (!_blnIsOpen)
  945. throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
  946. if (bits == null)
  947. throw new ArgumentNullException("bits", BitStreamResources.GetString("ArgumentNull_BitBuffer"));
  948. if (offset < 0)
  949. throw new ArgumentOutOfRangeException("offset", BitStreamResources.GetString("ArgumentOutOfRange_NegativeParameter"));
  950. if (count < 0)
  951. throw new ArgumentOutOfRangeException("count", BitStreamResources.GetString("ArgumentOutOfRange_NegativeParameter"));
  952. if (count > (bits.Length - offset))
  953. throw new ArgumentException(BitStreamResources.GetString("Argument_InvalidCountOrOffset"));
  954. int iEndIndex = offset + count;
  955. for (int iBitCounter = offset; iBitCounter < iEndIndex; iBitCounter++)
  956. Write(bits[iBitCounter]);
  957. }
  958. #endregion
  959. #region 8-Bit Writes [20051124]
  960. /// <summary>
  961. /// Writes the <b>bits</b> contained in a <see cref="Byte"/> value to
  962. /// the current stream.
  963. /// </summary>
  964. /// <remarks>
  965. /// All write operations at the end of the <b>BitStream</b> expand the
  966. /// <b>BitStream</b>.
  967. /// </remarks>
  968. /// <param name="bits">
  969. /// A <see cref="Byte"/> value specifying the <b>bits</b> to write data
  970. /// from.
  971. /// </param>
  972. /// <seealso cref="Byte"/>
  973. public virtual void Write(byte bits)
  974. {
  975. Write(bits, 0, SizeOfByte);
  976. }
  977. /// <summary>
  978. /// Writes the <b>bits</b> contained in a <see cref="Byte"/> value to
  979. /// the current stream.
  980. /// </summary>
  981. /// <exception cref="System.ObjectDisposedException">
  982. /// The current stream is closed.
  983. /// </exception>
  984. /// <exception cref="System.ArgumentOutOfRangeException">
  985. /// <i>bitIndex</i> or <i>count</i> is negative.
  986. /// </exception>
  987. /// <exception cref="System.ArgumentException">
  988. /// <i>bitIndex</i> subtracted from the number of <b>bits</b> in a
  989. /// <see cref="Byte"/> is less than <i>count</i>.
  990. /// </exception>
  991. /// <remarks>
  992. /// All write operations at the end of the <b>BitStream</b> expand the
  993. /// <b>BitStream</b>.
  994. /// </remarks>
  995. /// <param name="bits">
  996. /// A <see cref="Byte"/> value specifying the <b>bits</b> to write data
  997. /// from.
  998. /// </param>
  999. /// <param name="bitIndex">
  1000. /// An <see cref="Int32"/> value specifying the little-endian <b>bit</b>
  1001. /// index to begin writing from.
  1002. /// </param>
  1003. /// <param name="count">
  1004. /// An <see cref="Int32"/> value specifying the maximum number of
  1005. /// <b>bits</b> to write.
  1006. /// </param>
  1007. /// <seealso cref="Byte"/>
  1008. /// <seealso cref="Int32"/>
  1009. public virtual void Write(byte bits, int bitIndex, int count)
  1010. {
  1011. if (!_blnIsOpen)
  1012. throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
  1013. if (bitIndex < 0)
  1014. throw new ArgumentOutOfRangeException("bitIndex", BitStreamResources.GetString("ArgumentOutOfRange_NegativeParameter"));
  1015. if (count < 0)
  1016. throw new ArgumentOutOfRangeException("count", BitStreamResources.GetString("ArgumentOutOfRange_NegativeParameter"));
  1017. if (count > (SizeOfByte - bitIndex))
  1018. throw new ArgumentException(BitStreamResources.GetString("Argument_InvalidCountOrBitIndex_Byte"));
  1019. uint uiBits = (uint)bits;
  1020. uint uiBitIndex = (uint)bitIndex;
  1021. uint uiCount = (uint)count;
  1022. Write(ref uiBits, ref uiBitIndex, ref uiCount);
  1023. }
  1024. /// <summary>
  1025. /// Writes the <b>bits</b> contained in a <see cref="Byte"/> buffer to
  1026. /// the current stream.
  1027. /// </summary>
  1028. /// <exception cref="System.ObjectDisposedException">
  1029. /// The current stream is closed.
  1030. /// </exception>
  1031. /// <exception cref="ArgumentNullException">
  1032. /// <i>bits</i> is a null reference (<b>Nothing</b> in Visual Basic).
  1033. /// </exception>
  1034. /// <remarks>
  1035. /// All write operations at the end of the <b>BitStream</b> expand the
  1036. /// <b>BitStream</b>.
  1037. /// </remarks>
  1038. /// <param name="bits">
  1039. /// A <see cref="Byte"/> array specifying the buffer to write data from.
  1040. /// </param>
  1041. /// <seealso cref="Byte"/>
  1042. public virtual void Write(byte[] bits)
  1043. {
  1044. if (!_blnIsOpen)
  1045. throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
  1046. if (bits == null)
  1047. throw new ArgumentNullException("bits", BitStreamResources.GetString("ArgumentNull_BitBuffer"));
  1048. Write(bits, 0, bits.Length);
  1049. }
  1050. /// <summary>
  1051. /// Writes the <b>bits</b> contained in a <see cref="Byte"/> buffer to
  1052. /// the current stream.
  1053. /// </summary>
  1054. /// <exception cref="System.ObjectDisposedException">
  1055. /// The current stream is closed.
  1056. /// </exception>
  1057. /// <exception cref="System.ArgumentNullException">
  1058. /// <i>bits</i> is a null reference (<b>Nothing</b> in Visual Basic).
  1059. /// </exception>
  1060. /// <exception cref="System.ArgumentOutOfRangeException">
  1061. /// <i>offset</i> or <i>count</i> is negative.
  1062. /// </exception>
  1063. /// <exception cref="System.ArgumentException">
  1064. /// <i>offset</i> subtracted from the buffer length is less than <i>count</i>.
  1065. /// </exception>
  1066. /// <remarks>
  1067. /// All write operations at the end of the <b>BitStream</b> expand the
  1068. /// <b>BitStream</b>.
  1069. /// </remarks>
  1070. /// <param name="bits">
  1071. /// A <see cref="Byte"/> array specifying the buffer to write data from.
  1072. /// </param>
  1073. /// <param name="offset">
  1074. /// An <see cref="Int32"/> value specifying the <see cref="Byte"/> offset
  1075. /// to begin writing from.
  1076. /// </param>
  1077. /// <param name="count">
  1078. /// An <see cref="Int32"/> value specifying the maximum number of
  1079. /// <see cref="Byte"/> values to write.
  1080. /// </param>
  1081. /// <seealso cref="Byte"/>
  1082. /// <seealso cref="Int32"/>
  1083. public override void Write(byte[] bits, int offset, int count)
  1084. {
  1085. if (!_blnIsOpen)
  1086. throw new ObjectDisposedException(BitStreamResources.GetString("ObjectDisposed_BitStreamClosed"));
  1087. if (bits == null)
  1088. throw new ArgumentNullException("bits", BitStreamResources.GetString("ArgumentNull_BitBuffer"));
  1089. if (offset < 0)
  1090. throw new ArgumentOutOfRangeException("offset", BitStreamResources.GetString("ArgumentOutOfRange_NegativeParameter"));
  1091. if (count < 0)
  1092. throw new ArgumentOutOfRangeException("count", BitStreamResources.GetString("ArgumentOutOfRange_NegativeParameter"));
  1093. if (count > (bits.Length - offset))
  1094. throw new ArgumentException(BitStreamResources.GetString("Argument_InvalidCountOrOffset"));
  1095. int iEndIndex = offset + count;
  1096. for (int iByteCounter = offset; iByteCounter < iEndIndex; iByteCounter++)
  1097. Write(bits[iByteCounter]);
  1098. }
  1099. /// <summary>
  1100. /// Writes the <b>bits</b> contained in an <see cref="SByte"/> value to
  1101. /// the current stream.
  1102. /// </summary>
  1103. /// <remarks>
  1104. /// All write operations at the end of the <b>BitStream</b> expand the
  1105. /// <b>BitStream</b>.
  1106. /// </remarks>
  1107. /// <param name="bits">
  1108. /// An <see cref="SByte"/> value specifying the <b>bits</b> to write data
  1109. /// from.
  1110. /// </param>
  1111. /// <seealso cref="SByte"/>
  1112. public virtual void Write(sbyte bits)
  1113. {
  1114. Write(bits, 0, SizeOfByte);
  1115. }
  1116. /// <summary>
  1117. /// Writes the <b>bits</b> contained in an <see cref="SByte"/> value to
  1118. /// the current stream.
  1119. /// </summary>
  1120. /// <remarks>
  1121. /// All write operations at the end of the <b>BitStream</b> expand the
  1122. /// <b>BitStream</b>.
  1123. /// </remarks>
  1124. /// <param name="bits">
  1125. /// An <see cref="SByte"/> value specifying the <b>bits</b> to write data
  1126. /// from.
  1127. /// </param>
  1128. /// <param name="bitIndex">
  1129. /// An <see cref="Int32"/> value specifying the little-endian <b>bit</b>
  1130. /// index to begin writing from.
  1131. /// </param>
  1132. /// <param name="count">

Large files files are truncated, but you can click here to view the full file