Browse Source

Convert Google::Protobuf.deep_copy to pure Ruby

In general, I think it will help us to debug issues if we have less C
code and more Ruby code.  This method can be implemented in pure Ruby,
so this commit converts it to pure Ruby.
Aaron Patterson 6 years ago
parent
commit
3b67455319

+ 3 - 2
ruby/ext/google/protobuf_c/map.c

@@ -538,8 +538,8 @@ VALUE Map_dup(VALUE _self) {
   return new_map;
   return new_map;
 }
 }
 
 
-// Used by Google::Protobuf.deep_copy but not exposed directly.
-VALUE Map_deep_copy(VALUE _self) {
+/* :nodoc: */
+static VALUE Map_deep_copy(VALUE _self) {
   Map* self = ruby_to_Map(_self);
   Map* self = ruby_to_Map(_self);
   VALUE new_map = Map_new_this_type(_self);
   VALUE new_map = Map_new_this_type(_self);
   Map* new_self = ruby_to_Map(new_map);
   Map* new_self = ruby_to_Map(new_map);
@@ -851,5 +851,6 @@ void Map_register(VALUE module) {
   rb_define_method(klass, "to_h", Map_to_h, 0);
   rb_define_method(klass, "to_h", Map_to_h, 0);
   rb_define_method(klass, "inspect", Map_inspect, 0);
   rb_define_method(klass, "inspect", Map_inspect, 0);
   rb_define_method(klass, "merge", Map_merge, 1);
   rb_define_method(klass, "merge", Map_merge, 1);
+  rb_define_method(klass, "deep_copy", Map_deep_copy, 0);
   rb_include_module(klass, rb_mEnumerable);
   rb_include_module(klass, rb_mEnumerable);
 }
 }

+ 3 - 20
ruby/ext/google/protobuf_c/message.c

@@ -511,8 +511,8 @@ VALUE Message_dup(VALUE _self) {
   return new_msg;
   return new_msg;
 }
 }
 
 
-// Internal only; used by Google::Protobuf.deep_copy.
-VALUE Message_deep_copy(VALUE _self) {
+/* :nodoc: */
+static VALUE Message_deep_copy(VALUE _self) {
   MessageHeader* self;
   MessageHeader* self;
   MessageHeader* new_msg_self;
   MessageHeader* new_msg_self;
   VALUE new_msg;
   VALUE new_msg;
@@ -742,6 +742,7 @@ VALUE build_class_from_descriptor(Descriptor* desc) {
   rb_define_method(klass, "to_s", Message_inspect, 0);
   rb_define_method(klass, "to_s", Message_inspect, 0);
   rb_define_method(klass, "[]", Message_index, 1);
   rb_define_method(klass, "[]", Message_index, 1);
   rb_define_method(klass, "[]=", Message_index_set, 2);
   rb_define_method(klass, "[]=", Message_index_set, 2);
+  rb_define_method(klass, "deep_copy", Message_deep_copy, 0);
   rb_define_singleton_method(klass, "decode", Message_decode, 1);
   rb_define_singleton_method(klass, "decode", Message_decode, 1);
   rb_define_singleton_method(klass, "encode", Message_encode, 1);
   rb_define_singleton_method(klass, "encode", Message_encode, 1);
   rb_define_singleton_method(klass, "decode_json", Message_decode_json, -1);
   rb_define_singleton_method(klass, "decode_json", Message_decode_json, -1);
@@ -829,21 +830,3 @@ VALUE build_module_from_enumdesc(EnumDescriptor* enumdesc) {
 
 
   return mod;
   return mod;
 }
 }
-
-/*
- * call-seq:
- *     Google::Protobuf.deep_copy(obj) => copy_of_obj
- *
- * Performs a deep copy of a RepeatedField instance, a Map instance, or a
- * message object, recursively copying its members.
- */
-VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) {
-  VALUE klass = CLASS_OF(obj);
-  if (klass == cRepeatedField) {
-    return RepeatedField_deep_copy(obj);
-  } else if (klass == cMap) {
-    return Map_deep_copy(obj);
-  } else {
-    return Message_deep_copy(obj);
-  }
-}

+ 0 - 3
ruby/ext/google/protobuf_c/protobuf.h

@@ -425,7 +425,6 @@ VALUE RepeatedField_replace(VALUE _self, VALUE list);
 VALUE RepeatedField_clear(VALUE _self);
 VALUE RepeatedField_clear(VALUE _self);
 VALUE RepeatedField_length(VALUE _self);
 VALUE RepeatedField_length(VALUE _self);
 VALUE RepeatedField_dup(VALUE _self);
 VALUE RepeatedField_dup(VALUE _self);
-VALUE RepeatedField_deep_copy(VALUE _self);
 VALUE RepeatedField_to_ary(VALUE _self);
 VALUE RepeatedField_to_ary(VALUE _self);
 VALUE RepeatedField_eq(VALUE _self, VALUE _other);
 VALUE RepeatedField_eq(VALUE _self, VALUE _other);
 VALUE RepeatedField_hash(VALUE _self);
 VALUE RepeatedField_hash(VALUE _self);
@@ -469,7 +468,6 @@ VALUE Map_delete(VALUE _self, VALUE key);
 VALUE Map_clear(VALUE _self);
 VALUE Map_clear(VALUE _self);
 VALUE Map_length(VALUE _self);
 VALUE Map_length(VALUE _self);
 VALUE Map_dup(VALUE _self);
 VALUE Map_dup(VALUE _self);
-VALUE Map_deep_copy(VALUE _self);
 VALUE Map_eq(VALUE _self, VALUE _other);
 VALUE Map_eq(VALUE _self, VALUE _other);
 VALUE Map_hash(VALUE _self);
 VALUE Map_hash(VALUE _self);
 VALUE Map_to_h(VALUE _self);
 VALUE Map_to_h(VALUE _self);
@@ -564,7 +562,6 @@ VALUE Message_alloc(VALUE klass);
 VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self);
 VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self);
 VALUE Message_initialize(int argc, VALUE* argv, VALUE _self);
 VALUE Message_initialize(int argc, VALUE* argv, VALUE _self);
 VALUE Message_dup(VALUE _self);
 VALUE Message_dup(VALUE _self);
