root/trunk/Updater/ICSharpCode.SharpZipLib/Zip/Compression/PendingBuffer.cs @ 597

Wersja 597, 8.2 KB (wprowadzona przez marek, 17 years temu)

re #165

Line 
1// PendingBuffer.cs
2//
3// Copyright (C) 2001 Mike Krueger
4// Copyright (C) 2004 John Reilly
5//
6// This file was translated from java, it was part of the GNU Classpath
7// Copyright (C) 2001 Free Software Foundation, Inc.
8//
9// This program is free software; you can redistribute it and/or
10// modify it under the terms of the GNU General Public License
11// as published by the Free Software Foundation; either version 2
12// of the License, or (at your option) any later version.
13//
14// This program is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17// GNU General Public License for more details.
18//
19// You should have received a copy of the GNU General Public License
20// along with this program; if not, write to the Free Software
21// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22//
23// Linking this library statically or dynamically with other modules is
24// making a combined work based on this library.  Thus, the terms and
25// conditions of the GNU General Public License cover the whole
26// combination.
27//
28// As a special exception, the copyright holders of this library give you
29// permission to link this library with independent modules to produce an
30// executable, regardless of the license terms of these independent
31// modules, and to copy and distribute the resulting executable under
32// terms of your choice, provided that you also meet, for each linked
33// independent module, the terms and conditions of the license of that
34// module.  An independent module is a module which is not derived from
35// or based on this library.  If you modify this library, you may extend
36// this exception to your version of the library, but you are not
37// obligated to do so.  If you do not wish to do so, delete this
38// exception statement from your version.
39
40using System;
41
42namespace ICSharpCode.SharpZipLib.Zip.Compression
43{
44       
45        /// <summary>
46        /// This class is general purpose class for writing data to a buffer.
47        ///
48        /// It allows you to write bits as well as bytes
49        /// Based on DeflaterPending.java
50        ///
51        /// author of the original java version : Jochen Hoenicke
52        /// </summary>
53        public class PendingBuffer
54        {
55                #region Instance Fields
56                /// <summary>
57                /// Internal work buffer
58                /// </summary>
59                byte[] buffer_;
60               
61                int    start;
62                int    end;
63               
64                uint   bits;
65                int    bitCount;
66                #endregion
67
68                #region Constructors
69                /// <summary>
70                /// construct instance using default buffer size of 4096
71                /// </summary>
72                public PendingBuffer() : this( 4096 )
73                {
74                }
75               
76                /// <summary>
77                /// construct instance using specified buffer size
78                /// </summary>
79                /// <param name="bufferSize">
80                /// size to use for internal buffer
81                /// </param>
82                public PendingBuffer(int bufferSize)
83                {
84                        buffer_ = new byte[bufferSize];
85                }
86
87                #endregion
88
89                /// <summary>
90                /// Clear internal state/buffers
91                /// </summary>
92                public void Reset()
93                {
94                        start = end = bitCount = 0;
95                }
96
97                /// <summary>
98                /// Write a byte to buffer
99                /// </summary>
100                /// <param name="value">
101                /// The value to write
102                /// </param>
103                public void WriteByte(int value)
104                {
105#if DebugDeflation
106                        if (DeflaterConstants.DEBUGGING && (start != 0) )
107                        {
108                                throw new SharpZipBaseException("Debug check: start != 0");
109                        }
110#endif
111                        buffer_[end++] = unchecked((byte) value);
112                }
113
114                /// <summary>
115                /// Write a short value to buffer LSB first
116                /// </summary>
117                /// <param name="value">
118                /// The value to write.
119                /// </param>
120                public void WriteShort(int value)
121                {
122#if DebugDeflation
123                        if (DeflaterConstants.DEBUGGING && (start != 0) )
124                        {
125                                throw new SharpZipBaseException("Debug check: start != 0");
126                        }
127#endif
128                        buffer_[end++] = unchecked((byte) value);
129                        buffer_[end++] = unchecked((byte) (value >> 8));
130                }
131
132                /// <summary>
133                /// write an integer LSB first
134                /// </summary>
135                /// <param name="value">The value to write.</param>
136                public void WriteInt(int value)
137                {
138#if DebugDeflation
139                        if (DeflaterConstants.DEBUGGING && (start != 0) )
140                        {
141                                throw new SharpZipBaseException("Debug check: start != 0");
142                        }
143#endif
144                        buffer_[end++] = unchecked((byte) value);
145                        buffer_[end++] = unchecked((byte) (value >> 8));
146                        buffer_[end++] = unchecked((byte) (value >> 16));
147                        buffer_[end++] = unchecked((byte) (value >> 24));
148                }
149               
150                /// <summary>
151                /// Write a block of data to buffer
152                /// </summary>
153                /// <param name="block">data to write</param>
154                /// <param name="offset">offset of first byte to write</param>
155                /// <param name="length">number of bytes to write</param>
156                public void WriteBlock(byte[] block, int offset, int length)
157                {
158#if DebugDeflation
159                        if (DeflaterConstants.DEBUGGING && (start != 0) )
160                        {
161                                throw new SharpZipBaseException("Debug check: start != 0");
162                        }
163#endif
164                        System.Array.Copy(block, offset, buffer_, end, length);
165                        end += length;
166                }
167
168                /// <summary>
169                /// The number of bits written to the buffer
170                /// </summary>
171                public int BitCount {
172                        get {
173                                return bitCount;
174                        }
175                }
176               
177                /// <summary>
178                /// Align internal buffer on a byte boundary
179                /// </summary>
180                public void AlignToByte()
181                {
182#if DebugDeflation
183                        if (DeflaterConstants.DEBUGGING && (start != 0) )
184                        {
185                                throw new SharpZipBaseException("Debug check: start != 0");
186                        }
187#endif
188                        if (bitCount > 0)
189                        {
190                                buffer_[end++] = unchecked((byte) bits);
191                                if (bitCount > 8) {
192                                        buffer_[end++] = unchecked((byte) (bits >> 8));
193                                }
194                        }
195                        bits = 0;
196                        bitCount = 0;
197                }
198
199                /// <summary>
200                /// Write bits to internal buffer
201                /// </summary>
202                /// <param name="b">source of bits</param>
203                /// <param name="count">number of bits to write</param>
204                public void WriteBits(int b, int count)
205                {
206#if DebugDeflation
207                        if (DeflaterConstants.DEBUGGING && (start != 0) )
208                        {
209                                throw new SharpZipBaseException("Debug check: start != 0");
210                        }
211
212                        //                      if (DeflaterConstants.DEBUGGING) {
213                        //                              //Console.WriteLine("writeBits("+b+","+count+")");
214                        //                      }
215#endif
216                        bits |= (uint)(b << bitCount);
217                        bitCount += count;
218                        if (bitCount >= 16) {
219                                buffer_[end++] = unchecked((byte) bits);
220                                buffer_[end++] = unchecked((byte) (bits >> 8));
221                                bits >>= 16;
222                                bitCount -= 16;
223                        }
224                }
225
226                /// <summary>
227                /// Write a short value to internal buffer most significant byte first
228                /// </summary>
229                /// <param name="s">value to write</param>
230                public void WriteShortMSB(int s)
231                {
232#if DebugDeflation
233                        if (DeflaterConstants.DEBUGGING && (start != 0) )
234                        {
235                                throw new SharpZipBaseException("Debug check: start != 0");
236                        }
237#endif
238                        buffer_[end++] = unchecked((byte) (s >> 8));
239                        buffer_[end++] = unchecked((byte) s);
240                }
241               
242                /// <summary>
243                /// Indicates if buffer has been flushed
244                /// </summary>
245                public bool IsFlushed {
246                        get {
247                                return end == 0;
248                        }
249                }
250               
251                /// <summary>
252                /// Flushes the pending buffer into the given output array.  If the
253                /// output array is to small, only a partial flush is done.
254                /// </summary>
255                /// <param name="output">The output array.</param>
256                /// <param name="offset">The offset into output array.</param>
257                /// <param name="length">The maximum number of bytes to store.</param>
258                /// <returns>The number of bytes flushed.</returns>
259                public int Flush(byte[] output, int offset, int length)
260                {
261                        if (bitCount >= 8) {
262                                buffer_[end++] = unchecked((byte) bits);
263                                bits >>= 8;
264                                bitCount -= 8;
265                        }
266
267                        if (length > end - start) {
268                                length = end - start;
269                                System.Array.Copy(buffer_, start, output, offset, length);
270                                start = 0;
271                                end = 0;
272                        } else {
273                                System.Array.Copy(buffer_, start, output, offset, length);
274                                start += length;
275                        }
276                        return length;
277                }
278
279                /// <summary>
280                /// Convert internal buffer to byte array.
281                /// Buffer is empty on completion
282                /// </summary>
283                /// <returns>
284                /// The internal buffer contents converted to a byte array.
285                /// </returns>
286                public byte[] ToByteArray()
287                {
288                        byte[] result = new byte[end - start];
289                        System.Array.Copy(buffer_, start, result, 0, result.Length);
290                        start = 0;
291                        end = 0;
292                        return result;
293                }
294        }
295}       
Notatka: Zobacz TracBrowser aby uzyskać więcej informacji.