// utilities for platform ... // // Date: 2023-06-30 // #pragma once #include #include #include enum log_type { LOG_TYPE_NONE = 0, // no logging LOG_TYPE_CONSOLE, // print to console LOG_TYPE_FILE, // write log into file }; enum log_level { LOG_LEVEL_ALL = 0, LOG_LEVEL_DEBUG, LOG_LEVEL_WARNING, LOG_LEVEL_FATAL, }; namespace utils { std::string utf82ansi(const char* utf8); std::string ansi2utf8(const char* ansi); std::string get_command_result(const char* cmd, int len = -1); std::string get_local_data_path(void); std::string temporary_path(void); std::string format_current_time(void); std::string get_module_full_path(const char* part_name = nullptr/*nullptr to get main-pe/first module's full path*/); std::string find_file(const char* root_dir, const char* part_name, bool recursive = false); std::string target_file_from_link(const char* lnk_file); std::string get_ini_value(const char* seg, const char* key, const char* cfg_file); // return "" if not found std::string load_mini_file(const char* file, int* err); // <= 1MB int save_2_file(void* data, size_t len, const char* file, bool append = false/*append or new*/, size_t max_size = -1/*in append mode, truncate file if size is exceeded this value if was not -1*/); bool is_match_pattern(const char* text, const char* pattern); const char* to_lower(std::string& str); // return str.c_str() const char* trim(std::string& str, const char* sp = "\r\n\t "); // return str.c_str() HMODULE load_dll(const char* path_file, int flag); bool create_folder(const char* folder); void set_ini_value(const char* seg, const char* key, const char* val, const char* cfg_file); int enum_file(const char* folder, bool recursive, bool/*return false to stop enumeration*/(STDCALL* found)(const char* path_name, bool dir, void* param), void* param); int move_file(const char* from, const char* to); int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block); unsigned int get_page_size(unsigned int* map_unit = nullptr); void init_log(log_type type, log_level level = LOG_LEVEL_ALL, const char* fn_appendix = nullptr/*appendix to default log-file-name*/); void uninit(void); void log_info(const char* info, int level = LOG_LEVEL_ALL); void log_mem_info(const char* desc, const void* data, size_t bytes, int level = LOG_LEVEL_ALL); // log as 0x12345678 00 01 02 ... int get_log_type(void); int get_log_level(void); int copy_log_file_to(const char* dst); int clear_log_file(void); template void to_log(int level, const char* fmt, Args ... args) { if (get_log_type() != LOG_TYPE_NONE && get_log_level() <= level) { size_t size = snprintf(nullptr, 0, fmt, args ...) + 2; std::unique_ptr buf(new char[size]); snprintf(buf.get(), size, fmt, args ...); log_info(buf.get(), (log_level)level); } } template void to_log_with_api(bool(*is_enable)(int), void(*log_api)(const char*, int), int level, const char* fmt, Args ... args) { if (is_enable(level)) { size_t size = snprintf(nullptr, 0, fmt, args ...) + 2; std::unique_ptr buf(new char[size]); snprintf(buf.get(), size, fmt, args ...); log_api(buf.get(), (log_level)level); } } }; #if OS_WIN struct _time_val { time_t tv_sec; /* Seconds. */ time_t tv_usec; /* Microseconds. */ }; typedef struct _time_val TIMEV; struct timezone { int tz_minuteswest; /* Minutes west of GMT. */ int tz_dsttime; /* Nonzero if DST is ever in effect. */ }; int gettimeofday(TIMEV* tv, struct timezone* tz); #else #include typedef struct timeval TIMEV; #endif class chronograph { TIMEV bgn_; public: chronograph(); ~chronograph(); static bool now(TIMEV* tv); static bool now(uint64_t* seconds, uint64_t* u_seconds); static std::string now(bool with_ms = true/*whether with milliseconds*/); // return '2022-11-30 10:38:42.123', no '.123' if with_ms was false public: uint64_t elapse_s(void); uint64_t elapse_ms(void); uint64_t elapse_us(void); void reset(void); };