THRIFT-332. rb: Compact Protocol in Ruby
This patch includes both a pure Ruby and C-extension port of the Compact Protocol described in THRIFT-110. It also fixes a bug in struct.c that was interfering with native protocol method calls, and adds some utility classes to the Java library for serializing/deserializing to a file for the purpose of testing protocols cross-language.
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@756133 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/rb/ext/struct.c b/lib/rb/ext/struct.c
index b882344..20b48b9 100644
--- a/lib/rb/ext/struct.c
+++ b/lib/rb/ext/struct.c
@@ -24,10 +24,30 @@
#endif
static native_proto_method_table *mt;
+static native_proto_method_table *default_mt;
+static VALUE last_proto_class = Qnil;
#define IS_CONTAINER(ttype) ((ttype) == TTYPE_MAP || (ttype) == TTYPE_LIST || (ttype) == TTYPE_SET)
#define STRUCT_FIELDS(obj) rb_const_get(CLASS_OF(obj), fields_const_id)
+static void set_native_proto_function_pointers(VALUE protocol) {
+ VALUE method_table_object = rb_const_get(CLASS_OF(protocol), rb_intern("@native_method_table"));
+ // TODO: check nil?
+ Data_Get_Struct(method_table_object, native_proto_method_table, mt);
+}
+
+static void check_native_proto_method_table(VALUE protocol) {
+ VALUE protoclass = CLASS_OF(protocol);
+ if (protoclass != last_proto_class) {
+ last_proto_class = protoclass;
+ if (rb_funcall(protocol, native_qmark_method_id, 0) == Qtrue) {
+ set_native_proto_function_pointers(protocol);
+ } else {
+ mt = default_mt;
+ }
+ }
+}
+
//-------------------------------------------
// Writing section
//-------------------------------------------
@@ -193,51 +213,44 @@
}
static void set_default_proto_function_pointers() {
- mt = ALLOC(native_proto_method_table);
-
- mt->write_field_begin = default_write_field_begin;
- mt->write_field_stop = default_write_field_stop;
- mt->write_map_begin = default_write_map_begin;
- mt->write_map_end = default_write_map_end;
- mt->write_list_begin = default_write_list_begin;
- mt->write_list_end = default_write_list_end;
- mt->write_set_begin = default_write_set_begin;
- mt->write_set_end = default_write_set_end;
- mt->write_byte = default_write_byte;
- mt->write_bool = default_write_bool;
- mt->write_i16 = default_write_i16;
- mt->write_i32 = default_write_i32;
- mt->write_i64 = default_write_i64;
- mt->write_double = default_write_double;
- mt->write_string = default_write_string;
- mt->write_struct_begin = default_write_struct_begin;
- mt->write_struct_end = default_write_struct_end;
- mt->write_field_end = default_write_field_end;
+ default_mt = ALLOC(native_proto_method_table);
- mt->read_struct_begin = default_read_struct_begin;
- mt->read_struct_end = default_read_struct_end;
- mt->read_field_begin = default_read_field_begin;
- mt->read_field_end = default_read_field_end;
- mt->read_map_begin = default_read_map_begin;
- mt->read_map_end = default_read_map_end;
- mt->read_list_begin = default_read_list_begin;
- mt->read_list_end = default_read_list_end;
- mt->read_set_begin = default_read_set_begin;
- mt->read_set_end = default_read_set_end;
- mt->read_byte = default_read_byte;
- mt->read_bool = default_read_bool;
- mt->read_i16 = default_read_i16;
- mt->read_i32 = default_read_i32;
- mt->read_i64 = default_read_i64;
- mt->read_double = default_read_double;
- mt->read_string = default_read_string;
-
-}
+ default_mt->write_field_begin = default_write_field_begin;
+ default_mt->write_field_stop = default_write_field_stop;
+ default_mt->write_map_begin = default_write_map_begin;
+ default_mt->write_map_end = default_write_map_end;
+ default_mt->write_list_begin = default_write_list_begin;
+ default_mt->write_list_end = default_write_list_end;
+ default_mt->write_set_begin = default_write_set_begin;
+ default_mt->write_set_end = default_write_set_end;
+ default_mt->write_byte = default_write_byte;
+ default_mt->write_bool = default_write_bool;
+ default_mt->write_i16 = default_write_i16;
+ default_mt->write_i32 = default_write_i32;
+ default_mt->write_i64 = default_write_i64;
+ default_mt->write_double = default_write_double;
+ default_mt->write_string = default_write_string;
+ default_mt->write_struct_begin = default_write_struct_begin;
+ default_mt->write_struct_end = default_write_struct_end;
+ default_mt->write_field_end = default_write_field_end;
-static void set_native_proto_function_pointers(VALUE protocol) {
- VALUE method_table_object = rb_const_get(CLASS_OF(protocol), rb_intern("@native_method_table"));
- // TODO: check nil?
- Data_Get_Struct(method_table_object, native_proto_method_table, mt);
+ default_mt->read_struct_begin = default_read_struct_begin;
+ default_mt->read_struct_end = default_read_struct_end;
+ default_mt->read_field_begin = default_read_field_begin;
+ default_mt->read_field_end = default_read_field_end;
+ default_mt->read_map_begin = default_read_map_begin;
+ default_mt->read_map_end = default_read_map_end;
+ default_mt->read_list_begin = default_read_list_begin;
+ default_mt->read_list_end = default_read_list_end;
+ default_mt->read_set_begin = default_read_set_begin;
+ default_mt->read_set_end = default_read_set_end;
+ default_mt->read_byte = default_read_byte;
+ default_mt->read_bool = default_read_bool;
+ default_mt->read_i16 = default_read_i16;
+ default_mt->read_i32 = default_read_i32;
+ default_mt->read_i64 = default_read_i64;
+ default_mt->read_double = default_read_double;
+ default_mt->read_string = default_read_string;
}
// end default protocol methods
@@ -383,11 +396,12 @@
// call validate
rb_funcall(self, validate_method_id, 0);
- if (RTEST(rb_funcall(protocol, native_qmark_method_id, 0))) {
- set_native_proto_function_pointers(protocol);
- } else {
- set_default_proto_function_pointers();
- }
+ // if (rb_funcall(protocol, native_qmark_method_id, 0) == Qtrue) {
+ // set_native_proto_function_pointers(protocol);
+ // } else {
+ // set_default_proto_function_pointers();
+ // }
+ check_native_proto_method_table(protocol);
// write struct begin
mt->write_struct_begin(protocol, rb_class_name(CLASS_OF(self)));
@@ -522,6 +536,8 @@
}
static VALUE rb_thrift_struct_read(VALUE self, VALUE protocol) {
+ check_native_proto_method_table(protocol);
+
// read struct begin
mt->read_struct_begin(protocol);