Class: Protocol::HTTP::Body::Inflate

Inherits:
ZStream show all
Defined in:
lib/protocol/http/body/inflate.rb

Overview

A body which decompresses the contents using the DEFLATE or GZIP algorithm.

Constant Summary

Constants inherited from ZStream

ZStream::DEFAULT_LEVEL, ZStream::DEFLATE, ZStream::ENCODINGS, ZStream::GZIP

Instance Attribute Summary

Attributes inherited from ZStream

#input_length, #input_length the total number of bytes read from the input., #output_length, #output_length the total number of bytes written to the output.

Attributes inherited from Wrapper

#body

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ZStream

#as_json, #close, #initialize, #inspect, #length, #ratio

Methods inherited from Wrapper

#The wrapped body.=, #as_json, #buffered, #close, #discard, #empty?, #initialize, #inspect, #length, #ready?, #rewind, #rewindable?, #to_json, wrap

Methods inherited from Readable

#as_json, #buffered, #call, #close, #discard, #each, #empty?, #finish, #join, #length, #ready?, #rewind, #rewindable?, #stream?, #to_json

Constructor Details

This class inherits a constructor from Protocol::HTTP::Body::ZStream

Class Method Details

.for(body, window_size = GZIP) ⇒ Object

Create a new body which decompresses the given body using the GZIP algorithm by default.



19
20
21
# File 'lib/protocol/http/body/inflate.rb', line 19

def self.for(body, window_size = GZIP)
  self.new(body, Zlib::Inflate.new(window_size))
end

Instance Method Details

#readObject

Read from the underlying stream and inflate it.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/protocol/http/body/inflate.rb', line 26

def read
  if stream = @stream
    # Read from the underlying stream and inflate it:
    while chunk = super
      @input_length += chunk.bytesize
      
      # It's possible this triggers the stream to finish.
      chunk = stream.inflate(chunk)
      
      break unless chunk&.empty?
    end
    
    if chunk
      @output_length += chunk.bytesize
    elsif !stream.closed?
      chunk = stream.finish
      @output_length += chunk.bytesize
    end
    
    # If the stream is finished, we need to close it and potentially return nil:
    if stream.finished?
      @stream = nil
      stream.close
      
      while super
        # There is data left in the stream, so we need to keep reading until it's all consumed.
      end
      
      if chunk.empty?
        return nil
      end
    end
    
    return chunk
  end
end