varint.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #include "varint.h"
  19. #include <errno.h>
  20. #include <stdint.h>
  21. int varint32_size(int32_t val)
  22. {
  23. if ((val & (0xffffffff << 7)) == 0) return 1;
  24. if ((val & (0xffffffff << 14)) == 0) return 2;
  25. if ((val & (0xffffffff << 21)) == 0) return 3;
  26. if ((val & (0xffffffff << 28)) == 0) return 4;
  27. return 5;
  28. }
  29. int varint32_encode(int32_t val, uint8_t *buf, int32_t len, int32_t *off)
  30. {
  31. int32_t o = *off;
  32. uint32_t var = (uint32_t)val;
  33. while (1) {
  34. if (o == len)
  35. return -ENOBUFS;
  36. if (var <= 127) {
  37. buf[o++] = var;
  38. break;
  39. }
  40. buf[o++] = 0x80 | (var & 0x7f);
  41. var >>= 7;
  42. }
  43. *off = o;
  44. return 0;
  45. }
  46. int varint32_decode(int32_t *val, const uint8_t *buf, int32_t len,
  47. int32_t *off)
  48. {
  49. uint32_t accum = 0;
  50. int shift = 0, o = *off, idx = 0;
  51. uint8_t b;
  52. do {
  53. if (o == len)
  54. return -ENOBUFS;
  55. if (idx++ > 5)
  56. return -EINVAL;
  57. b = buf[o++];
  58. accum += (b & 0x7f) << shift;
  59. shift += 7;
  60. } while(b & 0x80);
  61. *val = (int32_t)accum;
  62. *off = o;
  63. return 0;
  64. }
  65. void be32_encode(int32_t val, uint8_t *buf)
  66. {
  67. buf[0] = (val >> 24) & 0xff;
  68. buf[1] = (val >> 16) & 0xff;
  69. buf[2] = (val >> 8) & 0xff;
  70. buf[3] = (val >> 0) & 0xff;
  71. }
  72. int32_t be32_decode(const uint8_t *buf)
  73. {
  74. int32_t v = 0;
  75. v |= (buf[0] << 24);
  76. v |= (buf[1] << 16);
  77. v |= (buf[2] << 8);
  78. v |= (buf[3] << 0);
  79. return v;
  80. }
  81. // vim: ts=4:sw=4:tw=79:et