inlined.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #ifndef NETDATA_INLINED_H
  3. #define NETDATA_INLINED_H 1
  4. #include "libnetdata.h"
  5. #ifdef KERNEL_32BIT
  6. typedef uint32_t kernel_uint_t;
  7. #define str2kernel_uint_t(string) str2uint32_t(string)
  8. #define KERNEL_UINT_FORMAT "%u"
  9. #else
  10. typedef uint64_t kernel_uint_t;
  11. #define str2kernel_uint_t(string) str2uint64_t(string)
  12. #define KERNEL_UINT_FORMAT "%" PRIu64
  13. #endif
  14. #define str2pid_t(string) str2uint32_t(string)
  15. // for faster execution, allow the compiler to inline
  16. // these functions that are called thousands of times per second
  17. static inline uint32_t simple_hash(const char *name) {
  18. unsigned char *s = (unsigned char *) name;
  19. uint32_t hval = 0x811c9dc5;
  20. while (*s) {
  21. hval *= 16777619;
  22. hval ^= (uint32_t) *s++;
  23. }
  24. return hval;
  25. }
  26. static inline uint32_t simple_uhash(const char *name) {
  27. unsigned char *s = (unsigned char *) name;
  28. uint32_t hval = 0x811c9dc5, c;
  29. while ((c = *s++)) {
  30. if (unlikely(c >= 'A' && c <= 'Z')) c += 'a' - 'A';
  31. hval *= 16777619;
  32. hval ^= c;
  33. }
  34. return hval;
  35. }
  36. static inline int simple_hash_strcmp(const char *name, const char *b, uint32_t *hash) {
  37. unsigned char *s = (unsigned char *) name;
  38. uint32_t hval = 0x811c9dc5;
  39. int ret = 0;
  40. while (*s) {
  41. if(!ret) ret = *s - *b++;
  42. hval *= 16777619;
  43. hval ^= (uint32_t) *s++;
  44. }
  45. *hash = hval;
  46. return ret;
  47. }
  48. static inline int str2i(const char *s) {
  49. int n = 0;
  50. char c, negative = (*s == '-');
  51. for(c = (negative)?*(++s):*s; c >= '0' && c <= '9' ; c = *(++s)) {
  52. n *= 10;
  53. n += c - '0';
  54. }
  55. if(unlikely(negative))
  56. return -n;
  57. return n;
  58. }
  59. static inline long str2l(const char *s) {
  60. long n = 0;
  61. char c, negative = (*s == '-');
  62. for(c = (negative)?*(++s):*s; c >= '0' && c <= '9' ; c = *(++s)) {
  63. n *= 10;
  64. n += c - '0';
  65. }
  66. if(unlikely(negative))
  67. return -n;
  68. return n;
  69. }
  70. static inline uint32_t str2uint32_t(const char *s) {
  71. uint32_t n = 0;
  72. char c;
  73. for(c = *s; c >= '0' && c <= '9' ; c = *(++s)) {
  74. n *= 10;
  75. n += c - '0';
  76. }
  77. return n;
  78. }
  79. static inline uint64_t str2uint64_t(const char *s) {
  80. uint64_t n = 0;
  81. char c;
  82. for(c = *s; c >= '0' && c <= '9' ; c = *(++s)) {
  83. n *= 10;
  84. n += c - '0';
  85. }
  86. return n;
  87. }
  88. static inline unsigned long str2ul(const char *s) {
  89. unsigned long n = 0;
  90. char c;
  91. for(c = *s; c >= '0' && c <= '9' ; c = *(++s)) {
  92. n *= 10;
  93. n += c - '0';
  94. }
  95. return n;
  96. }
  97. static inline unsigned long long str2ull(const char *s) {
  98. unsigned long long n = 0;
  99. char c;
  100. for(c = *s; c >= '0' && c <= '9' ; c = *(++s)) {
  101. n *= 10;
  102. n += c - '0';
  103. }
  104. return n;
  105. }
  106. static inline long long str2ll(const char *s, char **endptr) {
  107. int negative = 0;
  108. if(unlikely(*s == '-')) {
  109. s++;
  110. negative = 1;
  111. }
  112. else if(unlikely(*s == '+'))
  113. s++;
  114. long long n = 0;
  115. char c;
  116. for(c = *s; c >= '0' && c <= '9' ; c = *(++s)) {
  117. n *= 10;
  118. n += c - '0';
  119. }
  120. if(unlikely(endptr))
  121. *endptr = (char *)s;
  122. if(unlikely(negative))
  123. return -n;
  124. else
  125. return n;
  126. }
  127. static inline long double str2ld(const char *s, char **endptr) {
  128. int negative = 0;
  129. const char *start = s;
  130. unsigned long long integer_part = 0;
  131. unsigned long decimal_part = 0;
  132. size_t decimal_digits = 0;
  133. switch(*s) {
  134. case '-':
  135. s++;
  136. negative = 1;
  137. break;
  138. case '+':
  139. s++;
  140. break;
  141. case 'n':
  142. if(s[1] == 'a' && s[2] == 'n') {
  143. if(endptr) *endptr = (char *)&s[3];
  144. return NAN;
  145. }
  146. break;
  147. case 'i':
  148. if(s[1] == 'n' && s[2] == 'f') {
  149. if(endptr) *endptr = (char *)&s[3];
  150. return INFINITY;
  151. }
  152. break;
  153. default:
  154. break;
  155. }
  156. while (*s >= '0' && *s <= '9') {
  157. integer_part = (integer_part * 10) + (*s - '0');
  158. s++;
  159. }
  160. if(unlikely(*s == '.')) {
  161. decimal_part = 0;
  162. s++;
  163. while (*s >= '0' && *s <= '9') {
  164. decimal_part = (decimal_part * 10) + (*s - '0');
  165. s++;
  166. decimal_digits++;
  167. }
  168. }
  169. if(unlikely(*s == 'e' || *s == 'E'))
  170. return strtold(start, endptr);
  171. if(unlikely(endptr))
  172. *endptr = (char *)s;
  173. if(unlikely(negative)) {
  174. if(unlikely(decimal_digits))
  175. return -((long double)integer_part + (long double)decimal_part / powl(10.0, decimal_digits));
  176. else
  177. return -((long double)integer_part);
  178. }
  179. else {
  180. if(unlikely(decimal_digits))
  181. return (long double)integer_part + (long double)decimal_part / powl(10.0, decimal_digits);
  182. else
  183. return (long double)integer_part;
  184. }
  185. }
  186. static inline char *strncpyz(char *dst, const char *src, size_t n) {
  187. char *p = dst;
  188. while (*src && n--)
  189. *dst++ = *src++;
  190. *dst = '\0';
  191. return p;
  192. }
  193. static inline void sanitize_json_string(char *dst, char *src, size_t len) {
  194. while (*src != '\0' && len > 1) {
  195. if (*src == '\\' || *src == '\"' || *src < 0x1F) {
  196. if (*src < 0x1F) {
  197. *dst++ = '_';
  198. src++;
  199. len--;
  200. } else {
  201. *dst++ = '\\';
  202. *dst++ = *src++;
  203. len -= 2;
  204. }
  205. } else {
  206. *dst++ = *src++;
  207. len--;
  208. }
  209. }
  210. *dst = '\0';
  211. }
  212. static inline int read_file(const char *filename, char *buffer, size_t size) {
  213. if(unlikely(!size)) return 3;
  214. int fd = open(filename, O_RDONLY, 0666);
  215. if(unlikely(fd == -1)) {
  216. buffer[0] = '\0';
  217. return 1;
  218. }
  219. ssize_t r = read(fd, buffer, size);
  220. if(unlikely(r == -1)) {
  221. buffer[0] = '\0';
  222. close(fd);
  223. return 2;
  224. }
  225. buffer[r] = '\0';
  226. close(fd);
  227. return 0;
  228. }
  229. static inline int read_single_number_file(const char *filename, unsigned long long *result) {
  230. char buffer[30 + 1];
  231. int ret = read_file(filename, buffer, 30);
  232. if(unlikely(ret)) {
  233. *result = 0;
  234. return ret;
  235. }
  236. buffer[30] = '\0';
  237. *result = str2ull(buffer);
  238. return 0;
  239. }
  240. static inline int read_single_signed_number_file(const char *filename, long long *result) {
  241. char buffer[30 + 1];
  242. int ret = read_file(filename, buffer, 30);
  243. if(unlikely(ret)) {
  244. *result = 0;
  245. return ret;
  246. }
  247. buffer[30] = '\0';
  248. *result = atoll(buffer);
  249. return 0;
  250. }
  251. #endif //NETDATA_INLINED_H