summaryrefslogtreecommitdiff
path: root/upb/encode.c
diff options
context:
space:
mode:
authorJosh Haberman <jhaberman@gmail.com>2018-09-06 18:10:45 -0700
committerJosh Haberman <jhaberman@gmail.com>2018-09-06 18:10:45 -0700
commit340bd013380f23eeb3aadd6d1eb0209c5fe7312e (patch)
tree26e11ecb0f79cf5fc2365d435a99fec0058a6787 /upb/encode.c
parent3d511104acf016e1cd3ca9352193c5aeb00d4aa4 (diff)
Removed default instance and oneof array from tables.
Diffstat (limited to 'upb/encode.c')
-rw-r--r--upb/encode.c68
1 files changed, 24 insertions, 44 deletions
diff --git a/upb/encode.c b/upb/encode.c
index 034a90d..45f8159 100644
--- a/upb/encode.c
+++ b/upb/encode.c
@@ -126,16 +126,17 @@ static bool upb_put_float(upb_encstate *e, float d) {
return upb_put_fixed32(e, u32);
}
-static uint32_t upb_readcase(const char *msg, const upb_msglayout *m,
- int oneof_index) {
+static uint32_t upb_readcase(const char *msg, const upb_msglayout_field *f) {
uint32_t ret;
- memcpy(&ret, msg + m->oneofs[oneof_index].case_offset, sizeof(ret));
+ uint32_t offset = ~f->presence;
+ memcpy(&ret, msg + offset, sizeof(ret));
return ret;
}
static bool upb_readhasbit(const char *msg, const upb_msglayout_field *f) {
- UPB_ASSERT(f->hasbit != UPB_NO_HASBIT);
- return msg[f->hasbit / 8] & (1 << (f->hasbit % 8));
+ UPB_ASSERT(f->presence > 0);
+ uint32_t hasbit = f->presence;
+ return msg[hasbit / 8] & (1 << (hasbit % 8));
}
static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) {
@@ -254,9 +255,7 @@ do { ; } while(0)
static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem,
const upb_msglayout *m,
const upb_msglayout_field *f,
- bool is_proto3) {
- bool skip_zero_value = is_proto3 && f->oneof_index == UPB_NOT_IN_ONEOF;
-
+ bool skip_zero_value) {
#define CASE(ctype, type, wire_type, encodeval) do { \
ctype val = *(ctype*)field_mem; \
if (skip_zero_value && val == 0) { \
@@ -305,7 +304,7 @@ static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem,
size_t size;
void *submsg = *(void **)field_mem;
const upb_msglayout *subm = m->submsgs[f->submsg_index];
- if (skip_zero_value && submsg == NULL) {
+ if (submsg == NULL) {
return true;
}
return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
@@ -316,7 +315,7 @@ static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem,
size_t size;
void *submsg = *(void **)field_mem;
const upb_msglayout *subm = m->submsgs[f->submsg_index];
- if (skip_zero_value && submsg == NULL) {
+ if (submsg == NULL) {
return true;
}
return upb_encode_message(e, submsg, subm, &size) &&
@@ -328,52 +327,33 @@ static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem,
UPB_UNREACHABLE();
}
-bool upb_encode_hasscalarfield(const char *msg, const upb_msglayout *m,
- const upb_msglayout_field *f) {
- if (f->oneof_index != UPB_NOT_IN_ONEOF) {
- return upb_readcase(msg, m, f->oneof_index) == f->number;
- } else if (m->is_proto2) {
- return upb_readhasbit(msg, f);
- } else {
- /* For proto3, we'll test for the field being empty later. */
- return true;
- }
-}
-
-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;
size_t pre_len = e->limit - e->ptr;
- if (msg == NULL) {
- return true;
- }
-
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 + offset, m, f));
+ CHK(upb_encode_array(e, msg + f->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 + 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,
- m, f, !m->is_proto2));
+ bool skip_empty = false;
+ if (f->presence == 0) {
+ /* Proto3 presence. */
+ skip_empty = true;
+ } else if (f->presence > 0) {
+ /* Proto2 presence: hasbit. */
+ if (!upb_readhasbit(msg, f)) {
+ continue;
+ }
+ } else {
+ /* Field is in a oneof. */
+ if (upb_readcase(msg, f) != f->number) {
+ continue;
}
}
+ CHK(upb_encode_scalarfield(e, msg + f->offset, m, f, skip_empty));
}
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback