hbase.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. #include "hbase.h"
  2. #ifdef OS_DARWIN
  3. #include <mach-o/dyld.h> // for _NSGetExecutablePath
  4. #endif
  5. #include "hatomic.h"
  6. #ifndef RAND_MAX
  7. #define RAND_MAX 2147483647
  8. #endif
  9. static hatomic_t s_alloc_cnt = HATOMIC_VAR_INIT(0);
  10. static hatomic_t s_free_cnt = HATOMIC_VAR_INIT(0);
  11. long hv_alloc_cnt() {
  12. return s_alloc_cnt;
  13. }
  14. long hv_free_cnt() {
  15. return s_free_cnt;
  16. }
  17. void* hv_malloc(size_t size) {
  18. hatomic_inc(&s_alloc_cnt);
  19. void* ptr = malloc(size);
  20. if (!ptr) {
  21. fprintf(stderr, "malloc failed!\n");
  22. exit(-1);
  23. }
  24. return ptr;
  25. }
  26. void* hv_realloc(void* oldptr, size_t newsize, size_t oldsize) {
  27. hatomic_inc(&s_alloc_cnt);
  28. if (oldptr) hatomic_inc(&s_free_cnt);
  29. void* ptr = realloc(oldptr, newsize);
  30. if (!ptr) {
  31. fprintf(stderr, "realloc failed!\n");
  32. exit(-1);
  33. }
  34. if (newsize > oldsize) {
  35. memset((char*)ptr + oldsize, 0, newsize - oldsize);
  36. }
  37. return ptr;
  38. }
  39. void* hv_calloc(size_t nmemb, size_t size) {
  40. hatomic_inc(&s_alloc_cnt);
  41. void* ptr = calloc(nmemb, size);
  42. if (!ptr) {
  43. fprintf(stderr, "calloc failed!\n");
  44. exit(-1);
  45. }
  46. return ptr;
  47. }
  48. void* hv_zalloc(size_t size) {
  49. hatomic_inc(&s_alloc_cnt);
  50. void* ptr = malloc(size);
  51. if (!ptr) {
  52. fprintf(stderr, "malloc failed!\n");
  53. exit(-1);
  54. }
  55. memset(ptr, 0, size);
  56. return ptr;
  57. }
  58. void hv_free(void* ptr) {
  59. if (ptr) {
  60. free(ptr);
  61. ptr = NULL;
  62. hatomic_inc(&s_free_cnt);
  63. }
  64. }
  65. char* hv_strupper(char* str) {
  66. char* p = str;
  67. while (*p != '\0') {
  68. if (*p >= 'a' && *p <= 'z') {
  69. *p &= ~0x20;
  70. }
  71. ++p;
  72. }
  73. return str;
  74. }
  75. char* hv_strlower(char* str) {
  76. char* p = str;
  77. while (*p != '\0') {
  78. if (*p >= 'A' && *p <= 'Z') {
  79. *p |= 0x20;
  80. }
  81. ++p;
  82. }
  83. return str;
  84. }
  85. char* hv_strreverse(char* str) {
  86. if (str == NULL) return NULL;
  87. char* b = str;
  88. char* e = str;
  89. while(*e) {++e;}
  90. --e;
  91. char tmp;
  92. while (e > b) {
  93. tmp = *e;
  94. *e = *b;
  95. *b = tmp;
  96. --e;
  97. ++b;
  98. }
  99. return str;
  100. }
  101. // n = sizeof(dest_buf)
  102. char* hv_strncpy(char* dest, const char* src, size_t n) {
  103. assert(dest != NULL && src != NULL);
  104. char* ret = dest;
  105. while (*src != '\0' && --n > 0) {
  106. *dest++ = *src++;
  107. }
  108. *dest = '\0';
  109. return ret;
  110. }
  111. // n = sizeof(dest_buf)
  112. char* hv_strncat(char* dest, const char* src, size_t n) {
  113. assert(dest != NULL && src != NULL);
  114. char* ret = dest;
  115. while (*dest) {++dest;--n;}
  116. while (*src != '\0' && --n > 0) {
  117. *dest++ = *src++;
  118. }
  119. *dest = '\0';
  120. return ret;
  121. }
  122. bool hv_strstartswith(const char* str, const char* start) {
  123. assert(str != NULL && start != NULL);
  124. while (*str && *start && *str == *start) {
  125. ++str;
  126. ++start;
  127. }
  128. return *start == '\0';
  129. }
  130. bool hv_strendswith(const char* str, const char* end) {
  131. assert(str != NULL && end != NULL);
  132. int len1 = 0;
  133. int len2 = 0;
  134. while (*str) {++str; ++len1;}
  135. while (*end) {++end; ++len2;}
  136. if (len1 < len2) return false;
  137. while (len2-- > 0) {
  138. --str;
  139. --end;
  140. if (*str != *end) {
  141. return false;
  142. }
  143. }
  144. return true;
  145. }
  146. bool hv_strcontains(const char* str, const char* sub) {
  147. assert(str != NULL && sub != NULL);
  148. return strstr(str, sub) != NULL;
  149. }
  150. bool hv_wildcard_match(const char* str, const char* pattern) {
  151. assert(str != NULL && pattern != NULL);
  152. bool match = false;
  153. while (*str && *pattern) {
  154. if (*pattern == '*') {
  155. match = hv_strendswith(str, pattern + 1);
  156. break;
  157. } else if (*str != *pattern) {
  158. match = false;
  159. break;
  160. } else {
  161. ++str;
  162. ++pattern;
  163. }
  164. }
  165. return match ? match : (*str == '\0' && *pattern == '\0');
  166. }
  167. char* hv_strnchr(const char* s, char c, size_t n) {
  168. assert(s != NULL);
  169. const char* p = s;
  170. while (*p != '\0' && n-- > 0) {
  171. if (*p == c) return (char*)p;
  172. ++p;
  173. }
  174. return NULL;
  175. }
  176. char* hv_strnrchr(const char* s, char c, size_t n) {
  177. assert(s != NULL);
  178. const char* p = s;
  179. const char* last = NULL;
  180. while (*p != '\0' && n-- > 0) {
  181. if (*p == c) last = p;
  182. ++p;
  183. }
  184. return (char*)last;
  185. }
  186. char* hv_strrchr_dir(const char* filepath) {
  187. char* p = (char*)filepath;
  188. while (*p) ++p;
  189. while (--p >= filepath) {
  190. #ifdef OS_WIN
  191. if (*p == '/' || *p == '\\')
  192. #else
  193. if (*p == '/')
  194. #endif
  195. return p;
  196. }
  197. return NULL;
  198. }
  199. const char* hv_basename(const char* filepath) {
  200. const char* pos = hv_strrchr_dir(filepath);
  201. return pos ? pos+1 : filepath;
  202. }
  203. const char* hv_suffixname(const char* filename) {
  204. const char* pos = hv_strrchr_dot(filename);
  205. return pos ? pos+1 : "";
  206. }
  207. int hv_mkdir_p(const char* dir) {
  208. if (access(dir, 0) == 0) {
  209. return EEXIST;
  210. }
  211. char tmp[MAX_PATH] = {0};
  212. hv_strncpy(tmp, dir, sizeof(tmp));
  213. char* p = tmp;
  214. char delim = '/';
  215. while (*p) {
  216. #ifdef OS_WIN
  217. if (*p == '/' || *p == '\\') {
  218. delim = *p;
  219. #else
  220. if (*p == '/') {
  221. #endif
  222. *p = '\0';
  223. hv_mkdir(tmp);
  224. *p = delim;
  225. }
  226. ++p;
  227. }
  228. if (hv_mkdir(tmp) != 0) {
  229. return EPERM;
  230. }
  231. return 0;
  232. }
  233. int hv_rmdir_p(const char* dir) {
  234. if (access(dir, 0) != 0) {
  235. return ENOENT;
  236. }
  237. if (rmdir(dir) != 0) {
  238. return EPERM;
  239. }
  240. char tmp[MAX_PATH] = {0};
  241. hv_strncpy(tmp, dir, sizeof(tmp));
  242. char* p = tmp;
  243. while (*p) ++p;
  244. while (--p >= tmp) {
  245. #ifdef OS_WIN
  246. if (*p == '/' || *p == '\\') {
  247. #else
  248. if (*p == '/') {
  249. #endif
  250. *p = '\0';
  251. if (rmdir(tmp) != 0) {
  252. return 0;
  253. }
  254. }
  255. }
  256. return 0;
  257. }
  258. bool hv_exists(const char* path) {
  259. return access(path, 0) == 0;
  260. }
  261. bool hv_isdir(const char* path) {
  262. if (access(path, 0) != 0) return false;
  263. struct stat st;
  264. memset(&st, 0, sizeof(st));
  265. stat(path, &st);
  266. return S_ISDIR(st.st_mode);
  267. }
  268. bool hv_isfile(const char* path) {
  269. if (access(path, 0) != 0) return false;
  270. struct stat st;
  271. memset(&st, 0, sizeof(st));
  272. stat(path, &st);
  273. return S_ISREG(st.st_mode);
  274. }
  275. bool hv_islink(const char* path) {
  276. #ifdef OS_WIN
  277. return hv_isdir(path) && (GetFileAttributes(path) & FILE_ATTRIBUTE_REPARSE_POINT);
  278. #else
  279. if (access(path, 0) != 0) return false;
  280. struct stat st;
  281. memset(&st, 0, sizeof(st));
  282. lstat(path, &st);
  283. return S_ISLNK(st.st_mode);
  284. #endif
  285. }
  286. size_t hv_filesize(const char* filepath) {
  287. struct stat st;
  288. memset(&st, 0, sizeof(st));
  289. stat(filepath, &st);
  290. return st.st_size;
  291. }
  292. char* get_executable_path(char* buf, int size) {
  293. #ifdef OS_WIN
  294. GetModuleFileName(NULL, buf, size);
  295. #elif defined(OS_LINUX)
  296. if (readlink("/proc/self/exe", buf, size) == -1) {
  297. return NULL;
  298. }
  299. #elif defined(OS_DARWIN)
  300. _NSGetExecutablePath(buf, (uint32_t*)&size);
  301. #endif
  302. return buf;
  303. }
  304. char* get_executable_dir(char* buf, int size) {
  305. char filepath[MAX_PATH] = {0};
  306. get_executable_path(filepath, sizeof(filepath));
  307. char* pos = hv_strrchr_dir(filepath);
  308. if (pos) {
  309. *pos = '\0';
  310. strncpy(buf, filepath, size);
  311. }
  312. return buf;
  313. }
  314. char* get_executable_file(char* buf, int size) {
  315. char filepath[MAX_PATH] = {0};
  316. get_executable_path(filepath, sizeof(filepath));
  317. char* pos = hv_strrchr_dir(filepath);
  318. if (pos) {
  319. strncpy(buf, pos+1, size);
  320. }
  321. return buf;
  322. }
  323. char* get_run_dir(char* buf, int size) {
  324. return getcwd(buf, size);
  325. }
  326. int hv_rand(int min, int max) {
  327. static int s_seed = 0;
  328. assert(max > min);
  329. if (s_seed == 0) {
  330. s_seed = time(NULL);
  331. srand(s_seed);
  332. }
  333. int _rand = rand();
  334. _rand = min + (int) ((double) ((double) (max) - (min) + 1.0) * ((_rand) / ((RAND_MAX) + 1.0)));
  335. return _rand;
  336. }
  337. char* hv_random_string(char *buf, int len) {
  338. static char s_characters[] = {
  339. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
  340. 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
  341. 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  342. };
  343. int i = 0;
  344. for (; i < len; i++) {
  345. buf[i] = s_characters[hv_rand(0, sizeof(s_characters) - 1)];
  346. }
  347. buf[i] = '\0';
  348. return buf;
  349. }
  350. bool hv_getboolean(const char* str) {
  351. if (str == NULL) return false;
  352. int len = strlen(str);
  353. if (len == 0) return false;
  354. switch (len) {
  355. case 1: return *str == '1' || *str == 'y' || *str == 'Y';
  356. case 2: return stricmp(str, "on") == 0;
  357. case 3: return stricmp(str, "yes") == 0;
  358. case 4: return stricmp(str, "true") == 0;
  359. case 6: return stricmp(str, "enable") == 0;
  360. default: return false;
  361. }
  362. }
  363. size_t hv_parse_size(const char* str) {
  364. size_t size = 0, n = 0;
  365. const char* p = str;
  366. char c;
  367. while ((c = *p) != '\0') {
  368. if (c >= '0' && c <= '9') {
  369. n = n * 10 + c - '0';
  370. } else {
  371. switch (c) {
  372. case 'K': case 'k': n <<= 10; break;
  373. case 'M': case 'm': n <<= 20; break;
  374. case 'G': case 'g': n <<= 30; break;
  375. case 'T': case 't': if(sizeof(size_t) > 5) n <<= 40; break;
  376. default: break;
  377. }
  378. size += n;
  379. n = 0;
  380. }
  381. ++p;
  382. }
  383. return size + n;
  384. }
  385. time_t hv_parse_time(const char* str) {
  386. time_t time = 0, n = 0;
  387. const char* p = str;
  388. char c;
  389. while ((c = *p) != '\0') {
  390. if (c >= '0' && c <= '9') {
  391. n = n * 10 + c - '0';
  392. } else {
  393. switch (c) {
  394. case 's': break;
  395. case 'm': n *= 60; break;
  396. case 'h': n *= 60 * 60; break;
  397. case 'd': n *= 24 * 60 * 60; break;
  398. case 'w': n *= 7 * 24 * 60 * 60; break;
  399. default: break;
  400. }
  401. time += n;
  402. n = 0;
  403. }
  404. ++p;
  405. }
  406. return time + n;
  407. }
  408. int hv_parse_url(hurl_t* stURL, const char* strURL) {
  409. if (stURL == NULL || strURL == NULL) return -1;
  410. memset(stURL, 0, sizeof(hurl_t));
  411. const char* begin = strURL;
  412. const char* end = strURL;
  413. while (*end != '\0') ++end;
  414. if (end - begin > 65535) return -2;
  415. // scheme://
  416. const char* sp = strURL;
  417. const char* ep = strstr(sp, "://");
  418. if (ep) {
  419. // stURL->fields[HV_URL_SCHEME].off = sp - begin;
  420. stURL->fields[HV_URL_SCHEME].len = ep - sp;
  421. sp = ep + 3;
  422. }
  423. // user:pswd@host:port
  424. ep = strchr(sp, '/');
  425. if (ep == NULL) ep = end;
  426. const char* user = sp;
  427. const char* host = sp;
  428. const char* pos = hv_strnchr(sp, '@', ep - sp);
  429. if (pos) {
  430. // user:pswd
  431. const char* pswd = hv_strnchr(user, ':', pos - user);
  432. if (pswd) {
  433. stURL->fields[HV_URL_PASSWORD].off = pswd + 1 - begin;
  434. stURL->fields[HV_URL_PASSWORD].len = pos - pswd - 1;
  435. } else {
  436. pswd = pos;
  437. }
  438. stURL->fields[HV_URL_USERNAME].off = user - begin;
  439. stURL->fields[HV_URL_USERNAME].len = pswd - user;
  440. // @
  441. host = pos + 1;
  442. }
  443. // host:port or ipv4:port or [ipv6]:port
  444. const char* hostend = host;
  445. if (*host == '[') {
  446. pos = hv_strnchr(host, ']', ep - host);
  447. if (pos) {
  448. // ipv6
  449. host++;
  450. hostend = pos;
  451. stURL->fields[HV_URL_HOST].off = host - begin;
  452. stURL->fields[HV_URL_HOST].len = hostend - host;
  453. }
  454. }
  455. const char* port = hv_strnchr(hostend, ':', ep - hostend);
  456. if (port) {
  457. stURL->fields[HV_URL_PORT].off = port + 1 - begin;
  458. stURL->fields[HV_URL_PORT].len = ep - port - 1;
  459. // atoi
  460. for (unsigned short i = 1; i <= stURL->fields[HV_URL_PORT].len; ++i) {
  461. stURL->port = stURL->port * 10 + (port[i] - '0');
  462. }
  463. } else {
  464. port = ep;
  465. // set default port
  466. stURL->port = 80;
  467. if (stURL->fields[HV_URL_SCHEME].len > 0) {
  468. if (strncmp(strURL, "https://", 8) == 0) {
  469. stURL->port = 443;
  470. }
  471. }
  472. }
  473. if (stURL->fields[HV_URL_HOST].len == 0) {
  474. stURL->fields[HV_URL_HOST].off = host - begin;
  475. stURL->fields[HV_URL_HOST].len = port - host;
  476. }
  477. if (ep == end) return 0;
  478. // /path
  479. sp = ep;
  480. ep = strchr(sp, '?');
  481. if (ep == NULL) ep = end;
  482. stURL->fields[HV_URL_PATH].off = sp - begin;
  483. stURL->fields[HV_URL_PATH].len = ep - sp;
  484. if (ep == end) return 0;
  485. // ?query
  486. sp = ep + 1;
  487. ep = strchr(sp, '#');
  488. if (ep == NULL) ep = end;
  489. stURL->fields[HV_URL_QUERY].off = sp - begin;
  490. stURL->fields[HV_URL_QUERY].len = ep - sp;
  491. if (ep == end) return 0;
  492. // #fragment
  493. sp = ep + 1;
  494. ep = end;
  495. stURL->fields[HV_URL_FRAGMENT].off = sp - begin;
  496. stURL->fields[HV_URL_FRAGMENT].len = ep - sp;
  497. return 0;
  498. }