var_int.cpp
上传用户:kx_jwh
上传日期:2021-09-03
资源大小:76k
文件大小:5k
源码类别:

STL

开发平台:

Visual C++

  1. /* vim: set tabstop=4 : */
  2. #include "var_int.h"
  3. #include <assert.h>
  4. #include <stdexcept>
  5. namespace febird {
  6. std::pair<uint16_t, int> load_var_uint16(const unsigned char* buf)
  7. {
  8. std::pair<uint32_t, int> x = load_var_uint32(buf);
  9. assert(x.first <= 0xFFFF);
  10. if (x.first > 0xFFFF)
  11. throw std::runtime_error(BOOST_CURRENT_FUNCTION);
  12. return std::pair<uint16_t, int>(uint16_t(x.first), x.second);
  13. }
  14. std::pair<uint32_t, int> load_var_uint32(const unsigned char* buf)
  15. {
  16. uint32_t v = 0;
  17. const unsigned char* p = buf;
  18. for (int shift = 0; shift < 35; shift += 7, ++p)
  19. {
  20. const unsigned char b = *p;
  21. v |= uint32_t(b & 0x7F) << shift;
  22. if ((b & 0x80) == 0)
  23. return std::pair<uint32_t, int>(v, int(++p-buf));
  24. }
  25. assert(0); // should not get here
  26. throw std::runtime_error(BOOST_CURRENT_FUNCTION);
  27. }
  28. std::pair<uint64_t, int> load_var_uint64(const unsigned char* buf)
  29. {
  30. uint64_t v = 0;
  31. const unsigned char* p = buf;
  32. for (int shift = 0; shift < 56; shift += 7, ++p)
  33. {
  34. register unsigned char b = *p;
  35. v |= uint64_t(b & 0x7F) << shift;
  36. if ((b & 0x80) == 0)
  37. return std::pair<uint64_t, int>(v, int(++p-buf));
  38. }
  39. v |= uint64_t(*p++) << 56;
  40. return std::pair<uint64_t, int>(v, int(p-buf));
  41. }
  42. std::pair<int16_t, int> load_var_int16(const unsigned char* buf)
  43. {
  44. std::pair<uint16_t, int> x = load_var_uint16(buf);
  45. return std::pair<int16_t, int>(var_int16_u2s(x.first), x.second);
  46. }
  47. std::pair<int32_t, int> load_var_int32(const unsigned char* buf)
  48. {
  49. std::pair<uint32_t, int> x = load_var_uint32(buf);
  50. return std::pair<int32_t, int>(var_int32_u2s(x.first), x.second);
  51. }
  52. std::pair<int64_t, int> load_var_int64(const unsigned char* buf)
  53. {
  54. std::pair<uint64_t, int> x = load_var_uint64(buf);
  55. return std::pair<int64_t, int>(var_int64_u2s(x.first), x.second);
  56. }
  57. //////////////////////////////////////////////////////////////////////////
  58. template<class IntType>
  59. unsigned char* save_var_uint(unsigned char* p, IntType x)
  60. {
  61. while (x & ~0x7F)
  62. {
  63. *p++ = (unsigned char)((x & 0x7f) | 0x80);
  64. x >>= 7; //doing unsigned shift
  65. }
  66. *p++ = (unsigned char)(x);
  67. return p;
  68. }
  69. unsigned char* save_var_uint32(unsigned char* buf, uint32_t x) { return save_var_uint(buf, x); }
  70. unsigned char* save_var_uint16(unsigned char* buf, uint16_t x) { return save_var_uint(buf, x); }
  71. unsigned char* save_var_uint64(unsigned char* p, uint64_t x)
  72. {
  73. for (int bytes = 0; bytes < 8; ++bytes)
  74. {
  75. if (x & ~0x7F) {
  76. *p++ = (unsigned char)((x & 0x7f) | 0x80);
  77. x >>= 7; //doing unsigned shift
  78. } else
  79. break;
  80. }
  81. *p++ = (unsigned char)x;
  82. return p;
  83. }
  84. unsigned char* save_var_int32(unsigned char* buf, int32_t x) { return save_var_uint32(buf, var_int32_s2u(x)); }
  85. unsigned char* save_var_int16(unsigned char* buf, int16_t x) { return save_var_uint16(buf, var_int16_s2u(x)); }
  86. unsigned char* save_var_int64(unsigned char* buf, int64_t x) { return save_var_uint64(buf, var_int64_s2u(x)); }
  87. /**
  88.  @brief reverse get var_uint32_t
  89.   
  90.  @note
  91.    - if first var_int has read, *cur == buf-1
  92.    - the sequence must all stored var_int, if not, the dilimeter byte's high bit must be 0
  93.  */
  94. uint32_t reverse_get_var_uint32(const unsigned char* buf, unsigned char const ** cur)
  95. {
  96. assert(cur);
  97. assert(*cur);
  98. assert(*cur >= buf);
  99. const unsigned char* p = *cur;
  100. uint32_t x = 0;
  101. uint32_t w = *p;
  102. assert(!(x & 0x80));
  103. int shift = 0;
  104. --p;
  105. while (p >= buf && *p & 0x80)
  106. {
  107. x = x << 7 | (uint32_t)(*p & 0x7F);
  108. shift += 7;
  109. --p;
  110. }
  111. x |= w << shift;
  112. *cur = p;
  113. return x;
  114. }
  115. /**
  116.  @brief reverse get var_int32_t
  117.   
  118.  @note if first var_int has read, *cur == buf-1
  119.  */
  120. int32_t reverse_get_var_int32(const unsigned char* buf, unsigned char const ** cur)
  121. {
  122. return var_int32_u2s(reverse_get_var_uint32(buf, cur));
  123. }
  124. uint16_t reverse_get_var_uint16(const unsigned char* buf, unsigned char const ** cur)
  125. {
  126. // same as uint32
  127. return (uint16_t)reverse_get_var_uint32(buf, cur);
  128. }
  129. int16_t reverse_get_var_int16(const unsigned char* buf, unsigned char const ** cur)
  130. {
  131. return var_int16_u2s(reverse_get_var_uint16(buf, cur));
  132. }
  133. #if !defined(BOOST_NO_INT64_T)
  134. /**
  135.  @brief reverse get var_uint64_t
  136.   
  137.  @note if first var_int has read, *cur == buf-1
  138.  */
  139. uint64_t reverse_get_var_uint64(const unsigned char* buf, unsigned char const ** cur)
  140. {
  141. assert(cur);
  142. assert(*cur);
  143. assert(*cur >= buf);
  144. const unsigned char* p = *cur;
  145. uint64_t x = 0;
  146. uint64_t w = *p;
  147. int shift = 0;
  148. --p;
  149. while (p >= buf && shift < 56 && *p & 0x80)
  150. {
  151. x = x << 7 | (uint64_t)(*p & 0x7F);
  152. shift += 7;
  153. --p;
  154. }
  155. assert(shift <= 56);
  156. x |= w << shift;
  157. *cur = p; // p now point to last byte of prev var_int
  158. return x;
  159. }
  160. /**
  161.  @brief reverse get var_int64_t
  162.   
  163.  @note if first var_int has read, *cur == buf-1
  164.  */
  165. int64_t reverse_get_var_int64(const unsigned char* buf, unsigned char const ** cur)
  166. {
  167. return var_int64_u2s(reverse_get_var_uint64(buf, cur));
  168. }
  169. #endif //BOOST_NO_INT64_T
  170. } // namespace febird