示例#1
0
        public bool ReadHeader(InputBuffer input)
        {
            while (true)
            {
                int bits;
                switch (gzipHeaderSubstate)
                {
                case GzipHeaderState.ReadingID1:
                    bits = input.GetBits(8);
                    if (bits < 0)
                    {
                        return(false);
                    }

                    if (bits != GZipConstants.ID1)
                    {
                        throw new InvalidDataException("CorruptedGZipHeader");
                    }
                    gzipHeaderSubstate = GzipHeaderState.ReadingID2;
                    goto case GzipHeaderState.ReadingID2;

                case GzipHeaderState.ReadingID2:
                    bits = input.GetBits(8);
                    if (bits < 0)
                    {
                        return(false);
                    }

                    if (bits != GZipConstants.ID2)
                    {
                        throw new InvalidDataException("CorruptedGZipHeader");
                    }

                    gzipHeaderSubstate = GzipHeaderState.ReadingCM;
                    goto case GzipHeaderState.ReadingCM;

                case GzipHeaderState.ReadingCM:
                    bits = input.GetBits(8);
                    if (bits < 0)
                    {
                        return(false);
                    }

                    if (bits != GZipConstants.Deflate)
                    {             // compression mode must be 8 (deflate)
                        throw new InvalidDataException("UnknownCompressionMode");
                    }

                    gzipHeaderSubstate = GzipHeaderState.ReadingFLG;;
                    goto case GzipHeaderState.ReadingFLG;

                case GzipHeaderState.ReadingFLG:
                    bits = input.GetBits(8);
                    if (bits < 0)
                    {
                        return(false);
                    }

                    gzip_header_flag   = bits;
                    gzipHeaderSubstate = GzipHeaderState.ReadingMMTime;
                    loopCounter        = 0; // 4 MMTIME bytes
                    goto case GzipHeaderState.ReadingMMTime;

                case GzipHeaderState.ReadingMMTime:
                    bits = 0;
                    while (loopCounter < 4)
                    {
                        bits = input.GetBits(8);
                        if (bits < 0)
                        {
                            return(false);
                        }

                        loopCounter++;
                    }

                    gzipHeaderSubstate = GzipHeaderState.ReadingXFL;
                    loopCounter        = 0;
                    goto case GzipHeaderState.ReadingXFL;

                case GzipHeaderState.ReadingXFL:          // ignore XFL
                    bits = input.GetBits(8);
                    if (bits < 0)
                    {
                        return(false);
                    }

                    gzipHeaderSubstate = GzipHeaderState.ReadingOS;
                    goto case GzipHeaderState.ReadingOS;

                case GzipHeaderState.ReadingOS:          // ignore OS
                    bits = input.GetBits(8);
                    if (bits < 0)
                    {
                        return(false);
                    }

                    gzipHeaderSubstate = GzipHeaderState.ReadingXLen1;
                    goto case GzipHeaderState.ReadingXLen1;

                case GzipHeaderState.ReadingXLen1:
                    if ((gzip_header_flag & (int)GZipOptionalHeaderFlags.ExtraFieldsFlag) == 0)
                    {
                        goto case GzipHeaderState.ReadingFileName;
                    }

                    bits = input.GetBits(8);
                    if (bits < 0)
                    {
                        return(false);
                    }

                    gzip_header_xlen   = bits;
                    gzipHeaderSubstate = GzipHeaderState.ReadingXLen2;
                    goto case GzipHeaderState.ReadingXLen2;

                case GzipHeaderState.ReadingXLen2:
                    bits = input.GetBits(8);
                    if (bits < 0)
                    {
                        return(false);
                    }

                    gzip_header_xlen  |= (bits << 8);
                    gzipHeaderSubstate = GzipHeaderState.ReadingXLenData;
                    loopCounter        = 0; // 0 bytes of XLEN data read so far
                    goto case GzipHeaderState.ReadingXLenData;

                case GzipHeaderState.ReadingXLenData:
                    bits = 0;
                    while (loopCounter < gzip_header_xlen)
                    {
                        bits = input.GetBits(8);
                        if (bits < 0)
                        {
                            return(false);
                        }

                        loopCounter++;
                    }
                    gzipHeaderSubstate = GzipHeaderState.ReadingFileName;
                    loopCounter        = 0;
                    goto case GzipHeaderState.ReadingFileName;

                case GzipHeaderState.ReadingFileName:
                    if ((gzip_header_flag & (int)GZipOptionalHeaderFlags.FileNameFlag) == 0)
                    {
                        gzipHeaderSubstate = GzipHeaderState.ReadingComment;
                        goto case GzipHeaderState.ReadingComment;
                    }

                    do
                    {
                        bits = input.GetBits(8);
                        if (bits < 0)
                        {
                            return(false);
                        }

                        if (bits == 0)
                        {       // see '\0' in the file name string
                            break;
                        }
                    } while (true);

                    gzipHeaderSubstate = GzipHeaderState.ReadingComment;
                    goto case GzipHeaderState.ReadingComment;

                case GzipHeaderState.ReadingComment:
                    if ((gzip_header_flag & (int)GZipOptionalHeaderFlags.CommentFlag) == 0)
                    {
                        gzipHeaderSubstate = GzipHeaderState.ReadingCRC16Part1;
                        goto case GzipHeaderState.ReadingCRC16Part1;
                    }

                    do
                    {
                        bits = input.GetBits(8);
                        if (bits < 0)
                        {
                            return(false);
                        }

                        if (bits == 0)
                        {       // see '\0' in the file name string
                            break;
                        }
                    } while (true);

                    gzipHeaderSubstate = GzipHeaderState.ReadingCRC16Part1;
                    goto case GzipHeaderState.ReadingCRC16Part1;

                case GzipHeaderState.ReadingCRC16Part1:
                    if ((gzip_header_flag & (int)GZipOptionalHeaderFlags.CRCFlag) == 0)
                    {
                        gzipHeaderSubstate = GzipHeaderState.Done;
                        goto case GzipHeaderState.Done;
                    }

                    bits = input.GetBits(8);         // ignore crc
                    if (bits < 0)
                    {
                        return(false);
                    }

                    gzipHeaderSubstate = GzipHeaderState.ReadingCRC16Part2;
                    goto case GzipHeaderState.ReadingCRC16Part2;

                case GzipHeaderState.ReadingCRC16Part2:
                    bits = input.GetBits(8);         // ignore crc
                    if (bits < 0)
                    {
                        return(false);
                    }

                    gzipHeaderSubstate = GzipHeaderState.Done;
                    goto case GzipHeaderState.Done;

                case GzipHeaderState.Done:
                    return(true);

                default:
                    Debug.Assert(false, "We should not reach unknown state!");
                    throw new InvalidDataException("UnknownState");
                }
            }
        }