summaryrefslogtreecommitdiff
path: root/upb
diff options
context:
space:
mode:
Diffstat (limited to 'upb')
-rw-r--r--upb/decode.c12
-rw-r--r--upb/encode.c14
2 files changed, 23 insertions, 3 deletions
diff --git a/upb/decode.c b/upb/decode.c
index 1e5a6bc..1f3e4d8 100644
--- a/upb/decode.c
+++ b/upb/decode.c
@@ -200,9 +200,19 @@ static void *upb_array_add(upb_array *arr, size_t elements) {
return ret;
}
+static size_t get_field_offset(const upb_decframe *frame,
+ const upb_msglayout_field *field) {
+ if (field->oneof_index == UPB_NOT_IN_ONEOF) {
+ return field->offset;
+ } else {
+ return frame->m->oneofs[field->oneof_index].data_offset;
+ }
+}
+
static upb_array *upb_getarr(upb_decframe *frame,
const upb_msglayout_field *field) {
UPB_ASSERT(field->label == UPB_LABEL_REPEATED);
+ UPB_ASSERT(field->oneof_index == UPB_NOT_IN_ONEOF);
return *(upb_array**)&frame->msg[field->offset];
}
@@ -237,7 +247,7 @@ static void upb_setoneofcase(upb_decframe *frame,
static char *upb_decode_prepareslot(upb_decstate *d, upb_decframe *frame,
const upb_msglayout_field *field) {
- char *field_mem = frame->msg + field->offset;
+ char *field_mem = frame->msg + get_field_offset(frame, field);
upb_array *arr;
if (field->label == UPB_LABEL_REPEATED) {
diff --git a/upb/encode.c b/upb/encode.c
index d38676d..034a90d 100644
--- a/upb/encode.c
+++ b/upb/encode.c
@@ -340,6 +340,15 @@ bool upb_encode_hasscalarfield(const char *msg, const upb_msglayout *m,
}
}
+static size_t get_field_offset2(const upb_msglayout *m,
+ const upb_msglayout_field *field) {
+ if (field->oneof_index == UPB_NOT_IN_ONEOF) {
+ return field->offset;
+ } else {
+ return m->oneofs[field->oneof_index].data_offset;
+ }
+}
+
bool upb_encode_message(upb_encstate *e, const char *msg,
const upb_msglayout *m, size_t *size) {
int i;
@@ -351,13 +360,14 @@ bool upb_encode_message(upb_encstate *e, const char *msg,
for (i = m->field_count - 1; i >= 0; i--) {
const upb_msglayout_field *f = &m->fields[i];
+ size_t offset = get_field_offset2(m, f);
if (f->label == UPB_LABEL_REPEATED) {
- CHK(upb_encode_array(e, msg + f->offset, m, f));
+ CHK(upb_encode_array(e, msg + offset, m, f));
} else {
if (upb_encode_hasscalarfield(msg, m, f)) {
if (f->oneof_index == UPB_NOT_IN_ONEOF) {
- CHK(upb_encode_scalarfield(e, msg + f->offset, m, f, !m->is_proto2));
+ CHK(upb_encode_scalarfield(e, msg + offset, m, f, !m->is_proto2));
} else {
const upb_msglayout_oneof *o = &m->oneofs[f->oneof_index];
CHK(upb_encode_scalarfield(e, msg + o->data_offset,
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback