summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2010-01-15 10:51:33 -0800
committerJoshua Haberman <joshua@reverberate.org>2010-01-15 10:51:33 -0800
commit088b995c9e873178ec5761418534ed108e20c4b5 (patch)
tree1a550e293b6dfc8782e3f923cbf2b98fa820f219 /src
parent90e4f086788169f870405646bc22ca866aa21b67 (diff)
Make msgsrc reversable.
Diffstat (limited to 'src')
-rw-r--r--src/upb_data.c16
-rw-r--r--src/upb_data.h3
-rw-r--r--src/upb_serialize.c2
3 files changed, 12 insertions, 9 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);
}
}
}
diff --git a/src/upb_data.h b/src/upb_data.h
index b0c9b6d..22a5ea9 100644
--- a/src/upb_data.h
+++ b/src/upb_data.h
@@ -524,7 +524,8 @@ void upb_msg_parsestr(upb_msg *msg, struct upb_msgdef *md, upb_strptr str,
// A nonresumable, non-interruptable (but simple and fast) source for pushing
// the data of a upb_msg to a upb_sink.
-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);
/* upb_msgsink ****************************************************************/
diff --git a/src/upb_serialize.c b/src/upb_serialize.c
index f3cf5b0..5503239 100644
--- a/src/upb_serialize.c
+++ b/src/upb_serialize.c
@@ -253,7 +253,7 @@ static upb_sink_status _upb_serializersink_strcb(upb_sink *sink, struct upb_fiel
// TODO: properly handle partially consumed strings and partially supplied
// strings.
_upb_serializer_push_buf(s, buf, ptr - buf);
- return _upb_serializer_push_buf(s, upb_string_getrobuf(str), end - start);
+ return _upb_serializer_push_buf(s, (uint8_t*)upb_string_getrobuf(str), end - start);
}
static upb_sink_status _upb_serializersink_startcb(upb_sink *sink,
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback