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
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);
}
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