lib/http/2/buffer.rb in http-2-0.8.2 vs lib/http/2/buffer.rb in http-2-0.8.3

- old
+ new

@@ -1,37 +1,63 @@ +require 'forwardable' + module HTTP2 - # Simple binary buffer backed by string. + # Binary buffer wraps String. # - # TODO: Refactor, it would be better if Buffer were not a String subclass, - # but rather wrap a string and only expose the mutating API needed so that - # the possible surface for things to go wrong stays controllable. - # - https://github.com/igrigorik/http-2/pull/46 - # - class Buffer < String + class Buffer + extend Forwardable + + def_delegators :@buffer, :ord, :encoding, :setbyte, :unpack, + :size, :each_byte, :to_str, :to_s, :length, :inspect, + :[], :[]=, :empty?, :bytesize, :include? + UINT32 = 'N'.freeze private_constant :UINT32 # Forces binary encoding on the string - def initialize(*) - super.force_encoding(Encoding::BINARY) + def initialize(str = '') + str = str.dup if str.frozen? + @buffer = str.force_encoding(Encoding::BINARY) end # Emulate StringIO#read: slice first n bytes from the buffer. # # @param n [Integer] number of bytes to slice from the buffer def read(n) - Buffer.new(slice!(0, n)) + Buffer.new(@buffer.slice!(0, n)) end - # Alias getbyte to readbyte - alias_method :readbyte, :getbyte - # Emulate StringIO#getbyte: slice first byte from buffer. def getbyte read(1).ord end + def slice!(*args) + Buffer.new(@buffer.slice!(*args)) + end + + def slice(*args) + Buffer.new(@buffer.slice(*args)) + end + + def force_encoding(*args) + @buffer = @buffer.force_encoding(*args) + end + + def ==(other) + @buffer == other + end + + def +(other) + @buffer += other + end + + # Emulate String#getbyte: return nth byte from buffer. + def readbyte(n) + @buffer[n].ord + end + # Slice unsigned 32-bit integer from buffer. # @return [Integer] def read_uint32 read(4).unpack(UINT32).first end @@ -39,10 +65,12 @@ # Ensures that data that is added is binary encoded as well, # otherwise this could lead to the Buffer instance changing its encoding. [:<<, :prepend].each do |mutating_method| define_method(mutating_method) do |string| string = string.dup if string.frozen? - super(string.force_encoding(Encoding::BINARY)) + @buffer.send mutating_method, string.force_encoding(Encoding::BINARY) + + self end end end end