hiutil.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. #ifndef __HIUTIL_H_
  2. #define __HIUTIL_H_
  3. #include <stdarg.h>
  4. #include <stdint.h>
  5. #include <sys/types.h>
  6. #define HI_OK 0
  7. #define HI_ERROR -1
  8. #define HI_EAGAIN -2
  9. #define HI_ENOMEM -3
  10. typedef int rstatus_t; /* return type */
  11. #define LF (uint8_t) 10
  12. #define CR (uint8_t) 13
  13. #define CRLF "\x0d\x0a"
  14. #define CRLF_LEN (sizeof("\x0d\x0a") - 1)
  15. #define NELEMS(a) ((sizeof(a)) / sizeof((a)[0]))
  16. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  17. #define MAX(a, b) ((a) > (b) ? (a) : (b))
  18. #define SQUARE(d) ((d) * (d))
  19. #define VAR(s, s2, n) (((n) < 2) ? 0.0 : ((s2) - SQUARE(s)/(n)) / ((n) - 1))
  20. #define STDDEV(s, s2, n) (((n) < 2) ? 0.0 : sqrt(VAR((s), (s2), (n))))
  21. #define HI_INET4_ADDRSTRLEN (sizeof("255.255.255.255") - 1)
  22. #define HI_INET6_ADDRSTRLEN \
  23. (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") - 1)
  24. #define HI_INET_ADDRSTRLEN MAX(HI_INET4_ADDRSTRLEN, HI_INET6_ADDRSTRLEN)
  25. #define HI_UNIX_ADDRSTRLEN \
  26. (sizeof(struct sockaddr_un) - offsetof(struct sockaddr_un, sun_path))
  27. #define HI_MAXHOSTNAMELEN 256
  28. /*
  29. * Length of 1 byte, 2 bytes, 4 bytes, 8 bytes and largest integral
  30. * type (uintmax_t) in ascii, including the null terminator '\0'
  31. *
  32. * From stdint.h, we have:
  33. * # define UINT8_MAX (255)
  34. * # define UINT16_MAX (65535)
  35. * # define UINT32_MAX (4294967295U)
  36. * # define UINT64_MAX (__UINT64_C(18446744073709551615))
  37. */
  38. #define HI_UINT8_MAXLEN (3 + 1)
  39. #define HI_UINT16_MAXLEN (5 + 1)
  40. #define HI_UINT32_MAXLEN (10 + 1)
  41. #define HI_UINT64_MAXLEN (20 + 1)
  42. #define HI_UINTMAX_MAXLEN HI_UINT64_MAXLEN
  43. /*
  44. * Make data 'd' or pointer 'p', n-byte aligned, where n is a power of 2
  45. * of 2.
  46. */
  47. #define HI_ALIGNMENT sizeof(unsigned long) /* platform word */
  48. #define HI_ALIGN(d, n) (((d) + (n - 1)) & ~(n - 1))
  49. #define HI_ALIGN_PTR(p, n) \
  50. (void *) (((uintptr_t) (p) + ((uintptr_t) n - 1)) & ~((uintptr_t) n - 1))
  51. #define str3icmp(m, c0, c1, c2) \
  52. ((m[0] == c0 || m[0] == (c0 ^ 0x20)) && \
  53. (m[1] == c1 || m[1] == (c1 ^ 0x20)) && \
  54. (m[2] == c2 || m[2] == (c2 ^ 0x20)))
  55. #define str4icmp(m, c0, c1, c2, c3) \
  56. (str3icmp(m, c0, c1, c2) && (m[3] == c3 || m[3] == (c3 ^ 0x20)))
  57. #define str5icmp(m, c0, c1, c2, c3, c4) \
  58. (str4icmp(m, c0, c1, c2, c3) && (m[4] == c4 || m[4] == (c4 ^ 0x20)))
  59. #define str6icmp(m, c0, c1, c2, c3, c4, c5) \
  60. (str5icmp(m, c0, c1, c2, c3, c4) && (m[5] == c5 || m[5] == (c5 ^ 0x20)))
  61. #define str7icmp(m, c0, c1, c2, c3, c4, c5, c6) \
  62. (str6icmp(m, c0, c1, c2, c3, c4, c5) && \
  63. (m[6] == c6 || m[6] == (c6 ^ 0x20)))
  64. #define str8icmp(m, c0, c1, c2, c3, c4, c5, c6, c7) \
  65. (str7icmp(m, c0, c1, c2, c3, c4, c5, c6) && \
  66. (m[7] == c7 || m[7] == (c7 ^ 0x20)))
  67. #define str9icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8) \
  68. (str8icmp(m, c0, c1, c2, c3, c4, c5, c6, c7) && \
  69. (m[8] == c8 || m[8] == (c8 ^ 0x20)))
  70. #define str10icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9) \
  71. (str9icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8) && \
  72. (m[9] == c9 || m[9] == (c9 ^ 0x20)))
  73. #define str11icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10) \
  74. (str10icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9) && \
  75. (m[10] == c10 || m[10] == (c10 ^ 0x20)))
  76. #define str12icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11) \
  77. (str11icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10) && \
  78. (m[11] == c11 || m[11] == (c11 ^ 0x20)))
  79. #define str13icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12) \
  80. (str12icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11) && \
  81. (m[12] == c12 || m[12] == (c12 ^ 0x20)))
  82. #define str14icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) \
  83. (str13icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12) && \
  84. (m[13] == c13 || m[13] == (c13 ^ 0x20)))
  85. #define str15icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14) \
  86. (str14icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) && \
  87. (m[14] == c14 || m[14] == (c14 ^ 0x20)))
  88. #define str16icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15) \
  89. (str15icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14) && \
  90. (m[15] == c15 || m[15] == (c15 ^ 0x20)))
  91. /*
  92. * Wrapper to workaround well known, safe, implicit type conversion when
  93. * invoking system calls.
  94. */
  95. #define hi_gethostname(_name, _len) \
  96. gethostname((char *)_name, (size_t)_len)
  97. #define hi_atoi(_line, _n) \
  98. _hi_atoi((uint8_t *)_line, (size_t)_n)
  99. #define hi_itoa(_line, _n) \
  100. _hi_itoa((uint8_t *)_line, (int)_n)
  101. #define uint_len(_n) \
  102. _uint_len((uint32_t)_n)
  103. int hi_set_blocking(int sd);
  104. int hi_set_nonblocking(int sd);
  105. int hi_set_reuseaddr(int sd);
  106. int hi_set_tcpnodelay(int sd);
  107. int hi_set_linger(int sd, int timeout);
  108. int hi_set_sndbuf(int sd, int size);
  109. int hi_set_rcvbuf(int sd, int size);
  110. int hi_get_soerror(int sd);
  111. int hi_get_sndbuf(int sd);
  112. int hi_get_rcvbuf(int sd);
  113. int _hi_atoi(uint8_t *line, size_t n);
  114. void _hi_itoa(uint8_t *s, int num);
  115. int hi_valid_port(int n);
  116. int _uint_len(uint32_t num);
  117. /*
  118. * Memory allocation and free wrappers.
  119. *
  120. * These wrappers enables us to loosely detect double free, dangling
  121. * pointer access and zero-byte alloc.
  122. */
  123. #define hi_alloc(_s) \
  124. _hi_alloc((size_t)(_s), __FILE__, __LINE__)
  125. #define hi_zalloc(_s) \
  126. _hi_zalloc((size_t)(_s), __FILE__, __LINE__)
  127. #define hi_calloc(_n, _s) \
  128. _hi_calloc((size_t)(_n), (size_t)(_s), __FILE__, __LINE__)
  129. #define hi_realloc(_p, _s) \
  130. _hi_realloc(_p, (size_t)(_s), __FILE__, __LINE__)
  131. #define hi_free(_p) do { \
  132. _hi_free(_p, __FILE__, __LINE__); \
  133. (_p) = NULL; \
  134. } while (0)
  135. void *_hi_alloc(size_t size, const char *name, int line);
  136. void *_hi_zalloc(size_t size, const char *name, int line);
  137. void *_hi_calloc(size_t nmemb, size_t size, const char *name, int line);
  138. void *_hi_realloc(void *ptr, size_t size, const char *name, int line);
  139. void _hi_free(void *ptr, const char *name, int line);
  140. #define hi_strndup(_s, _n) \
  141. strndup((char *)(_s), (size_t)(_n));
  142. /*
  143. * Wrappers to send or receive n byte message on a blocking
  144. * socket descriptor.
  145. */
  146. #define hi_sendn(_s, _b, _n) \
  147. _hi_sendn(_s, _b, (size_t)(_n))
  148. #define hi_recvn(_s, _b, _n) \
  149. _hi_recvn(_s, _b, (size_t)(_n))
  150. /*
  151. * Wrappers to read or write data to/from (multiple) buffers
  152. * to a file or socket descriptor.
  153. */
  154. #define hi_read(_d, _b, _n) \
  155. read(_d, _b, (size_t)(_n))
  156. #define hi_readv(_d, _b, _n) \
  157. readv(_d, _b, (int)(_n))
  158. #define hi_write(_d, _b, _n) \
  159. write(_d, _b, (size_t)(_n))
  160. #define hi_writev(_d, _b, _n) \
  161. writev(_d, _b, (int)(_n))
  162. ssize_t _hi_sendn(int sd, const void *vptr, size_t n);
  163. ssize_t _hi_recvn(int sd, void *vptr, size_t n);
  164. /*
  165. * Wrappers for defining custom assert based on whether macro
  166. * HI_ASSERT_PANIC or HI_ASSERT_LOG was defined at the moment
  167. * ASSERT was called.
  168. */
  169. #ifdef HI_ASSERT_PANIC
  170. #define ASSERT(_x) do { \
  171. if (!(_x)) { \
  172. hi_assert(#_x, __FILE__, __LINE__, 1); \
  173. } \
  174. } while (0)
  175. #define NOT_REACHED() ASSERT(0)
  176. #elif HI_ASSERT_LOG
  177. #define ASSERT(_x) do { \
  178. if (!(_x)) { \
  179. hi_assert(#_x, __FILE__, __LINE__, 0); \
  180. } \
  181. } while (0)
  182. #define NOT_REACHED() ASSERT(0)
  183. #else
  184. #define ASSERT(_x)
  185. #define NOT_REACHED()
  186. #endif
  187. void hi_assert(const char *cond, const char *file, int line, int panic);
  188. void hi_stacktrace(int skip_count);
  189. void hi_stacktrace_fd(int fd);
  190. int _scnprintf(char *buf, size_t size, const char *fmt, ...);
  191. int _vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
  192. int64_t hi_usec_now(void);
  193. int64_t hi_msec_now(void);
  194. void print_string_with_length(char *s, size_t len);
  195. void print_string_with_length_fix_CRLF(char *s, size_t len);
  196. uint16_t crc16(const char *buf, int len);
  197. #endif