varint.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #include "varint.h"
  2. size_t varint_uint32_pack(uint32_t value, uint8_t* output) {
  3. uint8_t* start = output;
  4. while(value >= 0x80) {
  5. *output++ = (value | 0x80);
  6. value >>= 7;
  7. }
  8. *output++ = value;
  9. return output - start;
  10. }
  11. size_t varint_uint32_unpack(uint32_t* value, const uint8_t* input, size_t input_size) {
  12. size_t i;
  13. uint32_t parsed = 0;
  14. for(i = 0; i < input_size; i++) {
  15. parsed |= (input[i] & 0x7F) << (7 * i);
  16. if(!(input[i] & 0x80)) {
  17. break;
  18. }
  19. }
  20. *value = parsed;
  21. return i + 1;
  22. }
  23. size_t varint_uint32_length(uint32_t value) {
  24. size_t size = 0;
  25. while(value >= 0x80) {
  26. value >>= 7;
  27. size++;
  28. }
  29. size++;
  30. return size;
  31. }
  32. size_t varint_int32_pack(int32_t value, uint8_t* output) {
  33. uint32_t v;
  34. if(value >= 0) {
  35. v = value * 2;
  36. } else {
  37. v = (value * -2) - 1;
  38. }
  39. return varint_uint32_pack(v, output);
  40. }
  41. size_t varint_int32_unpack(int32_t* value, const uint8_t* input, size_t input_size) {
  42. uint32_t v;
  43. size_t size = varint_uint32_unpack(&v, input, input_size);
  44. if(v & 1) {
  45. *value = (int32_t)(v + 1) / (-2);
  46. } else {
  47. *value = v / 2;
  48. }
  49. return size;
  50. }
  51. size_t varint_int32_length(int32_t value) {
  52. uint32_t v;
  53. if(value >= 0) {
  54. v = value * 2;
  55. } else {
  56. v = (value * -2) - 1;
  57. }
  58. return varint_uint32_length(v);
  59. }