|
|
|
@ -187,11 +187,11 @@ static void *appendsubmsg_handler(void *closure, const void *hd) { |
|
|
|
|
VALUE subdesc = |
|
|
|
|
get_def_obj((void*)submsgdata->md); |
|
|
|
|
VALUE subklass = Descriptor_msgclass(subdesc); |
|
|
|
|
MessageHeader* submsg; |
|
|
|
|
|
|
|
|
|
VALUE submsg_rb = rb_class_new_instance(0, NULL, subklass); |
|
|
|
|
RepeatedField_push(ary, submsg_rb); |
|
|
|
|
|
|
|
|
|
MessageHeader* submsg; |
|
|
|
|
TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg); |
|
|
|
|
return submsg; |
|
|
|
|
} |
|
|
|
@ -203,14 +203,15 @@ static void *submsg_handler(void *closure, const void *hd) { |
|
|
|
|
VALUE subdesc = |
|
|
|
|
get_def_obj((void*)submsgdata->md); |
|
|
|
|
VALUE subklass = Descriptor_msgclass(subdesc); |
|
|
|
|
VALUE submsg_rb; |
|
|
|
|
MessageHeader* submsg; |
|
|
|
|
|
|
|
|
|
if (DEREF(msg, submsgdata->ofs, VALUE) == Qnil) { |
|
|
|
|
DEREF(msg, submsgdata->ofs, VALUE) = |
|
|
|
|
rb_class_new_instance(0, NULL, subklass); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VALUE submsg_rb = DEREF(msg, submsgdata->ofs, VALUE); |
|
|
|
|
MessageHeader* submsg; |
|
|
|
|
submsg_rb = DEREF(msg, submsgdata->ofs, VALUE); |
|
|
|
|
TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg); |
|
|
|
|
return submsg; |
|
|
|
|
} |
|
|
|
@ -266,12 +267,14 @@ static bool endmap_handler(void *closure, const void *hd, upb_status* s) { |
|
|
|
|
&frame->key_storage); |
|
|
|
|
|
|
|
|
|
VALUE value_field_typeclass = Qnil; |
|
|
|
|
VALUE value; |
|
|
|
|
|
|
|
|
|
if (mapdata->value_field_type == UPB_TYPE_MESSAGE || |
|
|
|
|
mapdata->value_field_type == UPB_TYPE_ENUM) { |
|
|
|
|
value_field_typeclass = get_def_obj(mapdata->value_field_subdef); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VALUE value = native_slot_get( |
|
|
|
|
value = native_slot_get( |
|
|
|
|
mapdata->value_field_type, value_field_typeclass, |
|
|
|
|
&frame->value_storage); |
|
|
|
|
|
|
|
|
@ -292,15 +295,14 @@ static map_handlerdata_t* new_map_handlerdata( |
|
|
|
|
size_t ofs, |
|
|
|
|
const upb_msgdef* mapentry_def, |
|
|
|
|
Descriptor* desc) { |
|
|
|
|
|
|
|
|
|
const upb_fielddef* key_field; |
|
|
|
|
const upb_fielddef* value_field; |
|
|
|
|
map_handlerdata_t* hd = ALLOC(map_handlerdata_t); |
|
|
|
|
hd->ofs = ofs; |
|
|
|
|
const upb_fielddef* key_field = upb_msgdef_itof(mapentry_def, |
|
|
|
|
MAP_KEY_FIELD); |
|
|
|
|
key_field = upb_msgdef_itof(mapentry_def, MAP_KEY_FIELD); |
|
|
|
|
assert(key_field != NULL); |
|
|
|
|
hd->key_field_type = upb_fielddef_type(key_field); |
|
|
|
|
const upb_fielddef* value_field = upb_msgdef_itof(mapentry_def, |
|
|
|
|
MAP_VALUE_FIELD); |
|
|
|
|
value_field = upb_msgdef_itof(mapentry_def, MAP_VALUE_FIELD); |
|
|
|
|
assert(value_field != NULL); |
|
|
|
|
hd->value_field_type = upb_fielddef_type(value_field); |
|
|
|
|
hd->value_field_subdef = upb_fielddef_subdef(value_field); |
|
|
|
@ -366,6 +368,8 @@ static void *oneofsubmsg_handler(void *closure, |
|
|
|
|
VALUE subdesc = |
|
|
|
|
get_def_obj((void*)oneofdata->md); |
|
|
|
|
VALUE subklass = Descriptor_msgclass(subdesc); |
|
|
|
|
VALUE submsg_rb; |
|
|
|
|
MessageHeader* submsg; |
|
|
|
|
|
|
|
|
|
if (oldcase != oneofdata->oneof_case_num || |
|
|
|
|
DEREF(msg, oneofdata->ofs, VALUE) == Qnil) { |
|
|
|
@ -381,8 +385,7 @@ static void *oneofsubmsg_handler(void *closure, |
|
|
|
|
DEREF(msg, oneofdata->case_ofs, uint32_t) = |
|
|
|
|
oneofdata->oneof_case_num; |
|
|
|
|
|
|
|
|
|
VALUE submsg_rb = DEREF(msg, oneofdata->ofs, VALUE); |
|
|
|
|
MessageHeader* submsg; |
|
|
|
|
submsg_rb = DEREF(msg, oneofdata->ofs, VALUE); |
|
|
|
|
TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg); |
|
|
|
|
return submsg; |
|
|
|
|
} |
|
|
|
@ -477,8 +480,9 @@ static void add_handlers_for_mapfield(upb_handlers* h, |
|
|
|
|
Descriptor* desc) { |
|
|
|
|
const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef); |
|
|
|
|
map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc); |
|
|
|
|
upb_handlers_addcleanup(h, hd, free); |
|
|
|
|
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
|
|
|
|
|
|
|
|
|
upb_handlers_addcleanup(h, hd, free); |
|
|
|
|
upb_handlerattr_sethandlerdata(&attr, hd); |
|
|
|
|
upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr); |
|
|
|
|
upb_handlerattr_uninit(&attr); |
|
|
|
@ -491,8 +495,9 @@ static void add_handlers_for_mapentry(const upb_msgdef* msgdef, |
|
|
|
|
const upb_fielddef* key_field = map_entry_key(msgdef); |
|
|
|
|
const upb_fielddef* value_field = map_entry_value(msgdef); |
|
|
|
|
map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc); |
|
|
|
|
upb_handlers_addcleanup(h, hd, free); |
|
|
|
|
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
|
|
|
|
|
|
|
|
|
upb_handlers_addcleanup(h, hd, free); |
|
|
|
|
upb_handlerattr_sethandlerdata(&attr, hd); |
|
|
|
|
upb_handlers_setendmsg(h, endmap_handler, &attr); |
|
|
|
|
|
|
|
|
@ -554,6 +559,7 @@ static void add_handlers_for_oneof_field(upb_handlers *h, |
|
|
|
|
static void add_handlers_for_message(const void *closure, upb_handlers *h) { |
|
|
|
|
const upb_msgdef* msgdef = upb_handlers_msgdef(h); |
|
|
|
|
Descriptor* desc = ruby_to_Descriptor(get_def_obj((void*)msgdef)); |
|
|
|
|
upb_msg_field_iter i; |
|
|
|
|
|
|
|
|
|
// If this is a mapentry message type, set up a special set of handlers and
|
|
|
|
|
// bail out of the normal (user-defined) message type handling.
|
|
|
|
@ -570,7 +576,6 @@ static void add_handlers_for_message(const void *closure, upb_handlers *h) { |
|
|
|
|
desc->layout = create_layout(desc->msgdef); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
upb_msg_field_iter i; |
|
|
|
|
for (upb_msg_field_begin(&i, desc->msgdef); |
|
|
|
|
!upb_msg_field_done(&i); |
|
|
|
|
upb_msg_field_next(&i)) { |
|
|
|
@ -622,8 +627,7 @@ const upb_pbdecodermethod *new_fillmsg_decodermethod(Descriptor* desc, |
|
|
|
|
upb_pbdecodermethodopts opts; |
|
|
|
|
upb_pbdecodermethodopts_init(&opts, handlers); |
|
|
|
|
|
|
|
|
|
const upb_pbdecodermethod *ret = upb_pbdecodermethod_new(&opts, owner); |
|
|
|
|
return ret; |
|
|
|
|
return upb_pbdecodermethod_new(&opts, owner); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) { |
|
|
|
@ -691,28 +695,31 @@ VALUE Message_decode(VALUE klass, VALUE data) { |
|
|
|
|
VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned); |
|
|
|
|
Descriptor* desc = ruby_to_Descriptor(descriptor); |
|
|
|
|
VALUE msgklass = Descriptor_msgclass(descriptor); |
|
|
|
|
VALUE msg_rb; |
|
|
|
|
MessageHeader* msg; |
|
|
|
|
|
|
|
|
|
if (TYPE(data) != T_STRING) { |
|
|
|
|
rb_raise(rb_eArgError, "Expected string for binary protobuf data."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VALUE msg_rb = rb_class_new_instance(0, NULL, msgklass); |
|
|
|
|
MessageHeader* msg; |
|
|
|
|
msg_rb = rb_class_new_instance(0, NULL, msgklass); |
|
|
|
|
TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); |
|
|
|
|
|
|
|
|
|
const upb_pbdecodermethod* method = msgdef_decodermethod(desc); |
|
|
|
|
const upb_handlers* h = upb_pbdecodermethod_desthandlers(method); |
|
|
|
|
stackenv se; |
|
|
|
|
stackenv_init(&se, "Error occurred during parsing: %s"); |
|
|
|
|
{ |
|
|
|
|
const upb_pbdecodermethod* method = msgdef_decodermethod(desc); |
|
|
|
|
const upb_handlers* h = upb_pbdecodermethod_desthandlers(method); |
|
|
|
|
stackenv se; |
|
|
|
|
upb_sink sink; |
|
|
|
|
upb_pbdecoder* decoder; |
|
|
|
|
stackenv_init(&se, "Error occurred during parsing: %s"); |
|
|
|
|
|
|
|
|
|
upb_sink sink; |
|
|
|
|
upb_sink_reset(&sink, h, msg); |
|
|
|
|
upb_pbdecoder* decoder = |
|
|
|
|
upb_pbdecoder_create(&se.env, method, &sink); |
|
|
|
|
upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data), |
|
|
|
|
upb_pbdecoder_input(decoder)); |
|
|
|
|
upb_sink_reset(&sink, h, msg); |
|
|
|
|
decoder = upb_pbdecoder_create(&se.env, method, &sink); |
|
|
|
|
upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data), |
|
|
|
|
upb_pbdecoder_input(decoder)); |
|
|
|
|
|
|
|
|
|
stackenv_uninit(&se); |
|
|
|
|
stackenv_uninit(&se); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return msg_rb; |
|
|
|
|
} |
|
|
|
@ -729,6 +736,8 @@ VALUE Message_decode_json(VALUE klass, VALUE data) { |
|
|
|
|
VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned); |
|
|
|
|
Descriptor* desc = ruby_to_Descriptor(descriptor); |
|
|
|
|
VALUE msgklass = Descriptor_msgclass(descriptor); |
|
|
|
|
VALUE msg_rb; |
|
|
|
|
MessageHeader* msg; |
|
|
|
|
|
|
|
|
|
if (TYPE(data) != T_STRING) { |
|
|
|
|
rb_raise(rb_eArgError, "Expected string for JSON data."); |
|
|
|
@ -737,20 +746,22 @@ VALUE Message_decode_json(VALUE klass, VALUE data) { |
|
|
|
|
// convert, because string handlers pass data directly to message string
|
|
|
|
|
// fields.
|
|
|
|
|
|
|
|
|
|
VALUE msg_rb = rb_class_new_instance(0, NULL, msgklass); |
|
|
|
|
MessageHeader* msg; |
|
|
|
|
msg_rb = rb_class_new_instance(0, NULL, msgklass); |
|
|
|
|
TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); |
|
|
|
|
|
|
|
|
|
stackenv se; |
|
|
|
|
stackenv_init(&se, "Error occurred during parsing: %s"); |
|
|
|
|
{ |
|
|
|
|
stackenv se; |
|
|
|
|
upb_sink sink; |
|
|
|
|
upb_json_parser* parser; |
|
|
|
|
stackenv_init(&se, "Error occurred during parsing: %s"); |
|
|
|
|
|
|
|
|
|
upb_sink sink; |
|
|
|
|
upb_sink_reset(&sink, get_fill_handlers(desc), msg); |
|
|
|
|
upb_json_parser* parser = upb_json_parser_create(&se.env, &sink); |
|
|
|
|
upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data), |
|
|
|
|
upb_json_parser_input(parser)); |
|
|
|
|
upb_sink_reset(&sink, get_fill_handlers(desc), msg); |
|
|
|
|
parser = upb_json_parser_create(&se.env, &sink); |
|
|
|
|
upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data), |
|
|
|
|
upb_json_parser_input(parser)); |
|
|
|
|
|
|
|
|
|
stackenv_uninit(&se); |
|
|
|
|
stackenv_uninit(&se); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return msg_rb; |
|
|
|
|
} |
|
|
|
@ -781,12 +792,12 @@ static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) { |
|
|
|
|
|
|
|
|
|
static size_t stringsink_string(void *_sink, const void *hd, const char *ptr, |
|
|
|
|
size_t len, const upb_bufhandle *handle) { |
|
|
|
|
UPB_UNUSED(hd); |
|
|
|
|
UPB_UNUSED(handle); |
|
|
|
|
|
|
|
|
|
stringsink *sink = _sink; |
|
|
|
|
size_t new_size = sink->size; |
|
|
|
|
|
|
|
|
|
UPB_UNUSED(hd); |
|
|
|
|
UPB_UNUSED(handle); |
|
|
|
|
|
|
|
|
|
while (sink->len + len > new_size) { |
|
|
|
|
new_size *= 2; |
|
|
|
|
} |
|
|
|
@ -840,10 +851,11 @@ static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) { |
|
|
|
|
upb_sink subsink; |
|
|
|
|
|
|
|
|
|
if (str == Qnil) return; |
|
|
|
|
|
|
|
|
|
assert(BUILTIN_TYPE(str) == RUBY_T_STRING); |
|
|
|
|
upb_sink subsink; |
|
|
|
|
|
|
|
|
|
// Ensure that the string has the correct encoding. We also check at field-set
|
|
|
|
|
// time, but the user may have mutated the string object since then.
|
|
|
|
@ -858,11 +870,14 @@ static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) { |
|
|
|
|
|
|
|
|
|
static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink, |
|
|
|
|
int depth) { |
|
|
|
|
upb_sink subsink; |
|
|
|
|
VALUE descriptor; |
|
|
|
|
Descriptor* subdesc; |
|
|
|
|
|
|
|
|
|
if (submsg == Qnil) return; |
|
|
|
|
|
|
|
|
|
upb_sink subsink; |
|
|
|
|
VALUE descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned); |
|
|
|
|
Descriptor* subdesc = ruby_to_Descriptor(descriptor); |
|
|
|
|
descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned); |
|
|
|
|
subdesc = ruby_to_Descriptor(descriptor); |
|
|
|
|
|
|
|
|
|
upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink); |
|
|
|
|
putmsg(submsg, subdesc, &subsink, depth + 1); |
|
|
|
@ -871,19 +886,20 @@ static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink, |
|
|
|
|
|
|
|
|
|
static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink, |
|
|
|
|
int depth) { |
|
|
|
|
if (ary == Qnil) return; |
|
|
|
|
|
|
|
|
|
upb_sink subsink; |
|
|
|
|
upb_fieldtype_t type = upb_fielddef_type(f); |
|
|
|
|
upb_selector_t sel = 0; |
|
|
|
|
int size; |
|
|
|
|
|
|
|
|
|
if (ary == Qnil) return; |
|
|
|
|
|
|
|
|
|
upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink); |
|
|
|
|
|
|
|
|
|
upb_fieldtype_t type = upb_fielddef_type(f); |
|
|
|
|
upb_selector_t sel = 0; |
|
|
|
|
if (upb_fielddef_isprimitive(f)) { |
|
|
|
|
sel = getsel(f, upb_handlers_getprimitivehandlertype(f)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int size = NUM2INT(RepeatedField_length(ary)); |
|
|
|
|
size = NUM2INT(RepeatedField_length(ary)); |
|
|
|
|
for (int i = 0; i < size; i++) { |
|
|
|
|
void* memory = RepeatedField_index_native(ary, i); |
|
|
|
|
switch (type) { |
|
|
|
@ -966,21 +982,25 @@ static void put_ruby_value(VALUE value, |
|
|
|
|
|
|
|
|
|
static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink, |
|
|
|
|
int depth) { |
|
|
|
|
if (map == Qnil) return; |
|
|
|
|
Map* self = ruby_to_Map(map); |
|
|
|
|
|
|
|
|
|
Map* self; |
|
|
|
|
upb_sink subsink; |
|
|
|
|
const upb_fielddef* key_field; |
|
|
|
|
const upb_fielddef* value_field; |
|
|
|
|
Map_iter it; |
|
|
|
|
|
|
|
|
|
if (map == Qnil) return; |
|
|
|
|
self = ruby_to_Map(map); |
|
|
|
|
|
|
|
|
|
upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink); |
|
|
|
|
|
|
|
|
|
assert(upb_fielddef_type(f) == UPB_TYPE_MESSAGE); |
|
|
|
|
const upb_fielddef* key_field = map_field_key(f); |
|
|
|
|
const upb_fielddef* value_field = map_field_value(f); |
|
|
|
|
key_field = map_field_key(f); |
|
|
|
|
value_field = map_field_value(f); |
|
|
|
|
|
|
|
|
|
Map_iter it; |
|
|
|
|
for (Map_begin(map, &it); !Map_done(&it); Map_next(&it)) { |
|
|
|
|
VALUE key = Map_iter_key(&it); |
|
|
|
|
VALUE value = Map_iter_value(&it); |
|
|
|
|
upb_status status; |
|
|
|
|
|
|
|
|
|
upb_sink entry_sink; |
|
|
|
|
upb_sink_startsubmsg(&subsink, getsel(f, UPB_HANDLER_STARTSUBMSG), |
|
|
|
@ -991,7 +1011,6 @@ static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink, |
|
|
|
|
put_ruby_value(value, value_field, self->value_type_class, depth + 1, |
|
|
|
|
&entry_sink); |
|
|
|
|
|
|
|
|
|
upb_status status; |
|
|
|
|
upb_sink_endmsg(&entry_sink, &status); |
|
|
|
|
upb_sink_endsubmsg(&subsink, getsel(f, UPB_HANDLER_ENDSUBMSG)); |
|
|
|
|
} |
|
|
|
@ -1001,6 +1020,10 @@ static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink, |
|
|
|
|
|
|
|
|
|
static void putmsg(VALUE msg_rb, const Descriptor* desc, |
|
|
|
|
upb_sink *sink, int depth) { |
|
|
|
|
MessageHeader* msg; |
|
|
|
|
upb_msg_field_iter i; |
|
|
|
|
upb_status status; |
|
|
|
|
|
|
|
|
|
upb_sink_startmsg(sink); |
|
|
|
|
|
|
|
|
|
// Protect against cycles (possible because users may freely reassign message
|
|
|
|
@ -1010,10 +1033,8 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc, |
|
|
|
|
"Maximum recursion depth exceeded during encoding."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
MessageHeader* msg; |
|
|
|
|
TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); |
|
|
|
|
|
|
|
|
|
upb_msg_field_iter i; |
|
|
|
|
for (upb_msg_field_begin(&i, desc->msgdef); |
|
|
|
|
!upb_msg_field_done(&i); |
|
|
|
|
upb_msg_field_next(&i)) { |
|
|
|
@ -1085,7 +1106,6 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
upb_status status; |
|
|
|
|
upb_sink_endmsg(sink, &status); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1120,22 +1140,26 @@ VALUE Message_encode(VALUE klass, VALUE msg_rb) { |
|
|
|
|
stringsink sink; |
|
|
|
|
stringsink_init(&sink); |
|
|
|
|
|
|
|
|
|
const upb_handlers* serialize_handlers = |
|
|
|
|
msgdef_pb_serialize_handlers(desc); |
|
|
|
|
{ |
|
|
|
|
const upb_handlers* serialize_handlers = |
|
|
|
|
msgdef_pb_serialize_handlers(desc); |
|
|
|
|
|
|
|
|
|
stackenv se; |
|
|
|
|
stackenv_init(&se, "Error occurred during encoding: %s"); |
|
|
|
|
upb_pb_encoder* encoder = |
|
|
|
|
upb_pb_encoder_create(&se.env, serialize_handlers, &sink.sink); |
|
|
|
|
stackenv se; |
|
|
|
|
upb_pb_encoder* encoder; |
|
|
|
|
VALUE ret; |
|
|
|
|
|
|
|
|
|
putmsg(msg_rb, desc, upb_pb_encoder_input(encoder), 0); |
|
|
|
|
stackenv_init(&se, "Error occurred during encoding: %s"); |
|
|
|
|
encoder = upb_pb_encoder_create(&se.env, serialize_handlers, &sink.sink); |
|
|
|
|
|
|
|
|
|
VALUE ret = rb_str_new(sink.ptr, sink.len); |
|
|
|
|
putmsg(msg_rb, desc, upb_pb_encoder_input(encoder), 0); |
|
|
|
|
|
|
|
|
|
stackenv_uninit(&se); |
|
|
|
|
stringsink_uninit(&sink); |
|
|
|
|
ret = rb_str_new(sink.ptr, sink.len); |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
stackenv_uninit(&se); |
|
|
|
|
stringsink_uninit(&sink); |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -1151,21 +1175,24 @@ VALUE Message_encode_json(VALUE klass, VALUE msg_rb) { |
|
|
|
|
stringsink sink; |
|
|
|
|
stringsink_init(&sink); |
|
|
|
|
|
|
|
|
|
const upb_handlers* serialize_handlers = |
|
|
|
|
msgdef_json_serialize_handlers(desc); |
|
|
|
|
{ |
|
|
|
|
const upb_handlers* serialize_handlers = |
|
|
|
|
msgdef_json_serialize_handlers(desc); |
|
|
|
|
upb_json_printer* printer; |
|
|
|
|
stackenv se; |
|
|
|
|
VALUE ret; |
|
|
|
|
|
|
|
|
|
stackenv se; |
|
|
|
|
stackenv_init(&se, "Error occurred during encoding: %s"); |
|
|
|
|
upb_json_printer* printer = |
|
|
|
|
upb_json_printer_create(&se.env, serialize_handlers, &sink.sink); |
|
|
|
|
stackenv_init(&se, "Error occurred during encoding: %s"); |
|
|
|
|
printer = upb_json_printer_create(&se.env, serialize_handlers, &sink.sink); |
|
|
|
|
|
|
|
|
|
putmsg(msg_rb, desc, upb_json_printer_input(printer), 0); |
|
|
|
|
putmsg(msg_rb, desc, upb_json_printer_input(printer), 0); |
|
|
|
|
|
|
|
|
|
VALUE ret = rb_str_new(sink.ptr, sink.len); |
|
|
|
|
ret = rb_str_new(sink.ptr, sink.len); |
|
|
|
|
|
|
|
|
|
stackenv_uninit(&se); |
|
|
|
|
stringsink_uninit(&sink); |
|
|
|
|
stackenv_uninit(&se); |
|
|
|
|
stringsink_uninit(&sink); |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|