Statistics
| Branch: | Revision:

root / trunk / hammock / src / net35 / ICSharpCode.SharpZipLib.Silverlight / Zip / Compression / PendingBuffer.cs @ 0eea575a

History | View | Annotate | Download (8 kB)

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