1
0

hmath.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #ifndef HV_MATH_H_
  2. #define HV_MATH_H_
  3. #include <math.h>
  4. static inline unsigned long floor2e(unsigned long num) {
  5. unsigned long n = num;
  6. int e = 0;
  7. while (n>>=1) ++e;
  8. unsigned long ret = 1;
  9. while (e--) ret<<=1;
  10. return ret;
  11. }
  12. static inline unsigned long ceil2e(unsigned long num) {
  13. // 2**0 = 1
  14. if (num == 0 || num == 1) return 1;
  15. unsigned long n = num - 1;
  16. int e = 1;
  17. while (n>>=1) ++e;
  18. unsigned long ret = 1;
  19. while (e--) ret<<=1;
  20. return ret;
  21. }
  22. // varint little-endian
  23. // MSB
  24. static inline int varint_encode(long long value, unsigned char* buf) {
  25. unsigned char ch;
  26. unsigned char *p = buf;
  27. int bytes = 0;
  28. do {
  29. ch = value & 0x7F;
  30. value >>= 7;
  31. *p++ = value == 0 ? ch : (ch | 0x80);
  32. ++bytes;
  33. } while (value);
  34. return bytes;
  35. }
  36. // @param[IN|OUT] len: in=>buflen, out=>varint bytesize
  37. static inline long long varint_decode(const unsigned char* buf, int* len) {
  38. long long ret = 0;
  39. int bytes = 0, bits = 0;
  40. const unsigned char *p = buf;
  41. do {
  42. if (len && *len && bytes == *len) {
  43. // Not enough length
  44. *len = 0;
  45. return 0;
  46. }
  47. ret |= ((long long)(*p & 0x7F)) << bits;
  48. ++bytes;
  49. if ((*p & 0x80) == 0) {
  50. // Found end
  51. if (len) *len = bytes;
  52. return ret;
  53. }
  54. ++p;
  55. bits += 7;
  56. } while(bytes < 10);
  57. // Not found end
  58. if (len) *len = -1;
  59. return ret;
  60. }
  61. static inline int asn1_encode(long long value, unsigned char* buf) {
  62. /*
  63. * unrolled for efficiency
  64. * check each possibitlity of the 4 byte integer
  65. */
  66. unsigned char* p = buf;
  67. if (value < 128)
  68. {
  69. *p = (unsigned char)value;
  70. return 1;
  71. }
  72. else if (value < 256)
  73. {
  74. *p = 0x81;
  75. p++;
  76. *p = (unsigned char)value;
  77. return 2;
  78. }
  79. else if (value < 65536)
  80. {
  81. *p = 0x82;
  82. p++;
  83. *p = (unsigned char)(value>>8);
  84. p++;
  85. *p = (unsigned char)value;
  86. return 3;
  87. }
  88. else if (value < 16777126)
  89. {
  90. *p = 0x83;
  91. p++;
  92. *p = (unsigned char)(value>>16);
  93. p++;
  94. *p = (unsigned char)(value >> 8);
  95. p++;
  96. *p = (unsigned char)value;
  97. return 4;
  98. }
  99. else
  100. {
  101. *p = 0x84;
  102. p++;
  103. *p = (unsigned char)(value >> 24);
  104. p++;
  105. *p = (unsigned char)(value >> 16);
  106. p++;
  107. *p = (unsigned char)(value >> 8);
  108. p++;
  109. *p = (unsigned char)value;
  110. return 5;
  111. }
  112. }
  113. static inline long long asn1_decode(const unsigned char* buf, int* len) {
  114. long long ret = 0;
  115. int bytes = 0;
  116. unsigned int tag = 0, lenBytes = 0;
  117. const unsigned char* p = buf;
  118. tag = *p;
  119. p++;
  120. if (tag < 128) {
  121. // Single-byte data
  122. if (len) *len = 1;
  123. return tag;
  124. }
  125. else if (tag == 0x80) {
  126. // invalid data
  127. if (len) *len = -1;
  128. return 0;
  129. }
  130. // Multi-byte data
  131. bytes++;
  132. lenBytes = tag & 0x7F;
  133. for (ret = 0; lenBytes > 0; lenBytes--) {
  134. if (len && *len && bytes == *len) {
  135. // Not enough length
  136. *len = 0;
  137. return 0;
  138. }
  139. ret = (ret << 8) | *p;
  140. p++;
  141. bytes++;
  142. }
  143. if (len) *len = bytes;
  144. return ret;
  145. }
  146. #endif // HV_MATH_H_