Skip to content

Instantly share code, notes, and snippets.

@matteobertozzi
Created November 6, 2012 17:34
Show Gist options
  • Select an option

  • Save matteobertozzi/4026228 to your computer and use it in GitHub Desktop.

Select an option

Save matteobertozzi/4026228 to your computer and use it in GitHub Desktop.
VarInt with with length in the head
/*
* Variable length int encoding. The 1st byte contains the number of bytes left.
* Compared to the 7bit vint-encoding, is worst on small numbers (< 21bit) but
* better with large numbers.
*
* 0: 11110000 -> 4 v7
* 1: 00000000 -> 8 (12) v7 (14)
* 2: 00000000 -> 8 (20) v7 (21)
* 3: 00000000 -> 8 (28) v7 (28)
* 4: 00000000 -> 8 (36) v7 (35)
* 5: 00000000 -> 8 (44) v7 (42)
* 6: 00000000 -> 8 (52) v7 (49)
* 7: 00000000 -> 8 (60) v7 (56)
* 8: 00000000 -> 8 (68) v7 (63)
* 9: v7 (64)
*/
unsigned int vint_length (uint64_t value) {
if (value < (1ULL << 28)) {
if (value < (1 << 12)) {
if (value < (1 << 4)) return(1);
return(2);
}
if (value < (1ULL << 20)) return(3);
return(4);
} else {
if (value < (1ULL << 36)) return(5);
if (value < (1ULL << 44)) return(6);
if (value < (1ULL << 52)) return(7);
if (value < (1ULL << 60)) return(8);
}
return(9);
}
int vint_encode (unsigned char *buf, uint64_t value) {
unsigned int length = vint_length(value) - 1;
buf[0] = (length << 4) | (value & 0xf);
switch (length) {
case 8: buf[8] = (value >> 60) & 0xff;
case 7: buf[7] = (value >> 52) & 0xff;
case 6: buf[6] = (value >> 44) & 0xff;
case 5: buf[5] = (value >> 36) & 0xff;
case 4: buf[4] = (value >> 28) & 0xff;
case 3: buf[3] = (value >> 20) & 0xff;
case 2: buf[2] = (value >> 12) & 0xff;
case 1: buf[1] = (value >> 4) & 0xff;
}
return(1 + length);
}
int vint_decode (unsigned char *buf, uint64_t *value) {
unsigned int length;
uint64_t result;
result = buf[0] & 0xf;
switch ((length = buf[0] >> 4)) {
case 8: result += ((uint64_t)buf[8]) << 60;
case 7: result += ((uint64_t)buf[7]) << 52;
case 6: result += ((uint64_t)buf[6]) << 44;
case 5: result += ((uint64_t)buf[5]) << 36;
case 4: result += ((uint64_t)buf[4]) << 28;
case 3: result += ((uint64_t)buf[3]) << 20;
case 2: result += buf[2] << 12;
case 1: result += buf[1] << 4;
}
*value = result;
return(1 + length);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment