public bool ReadGzipFooter()
        {
            input.SkipToByteBoundary();
            if (gzipFooterSubstate == GZIPHeaderState.ReadingCRC)
            {
                while (loopCounter < 4)
                {
                    int bits = input.GetBits(8);
                    if (bits < 0)
                    {
                        return(false);
                    }

                    gzipCrc32 |= ((uint)bits << (8 * loopCounter));
                    loopCounter++;
                }
                gzipFooterSubstate = GZIPHeaderState.ReadingFileSize;
                loopCounter        = 0;
            }

            if (gzipFooterSubstate == GZIPHeaderState.ReadingFileSize)
            {
                if (loopCounter == 0)
                {
                    gzipOutputStreamSize = 0;
                }

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

                    gzipOutputStreamSize |= ((uint)bits << (8 * loopCounter));
                    loopCounter++;
                }
            }

            return(true);
        }
Exemple #2
0
        // Format of Non-compressed blocks (BTYPE=00): 
        //
        // Any bits of input up to the next byte boundary are ignored. 
        // The rest of the block consists of the following information: 
        //
        //     0   1   2   3   4... 
        //   +---+---+---+---+================================+
        //   |  LEN  | NLEN  |... LEN bytes of literal data...|
        //   +---+---+---+---+================================+
        // 
        // LEN is the number of data bytes in the block.  NLEN is the
        // one's complement of LEN. 

        private bool DecodeUncompressedBlock(out bool endOfBlock)
        {
            endOfBlock = false;
            while (true)
            {
                switch (_state)
                {
                    case InflaterState.UncompressedAligning: // intial state when calling this function 
                        // we must skip to a byte boundary
                        _input.SkipToByteBoundary();
                        _state = InflaterState.UncompressedByte1;
                        goto case InflaterState.UncompressedByte1;

                    case InflaterState.UncompressedByte1: // decoding block length
                    case InflaterState.UncompressedByte2:
                    case InflaterState.UncompressedByte3:
                    case InflaterState.UncompressedByte4:
                        int bits = _input.GetBits(8);
                        if (bits < 0)
                        {
                            return false;
                        }

                        _blockLengthBuffer[_state - InflaterState.UncompressedByte1] = (byte) bits;
                        if (_state == InflaterState.UncompressedByte4)
                        {
                            _blockLength = _blockLengthBuffer[0] + (_blockLengthBuffer[1])*256;
                            int blockLengthComplement = _blockLengthBuffer[2] + (_blockLengthBuffer[3])*256;

                            // make sure complement matches 
                            if ((ushort) _blockLength != (ushort) (~blockLengthComplement))
                            {
                                throw new InvalidDataException("SR.InvalidBlockLength");
                            }
                        }

                        _state += 1;
                        break;

                    case InflaterState.DecodingUncompressed: // copying block data 

                        // Directly copy bytes from input to output. 
                        int bytesCopied = _output.CopyFrom(_input, _blockLength);
                        _blockLength -= bytesCopied;

                        if (_blockLength == 0)
                        {
                            // Done with this block, need to re-init bit buffer for next block
                            _state = InflaterState.ReadingBFinal;
                            endOfBlock = true;

                            return true;
                        }

                        // We can fail to copy all bytes for two reasons:
                        //    Running out of Input 
                        //    running out of free space in output window
                        if (_output.FreeBytes == 0)
                        {
                            return true;
                        }

                        return false;

                    default:
                        Debug.Assert(false, "check why we are here!");
                        throw new InvalidDataException("SR.UnknownState");
                }
            }
        }