Mercurial > repos > SharpZipLib
comparison Zip/Compression/InflaterDynHeader.cs @ 1:94e25b786321
Re #311: can't read ZIP file packed by Linux app Archive Manager/File Roller
Initial commit of clean SharpZipLib 0860 source. Only change is build paths.
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sat, 30 Oct 2010 14:03:17 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:d16ef17fa7bb | 1:94e25b786321 |
---|---|
1 // InflaterDynHeader.cs | |
2 // Copyright (C) 2001 Mike Krueger | |
3 // | |
4 // This file was translated from java, it was part of the GNU Classpath | |
5 // Copyright (C) 2001 Free Software Foundation, Inc. | |
6 // | |
7 // This program is free software; you can redistribute it and/or | |
8 // modify it under the terms of the GNU General Public License | |
9 // as published by the Free Software Foundation; either version 2 | |
10 // of the License, or (at your option) any later version. | |
11 // | |
12 // This program is distributed in the hope that it will be useful, | |
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 // GNU General Public License for more details. | |
16 // | |
17 // You should have received a copy of the GNU General Public License | |
18 // along with this program; if not, write to the Free Software | |
19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
20 // | |
21 // Linking this library statically or dynamically with other modules is | |
22 // making a combined work based on this library. Thus, the terms and | |
23 // conditions of the GNU General Public License cover the whole | |
24 // combination. | |
25 // | |
26 // As a special exception, the copyright holders of this library give you | |
27 // permission to link this library with independent modules to produce an | |
28 // executable, regardless of the license terms of these independent | |
29 // modules, and to copy and distribute the resulting executable under | |
30 // terms of your choice, provided that you also meet, for each linked | |
31 // independent module, the terms and conditions of the license of that | |
32 // module. An independent module is a module which is not derived from | |
33 // or based on this library. If you modify this library, you may extend | |
34 // this exception to your version of the library, but you are not | |
35 // obligated to do so. If you do not wish to do so, delete this | |
36 // exception statement from your version. | |
37 | |
38 using System; | |
39 | |
40 using ICSharpCode.SharpZipLib.Zip.Compression.Streams; | |
41 | |
42 namespace ICSharpCode.SharpZipLib.Zip.Compression | |
43 { | |
44 | |
45 class InflaterDynHeader | |
46 { | |
47 #region Constants | |
48 const int LNUM = 0; | |
49 const int DNUM = 1; | |
50 const int BLNUM = 2; | |
51 const int BLLENS = 3; | |
52 const int LENS = 4; | |
53 const int REPS = 5; | |
54 | |
55 static readonly int[] repMin = { 3, 3, 11 }; | |
56 static readonly int[] repBits = { 2, 3, 7 }; | |
57 | |
58 static readonly int[] BL_ORDER = | |
59 { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; | |
60 | |
61 #endregion | |
62 | |
63 #region Constructors | |
64 public InflaterDynHeader() | |
65 { | |
66 } | |
67 #endregion | |
68 | |
69 public bool Decode(StreamManipulator input) | |
70 { | |
71 decode_loop: | |
72 for (;;) { | |
73 switch (mode) { | |
74 case LNUM: | |
75 lnum = input.PeekBits(5); | |
76 if (lnum < 0) { | |
77 return false; | |
78 } | |
79 lnum += 257; | |
80 input.DropBits(5); | |
81 // System.err.println("LNUM: "+lnum); | |
82 mode = DNUM; | |
83 goto case DNUM; // fall through | |
84 case DNUM: | |
85 dnum = input.PeekBits(5); | |
86 if (dnum < 0) { | |
87 return false; | |
88 } | |
89 dnum++; | |
90 input.DropBits(5); | |
91 // System.err.println("DNUM: "+dnum); | |
92 num = lnum+dnum; | |
93 litdistLens = new byte[num]; | |
94 mode = BLNUM; | |
95 goto case BLNUM; // fall through | |
96 case BLNUM: | |
97 blnum = input.PeekBits(4); | |
98 if (blnum < 0) { | |
99 return false; | |
100 } | |
101 blnum += 4; | |
102 input.DropBits(4); | |
103 blLens = new byte[19]; | |
104 ptr = 0; | |
105 // System.err.println("BLNUM: "+blnum); | |
106 mode = BLLENS; | |
107 goto case BLLENS; // fall through | |
108 case BLLENS: | |
109 while (ptr < blnum) { | |
110 int len = input.PeekBits(3); | |
111 if (len < 0) { | |
112 return false; | |
113 } | |
114 input.DropBits(3); | |
115 // System.err.println("blLens["+BL_ORDER[ptr]+"]: "+len); | |
116 blLens[BL_ORDER[ptr]] = (byte) len; | |
117 ptr++; | |
118 } | |
119 blTree = new InflaterHuffmanTree(blLens); | |
120 blLens = null; | |
121 ptr = 0; | |
122 mode = LENS; | |
123 goto case LENS; // fall through | |
124 case LENS: | |
125 { | |
126 int symbol; | |
127 while (((symbol = blTree.GetSymbol(input)) & ~15) == 0) { | |
128 /* Normal case: symbol in [0..15] */ | |
129 | |
130 // System.err.println("litdistLens["+ptr+"]: "+symbol); | |
131 litdistLens[ptr++] = lastLen = (byte)symbol; | |
132 | |
133 if (ptr == num) { | |
134 /* Finished */ | |
135 return true; | |
136 } | |
137 } | |
138 | |
139 /* need more input ? */ | |
140 if (symbol < 0) { | |
141 return false; | |
142 } | |
143 | |
144 /* otherwise repeat code */ | |
145 if (symbol >= 17) { | |
146 /* repeat zero */ | |
147 // System.err.println("repeating zero"); | |
148 lastLen = 0; | |
149 } else { | |
150 if (ptr == 0) { | |
151 throw new SharpZipBaseException(); | |
152 } | |
153 } | |
154 repSymbol = symbol-16; | |
155 } | |
156 mode = REPS; | |
157 goto case REPS; // fall through | |
158 case REPS: | |
159 { | |
160 int bits = repBits[repSymbol]; | |
161 int count = input.PeekBits(bits); | |
162 if (count < 0) { | |
163 return false; | |
164 } | |
165 input.DropBits(bits); | |
166 count += repMin[repSymbol]; | |
167 // System.err.println("litdistLens repeated: "+count); | |
168 | |
169 if (ptr + count > num) { | |
170 throw new SharpZipBaseException(); | |
171 } | |
172 while (count-- > 0) { | |
173 litdistLens[ptr++] = lastLen; | |
174 } | |
175 | |
176 if (ptr == num) { | |
177 /* Finished */ | |
178 return true; | |
179 } | |
180 } | |
181 mode = LENS; | |
182 goto decode_loop; | |
183 } | |
184 } | |
185 } | |
186 | |
187 public InflaterHuffmanTree BuildLitLenTree() | |
188 { | |
189 byte[] litlenLens = new byte[lnum]; | |
190 Array.Copy(litdistLens, 0, litlenLens, 0, lnum); | |
191 return new InflaterHuffmanTree(litlenLens); | |
192 } | |
193 | |
194 public InflaterHuffmanTree BuildDistTree() | |
195 { | |
196 byte[] distLens = new byte[dnum]; | |
197 Array.Copy(litdistLens, lnum, distLens, 0, dnum); | |
198 return new InflaterHuffmanTree(distLens); | |
199 } | |
200 | |
201 #region Instance Fields | |
202 byte[] blLens; | |
203 byte[] litdistLens; | |
204 | |
205 InflaterHuffmanTree blTree; | |
206 | |
207 /// <summary> | |
208 /// The current decode mode | |
209 /// </summary> | |
210 int mode; | |
211 int lnum, dnum, blnum, num; | |
212 int repSymbol; | |
213 byte lastLen; | |
214 int ptr; | |
215 #endregion | |
216 | |
217 } | |
218 } |