diff options
-rw-r--r-- | pb.h | 6 | ||||
-rw-r--r-- | pb_decode.c | 8 | ||||
-rw-r--r-- | pb_encode.c | 13 |
3 files changed, 24 insertions, 3 deletions
@@ -456,9 +456,11 @@ struct pb_extension_s { 0, \ pb_membersize(st, m), 0, ptr} +#define PB_OPTEXT_POINTER(tag, st, m, fd, ltype, ptr) \ + PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr) + #define PB_OPTEXT_CALLBACK(tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \ - 0, 0, pb_membersize(st, m), 0, ptr} + PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr) /* The mapping from protobuf types to LTYPEs is done using these macros. */ #define PB_LTYPE_MAP_BOOL PB_LTYPE_VARINT diff --git a/pb_decode.c b/pb_decode.c index d1efd1b5..26d7c2b7 100644 --- a/pb_decode.c +++ b/pb_decode.c @@ -650,6 +650,14 @@ static bool checkreturn default_extension_decoder(pb_istream_t *stream, iter.pData = extension->dest; iter.pSize = &extension->found; + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { + /* For pointer extensions, the pointer is stored directly + * in the extension structure. This avoids having an extra + * indirection. */ + iter.pData = &extension->dest; + } + return decode_field(stream, wire_type, &iter); } diff --git a/pb_encode.c b/pb_encode.c index cdd78955..5318361e 100644 --- a/pb_encode.c +++ b/pb_encode.c @@ -302,7 +302,18 @@ static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension) { const pb_field_t *field = (const pb_field_t*)extension->type->arg; - return encode_field(stream, field, extension->dest); + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { + /* For pointer extensions, the pointer is stored directly + * in the extension structure. This avoids having an extra + * indirection. */ + return encode_field(stream, field, &extension->dest); + } + else + { + return encode_field(stream, field, extension->dest); + } } /* Walk through all the registered extensions and give them a chance |