The function is an exact copy of b_peek_varint() with ofs==0 and doing a
b_del() at the end. We can simply call that other one and delete the
contents. It turns out that the code is bigger with this change because
b_peek_varint() passes its offset to b_peek() which performs a wrapping
check. When ofs==0 the wrapping cannot happen, but there's no real way
to tell that to the compiler. Instead conditioning the if() in b_peek()
with (!__builtin_constant_p(ofs) || ofs) does the job, but it's not worth
it at the moment since we have no users of b_get_varint() for now. Let's
just stick to the simple normal code.
*/
int b_get_varint(struct buffer *b, uint64_t *vptr)
{
- const uint8_t *head = (const uint8_t *)b_head(b);
- const uint8_t *wrap = (const uint8_t *)b_wrap(b);
- size_t data = b->data;
- size_t size = b_size(b);
- uint64_t v = 0;
- int bits = 0;
-
- if (data != 0 && (*head >= 0xF0)) {
- v = *head;
- bits += 4;
- while (1) {
- if (++head == wrap)
- head -= size;
- data--;
- if (!data || !(*head & 0x80))
- break;
- v += (uint64_t)*head << bits;
- bits += 7;
- }
- }
-
- /* last byte */
- if (!data)
- return 0;
+ int size;
- v += (uint64_t)*head << bits;
- *vptr = v;
- data--;
- size = b->data - data;
+ size = b_peek_varint(b, 0, vptr);
b_del(b, size);
return size;
}