1
0

hbase.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. #include "hbase.h"
  2. #ifdef OS_DARWIN
  3. #include <mach-o/dyld.h> // for _NSGetExecutablePath
  4. #endif
  5. #include "hatomic.h"
  6. static hatomic_t s_alloc_cnt = HATOMIC_VAR_INIT(0);
  7. static hatomic_t s_free_cnt = HATOMIC_VAR_INIT(0);
  8. long hv_alloc_cnt() {
  9. return s_alloc_cnt;
  10. }
  11. long hv_free_cnt() {
  12. return s_free_cnt;
  13. }
  14. void* safe_malloc(size_t size) {
  15. // 原子增加内存分配计数
  16. hatomic_inc(&s_alloc_cnt);
  17. void* ptr = malloc(size);
  18. if (!ptr) {
  19. fprintf(stderr, "malloc failed!\n");
  20. exit(-1);
  21. }
  22. return ptr;
  23. }
  24. void* safe_realloc(void* oldptr, size_t newsize, size_t oldsize) {
  25. // 原子增加内存分配计数
  26. hatomic_inc(&s_alloc_cnt);
  27. // 原子增加内存释放计数
  28. 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. // 将新增的内存置0(系统库里的realloc未置空)
  35. if (newsize > oldsize) {
  36. memset((char*)ptr + oldsize, 0, newsize - oldsize);
  37. }
  38. return ptr;
  39. }
  40. void* safe_calloc(size_t nmemb, size_t size) {
  41. hatomic_inc(&s_alloc_cnt);
  42. void* ptr = calloc(nmemb, size);
  43. if (!ptr) {
  44. fprintf(stderr, "calloc failed!\n");
  45. exit(-1);
  46. }
  47. return ptr;
  48. }
  49. void* safe_zalloc(size_t size) {
  50. hatomic_inc(&s_alloc_cnt);
  51. void* ptr = malloc(size);
  52. if (!ptr) {
  53. fprintf(stderr, "malloc failed!\n");
  54. exit(-1);
  55. }
  56. memset(ptr, 0, size);
  57. return ptr;
  58. }
  59. void safe_free(void* ptr) {
  60. if (ptr) {
  61. free(ptr);
  62. ptr = NULL;
  63. hatomic_inc(&s_free_cnt);
  64. }
  65. }
  66. char* strupper(char* str) {
  67. char* p = str;
  68. while (*p != '\0') {
  69. if (*p >= 'a' && *p <= 'z') {
  70. // 大小写只有bits[5]不同,利用这一特性,使用位操作符比加减操作更高效
  71. *p &= ~0x20;
  72. }
  73. ++p;
  74. }
  75. return str;
  76. }
  77. char* strlower(char* str) {
  78. char* p = str;
  79. while (*p != '\0') {
  80. if (*p >= 'A' && *p <= 'Z') {
  81. // 大小写只有bits[5]不同,利用这一特性,使用位操作符比加减操作更高效
  82. *p |= 0x20;
  83. }
  84. ++p;
  85. }
  86. return str;
  87. }
  88. char* strreverse(char* str) {
  89. if (str == NULL) return NULL;
  90. char* b = str;
  91. char* e = str;
  92. while(*e) {++e;} // 此时e指向‘\0’结束符
  93. --e; // 此时e指向最后一个字符
  94. char tmp;
  95. // 头尾指针法
  96. while (e > b) {
  97. tmp = *e;
  98. *e = *b;
  99. *b = tmp;
  100. --e;
  101. ++b;
  102. }
  103. return str;
  104. }
  105. // n = sizeof(dest_buf)
  106. char* safe_strncpy(char* dest, const char* src, size_t n) {
  107. assert(dest != NULL && src != NULL);
  108. char* ret = dest;
  109. while (*src != '\0' && --n > 0) {
  110. *dest++ = *src++;
  111. }
  112. *dest = '\0';
  113. return ret;
  114. }
  115. // n = sizeof(dest_buf)
  116. char* safe_strncat(char* dest, const char* src, size_t n) {
  117. assert(dest != NULL && src != NULL);
  118. char* ret = dest;
  119. while (*dest) {++dest;--n;}
  120. while (*src != '\0' && --n > 0) {
  121. *dest++ = *src++;
  122. }
  123. *dest = '\0';
  124. return ret;
  125. }
  126. bool strstartswith(const char* str, const char* start) {
  127. assert(str != NULL && start != NULL);
  128. while (*str && *start && *str == *start) {
  129. ++str;
  130. ++start;
  131. }
  132. // 如果start走到了'\0'结束符,说明str是以start开头
  133. return *start == '\0';
  134. }
  135. bool strendswith(const char* str, const char* end) {
  136. assert(str != NULL && end != NULL);
  137. int len1 = 0;
  138. int len2 = 0;
  139. while (*str) {++str; ++len1;} // 统计str的长度,str此时走到了'\0'结束符
  140. while (*end) {++end; ++len2;} // 统计end的长度,end此时走到了'\0'结束符
  141. // 如果str的长度比end的长度还小,当然不可能是以end字符串结尾,直接返回false
  142. if (len1 < len2) return false;
  143. // 从最后一个字符开始比较是否相等
  144. while (len2-- > 0) {
  145. --str;
  146. --end;
  147. if (*str != *end) {
  148. return false;
  149. }
  150. }
  151. return true;
  152. }
  153. bool strcontains(const char* str, const char* sub) {
  154. assert(str != NULL && sub != NULL);
  155. // 直接使用了标准库函数strstr
  156. return strstr(str, sub) != NULL;
  157. }
  158. char* strrchr_dir(const char* filepath) {
  159. char* p = (char*)filepath;
  160. while (*p) ++p;
  161. while (--p >= filepath) {
  162. #ifdef OS_WIN
  163. // windows下通常以正斜杠‘\’表示路径分隔符
  164. if (*p == '/' || *p == '\\')
  165. #else
  166. // unix下以反斜杠‘/’表示路径分隔符
  167. if (*p == '/')
  168. #endif
  169. return p;
  170. }
  171. return NULL;
  172. }
  173. const char* hv_basename(const char* filepath) {
  174. // 找到最后一个路径分割符,返回pos+1
  175. const char* pos = strrchr_dir(filepath);
  176. return pos ? pos+1 : filepath;
  177. }
  178. const char* hv_suffixname(const char* filename) {
  179. // 找到最后一个点符号,返回pos+1
  180. const char* pos = strrchr_dot(filename);
  181. return pos ? pos+1 : "";
  182. }
  183. int hv_mkdir_p(const char* dir) {
  184. // 如果路径可访问,说明路径已经存在,直接返回
  185. if (access(dir, 0) == 0) {
  186. return EEXIST;
  187. }
  188. char tmp[MAX_PATH];
  189. safe_strncpy(tmp, dir, sizeof(tmp));
  190. char* p = tmp;
  191. char delim = '/';
  192. // 通过路径分隔符,一级一级的创建子目录
  193. while (*p) {
  194. #ifdef OS_WIN
  195. if (*p == '/' || *p == '\\') {
  196. delim = *p;
  197. #else
  198. if (*p == '/') {
  199. #endif
  200. *p = '\0';
  201. hv_mkdir(tmp);
  202. *p = delim;
  203. }
  204. ++p;
  205. }
  206. // 创建最后一级目录
  207. if (hv_mkdir(tmp) != 0) {
  208. return EPERM;
  209. }
  210. return 0;
  211. }
  212. int hv_rmdir_p(const char* dir) {
  213. // 如果路径不可访问,说明路径不存在,直接返回
  214. if (access(dir, 0) != 0) {
  215. return ENOENT;
  216. }
  217. // 删除最后一级目录
  218. if (rmdir(dir) != 0) {
  219. return EPERM;
  220. }
  221. char tmp[MAX_PATH];
  222. safe_strncpy(tmp, dir, sizeof(tmp));
  223. char* p = tmp;
  224. while (*p) ++p;
  225. // 通过路径分隔符,一级一级的删除父目录
  226. while (--p >= tmp) {
  227. #ifdef OS_WIN
  228. if (*p == '/' || *p == '\\') {
  229. #else
  230. if (*p == '/') {
  231. #endif
  232. *p = '\0';
  233. if (rmdir(tmp) != 0) {
  234. return 0;
  235. }
  236. }
  237. }
  238. return 0;
  239. }
  240. bool getboolean(const char* str) {
  241. if (str == NULL) return false;
  242. int len = strlen(str);
  243. if (len == 0) return false;
  244. // 通过长度判断后再和对应字符串做比较,
  245. // 而不需要和每个代表true的字符串都对比一遍。
  246. switch (len) {
  247. case 1: return *str == '1' || *str == 'y' || *str == 'Y';
  248. case 2: return stricmp(str, "on") == 0;
  249. case 3: return stricmp(str, "yes") == 0;
  250. case 4: return stricmp(str, "true") == 0;
  251. case 6: return stricmp(str, "enable") == 0;
  252. default: return false;
  253. }
  254. }
  255. // 获取可执行文件路径在各个操作系统上的实现不同,这里提供统一的封装接口
  256. char* get_executable_path(char* buf, int size) {
  257. #ifdef OS_WIN
  258. GetModuleFileName(NULL, buf, size);
  259. #elif defined(OS_LINUX)
  260. if (readlink("/proc/self/exe", buf, size) == -1) {
  261. return NULL;
  262. }
  263. #elif defined(OS_DARWIN)
  264. _NSGetExecutablePath(buf, (uint32_t*)&size);
  265. #endif
  266. return buf;
  267. }
  268. char* get_executable_dir(char* buf, int size) {
  269. char filepath[MAX_PATH];
  270. get_executable_path(filepath, sizeof(filepath));
  271. char* pos = strrchr_dir(filepath);
  272. if (pos) {
  273. *pos = '\0';
  274. strncpy(buf, filepath, size);
  275. }
  276. return buf;
  277. }
  278. char* get_executable_file(char* buf, int size) {
  279. char filepath[MAX_PATH];
  280. get_executable_path(filepath, sizeof(filepath));
  281. char* pos = strrchr_dir(filepath);
  282. if (pos) {
  283. strncpy(buf, pos+1, size);
  284. }
  285. return buf;
  286. }
  287. char* get_run_dir(char* buf, int size) {
  288. return getcwd(buf, size);
  289. }