internal static int Process(zlib.ZStream /*!*/ zst, MutableString str, zlib.FlushStrategy flush, bool compress, out MutableString /*!*/ result, ref MutableString trailingUncompressedData) { result = MutableString.CreateBinary(); // add previously compressed data to the output: if (zst.next_out != null) { result.Append(zst.next_out, 0, zst.next_out_index); } int err; int bufferStart = zst.next_out_index; err = Process(zst, str, flush, compress, ref trailingUncompressedData); result.Append(zst.next_out, bufferStart, zst.next_out_index - bufferStart); if (err == Z_STREAM_END && (flush == zlib.FlushStrategy.Z_FINISH || str == null)) { err = compress ? zst.deflateEnd() : zst.inflateEnd(); } zst.next_out = null; zst.next_out_index = 0; zst.avail_out = 0; return(err); }
internal static int Process(zlib.ZStream /*!*/ zst, MutableString str, zlib.FlushStrategy flush, bool compress, ref MutableString trailingUncompressedData) { if (str == null) { str = MutableString.FrozenEmpty; flush = zlib.FlushStrategy.Z_FINISH; } else if (str.Length == 0 && flush == NO_FLUSH) { return(Z_OK); } // data still available from previous input: if (zst.avail_in > 0) { int err = Process(zst, flush, compress, ref trailingUncompressedData); // double flush: if (compress && flush != zlib.FlushStrategy.Z_FINISH && err == (int)zlib.ZLibResultCode.Z_DATA_ERROR) { return(Z_OK); } // append new input to the current input: if (err != Z_OK && err != Z_STREAM_END) { byte[] currentInput = zst.next_in; byte[] newInput = str.ToByteArray(); int minLength = zst.next_in_index + zst.avail_in + newInput.Length; if (currentInput.Length < minLength) { Array.Resize(ref currentInput, Math.Max(currentInput.Length * 2, minLength)); } Buffer.BlockCopy(newInput, 0, currentInput, zst.next_in_index + zst.avail_in, newInput.Length); zst.next_in = currentInput; zst.avail_in += newInput.Length; return(err); } } if (str != null) { byte[] input = str.ToByteArray(); zst.next_in = input; zst.next_in_index = 0; zst.avail_in = input.Length; } else { zst.avail_in = 0; } return(Process(zst, flush, compress, ref trailingUncompressedData)); }
private static zlib.ZStream CreateDeflateStream(int level, int windowBits, int memLevel, int strategy) { var stream = new zlib.ZStream(); int result = stream.deflateInit(level, windowBits, memLevel, (zlib.CompressionStrategy)strategy); if (result != Z_OK) { throw MakeError(result, null); } return(stream); }
private static zlib.ZStream CreateInflateStream(int windowBits) { var zst = new zlib.ZStream(); int result = zst.inflateInit(windowBits); if (result != Z_OK) { throw MakeError(result, zst.msg); } return(zst); }
internal Compress(int level, int method, int wbits, int memlevel, int strategy) { zst = new ZStream(); int err = zst.deflateInit(level, wbits); switch(err) { case ZlibModule.Z_OK: break; case ZlibModule.Z_STREAM_ERROR: throw PythonOps.ValueError("Invalid initialization option"); default: throw ZlibModule.zlib_error(this.zst, err, "while creating compression object"); } }
internal static MutableString /*!*/ InflateString(MutableString /*!*/ str) { zlib.ZStream zst = CreateInflateStream(); // uncompressed data are ignored: MutableString trailingUncompressedData = null; MutableString uncompressed; int result = Process(zst, str, zlib.FlushStrategy.Z_SYNC_FLUSH, decompress, out uncompressed, ref trailingUncompressedData); if (result != Z_OK && result != Z_STREAM_END) { throw MakeError(result, zst.msg); } return(uncompressed); }
/// <summary> /// Builds dynamic trees /// </summary> internal static int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZStream z) { int r; int[] hn = new int[1]; // hufts used in space int[] v = new int[288]; // work area for huft_build // build literal/length tree r = huft_build(c, 0, nl, 257, InfTreeUtil.cplens, InfTreeUtil.cplext, tl, bl, hp, hn, v); if (r != (int)ZLibResultCode.Z_OK || bl[0] == 0) { if (r == (int)ZLibResultCode.Z_DATA_ERROR) { z.msg = "oversubscribed literal/length tree"; } else if (r != (int)ZLibResultCode.Z_DATA_ERROR) { z.msg = "incomplete literal/length tree"; r = (int)ZLibResultCode.Z_DATA_ERROR; } return r; } // build distance tree r = huft_build(c, nl, nd, 0, InfTreeUtil.cpdist, InfTreeUtil.cpdext, td, bd, hp, hn, v); if (r != (int)ZLibResultCode.Z_OK || (bd[0] == 0 && nl > 257)) { if (r == (int)ZLibResultCode.Z_DATA_ERROR) { z.msg = "oversubscribed distance tree"; } else if (r == (int)ZLibResultCode.Z_DATA_ERROR) { z.msg = "incomplete distance tree"; r = (int)ZLibResultCode.Z_DATA_ERROR; } else if (r != (int)ZLibResultCode.Z_DATA_ERROR) { z.msg = "empty distance tree with lengths"; r = (int)ZLibResultCode.Z_DATA_ERROR; } return r; } return (int)ZLibResultCode.Z_OK; }
public static MutableString /*!*/ DeflateString(RubyClass /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ str, [DefaultParameterValue(DEFAULT_COMPRESSION)] int level) { zlib.ZStream zst = CreateDeflateStream(level); MutableString compressed; MutableString trailingUncompressedData = null; int result = Process(zst, str, zlib.FlushStrategy.Z_FINISH, compress, out compressed, ref trailingUncompressedData); if (result != Z_OK) { throw MakeError(result, zst.msg); } return(compressed); }
internal Decompress(int wbits) { zst = new ZStream(); int err = zst.inflateInit(wbits); switch(err) { case ZlibModule.Z_OK: break; case ZlibModule.Z_STREAM_ERROR: throw PythonOps.ValueError("Invalid initialization option"); default: throw ZlibModule.zlib_error(this.zst, err, "while creating decompression object"); } _unused_data = string.Empty; _unconsumed_tail = string.Empty; }
/// <summary> /// Build trees /// </summary> internal static int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZStream z) { int r; int[] hn = new int[1]; // hufts used in space int[] v = new int[19]; // work area for huft_build r = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); if (r == (int)ZLibResultCode.Z_DATA_ERROR) { z.msg = "oversubscribed dynamic bit lengths tree"; } else if (r == (int)ZLibResultCode.Z_DATA_ERROR || bb[0] == 0) { z.msg = "incomplete dynamic bit lengths tree"; r = (int)ZLibResultCode.Z_DATA_ERROR; } return r; }
public static object TotalOut(ZStream/*!*/ self) { return Protocols.Normalize(self.GetStream().total_out); }
public static void Reset(ZStream/*!*/ self) { var zst = self.GetStream(); if (zst.IsInitialized) { int err = zst.reset(); Debug.Assert(err == Z_OK); } }
public static int GetAvailOut(ZStream/*!*/ self) { return self.GetStream().avail_out; }
public static MutableString Finish(ZStream/*!*/ self) { return self.Finish(); }
public static void Close(ZStream/*!*/ self) { if (self._stream != null) { self.Close(); self._stream = null; } }
public static object Adler(ZStream/*!*/ self) { return Protocols.Normalize(self.GetStream().adler); }
/// <summary> /// Block processing method /// </summary> /// <param name="s">An instance of the InfBlocks class</param> /// <param name="z">A ZStream object</param> /// <param name="r">A result code</param> internal int proc(InfBlocks s, ZStream z, int r) { int j; // temporary storage //int[] t; // temporary pointer int tindex; // temporary pointer int e; // extra bits or operation int b = 0; // bit buffer int k = 0; // bits in bit buffer int p = 0; // input data pointer int n; // bytes available there int q; // output Window WritePos pointer int m; // bytes to End of Window or ReadPos pointer int f; // pointer to copy strings from // copy input/output information to locals (UPDATE macro restores) p = z.next_in_index; n = z.avail_in; b = s.BitB; k = s.BitK; q = s.WritePos; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; // process input and output based on current state while (true) { switch (mode) { // waiting for "i:"=input, "o:"=output, "x:"=nothing case InflateCodesMode.START: // x: set up for InflateCodesMode.LEN if (m >= 258 && n >= 10) { s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z); p = z.next_in_index; n = z.avail_in; b = s.BitB; k = s.BitK; q = s.WritePos; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; if (r != (int)ZLibResultCode.Z_OK) { mode = r == (int)ZLibResultCode.Z_STREAM_END? InflateCodesMode.WASH: InflateCodesMode.BADCODE; break; } } need = lbits; tree = ltree; tree_index = ltree_index; mode = InflateCodesMode.LEN; goto case InflateCodesMode.LEN; case InflateCodesMode.LEN: // i: get length/literal/eob next j = need; while (k < (j)) { if (n != 0) r = (int)ZLibResultCode.Z_OK; else { s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return s.inflate_flush(z, r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } tindex = (tree_index + (b & ZLibUtil.inflate_mask[j])) * 3; b = ZLibUtil.URShift(b, (tree[tindex + 1])); k -= (tree[tindex + 1]); e = tree[tindex]; if (e == 0) { // literal lit = tree[tindex + 2]; mode = InflateCodesMode.LIT; break; } if ((e & 16) != 0) { // length get_Renamed = e & 15; count = tree[tindex + 2]; mode = InflateCodesMode.LENEXT; break; } if ((e & 64) == 0) { // next table need = e; tree_index = tindex / 3 + tree[tindex + 2]; break; } if ((e & 32) != 0) { // End of block mode = InflateCodesMode.WASH; break; } mode = InflateCodesMode.BADCODE; // invalid code z.msg = "invalid literal/length code"; r = (int)ZLibResultCode.Z_DATA_ERROR; s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return s.inflate_flush(z, r); case InflateCodesMode.LENEXT: // i: getting length extra (have base) j = get_Renamed; while (k < (j)) { if (n != 0) r = (int)ZLibResultCode.Z_OK; else { s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return s.inflate_flush(z, r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } count += (b & ZLibUtil.inflate_mask[j]); b >>= j; k -= j; need = dbits; tree = dtree; tree_index = dtree_index; mode = InflateCodesMode.DIST; goto case InflateCodesMode.DIST; case InflateCodesMode.DIST: // i: get distance next j = need; while (k < (j)) { if (n != 0) r = (int)ZLibResultCode.Z_OK; else { s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return s.inflate_flush(z, r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } tindex = (tree_index + (b & ZLibUtil.inflate_mask[j])) * 3; b >>= tree[tindex + 1]; k -= tree[tindex + 1]; e = (tree[tindex]); if ((e & 16) != 0) { // distance get_Renamed = e & 15; dist = tree[tindex + 2]; mode = InflateCodesMode.DISTEXT; break; } if ((e & 64) == 0) { // next table need = e; tree_index = tindex / 3 + tree[tindex + 2]; break; } mode = InflateCodesMode.BADCODE; // invalid code z.msg = "invalid distance code"; r = (int)ZLibResultCode.Z_DATA_ERROR; s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return s.inflate_flush(z, r); case InflateCodesMode.DISTEXT: // i: getting distance extra j = get_Renamed; while (k < (j)) { if (n != 0) r = (int)ZLibResultCode.Z_OK; else { s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return s.inflate_flush(z, r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } dist += (b & ZLibUtil.inflate_mask[j]); b >>= j; k -= j; mode = InflateCodesMode.COPY; goto case InflateCodesMode.COPY; case InflateCodesMode.COPY: // o: copying bytes in Window, waiting for space f = q - dist; while (f < 0) { // modulo Window size-"while" instead f += s.End; // of "if" handles invalid distances } while (count != 0) { if (m == 0) { if (q == s.End && s.ReadPos != 0) { q = 0; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; } if (m == 0) { s.WritePos = q; r = s.inflate_flush(z, r); q = s.WritePos; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; if (q == s.End && s.ReadPos != 0) { q = 0; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; } if (m == 0) { s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return s.inflate_flush(z, r); } } } s.Window[q++] = s.Window[f++]; m--; if (f == s.End) f = 0; count--; } mode = InflateCodesMode.START; break; case InflateCodesMode.LIT: // o: got literal, waiting for output space if (m == 0) { if (q == s.End && s.ReadPos != 0) { q = 0; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; } if (m == 0) { s.WritePos = q; r = s.inflate_flush(z, r); q = s.WritePos; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; if (q == s.End && s.ReadPos != 0) { q = 0; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; } if (m == 0) { s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return s.inflate_flush(z, r); } } } r = (int)ZLibResultCode.Z_OK; s.Window[q++] = (byte) lit; m--; mode = InflateCodesMode.START; break; case InflateCodesMode.WASH: // o: got eob, possibly more output if (k > 7) { // return unused byte, if any k -= 8; n++; p--; // can always return one } s.WritePos = q; r = s.inflate_flush(z, r); q = s.WritePos; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; if (s.ReadPos != s.WritePos) { s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return s.inflate_flush(z, r); } mode = InflateCodesMode.END; goto case InflateCodesMode.END; case InflateCodesMode.END: r = (int)ZLibResultCode.Z_STREAM_END; s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return s.inflate_flush(z, r); case InflateCodesMode.BADCODE: // x: got error r = (int)ZLibResultCode.Z_DATA_ERROR; s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return s.inflate_flush(z, r); default: r = (int)ZLibResultCode.Z_STREAM_ERROR; s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return s.inflate_flush(z, r); } } }
private IEnumerable <object> StartHeaderSkipping(ZStream z) { var headerCollector = new List <byte>(FIXED_HEADER_SIZE); do { if (z.avail_in == 0) { yield return(false); } headerCollector.Add(GetNext(z)); } while (headerCollector.Count < FIXED_HEADER_SIZE); var flag = headerCollector[3]; if (0 != (flag & (byte)HEADER_FLAG.FEXTRA)) { if (z.avail_in == 0) { yield return(null); } var outstandingSize = (int)GetNext(z); if (z.avail_in == 0) { yield return(null); } outstandingSize += 256 * GetNext(z); do { if (z.avail_in == 0) { yield return(null); } GetNext(z); } while (--outstandingSize != 0); } // STATE_NAME if (0 != (flag & (byte)HEADER_FLAG.FNAME)) { do { if (z.avail_in == 0) { yield return(null); } } while (GetNext(z) != 0); } // STATE_COMMENT: if (0 != (flag & (byte)HEADER_FLAG.FCOMMENT)) { do { if (z.avail_in == 0) { yield return(null); } } while (GetNext(z) != 0); } // STATE_CRC: if (0 != (flag & (byte)HEADER_FLAG.FHCRC)) { var outstandingSize = 4; do { if (z.avail_in == 0) { yield return(null); } GetNext(z); } while (--outstandingSize != 0); } }
protected ZStream(RubyClass /*!*/ cls, zlib.ZStream /*!*/ stream) : base(cls) { Debug.Assert(stream != null); _stream = stream; }
/// <summary> /// Build fixed trees /// </summary> internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZStream z) { bl[0] = InfTreeUtil.fixed_bl; bd[0] = InfTreeUtil.fixed_bd; tl[0] = InfTreeUtil.fixed_tl; td[0] = InfTreeUtil.fixed_td; return (int)ZLibResultCode.Z_OK; }
///<summary> /// Returns true if inflate is currently at the End of a block generated /// by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP /// implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH /// but removes the length bytes of the resulting empty stored block. When /// decompressing, PPP checks that at the End of input packet, inflate is /// waiting for these length bytes. /// </summary> internal int inflateSyncPoint(ZStream z) { if (z == null || z.istate == null || z.istate.blocks == null) return (int)ZLibResultCode.Z_STREAM_ERROR; return z.istate.blocks.sync_point(); }
/// <summary> /// Inflate synchronization /// </summary> /// <param name="z">A ZStream object</param> /// <returns>Operation result code</returns> internal int inflateSync(ZStream z) { int n; // number of bytes to look at int p; // pointer to bytes int m; // number of marker bytes found in a row long r, w; // temporaries to save _total_in and _total_out // set up if (z == null || z.istate == null) return (int)ZLibResultCode.Z_STREAM_ERROR; if (z.istate.mode != InflateMode.BAD) { z.istate.mode = InflateMode.BAD; z.istate.marker = 0; } if ((n = z.avail_in) == 0) return (int)ZLibResultCode.Z_BUF_ERROR; p = z.next_in_index; m = z.istate.marker; // search while (n != 0 && m < 4) { if (z.next_in[p] == ZLibUtil.mark[m]) { m++; } else if (z.next_in[p] != 0) { m = 0; } else { m = 4 - m; } p++; n--; } // restore z.total_in += p - z.next_in_index; z.next_in_index = p; z.avail_in = n; z.istate.marker = m; // return no joy or set up to restart on a new block if (m != 4) { return (int)ZLibResultCode.Z_DATA_ERROR; } r = z.total_in; w = z.total_out; inflateReset(z); z.total_in = r; z.total_out = w; z.istate.mode = InflateMode.BLOCKS; return (int)ZLibResultCode.Z_OK; }
/// <summary> /// Fast inflate procedure. Called with number of bytes left to WritePos in Window at least 258 /// (the maximum string length) and number of input bytes available /// at least ten. The ten bytes are six bytes for the longest length/ /// distance pair plus four bytes for overloading the bit buffer. /// </summary> internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InfBlocks s, ZStream z) { int t; // temporary pointer int[] tp; // temporary pointer int tp_index; // temporary pointer int e; // extra bits or operation int b; // bit buffer int k; // bits in bit buffer int p; // input data pointer int n; // bytes available there int q; // output Window WritePos pointer int m; // bytes to End of Window or ReadPos pointer int ml; // mask for literal/length tree int md; // mask for distance tree int c; // bytes to copy int d; // distance back to copy from int r; // copy source pointer // load input, output, bit values p = z.next_in_index; n = z.avail_in; b = s.BitB; k = s.BitK; q = s.WritePos; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; // initialize masks ml = ZLibUtil.inflate_mask[bl]; md = ZLibUtil.inflate_mask[bd]; // do until not enough input or output space for fast loop do { // assume called with m >= 258 && n >= 10 // get literal/length code while (k < (20)) { // max bits for literal/length code n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = b & ml; tp = tl; tp_index = tl_index; if ((e = tp[(tp_index + t) * 3]) == 0) { b >>= (tp[(tp_index + t) * 3 + 1]); k -= (tp[(tp_index + t) * 3 + 1]); s.Window[q++] = (byte) tp[(tp_index + t) * 3 + 2]; m--; continue; } do { b >>= (tp[(tp_index + t) * 3 + 1]); k -= (tp[(tp_index + t) * 3 + 1]); if ((e & 16) != 0) { e &= 15; c = tp[(tp_index + t) * 3 + 2] + ((int) b & ZLibUtil.inflate_mask[e]); b >>= e; k -= e; // decode distance base of block to copy while (k < (15)) { // max bits for distance code n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = b & md; tp = td; tp_index = td_index; e = tp[(tp_index + t) * 3]; do { b >>= (tp[(tp_index + t) * 3 + 1]); k -= (tp[(tp_index + t) * 3 + 1]); if ((e & 16) != 0) { // get extra bits to add to distance base e &= 15; while (k < (e)) { // get extra bits (up to 13) n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } d = tp[(tp_index + t) * 3 + 2] + (b & ZLibUtil.inflate_mask[e]); b >>= (e); k -= (e); // do the copy m -= c; if (q >= d) { // offset before dest // just copy r = q - d; if (q - r > 0 && 2 > (q - r)) { s.Window[q++] = s.Window[r++]; c--; // minimum count is three, s.Window[q++] = s.Window[r++]; c--; // so unroll loop a little } else { Array.Copy(s.Window, r, s.Window, q, 2); q += 2; r += 2; c -= 2; } } else { // else offset after destination r = q - d; do { r += s.End; // force pointer in Window } while (r < 0); // covers invalid distances e = s.End - r; if (c > e) { // if source crosses, c -= e; // wrapped copy if (q - r > 0 && e > (q - r)) { do { s.Window[q++] = s.Window[r++]; } while (--e != 0); } else { Array.Copy(s.Window, r, s.Window, q, e); q += e; r += e; e = 0; } r = 0; // copy rest from start of Window } } // copy all or what's left if (q - r > 0 && c > (q - r)) { do { s.Window[q++] = s.Window[r++]; } while (--c != 0); } else { Array.Copy(s.Window, r, s.Window, q, c); q += c; r += c; c = 0; } break; } else if ((e & 64) == 0) { t += tp[(tp_index + t) * 3 + 2]; t += (b & ZLibUtil.inflate_mask[e]); e = tp[(tp_index + t) * 3]; } else { z.msg = "invalid distance code"; c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= (c << 3); s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return (int)ZLibResultCode.Z_DATA_ERROR; } } while (true); break; } if ((e & 64) == 0) { t += tp[(tp_index + t) * 3 + 2]; t += (b & ZLibUtil.inflate_mask[e]); if ((e = tp[(tp_index + t) * 3]) == 0) { b >>= (tp[(tp_index + t) * 3 + 1]); k -= (tp[(tp_index + t) * 3 + 1]); s.Window[q++] = (byte) tp[(tp_index + t) * 3 + 2]; m--; break; } } else if ((e & 32) != 0) { c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= (c << 3); s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return (int)ZLibResultCode.Z_STREAM_END; } else { z.msg = "invalid literal/length code"; c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= (c << 3); s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return (int)ZLibResultCode.Z_DATA_ERROR; } } while (true); } while (m >= 258 && n >= 10); // not enough input or output--restore pointers and return c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= (c << 3); s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return (int)ZLibResultCode.Z_OK; }
private byte GetNext(ZStream z) { z.avail_in--; z.total_in++; return(z.next_in[z.next_in_index++]); }
/// <summary> /// Runs inflate algorithm /// </summary> /// <param name="z">A ZStream object</param> /// <param name="flush">Flush strategy</param> /// <returns>Operation result code</returns> internal int inflate(ZStream z, FlushStrategy flush) { int r; int b; int internalFlush = (int)flush; int res_temp; if (z == null || z.istate == null || z.next_in == null) { return((int)ZLibResultCode.Z_STREAM_ERROR); } res_temp = internalFlush == (int)FlushStrategy.Z_FINISH ? (int)ZLibResultCode.Z_BUF_ERROR : (int)ZLibResultCode.Z_OK; r = (int)ZLibResultCode.Z_BUF_ERROR; if (detectHeader) { if (z.avail_in == 0) { return(r); } if (z.next_in[z.next_in_index] == 0x1F) { gzipHeaderRemover = GzipHeader.CreateRemover(z); } detectHeader = false; } if (gzipHeaderRemover != null) { if (z.avail_in == 0) { return(r); } if (gzipHeaderRemover.MoveNext()) { return(r); } gzipHeaderRemover = null; z.istate.mode = InflateMode.BLOCKS; z.istate.blocks.needCheck = false; nowrap = 1; } while (true) { switch (z.istate.mode) { case InflateMode.METHOD: if (z.avail_in == 0) { return(r); } r = res_temp; z.avail_in--; z.total_in++; if (((z.istate.method = z.next_in[z.next_in_index++]) & 0xf) != ZLibUtil.Z_DEFLATED) { z.istate.mode = InflateMode.BAD; z.msg = "unknown compression method"; z.istate.marker = 5; // can't try inflateSync break; } if ((z.istate.method >> 4) + 8 > z.istate.wbits) { z.istate.mode = InflateMode.BAD; z.msg = "invalid Window size"; z.istate.marker = 5; // can't try inflateSync break; } z.istate.mode = InflateMode.FLAG; goto case InflateMode.FLAG; case InflateMode.FLAG: if (z.avail_in == 0) { return(r); } r = res_temp; z.avail_in--; z.total_in++; b = (z.next_in[z.next_in_index++]) & 0xff; if ((((z.istate.method << 8) + b) % 31) != 0) { z.istate.mode = InflateMode.BAD; z.msg = "incorrect header check"; z.istate.marker = 5; // can't try inflateSync break; } if ((b & ZLibUtil.PRESET_DICT) == 0) { z.istate.mode = InflateMode.BLOCKS; break; } z.istate.mode = InflateMode.DICT4; goto case InflateMode.DICT4; case InflateMode.DICT4: if (z.avail_in == 0) { return(r); } r = res_temp; z.avail_in--; z.total_in++; z.istate.need = ((long)(z.next_in[z.next_in_index++] & 0xff) << 24) & unchecked ((int)0xff000000L); z.istate.mode = InflateMode.DICT3; goto case InflateMode.DICT3; case InflateMode.DICT3: if (z.avail_in == 0) { return(r); } r = res_temp; z.avail_in--; z.total_in++; z.istate.need += (((long)(z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L); z.istate.mode = InflateMode.DICT2; goto case InflateMode.DICT2; case InflateMode.DICT2: if (z.avail_in == 0) { return(r); } r = res_temp; z.avail_in--; z.total_in++; z.istate.need += (((long)(z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L); z.istate.mode = InflateMode.DICT1; goto case InflateMode.DICT1; case InflateMode.DICT1: if (z.avail_in == 0) { return(r); } r = res_temp; z.avail_in--; z.total_in++; z.istate.need += (z.next_in[z.next_in_index++] & 0xffL); z.adler = z.istate.need; z.istate.mode = InflateMode.DICT0; return((int)ZLibResultCode.Z_NEED_DICT); case InflateMode.DICT0: z.istate.mode = InflateMode.BAD; z.msg = "need dictionary"; z.istate.marker = 0; // can try inflateSync return((int)ZLibResultCode.Z_STREAM_ERROR); case InflateMode.BLOCKS: r = z.istate.blocks.proc(z, r); if (r == (int)ZLibResultCode.Z_DATA_ERROR) { z.istate.mode = InflateMode.BAD; z.istate.marker = 0; // can try inflateSync break; } if (r == (int)ZLibResultCode.Z_OK) { r = res_temp; } if (r != (int)ZLibResultCode.Z_STREAM_END) { return(r); } r = res_temp; z.istate.blocks.reset(z, z.istate.was); if (z.istate.nowrap != 0) { z.istate.mode = InflateMode.DONE; break; } z.istate.mode = InflateMode.CHECK4; goto case InflateMode.CHECK4; case InflateMode.CHECK4: if (z.avail_in == 0) { return(r); } r = res_temp; z.avail_in--; z.total_in++; z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & unchecked ((int)0xff000000L); z.istate.mode = InflateMode.CHECK3; goto case InflateMode.CHECK3; case InflateMode.CHECK3: if (z.avail_in == 0) { return(r); } r = res_temp; z.avail_in--; z.total_in++; z.istate.need += (((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L); z.istate.mode = InflateMode.CHECK2; goto case InflateMode.CHECK2; case InflateMode.CHECK2: if (z.avail_in == 0) { return(r); } r = res_temp; z.avail_in--; z.total_in++; z.istate.need += (((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L); z.istate.mode = InflateMode.CHECK1; goto case InflateMode.CHECK1; case InflateMode.CHECK1: if (z.avail_in == 0) { return(r); } r = res_temp; z.avail_in--; z.total_in++; z.istate.need += (z.next_in[z.next_in_index++] & 0xffL); if (unchecked (((int)(z.istate.was[0])) != ((int)(z.istate.need)))) { z.istate.mode = InflateMode.BAD; z.msg = "incorrect data check"; z.istate.marker = 5; // can't try inflateSync break; } z.istate.mode = InflateMode.DONE; goto case InflateMode.DONE; case InflateMode.DONE: return((int)ZLibResultCode.Z_STREAM_END); case InflateMode.BAD: return((int)ZLibResultCode.Z_DATA_ERROR); default: return((int)ZLibResultCode.Z_STREAM_ERROR); } } }
private static int Process(zlib.ZStream /*!*/ zst, zlib.FlushStrategy flush, bool compress, ref MutableString trailingUncompressedData) { if (zst.next_out == null) { zst.next_out = new byte[DEFAULTALLOC]; zst.next_out_index = 0; zst.avail_out = zst.next_out.Length; } int result = compress ? zst.deflate(flush) : zst.inflate(flush); while (result == Z_OK && zst.avail_out == 0) { byte[] output = zst.next_out; int oldLength = output.Length; Array.Resize(ref output, oldLength * 2); zst.next_out = output; zst.avail_out = oldLength; result = compress ? zst.deflate(flush) : zst.inflate(flush); } if (!compress && (result == Z_STREAM_END || result == Z_STREAM_ERROR && !zst.IsInitialized)) { // MRI hack: any data left in the stream are saved into a separate buffer and returned when "finish" is called // This is weird behavior, one would expect the rest of the stream is either ignored or copied to the output buffer. #if COPY_UNCOMPRESSED_DATA_TO_OUTPUT_BUFFER Debug.Assert(zst.next_in_index + zst.avail_in <= zst.next_in.Length); Debug.Assert(zst.next_out_index + zst.avail_out <= zst.next_out.Length); if (zst.avail_in > zst.avail_out) { byte[] output = zst.next_out; int oldLength = output.Length; Array.Resize(ref output, Math.Max(zst.next_out_index + zst.avail_in, oldLength * 2)); zst.next_out = output; } Buffer.BlockCopy(zst.next_in, zst.next_in_index, zst.next_out, zst.next_out_index, zst.avail_in); // MRI subtracts till 0 is reached: zst.avail_out = Math.Max(zst.avail_out - zst.avail_in, 0); zst.next_out_index += zst.avail_in; zst.avail_in = 0; #else if (trailingUncompressedData == null) { trailingUncompressedData = MutableString.CreateBinary(); } trailingUncompressedData.Append(zst.next_in, zst.next_in_index, zst.avail_in); // MRI subtracts till 0 is reached: zst.avail_out = Math.Max(zst.avail_out - zst.avail_in, 0); zst.avail_in = 0; #endif result = Z_STREAM_END; } return(result); }
public static int AvailIn(ZStream/*!*/ self) { return self.GetStream().avail_in; }
/// <summary> /// Creates header remover. /// As long as header is not completed, call to Remover.MoveNext() returns true and /// adjust state of z. /// </summary> /// <param name="z">Stream where gzip header will appear.</param> /// <returns></returns> public static IEnumerator <object> CreateRemover(ZStream z) { return(new GzipHeader().StartHeaderSkipping(z).GetEnumerator()); }
public static int DataType(ZStream/*!*/ self) { return (int)self.GetStream().Data_type; }
/// <summary> /// Initializes deflate algorithm /// </summary> /// <param name="strm">ZStream object</param> /// <param name="level">Compression level</param> /// <returns>Operation result result code</returns> internal int deflateInit(ZStream strm, int level) { return deflateInit(strm, level, ZLibUtil.MAX_WBITS); }
public static MutableString FlushNextOut(ZStream/*!*/ self) { throw new NotImplementedError(); }
/// <summary> /// Resets the current state of deflate object /// </summary> internal int deflateReset(ZStream strm) { strm.total_in = strm.total_out = 0; strm.msg = null; // strm.Data_type = BlockType.Z_UNKNOWN; pending = 0; Pending_out = 0; if (NoHeader < 0) { NoHeader = 0; // was set to -1 by deflate(..., Z_FINISH); } status = (NoHeader != 0) ? DeflateState.BUSY_STATE : DeflateState.INIT_STATE; strm.adler = Adler32.GetAdler32Checksum(0, null, 0, 0); last_flush = (int)FlushStrategy.Z_NO_FLUSH; tr_init(); lm_init(); return (int)ZLibResultCode.Z_OK; }
public static bool IsClosed(ZStream/*!*/ self) { var zst = self._stream; return zst == null || !zst.IsInitialized; }
/// <summary> /// Sets deflate dictionary /// </summary> internal int deflateSetDictionary(ZStream strm, byte[] dictionary, int dictLength) { int length = dictLength; int index = 0; if (dictionary == null || status != DeflateState.INIT_STATE) return (int)ZLibResultCode.Z_STREAM_ERROR; strm.adler = Adler32.GetAdler32Checksum(strm.adler, dictionary, 0, dictLength); if (length < MIN_MATCH) return (int)ZLibResultCode.Z_OK; if (length > w_size - MIN_LOOKAHEAD) { length = w_size - MIN_LOOKAHEAD; index = dictLength - length; // use the tail of the dictionary } Array.Copy(dictionary, index, window, 0, length); strstart = length; block_start = length; // Insert all strings in the hash table (except for the last two bytes). // s->lookahead stays null, so s->ins_h will be recomputed at the next // call of fill_window. ins_h = window[0] & 0xff; ins_h = (((ins_h) << hash_shift) ^ (window[1] & 0xff)) & hash_mask; for (int n = 0; n <= length - MIN_MATCH; n++) { ins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; prev[n & w_mask] = head[ins_h]; head[ins_h] = (short)n; } return (int)ZLibResultCode.Z_OK; }
public static int SetAvailOut(ZStream/*!*/ self, int size) { long newBufferSize; var zst = self.GetStream(); if (size < 0 || (newBufferSize = zst.next_out_index + size) > Int32.MaxValue) { throw RubyExceptions.CreateArgumentError("negative string size (or size too big)"); } int old = zst.avail_out; // Make sure we have enough space in the buffer. // We could keep the buffer larger but since users are calling // this API explicitly they probably want to resize the buffer. var output = zst.next_out; Array.Resize(ref output, (int)newBufferSize); zst.next_out = output; zst.avail_out = size; return old; }
/// <summary> /// copy as much as possible from the sliding Window to the output area /// </summary> internal int inflate_flush(ZStream z, int r) { int n; int p; int q; // local copies of source and destination pointers p = z.next_out_index; q = ReadPos; // compute number of bytes to copy as far as End of Window n = (int)((q <= WritePos?WritePos:End) - q); if (n > z.avail_out) { n = z.avail_out; } if (n != 0 && r == (int)ZLibResultCode.Z_BUF_ERROR) { r = (int)ZLibResultCode.Z_OK; } // update counters z.avail_out -= n; z.total_out += n; // update check information if (this.needCheck) { z.adler = check = Adler32.GetAdler32Checksum(check, Window, q, n); } // copy as far as End of Window Array.Copy(Window, q, z.next_out, p, n); p += n; q += n; // see if more to copy at beginning of Window if (q == End) { // wrap pointers q = 0; if (WritePos == End) { WritePos = 0; } // compute bytes to copy n = WritePos - q; if (n > z.avail_out) { n = z.avail_out; } if (n != 0 && r == (int)ZLibResultCode.Z_BUF_ERROR) { r = (int)ZLibResultCode.Z_OK; } // update counters z.avail_out -= n; z.total_out += n; // update check information if (this.needCheck) { z.adler = check = Adler32.GetAdler32Checksum(check, Window, q, n); } // copy Array.Copy(Window, q, z.next_out, p, n); p += n; q += n; } // update pointers z.next_out_index = p; ReadPos = q; // done return(r); }
/// <summary> /// Deflate algorithm initialization /// </summary> /// <param name="strm">ZStream object</param> /// <param name="level">Compression level</param> /// <param name="bits">Window bits</param> /// <returns>A result code</returns> internal int deflateInit(ZStream strm, int level, int bits) { return deflateInit2(strm, level, Z_DEFLATED, bits, DEF_MEM_LEVEL, CompressionStrategy.Z_DEFAULT_STRATEGY); }
/// <summary> /// Sets dictionary for the inflate operation /// </summary> /// <param name="z">A ZStream object</param> /// <param name="dictionary">An array of byte - dictionary</param> /// <param name="dictLength">Dictionary length</param> /// <returns>Operation result code</returns> internal int inflateSetDictionary(ZStream z, byte[] dictionary, int dictLength) { int index = 0; int length = dictLength; if (z == null || z.istate == null || z.istate.mode != InflateMode.DICT0) return (int)ZLibResultCode.Z_STREAM_ERROR; if (Adler32.GetAdler32Checksum(1L, dictionary, 0, dictLength) != z.adler) { return (int)ZLibResultCode.Z_DATA_ERROR; } z.adler = Adler32.GetAdler32Checksum(0, null, 0, 0); if (length >= (1 << z.istate.wbits)) { length = (1 << z.istate.wbits) - 1; index = dictLength - length; } z.istate.blocks.set_dictionary(dictionary, index, length); z.istate.mode = InflateMode.BLOCKS; return (int)ZLibResultCode.Z_OK; }
/// <summary> /// Deflate algorithm initialization /// </summary> /// <param name="strm">ZStream object</param> /// <param name="level">Compression level</param> /// <param name="method">Compression method</param> /// <param name="windowBits">Window bits</param> /// <param name="memLevel">Memory level</param> /// <param name="strategy">Compression strategy</param> /// <returns>Operation result code</returns> internal int deflateInit2(ZStream strm, int level, int method, int windowBits, int memLevel, CompressionStrategy strategy) { int noheader = 0; strm.msg = null; if (level == Z_DEFAULT_COMPRESSION) level = 6; if (windowBits < 0) { // undocumented feature: suppress zlib header noheader = 1; windowBits = -windowBits; } if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > CompressionStrategy.Z_HUFFMAN_ONLY) { return (int)ZLibResultCode.Z_STREAM_ERROR; } strm.dstate = (Deflate)this; this.NoHeader = noheader; w_bits = windowBits; w_size = 1 << w_bits; w_mask = w_size - 1; hash_bits = memLevel + 7; hash_size = 1 << hash_bits; hash_mask = hash_size - 1; hash_shift = ((hash_bits + MIN_MATCH - 1) / MIN_MATCH); window = new byte[w_size * 2]; prev = new short[w_size]; head = new short[hash_size]; lit_bufsize = 1 << (memLevel + 6); // 16K elements by default // We overlay Pending_buf and d_buf+l_buf. This works since the average // output size for (length,distance) codes is <= 24 bits. Pending_buf = new byte[lit_bufsize * 4]; pending_buf_size = lit_bufsize * 4; d_buf = lit_bufsize; l_buf = (1 + 2) * lit_bufsize; this.level = level; this.strategy = strategy; this.method = (byte)method; return deflateReset(strm); }
/// <summary> /// Constructor which takes literal, distance trees, corresponding bites decoded for branches and a ZStream object /// </summary> internal InfCodes(int bl, int bd, int[] tl, int[] td, ZStream z) { mode = InflateCodesMode.START; lbits = (byte) bl; dbits = (byte) bd; ltree = tl; ltree_index = 0; dtree = td; dtree_index = 0; }
/// <summary> /// Sets deflate algorithm parameters /// </summary> internal int deflateParams(ZStream strm, int level, CompressionStrategy strategy) { int err = (int)ZLibResultCode.Z_OK; if (level == Z_DEFAULT_COMPRESSION) { level = 6; } if (level < 0 || level > 9 || strategy < 0 || strategy > CompressionStrategy.Z_HUFFMAN_ONLY) { return (int)ZLibResultCode.Z_STREAM_ERROR; } if (config_table[this._level].func != config_table[level].func && strm.total_in != 0) { // Flush the last buffer: err = strm.deflate(FlushStrategy.Z_PARTIAL_FLUSH); } if (this._level != level) { this._level = level; max_lazy_match = config_table[this._level].max_lazy; good_match = config_table[this._level].good_length; nice_match = config_table[this._level].nice_length; max_chain_length = config_table[this._level].max_chain; } this.strategy = strategy; return err; }
/// <summary> /// Frees allocated resources /// </summary> internal void free(ZStream z) { }
/// <summary> /// Performs data compression with the deflate algorithm /// </summary> internal int deflate(ZStream strm, FlushStrategy f) { int old_flush; int internalFlush = (int)f; if (internalFlush > (int)FlushStrategy.Z_FINISH || internalFlush < 0) { return (int)ZLibResultCode.Z_STREAM_ERROR; } if (strm.next_out == null || (strm.next_in == null && strm.avail_in != 0) || (status == DeflateState.FINISH_STATE && internalFlush != (int)FlushStrategy.Z_FINISH)) { strm.msg = ZLibUtil.z_errmsg[(int)ZLibResultCode.Z_NEED_DICT - ((int)ZLibResultCode.Z_STREAM_ERROR)]; return (int)ZLibResultCode.Z_STREAM_ERROR; } if (strm.avail_out == 0) { strm.msg = ZLibUtil.z_errmsg[(int)ZLibResultCode.Z_NEED_DICT - ((int)ZLibResultCode.Z_BUF_ERROR)]; return (int)ZLibResultCode.Z_DATA_ERROR; } this.strm = strm; // just in case old_flush = last_flush; last_flush = internalFlush; // Write the zlib header if (status == DeflateState.INIT_STATE) { int header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8; int level_flags = ((level - 1) & 0xff) >> 1; if (level_flags > 3) level_flags = 3; header |= (level_flags << 6); if (strstart != 0) header |= PRESET_DICT; header += 31 - (header % 31); status = DeflateState.BUSY_STATE; putShortMSB(header); // Save the adler32 of the preset dictionary: if (strstart != 0) { putShortMSB((int)(ZLibUtil.URShift(strm.adler, 16))); putShortMSB((int)(strm.adler & 0xffff)); } strm.adler = Adler32.GetAdler32Checksum(0, null, 0, 0); } // Flush as much pending output as possible if (pending != 0) { strm.flush_pending(); if (strm.avail_out == 0) { //System.out.println(" _avail_out==0"); // Since _avail_out is 0, deflate will be called again with // more output space, but possibly with both pending and // _avail_in equal to zero. There won't be anything to do, // but this is not an error situation so make sure we // return OK instead of BUF_ERROR at next call of deflate: last_flush = -1; return (int)ZLibResultCode.Z_OK; } // Make sure there is something to do and avoid duplicate consecutive // flushes. For repeated and useless calls with Z_FINISH, we keep // returning (int)ZLibResultCode.Z_STREAM_END instead of Z_BUFF_ERROR. } else if (strm.avail_in == 0 && internalFlush <= old_flush && internalFlush != (int)FlushStrategy.Z_FINISH) { strm.msg = ZLibUtil.z_errmsg[(int)ZLibResultCode.Z_NEED_DICT - ((int)ZLibResultCode.Z_BUF_ERROR)]; return (int)ZLibResultCode.Z_DATA_ERROR; } // User must not provide more input after the first FINISH: if (status == DeflateState.FINISH_STATE && strm.avail_in != 0) { strm.msg = ZLibUtil.z_errmsg[(int)ZLibResultCode.Z_NEED_DICT - ((int)ZLibResultCode.Z_BUF_ERROR)]; return (int)ZLibResultCode.Z_DATA_ERROR; } // Start a new block or continue the current one. if (strm.avail_in != 0 || lookahead != 0 || (internalFlush != (int)FlushStrategy.Z_NO_FLUSH && status != DeflateState.FINISH_STATE)) { int bstate = - 1; switch (config_table[level].func) { case STORED: bstate = deflate_stored(internalFlush); break; case FAST: bstate = deflate_fast(internalFlush); break; case SLOW: bstate = deflate_slow(internalFlush); break; default: break; } if (bstate == FinishStarted || bstate == FinishDone) { status = DeflateState.FINISH_STATE; } if (bstate == NeedMore || bstate == FinishStarted) { if (strm.avail_out == 0) { last_flush = -1; // avoid BUF_ERROR next call, see above } return (int)ZLibResultCode.Z_OK; // If internalFlush != Z_NO_FLUSH && _avail_out == 0, the next call // of deflate should use the same internalFlush parameter to make sure // that the internalFlush is complete. So we don't have to output an // empty block here, this will be done at next call. This also // ensures that for a very small output buffer, we emit at most // one empty block. } if (bstate == BlockDone) { if (internalFlush == (int)FlushStrategy.Z_PARTIAL_FLUSH) { _tr_align(); } else { // FULL_FLUSH or SYNC_FLUSH _tr_stored_block(0, 0, false); // For a full internalFlush, this empty block will be recognized // as a special marker by inflate_sync(). if (internalFlush == (int)FlushStrategy.Z_FULL_FLUSH) { for (int i = 0; i < hash_size; i++) // forget history head[i] = 0; } } strm.flush_pending(); if (strm.avail_out == 0) { last_flush = -1; // avoid BUF_ERROR at next call, see above return (int)ZLibResultCode.Z_OK; } } } if (internalFlush != (int)FlushStrategy.Z_FINISH) return (int)ZLibResultCode.Z_OK; if (NoHeader != 0) return (int)ZLibResultCode.Z_STREAM_END; // Write the zlib trailer (adler32) putShortMSB((int) (ZLibUtil.URShift(strm.adler, 16))); putShortMSB((int) (strm.adler & 0xffff)); strm.flush_pending(); // If _avail_out is zero, the application will call deflate again // to internalFlush the rest. NoHeader = - 1; // WritePos the trailer only once! return pending != 0 ? (int)ZLibResultCode.Z_OK : (int)ZLibResultCode.Z_STREAM_END; }
/// <summary> /// Block processing functions /// </summary> 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 WritePos pointer int m; // bytes to End of Window or ReadPos pointer // copy input/output information to locals (UPDATE macro restores) { p = z.next_in_index; n = z.avail_in; b = BitB; k = BitK; } { q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); } // process input based on current state while (true) { switch (mode) { case InflateBlockMode.TYPE: while (k < (3)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = (int)(b & 7); last = t & 1; switch (ZLibUtil.URShift(t, 1)) { case 0: // stored { b = ZLibUtil.URShift(b, (3)); k -= (3); } t = k & 7; // go to byte boundary { b = ZLibUtil.URShift(b, (t)); k -= (t); } mode = InflateBlockMode.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 = ZLibUtil.URShift(b, (3)); k -= (3); } mode = InflateBlockMode.CODES; break; case 2: // dynamic { b = ZLibUtil.URShift(b, (3)); k -= (3); } mode = InflateBlockMode.TABLE; break; case 3: // illegal { b = ZLibUtil.URShift(b, (3)); k -= (3); } mode = InflateBlockMode.BAD; z.msg = "invalid block type"; r = (int)ZLibResultCode.Z_DATA_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } break; case InflateBlockMode.LENS: while (k < (32)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } if (((ZLibUtil.URShift((~b), 16)) & 0xffff) != (b & 0xffff)) { mode = InflateBlockMode.BAD; z.msg = "invalid stored block lengths"; r = (int)ZLibResultCode.Z_DATA_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } left = (b & 0xffff); b = k = 0; // dump bits mode = (left != 0) ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE); break; case InflateBlockMode.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; WritePos = q; return(inflate_flush(z, r)); } if (m == 0) { if (q == End && ReadPos != 0) { q = 0; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); } if (m == 0) { WritePos = q; r = inflate_flush(z, r); q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); if (q == End && ReadPos != 0) { q = 0; m = (int)(q < ReadPos ? ReadPos - 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; WritePos = q; return(inflate_flush(z, r)); } } } r = (int)ZLibResultCode.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 ? InflateBlockMode.DRY : InflateBlockMode.TYPE; break; case InflateBlockMode.TABLE: while (k < (14)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = 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 = InflateBlockMode.BAD; z.msg = "too many length or distance symbols"; r = (int)ZLibResultCode.Z_DATA_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); blens = new int[t]; { b = ZLibUtil.URShift(b, (14)); k -= (14); } index = 0; mode = InflateBlockMode.BTREE; goto case InflateBlockMode.BTREE; case InflateBlockMode.BTREE: while (index < 4 + (ZLibUtil.URShift(table, 10))) { while (k < (3)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } blens[ZLibUtil.border[index++]] = b & 7; { b = ZLibUtil.URShift(b, (3)); k -= (3); } } while (index < 19) { blens[ZLibUtil.border[index++]] = 0; } bb[0] = 7; t = InfTree.inflate_trees_bits(blens, bb, tb, hufts, z); if (t != (int)ZLibResultCode.Z_OK) { r = t; if (r == (int)ZLibResultCode.Z_DATA_ERROR) { blens = null; mode = InflateBlockMode.BAD; } BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } index = 0; mode = InflateBlockMode.DTREE; goto case InflateBlockMode.DTREE; case InflateBlockMode.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 = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = hufts[(tb[0] + (b & ZLibUtil.inflate_mask[t])) * 3 + 1]; c = hufts[(tb[0] + (b & ZLibUtil.inflate_mask[t])) * 3 + 2]; if (c < 16) { b = ZLibUtil.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 = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } b = ZLibUtil.URShift(b, (t)); k -= (t); j += (b & ZLibUtil.inflate_mask[i]); b = ZLibUtil.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 = InflateBlockMode.BAD; z.msg = "invalid bit length repeat"; r = (int)ZLibResultCode.Z_DATA_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = 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 != (int)ZLibResultCode.Z_OK) { if (t == (int)ZLibResultCode.Z_DATA_ERROR) { blens = null; mode = InflateBlockMode.BAD; } r = t; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } codes = new InfCodes(bl[0], bd[0], hufts, tl[0], hufts, td[0], z); } blens = null; mode = InflateBlockMode.CODES; goto case InflateBlockMode.CODES; case InflateBlockMode.CODES: BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; if ((r = codes.proc(this, z, r)) != (int)ZLibResultCode.Z_STREAM_END) { return(inflate_flush(z, r)); } r = (int)ZLibResultCode.Z_OK; codes.free(z); p = z.next_in_index; n = z.avail_in; b = BitB; k = BitK; q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); if (last == 0) { mode = InflateBlockMode.TYPE; break; } mode = InflateBlockMode.DRY; goto case InflateBlockMode.DRY; case InflateBlockMode.DRY: WritePos = q; r = inflate_flush(z, r); q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); if (ReadPos != WritePos) { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } mode = InflateBlockMode.DONE; goto case InflateBlockMode.DONE; case InflateBlockMode.DONE: r = (int)ZLibResultCode.Z_STREAM_END; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); case InflateBlockMode.BAD: r = (int)ZLibResultCode.Z_DATA_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); default: r = (int)ZLibResultCode.Z_STREAM_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } } }