public GetSymbol ( |
||
input | /// input the input source. /// | |
리턴 | int |
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); mode = DNUM; goto case 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; goto case 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; goto case 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; goto case 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 SharpZipBaseException(); } } repSymbol = symbol-16; } mode = REPS; goto case 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 SharpZipBaseException(); } while (count-- > 0) { litdistLens[ptr++] = lastLen; } if (ptr == num) { return true; } } mode = LENS; goto decode_loop; } } }
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; } } }
/// <summary> /// Decodes the huffman encoded symbols in the input stream. /// </summary> /// <returns> /// false if more input is needed, true if output window is /// full or the current block ends. /// </returns> /// <exception cref="SharpZipBaseException"> /// if deflated stream is invalid. /// </exception> private bool DecodeHuffman() { int free = outputWindow.GetFreeSpace(); while (free >= 258) { int symbol; switch (mode) { case DECODE_HUFFMAN: // This is the inner loop so it is optimized a bit while (((symbol = litlenTree.GetSymbol(input)) & ~0xff) == 0) { outputWindow.Write(symbol); if (--free < 258) { return(true); } } if (symbol < 257) { if (symbol < 0) { return(false); } else { // symbol == 256: end of block distTree = null; litlenTree = null; mode = DECODE_BLOCKS; return(true); } } try { repLength = CPLENS[symbol - 257]; neededBits = CPLEXT[symbol - 257]; } catch (Exception) { throw new SharpZipBaseException("Illegal rep length code"); } goto case DECODE_HUFFMAN_LENBITS; // fall through case DECODE_HUFFMAN_LENBITS: if (neededBits > 0) { mode = DECODE_HUFFMAN_LENBITS; int i = input.PeekBits(neededBits); if (i < 0) { return(false); } input.DropBits(neededBits); repLength += i; } mode = DECODE_HUFFMAN_DIST; goto case DECODE_HUFFMAN_DIST; // fall through case DECODE_HUFFMAN_DIST: symbol = distTree.GetSymbol(input); if (symbol < 0) { return(false); } try { repDist = CPDIST[symbol]; neededBits = CPDEXT[symbol]; } catch (Exception) { throw new SharpZipBaseException("Illegal rep dist code"); } goto case DECODE_HUFFMAN_DISTBITS; // fall through case DECODE_HUFFMAN_DISTBITS: if (neededBits > 0) { mode = DECODE_HUFFMAN_DISTBITS; int i = input.PeekBits(neededBits); if (i < 0) { return(false); } input.DropBits(neededBits); repDist += i; } outputWindow.Repeat(repLength, repDist); free -= repLength; mode = DECODE_HUFFMAN; break; default: throw new SharpZipBaseException("Inflater unknown mode"); } } return(true); }