aboutsummaryrefslogtreecommitdiff
path: root/php/ext/google/protobuf/encode_decode.c
diff options
context:
space:
mode:
authorPaul Yang <TeBoring@users.noreply.github.com>2017-10-09 12:39:13 -0700
committerGitHub <noreply@github.com>2017-10-09 12:39:13 -0700
commit6032746882ea48ff6d983df8cb77e2ebf399bf0c (patch)
tree700ba1d858ea0365401b639bd7ef613c90c89743 /php/ext/google/protobuf/encode_decode.c
parent77f64bb7779ec2195f9bc4dc82497d12c18fc6b7 (diff)
downloadprotobuf-6032746882ea48ff6d983df8cb77e2ebf399bf0c.tar.gz
protobuf-6032746882ea48ff6d983df8cb77e2ebf399bf0c.tar.bz2
protobuf-6032746882ea48ff6d983df8cb77e2ebf399bf0c.zip
Reserve unknown fields in php (#3659)
* 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. * Register the function to encode unknown field at decode time. * Remove upb_handlers_setaddunknown * Use upb_sink_putunknown in decoder * Remove upb_pb_encoder_encode_unknown * Do not expose encode_unknown * Implement reserve unknown field in php Implement. * Make buffer private to CodedInputStream
Diffstat (limited to 'php/ext/google/protobuf/encode_decode.c')
-rw-r--r--php/ext/google/protobuf/encode_decode.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/php/ext/google/protobuf/encode_decode.c b/php/ext/google/protobuf/encode_decode.c
index 93a5e9c4..7e2b3ae6 100644
--- a/php/ext/google/protobuf/encode_decode.c
+++ b/php/ext/google/protobuf/encode_decode.c
@@ -142,6 +142,23 @@ static const void* newhandlerdata(upb_handlers* h, uint32_t ofs) {
return hd_ofs;
}
+typedef size_t (*encodeunknown_handlerfunc)(void* _sink, const void* hd,
+ const char* ptr, size_t len,
+ const upb_bufhandle* handle);
+
+typedef struct {
+ encodeunknown_handlerfunc handler;
+} unknownfields_handlerdata_t;
+
+// Creates a handlerdata for unknown fields.
+static const void *newunknownfieldshandlerdata(upb_handlers* h) {
+ unknownfields_handlerdata_t* hd =
+ (unknownfields_handlerdata_t*)malloc(sizeof(unknownfields_handlerdata_t));
+ hd->handler = stringsink_string;
+ upb_handlers_addcleanup(h, hd, free);
+ return hd;
+}
+
typedef struct {
size_t ofs;
const upb_msgdef *md;
@@ -944,6 +961,24 @@ static void add_handlers_for_oneof_field(upb_handlers *h,
upb_handlerattr_uninit(&attr);
}
+static bool add_unknown_handler(void* closure, const void* hd, const char* buf,
+ size_t size) {
+ encodeunknown_handlerfunc handler =
+ ((unknownfields_handlerdata_t*)hd)->handler;
+
+ MessageHeader* msg = (MessageHeader*)closure;
+ stringsink* unknown = DEREF(message_data(msg), 0, stringsink*);
+ if (unknown == NULL) {
+ DEREF(message_data(msg), 0, stringsink*) = ALLOC(stringsink);
+ unknown = DEREF(message_data(msg), 0, stringsink*);
+ stringsink_init(unknown);
+ }
+
+ handler(unknown, NULL, buf, size, NULL);
+
+ return true;
+}
+
static void add_handlers_for_message(const void* closure,
upb_handlers* h) {
const upb_msgdef* msgdef = upb_handlers_msgdef(h);
@@ -967,6 +1002,10 @@ static void add_handlers_for_message(const void* closure,
desc->layout = create_layout(desc->msgdef);
}
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
+ upb_handlerattr_sethandlerdata(&attr, newunknownfieldshandlerdata(h));
+ upb_handlers_setunknown(h, add_unknown_handler, &attr);
+
for (upb_msg_field_begin(&i, desc->msgdef);
!upb_msg_field_done(&i);
upb_msg_field_next(&i)) {
@@ -1278,6 +1317,11 @@ static void putrawmsg(MessageHeader* msg, const Descriptor* desc,
}
}
+ stringsink* unknown = DEREF(message_data(msg), 0, stringsink*);
+ if (unknown != NULL) {
+ upb_sink_putunknown(sink, unknown->ptr, unknown->len);
+ }
+
upb_sink_endmsg(sink, &status);
}