From d1b52a00e002fd7a4adbcdeafa0634de6088a88f Mon Sep 17 00:00:00 2001 From: Adam Greene Date: Sun, 3 May 2015 10:55:10 -0700 Subject: adding and simplifying encoders/decoders * make consistent between mri and jruby * create a #to_h and have it use symbols for keys * add #to_json and #to_proto helpers on the Google::Protobuf message classes --- ruby/ext/google/protobuf_c/encode_decode.c | 47 ------------------------------ ruby/ext/google/protobuf_c/message.c | 31 ++++++++++++++++++++ ruby/ext/google/protobuf_c/protobuf.c | 7 ----- ruby/ext/google/protobuf_c/protobuf.h | 6 +--- 4 files changed, 32 insertions(+), 59 deletions(-) (limited to 'ruby/ext/google') diff --git a/ruby/ext/google/protobuf_c/encode_decode.c b/ruby/ext/google/protobuf_c/encode_decode.c index 5730504d..f9a046cb 100644 --- a/ruby/ext/google/protobuf_c/encode_decode.c +++ b/ruby/ext/google/protobuf_c/encode_decode.c @@ -1118,50 +1118,3 @@ VALUE Message_encode_json(VALUE klass, VALUE msg_rb) { return ret; } -/* - * call-seq: - * Google::Protobuf.encode(msg) => bytes - * - * Encodes the given message object to protocol buffers wire format. This is an - * alternative to the #encode method on msg's class. - */ -VALUE Google_Protobuf_encode(VALUE self, VALUE msg_rb) { - VALUE klass = CLASS_OF(msg_rb); - return Message_encode(klass, msg_rb); -} - -/* - * call-seq: - * Google::Protobuf.encode_json(msg) => json_string - * - * Encodes the given message object to its JSON representation. This is an - * alternative to the #encode_json method on msg's class. - */ -VALUE Google_Protobuf_encode_json(VALUE self, VALUE msg_rb) { - VALUE klass = CLASS_OF(msg_rb); - return Message_encode_json(klass, msg_rb); -} - -/* - * call-seq: - * Google::Protobuf.decode(class, bytes) => msg - * - * Decodes the given bytes as protocol buffers wire format under the - * interpretation given by the given class's message definition. This is an - * alternative to the #decode method on the given class. - */ -VALUE Google_Protobuf_decode(VALUE self, VALUE klass, VALUE msg_rb) { - return Message_decode(klass, msg_rb); -} - -/* - * call-seq: - * Google::Protobuf.decode_json(class, json_string) => msg - * - * Decodes the given JSON string under the interpretation given by the given - * class's message definition. This is an alternative to the #decode_json method - * on the given class. - */ -VALUE Google_Protobuf_decode_json(VALUE self, VALUE klass, VALUE msg_rb) { - return Message_decode_json(klass, msg_rb); -} diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c index 7e58a617..6e850427 100644 --- a/ruby/ext/google/protobuf_c/message.c +++ b/ruby/ext/google/protobuf_c/message.c @@ -329,6 +329,30 @@ VALUE Message_inspect(VALUE _self) { return str; } + +VALUE Message_to_h(VALUE _self) { + MessageHeader* self; + TypedData_Get_Struct(_self, MessageHeader, &Message_type, self); + + VALUE hash = rb_hash_new(); + + upb_msg_field_iter it; + for (upb_msg_field_begin(&it, self->descriptor->msgdef); + !upb_msg_field_done(&it); + upb_msg_field_next(&it)) { + const upb_fielddef* field = upb_msg_iter_field(&it); + VALUE msg_value = layout_get(self->descriptor->layout, Message_data(self), field); + VALUE msg_key = ID2SYM(rb_intern(upb_fielddef_name(field))); + if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { + msg_value = RepeatedField_to_ary(msg_value); + } + rb_hash_aset(hash, msg_key, msg_value); + } + return hash; +} + + + /* * call-seq: * Message.[](index) => value @@ -399,6 +423,10 @@ VALUE build_class_from_descriptor(Descriptor* desc) { rb_cObject); rb_iv_set(klass, kDescriptorInstanceVar, get_def_obj(desc->msgdef)); rb_define_alloc_func(klass, Message_alloc); + rb_require("google/protobuf/message_exts"); + rb_include_module(klass, rb_eval_string("Google::Protobuf::MessageExts")); + rb_extend_object(klass, rb_eval_string("Google::Protobuf::MessageExts::ClassMethods")); + rb_define_method(klass, "method_missing", Message_method_missing, -1); rb_define_method(klass, "initialize", Message_initialize, -1); @@ -407,6 +435,8 @@ VALUE build_class_from_descriptor(Descriptor* desc) { rb_define_method(klass, "clone", Message_dup, 0); rb_define_method(klass, "==", Message_eq, 1); rb_define_method(klass, "hash", Message_hash, 0); + rb_define_method(klass, "to_h", Message_to_h, 0); + rb_define_method(klass, "to_hash", Message_to_h, 0); rb_define_method(klass, "inspect", Message_inspect, 0); rb_define_method(klass, "[]", Message_index, 1); rb_define_method(klass, "[]=", Message_index_set, 2); @@ -415,6 +445,7 @@ VALUE build_class_from_descriptor(Descriptor* desc) { rb_define_singleton_method(klass, "decode_json", Message_decode_json, 1); rb_define_singleton_method(klass, "encode_json", Message_encode_json, 1); rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0); + return klass; } diff --git a/ruby/ext/google/protobuf_c/protobuf.c b/ruby/ext/google/protobuf_c/protobuf.c index d2d35033..8ab518a5 100644 --- a/ruby/ext/google/protobuf_c/protobuf.c +++ b/ruby/ext/google/protobuf_c/protobuf.c @@ -86,13 +86,6 @@ void Init_protobuf_c() { RepeatedField_register(protobuf); Map_register(protobuf); - rb_define_singleton_method(protobuf, "encode", Google_Protobuf_encode, 1); - rb_define_singleton_method(protobuf, "decode", Google_Protobuf_decode, 2); - rb_define_singleton_method(protobuf, "encode_json", - Google_Protobuf_encode_json, 1); - rb_define_singleton_method(protobuf, "decode_json", - Google_Protobuf_decode_json, 2); - rb_define_singleton_method(protobuf, "deep_copy", Google_Protobuf_deep_copy, 1); diff --git a/ruby/ext/google/protobuf_c/protobuf.h b/ruby/ext/google/protobuf_c/protobuf.h index d8a327aa..ef00b5fa 100644 --- a/ruby/ext/google/protobuf_c/protobuf.h +++ b/ruby/ext/google/protobuf_c/protobuf.h @@ -374,6 +374,7 @@ VALUE RepeatedField_clear(VALUE _self); VALUE RepeatedField_length(VALUE _self); VALUE RepeatedField_dup(VALUE _self); VALUE RepeatedField_deep_copy(VALUE _self); +VALUE RepeatedField_to_ary(VALUE _self); VALUE RepeatedField_eq(VALUE _self, VALUE _other); VALUE RepeatedField_hash(VALUE _self); VALUE RepeatedField_inspect(VALUE _self); @@ -497,11 +498,6 @@ VALUE Message_encode(VALUE klass, VALUE msg_rb); VALUE Message_decode_json(VALUE klass, VALUE data); VALUE Message_encode_json(VALUE klass, VALUE msg_rb); -VALUE Google_Protobuf_encode(VALUE self, VALUE msg_rb); -VALUE Google_Protobuf_decode(VALUE self, VALUE klass, VALUE msg_rb); -VALUE Google_Protobuf_encode_json(VALUE self, VALUE msg_rb); -VALUE Google_Protobuf_decode_json(VALUE self, VALUE klass, VALUE msg_rb); - VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj); VALUE build_module_from_enumdesc(EnumDescriptor* enumdef); -- cgit v1.2.3