// package net.sf.zipme; class InflaterDynHeader { private static final int LNUM=0; private static final int DNUM=1; private static final int BLNUM=2; private static final int BLLENS=3; private static final int LENS=4; private static final int REPS=5; private static final int repMin[]={3,3,11}; private static final int repBits[]={2,3,7}; private byte[] blLens; private byte[] litdistLens; private InflaterHuffmanTree blTree; private int mode; private int lnum, dnum, blnum, num; private int repSymbol; private byte lastLen; private int ptr; private static final int[] BL_ORDER={16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; public InflaterDynHeader(){ } public boolean decode( StreamManipulator input) throws DataFormatException { decode_loop: for (; ; ) { switch (mode) { case LNUM: lnum=input.peekBits(5); if (lnum < 0) return false; lnum+=257; input.dropBits(5); mode=DNUM; case DNUM: dnum=input.peekBits(5); if (dnum < 0) return false; dnum++; input.dropBits(5); num=lnum + dnum; litdistLens=new byte[num]; mode=BLNUM; case BLNUM: blnum=input.peekBits(4); if (blnum < 0) return false; blnum+=4; input.dropBits(4); blLens=new byte[19]; ptr=0; mode=BLLENS; case BLLENS: while (ptr < blnum) { int len=input.peekBits(3); if (len < 0) return false; input.dropBits(3); blLens[BL_ORDER[ptr]]=(byte)len; ptr++; } blTree=new InflaterHuffmanTree(blLens); blLens=null; ptr=0; mode=LENS; case LENS: { int symbol; while (((symbol=blTree.getSymbol(input)) & ~15) == 0) { litdistLens[ptr++]=lastLen=(byte)symbol; if (ptr == num) { return true; } } if (symbol < 0) return false; if (symbol >= 17) { lastLen=0; } else { if (ptr == 0) throw new DataFormatException(); } repSymbol=symbol - 16; mode=REPS; } case REPS: { int bits=repBits[repSymbol]; int count=input.peekBits(bits); if (count < 0) return false; input.dropBits(bits); count+=repMin[repSymbol]; if (ptr + count > num) throw new DataFormatException(); while (count-- > 0) litdistLens[ptr++]=lastLen; if (ptr == num) { return true; } } mode=LENS; continue decode_loop; } } } public InflaterHuffmanTree buildLitLenTree() throws DataFormatException { byte[] litlenLens=new byte[lnum]; System.arraycopy(litdistLens,0,litlenLens,0,lnum); return new InflaterHuffmanTree(litlenLens); } public InflaterHuffmanTree buildDistTree() throws DataFormatException { byte[] distLens=new byte[dnum]; System.arraycopy(litdistLens,lnum,distLens,0,dnum); return new InflaterHuffmanTree(distLens); } }