PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/Utilities/Compression/PendingBuffer.cs

#
C# | 270 lines | 159 code | 27 blank | 84 comment | 6 complexity | b059631fdefa7b64eb69d3b5a1d7b994 MD5 | raw file
Possible License(s): Apache-2.0
  1. // Based on Mike Krueger's SharpZipLib, Copyright (C) 2001 (GNU license).
  2. // Authors of the original java version: Jochen Hoenicke, John Leuner
  3. // See http://www.ISeeSharpCode.com for more information.
  4. using System;
  5. namespace Delta.Utilities.Compression
  6. {
  7. /// <summary>
  8. /// This class is general purpose class for writing data to a buffer.
  9. /// It allows you to write bits as well as bytes.
  10. /// </summary>
  11. public class PendingBuffer
  12. {
  13. #region BitCount (Public)
  14. /// <summary>
  15. /// Bit count
  16. /// </summary>
  17. /// <returns>Int</returns>
  18. public int BitCount
  19. {
  20. get
  21. {
  22. return bitCount;
  23. } // get
  24. }
  25. #endregion
  26. #region IsFlushed (Public)
  27. /// <summary>
  28. /// Is this buffer already flushed?
  29. /// </summary>
  30. /// <returns>True if we have flushed to the end already.</returns>
  31. public bool IsFlushed
  32. {
  33. get
  34. {
  35. return end == 0;
  36. } // get
  37. }
  38. #endregion
  39. #region Protected
  40. #region buf (Protected)
  41. /// <summary>
  42. /// Buffer used for pending data.
  43. /// </summary>
  44. protected byte[] buf;
  45. #endregion
  46. #endregion
  47. #region Private
  48. #region start (Private)
  49. /// <summary>
  50. /// Start
  51. /// </summary>
  52. private int start;
  53. #endregion
  54. #region end (Private)
  55. /// <summary>
  56. /// End
  57. /// </summary>
  58. private int end;
  59. #endregion
  60. #region bits (Private)
  61. /// <summary>
  62. /// Bits
  63. /// </summary>
  64. private uint bits;
  65. #endregion
  66. #region bitCount (Private)
  67. /// <summary>
  68. /// Bit count
  69. /// </summary>
  70. private int bitCount;
  71. #endregion
  72. #endregion
  73. #region Constructors
  74. /// <summary>
  75. /// Create pending buffer
  76. /// </summary>
  77. public PendingBuffer()
  78. : this(4096)
  79. {
  80. }
  81. // PendingBuffer()
  82. /// <summary>
  83. /// Create pending buffer
  84. /// </summary>
  85. /// <param name="bufsize">Bufsize</param>
  86. public PendingBuffer(int bufsize)
  87. {
  88. buf = new byte[bufsize];
  89. }
  90. #endregion
  91. #region Reset (Public)
  92. /// <summary>
  93. /// Reset
  94. /// </summary>
  95. public void Reset()
  96. {
  97. start = end = bitCount = 0;
  98. }
  99. #endregion
  100. #region WriteByte (Public)
  101. /// <summary>
  102. /// Write byte
  103. /// </summary>
  104. /// <param name="b">B</param>
  105. public void WriteByte(int b)
  106. {
  107. buf[end++] = (byte)b;
  108. }
  109. #endregion
  110. #region WriteShort (Public)
  111. /// <summary>
  112. /// Write short
  113. /// </summary>
  114. /// <param name="s">S</param>
  115. public void WriteShort(int s)
  116. {
  117. buf[end++] = (byte)s;
  118. buf[end++] = (byte)(s >> 8);
  119. }
  120. #endregion
  121. #region WriteInt (Public)
  122. /// <summary>
  123. /// Write int
  124. /// </summary>
  125. /// <param name="s">S</param>
  126. public void WriteInt(int s)
  127. {
  128. buf[end++] = (byte)s;
  129. buf[end++] = (byte)(s >> 8);
  130. buf[end++] = (byte)(s >> 16);
  131. buf[end++] = (byte)(s >> 24);
  132. }
  133. #endregion
  134. #region WriteBlock (Public)
  135. /// <summary>
  136. /// Write block
  137. /// </summary>
  138. /// <param name="block">Block</param>
  139. /// <param name="offset">Offset</param>
  140. /// <param name="len">Len</param>
  141. public void WriteBlock(byte[] block, int offset, int len)
  142. {
  143. Array.Copy(block, offset, buf, end, len);
  144. end += len;
  145. }
  146. #endregion
  147. #region AlignToByte (Public)
  148. /// <summary>
  149. /// Align to byte
  150. /// </summary>
  151. public void AlignToByte()
  152. {
  153. if (bitCount > 0)
  154. {
  155. buf[end++] = (byte)bits;
  156. if (bitCount > 8)
  157. {
  158. buf[end++] = (byte)(bits >> 8);
  159. } // if (bitCount)
  160. } // if (bitCount)
  161. bits = 0;
  162. bitCount = 0;
  163. }
  164. #endregion
  165. #region WriteBits (Public)
  166. /// <summary>
  167. /// Write bits
  168. /// </summary>
  169. /// <param name="b">B</param>
  170. /// <param name="count">Count</param>
  171. public void WriteBits(int b, int count)
  172. {
  173. bits |= (uint)(b << bitCount);
  174. bitCount += count;
  175. if (bitCount >= 16)
  176. {
  177. buf[end++] = (byte)bits;
  178. buf[end++] = (byte)(bits >> 8);
  179. bits >>= 16;
  180. bitCount -= 16;
  181. } // if (bitCount)
  182. }
  183. #endregion
  184. #region WriteShortMsb (Public)
  185. /// <summary>
  186. /// Write short Msb
  187. /// </summary>
  188. /// <param name="s">S</param>
  189. public void WriteShortMsb(int s)
  190. {
  191. buf[end++] = (byte)(s >> 8);
  192. buf[end++] = (byte)s;
  193. }
  194. #endregion
  195. #region Flush (Public)
  196. /// <summary>
  197. /// Flushes the pending buffer into the given output array. If the
  198. /// output array is to small, only a partial flush is done.
  199. /// </summary>
  200. /// <param name="output">Output array</param>
  201. /// <param name="offset">Offset into output array</param>
  202. /// <param name="length">Length the maximum number of bytes to store
  203. /// </param>
  204. /// <exception name="ArgumentOutOfRangeException">
  205. /// IndexOutOfBoundsException if offset or length are invalid.</exception>
  206. public int Flush(byte[] output, int offset, int length)
  207. {
  208. if (bitCount >= 8)
  209. {
  210. buf[end++] = (byte)bits;
  211. bits >>= 8;
  212. bitCount -= 8;
  213. } // if (bitCount)
  214. if (length > end - start)
  215. {
  216. length = end - start;
  217. Array.Copy(buf, start, output, offset, length);
  218. start = 0;
  219. end = 0;
  220. } // if (length)
  221. else
  222. {
  223. Array.Copy(buf, start, output, offset, length);
  224. start += length;
  225. } // else
  226. return length;
  227. }
  228. #endregion
  229. #region ToByteArray (Public)
  230. /// <summary>
  231. /// To byte array
  232. /// </summary>
  233. public byte[] ToByteArray()
  234. {
  235. byte[] ret = new byte[end - start];
  236. Array.Copy(buf, start, ret, 0, ret.Length);
  237. start = 0;
  238. end = 0;
  239. return ret;
  240. }
  241. #endregion
  242. }
  243. }