diff options
Diffstat (limited to 'pb_encode.c')
-rw-r--r-- | pb_encode.c | 67 |
1 files changed, 53 insertions, 14 deletions
diff --git a/pb_encode.c b/pb_encode.c index f6e08a5..9c3ed2d 100644 --- a/pb_encode.c +++ b/pb_encode.c @@ -118,8 +118,8 @@ static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *fie if (count == 0) return true; - - if (count > field->array_size) + + if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size) PB_RETURN_ERROR(stream, "array max size exceeded"); /* We always pack arrays if the datatype allows it. */ @@ -172,8 +172,19 @@ static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *fie { if (!pb_encode_tag_for_field(stream, field)) return false; - if (!func(stream, field, p)) - return false; + + /* Special case for strings */ + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER && + PB_LTYPE(field->type) == PB_LTYPE_STRING) + { + if (!func(stream, field, *(const void**)p)) + return false; + } + else + { + if (!func(stream, field, p)) + return false; + } p = (const char*)p + field->data_size; } } @@ -194,12 +205,19 @@ static bool checkreturn encode_static_field(pb_ostream_t *stream, if (field->size_offset) pSize = (const char*)pData + field->size_offset; + else if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + pSize = *(const void**)pData ? &dummy : pData; else pSize = &dummy; - + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + pData = *(const void**)pData; + switch (PB_HTYPE(field->type)) { case PB_HTYPE_REQUIRED: + if (!pData) + return false; if (!pb_encode_tag_for_field(stream, field)) return false; if (!func(stream, field, pData)) @@ -257,6 +275,7 @@ static bool checkreturn encode_field(pb_ostream_t *stream, switch (PB_ATYPE(field->type)) { case PB_ATYPE_STATIC: + case PB_ATYPE_POINTER: return encode_static_field(stream, field, pData); case PB_ATYPE_CALLBACK: @@ -314,7 +333,10 @@ bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], cons while (field->tag != 0) { pData = (const char*)pData + prev_size + field->data_offset; - prev_size = field->data_size; + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + prev_size = sizeof(const void*); + else + prev_size = field->data_size; /* Special case for static arrays */ if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && @@ -569,10 +591,17 @@ bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, con { const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)src; - if (bytes->size + offsetof(pb_bytes_array_t, bytes) > field->data_size) - PB_RETURN_ERROR(stream, "bytes size exceeded"); - - return pb_encode_string(stream, bytes->bytes, bytes->size); + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { + return pb_encode_string(stream, *(const uint8_t**)bytes->bytes, bytes->size); + } + else + { + if (bytes->size + offsetof(pb_bytes_array_t, bytes) > field->data_size) + PB_RETURN_ERROR(stream, "bytes size exceeded"); + + return pb_encode_string(stream, bytes->bytes, bytes->size); + } } bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src) @@ -580,12 +609,22 @@ bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, co /* strnlen() is not always available, so just use a for-loop */ size_t size = 0; const char *p = (const char*)src; - while (size < field->data_size && *p != '\0') + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) { - size++; - p++; + while (*p != '\0') + { + size++; + p++; + } + } + else + { + while (size < field->data_size && *p != '\0') + { + size++; + p++; + } } - return pb_encode_string(stream, (const uint8_t*)src, size); } |