Add support for POINTER type in extensions
authorPetteri Aimonen <jpa@git.mail.kapsi.fi>
Fri, 26 Dec 2014 16:23:36 +0000 (18:23 +0200)
committerPetteri Aimonen <jpa@git.mail.kapsi.fi>
Fri, 26 Dec 2014 16:23:36 +0000 (18:23 +0200)
pb.h
pb_decode.c
pb_encode.c

diff --git a/pb.h b/pb.h
index b8a957a..442d965 100644 (file)
--- a/pb.h
+++ b/pb.h
@@ -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
index d1efd1b..26d7c2b 100644 (file)
@@ -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);
 }
 
index cdd7895..5318361 100644 (file)
@@ -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