PageRenderTime 123ms CodeModel.GetById 60ms app.highlight 8ms RepoModel.GetById 52ms app.codeStats 1ms

/Utilities/Compression/PendingBuffer.cs

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