diff options
author | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2013-11-14 17:56:42 +0200 |
---|---|---|
committer | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2013-11-14 17:56:42 +0200 |
commit | eff9e11150c0bfb6baf5d6bec2351034b72d95ed (patch) | |
tree | fac57595f904b8e5f5f01241911d25916e7c0293 | |
parent | 5813144246f8f132f90bea117e578477914be0ea (diff) |
Optimize the common case of 1-byte reads for varints.
For PB_BUFFER_ONLY configuration, this gives 20% speedup without
increasing code size.
-rw-r--r-- | pb_decode.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/pb_decode.c b/pb_decode.c index 90fa18d2..a887d155 100644 --- a/pb_decode.c +++ b/pb_decode.c @@ -124,6 +124,26 @@ bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count) return true; } +/* 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) +{ + if (!stream->bytes_left) + PB_RETURN_ERROR(stream, "end-of-stream"); + +#ifndef PB_BUFFER_ONLY + if (!stream->callback(stream, buf, 1)) + PB_RETURN_ERROR(stream, "io error"); +#else + *buf = *(uint8_t*)stream->state; + stream->state = (uint8_t*)stream->state + 1; +#endif + + stream->bytes_left--; + + return true; +} + pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize) { pb_istream_t stream; @@ -149,7 +169,7 @@ static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) uint8_t byte; uint32_t result; - if (!pb_read(stream, &byte, 1)) + if (!pb_readbyte(stream, &byte)) return false; if (!(byte & 0x80)) @@ -168,7 +188,7 @@ static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) if (bitpos >= 32) PB_RETURN_ERROR(stream, "varint overflow"); - if (!pb_read(stream, &byte, 1)) + if (!pb_readbyte(stream, &byte)) return false; result |= (uint32_t)(byte & 0x7F) << bitpos; @@ -191,7 +211,7 @@ bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest) if (bitpos >= 64) PB_RETURN_ERROR(stream, "varint overflow"); - if (!pb_read(stream, &byte, 1)) + if (!pb_readbyte(stream, &byte)) return false; result |= (uint64_t)(byte & 0x7F) << bitpos; |