util.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /*
  2. * Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved.
  3. *
  4. * This file is part of ZLToolKit(https://github.com/ZLMediaKit/ZLToolKit).
  5. *
  6. * Use of this source code is governed by MIT license that can be found in the
  7. * LICENSE file in the root of the source tree. All contributing project authors
  8. * may be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef UTIL_UTIL_H_
  11. #define UTIL_UTIL_H_
  12. #include <ctime>
  13. #include <cstdio>
  14. #include <cstring>
  15. #include <memory>
  16. #include <string>
  17. #include <sstream>
  18. #include <vector>
  19. #include <atomic>
  20. #include <unordered_map>
  21. #include "function_traits.h"
  22. #if defined(_WIN32)
  23. #undef FD_SETSIZE
  24. //修改默认64为1024路
  25. #define FD_SETSIZE 1024
  26. #include <winsock2.h>
  27. #pragma comment (lib,"WS2_32")
  28. #else
  29. #include <unistd.h>
  30. #include <sys/time.h>
  31. #include <sys/types.h>
  32. #include <cstddef>
  33. #endif // defined(_WIN32)
  34. #if defined(__APPLE__)
  35. #include "TargetConditionals.h"
  36. #if TARGET_IPHONE_SIMULATOR
  37. #define OS_IPHONE
  38. #elif TARGET_OS_IPHONE
  39. #define OS_IPHONE
  40. #endif
  41. #endif //__APPLE__
  42. #define INSTANCE_IMP(class_name, ...) \
  43. class_name &class_name::Instance() { \
  44. static std::shared_ptr<class_name> s_instance(new class_name(__VA_ARGS__)); \
  45. static class_name &s_instance_ref = *s_instance; \
  46. return s_instance_ref; \
  47. }
  48. namespace toolkit {
  49. #define StrPrinter ::toolkit::_StrPrinter()
  50. class _StrPrinter : public std::string {
  51. public:
  52. _StrPrinter() {}
  53. template<typename T>
  54. _StrPrinter& operator <<(T && data) {
  55. _stream << std::forward<T>(data);
  56. this->std::string::operator=(_stream.str());
  57. return *this;
  58. }
  59. std::string operator <<(std::ostream&(*f)(std::ostream&)) const {
  60. return *this;
  61. }
  62. private:
  63. std::stringstream _stream;
  64. };
  65. //禁止拷贝基类
  66. class noncopyable {
  67. protected:
  68. noncopyable() {}
  69. ~noncopyable() {}
  70. private:
  71. //禁止拷贝
  72. noncopyable(const noncopyable &that) = delete;
  73. noncopyable(noncopyable &&that) = delete;
  74. noncopyable &operator=(const noncopyable &that) = delete;
  75. noncopyable &operator=(noncopyable &&that) = delete;
  76. };
  77. //可以保存任意的对象
  78. class Any{
  79. public:
  80. using Ptr = std::shared_ptr<Any>;
  81. Any() = default;
  82. ~Any() = default;
  83. template <typename C,typename ...ArgsType>
  84. void set(ArgsType &&...args){
  85. _data.reset(new C(std::forward<ArgsType>(args)...),[](void *ptr){
  86. delete (C*) ptr;
  87. });
  88. }
  89. template <typename C>
  90. C& get(){
  91. if(!_data){
  92. throw std::invalid_argument("Any is empty");
  93. }
  94. C *ptr = (C *)_data.get();
  95. return *ptr;
  96. }
  97. operator bool() {
  98. return _data.operator bool ();
  99. }
  100. bool empty(){
  101. return !bool();
  102. }
  103. private:
  104. std::shared_ptr<void> _data;
  105. };
  106. //用于保存一些外加属性
  107. class AnyStorage : public std::unordered_map<std::string,Any>{
  108. public:
  109. AnyStorage() = default;
  110. ~AnyStorage() = default;
  111. using Ptr = std::shared_ptr<AnyStorage>;
  112. };
  113. #ifndef CLASS_FUNC_TRAITS
  114. #define CLASS_FUNC_TRAITS(func_name) \
  115. template<typename T, typename ... ARGS> \
  116. constexpr bool Has_##func_name(decltype(&T::on##func_name) /*unused*/) { \
  117. using RET = typename function_traits<decltype(&T::on##func_name)>::return_type; \
  118. using FuncType = RET (T::*)(ARGS...); \
  119. return std::is_same<decltype(&T::on ## func_name), FuncType>::value; \
  120. } \
  121. \
  122. template<class T, typename ... ARGS> \
  123. constexpr bool Has_##func_name(...) { \
  124. return false; \
  125. } \
  126. \
  127. template<typename T, typename ... ARGS> \
  128. static void InvokeFunc_##func_name(typename std::enable_if<!Has_##func_name<T, ARGS...>(nullptr), T>::type &obj, ARGS ...args) {} \
  129. \
  130. template<typename T, typename ... ARGS>\
  131. static typename function_traits<decltype(&T::on##func_name)>::return_type InvokeFunc_##func_name(typename std::enable_if<Has_##func_name<T, ARGS...>(nullptr), T>::type &obj, ARGS ...args) {\
  132. return obj.on##func_name(std::forward<ARGS>(args)...);\
  133. }
  134. #endif //CLASS_FUNC_TRAITS
  135. #ifndef CLASS_FUNC_INVOKE
  136. #define CLASS_FUNC_INVOKE(T, obj, func_name, ...) InvokeFunc_##func_name<T>(obj, ##__VA_ARGS__)
  137. #endif //CLASS_FUNC_INVOKE
  138. CLASS_FUNC_TRAITS(Destory)
  139. CLASS_FUNC_TRAITS(Create)
  140. /**
  141. * 对象安全的构建和析构,构建后执行onCreate函数,析构前执行onDestory函数
  142. * 在函数onCreate和onDestory中可以执行构造或析构中不能调用的方法,比如说shared_from_this或者虚函数
  143. * @warning onDestory函数确保参数个数为0;否则会被忽略调用
  144. */
  145. class Creator {
  146. public:
  147. /**
  148. * 创建对象,用空参数执行onCreate和onDestory函数
  149. * @param args 对象构造函数参数列表
  150. * @return args对象的智能指针
  151. */
  152. template<typename C, typename ...ArgsType>
  153. static std::shared_ptr<C> create(ArgsType &&...args) {
  154. std::shared_ptr<C> ret(new C(std::forward<ArgsType>(args)...), [](C *ptr) {
  155. try {
  156. CLASS_FUNC_INVOKE(C, *ptr, Destory);
  157. } catch (std::exception &ex){
  158. onDestoryException(typeid(C), ex);
  159. }
  160. delete ptr;
  161. });
  162. CLASS_FUNC_INVOKE(C, *ret, Create);
  163. return ret;
  164. }
  165. /**
  166. * 创建对象,用指定参数执行onCreate函数
  167. * @param args 对象onCreate函数参数列表
  168. * @warning args参数类型和个数必须与onCreate函数类型匹配(不可忽略默认参数),否则会由于模板匹配失败导致忽略调用
  169. * @return args对象的智能指针
  170. */
  171. template<typename C, typename ...ArgsType>
  172. static std::shared_ptr<C> create2(ArgsType &&...args) {
  173. std::shared_ptr<C> ret(new C(), [](C *ptr) {
  174. try {
  175. CLASS_FUNC_INVOKE(C, *ptr, Destory);
  176. } catch (std::exception &ex){
  177. onDestoryException(typeid(C), ex);
  178. }
  179. delete ptr;
  180. });
  181. CLASS_FUNC_INVOKE(C, *ret, Create, std::forward<ArgsType>(args)...);
  182. return ret;
  183. }
  184. private:
  185. static void onDestoryException(const std::type_info &info, const std::exception &ex);
  186. private:
  187. Creator() = default;
  188. ~Creator() = default;
  189. };
  190. template <class C>
  191. class ObjectStatistic{
  192. public:
  193. ObjectStatistic(){
  194. ++getCounter();
  195. }
  196. ~ObjectStatistic(){
  197. --getCounter();
  198. }
  199. static size_t count(){
  200. return getCounter().load();
  201. }
  202. private:
  203. static std::atomic<size_t> & getCounter();
  204. };
  205. #define StatisticImp(Type) \
  206. template<> \
  207. std::atomic<size_t>& ObjectStatistic<Type>::getCounter(){ \
  208. static std::atomic<size_t> instance(0); \
  209. return instance; \
  210. }
  211. std::string makeRandStr(int sz, bool printable = true);
  212. std::string hexdump(const void *buf, size_t len);
  213. std::string hexmem(const void* buf, size_t len);
  214. std::string exePath(bool isExe = true);
  215. std::string exeDir(bool isExe = true);
  216. std::string exeName(bool isExe = true);
  217. std::vector<std::string> split(const std::string& s, const char *delim);
  218. //去除前后的空格、回车符、制表符...
  219. std::string& trim(std::string &s,const std::string &chars=" \r\n\t");
  220. std::string trim(std::string &&s,const std::string &chars=" \r\n\t");
  221. // string转小写
  222. std::string &strToLower(std::string &str);
  223. std::string strToLower(std::string &&str);
  224. // string转大写
  225. std::string &strToUpper(std::string &str);
  226. std::string strToUpper(std::string &&str);
  227. //替换子字符串
  228. void replace(std::string &str, const std::string &old_str, const std::string &new_str, std::string::size_type b_pos = 0) ;
  229. //判断是否为ip
  230. bool isIP(const char *str);
  231. //字符串是否以xx开头
  232. bool start_with(const std::string &str, const std::string &substr);
  233. //字符串是否以xx结尾
  234. bool end_with(const std::string &str, const std::string &substr);
  235. //拼接格式字符串
  236. template<typename... Args>
  237. std::string str_format(const std::string &format, Args... args) {
  238. #if __cplusplus > 202002L
  239. return std::format(format, args...);
  240. #else
  241. // Calculate the buffer size
  242. auto size_buf = snprintf(nullptr, 0, format.c_str(), args ...) + 1;
  243. // Allocate the buffer
  244. #if __cplusplus >= 201703L
  245. // C++17
  246. auto buf = std::make_unique<char[]>(size_buf);
  247. #else
  248. // C++11
  249. std:: unique_ptr<char[]> buf(new(std::nothrow) char[size_buf]);
  250. #endif
  251. // Check if the allocation is successful
  252. if (buf == nullptr) {
  253. return {};
  254. }
  255. // Fill the buffer with formatted string
  256. auto result = snprintf(buf.get(), size_buf, format.c_str(), args ...);
  257. // Return the formatted string
  258. return std::string(buf.get(), buf.get() + result);
  259. #endif
  260. }
  261. #ifndef bzero
  262. #define bzero(ptr,size) memset((ptr),0,(size));
  263. #endif //bzero
  264. #if defined(ANDROID)
  265. template <typename T>
  266. std::string to_string(T value){
  267. std::ostringstream os ;
  268. os << std::forward<T>(value);
  269. return os.str() ;
  270. }
  271. #endif//ANDROID
  272. #if defined(_WIN32)
  273. int gettimeofday(struct timeval *tp, void *tzp);
  274. void usleep(int micro_seconds);
  275. void sleep(int second);
  276. int vasprintf(char **strp, const char *fmt, va_list ap);
  277. int asprintf(char **strp, const char *fmt, ...);
  278. const char *strcasestr(const char *big, const char *little);
  279. #if !defined(strcasecmp)
  280. #define strcasecmp _stricmp
  281. #endif
  282. #ifndef ssize_t
  283. #ifdef _WIN64
  284. #define ssize_t int64_t
  285. #else
  286. #define ssize_t int32_t
  287. #endif
  288. #endif
  289. #endif //WIN32
  290. /**
  291. * 获取时间差, 返回值单位为秒
  292. */
  293. long getGMTOff();
  294. /**
  295. * 获取1970年至今的毫秒数
  296. * @param system_time 是否为系统时间(系统时间可以回退),否则为程序启动时间(不可回退)
  297. */
  298. uint64_t getCurrentMillisecond(bool system_time = false);
  299. /**
  300. * 获取1970年至今的微秒数
  301. * @param system_time 是否为系统时间(系统时间可以回退),否则为程序启动时间(不可回退)
  302. */
  303. uint64_t getCurrentMicrosecond(bool system_time = false);
  304. /**
  305. * 获取时间字符串
  306. * @param fmt 时间格式,譬如%Y-%m-%d %H:%M:%S
  307. * @return 时间字符串
  308. */
  309. std::string getTimeStr(const char *fmt,time_t time = 0);
  310. /**
  311. * 根据unix时间戳获取本地时间
  312. * @param sec unix时间戳
  313. * @return tm结构体
  314. */
  315. struct tm getLocalTime(time_t sec);
  316. /**
  317. * 设置线程名
  318. */
  319. void setThreadName(const char *name);
  320. /**
  321. * 获取线程名
  322. */
  323. std::string getThreadName();
  324. /**
  325. * 设置当前线程cpu亲和性
  326. * @param i cpu索引,如果为-1,那么取消cpu亲和性
  327. * @return 是否成功,目前只支持linux
  328. */
  329. bool setThreadAffinity(int i);
  330. /**
  331. * 根据typeid(class).name()获取类名
  332. */
  333. std::string demangle(const char *mangled);
  334. /**
  335. * 获取环境变量内容,以'$'开头
  336. */
  337. std::string getEnv(const std::string &key);
  338. } // namespace toolkit
  339. #endif /* UTIL_UTIL_H_ */