WriteLengthDistance() public method

public WriteLengthDistance ( int length, int distance ) : void
length int
distance int
return void
Esempio n. 1
0
        bool DecodeBlock(out bool end_of_block_code_seen)
        {
            end_of_block_code_seen = false;

            int freeBytes = output.FreeBytes;   // it is a little bit faster than frequently accessing the property

            while (freeBytes > 258)
            {
                // 258 means we can safely do decoding since maximum repeat length is 258

                int symbol;
                switch (state)
                {
                case InflaterState.DecodeTop:

                    symbol = literalLengthTree.GetNextSymbol(input);
                    if (symbol < 0)            // running out of input
                    {
                        return(false);
                    }

                    if (symbol < 256)          // literal
                    {
                        output.Write((byte)symbol);
                        --freeBytes;
                    }
                    else if (symbol == 256)   // end of block
                    {
                        end_of_block_code_seen = true;
                        Debug.WriteLineIf(CompressionTracingSwitch.Informational, "End of Block", "Compression");
                        // Reset state
                        state = InflaterState.ReadingBFinal;
                        return(true);      // ***********
                    }
                    else                   // length/distance pair
                    {
                        symbol -= 257;     // length code started at 257
                        if (symbol < 8)
                        {
                            symbol   += 3; // match length = 3,4,5,6,7,8,9,10
                            extraBits = 0;
                        }
                        else if (symbol == 28)   // extra bits for code 285 is 0
                        {
                            symbol    = 258;     // code 285 means length 258
                            extraBits = 0;
                        }
                        else
                        {
                            extraBits = extraLengthBits[symbol];
                            Debug.Assert(extraBits != 0, "We handle other cases seperately!");
                        }
                        length = symbol;
                        goto case InflaterState.HaveInitialLength;
                    }
                    break;

                case InflaterState.HaveInitialLength:
                    if (extraBits > 0)
                    {
                        state = InflaterState.HaveInitialLength;
                        int bits = input.GetBits(extraBits);
                        if (bits < 0)
                        {
                            return(false);
                        }
                        length = lengthBase[length] + bits;
                    }
                    state = InflaterState.HaveFullLength;
                    goto case InflaterState.HaveFullLength;

                case InflaterState.HaveFullLength:
                    if (blockType == BlockType.Dynamic)
                    {
                        distanceCode = distanceTree.GetNextSymbol(input);
                    }
                    else     // get distance code directly for static block
                    {
                        distanceCode = input.GetBits(5);
                        if (distanceCode >= 0)
                        {
                            distanceCode = staticDistanceTreeTable[distanceCode];
                        }
                    }

                    if (distanceCode < 0)   // running out input
                    {
                        return(false);
                    }

                    state = InflaterState.HaveDistCode;
                    goto case InflaterState.HaveDistCode;

                case InflaterState.HaveDistCode:
                    // To avoid a table lookup we note that for distanceCode >= 2,
                    // extra_bits = (distanceCode-2) >> 1
                    int offset;
                    if (distanceCode > 3)
                    {
                        extraBits = (distanceCode - 2) >> 1;
                        int bits = input.GetBits(extraBits);
                        if (bits < 0)
                        {
                            return(false);
                        }
                        offset = distanceBasePosition[distanceCode] + bits;
                    }
                    else
                    {
                        offset = distanceCode + 1;
                    }

                    Debug.Assert(freeBytes >= 258, "following operation is not safe!");
                    output.WriteLengthDistance(length, offset);
                    freeBytes -= length;
                    state      = InflaterState.DecodeTop;
                    break;

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

            return(true);
        }
Esempio n. 2
0
        private bool DecodeBlock(out bool end_of_block_code_seen)
        {
            end_of_block_code_seen = false;

            int freeBytes = _output.FreeBytes;   // it is a little bit faster than frequently accessing the property

            while (freeBytes > 65536)
            {
                // With Deflate64 we can have up to a 64kb length, so we ensure at least that much space is available
                // in the OutputWindow to avoid overwriting previous unflushed output data.

                int symbol;
                switch (_state)
                {
                case InflaterState.DecodeTop:
                    // decode an element from the literal tree

                    Debug.Assert(_literalLengthTree != null);
                    // TODO: optimize this!!!
                    symbol = _literalLengthTree.GetNextSymbol(_input);
                    if (symbol < 0)
                    {
                        // running out of input
                        return(false);
                    }

                    if (symbol < 256)
                    {
                        // literal
                        _output.Write((byte)symbol);
                        --freeBytes;
                    }
                    else if (symbol == 256)
                    {
                        // end of block
                        end_of_block_code_seen = true;
                        // Reset state
                        _state = InflaterState.ReadingBFinal;
                        return(true);
                    }
                    else
                    {
                        // length/distance pair
                        symbol -= 257;         // length code started at 257
                        if (symbol < 8)
                        {
                            symbol    += 3;    // match length = 3,4,5,6,7,8,9,10
                            _extraBits = 0;
                        }
                        else if (!_deflate64 && symbol == 28)
                        {
                            // extra bits for code 285 is 0
                            symbol     = 258;             // code 285 means length 258
                            _extraBits = 0;
                        }
                        else
                        {
                            if ((uint)symbol >= ExtraLengthBits.Length)
                            {
                                throw new InvalidDataException(SR.GenericInvalidData);
                            }
                            _extraBits = ExtraLengthBits[symbol];
                            Debug.Assert(_extraBits != 0, "We handle other cases separately!");
                        }
                        _length = symbol;
                        goto case InflaterState.HaveInitialLength;
                    }
                    break;

                case InflaterState.HaveInitialLength:
                    if (_extraBits > 0)
                    {
                        _state = InflaterState.HaveInitialLength;
                        int bits = _input.GetBits(_extraBits);
                        if (bits < 0)
                        {
                            return(false);
                        }

                        if (_length < 0 || _length >= s_lengthBase.Length)
                        {
                            throw new InvalidDataException(SR.GenericInvalidData);
                        }
                        _length = s_lengthBase[_length] + bits;
                    }
                    _state = InflaterState.HaveFullLength;
                    goto case InflaterState.HaveFullLength;

                case InflaterState.HaveFullLength:
                    if (_blockType == BlockType.Dynamic)
                    {
                        Debug.Assert(_distanceTree != null);
                        _distanceCode = _distanceTree.GetNextSymbol(_input);
                    }
                    else
                    {
                        // get distance code directly for static block
                        _distanceCode = _input.GetBits(5);
                        if (_distanceCode >= 0)
                        {
                            _distanceCode = StaticDistanceTreeTable[_distanceCode];
                        }
                    }

                    if (_distanceCode < 0)
                    {
                        // running out input
                        return(false);
                    }

                    _state = InflaterState.HaveDistCode;
                    goto case InflaterState.HaveDistCode;

                case InflaterState.HaveDistCode:
                    // To avoid a table lookup we note that for distanceCode > 3,
                    // extra_bits = (distanceCode-2) >> 1
                    int offset;
                    if (_distanceCode > 3)
                    {
                        _extraBits = (_distanceCode - 2) >> 1;
                        int bits = _input.GetBits(_extraBits);
                        if (bits < 0)
                        {
                            return(false);
                        }
                        offset = s_distanceBasePosition[_distanceCode] + bits;
                    }
                    else
                    {
                        offset = _distanceCode + 1;
                    }

                    _output.WriteLengthDistance(_length, offset);
                    freeBytes -= _length;
                    _state     = InflaterState.DecodeTop;
                    break;

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

            return(true);
        }