X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=pb_encode.c;h=fbeeacfc96f2209bbc6ce6ffce689778152a4ed7;hb=41f98343c8e4c94180b514902219044510a234b1;hp=8868bb646d20f376c383d1bc9ff93fd9ddf174cc;hpb=10b5da12dc9757b345a9d6f9daeef9098731ff69;p=apps%2Fagl-service-can-low-level.git diff --git a/pb_encode.c b/pb_encode.c index 8868bb64..fbeeacfc 100644 --- a/pb_encode.c +++ b/pb_encode.c @@ -8,14 +8,14 @@ #include "pb_encode.h" #include -#ifdef __GNUC__ -/* Verify that we remember to check all return values for proper error propagation */ -#define checkreturn __attribute__((warn_unused_result)) +/* The warn_unused_result attribute appeared first in gcc-3.4.0 */ +#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) + #define checkreturn #else -#define checkreturn + /* Verify that we remember to check all return values for proper error propagation */ + #define checkreturn __attribute__((warn_unused_result)) #endif - typedef bool (*pb_encoder_t)(pb_ostream_t *stream, const pb_field_t *field, const void *src) checkreturn; /* --- Function pointers to field encoders --- @@ -37,15 +37,22 @@ static const pb_encoder_t PB_ENCODERS[PB_LTYPES_COUNT] = { static bool checkreturn buf_write(pb_ostream_t *stream, const uint8_t *buf, size_t count) { uint8_t *dest = (uint8_t*)stream->state; - memcpy(dest, buf, count); stream->state = dest + count; + + while (count--) + *dest++ = *buf++; + return true; } pb_ostream_t pb_ostream_from_buffer(uint8_t *buf, size_t bufsize) { pb_ostream_t stream; +#ifdef PB_BUFFER_ONLY + stream.callback = (void*)1; /* Just some marker value */ +#else stream.callback = &buf_write; +#endif stream.state = buf; stream.max_size = bufsize; stream.bytes_written = 0; @@ -58,9 +65,14 @@ bool checkreturn pb_write(pb_ostream_t *stream, const uint8_t *buf, size_t count { if (stream->bytes_written + count > stream->max_size) return false; - + +#ifdef PB_BUFFER_ONLY + if (!buf_write(stream, buf, count)) + return false; +#else if (!stream->callback(stream, buf, count)) return false; +#endif } stream->bytes_written += count; @@ -141,58 +153,89 @@ static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *fie return true; } +bool checkreturn encode_static_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData) +{ + pb_encoder_t func; + const void *pSize; + + func = PB_ENCODERS[PB_LTYPE(field->type)]; + pSize = (const char*)pData + field->size_offset; + + switch (PB_HTYPE(field->type)) + { + case PB_HTYPE_REQUIRED: + if (!pb_encode_tag_for_field(stream, field)) + return false; + if (!func(stream, field, pData)) + return false; + break; + + case PB_HTYPE_OPTIONAL: + if (*(const bool*)pSize) + { + if (!pb_encode_tag_for_field(stream, field)) + return false; + + if (!func(stream, field, pData)) + return false; + } + break; + + case PB_HTYPE_REPEATED: + if (!encode_array(stream, field, pData, *(const size_t*)pSize, func)) + return false; + break; + + default: + return false; + } + + return true; +} + +bool checkreturn encode_callback_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData) +{ + const pb_callback_t *callback = (const pb_callback_t*)pData; + if (callback->funcs.encode != NULL) + { + if (!callback->funcs.encode(stream, field, callback->arg)) + return false; + } + return true; +} + bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) { const pb_field_t *field = fields; const void *pData = src_struct; - const void *pSize; size_t prev_size = 0; while (field->tag != 0) { - pb_encoder_t func = PB_ENCODERS[PB_LTYPE(field->type)]; pData = (const char*)pData + prev_size + field->data_offset; - pSize = (const char*)pData + field->size_offset; - prev_size = field->data_size; - if (PB_HTYPE(field->type) == PB_HTYPE_ARRAY) + + /* Special case for static arrays */ + if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && + PB_HTYPE(field->type) == PB_HTYPE_REPEATED) + { prev_size *= field->array_size; + } - switch (PB_HTYPE(field->type)) + switch (PB_ATYPE(field->type)) { - case PB_HTYPE_REQUIRED: - if (!pb_encode_tag_for_field(stream, field)) - return false; - if (!func(stream, field, pData)) + case PB_ATYPE_STATIC: + if (!encode_static_field(stream, field, pData)) return false; break; - case PB_HTYPE_OPTIONAL: - if (*(bool*)pSize) - { - if (!pb_encode_tag_for_field(stream, field)) - return false; - - if (!func(stream, field, pData)) - return false; - } - break; - - case PB_HTYPE_ARRAY: - if (!encode_array(stream, field, pData, *(size_t*)pSize, func)) + case PB_ATYPE_CALLBACK: + if (!encode_callback_field(stream, field, pData)) return false; break; - case PB_HTYPE_CALLBACK: - { - pb_callback_t *callback = (pb_callback_t*)pData; - if (callback->funcs.encode != NULL) - { - if (!callback->funcs.encode(stream, field, callback->arg)) - return false; - } - break; - } + default: + return false; } field++; @@ -205,7 +248,7 @@ bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], cons bool checkreturn pb_encode_varint(pb_ostream_t *stream, uint64_t value) { uint8_t buffer[10]; - int i = 0; + size_t i = 0; if (value == 0) return pb_write(stream, (uint8_t*)&value, 1); @@ -225,9 +268,9 @@ bool checkreturn pb_encode_svarint(pb_ostream_t *stream, int64_t value) { uint64_t zigzagged; if (value < 0) - zigzagged = ~(value << 1); + zigzagged = (uint64_t)(~(value << 1)); else - zigzagged = value << 1; + zigzagged = (uint64_t)(value << 1); return pb_encode_varint(stream, zigzagged); } @@ -243,7 +286,7 @@ bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value) lebytes[3] = bytes[0]; return pb_write(stream, lebytes, 4); #else - return pb_write(stream, (uint8_t*)value, 4); + return pb_write(stream, (const uint8_t*)value, 4); #endif } @@ -262,14 +305,14 @@ bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value) lebytes[7] = bytes[0]; return pb_write(stream, lebytes, 8); #else - return pb_write(stream, (uint8_t*)value, 8); + return pb_write(stream, (const uint8_t*)value, 8); #endif } -bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, int field_number) +bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number) { - int tag = wiretype | (field_number << 3); - return pb_encode_varint(stream, (uint64_t)tag); + uint64_t tag = wiretype | (field_number << 3); + return pb_encode_varint(stream, tag); } bool checkreturn pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field) @@ -358,10 +401,10 @@ bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, co switch (field->data_size) { - case 1: value = *(uint8_t*)src; break; - case 2: value = *(uint16_t*)src; break; - case 4: value = *(uint32_t*)src; break; - case 8: value = *(uint64_t*)src; break; + case 1: value = *(const uint8_t*)src; break; + case 2: value = *(const uint16_t*)src; break; + case 4: value = *(const uint32_t*)src; break; + case 8: value = *(const uint64_t*)src; break; default: return false; } @@ -370,12 +413,12 @@ bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, co bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src) { - uint64_t value = 0; + int64_t value = 0; switch (field->data_size) { - case 4: value = *(int32_t*)src; break; - case 8: value = *(int64_t*)src; break; + case 4: value = *(const int32_t*)src; break; + case 8: value = *(const int64_t*)src; break; default: return false; } @@ -396,7 +439,7 @@ bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, c bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src) { - pb_bytes_array_t *bytes = (pb_bytes_array_t*)src; + const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)src; UNUSED(field); return pb_encode_string(stream, bytes->bytes, bytes->size); } @@ -404,7 +447,7 @@ bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, con bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src) { UNUSED(field); - return pb_encode_string(stream, (uint8_t*)src, strlen((char*)src)); + return pb_encode_string(stream, (const uint8_t*)src, strlen((const char*)src)); } bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src) @@ -412,6 +455,6 @@ bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field if (field->ptr == NULL) return false; - return pb_encode_submessage(stream, (pb_field_t*)field->ptr, src); + return pb_encode_submessage(stream, (const pb_field_t*)field->ptr, src); }