summaryrefslogtreecommitdiffstats
path: root/pb_decode.c
diff options
context:
space:
mode:
Diffstat (limited to 'pb_decode.c')
-rw-r--r--pb_decode.c90
1 files changed, 47 insertions, 43 deletions
diff --git a/pb_decode.c b/pb_decode.c
index e7689806..b7a0093e 100644
--- a/pb_decode.c
+++ b/pb_decode.c
@@ -23,9 +23,9 @@
typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn;
-static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t count);
+static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count);
static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest);
-static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, uint8_t *buf, size_t *size);
+static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size);
static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter);
static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter);
static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter);
@@ -72,10 +72,10 @@ static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = {
* pb_istream_t implementation *
*******************************/
-static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t count)
+static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count)
{
- const uint8_t *source = (const uint8_t*)stream->state;
- stream->state = (uint8_t*)stream->state + count;
+ const pb_byte_t *source = (const pb_byte_t*)stream->state;
+ stream->state = (pb_byte_t*)stream->state + count;
if (buf != NULL)
{
@@ -86,13 +86,13 @@ static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t coun
return true;
}
-bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count)
+bool checkreturn pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count)
{
#ifndef PB_BUFFER_ONLY
if (buf == NULL && stream->callback != buf_read)
{
/* Skip input bytes */
- uint8_t tmp[16];
+ pb_byte_t tmp[16];
while (count > 16)
{
if (!pb_read(stream, tmp, 16))
@@ -122,7 +122,7 @@ bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count)
/* Read a single byte from input stream. buf may not be NULL.
* This is an optimization for the varint decoding. */
-static bool checkreturn pb_readbyte(pb_istream_t *stream, uint8_t *buf)
+static bool checkreturn pb_readbyte(pb_istream_t *stream, pb_byte_t *buf)
{
if (stream->bytes_left == 0)
PB_RETURN_ERROR(stream, "end-of-stream");
@@ -131,8 +131,8 @@ static bool checkreturn pb_readbyte(pb_istream_t *stream, uint8_t *buf)
if (!stream->callback(stream, buf, 1))
PB_RETURN_ERROR(stream, "io error");
#else
- *buf = *(const uint8_t*)stream->state;
- stream->state = (uint8_t*)stream->state + 1;
+ *buf = *(const pb_byte_t*)stream->state;
+ stream->state = (pb_byte_t*)stream->state + 1;
#endif
stream->bytes_left--;
@@ -140,7 +140,7 @@ static bool checkreturn pb_readbyte(pb_istream_t *stream, uint8_t *buf)
return true;
}
-pb_istream_t pb_istream_from_buffer(const uint8_t *buf, size_t bufsize)
+pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize)
{
pb_istream_t stream;
/* Cast away the const from buf without a compiler error. We are
@@ -170,7 +170,7 @@ pb_istream_t pb_istream_from_buffer(const uint8_t *buf, size_t bufsize)
static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
{
- uint8_t byte;
+ pb_byte_t byte;
uint32_t result;
if (!pb_readbyte(stream, &byte))
@@ -184,7 +184,7 @@ static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
else
{
/* Multibyte case */
- uint8_t bitpos = 7;
+ uint_fast8_t bitpos = 7;
result = byte & 0x7F;
do
@@ -196,7 +196,7 @@ static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
return false;
result |= (uint32_t)(byte & 0x7F) << bitpos;
- bitpos = (uint8_t)(bitpos + 7);
+ bitpos = (uint_fast8_t)(bitpos + 7);
} while (byte & 0x80);
}
@@ -206,8 +206,8 @@ static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest)
{
- uint8_t byte;
- uint8_t bitpos = 0;
+ pb_byte_t byte;
+ uint_fast8_t bitpos = 0;
uint64_t result = 0;
do
@@ -219,7 +219,7 @@ bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest)
return false;
result |= (uint64_t)(byte & 0x7F) << bitpos;
- bitpos = (uint8_t)(bitpos + 7);
+ bitpos = (uint_fast8_t)(bitpos + 7);
} while (byte & 0x80);
*dest = result;
@@ -228,7 +228,7 @@ bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest)
bool checkreturn pb_skip_varint(pb_istream_t *stream)
{
- uint8_t byte;
+ pb_byte_t byte;
do
{
if (!pb_read(stream, &byte, 1))
@@ -287,7 +287,7 @@ bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type)
/* Read a raw value to buffer, for the purpose of passing it to callback as
* a substream. Size is maximum size on call, and actual size on return.
*/
-static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, uint8_t *buf, size_t *size)
+static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size)
{
size_t max_size = *size;
switch (wire_type)
@@ -375,7 +375,7 @@ static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t
while (substream.bytes_left > 0 && *size < iter->pos->array_size)
{
- void *pItem = (uint8_t*)iter->pData + iter->pos->data_size * (*size);
+ void *pItem = (char*)iter->pData + iter->pos->data_size * (*size);
if (!func(&substream, iter->pos, pItem))
{
status = false;
@@ -394,7 +394,7 @@ static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t
{
/* Repeated field */
pb_size_t *size = (pb_size_t*)iter->pSize;
- void *pItem = (uint8_t*)iter->pData + iter->pos->data_size * (*size);
+ void *pItem = (char*)iter->pData + iter->pos->data_size * (*size);
if (*size >= iter->pos->array_size)
PB_RETURN_ERROR(stream, "array overflow");
@@ -548,7 +548,7 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_
}
/* Decode the array entry */
- pItem = *(uint8_t**)iter->pData + iter->pos->data_size * (*size);
+ pItem = *(char**)iter->pData + iter->pos->data_size * (*size);
initialize_pointer_field(pItem, iter);
if (!func(&substream, iter->pos, pItem))
{
@@ -584,7 +584,7 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_
if (!allocate_field(stream, iter->pData, iter->pos->data_size, *size))
return false;
- pItem = *(uint8_t**)iter->pData + iter->pos->data_size * (*size - 1);
+ pItem = *(char**)iter->pData + iter->pos->data_size * (*size - 1);
initialize_pointer_field(pItem, iter);
return func(stream, iter->pos, pItem);
}
@@ -631,7 +631,7 @@ static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type
* which in turn allows to use same callback for packed and
* not-packed fields. */
pb_istream_t substream;
- uint8_t buffer[10];
+ pb_byte_t buffer[10];
size_t size = sizeof(buffer);
if (!read_raw_value(stream, wire_type, buffer, &size))
@@ -838,7 +838,8 @@ static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_str
bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
{
- uint8_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 7) / 8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ uint32_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 31) / 32] = {0, 0};
+ const uint32_t allbits = ~(uint32_t)0;
uint32_t extension_range_start = 0;
pb_field_iter_t iter;
@@ -894,8 +895,8 @@ bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[
if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REQUIRED
&& iter.required_field_index < PB_MAX_REQUIRED_FIELDS)
{
- uint8_t tmp = (uint8_t)(1 << (iter.required_field_index & 7));
- fields_seen[iter.required_field_index >> 3] |= tmp;
+ uint32_t tmp = ((uint32_t)1 << (iter.required_field_index & 31));
+ fields_seen[iter.required_field_index >> 5] |= tmp;
}
if (!decode_field(stream, wire_type, &iter))
@@ -920,16 +921,19 @@ bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[
if (PB_HTYPE(last_type) == PB_HTYPE_REQUIRED && iter.pos->tag != 0)
req_field_count++;
- /* Check the whole bytes */
- for (i = 0; i < (req_field_count >> 3); i++)
+ if (req_field_count > 0)
{
- if (fields_seen[i] != 0xFF)
+ /* Check the whole words */
+ for (i = 0; i < (req_field_count >> 5); i++)
+ {
+ if (fields_seen[i] != allbits)
+ PB_RETURN_ERROR(stream, "missing required field");
+ }
+
+ /* Check the remaining bits */
+ if (fields_seen[req_field_count >> 5] != (allbits >> (32 - (req_field_count & 31))))
PB_RETURN_ERROR(stream, "missing required field");
}
-
- /* Check the remaining bits */
- if (fields_seen[req_field_count >> 3] != (0xFF >> (8 - (req_field_count & 7))))
- PB_RETURN_ERROR(stream, "missing required field");
}
return true;
@@ -1038,7 +1042,7 @@ static void pb_release_single_field(const pb_field_iter_t *iter)
while (count--)
{
pb_release((const pb_field_t*)iter->pos->ptr, pItem);
- pItem = (uint8_t*)pItem + iter->pos->data_size;
+ pItem = (char*)pItem + iter->pos->data_size;
}
}
}
@@ -1106,7 +1110,7 @@ bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest)
bool pb_decode_fixed32(pb_istream_t *stream, void *dest)
{
- uint8_t bytes[4];
+ pb_byte_t bytes[4];
if (!pb_read(stream, bytes, 4))
return false;
@@ -1120,7 +1124,7 @@ bool pb_decode_fixed32(pb_istream_t *stream, void *dest)
bool pb_decode_fixed64(pb_istream_t *stream, void *dest)
{
- uint8_t bytes[8];
+ pb_byte_t bytes[8];
if (!pb_read(stream, bytes, 8))
return false;
@@ -1179,8 +1183,8 @@ static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *f
switch (field->data_size)
{
- case 1: clamped = *(uint8_t*)dest = (uint8_t)value; break;
- case 2: clamped = *(uint16_t*)dest = (uint16_t)value; break;
+ case 1: clamped = *(uint_least8_t*)dest = (uint_least8_t)value; break;
+ case 2: clamped = *(uint_least16_t*)dest = (uint_least16_t)value; break;
case 4: clamped = *(uint32_t*)dest = (uint32_t)value; break;
case 8: clamped = *(uint64_t*)dest = value; break;
default: PB_RETURN_ERROR(stream, "invalid data_size");
@@ -1200,8 +1204,8 @@ static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *f
switch (field->data_size)
{
- case 1: clamped = *(int8_t*)dest = (int8_t)value; break;
- case 2: clamped = *(int16_t*)dest = (int16_t)value; break;
+ case 1: clamped = *(int_least8_t*)dest = (int_least8_t)value; break;
+ case 2: clamped = *(int_least16_t*)dest = (int_least16_t)value; break;
case 4: clamped = *(int32_t*)dest = (int32_t)value; break;
case 8: clamped = *(int64_t*)dest = value; break;
default: PB_RETURN_ERROR(stream, "invalid data_size");
@@ -1292,8 +1296,8 @@ static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *fi
PB_RETURN_ERROR(stream, "string overflow");
}
- status = pb_read(stream, (uint8_t*)dest, size);
- *((uint8_t*)dest + size) = 0;
+ status = pb_read(stream, (pb_byte_t*)dest, size);
+ *((pb_byte_t*)dest + size) = 0;
return status;
}