deprecate_class! :TFramedTransportFactory => FramedTransportFactory
class MemoryBuffer < Transport
+ GARBAGE_BUFFER_SIZE = 4*(2**10) # 4kB
+
# If you pass a string to this, you should #dup that string
# unless you want it to be modified by #read and #write
#--
- # yes this behavior is intentional
+ # this behavior is no longer required. If you wish to change it
+ # go ahead, just make sure the specs pass
def initialize(buffer = nil)
@buf = buffer || ''
+ @index = 0
end
def open?
end
def peek
- not @buf.empty?
+ @index < @buf.size
end
# this method does not use the passed object directly but copies it
def reset_buffer(new_buf = '')
@buf.replace new_buf
+ @index = 0
end
def available
- @buf.length
+ @buf.length - @index
end
def read(len)
- @buf.slice!(0, len)
+ data = @buf.slice(@index, len)
+ @index += len
+ @index = @buf.size if @index > @buf.size
+ if @index >= GARBAGE_BUFFER_SIZE
+ @buf = @buf.slice(@index..-1)
+ @index = 0
+ end
+ data
end
def write(wbuf)
# For fast binary protocol access
def borrow(size = nil)
if size.nil?
- @buf[0..-1]
+ @buf[@index..-1]
else
- if size > @buf.length
+ if size > available
raise EOFError # Memory buffers only get one shot.
else
- @buf[0..size]
+ @buf[@index, size]
end
end
end
- def consume!(size)
- @buf.slice!(0, size)
- end
+ alias_method :consume!, :read
end
deprecate_class! :TMemoryBuffer => MemoryBuffer
s = "this is a test"
@buffer = MemoryBuffer.new(s)
@buffer.read(4).should == "this"
- s.should == " is a test"
+ s.slice!(-4..-1)
+ @buffer.read(@buffer.available).should == " is a "
end
it "should always remain open" do