* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / ICSharpCode.SharpZipLib / ICSharpCode.SharpZipLib / Zip / Compression / PendingBuffer.cs
1 // PendingBuffer.cs\r
2 //\r
3 // Copyright (C) 2001 Mike Krueger\r
4 // Copyright (C) 2004 John Reilly\r
5 //\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
8 //\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
13 //\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
18 //\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
22 //\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
26 // combination.\r
27 // \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
39 \r
40 using System;\r
41 \r
42 namespace ICSharpCode.SharpZipLib.Zip.Compression \r
43 {\r
44         \r
45         /// <summary>\r
46         /// This class is general purpose class for writing data to a buffer.\r
47         /// \r
48         /// It allows you to write bits as well as bytes\r
49         /// Based on DeflaterPending.java\r
50         /// \r
51         /// author of the original java version : Jochen Hoenicke\r
52         /// </summary>\r
53         public class PendingBuffer\r
54         {\r
55                 /// <summary>Internal work buffer\r
56                 /// </summary>\r
57                 protected byte[] buf;\r
58                 \r
59                 int    start;\r
60                 int    end;\r
61                 \r
62                 uint    bits;\r
63                 int    bitCount;\r
64 \r
65                 /// <summary>\r
66                 /// construct instance using default buffer size of 4096\r
67                 /// </summary>\r
68                 public PendingBuffer() : this( 4096 )\r
69                 {\r
70                         \r
71                 }\r
72                 \r
73                 /// <summary>\r
74                 /// construct instance using specified buffer size\r
75                 /// </summary>\r
76                 /// <param name="bufsize">\r
77                 /// size to use for internal buffer\r
78                 /// </param>\r
79                 public PendingBuffer(int bufsize)\r
80                 {\r
81                         buf = new byte[bufsize];\r
82                 }\r
83 \r
84                 /// <summary>\r
85                 /// Clear internal state/buffers\r
86                 /// </summary>\r
87                 public void Reset() \r
88                 {\r
89                         start = end = bitCount = 0;\r
90                 }\r
91 \r
92                 /// <summary>\r
93                 /// write a byte to buffer\r
94                 /// </summary>\r
95                 /// <param name="b">\r
96                 /// value to write\r
97                 /// </param>\r
98                 public void WriteByte(int b)\r
99                 {\r
100                         if (DeflaterConstants.DEBUGGING && start != 0) {\r
101                                 throw new SharpZipBaseException();\r
102                         }\r
103                         buf[end++] = (byte) b;\r
104                 }\r
105 \r
106                 /// <summary>\r
107                 /// Write a short value to buffer LSB first\r
108                 /// </summary>\r
109                 /// <param name="s">\r
110                 /// value to write\r
111                 /// </param>\r
112                 public void WriteShort(int s)\r
113                 {\r
114                         if (DeflaterConstants.DEBUGGING && start != 0) {\r
115                                 throw new SharpZipBaseException();\r
116                         }\r
117                         buf[end++] = (byte) s;\r
118                         buf[end++] = (byte) (s >> 8);\r
119                 }\r
120 \r
121                 /// <summary>\r
122                 /// write an integer LSB first\r
123                 /// </summary>\r
124                 /// <param name="s">value to write</param>\r
125                 public void WriteInt(int s)\r
126                 {\r
127                         if (DeflaterConstants.DEBUGGING && start != 0) {\r
128                                 throw new SharpZipBaseException();\r
129                         }\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
134                 }\r
135                 \r
136                 /// <summary>\r
137                 /// Write a block of data to buffer\r
138                 /// </summary>\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
143                 {\r
144                         if (DeflaterConstants.DEBUGGING && start != 0) {\r
145                                 throw new SharpZipBaseException();\r
146                         }\r
147                         System.Array.Copy(block, offset, buf, end, len);\r
148                         end += len;\r
149                 }\r
150 \r
151                 /// <summary>\r
152                 /// The number of bits written to the buffer\r
153                 /// </summary>\r
154                 public int BitCount {\r
155                         get {\r
156                                 return bitCount;\r
157                         }\r
158                 }\r
159                 \r
160                 /// <summary>\r
161                 /// Align internal buffer on a byte boundary\r
162                 /// </summary>\r
163                 public void AlignToByte() \r
164                 {\r
165                         if (DeflaterConstants.DEBUGGING && start != 0) {\r
166                                 throw new SharpZipBaseException();\r
167                         }\r
168                         if (bitCount > 0) {\r
169                                 buf[end++] = (byte) bits;\r
170                                 if (bitCount > 8) {\r
171                                         buf[end++] = (byte) (bits >> 8);\r
172                                 }\r
173                         }\r
174                         bits = 0;\r
175                         bitCount = 0;\r
176                 }\r
177 \r
178                 /// <summary>\r
179                 /// Write bits to internal buffer\r
180                 /// </summary>\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
184                 {\r
185                         if (DeflaterConstants.DEBUGGING && start != 0) {\r
186                                 throw new SharpZipBaseException();\r
187                         }\r
188                         //                      if (DeflaterConstants.DEBUGGING) {\r
189                         //                              //Console.WriteLine("writeBits("+b+","+count+")");\r
190                         //                      }\r
191                         bits |= (uint)(b << bitCount);\r
192                         bitCount += count;\r
193                         if (bitCount >= 16) {\r
194                                 buf[end++] = (byte) bits;\r
195                                 buf[end++] = (byte) (bits >> 8);\r
196                                 bits >>= 16;\r
197                                 bitCount -= 16;\r
198                         }\r
199                 }\r
200 \r
201                 /// <summary>\r
202                 /// Write a short value to internal buffer most significant byte first\r
203                 /// </summary>\r
204                 /// <param name="s">value to write</param>\r
205                 public void WriteShortMSB(int s) \r
206                 {\r
207                         if (DeflaterConstants.DEBUGGING && start != 0) {\r
208                                 throw new SharpZipBaseException();\r
209                         }\r
210                         buf[end++] = (byte) (s >> 8);\r
211                         buf[end++] = (byte) s;\r
212                 }\r
213                 \r
214                 /// <summary>\r
215                 /// Indicates if buffer has been flushed\r
216                 /// </summary>\r
217                 public bool IsFlushed {\r
218                         get {\r
219                                 return end == 0;\r
220                         }\r
221                 }\r
222                 \r
223                 /// <summary>\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
226                 /// </summary>\r
227                 /// <param name="output">\r
228                 /// the output array;\r
229                 /// </param>\r
230                 /// <param name="offset">\r
231                 /// the offset into output array;\r
232                 /// </param>\r
233                 /// <param name="length">               \r
234                 /// length the maximum number of bytes to store;\r
235                 /// </param>\r
236                 /// <exception name="ArgumentOutOfRangeException">\r
237                 /// IndexOutOfBoundsException if offset or length are invalid.\r
238                 /// </exception>\r
239                 public int Flush(byte[] output, int offset, int length) \r
240                 {\r
241                         if (bitCount >= 8) {\r
242                                 buf[end++] = (byte) bits;\r
243                                 bits >>= 8;\r
244                                 bitCount -= 8;\r
245                         }\r
246                         if (length > end - start) {\r
247                                 length = end - start;\r
248                                 System.Array.Copy(buf, start, output, offset, length);\r
249                                 start = 0;\r
250                                 end = 0;\r
251                         } else {\r
252                                 System.Array.Copy(buf, start, output, offset, length);\r
253                                 start += length;\r
254                         }\r
255                         return length;\r
256                 }\r
257 \r
258                 /// <summary>\r
259                 /// Convert internal buffer to byte array.\r
260                 /// Buffer is empty on completion\r
261                 /// </summary>\r
262                 /// <returns>\r
263                 /// converted buffer contents contents\r
264                 /// </returns>\r
265                 public byte[] ToByteArray()\r
266                 {\r
267                         byte[] ret = new byte[end - start];\r
268                         System.Array.Copy(buf, start, ret, 0, ret.Length);\r
269                         start = 0;\r
270                         end = 0;\r
271                         return ret;\r
272                 }\r
273         }\r
274 }       \r