Improve the pb_decode_varint implementations.

Results for ARM: -4% execution time, +1% code size
This commit is contained in:
Petteri Aimonen
2013-02-06 22:11:02 +02:00
parent d23939d688
commit 4f379364b3

View File

@@ -107,37 +107,59 @@ pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize)
static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
{ {
uint8_t byte; uint8_t byte;
int bitpos = 0; uint32_t result;
*dest = 0;
while (bitpos < 32 && pb_read(stream, &byte, 1)) if (!pb_read(stream, &byte, 1))
return false;
if (!(byte & 0x80))
{ {
*dest |= (uint32_t)(byte & 0x7F) << bitpos; /* Quick case, 1 byte value */
bitpos += 7; result = byte;
if (!(byte & 0x80))
return true;
} }
else
{
/* Multibyte case */
int bitpos = 7;
result = byte & 0x7F;
PB_RETURN_ERROR(stream, "varint overflow"); do
{
if (bitpos >= 32)
PB_RETURN_ERROR(stream, "varint overflow");
if (!pb_read(stream, &byte, 1))
return false;
result |= (uint32_t)(byte & 0x7F) << bitpos;
bitpos += 7;
} while (byte & 0x80);
}
*dest = result;
return true;
} }
bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest) bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest)
{ {
uint8_t byte; uint8_t byte;
int bitpos = 0; int bitpos = 0;
*dest = 0; uint64_t result = 0;
while (bitpos < 64 && pb_read(stream, &byte, 1)) do
{ {
*dest |= (uint64_t)(byte & 0x7F) << bitpos; if (bitpos >= 64)
PB_RETURN_ERROR(stream, "varint overflow");
if (!pb_read(stream, &byte, 1))
return false;
result |= (uint64_t)(byte & 0x7F) << bitpos;
bitpos += 7; bitpos += 7;
} while (byte & 0x80);
if (!(byte & 0x80)) *dest = result;
return true; return true;
}
PB_RETURN_ERROR(stream, "varint overflow");
} }
bool checkreturn pb_skip_varint(pb_istream_t *stream) bool checkreturn pb_skip_varint(pb_istream_t *stream)