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

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

re #165

RevLine 
[597]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
38using System;
39
40using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
41
42namespace 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                int mode;
208                int lnum, dnum, blnum, num;
209                int repSymbol;
210                byte lastLen;
211                int ptr;
212                #endregion
213
214        }
215}
Notatka: Zobacz TracBrowser aby uzyskać więcej informacji.