summaryrefslogtreecommitdiff
path: root/src/upb_data.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/upb_data.c')
-rw-r--r--src/upb_data.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/src/upb_data.c b/src/upb_data.c
index dab2d20..fd0415c 100644
--- a/src/upb_data.c
+++ b/src/upb_data.c
@@ -301,11 +301,11 @@ void upb_msg_parsestr(upb_msg *msg, struct upb_msgdef *md, upb_strptr str,
/* upb_msgsrc ****************************************************************/
static void _upb_msgsrc_produceval(union upb_value v, struct upb_fielddef *f,
- upb_sink *sink)
+ upb_sink *sink, bool reverse)
{
if(upb_issubmsg(f)) {
upb_sink_onstart(sink, f);
- upb_msgsrc_produce(v.msg, upb_downcast_msgdef(f->def), sink);
+ upb_msgsrc_produce(v.msg, upb_downcast_msgdef(f->def), sink, reverse);
upb_sink_onend(sink, f);
} else if(upb_isstring(f)) {
upb_sink_onstr(sink, f, v.str, 0, upb_strlen(v.str));
@@ -314,20 +314,22 @@ static void _upb_msgsrc_produceval(union upb_value v, struct upb_fielddef *f,
}
}
-void upb_msgsrc_produce(upb_msg *msg, struct upb_msgdef *md, upb_sink *sink)
+void upb_msgsrc_produce(upb_msg *msg, struct upb_msgdef *md, upb_sink *sink,
+ bool reverse)
{
for(int i = 0; i < md->num_fields; i++) {
- struct upb_fielddef *f = &md->fields[i];
+ struct upb_fielddef *f = &md->fields[reverse ? md->num_fields - i - 1 : i];
if(!upb_msg_has(msg, f)) continue;
union upb_value v = upb_msg_get(msg, f);
if(upb_isarray(f)) {
upb_arrayptr arr = v.arr;
+ upb_arraylen_t len = upb_array_len(arr);
for(upb_arraylen_t j = 0; j < upb_array_len(arr); j++) {
- union upb_value elem = upb_array_get(arr, f, j);
- _upb_msgsrc_produceval(elem, f, sink);
+ union upb_value elem = upb_array_get(arr, f, reverse ? len - j - 1 : j);
+ _upb_msgsrc_produceval(elem, f, sink, reverse);
}
} else {
- _upb_msgsrc_produceval(v, f, sink);
+ _upb_msgsrc_produceval(v, f, sink, reverse);
}
}
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback