varint.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // This code is derived from code distributed as part of Google LevelDB.
  2. // The original is available in leveldb as util/coding.cc.
  3. // This file was retrieved Jul 15, 2013 by Robert Escriva and imported into
  4. // libe. This code is copied/modified from libe.
  5. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  6. // Use of this source code is governed by a BSD-style license that can be
  7. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  8. /* C */
  9. #include <stdint.h>
  10. #include <stdlib.h>
  11. /* macaroons */
  12. #include "varint.h"
  13. unsigned char*
  14. packvarint(uint64_t v, unsigned char* ptr)
  15. {
  16. const unsigned B = 128;
  17. while (v >= B)
  18. {
  19. *(ptr++) = (v & (B-1)) | B;
  20. v >>= 7;
  21. }
  22. *(ptr++) = (unsigned char)(v);
  23. return ptr;
  24. }
  25. const unsigned char*
  26. unpackvarint(const unsigned char* ptr,
  27. const unsigned char* end,
  28. uint64_t* value)
  29. {
  30. uint64_t result = 0;
  31. unsigned int shift;
  32. for (shift = 0; shift <= 63 && ptr < end; shift += 7)
  33. {
  34. uint64_t byte = *ptr & 0xff;
  35. ptr++;
  36. if (byte & 128)
  37. {
  38. // More bytes are present
  39. result |= ((byte & 127) << shift);
  40. }
  41. else
  42. {
  43. result |= (byte << shift);
  44. *value = result;
  45. return ptr;
  46. }
  47. }
  48. return NULL;
  49. }
  50. unsigned
  51. varint_length(uint64_t v)
  52. {
  53. int len = 1;
  54. while (v >= 128)
  55. {
  56. v >>= 7;
  57. len++;
  58. }
  59. return len;
  60. }