public ZlibCompressionState DeflateEnd() { if (this.Dstate == null) { return(ZlibCompressionState.ZSTREAMERROR); } ZlibCompressionState ret = this.Dstate.DeflateEnd(); this.Dstate = null; return(ret); }
// copy as much as possible from the sliding window to the output area internal ZlibCompressionState Inflate_flush(ZStream z, ZlibCompressionState r) { int n; int p; int q; // local copies of source and destination pointers p = z.NextOutIndex; q = this.Read; // compute number of bytes to copy as far as end of window n = (q <= this.Write ? this.Write : this.End) - q; if (n > z.AvailOut) { n = z.AvailOut; } if (n != 0 && r == ZlibCompressionState.ZBUFERROR) { r = ZlibCompressionState.ZOK; } // update counters z.AvailOut -= n; z.TotalOut += n; // update check information if (this.checkfn != null) { z.Adler = this.check = Adler32.Calculate(this.check, this.Window, q, n); } // copy as far as end of window Array.Copy(this.Window, q, z.INextOut, p, n); p += n; q += n; // see if more to copy at beginning of window if (q == this.End) { // wrap pointers q = 0; if (this.Write == this.End) { this.Write = 0; } // compute bytes to copy n = this.Write - q; if (n > z.AvailOut) { n = z.AvailOut; } if (n != 0 && r == ZlibCompressionState.ZBUFERROR) { r = ZlibCompressionState.ZOK; } // update counters z.AvailOut -= n; z.TotalOut += n; // update check information if (this.checkfn != null) { z.Adler = this.check = Adler32.Calculate(this.check, this.Window, q, n); } // copy Array.Copy(this.Window, q, z.INextOut, p, n); p += n; q += n; } // update pointers z.NextOutIndex = p; this.Read = q; // done return(r); }
internal ZlibCompressionState Proc(ZStream z, ZlibCompressionState 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.NextInIndex; n = z.AvailIn; b = this.Bitb; k = this.Bitk; } { q = this.Write; m = q < this.Read ? this.Read - q - 1 : this.End - q; } // process input based on current state while (true) { switch (this.mode) { case TYPE: while (k < 3) { if (n != 0) { r = ZlibCompressionState.ZOK; } else { this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); } n--; b |= (z.INextIn[p++] & 0xff) << k; k += 8; } t = b & 7; this.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; } this.mode = 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.Inflate_trees_fixed(bl, bd, tl, td); this.codes = new InfCodes(bl[0], bd[0], tl[0], td[0]); } { b = SupportClass.URShift(b, 3); k -= 3; } this.mode = CODES; break; case 2: // dynamic { b = SupportClass.URShift(b, 3); k -= 3; } this.mode = TABLE; break; case 3: // illegal { b = SupportClass.URShift(b, 3); k -= 3; } this.mode = BAD; z.Msg = "invalid block type"; r = ZlibCompressionState.ZDATAERROR; this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); } break; case LENS: while (k < 32) { if (n != 0) { r = ZlibCompressionState.ZOK; } else { this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); } n--; b |= (z.INextIn[p++] & 0xff) << k; k += 8; } if ((SupportClass.URShift(~b, 16) & 0xffff) != (b & 0xffff)) { this.mode = BAD; z.Msg = "invalid stored block lengths"; r = ZlibCompressionState.ZDATAERROR; this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); } this.left = b & 0xffff; b = k = 0; // dump bits this.mode = this.left != 0 ? STORED : (this.last != 0 ? DRY : TYPE); break; case STORED: if (n == 0) { this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); } if (m == 0) { if (q == this.End && this.Read != 0) { q = 0; m = q < this.Read ? this.Read - q - 1 : this.End - q; } if (m == 0) { this.Write = q; r = this.Inflate_flush(z, r); q = this.Write; m = q < this.Read ? this.Read - q - 1 : this.End - q; if (q == this.End && this.Read != 0) { q = 0; m = q < this.Read ? this.Read - q - 1 : this.End - q; } if (m == 0) { this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); } } } r = ZlibCompressionState.ZOK; t = this.left; if (t > n) { t = n; } if (t > m) { t = m; } Array.Copy(z.INextIn, p, this.Window, q, t); p += t; n -= t; q += t; m -= t; if ((this.left -= t) != 0) { break; } this.mode = this.last != 0 ? DRY : TYPE; break; case TABLE: while (k < 14) { if (n != 0) { r = ZlibCompressionState.ZOK; } else { this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); } n--; b |= (z.INextIn[p++] & 0xff) << k; k += 8; } this.table = t = b & 0x3fff; if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) { this.mode = BAD; z.Msg = "too many length or distance symbols"; r = ZlibCompressionState.ZDATAERROR; this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); } t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); this.blens = new int[t]; { b = SupportClass.URShift(b, 14); k -= 14; } this.index = 0; this.mode = BTREE; goto case BTREE; case BTREE: while (this.index < 4 + SupportClass.URShift(this.table, 10)) { while (k < 3) { if (n != 0) { r = ZlibCompressionState.ZOK; } else { this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); } n--; b |= (z.INextIn[p++] & 0xff) << k; k += 8; } this.blens[Border[this.index++]] = b & 7; { b = SupportClass.URShift(b, 3); k -= 3; } } while (this.index < 19) { this.blens[Border[this.index++]] = 0; } this.bb[0] = 7; t = (int)InfTree.Inflate_trees_bits(this.blens, this.bb, this.tb, this.hufts, z); if (t != (int)ZlibCompressionState.ZOK) { r = (ZlibCompressionState)t; if (r == ZlibCompressionState.ZDATAERROR) { this.blens = null; this.mode = BAD; } this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); } this.index = 0; this.mode = DTREE; goto case DTREE; case DTREE: while (true) { t = this.table; if (!(this.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) { break; } int i, j, c; t = this.bb[0]; while (k < t) { if (n != 0) { r = ZlibCompressionState.ZOK; } else { this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); } n--; b |= (z.INextIn[p++] & 0xff) << k; k += 8; } if (this.tb[0] == -1) { // System.err.println("null..."); } t = this.hufts[((this.tb[0] + (b & InflateMask[t])) * 3) + 1]; c = this.hufts[((this.tb[0] + (b & InflateMask[t])) * 3) + 2]; if (c < 16) { b = SupportClass.URShift(b, t); k -= t; this.blens[this.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 = ZlibCompressionState.ZOK; } else { this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); } n--; b |= (z.INextIn[p++] & 0xff) << k; k += 8; } b = SupportClass.URShift(b, t); k -= t; j += b & InflateMask[i]; b = SupportClass.URShift(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 = BAD; z.Msg = "invalid bit length repeat"; r = ZlibCompressionState.ZDATAERROR; this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, 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 int[1]; var bd = new int[1]; var tl = new int[1]; var td = new int[1]; bl[0] = 9; // must be <= 9 for lookahead assumptions bd[0] = 6; // must be <= 9 for lookahead assumptions t = this.table; t = (int)InfTree.Inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), this.blens, bl, bd, tl, td, this.hufts, z); if (t != (int)ZlibCompressionState.ZOK) { if (t == (int)ZlibCompressionState.ZDATAERROR) { this.blens = null; this.mode = BAD; } r = (ZlibCompressionState)t; this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); } this.codes = new InfCodes(bl[0], bd[0], this.hufts, tl[0], this.hufts, td[0]); } this.blens = null; this.mode = CODES; goto case CODES; case CODES: this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; if ((r = this.codes.Proc(this, z, r)) != ZlibCompressionState.ZSTREAMEND) { return(this.Inflate_flush(z, r)); } r = ZlibCompressionState.ZOK; InfCodes.Free(); p = z.NextInIndex; n = z.AvailIn; b = this.Bitb; k = this.Bitk; q = this.Write; m = q < this.Read ? this.Read - q - 1 : this.End - q; if (this.last == 0) { this.mode = TYPE; break; } this.mode = DRY; goto case DRY; case DRY: this.Write = q; r = this.Inflate_flush(z, r); q = this.Write; m = q < this.Read ? this.Read - q - 1 : this.End - q; if (this.Read != this.Write) { this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); } this.mode = DONE; goto case DONE; case DONE: r = ZlibCompressionState.ZSTREAMEND; this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); case BAD: r = ZlibCompressionState.ZDATAERROR; this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); default: r = ZlibCompressionState.ZSTREAMERROR; this.Bitb = b; this.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; this.Write = q; return(this.Inflate_flush(z, r)); } } }
internal ZlibCompressionState Proc(InfBlocks s, ZStream z, ZlibCompressionState r) { int j; // temporary storage // int[] t; // temporary pointer int tindex; // temporary pointer int e; // extra bits or operation var b = 0; // bit buffer var k = 0; // bits in bit buffer var p = 0; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer int f; // pointer to copy strings from // copy input/output information to locals (UPDATE macro restores) p = z.NextInIndex; n = z.AvailIn; b = s.Bitb; k = s.Bitk; q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; // process input and output based on current state while (true) { switch (this.Mode) { // waiting for "i:"=input, "o:"=output, "x:"=nothing case START: // x: set up for LEN if (m >= 258 && n >= 10) { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; r = Inflate_fast(this.Lbits, this.Dbits, this.Ltree, this.LtreeIndex, this.Dtree, this.DtreeIndex, s, z); p = z.NextInIndex; n = z.AvailIn; b = s.Bitb; k = s.Bitk; q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; if (r != ZlibCompressionState.ZOK) { this.Mode = r == ZlibCompressionState.ZSTREAMEND ? WASH : BADCODE; break; } } this.Need = this.Lbits; this.Tree = this.Ltree; this.TreeIndex = this.LtreeIndex; this.Mode = LEN; goto case LEN; case LEN: // i: get length/literal/eob next j = this.Need; while (k < j) { if (n != 0) { r = ZlibCompressionState.ZOK; } else { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.Inflate_flush(z, r)); } n--; b |= (z.INextIn[p++] & 0xff) << k; k += 8; } tindex = (this.TreeIndex + (b & InflateMask[j])) * 3; b = SupportClass.URShift(b, this.Tree[tindex + 1]); k -= this.Tree[tindex + 1]; e = this.Tree[tindex]; if (e == 0) { // literal this.Lit = this.Tree[tindex + 2]; this.Mode = LIT; break; } if ((e & 16) != 0) { // length this.GetRenamed = e & 15; this.Len = this.Tree[tindex + 2]; this.Mode = LENEXT; break; } if ((e & 64) == 0) { // next table this.Need = e; this.TreeIndex = (tindex / 3) + this.Tree[tindex + 2]; break; } if ((e & 32) != 0) { // end of block this.Mode = WASH; break; } this.Mode = BADCODE; // invalid code z.Msg = "invalid literal/length code"; r = ZlibCompressionState.ZDATAERROR; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.Inflate_flush(z, r)); case LENEXT: // i: getting length extra (have base) j = this.GetRenamed; while (k < j) { if (n != 0) { r = ZlibCompressionState.ZOK; } else { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.Inflate_flush(z, r)); } n--; b |= (z.INextIn[p++] & 0xff) << k; k += 8; } this.Len += b & InflateMask[j]; b >>= j; k -= j; this.Need = this.Dbits; this.Tree = this.Dtree; this.TreeIndex = this.DtreeIndex; this.Mode = DIST; goto case DIST; case DIST: // i: get distance next j = this.Need; while (k < j) { if (n != 0) { r = ZlibCompressionState.ZOK; } else { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.Inflate_flush(z, r)); } n--; b |= (z.INextIn[p++] & 0xff) << k; k += 8; } tindex = (this.TreeIndex + (b & InflateMask[j])) * 3; b >>= this.Tree[tindex + 1]; k -= this.Tree[tindex + 1]; e = this.Tree[tindex]; if ((e & 16) != 0) { // distance this.GetRenamed = e & 15; this.Dist = this.Tree[tindex + 2]; this.Mode = DISTEXT; break; } if ((e & 64) == 0) { // next table this.Need = e; this.TreeIndex = (tindex / 3) + this.Tree[tindex + 2]; break; } this.Mode = BADCODE; // invalid code z.Msg = "invalid distance code"; r = ZlibCompressionState.ZDATAERROR; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.Inflate_flush(z, r)); case DISTEXT: // i: getting distance extra j = this.GetRenamed; while (k < j) { if (n != 0) { r = ZlibCompressionState.ZOK; } else { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.Inflate_flush(z, r)); } n--; b |= (z.INextIn[p++] & 0xff) << k; k += 8; } this.Dist += b & InflateMask[j]; b >>= j; k -= j; this.Mode = COPY; goto case COPY; case COPY: // o: copying bytes in window, waiting for space f = q - this.Dist; while (f < 0) { // modulo window size-"while" instead f += s.End; // of "if" handles invalid distances } while (this.Len != 0) { if (m == 0) { if (q == s.End && s.Read != 0) { q = 0; m = q < s.Read ? s.Read - q - 1 : s.End - q; } if (m == 0) { s.Write = q; r = s.Inflate_flush(z, r); q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; if (q == s.End && s.Read != 0) { q = 0; m = q < s.Read ? s.Read - q - 1 : s.End - q; } if (m == 0) { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.Inflate_flush(z, r)); } } } s.Window[q++] = s.Window[f++]; m--; if (f == s.End) { f = 0; } this.Len--; } this.Mode = START; break; case LIT: // o: got literal, waiting for output space if (m == 0) { if (q == s.End && s.Read != 0) { q = 0; m = q < s.Read ? s.Read - q - 1 : s.End - q; } if (m == 0) { s.Write = q; r = s.Inflate_flush(z, r); q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; if (q == s.End && s.Read != 0) { q = 0; m = q < s.Read ? s.Read - q - 1 : s.End - q; } if (m == 0) { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.Inflate_flush(z, r)); } } } r = ZlibCompressionState.ZOK; s.Window[q++] = (byte)this.Lit; m--; this.Mode = START; break; case WASH: // o: got eob, possibly more output if (k > 7) { // return unused byte, if any k -= 8; n++; p--; // can always return one } s.Write = q; r = s.Inflate_flush(z, r); q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; if (s.Read != s.Write) { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.Inflate_flush(z, r)); } this.Mode = END; goto case END; case END: r = ZlibCompressionState.ZSTREAMEND; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.Inflate_flush(z, r)); case BADCODE: // x: got error r = ZlibCompressionState.ZDATAERROR; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.Inflate_flush(z, r)); default: r = ZlibCompressionState.ZSTREAMERROR; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.Inflate_flush(z, r)); } } }