Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
                }
            }
        }