Exemple #1
0
        public bool ReadFooter(InputBuffer input)
        {
            input.SkipToByteBoundary();
            if (gzipFooterSubstate == GzipHeaderState.ReadingCRC)
            {
                while (loopCounter < 4)
                {
                    int bits = input.GetBits(8);
                    if (bits < 0)
                    {
                        return(false);
                    }

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

            if (gzipFooterSubstate == GzipHeaderState.ReadingFileSize)
            {
                if (loopCounter == 0)
                {
                    expectedOutputStreamSize = 0;
                }

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

                    expectedOutputStreamSize |= ((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 end_of_block)
        {
            end_of_block = 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] + ((int)blockLengthBuffer[1]) * 256;
                        int blockLengthComplement = blockLengthBuffer[2] + ((int)blockLengthBuffer[3]) * 256;

                        // make sure complement matches
                        if ((ushort)blockLength != (ushort)(~blockLengthComplement))
                        {
                            throw new InvalidDataException("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;
                        end_of_block = true;
                        Debug.WriteLineIf(CompressionTracingSwitch.Informational, "End of Block", "Compression");
                        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("UnknownState");
                }
            }
        }