diff options
author | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2017-02-22 21:06:32 +0200 |
---|---|---|
committer | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2017-02-22 21:10:26 +0200 |
commit | 07375a126337916f3a34ea94f8085b8f89d789a1 (patch) | |
tree | ef95d9138252d8ae4797e0a7092bc7417c1abefb /pb_decode.c | |
parent | ca74746e23b5a9e7916e8fde6632d71d61603f50 (diff) |
Extend inline / fixed length bytes array support (issue #244)
Adds support for proto3 and POINTER field types to have
fixed length bytes arrays. Also changed the .proto option
to a separate fixed_length:true, while also supporting the old FT_INLINE
option.
Restructured the generator and decoder logic to threat the inline
bytes fields more like "just another field type".
Diffstat (limited to 'pb_decode.c')
-rw-r--r-- | pb_decode.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/pb_decode.c b/pb_decode.c index 92d0175d..a8cd61a7 100644 --- a/pb_decode.c +++ b/pb_decode.c @@ -42,6 +42,7 @@ static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *f static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest); static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest); static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest); static bool checkreturn pb_skip_varint(pb_istream_t *stream); static bool checkreturn pb_skip_string(pb_istream_t *stream); @@ -65,7 +66,7 @@ static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = { &pb_dec_string, &pb_dec_submessage, NULL, /* extensions */ - &pb_dec_bytes /* PB_LTYPE_FIXED_LENGTH_BYTES */ + &pb_dec_fixed_length_bytes }; /******************************* @@ -1286,12 +1287,6 @@ static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *fie } else { - if (PB_LTYPE(field->type) == PB_LTYPE_FIXED_LENGTH_BYTES) { - if (size != field->data_size) - PB_RETURN_ERROR(stream, "incorrect inline bytes size"); - return pb_read(stream, (pb_byte_t*)dest, field->data_size); - } - if (alloc_size > field->data_size) PB_RETURN_ERROR(stream, "bytes overflow"); bdest = (pb_bytes_array_t*)dest; @@ -1359,3 +1354,26 @@ static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t return false; return status; } + +static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + uint32_t size; + + if (!pb_decode_varint32(stream, &size)) + return false; + + if (size > PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "bytes overflow"); + + if (size == 0) + { + /* As a special case, treat empty bytes string as all zeros for fixed_length_bytes. */ + memset(dest, 0, field->data_size); + return true; + } + + if (size != field->data_size) + PB_RETURN_ERROR(stream, "incorrect fixed length bytes size"); + + return pb_read(stream, (pb_byte_t*)dest, field->data_size); +} |