summaryrefslogtreecommitdiff
path: root/upb/pb
diff options
context:
space:
mode:
authorBo Yang <teboring@google.com>2017-09-19 14:23:36 -0700
committerBo Yang <teboring@google.com>2017-09-19 14:23:36 -0700
commit0b7904e18cad70e17a2dbed5f1362ccdc62fd385 (patch)
treee94665631c7437d1bebb62b9a45f0c1be1f21d81 /upb/pb
parentae30b4a816a57a8101ce187245edc3050d515c06 (diff)
Reserve unknown fields in upb
1. For decoding, an unknownfields will be lazily created on message, which contains bytes of unknown fields. 2. For encoding, if the unknownfields is present on message, all bytes contained in it will be serialized.
Diffstat (limited to 'upb/pb')
-rw-r--r--upb/pb/decoder.c11
-rw-r--r--upb/pb/encoder.c13
-rw-r--r--upb/pb/encoder.h2
3 files changed, 26 insertions, 0 deletions
diff --git a/upb/pb/decoder.c b/upb/pb/decoder.c
index 182ecc9..79142bf 100644
--- a/upb/pb/decoder.c
+++ b/upb/pb/decoder.c
@@ -543,6 +543,9 @@ UPB_NOINLINE int32_t upb_pbdecoder_checktag_slow(upb_pbdecoder *d,
int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum,
uint8_t wire_type) {
+ upb_addunknown_handlerfunc *addunknown;
+ const void* hd;
+
if (fieldnum >= 0)
goto have_tag;
@@ -596,6 +599,14 @@ have_tag:
}
if (d->top->groupnum >= 0) {
+ addunknown = (upb_addunknown_handlerfunc *)upb_handlers_gethandler(
+ (d->top->sink).handlers, UPB_UNKNOWN_SELECTOR);
+ if (addunknown != NULL) {
+ hd = upb_handlers_gethandlerdata((d->top->sink).handlers,
+ UPB_UNKNOWN_SELECTOR);
+ addunknown((d->top->sink).closure, hd, d->checkpoint,
+ d->ptr - d->checkpoint);
+ }
return DECODE_OK;
}
diff --git a/upb/pb/encoder.c b/upb/pb/encoder.c
index b457867..b8e9191 100644
--- a/upb/pb/encoder.c
+++ b/upb/pb/encoder.c
@@ -374,6 +374,12 @@ static void *encode_startdelimfield(void *c, const void *hd) {
return ok ? c : UPB_BREAK;
}
+static bool encode_unknown(void *c, const void *hd, const char *buf,
+ size_t len) {
+ UPB_UNUSED(hd);
+ return encode_bytes(c, buf, len) && commit(c);
+}
+
static bool encode_enddelimfield(void *c, const void *hd) {
UPB_UNUSED(hd);
return end_delim(c);
@@ -436,6 +442,7 @@ static void newhandlers_callback(const void *closure, upb_handlers *h) {
upb_handlers_setstartmsg(h, startmsg, NULL);
upb_handlers_setendmsg(h, endmsg, NULL);
+ upb_handlers_setunknown(h, encode_unknown, NULL);
m = upb_handlers_msgdef(h);
for(upb_msg_field_begin(&i, m);
@@ -564,3 +571,9 @@ upb_pb_encoder *upb_pb_encoder_create(upb_env *env, const upb_handlers *h,
}
upb_sink *upb_pb_encoder_input(upb_pb_encoder *e) { return &e->input_; }
+
+void upb_pb_encoder_encode_unknown(upb_pb_encoder *p, const char *buf,
+ size_t size) {
+ encode_bytes(p, buf, size);
+ commit(p);
+}
diff --git a/upb/pb/encoder.h b/upb/pb/encoder.h
index 41b7e7b..3d8dce1 100644
--- a/upb/pb/encoder.h
+++ b/upb/pb/encoder.h
@@ -64,6 +64,8 @@ const upb_handlers *upb_pb_encoder_newhandlers(const upb_msgdef *m,
upb_sink *upb_pb_encoder_input(upb_pb_encoder *p);
upb_pb_encoder* upb_pb_encoder_create(upb_env* e, const upb_handlers* h,
upb_bytessink* output);
+void upb_pb_encoder_encode_unknown(upb_pb_encoder* p, const char* buf,
+ size_t size);
UPB_END_EXTERN_C
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback