You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by ro...@apache.org on 2012/12/27 01:25:29 UTC

git commit: THRIFT-1766 [Ruby] Provide support for binary types Patch: Nathan Beyer

Updated Branches:
  refs/heads/master f089f8ee5 -> 19dbbefcc


THRIFT-1766 [Ruby] Provide support for binary types
Patch: Nathan Beyer


Project: http://git-wip-us.apache.org/repos/asf/thrift/repo
Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/19dbbefc
Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/19dbbefc
Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/19dbbefc

Branch: refs/heads/master
Commit: 19dbbefcc183abce5f502aadc83fc86b7edb90c7
Parents: f089f8e
Author: Roger Meier <ro...@apache.org>
Authored: Thu Dec 27 01:24:20 2012 +0100
Committer: Roger Meier <ro...@apache.org>
Committed: Thu Dec 27 01:24:20 2012 +0100

----------------------------------------------------------------------
 lib/rb/ext/binary_protocol_accelerated.c       |   22 ++++-
 lib/rb/ext/compact_protocol.c                  |   28 ++++--
 lib/rb/lib/thrift/protocol/base_protocol.rb    |   97 +++++++++++++++++--
 lib/rb/lib/thrift/protocol/binary_protocol.rb  |   18 +++-
 lib/rb/lib/thrift/protocol/compact_protocol.rb |   21 +++--
 lib/rb/lib/thrift/struct.rb                    |    2 +-
 lib/rb/lib/thrift/struct_union.rb              |    4 +-
 lib/rb/spec/base_protocol_spec.rb              |   72 +++++++++++++--
 lib/rb/spec/binary_protocol_spec_shared.rb     |   30 ++++++
 lib/rb/spec/compact_protocol_spec.rb           |    4 +-
 10 files changed, 253 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/thrift/blob/19dbbefc/lib/rb/ext/binary_protocol_accelerated.c
----------------------------------------------------------------------
diff --git a/lib/rb/ext/binary_protocol_accelerated.c b/lib/rb/ext/binary_protocol_accelerated.c
index a8ebe7f..8b27dbc 100644
--- a/lib/rb/ext/binary_protocol_accelerated.c
+++ b/lib/rb/ext/binary_protocol_accelerated.c
@@ -79,7 +79,7 @@ static void write_i64_direct(VALUE trans, int64_t value) {
 
 static void write_string_direct(VALUE trans, VALUE str) {
   if (TYPE(str) != T_STRING) {
-    rb_raise(rb_eStandardError, "Value should be a string");    
+    rb_raise(rb_eStandardError, "Value should be a string");
   }
   str = convert_to_utf8_byte_buffer(str);
   write_i32_direct(trans, RSTRING_LEN(str));
@@ -219,11 +219,21 @@ VALUE rb_thrift_binary_proto_write_string(VALUE self, VALUE str) {
   return Qnil;
 }
 
+VALUE rb_thrift_binary_proto_write_binary(VALUE self, VALUE buf) {
+  CHECK_NIL(buf);
+  VALUE trans = GET_TRANSPORT(self);
+  buf = force_binary_encoding(buf);
+  write_i32_direct(trans, RSTRING_LEN(buf));
+  rb_funcall(trans, write_method_id, 1, buf);
+  return Qnil;
+}
+
 //---------------------------------------
 // interface reading methods
 //---------------------------------------
 
 VALUE rb_thrift_binary_proto_read_string(VALUE self);
+VALUE rb_thrift_binary_proto_read_binary(VALUE self);
 VALUE rb_thrift_binary_proto_read_byte(VALUE self);
 VALUE rb_thrift_binary_proto_read_i32(VALUE self);
 VALUE rb_thrift_binary_proto_read_i16(VALUE self);
@@ -381,11 +391,15 @@ VALUE rb_thrift_binary_proto_read_double(VALUE self) {
 }
 
 VALUE rb_thrift_binary_proto_read_string(VALUE self) {
-  int size = read_i32_direct(self);
-  VALUE buffer = READ(self, size);
+  VALUE buffer = rb_thrift_binary_proto_read_binary(self);
   return convert_to_string(buffer);
 }
 
+VALUE rb_thrift_binary_proto_read_binary(VALUE self) {
+  int size = read_i32_direct(self);
+  return READ(self, size);
+}
+
 void Init_binary_protocol_accelerated() {
   VALUE thrift_binary_protocol_class = rb_const_get(thrift_module, rb_intern("BinaryProtocol"));
 
@@ -410,6 +424,7 @@ void Init_binary_protocol_accelerated() {
   rb_define_method(bpa_class, "write_i64",           rb_thrift_binary_proto_write_i64, 1);
   rb_define_method(bpa_class, "write_double",        rb_thrift_binary_proto_write_double, 1);
   rb_define_method(bpa_class, "write_string",        rb_thrift_binary_proto_write_string, 1);
+  rb_define_method(bpa_class, "write_binary",        rb_thrift_binary_proto_write_binary, 1);
   // unused methods
   rb_define_method(bpa_class, "write_message_end", rb_thrift_binary_proto_write_message_end, 0);
   rb_define_method(bpa_class, "write_struct_begin", rb_thrift_binary_proto_write_struct_begin, 1);
@@ -431,6 +446,7 @@ void Init_binary_protocol_accelerated() {
   rb_define_method(bpa_class, "read_i64",            rb_thrift_binary_proto_read_i64, 0);
   rb_define_method(bpa_class, "read_double",         rb_thrift_binary_proto_read_double, 0);
   rb_define_method(bpa_class, "read_string",         rb_thrift_binary_proto_read_string, 0);
+  rb_define_method(bpa_class, "read_binary",         rb_thrift_binary_proto_read_binary, 0);
   // unused methods
   rb_define_method(bpa_class, "read_message_end", rb_thrift_binary_proto_read_message_end, 0);
   rb_define_method(bpa_class, "read_struct_begin", rb_thift_binary_proto_read_struct_begin, 0);

http://git-wip-us.apache.org/repos/asf/thrift/blob/19dbbefc/lib/rb/ext/compact_protocol.c
----------------------------------------------------------------------
diff --git a/lib/rb/ext/compact_protocol.c b/lib/rb/ext/compact_protocol.c
index 0c05481..1637e99 100644
--- a/lib/rb/ext/compact_protocol.c
+++ b/lib/rb/ext/compact_protocol.c
@@ -167,6 +167,7 @@ static void write_collection_begin(VALUE transport, VALUE elem_type, VALUE size_
 
 VALUE rb_thrift_compact_proto_write_i32(VALUE self, VALUE i32);
 VALUE rb_thrift_compact_proto_write_string(VALUE self, VALUE str);
+VALUE rb_thrift_compact_proto_write_binary(VALUE self, VALUE buf);
 
 VALUE rb_thrift_compact_proto_write_message_end(VALUE self) {
   return Qnil;
@@ -305,10 +306,16 @@ VALUE rb_thrift_compact_proto_write_double(VALUE self, VALUE dub) {
 }
 
 VALUE rb_thrift_compact_proto_write_string(VALUE self, VALUE str) {
-  VALUE transport = GET_TRANSPORT(self);
   str = convert_to_utf8_byte_buffer(str);
-  write_varint32(transport, RSTRING_LEN(str));
-  WRITE(transport, RSTRING_PTR(str), RSTRING_LEN(str));
+  rb_thrift_compact_proto_write_binary(self, str);
+  return Qnil;
+}
+
+VALUE rb_thrift_compact_proto_write_binary(VALUE self, VALUE buf) {
+  buf = force_binary_encoding(buf);
+  VALUE transport = GET_TRANSPORT(self);
+  write_varint32(transport, RSTRING_LEN(buf));
+  WRITE(transport, RSTRING_PTR(buf), RSTRING_LEN(buf));
   return Qnil;
 }
 
@@ -319,6 +326,7 @@ VALUE rb_thrift_compact_proto_write_string(VALUE self, VALUE str) {
 #define is_bool_type(ctype) (((ctype) & 0x0F) == CTYPE_BOOLEAN_TRUE || ((ctype) & 0x0F) == CTYPE_BOOLEAN_FALSE)
 
 VALUE rb_thrift_compact_proto_read_string(VALUE self);
+VALUE rb_thrift_compact_proto_read_binary(VALUE self);
 VALUE rb_thrift_compact_proto_read_byte(VALUE self);
 VALUE rb_thrift_compact_proto_read_i32(VALUE self);
 VALUE rb_thrift_compact_proto_read_i16(VALUE self);
@@ -547,20 +555,24 @@ VALUE rb_thrift_compact_proto_read_double(VALUE self) {
 }
 
 VALUE rb_thrift_compact_proto_read_string(VALUE self) {
-  int64_t size = read_varint64(self);
-  VALUE buffer = READ(self, size);
+  VALUE buffer = rb_thrift_compact_proto_read_binary(self);
   return convert_to_string(buffer);
 }
 
+VALUE rb_thrift_compact_proto_read_binary(VALUE self) {
+  int64_t size = read_varint64(self);
+  return READ(self, size);
+}
+
 static void Init_constants() {
   thrift_compact_protocol_class = rb_const_get(thrift_module, rb_intern("CompactProtocol"));
-  
+
   VERSION = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("VERSION")));
   VERSION_MASK = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("VERSION_MASK")));
   TYPE_MASK = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("TYPE_MASK")));
   TYPE_SHIFT_AMOUNT = FIX2INT(rb_const_get(thrift_compact_protocol_class, rb_intern("TYPE_SHIFT_AMOUNT")));
   PROTOCOL_ID = FIX2INT(rb_const_get(thrift_compact_protocol_class, rb_intern("PROTOCOL_ID")));
-  
+
   last_field_id = rb_intern("@last_field");
   boolean_field_id = rb_intern("@boolean_field");
   bool_value_id = rb_intern("@bool_value");
@@ -583,6 +595,7 @@ static void Init_rb_methods() {
   rb_define_method(thrift_compact_protocol_class, "write_i64",           rb_thrift_compact_proto_write_i64, 1);
   rb_define_method(thrift_compact_protocol_class, "write_double",        rb_thrift_compact_proto_write_double, 1);
   rb_define_method(thrift_compact_protocol_class, "write_string",        rb_thrift_compact_proto_write_string, 1);
+  rb_define_method(thrift_compact_protocol_class, "write_binary",        rb_thrift_compact_proto_write_binary, 1);
 
   rb_define_method(thrift_compact_protocol_class, "write_message_end", rb_thrift_compact_proto_write_message_end, 0);
   rb_define_method(thrift_compact_protocol_class, "write_struct_begin", rb_thrift_compact_proto_write_struct_begin, 1);
@@ -605,6 +618,7 @@ static void Init_rb_methods() {
   rb_define_method(thrift_compact_protocol_class, "read_i64",            rb_thrift_compact_proto_read_i64, 0);
   rb_define_method(thrift_compact_protocol_class, "read_double",         rb_thrift_compact_proto_read_double, 0);
   rb_define_method(thrift_compact_protocol_class, "read_string",         rb_thrift_compact_proto_read_string, 0);
+  rb_define_method(thrift_compact_protocol_class, "read_binary",         rb_thrift_compact_proto_read_binary, 0);
 
   rb_define_method(thrift_compact_protocol_class, "read_message_end", rb_thrift_compact_proto_read_message_end, 0);
   rb_define_method(thrift_compact_protocol_class, "read_struct_begin",  rb_thrift_compact_proto_read_struct_begin, 0);

http://git-wip-us.apache.org/repos/asf/thrift/blob/19dbbefc/lib/rb/lib/thrift/protocol/base_protocol.rb
----------------------------------------------------------------------
diff --git a/lib/rb/lib/thrift/protocol/base_protocol.rb b/lib/rb/lib/thrift/protocol/base_protocol.rb
index a5a174d..2869cc8 100644
--- a/lib/rb/lib/thrift/protocol/base_protocol.rb
+++ b/lib/rb/lib/thrift/protocol/base_protocol.rb
@@ -125,6 +125,16 @@ module Thrift
       raise NotImplementedError
     end
 
+    # Writes a Thrift Binary (Thrift String with no encoding). In Ruby 1.9+, the String passed
+    # will forced into BINARY encoding.
+    #
+    # buf - The String to write.
+    #
+    # Returns nothing.
+    def write_binary(buf)
+      raise NotImplementedError
+    end
+
     def read_message_begin
       raise NotImplementedError
     end
@@ -185,21 +195,67 @@ module Thrift
       raise NotImplementedError
     end
 
-    # Reads a Thrift String. In Ruby 1.9+, all String will be returned with an Encoding of UTF-8.
+    # Reads a Thrift String. In Ruby 1.9+, all Strings will be returned with an Encoding of UTF-8.
     #
     # Returns a String.
     def read_string
       raise NotImplementedError
     end
 
-    def write_field(name, type, fid, value)
-      write_field_begin(name, type, fid)
-      write_type(type, value)
+    # Reads a Thrift Binary (Thrift String without encoding). In Ruby 1.9+, all Strings will be returned
+    # with an Encoding of BINARY.
+    #
+    # Returns a String.
+    def read_binary
+      raise NotImplementedError
+    end
+
+    # Writes a field based on the field information, field ID and value.
+    #
+    # field_info - A Hash containing the definition of the field:
+    #              :name   - The name of the field.
+    #              :type   - The type of the field, which must be a Thrift::Types constant.
+    #              :binary - A Boolean flag that indicates if Thrift::Types::STRING is a binary string (string without encoding).
+    # fid        - The ID of the field.
+    # value      - The field's value to write; object type varies based on :type.
+    #
+    # Returns nothing.
+    def write_field(*args)
+      if args.size == 3
+        # handles the documented method signature - write_field(field_info, fid, value)
+        field_info = args[0]
+        fid = args[1]
+        value = args[2]
+      elsif args.size == 4
+        # handles the deprecated method signature - write_field(name, type, fid, value)
+        field_info = {:name => args[0], :type => args[1]}
+        fid = args[2]
+        value = args[3]
+      else
+        raise ArgumentError, "wrong number of arguments (#{args.size} for 3)"
+      end
+
+      write_field_begin(field_info[:name], field_info[:type], fid)
+      write_type(field_info, value)
       write_field_end
     end
 
-    def write_type(type, value)
-      case type
+    # Writes a field value based on the field information.
+    #
+    # field_info - A Hash containing the definition of the field:
+    #              :type   - The Thrift::Types constant that determines how the value is written.
+    #              :binary - A Boolean flag that indicates if Thrift::Types::STRING is a binary string (string without encoding).
+    # value      - The field's value to write; object type varies based on field_info[:type].
+    #
+    # Returns nothing.
+    def write_type(field_info, value)
+      # if field_info is a Fixnum, assume it is a Thrift::Types constant
+      # convert it into a field_info Hash for backwards compatibility
+      if field_info.is_a? Fixnum
+        field_info = {:type => field_info}
+      end
+
+      case field_info[:type]
       when Types::BOOL
         write_bool(value)
       when Types::BYTE
@@ -213,7 +269,11 @@ module Thrift
       when Types::I64
         write_i64(value)
       when Types::STRING
-        write_string(value)
+        if field_info[:binary]
+          write_binary(value)
+        else
+          write_string(value)
+        end
       when Types::STRUCT
         value.write(self)
       else
@@ -221,8 +281,21 @@ module Thrift
       end
     end
 
-    def read_type(type)
-      case type
+    # Reads a field value based on the field information.
+    #
+    # field_info - A Hash containing the pertinent data to write:
+    #              :type   - The Thrift::Types constant that determines how the value is written.
+    #              :binary - A flag that indicates if Thrift::Types::STRING is a binary string (string without encoding).
+    #
+    # Returns the value read; object type varies based on field_info[:type].
+    def read_type(field_info)
+      # if field_info is a Fixnum, assume it is a Thrift::Types constant
+      # convert it into a field_info Hash for backwards compatibility
+      if field_info.is_a? Fixnum
+        field_info = {:type => field_info}
+      end
+
+      case field_info[:type]
       when Types::BOOL
         read_bool
       when Types::BYTE
@@ -236,7 +309,11 @@ module Thrift
       when Types::I64
         read_i64
       when Types::STRING
-        read_string
+        if field_info[:binary]
+          read_binary
+        else
+          read_string
+        end
       else
         raise NotImplementedError
       end

http://git-wip-us.apache.org/repos/asf/thrift/blob/19dbbefc/lib/rb/lib/thrift/protocol/binary_protocol.rb
----------------------------------------------------------------------
diff --git a/lib/rb/lib/thrift/protocol/binary_protocol.rb b/lib/rb/lib/thrift/protocol/binary_protocol.rb
index 2528276..e70b1e3 100644
--- a/lib/rb/lib/thrift/protocol/binary_protocol.rb
+++ b/lib/rb/lib/thrift/protocol/binary_protocol.rb
@@ -107,9 +107,13 @@ module Thrift
     end
 
     def write_string(str)
-      str = Bytes.convert_to_utf8_byte_buffer(str)
-      write_i32(str.length)
-      trans.write(str)
+      buf = Bytes.convert_to_utf8_byte_buffer(str)
+      write_binary(buf)
+    end
+
+    def write_binary(buf)
+      write_i32(buf.bytesize)
+      trans.write(buf)
     end
 
     def read_message_begin
@@ -214,11 +218,15 @@ module Thrift
     end
 
     def read_string
-      size = read_i32
-      buffer = trans.read_all(size)
+      buffer = read_binary
       Bytes.convert_to_string(buffer)
     end
 
+    def read_binary
+      size = read_i32
+      trans.read_all(size)
+    end
+
   end
 
   class BinaryProtocolFactory < BaseProtocolFactory

http://git-wip-us.apache.org/repos/asf/thrift/blob/19dbbefc/lib/rb/lib/thrift/protocol/compact_protocol.rb
----------------------------------------------------------------------
diff --git a/lib/rb/lib/thrift/protocol/compact_protocol.rb b/lib/rb/lib/thrift/protocol/compact_protocol.rb
index 758e1ae..07a6792 100644
--- a/lib/rb/lib/thrift/protocol/compact_protocol.rb
+++ b/lib/rb/lib/thrift/protocol/compact_protocol.rb
@@ -210,9 +210,13 @@ module Thrift
     end
 
     def write_string(str)
-      str = Bytes.convert_to_utf8_byte_buffer(str)
-      write_varint32(str.length)
-      @trans.write(str)
+      buf = Bytes.convert_to_utf8_byte_buffer(str)
+      write_binary(buf)
+    end
+
+    def write_binary(buf)
+      write_varint32(buf.bytesize)
+      @trans.write(buf)
     end
 
     def read_message_begin
@@ -332,12 +336,15 @@ module Thrift
     end
 
     def read_string
-      size = read_varint32()
-      buffer = trans.read_all(size)
+      buffer = read_binary
       Bytes.convert_to_string(buffer)
     end
-    
-    
+
+    def read_binary
+      size = read_varint32()
+      trans.read_all(size)
+    end
+
     private
     
     # 

http://git-wip-us.apache.org/repos/asf/thrift/blob/19dbbefc/lib/rb/lib/thrift/struct.rb
----------------------------------------------------------------------
diff --git a/lib/rb/lib/thrift/struct.rb b/lib/rb/lib/thrift/struct.rb
index 3512463..df9d656 100644
--- a/lib/rb/lib/thrift/struct.rb
+++ b/lib/rb/lib/thrift/struct.rb
@@ -105,7 +105,7 @@ module Thrift
             write_container(oprot, value, field_info)
             oprot.write_field_end
           else
-            oprot.write_field(name, type, fid, value)
+            oprot.write_field(field_info, fid, value)
           end
         end
       end

http://git-wip-us.apache.org/repos/asf/thrift/blob/19dbbefc/lib/rb/lib/thrift/struct_union.rb
----------------------------------------------------------------------
diff --git a/lib/rb/lib/thrift/struct_union.rb b/lib/rb/lib/thrift/struct_union.rb
index 4e0afcf..e21b39e 100644
--- a/lib/rb/lib/thrift/struct_union.rb
+++ b/lib/rb/lib/thrift/struct_union.rb
@@ -101,7 +101,7 @@ module Thrift
         end
         iprot.read_set_end
       else
-        value = iprot.read_type(field[:type])
+        value = iprot.read_type(field)
       end
       value
     end
@@ -110,7 +110,7 @@ module Thrift
       if is_container? field[:type]
         write_container(oprot, value, field)
       else
-        oprot.write_type(field[:type], value)
+        oprot.write_type(field, value)
       end
     end
 

http://git-wip-us.apache.org/repos/asf/thrift/blob/19dbbefc/lib/rb/spec/base_protocol_spec.rb
----------------------------------------------------------------------
diff --git a/lib/rb/spec/base_protocol_spec.rb b/lib/rb/spec/base_protocol_spec.rb
index c0f9cfc..ec50c48 100644
--- a/lib/rb/spec/base_protocol_spec.rb
+++ b/lib/rb/spec/base_protocol_spec.rb
@@ -33,14 +33,21 @@ describe 'BaseProtocol' do
       @prot.trans.should eql(@trans)
     end
 
-    it "should write out a field nicely" do
+    it 'should write out a field nicely (deprecated write_field signature)' do
       @prot.should_receive(:write_field_begin).with('field', 'type', 'fid').ordered
-      @prot.should_receive(:write_type).with('type', 'value').ordered
+      @prot.should_receive(:write_type).with({:name => 'field', :type => 'type'}, 'value').ordered
       @prot.should_receive(:write_field_end).ordered
       @prot.write_field('field', 'type', 'fid', 'value')
     end
 
-    it "should write out the different types" do
+    it 'should write out a field nicely' do
+      @prot.should_receive(:write_field_begin).with('field', 'type', 'fid').ordered
+      @prot.should_receive(:write_type).with({:name => 'field', :type => 'type', :binary => false}, 'value').ordered
+      @prot.should_receive(:write_field_end).ordered
+      @prot.write_field({:name => 'field', :type => 'type', :binary => false}, 'fid', 'value')
+    end
+
+    it 'should write out the different types (deprecated write_type signature)' do
       @prot.should_receive(:write_bool).with('bool').ordered
       @prot.should_receive(:write_byte).with('byte').ordered
       @prot.should_receive(:write_double).with('double').ordered
@@ -60,11 +67,37 @@ describe 'BaseProtocol' do
       @prot.write_type(Thrift::Types::STRUCT, struct)
       # all other types are not implemented
       [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP, Thrift::Types::SET, Thrift::Types::LIST].each do |type|
-        lambda { @prot.write_type(type, type.to_s) }.should raise_error(NotImplementedError)
+        expect { @prot.write_type(type, type.to_s) }.to raise_error(NotImplementedError)
+      end
+    end
+
+    it 'should write out the different types' do
+      @prot.should_receive(:write_bool).with('bool').ordered
+      @prot.should_receive(:write_byte).with('byte').ordered
+      @prot.should_receive(:write_double).with('double').ordered
+      @prot.should_receive(:write_i16).with('i16').ordered
+      @prot.should_receive(:write_i32).with('i32').ordered
+      @prot.should_receive(:write_i64).with('i64').ordered
+      @prot.should_receive(:write_string).with('string').ordered
+      @prot.should_receive(:write_binary).with('binary').ordered
+      struct = mock('Struct')
+      struct.should_receive(:write).with(@prot).ordered
+      @prot.write_type({:type => Thrift::Types::BOOL}, 'bool')
+      @prot.write_type({:type => Thrift::Types::BYTE}, 'byte')
+      @prot.write_type({:type => Thrift::Types::DOUBLE}, 'double')
+      @prot.write_type({:type => Thrift::Types::I16}, 'i16')
+      @prot.write_type({:type => Thrift::Types::I32}, 'i32')
+      @prot.write_type({:type => Thrift::Types::I64}, 'i64')
+      @prot.write_type({:type => Thrift::Types::STRING}, 'string')
+      @prot.write_type({:type => Thrift::Types::STRING, :binary => true}, 'binary')
+      @prot.write_type({:type => Thrift::Types::STRUCT}, struct)
+      # all other types are not implemented
+      [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP, Thrift::Types::SET, Thrift::Types::LIST].each do |type|
+        expect { @prot.write_type({:type => type}, type.to_s) }.to raise_error(NotImplementedError)
       end
     end
 
-    it "should read the different types" do
+    it 'should read the different types (deprecated read_type signature)' do
       @prot.should_receive(:read_bool).ordered
       @prot.should_receive(:read_byte).ordered
       @prot.should_receive(:read_i16).ordered
@@ -80,8 +113,33 @@ describe 'BaseProtocol' do
       @prot.read_type(Thrift::Types::DOUBLE)
       @prot.read_type(Thrift::Types::STRING)
       # all other types are not implemented
-      [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP, Thrift::Types::SET, Thrift::Types::LIST].each do |type|
-        lambda { @prot.read_type(type) }.should raise_error(NotImplementedError)
+      [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP,
+       Thrift::Types::SET, Thrift::Types::LIST, Thrift::Types::STRUCT].each do |type|
+        expect { @prot.read_type(type) }.to raise_error(NotImplementedError)
+      end
+    end
+
+    it 'should read the different types' do
+      @prot.should_receive(:read_bool).ordered
+      @prot.should_receive(:read_byte).ordered
+      @prot.should_receive(:read_i16).ordered
+      @prot.should_receive(:read_i32).ordered
+      @prot.should_receive(:read_i64).ordered
+      @prot.should_receive(:read_double).ordered
+      @prot.should_receive(:read_string).ordered
+      @prot.should_receive(:read_binary).ordered
+      @prot.read_type({:type => Thrift::Types::BOOL})
+      @prot.read_type({:type => Thrift::Types::BYTE})
+      @prot.read_type({:type => Thrift::Types::I16})
+      @prot.read_type({:type => Thrift::Types::I32})
+      @prot.read_type({:type => Thrift::Types::I64})
+      @prot.read_type({:type => Thrift::Types::DOUBLE})
+      @prot.read_type({:type => Thrift::Types::STRING})
+      @prot.read_type({:type => Thrift::Types::STRING, :binary => true})
+      # all other types are not implemented
+      [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP,
+       Thrift::Types::SET, Thrift::Types::LIST, Thrift::Types::STRUCT].each do |type|
+        expect { @prot.read_type({:type => type}) }.to raise_error(NotImplementedError)
       end
     end
 

http://git-wip-us.apache.org/repos/asf/thrift/blob/19dbbefc/lib/rb/spec/binary_protocol_spec_shared.rb
----------------------------------------------------------------------
diff --git a/lib/rb/spec/binary_protocol_spec_shared.rb b/lib/rb/spec/binary_protocol_spec_shared.rb
index c49ff1f..c615b58 100644
--- a/lib/rb/spec/binary_protocol_spec_shared.rb
+++ b/lib/rb/spec/binary_protocol_spec_shared.rb
@@ -219,6 +219,14 @@ shared_examples_for 'a binary protocol' do
       a.encoding.should == Encoding::BINARY
       a.unpack('C*').should == [0x00, 0x00, 0x00, 0x07, 0x61, 0x62, 0x63, 0x20, 0xE2, 0x82, 0xAC]
     end
+
+    it 'should write a binary string' do
+      buffer = [0, 1, 2, 3].pack('C*')
+      @prot.write_binary(buffer)
+      a = @trans.read(@trans.available)
+      a.encoding.should == Encoding::BINARY
+      a.unpack('C*').should == [0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03]
+    end
   else
     it 'should write a string' do
       str = 'abc'
@@ -226,6 +234,13 @@ shared_examples_for 'a binary protocol' do
       a = @trans.read(@trans.available)
       a.unpack('C*').should == [0x00, 0x00, 0x00, 0x03, 0x61, 0x62, 0x63]
     end
+
+    it 'should write a binary string' do
+      buffer = [0, 1, 2, 3].pack('C*')
+      @prot.write_binary(buffer)
+      a = @trans.read(@trans.available)
+      a.unpack('C*').should == [0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03]
+    end
   end
 
   it "should error gracefully when trying to write a nil string" do
@@ -342,6 +357,14 @@ shared_examples_for 'a binary protocol' do
       a.should == "\u20AC".encode('UTF-8')
       a.encoding.should == Encoding::UTF_8
     end
+
+    it 'should read a binary string' do
+      buffer = [0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03].pack('C*')
+      @trans.write(buffer)
+      a = @prot.read_binary
+      a.should == [0x00, 0x01, 0x02, 0x03].pack('C*')
+      a.encoding.should == Encoding::BINARY
+    end
   else
     it 'should read a string' do
       # i32 of value 3, followed by three characters/UTF-8 bytes 'a', 'b', 'c'
@@ -349,6 +372,13 @@ shared_examples_for 'a binary protocol' do
       @trans.write(buffer)
       @prot.read_string.should == 'abc'
     end
+
+    it 'should read a binary string' do
+      buffer = [0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03].pack('C*')
+      @trans.write(buffer)
+      a = @prot.read_binary
+      a.should == [0x00, 0x01, 0x02, 0x03].pack('C*')
+    end
   end
 
   it "should perform a complete rpc with no args or return" do

http://git-wip-us.apache.org/repos/asf/thrift/blob/19dbbefc/lib/rb/spec/compact_protocol_spec.rb
----------------------------------------------------------------------
diff --git a/lib/rb/spec/compact_protocol_spec.rb b/lib/rb/spec/compact_protocol_spec.rb
index 91dfe44..daad583 100644
--- a/lib/rb/spec/compact_protocol_spec.rb
+++ b/lib/rb/spec/compact_protocol_spec.rb
@@ -134,12 +134,10 @@ describe Thrift::CompactProtocol do
   end
   
   def writer(sym)
-    sym = sym == :binary ? :string : sym
     "write_#{sym.to_s}"
   end
   
   def reader(sym)
-    sym = sym == :binary ? :string : sym
     "read_#{sym.to_s}"
   end
-end
\ No newline at end of file
+end