rb: Add FramedTransport#borrow/consume! [THRIFT-117]

This addition makes FramedTransport BinaryProtocolAccelerated ready.

Author: Bryan Duxbury


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@688901 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/rb/lib/thrift/transport.rb b/lib/rb/lib/thrift/transport.rb
index e4a70cd..abb4b1e 100644
--- a/lib/rb/lib/thrift/transport.rb
+++ b/lib/rb/lib/thrift/transport.rb
@@ -199,6 +199,17 @@
       @wbuf = ''
     end
 
+    def borrow(requested_length = 0)
+      read_frame if @rbuf.empty?
+      # there isn't any more coming, so if it's not enough, it's an error.
+      raise EOFError if requested_length > @rbuf.size
+      @rbuf
+    end
+    
+    def consume!(size)
+      @rbuf.slice!(0...size)
+    end
+
     private
 
     def read_frame
diff --git a/lib/rb/spec/transport_spec.rb b/lib/rb/spec/transport_spec.rb
index 98408ab..ef1918f 100644
--- a/lib/rb/spec/transport_spec.rb
+++ b/lib/rb/spec/transport_spec.rb
@@ -221,6 +221,40 @@
       @trans.should_receive(:write).with("\000\000\000\000")
       ftrans.flush
     end
+    
+    it "should refill its buffer when borrow is called and it is empty" do
+      ftrans = FramedTransport.new(@trans)
+      @trans.should_receive(:read_all).with(4).and_return([10].pack("N"))
+      @trans.should_receive(:read_all).with(10).and_return("1234567890")
+      ftrans.borrow(10).should == "1234567890"
+    end
+    
+    it "should not consume any data when borrow is called" do
+      ftrans = FramedTransport.new(@trans)
+      @trans.should_receive(:read_all).with(4).and_return([10].pack("N"))
+      @trans.should_receive(:read_all).with(10).and_return("1234567890")
+      ftrans.borrow(10).should == "1234567890"
+      ftrans.borrow(10).should == "1234567890"
+    end
+    
+    it "should remove data from the buffer when consume! is called" do
+      ftrans = FramedTransport.new(@trans)
+      @trans.should_receive(:read_all).with(4).ordered.and_return([10].pack("N"))
+      @trans.should_receive(:read_all).with(10).ordered.and_return("1234567890")
+      ftrans.borrow(5).should == "1234567890"
+      ftrans.consume!(5).should == "12345"
+      ftrans.borrow(5).should == "67890"
+    end
+    
+    it "should raise an EOFError when it is out of data and borrow is called" do
+      ftrans = FramedTransport.new(@trans)
+      @trans.should_receive(:read_all).with(4).ordered.and_return([10].pack("N"), [0].pack("N"))
+      @trans.should_receive(:read_all).with(10).ordered.and_return("1234567890")
+      @trans.should_receive(:read_all).with(0).ordered.and_return("")
+      ftrans.borrow(10).should == "1234567890"
+      ftrans.consume!(10).should == "1234567890"
+      lambda {ftrans.borrow(10)}.should raise_error(EOFError)
+    end
   end
 
   describe FramedTransportFactory do