module IO::Stream::Readable
def consume_read_buffer(size = nil, buffer = nil)
@parameter buffer [String | Nil] An optional buffer to fill with data instead of allocating a new string.
@parameter size [Integer | Nil] The amount of data to consume. If nil, consume entire buffer.
Consumes at most `size` bytes from the buffer.
def consume_read_buffer(size = nil, buffer = nil) # If we are at finished, and the read buffer is empty, we can't consume anything. if @finished && @read_buffer.empty? # Clear the buffer even when returning nil if buffer buffer.clear buffer.force_encoding(Encoding::BINARY) end return nil end result = nil if size.nil? or size >= @read_buffer.bytesize # Consume the entire read buffer: if buffer buffer.clear buffer << @read_buffer result = buffer else result = @read_buffer end @read_buffer = StringBuffer.new else # We know that we are not going to reuse the original buffer. # But byteslice will generate a hidden copy. So let's freeze it first: @read_buffer.freeze if buffer # Use replace instead of clear + << for better performance buffer.replace(@read_buffer.byteslice(0, size)) result = buffer else result = @read_buffer.byteslice(0, size) end @read_buffer = @read_buffer.byteslice(size, @read_buffer.bytesize) end return result end