--- /dev/null
+// InflaterDynHeader.cs\r
+// Copyright (C) 2001 Mike Krueger\r
+//\r
+// This file was translated from java, it was part of the GNU Classpath\r
+// Copyright (C) 2001 Free Software Foundation, Inc.\r
+//\r
+// This program is free software; you can redistribute it and/or\r
+// modify it under the terms of the GNU General Public License\r
+// as published by the Free Software Foundation; either version 2\r
+// of the License, or (at your option) any later version.\r
+//\r
+// This program is distributed in the hope that it will be useful,\r
+// but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+// GNU General Public License for more details.\r
+//\r
+// You should have received a copy of the GNU General Public License\r
+// along with this program; if not, write to the Free Software\r
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+//\r
+// Linking this library statically or dynamically with other modules is\r
+// making a combined work based on this library. Thus, the terms and\r
+// conditions of the GNU General Public License cover the whole\r
+// combination.\r
+//\r
+// As a special exception, the copyright holders of this library give you\r
+// permission to link this library with independent modules to produce an\r
+// executable, regardless of the license terms of these independent\r
+// modules, and to copy and distribute the resulting executable under\r
+// terms of your choice, provided that you also meet, for each linked\r
+// independent module, the terms and conditions of the license of that\r
+// module. An independent module is a module which is not derived from\r
+// or based on this library. If you modify this library, you may extend\r
+// this exception to your version of the library, but you are not\r
+// obligated to do so. If you do not wish to do so, delete this\r
+// exception statement from your version.\r
+\r
+using System;\r
+\r
+using ICSharpCode.SharpZipLib.Zip.Compression.Streams;\r
+\r
+namespace ICSharpCode.SharpZipLib.Zip.Compression \r
+{\r
+ \r
+ class InflaterDynHeader\r
+ {\r
+ const int LNUM = 0;\r
+ const int DNUM = 1;\r
+ const int BLNUM = 2;\r
+ const int BLLENS = 3;\r
+ const int LENS = 4;\r
+ const int REPS = 5;\r
+ \r
+ static readonly int[] repMin = { 3, 3, 11 };\r
+ static readonly int[] repBits = { 2, 3, 7 };\r
+ \r
+ byte[] blLens;\r
+ byte[] litdistLens;\r
+ \r
+ InflaterHuffmanTree blTree;\r
+ \r
+ int mode;\r
+ int lnum, dnum, blnum, num;\r
+ int repSymbol;\r
+ byte lastLen;\r
+ int ptr;\r
+ \r
+ static readonly int[] BL_ORDER = \r
+ { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };\r
+ \r
+ public InflaterDynHeader()\r
+ {\r
+ }\r
+ \r
+ public bool Decode(StreamManipulator input)\r
+ {\r
+ decode_loop:\r
+ for (;;) {\r
+ switch (mode) {\r
+ case LNUM:\r
+ lnum = input.PeekBits(5);\r
+ if (lnum < 0) {\r
+ return false;\r
+ }\r
+ lnum += 257;\r
+ input.DropBits(5);\r
+ // System.err.println("LNUM: "+lnum);\r
+ mode = DNUM;\r
+ goto case DNUM; // fall through\r
+ case DNUM:\r
+ dnum = input.PeekBits(5);\r
+ if (dnum < 0) {\r
+ return false;\r
+ }\r
+ dnum++;\r
+ input.DropBits(5);\r
+ // System.err.println("DNUM: "+dnum);\r
+ num = lnum+dnum;\r
+ litdistLens = new byte[num];\r
+ mode = BLNUM;\r
+ goto case BLNUM; // fall through\r
+ case BLNUM:\r
+ blnum = input.PeekBits(4);\r
+ if (blnum < 0) {\r
+ return false;\r
+ }\r
+ blnum += 4;\r
+ input.DropBits(4);\r
+ blLens = new byte[19];\r
+ ptr = 0;\r
+ // System.err.println("BLNUM: "+blnum);\r
+ mode = BLLENS;\r
+ goto case BLLENS; // fall through\r
+ case BLLENS:\r
+ while (ptr < blnum) {\r
+ int len = input.PeekBits(3);\r
+ if (len < 0) {\r
+ return false;\r
+ }\r
+ input.DropBits(3);\r
+ // System.err.println("blLens["+BL_ORDER[ptr]+"]: "+len);\r
+ blLens[BL_ORDER[ptr]] = (byte) len;\r
+ ptr++;\r
+ }\r
+ blTree = new InflaterHuffmanTree(blLens);\r
+ blLens = null;\r
+ ptr = 0;\r
+ mode = LENS;\r
+ goto case LENS; // fall through\r
+ case LENS: \r
+ {\r
+ int symbol;\r
+ while (((symbol = blTree.GetSymbol(input)) & ~15) == 0) {\r
+ /* Normal case: symbol in [0..15] */\r
+ \r
+ // System.err.println("litdistLens["+ptr+"]: "+symbol);\r
+ litdistLens[ptr++] = lastLen = (byte)symbol;\r
+ \r
+ if (ptr == num) {\r
+ /* Finished */\r
+ return true;\r
+ }\r
+ }\r
+ \r
+ /* need more input ? */\r
+ if (symbol < 0) {\r
+ return false;\r
+ }\r
+ \r
+ /* otherwise repeat code */\r
+ if (symbol >= 17) {\r
+ /* repeat zero */\r
+ // System.err.println("repeating zero");\r
+ lastLen = 0;\r
+ } else {\r
+ if (ptr == 0) {\r
+ throw new Exception();\r
+ }\r
+ }\r
+ repSymbol = symbol-16;\r
+ }\r
+ mode = REPS;\r
+ goto case REPS; // fall through\r
+ case REPS:\r
+ {\r
+ int bits = repBits[repSymbol];\r
+ int count = input.PeekBits(bits);\r
+ if (count < 0) {\r
+ return false;\r
+ }\r
+ input.DropBits(bits);\r
+ count += repMin[repSymbol];\r
+ // System.err.println("litdistLens repeated: "+count);\r
+ \r
+ if (ptr + count > num) {\r
+ throw new Exception();\r
+ }\r
+ while (count-- > 0) {\r
+ litdistLens[ptr++] = lastLen;\r
+ }\r
+ \r
+ if (ptr == num) {\r
+ /* Finished */\r
+ return true;\r
+ }\r
+ }\r
+ mode = LENS;\r
+ goto decode_loop;\r
+ }\r
+ }\r
+ }\r
+ \r
+ public InflaterHuffmanTree BuildLitLenTree()\r
+ {\r
+ byte[] litlenLens = new byte[lnum];\r
+ Array.Copy(litdistLens, 0, litlenLens, 0, lnum);\r
+ return new InflaterHuffmanTree(litlenLens);\r
+ }\r
+ \r
+ public InflaterHuffmanTree BuildDistTree()\r
+ {\r
+ byte[] distLens = new byte[dnum];\r
+ Array.Copy(litdistLens, lnum, distLens, 0, dnum);\r
+ return new InflaterHuffmanTree(distLens);\r
+ }\r
+ }\r
+}\r