/// <summary> /// Initializes the inflate algorithm /// </summary> /// <param name="z">A ZStream object</param> /// <param name="windowBits">Window size</param> /// <returns>Operation result code</returns> internal int inflateInit(ZStream z, int windowBits) { z.msg = null; blocks = null; // handle undocumented nowrap option (no zlib header or check) nowrap = 0; detectHeader = false; if (windowBits < 0) { // deflate, no header windowBits = -windowBits; nowrap = 1; } else if ((windowBits & 16) != 0) { gzipHeaderRemover = GzipHeader.CreateRemover(z); windowBits &= ~16; } else if ((windowBits & 32) != 0) { detectHeader = true; windowBits &= ~32; } // set Window size if (windowBits < 8 || windowBits > 15) { inflateEnd(z); return((int)ZLibResultCode.Z_STREAM_ERROR); } wbits = windowBits; z.istate.blocks = new InfBlocks(z, z.istate.nowrap == 0, 1 << windowBits); // reset state inflateReset(z); return((int)ZLibResultCode.Z_OK); }
/// <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 internalFlush = (int)flush; if (z?.istate == null || z.next_in == null) { return((int)ZLibResultCode.Z_STREAM_ERROR); } int res_temp = internalFlush == (int)FlushStrategy.Z_FINISH ? (int)ZLibResultCode.Z_BUF_ERROR : (int)ZLibResultCode.Z_OK; int 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++; int 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); } } }