int varint_u64_encode(uint8_t** start, const uint8_t* limit, uint64_t value) { uint64_t offset; uint8_t* position; int bytes; for (bytes = 1, offset = 0x80; value >= offset && bytes < 9; ++bytes) { offset = (offset << 7 ) | 0x80; } position = *start; value -= ( offset >> 7 ) ^ 1; if (position + bytes > limit) {return 0; /* not enough space */} *position = (((uint8_t)0xFF) << (9-bytes)) | (uint8_t)(value >> ((bytes-1) * 8 )); for (++position; --bytes > 0; ++position) { *position = (uint8_t) (value >> ((bytes-1) * 8)); } *start = position; return 1; } int varint_u64_decode(const uint8_t** start, const uint8_t* limit, uint64_t* result) { uint64_t value; uint64_t offset; const uint8_t* position; int bytes; uint8_t mask; position = *start; offset = 0; for(bytes=1, mask = 0x80; (mask & *position) == mask && bytes < 9; ++bytes) { mask = 0x80 | (mask >> 1); offset = (offset << 7) | 0x80; } if (position + bytes > limit) { return 0; /* not enough space */} value = (~mask) & *position; ++ position; for(; --bytes > 0; ++position) { value = (value << 8) + *position; } value += offset; if (bytes == 9 && value < (1uLL << 56)) {return 0; /* overflow, non-canonical encoding */ } *result = value; *start = position; return 1; }