diff options
author | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2014-03-15 08:45:58 +0200 |
---|---|---|
committer | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2014-03-15 08:45:58 +0200 |
commit | 9be2cfe968b4223f9d416aecd483f3b999bbab71 (patch) | |
tree | a13eb74ba8f6ac70fe3e63e89457f46be4df90c1 /pb_decode.c | |
parent | 9c196b89ba04733529edfe970af6307a34de1662 (diff) |
Get rid of pb_bytes_ptr_t, just allocate pb_bytes_array_t dynamically.
This makes the internal logic much simpler, and also keeps the datatypes
more similar between STATIC/POINTER cases. It will still be a bit cumbersome
to use because of variable length array member. Macros PB_BYTES_ARRAY_T(n) and
PB_BYTES_ARRAY_T_ALLOCSIZE(n) have been added to make life a bit easier.
This has the drawback that it is no longer as easy to use externally allocated
byte array as input for bytes field in pointer mode. However, this is still
easy to do using callbacks, so it shouldn't be a large issue.
Diffstat (limited to 'pb_decode.c')
-rw-r--r-- | pb_decode.c | 58 |
1 files changed, 17 insertions, 41 deletions
diff --git a/pb_decode.c b/pb_decode.c index 68497406..81febb9b 100644 --- a/pb_decode.c +++ b/pb_decode.c @@ -491,13 +491,10 @@ static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t /* Clear a newly allocated item in case it contains a pointer, or is a submessage. */ static void initialize_pointer_field(void *pItem, pb_field_iterator_t *iter) { - if (PB_LTYPE(iter->pos->type) == PB_LTYPE_STRING) + if (PB_LTYPE(iter->pos->type) == PB_LTYPE_STRING || + PB_LTYPE(iter->pos->type) == PB_LTYPE_BYTES) { - *(char**)pItem = NULL; - } - else if (PB_LTYPE(iter->pos->type) == PB_LTYPE_BYTES) - { - memset(pItem, 0, iter->pos->data_size); + *(void**)pItem = NULL; } else if (PB_LTYPE(iter->pos->type) == PB_LTYPE_SUBMESSAGE) { @@ -523,7 +520,8 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_ { case PB_HTYPE_REQUIRED: case PB_HTYPE_OPTIONAL: - if (PB_LTYPE(type) == PB_LTYPE_STRING) + if (PB_LTYPE(type) == PB_LTYPE_STRING || + PB_LTYPE(type) == PB_LTYPE_BYTES) { return func(stream, iter->pos, iter->pData); } @@ -930,10 +928,11 @@ void pb_release(const pb_field_t fields[], void *dest_struct) if (PB_ATYPE(type) == PB_ATYPE_POINTER) { - if (PB_LTYPE(type) == PB_LTYPE_STRING && - PB_HTYPE(type) == PB_HTYPE_REPEATED) + if (PB_HTYPE(type) == PB_HTYPE_REPEATED && + (PB_LTYPE(type) == PB_LTYPE_STRING || + PB_LTYPE(type) == PB_LTYPE_BYTES)) { - /* Release entries in repeated string array */ + /* Release entries in repeated string or bytes array */ void **pItem = *(void***)iter.pData; size_t count = *(size_t*)iter.pSize; while (count--) @@ -942,24 +941,6 @@ void pb_release(const pb_field_t fields[], void *dest_struct) *pItem++ = NULL; } } - else if (PB_LTYPE(type) == PB_LTYPE_BYTES) - { - /* Release entries in repeated bytes array */ - pb_bytes_ptr_t *pItem = *(pb_bytes_ptr_t**)iter.pData; - size_t count = (pItem ? 1 : 0); - - if (PB_HTYPE(type) == PB_HTYPE_REPEATED) - { - count = *(size_t*)iter.pSize; - } - - while (count--) - { - free(pItem->bytes); - pItem->bytes = NULL; - pItem++; - } - } else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE) { /* Release fields in submessages */ @@ -1109,35 +1090,30 @@ bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, v bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest) { uint32_t size; - size_t alloc_size; + pb_bytes_array_t *bdest; if (!pb_decode_varint32(stream, &size)) return false; - /* Space for the size_t header */ - alloc_size = size + offsetof(pb_bytes_array_t, bytes); - if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) { #ifndef PB_ENABLE_MALLOC PB_RETURN_ERROR(stream, "no malloc support"); #else - pb_bytes_ptr_t *bdest = (pb_bytes_ptr_t*)dest; - if (!allocate_field(stream, &bdest->bytes, alloc_size, 1)) + if (!allocate_field(stream, dest, PB_BYTES_ARRAY_T_ALLOCSIZE(size), 1)) return false; - - bdest->size = size; - return pb_read(stream, bdest->bytes, size); + bdest = *(pb_bytes_array_t**)dest; #endif } else { - pb_bytes_array_t* bdest = (pb_bytes_array_t*)dest; - if (alloc_size > field->data_size) + if (PB_BYTES_ARRAY_T_ALLOCSIZE(size) > field->data_size) PB_RETURN_ERROR(stream, "bytes overflow"); - bdest->size = size; - return pb_read(stream, bdest->bytes, size); + bdest = (pb_bytes_array_t*)dest; } + + bdest->size = size; + return pb_read(stream, bdest->bytes, size); } bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest) |