#include #include #include #include #include #include #ifdef WIN32 #include #else #include #include #include #endif #include #include "../../sdk/hginclude/hg_log.h" #define MAX_LOG_FILE_SIZE 100 * 1024 * 1024 #ifdef _INTSIZEOF #undef _INTSIZEOF #define _INTSIZEOF(n) ((sizeof(n) + sizeof(long) - 1) & ~(sizeof(long) - 1)) #endif class hglog { typedef void(*log_to)(const char*, void*); std::string path_file_; FILE* file_; log_to log_; int level_; log_callback lcb_; static hglog* inst_; static void log_none(const char* info, void* param) {} static void log_consonle(const char* info, void* param) { printf(info); } static void log_file(const char* info, void* param) { FILE* file = (FILE*)param; fwrite(info, 1, strlen(info), file); fflush(file); if (ftell(file) >= MAX_LOG_FILE_SIZE) fseek(file, 0, SEEK_SET); } protected: hglog() : path_file_(""), file_(0), log_(&hglog::log_consonle), level_(HG_LOG_LEVEL_ALL), lcb_(NULL) {} ~hglog() { if (file_) { fclose(file_); file_ = 0; } } public: static hglog* instance(void) { if (!hglog::inst_) hglog::inst_ = new hglog(); return hglog::inst_; } int set_log_type(int type, void* param) { int ret = 0; if (file_) { fclose(file_); file_ = 0; } lcb_ = NULL; log_ = NULL; if (type == HG_LOG_TYPE_NONE) log_ = &hglog::log_none; else if(type == HG_LOG_TYPE_CONSOLE) log_ = &hglog::log_consonle; else if (type == HG_LOG_TYPE_FILE) { log_ = &hglog::log_file; ret = -1; if (param) { path_file_ = (char*)param; file_ = fopen(path_file_.c_str(), "wb"); if (file_) { unsigned char bom[] = { 0x0ef, 0x0bb, 0x0bf }; fwrite(bom, sizeof(bom), 1, file_); ret = 0; } } } else if (type == HG_LOG_TYPE_CALLBACK) { lcb_ = (log_callback)param; } if(ret != 0) log_ = &hglog::log_none; return ret; } void set_log_level(int level) { level_ = level; } bool is_log_level_enabled(int level) { return level >= level_; } void log(const char* info) { log_(info, (void*)file_); } }; hglog* hglog::inst_ = NULL; #ifdef EXPORT_AS_C extern "C" { #endif namespace hg_log { static log_callback lcb_ = NULL; std::string format_ptr(void* ptr) { char buf[40]; if (sizeof(ptr) == sizeof(int)) { sprintf(buf, "0x%08x", ptr); } else { unsigned int* n = (unsigned int*)&ptr; sprintf(buf, "0x%x%08x", n[1], n[0]); } return buf; } std::string format_current_thread_id(void) { #ifdef WIN32 return format_ptr((void*)GetCurrentThreadId()); #else return format_ptr((void*)pthread_self()); #endif } int init(hg_log_type type, hg_log_level level, char* log_file) { if (type == HG_LOG_TYPE_CALLBACK) lcb_ = (log_callback)log_file; else lcb_ = NULL; hglog::instance()->set_log_level(level); return hglog::instance()->set_log_type(type, log_file); } std::string current_time(void) { char buf[40]; time_t t = time(NULL); tm* l = localtime(&t); sprintf(buf, "%d-%02d-%02d %02d:%02d:%02d", l->tm_year + 1900, l->tm_mon + 1, l->tm_mday, l->tm_hour, l->tm_min, l->tm_sec); return buf; } std::string format_size(unsigned long size) { char buf[40]; if (size > 1024 * 1024 * 1024) { double d = size; d /= 1024 * 1024 * 1024; sprintf(buf, "%.2fGB", d); } else if (size > 1024 * 1024) { double d = size; d /= 1024 * 1024; sprintf(buf, "%.2fMB", d); } else if (size > 1024) { double d = size; d /= 1024; sprintf(buf, "%.1fKB", d); } else { sprintf(buf, "%u bytes", (unsigned int)size); } return buf; } std::string u2utf8(const wchar_t* u) { std::string utf8(""); #ifdef WIN32 if (u) { char stack[256] = { 0 }, * ansi = NULL; int len = 0; len = WideCharToMultiByte(CP_UTF8, 0, u, lstrlenW(u), NULL, 0, NULL, NULL); ansi = new char[len + 2]; len = WideCharToMultiByte(CP_UTF8, 0, u, lstrlenW(u), ansi, len, NULL, NULL); ansi[len--] = 0; utf8 = ansi; delete[] ansi; } #else #endif return utf8; } std::string pe_path(std::string* name) { #ifdef WIN32 wchar_t path[MAX_PATH] = { 0 }, * last = NULL; GetModuleFileNameW(NULL, path, _countof(path) - 1); last = wcsrchr(path, L'\\'); if (last) { if (name) *name = u2utf8(last + 1); *last = 0; } return u2utf8(path); #else char path[256]; int len = readlink("/proc/self/exe", path, sizeof(path) - 1); if (len > 0 && len < sizeof(path)) { for (--len; len > 0; --len) { if (path[len] == '/') { path[len] = 0; if (name) *name = path + len + 1; break; } } } return path; #endif } unsigned long long available_memory(void) { #ifdef WIN32 MEMORYSTATUSEX ms; if (GlobalMemoryStatusEx(&ms)) return ms.ullAvailPhys; else return -1; #else struct sysinfo si; if (sysinfo(&si) == 0) return si.freeram * si.mem_unit; #endif } void log(hg_log_level level, const char* info) { if (lcb_) lcb_(level, info); else if (hglog::instance()->is_log_level_enabled(level)) hglog::instance()->log(info); } void vlog(hg_log_level level, const char* fmt, ...) { if (lcb_) { va_list args; char* buf = (char*)malloc(1024); va_start(args, fmt); //_vsnprintf(&buf[0], estimate_bytes, format, args); sprintf(buf, fmt, args); va_end(args); lcb_(level, buf); free(buf); } else if (hglog::instance()->is_log_level_enabled(level)) { va_list args; char* buf = (char*)malloc(1024); va_start(args, fmt); //_vsnprintf(&buf[0], estimate_bytes, format, args); sprintf(buf, fmt, args); va_end(args); hglog::instance()->log(buf); free(buf); } } } #ifdef EXPORT_AS_C } #endif #ifdef WIN32 void hg_debug_log(hg_log_level level, const char* info) { hg_log::log(level, info); } #endif