|
@@ -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;
|
|
|
+ }
|
|
|
}
|
|
|
|