module Protocol::HTTP::Body::Stream::Reader
def read(length = nil, buffer = nil)
@parameter buffer [String] the buffer which will receive the data
@parameterlength [Integer] the amount of data to read
If buffer is given, then the read data will be placed into buffer instead of a newly created String object.
If the length is not given, it will read all data until EOF, or return an empty string if the stream is already at EOF.
If given a non-negative length, it will read at most that many bytes from the stream. If the stream is at EOF, it will return nil.
Read data from the underlying stream.
def read(length = nil, buffer = nil) return "" if length == 0 buffer ||= String.new.force_encoding(Encoding::BINARY) # Take any previously buffered data and replace it into the given buffer. if @buffer buffer.replace(@buffer) @buffer = nil else buffer.clear end if length while buffer.bytesize < length and chunk = read_next buffer << chunk end # This ensures the subsequent `slice!` works correctly. buffer.force_encoding(Encoding::BINARY) # This will be at least one copy: @buffer = buffer.byteslice(length, buffer.bytesize) # This should be zero-copy: buffer.slice!(length, buffer.bytesize) if buffer.empty? return nil else return buffer end else while chunk = read_next buffer << chunk end return buffer end end