3 // Copyright (C) 2001 Mike Krueger
\r
4 // Copyright (C) 2004 John Reilly
\r
6 // This file was translated from java, it was part of the GNU Classpath
\r
7 // Copyright (C) 2001 Free Software Foundation, Inc.
\r
9 // This program is free software; you can redistribute it and/or
\r
10 // modify it under the terms of the GNU General Public License
\r
11 // as published by the Free Software Foundation; either version 2
\r
12 // of the License, or (at your option) any later version.
\r
14 // This program is distributed in the hope that it will be useful,
\r
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
17 // GNU General Public License for more details.
\r
19 // You should have received a copy of the GNU General Public License
\r
20 // along with this program; if not, write to the Free Software
\r
21 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
23 // Linking this library statically or dynamically with other modules is
\r
24 // making a combined work based on this library. Thus, the terms and
\r
25 // conditions of the GNU General Public License cover the whole
\r
28 // As a special exception, the copyright holders of this library give you
\r
29 // permission to link this library with independent modules to produce an
\r
30 // executable, regardless of the license terms of these independent
\r
31 // modules, and to copy and distribute the resulting executable under
\r
32 // terms of your choice, provided that you also meet, for each linked
\r
33 // independent module, the terms and conditions of the license of that
\r
34 // module. An independent module is a module which is not derived from
\r
35 // or based on this library. If you modify this library, you may extend
\r
36 // this exception to your version of the library, but you are not
\r
37 // obligated to do so. If you do not wish to do so, delete this
\r
38 // exception statement from your version.
\r
42 namespace ICSharpCode.SharpZipLib.Zip.Compression
\r
46 /// This class is general purpose class for writing data to a buffer.
\r
48 /// It allows you to write bits as well as bytes
\r
49 /// Based on DeflaterPending.java
\r
51 /// author of the original java version : Jochen Hoenicke
\r
53 public class PendingBuffer
\r
55 /// <summary>Internal work buffer
\r
57 protected byte[] buf;
\r
66 /// construct instance using default buffer size of 4096
\r
68 public PendingBuffer() : this( 4096 )
\r
74 /// construct instance using specified buffer size
\r
76 /// <param name="bufsize">
\r
77 /// size to use for internal buffer
\r
79 public PendingBuffer(int bufsize)
\r
81 buf = new byte[bufsize];
\r
85 /// Clear internal state/buffers
\r
87 public void Reset()
\r
89 start = end = bitCount = 0;
\r
93 /// write a byte to buffer
\r
95 /// <param name="b">
\r
98 public void WriteByte(int b)
\r
100 if (DeflaterConstants.DEBUGGING && start != 0) {
\r
101 throw new SharpZipBaseException();
\r
103 buf[end++] = (byte) b;
\r
107 /// Write a short value to buffer LSB first
\r
109 /// <param name="s">
\r
112 public void WriteShort(int s)
\r
114 if (DeflaterConstants.DEBUGGING && start != 0) {
\r
115 throw new SharpZipBaseException();
\r
117 buf[end++] = (byte) s;
\r
118 buf[end++] = (byte) (s >> 8);
\r
122 /// write an integer LSB first
\r
124 /// <param name="s">value to write</param>
\r
125 public void WriteInt(int s)
\r
127 if (DeflaterConstants.DEBUGGING && start != 0) {
\r
128 throw new SharpZipBaseException();
\r
130 buf[end++] = (byte) s;
\r
131 buf[end++] = (byte) (s >> 8);
\r
132 buf[end++] = (byte) (s >> 16);
\r
133 buf[end++] = (byte) (s >> 24);
\r
137 /// Write a block of data to buffer
\r
139 /// <param name="block">data to write</param>
\r
140 /// <param name="offset">offset of first byte to write</param>
\r
141 /// <param name="len">number of bytes to write</param>
\r
142 public void WriteBlock(byte[] block, int offset, int len)
\r
144 if (DeflaterConstants.DEBUGGING && start != 0) {
\r
145 throw new SharpZipBaseException();
\r
147 System.Array.Copy(block, offset, buf, end, len);
\r
152 /// The number of bits written to the buffer
\r
154 public int BitCount {
\r
161 /// Align internal buffer on a byte boundary
\r
163 public void AlignToByte()
\r
165 if (DeflaterConstants.DEBUGGING && start != 0) {
\r
166 throw new SharpZipBaseException();
\r
168 if (bitCount > 0) {
\r
169 buf[end++] = (byte) bits;
\r
170 if (bitCount > 8) {
\r
171 buf[end++] = (byte) (bits >> 8);
\r
179 /// Write bits to internal buffer
\r
181 /// <param name="b">source of bits</param>
\r
182 /// <param name="count">number of bits to write</param>
\r
183 public void WriteBits(int b, int count)
\r
185 if (DeflaterConstants.DEBUGGING && start != 0) {
\r
186 throw new SharpZipBaseException();
\r
188 // if (DeflaterConstants.DEBUGGING) {
\r
189 // //Console.WriteLine("writeBits("+b+","+count+")");
\r
191 bits |= (uint)(b << bitCount);
\r
193 if (bitCount >= 16) {
\r
194 buf[end++] = (byte) bits;
\r
195 buf[end++] = (byte) (bits >> 8);
\r
202 /// Write a short value to internal buffer most significant byte first
\r
204 /// <param name="s">value to write</param>
\r
205 public void WriteShortMSB(int s)
\r
207 if (DeflaterConstants.DEBUGGING && start != 0) {
\r
208 throw new SharpZipBaseException();
\r
210 buf[end++] = (byte) (s >> 8);
\r
211 buf[end++] = (byte) s;
\r
215 /// Indicates if buffer has been flushed
\r
217 public bool IsFlushed {
\r
224 /// Flushes the pending buffer into the given output array. If the
\r
225 /// output array is to small, only a partial flush is done.
\r
227 /// <param name="output">
\r
228 /// the output array;
\r
230 /// <param name="offset">
\r
231 /// the offset into output array;
\r
233 /// <param name="length">
\r
234 /// length the maximum number of bytes to store;
\r
236 /// <exception name="ArgumentOutOfRangeException">
\r
237 /// IndexOutOfBoundsException if offset or length are invalid.
\r
239 public int Flush(byte[] output, int offset, int length)
\r
241 if (bitCount >= 8) {
\r
242 buf[end++] = (byte) bits;
\r
246 if (length > end - start) {
\r
247 length = end - start;
\r
248 System.Array.Copy(buf, start, output, offset, length);
\r
252 System.Array.Copy(buf, start, output, offset, length);
\r
259 /// Convert internal buffer to byte array.
\r
260 /// Buffer is empty on completion
\r
263 /// converted buffer contents contents
\r
265 public byte[] ToByteArray()
\r
267 byte[] ret = new byte[end - start];
\r
268 System.Array.Copy(buf, start, ret, 0, ret.Length);
\r