| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 | using System;using ICSharpCode.SharpZipLib.Zip.Compression.Streams;namespace ICSharpCode.SharpZipLib.Zip.Compression{	class InflaterDynHeader	{		#region Constants		const int LNUM = 0;		const int DNUM = 1;		const int BLNUM = 2;		const int BLLENS = 3;		const int LENS = 4;		const int REPS = 5;		static readonly int[] repMin = { 3, 3, 11 };		static readonly int[] repBits = { 2, 3, 7 };		static readonly int[] BL_ORDER =		{ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };		#endregion		public bool Decode(StreamManipulator input)		{			decode_loop:			for (;;) {				switch (mode) {					case LNUM:						lnum = input.PeekBits(5);						if (lnum < 0) {							return false;						}						lnum += 257;						input.DropBits(5);						//  	    System.err.println("LNUM: "+lnum);						mode = DNUM;						goto case DNUM; // fall through					case DNUM:						dnum = input.PeekBits(5);						if (dnum < 0) {							return false;						}						dnum++;						input.DropBits(5);						//  	    System.err.println("DNUM: "+dnum);						num = lnum + dnum;						litdistLens = new byte[num];						mode = BLNUM;						goto case BLNUM; // fall through					case BLNUM:						blnum = input.PeekBits(4);						if (blnum < 0) {							return false;						}						blnum += 4;						input.DropBits(4);						blLens = new byte[19];						ptr = 0;						//  	    System.err.println("BLNUM: "+blnum);						mode = BLLENS;						goto case BLLENS; // fall through					case BLLENS:						while (ptr < blnum) {							int len = input.PeekBits(3);							if (len < 0) {								return false;							}							input.DropBits(3);							//  		System.err.println("blLens["+BL_ORDER[ptr]+"]: "+len);							blLens[BL_ORDER[ptr]] = (byte)len;							ptr++;						}						blTree = new InflaterHuffmanTree(blLens);						blLens = null;						ptr = 0;						mode = LENS;						goto case LENS; // fall through					case LENS: {							int symbol;							while (((symbol = blTree.GetSymbol(input)) & ~15) == 0) {								/* Normal case: symbol in [0..15] */								//  		  System.err.println("litdistLens["+ptr+"]: "+symbol);								litdistLens[ptr++] = lastLen = (byte)symbol;								if (ptr == num) {									/* Finished */									return true;								}							}							/* need more input ? */							if (symbol < 0) {								return false;							}							/* otherwise repeat code */							if (symbol >= 17) {								/* repeat zero */								//  		  System.err.println("repeating zero");								lastLen = 0;							} else {								if (ptr == 0) {									throw new SharpZipBaseException();								}							}							repSymbol = symbol - 16;						}						mode = REPS;						goto case REPS; // fall through					case REPS: {							int bits = repBits[repSymbol];							int count = input.PeekBits(bits);							if (count < 0) {								return false;							}							input.DropBits(bits);							count += repMin[repSymbol];							//  	      System.err.println("litdistLens repeated: "+count);							if (ptr + count > num) {								throw new SharpZipBaseException();							}							while (count-- > 0) {								litdistLens[ptr++] = lastLen;							}							if (ptr == num) {								/* Finished */								return true;							}						}						mode = LENS;						goto decode_loop;				}			}		}		public InflaterHuffmanTree BuildLitLenTree()		{			byte[] litlenLens = new byte[lnum];			Array.Copy(litdistLens, 0, litlenLens, 0, lnum);			return new InflaterHuffmanTree(litlenLens);		}		public InflaterHuffmanTree BuildDistTree()		{			byte[] distLens = new byte[dnum];			Array.Copy(litdistLens, lnum, distLens, 0, dnum);			return new InflaterHuffmanTree(distLens);		}		#region Instance Fields		byte[] blLens;		byte[] litdistLens;		InflaterHuffmanTree blTree;		/// <summary>		/// The current decode mode		/// </summary>		int mode;		int lnum, dnum, blnum, num;		int repSymbol;		byte lastLen;		int ptr;		#endregion	}}
 |