-VALUE Message_deep_copy(VALUE _self);
 VALUE Message_eq(VALUE _self, VALUE _other);
 VALUE Message_eq(VALUE _self, VALUE _other);
 VALUE Message_hash(VALUE _self);
 VALUE Message_hash(VALUE _self);
 VALUE Message_inspect(VALUE _self);
 VALUE Message_inspect(VALUE _self);

+ 3 - 2
ruby/ext/google/protobuf_c/repeated_field.c

@@ -355,8 +355,8 @@ VALUE RepeatedField_dup(VALUE _self) {
   return new_rptfield;
   return new_rptfield;
 }
 }
 
 
-// Internal only: used by Google::Protobuf.deep_copy.
-VALUE RepeatedField_deep_copy(VALUE _self) {
+/* :nodoc: */
+static VALUE RepeatedField_deep_copy(VALUE _self) {
   RepeatedField* self = ruby_to_RepeatedField(_self);
   RepeatedField* self = ruby_to_RepeatedField(_self);
   VALUE new_rptfield = RepeatedField_new_this_type(_self);
   VALUE new_rptfield = RepeatedField_new_this_type(_self);
   RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield);
   RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield);
@@ -656,5 +656,6 @@ void RepeatedField_register(VALUE module) {
   rb_define_method(klass, "hash", RepeatedField_hash, 0);
   rb_define_method(klass, "hash", RepeatedField_hash, 0);
   rb_define_method(klass, "+", RepeatedField_plus, 1);
   rb_define_method(klass, "+", RepeatedField_plus, 1);
   rb_define_method(klass, "concat", RepeatedField_concat, 1);
   rb_define_method(klass, "concat", RepeatedField_concat, 1);
+  rb_define_method(klass, "deep_copy", RepeatedField_deep_copy, 0);
   rb_include_module(klass, rb_mEnumerable);
   rb_include_module(klass, rb_mEnumerable);
 }
 }

+ 8 - 0
ruby/lib/google/protobuf.rb

@@ -73,5 +73,13 @@ module Google
       klass.decode_json(json, options)
       klass.decode_json(json, options)
     end
     end
 
 
+    # call-seq:
+    #     Google::Protobuf.deep_copy(obj) => copy_of_obj
+    #
+    # Performs a deep copy of a RepeatedField instance, a Map instance, or a
+    # message object, recursively copying its members.
+    def self.deep_copy(obj)
+      obj.deep_copy
+    end
   end
   end
 end
 end