/// <param name="r"> /// </param><returns></returns> internal int Process(int r) { // copy input/output information to locals (UPDATE macro restores) int p = this.Codec.NextIn; int n = this.Codec.AvailableBytesIn; int b = this.Bitb; int k = this.Bitk; int q = this.WriteAt; int m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q; // process input based on current state while (true) { int t; // temporary storage switch (this.mode) { case InflateBlockMode.Type: while (k < 3) { if (n != 0) { r = ZlibConstants.Zok; } else { this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } n--; b |= (this.Codec.InputBuffer[p++] & 0xff) << k; k += 8; } t = b & 7; this.last = t & 1; switch ((uint)t >> 1) { case 0: // stored b >>= 3; k -= 3; t = k & 7; // go to byte boundary b >>= t; k -= t; this.mode = InflateBlockMode.Lens; // get length of stored block break; case 1: // fixed var bl = new int[1]; var bd = new int[1]; var tl = new int[1][]; var td = new int[1][]; InfTree.InflateTreesFixed(bl, bd, tl, td); this.codes.Init(bl[0], bd[0], tl[0], 0, td[0], 0); b >>= 3; k -= 3; this.mode = InflateBlockMode.Codes; break; case 2: // dynamic b >>= 3; k -= 3; this.mode = InflateBlockMode.Table; break; case 3: // illegal b >>= 3; k -= 3; this.mode = InflateBlockMode.Bad; this.Codec.Message = "invalid block type"; r = ZlibConstants.ZDataError; this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } break; case InflateBlockMode.Lens: while (k < 32) { if (n != 0) { r = ZlibConstants.Zok; } else { this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } n--; b |= (this.Codec.InputBuffer[p++] & 0xff) << k; k += 8; } if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) { this.mode = InflateBlockMode.Bad; this.Codec.Message = "invalid stored block lengths"; r = ZlibConstants.ZDataError; this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } this.left = b & 0xffff; b = k = 0; // dump bits this.mode = this.left != 0 ? InflateBlockMode.Stored : (this.last != 0 ? InflateBlockMode.Dry : InflateBlockMode.Type); break; case InflateBlockMode.Stored: if (n == 0) { this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } if (m == 0) { if (q == this.End && this.ReadAt != 0) { q = 0; m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q; } if (m == 0) { this.WriteAt = q; r = this.Flush(r); q = this.WriteAt; m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q; if (q == this.End && this.ReadAt != 0) { q = 0; m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q; } if (m == 0) { this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } } } r = ZlibConstants.Zok; t = this.left; if (t > n) { t = n; } if (t > m) { t = m; } Array.Copy(this.Codec.InputBuffer, p, this.Window, q, t); p += t; n -= t; q += t; m -= t; if ((this.left -= t) != 0) { break; } this.mode = this.last != 0 ? InflateBlockMode.Dry : InflateBlockMode.Type; break; case InflateBlockMode.Table: while (k < 14) { if (n != 0) { r = ZlibConstants.Zok; } else { this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } n--; b |= (this.Codec.InputBuffer[p++] & 0xff) << k; k += 8; } this.table = t = b & 0x3fff; if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) { this.mode = InflateBlockMode.Bad; this.Codec.Message = "too many length or distance symbols"; r = ZlibConstants.ZDataError; this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); if (this.blens == null || this.blens.Length < t) { this.blens = new int[t]; } else { Array.Clear(this.blens, 0, t); // for (int i = 0; i < t; i++) { blens[i] = 0; } } b >>= 14; k -= 14; this.index = 0; this.mode = InflateBlockMode.Btree; goto case InflateBlockMode.Btree; case InflateBlockMode.Btree: while (this.index < 4 + (this.table >> 10)) { while (k < 3) { if (n != 0) { r = ZlibConstants.Zok; } else { this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } n--; b |= (this.Codec.InputBuffer[p++] & 0xff) << k; k += 8; } this.blens[Border[this.index++]] = b & 7; b >>= 3; k -= 3; } while (this.index < 19) { this.blens[Border[this.index++]] = 0; } this.bb[0] = 7; t = this.inftree.InflateTreesBits(this.blens, this.bb, this.tb, this.hufts, this.Codec); if (t != ZlibConstants.Zok) { r = t; if (r == ZlibConstants.ZDataError) { this.blens = null; this.mode = InflateBlockMode.Bad; } this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } this.index = 0; this.mode = InflateBlockMode.Dtree; goto case InflateBlockMode.Dtree; case InflateBlockMode.Dtree: while (true) { t = this.table; if (!(this.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) { break; } t = this.bb[0]; while (k < t) { if (n != 0) { r = ZlibConstants.Zok; } else { this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } n--; b |= (this.Codec.InputBuffer[p++] & 0xff) << k; k += 8; } t = this.hufts[(this.tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 1]; int c = this.hufts[(this.tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 2]; if (c < 16) { b >>= t; k -= t; this.blens[this.index++] = c; } else { // c == 16..18 int i = c == 18 ? 7 : c - 14; int j = c == 18 ? 11 : 3; while (k < (t + i)) { if (n != 0) { r = ZlibConstants.Zok; } else { this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } n--; b |= (this.Codec.InputBuffer[p++] & 0xff) << k; k += 8; } b >>= t; k -= t; j += b & InternalInflateConstants.InflateMask[i]; b >>= i; k -= i; i = this.index; t = this.table; if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) { this.blens = null; this.mode = InflateBlockMode.Bad; this.Codec.Message = "invalid bit length repeat"; r = ZlibConstants.ZDataError; this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } c = (c == 16) ? this.blens[i - 1] : 0; do { this.blens[i++] = c; }while (--j != 0); this.index = i; } } this.tb[0] = -1; { var bl = new[] { 9 }; // must be <= 9 for lookahead assumptions var bd = new[] { 6 }; // must be <= 9 for lookahead assumptions var tl = new int[1]; var td = new int[1]; t = this.table; t = this.inftree.InflateTreesDynamic( 257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), this.blens, bl, bd, tl, td, this.hufts, this.Codec); if (t != ZlibConstants.Zok) { if (t == ZlibConstants.ZDataError) { this.blens = null; this.mode = InflateBlockMode.Bad; } r = t; this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } this.codes.Init(bl[0], bd[0], this.hufts, tl[0], this.hufts, td[0]); } this.mode = InflateBlockMode.Codes; goto case InflateBlockMode.Codes; case InflateBlockMode.Codes: this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; r = this.codes.Process(this, r); if (r != ZlibConstants.ZStreamEnd) { return(this.Flush(r)); } r = ZlibConstants.Zok; p = this.Codec.NextIn; n = this.Codec.AvailableBytesIn; b = this.Bitb; k = this.Bitk; q = this.WriteAt; m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q; if (this.last == 0) { this.mode = InflateBlockMode.Type; break; } this.mode = InflateBlockMode.Dry; goto case InflateBlockMode.Dry; case InflateBlockMode.Dry: this.WriteAt = q; r = this.Flush(r); q = this.WriteAt; m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q; if (this.ReadAt != this.WriteAt) { this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } this.mode = InflateBlockMode.Done; goto case InflateBlockMode.Done; case InflateBlockMode.Done: r = ZlibConstants.ZStreamEnd; this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); case InflateBlockMode.Bad: r = ZlibConstants.ZDataError; this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); default: r = ZlibConstants.ZStreamError; this.Bitb = b; this.Bitk = k; this.Codec.AvailableBytesIn = n; this.Codec.TotalBytesIn += p - this.Codec.NextIn; this.Codec.NextIn = p; this.WriteAt = q; return(this.Flush(r)); } } }
internal int proc(ZStream z, int r) { int t; // temporary storage int b; // bit buffer int k; // bits in bit buffer int p; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer // copy input/output information to locals (UPDATE macro restores) { p = z.next_in_index; n = z.avail_in; b = bitb; k = bitk; } { q = write; m = (int)(q < read?read - q - 1:end - q); } // process input based on current state while (true) { switch (mode) { case TYPE: while (k < (3)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = (int)(b & 7); last = t & 1; switch (SupportClass.URShift(t, 1)) { case 0: // stored { b = SupportClass.URShift(b, (3)); k -= (3); } t = k & 7; // go to byte boundary { b = SupportClass.URShift(b, (t)); k -= (t); } mode = LENS; // get length of stored block break; case 1: // fixed { int[] bl = new int[1]; int[] bd = new int[1]; int[][] tl = new int[1][]; int[][] td = new int[1][]; InfTree.inflate_trees_fixed(bl, bd, tl, td, z); codes = new InfCodes(bl[0], bd[0], tl[0], td[0], z); } { b = SupportClass.URShift(b, (3)); k -= (3); } mode = CODES; break; case 2: // dynamic { b = SupportClass.URShift(b, (3)); k -= (3); } mode = TABLE; break; case 3: // illegal { b = SupportClass.URShift(b, (3)); k -= (3); } mode = BAD; z.msg = "invalid block type"; r = Z_DATA_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } break; case LENS: while (k < (32)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } if (((SupportClass.URShift((~b), 16)) & 0xffff) != (b & 0xffff)) { mode = BAD; z.msg = "invalid stored block lengths"; r = Z_DATA_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } left = (b & 0xffff); b = k = 0; // dump bits mode = left != 0?STORED:(last != 0?DRY:TYPE); break; case STORED: if (n == 0) { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } if (m == 0) { if (q == end && read != 0) { q = 0; m = (int)(q < read?read - q - 1:end - q); } if (m == 0) { write = q; r = inflate_flush(z, r); q = write; m = (int)(q < read?read - q - 1:end - q); if (q == end && read != 0) { q = 0; m = (int)(q < read?read - q - 1:end - q); } if (m == 0) { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } } } r = Z_OK; t = left; if (t > n) { t = n; } if (t > m) { t = m; } Array.Copy(z.next_in, p, window, q, t); p += t; n -= t; q += t; m -= t; if ((left -= t) != 0) { break; } mode = last != 0?DRY:TYPE; break; case TABLE: while (k < (14)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } table = t = (b & 0x3fff); if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) { mode = BAD; z.msg = "too many length or distance symbols"; r = Z_DATA_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); blens = new int[t]; { b = SupportClass.URShift(b, (14)); k -= (14); } index = 0; mode = BTREE; goto case BTREE; case BTREE: while (index < 4 + (SupportClass.URShift(table, 10))) { while (k < (3)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } blens[border[index++]] = b & 7; { b = SupportClass.URShift(b, (3)); k -= (3); } } while (index < 19) { blens[border[index++]] = 0; } bb[0] = 7; t = InfTree.inflate_trees_bits(blens, bb, tb, hufts, z); if (t != Z_OK) { r = t; if (r == Z_DATA_ERROR) { blens = null; mode = BAD; } bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } index = 0; mode = DTREE; goto case DTREE; case DTREE: while (true) { t = table; if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) { break; } int i, j, c; t = bb[0]; while (k < (t)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } if (tb[0] == -1) { //System.err.println("null..."); } t = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 1]; c = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 2]; if (c < 16) { b = SupportClass.URShift(b, (t)); k -= (t); blens[index++] = c; } else { // c == 16..18 i = c == 18?7:c - 14; j = c == 18?11:3; while (k < (t + i)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } b = SupportClass.URShift(b, (t)); k -= (t); j += (b & inflate_mask[i]); b = SupportClass.URShift(b, (i)); k -= (i); i = index; t = table; if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) { blens = null; mode = BAD; z.msg = "invalid bit length repeat"; r = Z_DATA_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } c = c == 16?blens[i - 1]:0; do { blens[i++] = c; }while (--j != 0); index = i; } } tb[0] = -1; { int[] bl = new int[1]; int[] bd = new int[1]; int[] tl = new int[1]; int[] td = new int[1]; bl[0] = 9; // must be <= 9 for lookahead assumptions bd[0] = 6; // must be <= 9 for lookahead assumptions t = table; t = InfTree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tl, td, hufts, z); if (t != Z_OK) { if (t == Z_DATA_ERROR) { blens = null; mode = BAD; } r = t; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } codes = new InfCodes(bl[0], bd[0], hufts, tl[0], hufts, td[0], z); } blens = null; mode = CODES; goto case CODES; case CODES: bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; if ((r = codes.proc(this, z, r)) != Z_STREAM_END) { return(inflate_flush(z, r)); } r = Z_OK; codes.free(z); p = z.next_in_index; n = z.avail_in; b = bitb; k = bitk; q = write; m = (int)(q < read?read - q - 1:end - q); if (last == 0) { mode = TYPE; break; } mode = DRY; goto case DRY; case DRY: write = q; r = inflate_flush(z, r); q = write; m = (int)(q < read?read - q - 1:end - q); if (read != write) { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } mode = DONE; goto case DONE; case DONE: r = Z_STREAM_END; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); case BAD: r = Z_DATA_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); default: r = Z_STREAM_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return(inflate_flush(z, r)); } } }