diff --git a/src/contrib/epee/include/misc_log_ex.h b/src/contrib/epee/include/misc_log_ex.h new file mode 100644 index 0000000..44f50af --- /dev/null +++ b/src/contrib/epee/include/misc_log_ex.h @@ -0,0 +1,1456 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + + +#ifndef _MISC_LOG_EX_H_ +#define _MISC_LOG_EX_H_ + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(WIN32) +#include +#else +#include +#endif + +#include "static_initializer.h" +#include "string_tools.h" +#include "time_helper.h" +#include "misc_os_dependent.h" + +#include "syncobj.h" + + +#define LOG_LEVEL_SILENT -1 +#define LOG_LEVEL_0 0 +#define LOG_LEVEL_1 1 +#define LOG_LEVEL_2 2 +#define LOG_LEVEL_3 3 +#define LOG_LEVEL_4 4 +#define LOG_LEVEL_MIN LOG_LEVEL_SILENT +#define LOG_LEVEL_MAX LOG_LEVEL_4 + + +#define LOGGER_NULL 0 +#define LOGGER_FILE 1 +#define LOGGER_DEBUGGER 2 +#define LOGGER_CONSOLE 3 +#define LOGGER_DUMP 4 + + +#ifndef LOCAL_ASSERT +#include +#if (defined _MSC_VER) +#define LOCAL_ASSERT(expr) {if(epee::debug::get_set_enable_assert()){_ASSERTE(expr);}} +#else +#define LOCAL_ASSERT(expr) +#endif + +#endif + +namespace epee +{ +namespace debug +{ + inline bool get_set_enable_assert(bool set = false, bool v = false) + { + static bool e = true; + if(set) + e = v; + return e; + } +} +namespace log_space +{ + class logger; + class log_message; + class log_singletone; + + /************************************************************************/ + /* */ + /************************************************************************/ + enum console_colors + { + console_color_default, + console_color_white, + console_color_red, + console_color_green, + console_color_blue, + console_color_cyan, + console_color_magenta, + console_color_yellow + }; + + + struct ibase_log_stream + { + ibase_log_stream(){} + virtual ~ibase_log_stream(){} + virtual bool out_buffer( const char* buffer, int buffer_len , int log_level, int color, const char* plog_name = NULL)=0; + virtual int get_type(){return 0;} + + virtual bool set_max_logfile_size(uint64_t max_size){return true;}; + virtual bool set_log_rotate_cmd(const std::string& cmd){return true;}; + }; + + /************************************************************************/ + /* */ + /************************************************************************/ + /*struct ibase_log_value + { + public: + virtual void debug_out( std::stringstream* p_stream)const = 0; + };*/ + + /************************************************************************/ + /* */ + /************************************************************************/ + /*class log_message: public std::stringstream + { + public: + log_message(const log_message& lm): std::stringstream(), std::stringstream::basic_ios() + {} + log_message(){} + + template + log_message& operator<< (T t) + { + std::stringstream* pstrstr = this; + (*pstrstr) << t; + + return *this; + } + }; + inline + log_space::log_message& operator<<(log_space::log_message& sstream, const ibase_log_value& log_val) + { + log_val.debug_out(&sstream); + return sstream; + } + */ + /************************************************************************/ + /* */ + /************************************************************************/ + struct delete_ptr + { + template + void operator() (P p) + { + delete p.first; + } + }; + + /************************************************************************/ + /* */ + /************************************************************************/ + //------------------------------------------------------------------------ +#define max_dbg_str_len 80 +#ifdef _MSC_VER + class debug_output_stream: public ibase_log_stream + { + virtual bool out_buffer( const char* buffer, int buffer_len , int log_level, int color, const char* plog_name = NULL) + { + for ( int i = 0; i < buffer_len; i = i + max_dbg_str_len ) + { + std::string s( buffer + i, buffer_len- i < max_dbg_str_len ? + buffer_len - i : max_dbg_str_len ); + + ::OutputDebugStringA( s.c_str() ); + } + return true; + } + + }; +#endif + + inline bool is_stdout_a_tty() + { + static std::atomic initialized(false); + static std::atomic is_a_tty(false); + + if (!initialized.load(std::memory_order_acquire)) + { +#if defined(WIN32) + is_a_tty.store(0 != _isatty(_fileno(stdout)), std::memory_order_relaxed); +#else + is_a_tty.store(0 != isatty(fileno(stdout)), std::memory_order_relaxed); +#endif + initialized.store(true, std::memory_order_release); + } + + return is_a_tty.load(std::memory_order_relaxed); + } + + inline void set_console_color(int color, bool bright) + { + if (!is_stdout_a_tty()) + return; + + switch(color) + { + case console_color_default: + { +#ifdef WIN32 + HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE| (bright ? FOREGROUND_INTENSITY:0)); +#else + if(bright) + std::cout << "\033[1;37m"; + else + std::cout << "\033[0m"; +#endif + } + break; + case console_color_white: + { +#ifdef WIN32 + HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | (bright ? FOREGROUND_INTENSITY:0)); +#else + if(bright) + std::cout << "\033[1;37m"; + else + std::cout << "\033[0;37m"; +#endif + } + break; + case console_color_red: + { +#ifdef WIN32 + HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | (bright ? FOREGROUND_INTENSITY:0)); +#else + if(bright) + std::cout << "\033[1;31m"; + else + std::cout << "\033[0;31m"; +#endif + } + break; + case console_color_green: + { +#ifdef WIN32 + HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(h_stdout, FOREGROUND_GREEN | (bright ? FOREGROUND_INTENSITY:0)); +#else + if(bright) + std::cout << "\033[1;32m"; + else + std::cout << "\033[0;32m"; +#endif + } + break; + + case console_color_blue: + { +#ifdef WIN32 + HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(h_stdout, FOREGROUND_BLUE | FOREGROUND_INTENSITY);//(bright ? FOREGROUND_INTENSITY:0)); +#else + if(bright) + std::cout << "\033[1;34m"; + else + std::cout << "\033[0;34m"; +#endif + } + break; + + case console_color_cyan: + { +#ifdef WIN32 + HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(h_stdout, FOREGROUND_GREEN | FOREGROUND_BLUE | (bright ? FOREGROUND_INTENSITY:0)); +#else + if(bright) + std::cout << "\033[1;36m"; + else + std::cout << "\033[0;36m"; +#endif + } + break; + + case console_color_magenta: + { +#ifdef WIN32 + HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(h_stdout, FOREGROUND_BLUE | FOREGROUND_RED | (bright ? FOREGROUND_INTENSITY:0)); +#else + if(bright) + std::cout << "\033[1;35m"; + else + std::cout << "\033[0;35m"; +#endif + } + break; + + case console_color_yellow: + { +#ifdef WIN32 + HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | FOREGROUND_GREEN | (bright ? FOREGROUND_INTENSITY:0)); +#else + if(bright) + std::cout << "\033[1;33m"; + else + std::cout << "\033[0;33m"; +#endif + } + break; + + } + } + + inline void reset_console_color() { + if (!is_stdout_a_tty()) + return; + +#ifdef WIN32 + HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); +#else + std::cout << "\033[0m"; + std::cout.flush(); +#endif + } + + class console_output_stream: public ibase_log_stream + { +#ifdef _MSC_VER + bool m_have_to_kill_console; +#endif + + public: + console_output_stream() + { +#ifdef _MSC_VER + + if(!::GetStdHandle(STD_OUTPUT_HANDLE)) + m_have_to_kill_console = true; + else + m_have_to_kill_console = false; + + ::AllocConsole(); +#endif + } + + ~console_output_stream() + { +#ifdef _MSC_VER + if(m_have_to_kill_console) + ::FreeConsole(); +#endif + } + int get_type(){return LOGGER_CONSOLE;} + + + + virtual bool out_buffer( const char* buffer, int buffer_len , int log_level, int color, const char* plog_name = NULL) + { + if(plog_name) + return true; //skip alternative logs from console + + set_console_color(color, log_level < 1); + +#ifdef _MSC_VER + const char* ptarget_buf = NULL; + char* pallocated_buf = NULL; + + // + int i = 0; + for(; i < buffer_len; i++) + if(buffer[i] == '\a') break; + if(i == buffer_len) + ptarget_buf = buffer; + else + { + pallocated_buf = new char[buffer_len]; + ptarget_buf = pallocated_buf; + for(i = 0; i < buffer_len; i++) + { + if(buffer[i] == '\a') + pallocated_buf[i] = '^'; + else + pallocated_buf[i] = buffer[i]; + } + } + + //uint32_t b = 0; + //::WriteConsoleA(::GetStdHandle(STD_OUTPUT_HANDLE), ptarget_buf, buffer_len, (DWORD*)&b, 0); + std::cout << ptarget_buf; + if(pallocated_buf) delete [] pallocated_buf; +#else + std::string buf(buffer, buffer_len); + for(size_t i = 0; i!= buf.size(); i++) + { + if(buf[i] == 7 || buf[i] == -107) + buf[i] = '^'; + } + + std::cout << buf; +#endif + reset_console_color(); + return true; + } + + + }; + + inline bool rotate_log_file(const char* pfile_path) + { +#ifdef _MSC_VER + if(!pfile_path) + return false; + + std::string file_path = pfile_path; + std::string::size_type a = file_path .rfind('.'); + if ( a != std::string::npos ) + file_path .erase( a, file_path .size()); + + ::DeleteFileA( (file_path + ".0").c_str() ); + ::MoveFileA( (file_path + ".log").c_str(), (file_path + ".0").c_str() ); +#else + return false;//not implemented yet +#endif + return true; + } + + + + + //--------------------------------------------------------------------------// + class file_output_stream : public ibase_log_stream + { + public: + typedef std::map named_log_streams; + + file_output_stream( std::string default_log_file_name, std::string log_path ) + { + m_default_log_filename = default_log_file_name; + m_max_logfile_size = 0; + m_default_log_path = log_path; + m_pdefault_file_stream = add_new_stream_and_open(default_log_file_name.c_str()); + } + + ~file_output_stream() + { + for(named_log_streams::iterator it = m_log_file_names.begin(); it!=m_log_file_names.end(); it++) + { + if ( it->second->is_open() ) + { + it->second->flush(); + it->second->close(); + } + delete it->second; + } + } + private: + named_log_streams m_log_file_names; + std::string m_default_log_path; + std::ofstream* m_pdefault_file_stream; + std::string m_log_rotate_cmd; + std::string m_default_log_filename; + uint64_t m_max_logfile_size; + + + std::ofstream* add_new_stream_and_open(const char* pstream_name) + { + //log_space::rotate_log_file((m_default_log_path + "\\" + pstream_name).c_str()); + + std::ofstream* pstream = (m_log_file_names[pstream_name] = new std::ofstream); + std::string target_path = m_default_log_path + "/" + pstream_name; + pstream->open( target_path.c_str(), std::ios_base::out | std::ios::app /*ios_base::trunc */); + if(pstream->fail()) + return NULL; + return pstream; + } + + bool set_max_logfile_size(uint64_t max_size) + { + m_max_logfile_size = max_size; + return true; + } + + bool set_log_rotate_cmd(const std::string& cmd) + { + m_log_rotate_cmd = cmd; + return true; + } + + + + virtual bool out_buffer( const char* buffer, int buffer_len, int log_level, int color, const char* plog_name = NULL ) + { + std::ofstream* m_target_file_stream = m_pdefault_file_stream; + if(plog_name) + { //find named stream + named_log_streams::iterator it = m_log_file_names.find(plog_name); + if(it == m_log_file_names.end()) + m_target_file_stream = add_new_stream_and_open(plog_name); + else + m_target_file_stream = it->second; + } + if(!m_target_file_stream || !m_target_file_stream->is_open()) + return false;//TODO: add assert here + + m_target_file_stream->write(buffer, buffer_len ); + m_target_file_stream->flush(); + + if(m_max_logfile_size) + { + std::ofstream::pos_type pt = m_target_file_stream->tellp(); + uint64_t current_sz = pt; + if(current_sz > m_max_logfile_size) + { + std::cout << "current_sz= " << current_sz << " m_max_logfile_size= " << m_max_logfile_size << std::endl; + std::string log_file_name; + if(!plog_name) + log_file_name = m_default_log_filename; + else + log_file_name = plog_name; + + m_target_file_stream->close(); + std::string new_log_file_name = log_file_name; + + time_t tm = 0; + time(&tm); + + int err_count = 0; + boost::system::error_code ec; + do + { + new_log_file_name = string_tools::cut_off_extension(log_file_name); + if(err_count) + new_log_file_name += misc_utils::get_time_str_v2(tm) + "(" + boost::lexical_cast(err_count) + ")" + ".log"; + else + new_log_file_name += misc_utils::get_time_str_v2(tm) + ".log"; + + err_count++; + }while(boost::filesystem::exists(m_default_log_path + "/" + new_log_file_name, ec)); + + std::string new_log_file_path = m_default_log_path + "/" + new_log_file_name; + boost::filesystem::rename(m_default_log_path + "/" + log_file_name, new_log_file_path, ec); + if(ec) + { + std::cout << "Filed to rename, ec = " << ec.message() << std::endl; + } + + if(m_log_rotate_cmd.size()) + { + + std::string m_log_rotate_cmd_local_copy = m_log_rotate_cmd; + //boost::replace_all(m_log_rotate_cmd, "[*SOURCE*]", new_log_file_path); + boost::replace_all(m_log_rotate_cmd_local_copy, "[*TARGET*]", new_log_file_path); + + misc_utils::call_sys_cmd(m_log_rotate_cmd_local_copy); + } + + m_target_file_stream->open( (m_default_log_path + "/" + log_file_name).c_str(), std::ios_base::out | std::ios::app /*ios_base::trunc */); + if(m_target_file_stream->fail()) + return false; + } + } + + return true; + } + int get_type(){return LOGGER_FILE;} + }; + /************************************************************************/ + /* */ + /************************************************************************/ + class log_stream_splitter + { + public: + typedef std::list > streams_container; + + log_stream_splitter(){} + ~log_stream_splitter() + { + //free pointers + std::for_each(m_log_streams.begin(), m_log_streams.end(), delete_ptr()); + } + + bool set_max_logfile_size(uint64_t max_size) + { + for(streams_container::iterator it = m_log_streams.begin(); it!=m_log_streams.end();it++) + it->first->set_max_logfile_size(max_size); + return true; + } + + bool set_log_rotate_cmd(const std::string& cmd) + { + for(streams_container::iterator it = m_log_streams.begin(); it!=m_log_streams.end();it++) + it->first->set_log_rotate_cmd(cmd); + return true; + } + + bool do_log_message(const std::string& rlog_mes, int log_level, int color, const char* plog_name = NULL) + { + std::string str_mess = rlog_mes; + size_t str_len = str_mess.size(); + const char* pstr = str_mess.c_str(); + for(streams_container::iterator it = m_log_streams.begin(); it!=m_log_streams.end();it++) + if(it->second >= log_level) + it->first->out_buffer(pstr, (int)str_len, log_level, color, plog_name); + return true; + } + + bool add_logger( int type, const char* pdefault_file_name, const char* pdefault_log_folder, int log_level_limit = LOG_LEVEL_4 ) + { + ibase_log_stream* ls = NULL; + + switch( type ) + { + case LOGGER_FILE: + ls = new file_output_stream( pdefault_file_name, pdefault_log_folder ); + break; + + case LOGGER_DEBUGGER: +#ifdef _MSC_VER + ls = new debug_output_stream( ); +#else + return false;//not implemented yet +#endif + break; + case LOGGER_CONSOLE: + ls = new console_output_stream( ); + break; + } + + if ( ls ) { + m_log_streams.push_back(streams_container::value_type(ls, log_level_limit)); + return true; + } + return ls ? true:false; + } + bool add_logger( ibase_log_stream* pstream, int log_level_limit = LOG_LEVEL_4 ) + { + m_log_streams.push_back(streams_container::value_type(pstream, log_level_limit) ); + return true; + } + + bool remove_logger(int type) + { + streams_container::iterator it = m_log_streams.begin(); + for(;it!=m_log_streams.end(); it++) + { + if(it->first->get_type() == type) + { + delete it->first; + m_log_streams.erase(it); + return true; + } + } + return false; + + } + + protected: + private: + + streams_container m_log_streams; + }; + + /************************************************************************/ + /* */ + /************************************************************************/ + inline int get_set_log_detalisation_level(bool is_need_set = false, int log_level_to_set = LOG_LEVEL_1); + inline int get_set_time_level(bool is_need_set = false, int time_log_level = LOG_LEVEL_0); + inline bool get_set_need_thread_id(bool is_need_set = false, bool is_need_val = false); + inline bool get_set_need_proc_name(bool is_need_set = false, bool is_need_val = false); + + + inline std::string get_daytime_string2() + { + boost::posix_time::ptime p = boost::posix_time::microsec_clock::local_time(); + return misc_utils::get_time_str_v3(p); + } + inline std::string get_day_time_string() + { + return get_daytime_string2(); + //time_t tm = 0; + //time(&tm); + //return misc_utils::get_time_str(tm); + } + + inline std::string get_time_string() + { + return get_daytime_string2(); + + } +#ifdef _MSC_VER + inline std::string get_time_string_adv(SYSTEMTIME* pst = NULL) + { + SYSTEMTIME st = {0}; + if(!pst) + { + pst = &st; + GetSystemTime(&st); + } + std::stringstream str_str; + str_str.fill('0'); + str_str << std::setw(2) << pst->wHour << "_" + << std::setw(2) << pst->wMinute << "_" + << std::setw(2) << pst->wSecond << "_" + << std::setw(3) << pst->wMilliseconds; + return str_str.str(); + } +#endif + + + + + + class logger + { + public: + friend class log_singletone; + + logger() + { + CRITICAL_REGION_BEGIN(m_critical_sec); + init(); + CRITICAL_REGION_END(); + } + ~logger() + { + } + + bool set_max_logfile_size(uint64_t max_size) + { + CRITICAL_REGION_BEGIN(m_critical_sec); + m_log_target.set_max_logfile_size(max_size); + CRITICAL_REGION_END(); + return true; + } + + bool set_log_rotate_cmd(const std::string& cmd) + { + CRITICAL_REGION_BEGIN(m_critical_sec); + m_log_target.set_log_rotate_cmd(cmd); + CRITICAL_REGION_END(); + return true; + } + + bool take_away_journal(std::list& journal) + { + CRITICAL_REGION_BEGIN(m_critical_sec); + m_journal.swap(journal); + CRITICAL_REGION_END(); + return true; + } + + bool do_log_message(const std::string& rlog_mes, int log_level, int color, bool add_to_journal = false, const char* plog_name = NULL) + { + CRITICAL_REGION_BEGIN(m_critical_sec); + m_log_target.do_log_message(rlog_mes, log_level, color, plog_name); + if(add_to_journal) + m_journal.push_back(rlog_mes); + + return true; + CRITICAL_REGION_END(); + } + + bool add_logger( int type, const char* pdefault_file_name, const char* pdefault_log_folder , int log_level_limit = LOG_LEVEL_4) + { + CRITICAL_REGION_BEGIN(m_critical_sec); + return m_log_target.add_logger( type, pdefault_file_name, pdefault_log_folder, log_level_limit); + CRITICAL_REGION_END(); + } + bool add_logger( ibase_log_stream* pstream, int log_level_limit = LOG_LEVEL_4) + { + CRITICAL_REGION_BEGIN(m_critical_sec); + return m_log_target.add_logger(pstream, log_level_limit); + CRITICAL_REGION_END(); + } + + bool remove_logger(int type) + { + CRITICAL_REGION_BEGIN(m_critical_sec); + return m_log_target.remove_logger(type); + CRITICAL_REGION_END(); + } + + + bool set_thread_prefix(const std::string& prefix) + { + CRITICAL_REGION_BEGIN(m_critical_sec); + m_thr_prefix_strings[misc_utils::get_thread_string_id()] = prefix; + CRITICAL_REGION_END(); + return true; + } + + + std::string get_default_log_file() + { + return m_default_log_file; + } + + std::string get_default_log_folder() + { + return m_default_log_folder; + } + + protected: + private: + bool init() + { + // + + m_process_name = string_tools::get_current_module_name(); + + init_log_path_by_default(); + + //init default set of loggers + init_default_loggers(); + + std::stringstream ss; + ss << get_time_string() << " Init logging. Level=" << get_set_log_detalisation_level() + << " Log path=" << m_default_log_folder << std::endl; + this->do_log_message(ss.str(), console_color_white, LOG_LEVEL_0); + return true; + } + bool init_default_loggers() + { + //TODO: + return true; + } + + bool init_log_path_by_default() + { + //load process name + m_default_log_folder = string_tools::get_current_module_folder(); + + m_default_log_file = m_process_name; + std::string::size_type a = m_default_log_file.rfind('.'); + if ( a != std::string::npos ) + m_default_log_file.erase( a, m_default_log_file.size()); + m_default_log_file += ".log"; + + return true; + } + + log_stream_splitter m_log_target; + + std::string m_default_log_folder; + std::string m_default_log_file; + std::string m_process_name; + std::map m_thr_prefix_strings; + std::list m_journal; + critical_section m_critical_sec; + }; + /************************************************************************/ + /* */ + /************************************************************************/ + class log_singletone + { + public: + friend class initializer; + friend class logger; + static int get_log_detalisation_level() + { + get_or_create_instance();//to initialize logger, if it not initialized + return get_set_log_detalisation_level(); + } + + static bool is_filter_error(int error_code) + { + return false; + } + + + static bool do_log_message(const std::string& rlog_mes, int log_level, int color, bool keep_in_journal, const char* plog_name = NULL) + { + logger* plogger = get_or_create_instance(); + bool res = false; + if(plogger) + res = plogger->do_log_message(rlog_mes, log_level, color, keep_in_journal, plog_name); + else + { //globally uninitialized, create new logger for each call of do_log_message() and then delete it + plogger = new logger(); + //TODO: some extra initialization + res = plogger->do_log_message(rlog_mes, log_level, color, keep_in_journal, plog_name); + delete plogger; + plogger = NULL; + } + return res; + } + + static bool take_away_journal(std::list& journal) + { + logger* plogger = get_or_create_instance(); + bool res = false; + if(plogger) + res = plogger->take_away_journal(journal); + + return res; + } + + static bool set_max_logfile_size(uint64_t file_size) + { + logger* plogger = get_or_create_instance(); + if(!plogger) return false; + return plogger->set_max_logfile_size(file_size); + } + + + static bool set_log_rotate_cmd(const std::string& cmd) + { + logger* plogger = get_or_create_instance(); + if(!plogger) return false; + return plogger->set_log_rotate_cmd(cmd); + } + + + static bool add_logger( int type, const char* pdefault_file_name, const char* pdefault_log_folder, int log_level_limit = LOG_LEVEL_4) + { + logger* plogger = get_or_create_instance(); + if(!plogger) return false; + return plogger->add_logger(type, pdefault_file_name, pdefault_log_folder, log_level_limit); + } + + static std::string get_default_log_file() + { + logger* plogger = get_or_create_instance(); + if(plogger) + return plogger->get_default_log_file(); + + return ""; + } + + static std::string get_default_log_folder() + { + logger* plogger = get_or_create_instance(); + if(plogger) + return plogger->get_default_log_folder(); + + return ""; + } + + static bool add_logger( ibase_log_stream* pstream, int log_level_limit = LOG_LEVEL_4 ) + { + logger* plogger = get_or_create_instance(); + if(!plogger) return false; + return plogger->add_logger(pstream, log_level_limit); + } + + + static bool remove_logger( int type ) + { + logger* plogger = get_or_create_instance(); + if(!plogger) return false; + return plogger->remove_logger(type); + } +PUSH_WARNINGS +DISABLE_GCC_WARNING(maybe-uninitialized) + static int get_set_log_detalisation_level(bool is_need_set = false, int log_level_to_set = LOG_LEVEL_1) + { + static int log_detalisation_level = LOG_LEVEL_1; + if(is_need_set) + log_detalisation_level = log_level_to_set; + return log_detalisation_level; + } +POP_WARNINGS + static int get_set_time_level(bool is_need_set = false, int time_log_level = LOG_LEVEL_0) + { + static int val_time_log_level = LOG_LEVEL_0; + if(is_need_set) + val_time_log_level = time_log_level; + + return val_time_log_level; + } + + static int get_set_process_level(bool is_need_set = false, int process_log_level = LOG_LEVEL_0) + { + static int val_process_log_level = LOG_LEVEL_0; + if(is_need_set) + val_process_log_level = process_log_level; + + return val_process_log_level; + } + + /*static int get_set_tid_level(bool is_need_set = false, int tid_log_level = LOG_LEVEL_0) + { + static int val_tid_log_level = LOG_LEVEL_0; + if(is_need_set) + val_tid_log_level = tid_log_level; + + return val_tid_log_level; + }*/ + + static bool get_set_need_thread_id(bool is_need_set = false, bool is_need_val = false) + { + static bool is_need = false; + if(is_need_set) + is_need = is_need_val; + + return is_need; + } + + static bool get_set_need_proc_name(bool is_need_set = false, bool is_need_val = false) + { + static bool is_need = true; + if(is_need_set) + is_need = is_need_val; + + return is_need; + } + static uint64_t get_set_err_count(bool is_need_set = false, uint64_t err_val = false) + { + static uint64_t err_count = 0; + if(is_need_set) + err_count = err_val; + + return err_count; + } + + +#ifdef _MSC_VER + + + static void SetThreadName( DWORD dwThreadID, const char* threadName) + { +#define MS_VC_EXCEPTION 0x406D1388 + +#pragma pack(push,8) + typedef struct tagTHREADNAME_INFO + { + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. + } THREADNAME_INFO; +#pragma pack(pop) + + + + Sleep(10); + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = (char*)threadName; + info.dwThreadID = dwThreadID; + info.dwFlags = 0; + + __try + { + RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + } + } +#endif + + static bool set_thread_log_prefix(const std::string& prefix) + { +#ifdef _MSC_VER + SetThreadName(-1, prefix.c_str()); +#endif + + + logger* plogger = get_or_create_instance(); + if(!plogger) return false; + return plogger->set_thread_prefix(prefix); + } + + + static std::string get_prefix_entry() + { + std::stringstream str_prefix; + //write time entry + if ( get_set_time_level() <= get_set_log_detalisation_level() ) + str_prefix << get_day_time_string() << " "; + + //write process info + logger* plogger = get_or_create_instance(); + //bool res = false; + if(!plogger) + { //globally uninitialized, create new logger for each call of get_prefix_entry() and then delete it + plogger = new logger(); + } + + //if ( get_set_need_proc_name() && get_set_process_level() <= get_set_log_detalisation_level() ) + // str_prefix << "[" << plogger->m_process_name << " (id=" << GetCurrentProcessId() << ")] "; +//#ifdef _MSC_VER_EX + if ( get_set_need_thread_id() /*&& get_set_tid_level() <= get_set_log_detalisation_level()*/ ) + str_prefix << "tid:" << misc_utils::get_thread_string_id() << " "; +//#endif + + if(plogger->m_thr_prefix_strings.size()) + { + CRITICAL_REGION_LOCAL(plogger->m_critical_sec); + std::string thr_str = misc_utils::get_thread_string_id(); + std::map::iterator it = plogger->m_thr_prefix_strings.find(thr_str); + if(it!=plogger->m_thr_prefix_strings.end()) + { + str_prefix << it->second; + } + } + + + if(get_set_is_uninitialized()) + delete plogger; + + return str_prefix.str(); + } + + private: + log_singletone(){}//restric to create an instance + //static initializer m_log_initializer;//must be in one .cpp file (for example main.cpp) via DEFINE_LOGGING macro + + static bool init() + { + return true;/*do nothing here*/ + } + static bool un_init() + { + //delete object + logger* plogger = get_set_instance_internal(); + if(plogger) delete plogger; + //set uninitialized + get_set_is_uninitialized(true, true); + get_set_instance_internal(true, NULL); + return true; + } + + static logger* get_or_create_instance() + { + logger* plogger = get_set_instance_internal(); + if(!plogger) + if(!get_set_is_uninitialized()) + get_set_instance_internal(true, plogger = new logger); + + return plogger; + } + + static logger* get_set_instance_internal(bool is_need_set = false, logger* pnew_logger_val = NULL) + { + static logger* val_plogger = NULL; + + if(is_need_set) + val_plogger = pnew_logger_val; + + return val_plogger; + } + + static bool get_set_is_uninitialized(bool is_need_set = false, bool is_uninitialized = false) + { + static bool val_is_uninitialized = false; + + if(is_need_set) + val_is_uninitialized = is_uninitialized; + + return val_is_uninitialized; + } + //static int get_set_error_filter(bool is_need_set = false) + }; + + const static initializer log_initializer; + /************************************************************************/ + /* */ +// /************************************************************************/ +// class log_array_value +// { +// int num; +// log_message& m_ref_log_mes; +// +// public: +// +// log_array_value( log_message& log_mes ) : num(0), m_ref_log_mes(log_mes) {} +// +// void operator ( )( ibase_log_value *val ) { +// m_ref_log_mes << "\n[" << num++ << "] "/* << val*/; } +// +// +// template +// void operator ()(T &value ) +// { +// m_ref_log_mes << "\n[" << num++ << "] " << value; +// } +// }; + + class log_frame + { + std::string m_name; + int m_level; + const char* m_plog_name; + public: + + log_frame(const std::string& name, int dlevel = LOG_LEVEL_2 , const char* plog_name = NULL) + { +#ifdef _MSC_VER + int lasterr=::GetLastError(); +#endif + m_plog_name = plog_name; + if ( dlevel <= log_singletone::get_log_detalisation_level() ) + { + m_name = name; + std::stringstream ss; + ss << log_space::log_singletone::get_prefix_entry() << "-->>" << m_name << std::endl; + log_singletone::do_log_message(ss.str(), dlevel, console_color_default, false, m_plog_name); + } + m_level = dlevel; +#ifdef _MSC_VER + ::SetLastError(lasterr); +#endif + } + ~log_frame() + { +#ifdef _MSC_VER + int lasterr=::GetLastError(); +#endif + + if (m_level <= log_singletone::get_log_detalisation_level() ) + { + std::stringstream ss; + ss << log_space::log_singletone::get_prefix_entry() << "<<--" << m_name << std::endl; + log_singletone::do_log_message(ss.str(), m_level, console_color_default, false,m_plog_name); + } +#ifdef _MSC_VER + ::SetLastError(lasterr); +#endif + } + }; + + inline int get_set_time_level(bool is_need_set, int time_log_level) + { + return log_singletone::get_set_time_level(is_need_set, time_log_level); + } + inline int get_set_log_detalisation_level(bool is_need_set, int log_level_to_set) + { + return log_singletone::get_set_log_detalisation_level(is_need_set, log_level_to_set); + } + inline std::string get_prefix_entry() + { + return log_singletone::get_prefix_entry(); + } + inline bool get_set_need_thread_id(bool is_need_set, bool is_need_val) + { + return log_singletone::get_set_need_thread_id(is_need_set, is_need_val); + } + inline bool get_set_need_proc_name(bool is_need_set, bool is_need_val ) + { + return log_singletone::get_set_need_proc_name(is_need_set, is_need_val); + } + + inline std::string get_win32_err_descr(int err_no) + { +#ifdef _MSC_VER + LPVOID lpMsgBuf; + + FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + err_no, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (char*) &lpMsgBuf, + 0, NULL ); + + std::string fix_sys_message = "(null)"; + if(lpMsgBuf) fix_sys_message = (char*)lpMsgBuf; + std::string::size_type a; + if ( (a = fix_sys_message.rfind( '\n' )) != std::string::npos ) + fix_sys_message.erase(a); + if ( (a = fix_sys_message.rfind( '\r' )) != std::string::npos ) + fix_sys_message.erase(a); + + LocalFree(lpMsgBuf); + return fix_sys_message; +#else + return "Not implemented yet"; +#endif + } + + inline bool getwin32_err_text(std::stringstream& ref_message, int error_no) + { + ref_message << "win32 error:" << get_win32_err_descr(error_no); + return true; + } +} +#if defined(_DEBUG) || defined(__GNUC__) + #define ENABLE_LOGGING_INTERNAL +#endif + +#if defined(ENABLE_RELEASE_LOGGING) + #define ENABLE_LOGGING_INTERNAL +#endif + + +#if defined(ENABLE_LOGGING_INTERNAL) + +#define LOG_PRINT_NO_PREFIX2(log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\ + {std::stringstream ss________; ss________ << x << std::endl; epee::log_space::log_singletone::do_log_message(ss________.str() , y, epee::log_space::console_color_default, false, log_name);}} + +#define LOG_PRINT_NO_PREFIX_NO_POSTFIX2(log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\ + {std::stringstream ss________; ss________ << x; epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, false, log_name);}} + + +#define LOG_PRINT_NO_POSTFIX2(log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\ + {std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x; epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, false, log_name);}} + + +#define LOG_PRINT2(log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\ + {std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, false, log_name);}} + +#define LOG_PRINT_COLOR2(log_name, x, y, color) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\ + {std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, color, false, log_name);}} + + +#define LOG_PRINT2_JORNAL(log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\ + {std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, true, log_name);}} + + +#define LOG_ERROR2(log_name, x) { \ + std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << "ERROR " << __FILE__ << ":" << __LINE__ << " " << x << std::endl; epee::log_space::log_singletone::do_log_message(ss________.str(), LOG_LEVEL_0, epee::log_space::console_color_red, true, log_name);LOCAL_ASSERT(0); epee::log_space::log_singletone::get_set_err_count(true, epee::log_space::log_singletone::get_set_err_count()+1);} + +#define LOG_FRAME2(log_name, x, y) epee::log_space::log_frame frame(x, y, log_name) + +#else + + +#define LOG_PRINT_NO_PREFIX2(log_name, x, y) + +#define LOG_PRINT_NO_PREFIX_NO_POSTFIX2(log_name, x, y) + +#define LOG_PRINT_NO_POSTFIX2(log_name, x, y) + +#define LOG_PRINT_COLOR2(log_name, x, y, color) + +#define LOG_PRINT2_JORNAL(log_name, x, y) + +#define LOG_PRINT2(log_name, x, y) + +#define LOG_ERROR2(log_name, x) + + +#define LOG_FRAME2(log_name, x, y) + + +#endif + + +#ifndef LOG_DEFAULT_TARGET + #define LOG_DEFAULT_TARGET NULL +#endif + + +#define LOG_PRINT_NO_POSTFIX(mess, level) LOG_PRINT_NO_POSTFIX2(LOG_DEFAULT_TARGET, mess, level) +#define LOG_PRINT_NO_PREFIX(mess, level) LOG_PRINT_NO_PREFIX2(LOG_DEFAULT_TARGET, mess, level) +#define LOG_PRINT_NO_PREFIX_NO_POSTFIX(mess, level) LOG_PRINT_NO_PREFIX_NO_POSTFIX2(LOG_DEFAULT_TARGET, mess, level) +#define LOG_PRINT(mess, level) LOG_PRINT2(LOG_DEFAULT_TARGET, mess, level) + +#define LOG_PRINT_COLOR(mess, level, color) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, color) +#define LOG_PRINT_RED(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_red) +#define LOG_PRINT_GREEN(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_green) +#define LOG_PRINT_BLUE(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_blue) +#define LOG_PRINT_YELLOW(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_yellow) +#define LOG_PRINT_CYAN(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_cyan) +#define LOG_PRINT_MAGENTA(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_magenta) + +#define LOG_PRINT_RED_L0(mess) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, LOG_LEVEL_0, epee::log_space::console_color_red) + +#define LOG_PRINT_L0(mess) LOG_PRINT(mess, LOG_LEVEL_0) +#define LOG_PRINT_L1(mess) LOG_PRINT(mess, LOG_LEVEL_1) +#define LOG_PRINT_L2(mess) LOG_PRINT(mess, LOG_LEVEL_2) +#define LOG_PRINT_L3(mess) LOG_PRINT(mess, LOG_LEVEL_3) +#define LOG_PRINT_L4(mess) LOG_PRINT(mess, LOG_LEVEL_4) +#define LOG_PRINT_J(mess, level) LOG_PRINT2_JORNAL(LOG_DEFAULT_TARGET, mess, level) + +#define LOG_ERROR(mess) LOG_ERROR2(LOG_DEFAULT_TARGET, mess) +#define LOG_FRAME(mess, level) LOG_FRAME2(LOG_DEFAULT_TARGET, mess, level) +#define LOG_VALUE(mess, level) LOG_VALUE2(LOG_DEFAULT_TARGET, mess, level) +#define LOG_ARRAY(mess, level) LOG_ARRAY2(LOG_DEFAULT_TARGET, mess, level) +//#define LOGWIN_PLATFORM_ERROR(err_no) LOGWINDWOS_PLATFORM_ERROR2(LOG_DEFAULT_TARGET, err_no) +#define LOG_SOCKET_ERROR(err_no) LOG_SOCKET_ERROR2(LOG_DEFAULT_TARGET, err_no) +//#define LOGWIN_PLATFORM_ERROR_UNCRITICAL(mess) LOGWINDWOS_PLATFORM_ERROR_UNCRITICAL2(LOG_DEFAULT_TARGET, mess) + +#define ENDL std::endl + +#define TRY_ENTRY() try { +#define CATCH_ENTRY(location, return_val) } \ + catch(const std::exception& ex) \ +{ \ + (void)(ex); \ + LOG_ERROR("Exception at [" << location << "], what=" << ex.what()); \ + return return_val; \ +}\ + catch(...)\ +{\ + LOG_ERROR("Exception at [" << location << "], generic exception \"...\"");\ + return return_val; \ +} + +#define CATCH_ENTRY_L0(lacation, return_val) CATCH_ENTRY(lacation, return_val) +#define CATCH_ENTRY_L1(lacation, return_val) CATCH_ENTRY(lacation, return_val) +#define CATCH_ENTRY_L2(lacation, return_val) CATCH_ENTRY(lacation, return_val) +#define CATCH_ENTRY_L3(lacation, return_val) CATCH_ENTRY(lacation, return_val) +#define CATCH_ENTRY_L4(lacation, return_val) CATCH_ENTRY(lacation, return_val) + + +#define ASSERT_MES_AND_THROW(message) {LOG_ERROR(message); std::stringstream ss; ss << message; throw std::runtime_error(ss.str());} +#define CHECK_AND_ASSERT_THROW_MES(expr, message) {if(!(expr)) ASSERT_MES_AND_THROW(message);} + + +#ifndef CHECK_AND_ASSERT +#define CHECK_AND_ASSERT(expr, fail_ret_val) do{if(!(expr)){LOCAL_ASSERT(expr); return fail_ret_val;};}while(0) +#endif + +#define NOTHING + +#ifndef CHECK_AND_ASSERT_MES +#define CHECK_AND_ASSERT_MES(expr, fail_ret_val, message) do{if(!(expr)) {LOG_ERROR(message); return fail_ret_val;};}while(0) +#endif + +#ifndef CHECK_AND_NO_ASSERT_MES +#define CHECK_AND_NO_ASSERT_MES(expr, fail_ret_val, message) do{if(!(expr)) {LOG_PRINT_L0(message); /*LOCAL_ASSERT(expr);*/ return fail_ret_val;};}while(0) +#endif + + +#ifndef CHECK_AND_ASSERT_MES_NO_RET +#define CHECK_AND_ASSERT_MES_NO_RET(expr, message) do{if(!(expr)) {LOG_ERROR(message); return;};}while(0) +#endif + + +#ifndef CHECK_AND_ASSERT_MES2 +#define CHECK_AND_ASSERT_MES2(expr, message) do{if(!(expr)) {LOG_ERROR(message); };}while(0) +#endif + +} +#endif //_MISC_LOG_EX_H_ diff --git a/src/contrib/epee/include/misc_os_dependent.h b/src/contrib/epee/include/misc_os_dependent.h new file mode 100644 index 0000000..4d9c991 --- /dev/null +++ b/src/contrib/epee/include/misc_os_dependent.h @@ -0,0 +1,108 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +#ifdef WIN32 + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + + //#ifdef _WIN32_WINNT + // #undef _WIN32_WINNT + // #define _WIN32_WINNT 0x0600 + //#endif + + +#include +#endif + +#ifdef __MACH__ +#include +#include +#endif + +#pragma once +namespace epee +{ +namespace misc_utils +{ + + inline uint64_t get_tick_count() + { +#if defined(_MSC_VER) + return ::GetTickCount64(); +#elif defined(__MACH__) + clock_serv_t cclock; + mach_timespec_t mts; + + host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); + clock_get_time(cclock, &mts); + mach_port_deallocate(mach_task_self(), cclock); + + return (mts.tv_sec * 1000) + (mts.tv_nsec/1000000); +#else + struct timespec ts; + if(clock_gettime(CLOCK_MONOTONIC, &ts) != 0) { + return 0; + } + return (ts.tv_sec * 1000) + (ts.tv_nsec/1000000); +#endif + } + + + inline int call_sys_cmd(const std::string& cmd) + { + std::cout << "# " << cmd << std::endl; + + FILE * fp ; + //char tstCommand[] ="ls *"; + char path[1000] = {0}; +#if !defined(__GNUC__) + fp = _popen(cmd.c_str(), "r"); +#else + fp = popen(cmd.c_str(), "r"); +#endif + while ( fgets( path, 1000, fp ) != NULL ) + std::cout << path; + +#if !defined(__GNUC__) + _pclose(fp); +#else + pclose(fp); +#endif + return 0; + + } + + + inline std::string get_thread_string_id() + { +#if defined(_MSC_VER) + return boost::lexical_cast(GetCurrentThreadId()); +#elif defined(__GNUC__) + return boost::lexical_cast(pthread_self()); +#endif + } +} +} diff --git a/src/contrib/epee/include/pragma_comp_defs.h b/src/contrib/epee/include/pragma_comp_defs.h new file mode 100644 index 0000000..f4ef705 --- /dev/null +++ b/src/contrib/epee/include/pragma_comp_defs.h @@ -0,0 +1,14 @@ +#pragma once + +#if defined(__GNUC__) + #define PRAGMA_WARNING_PUSH _Pragma("GCC diagnostic push") + #define PRAGMA_WARNING_POP _Pragma("GCC diagnostic pop") + #define PRAGMA_WARNING_DISABLE_VS(w) + #define PRAGMA_GCC(w) _Pragma(w) +#elif defined(_MSC_VER) + #define PRAGMA_WARNING_PUSH __pragma(warning( push )) + #define PRAGMA_WARNING_POP __pragma(warning( pop )) + #define PRAGMA_WARNING_DISABLE_VS(w) __pragma( warning ( disable: w )) + //#define PRAGMA_WARNING_DISABLE_GCC(w) + #define PRAGMA_GCC(w) +#endif diff --git a/src/contrib/epee/include/static_initializer.h b/src/contrib/epee/include/static_initializer.h new file mode 100644 index 0000000..3463a56 --- /dev/null +++ b/src/contrib/epee/include/static_initializer.h @@ -0,0 +1,82 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + + + +#ifndef _STATIC_INITIALIZER_H_ +#define _STATIC_INITIALIZER_H_ + + +namespace epee +{ +/*********************************************************************** +class initializer - useful to initialize some static classes + which have init() and un_init() static members +************************************************************************/ + +template +class initializer +{ +public: + initializer() + { + to_initialize::init(); + //get_set_is_initialized(true, true); + } + ~initializer() + { + to_initialize::un_init(); + //get_set_is_uninitialized(true, true); + } + + /*static inline bool is_initialized() + { + return get_set_is_initialized(); + } + static inline bool is_uninitialized() + { + return get_set_is_uninitialized(); + } + +private: + static inline bool get_set_is_initialized(bool need_to_set = false, bool val_to_set= false) + { + static bool val_is_initialized = false; + if(need_to_set) + val_is_initialized = val_to_set; + return val_is_initialized; + } + static inline bool get_set_is_uninitialized(bool need_to_set = false, bool val_to_set = false) + { + static bool val_is_uninitialized = false; + if(need_to_set) + val_is_uninitialized = val_to_set; + return val_is_uninitialized; + }*/ +}; + +} +#endif //_STATIC_INITIALIZER_H_ diff --git a/src/contrib/epee/include/string_tools.h b/src/contrib/epee/include/string_tools.h new file mode 100644 index 0000000..4cc8841 --- /dev/null +++ b/src/contrib/epee/include/string_tools.h @@ -0,0 +1,744 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + + + +#ifndef _STRING_TOOLS_H_ +#define _STRING_TOOLS_H_ + +//#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include "warnings.h" + + +#ifndef OUT + #define OUT +#endif + +#ifdef WINDOWS_PLATFORM +#pragma comment (lib, "Rpcrt4.lib") +#endif + +namespace epee +{ +namespace string_tools +{ + inline std::wstring get_str_from_guid(const boost::uuids::uuid& rid) + { + return boost::lexical_cast(rid); + } + //---------------------------------------------------------------------------- + inline std::string get_str_from_guid_a(const boost::uuids::uuid& rid) + { + return boost::lexical_cast(rid); + } + //---------------------------------------------------------------------------- + inline bool get_guid_from_string( boost::uuids::uuid& inetifer, std::wstring str_id) + { + if(str_id.size() < 36) + return false; + + if('{' == *str_id.begin()) + str_id.erase(0, 1); + + if('}' == *(--str_id.end())) + str_id.erase(--str_id.end()); + + try + { + inetifer = boost::lexical_cast(str_id); + return true; + } + catch(...) + { + return false; + } + } + //---------------------------------------------------------------------------- + inline bool get_guid_from_string(OUT boost::uuids::uuid& inetifer, const std::string& str_id) + { + std::string local_str_id = str_id; + if(local_str_id.size() < 36) + return false; + + if('{' == *local_str_id.begin()) + local_str_id.erase(0, 1); + + if('}' == *(--local_str_id.end())) + local_str_id.erase(--local_str_id.end()); + + try + { + inetifer = boost::lexical_cast(local_str_id); + return true; + } + catch(...) + { + return false; + } + } + //---------------------------------------------------------------------------- + template + std::basic_string buff_to_hex(const std::basic_string& s) + { + using namespace std; + basic_stringstream hexStream; + hexStream << hex << noshowbase << setw(2); + + for(typename std::basic_string::const_iterator it = s.begin(); it != s.end(); it++) + { + hexStream << "0x"<< static_cast(static_cast(*it)) << " "; + } + return hexStream.str(); + } + //---------------------------------------------------------------------------- + template + std::basic_string buff_to_hex_nodelimer(const std::basic_string& s) + { + using namespace std; + basic_stringstream hexStream; + hexStream << hex << noshowbase; + + for(typename std::basic_string::const_iterator it = s.begin(); it != s.end(); it++) + { + hexStream << setw(2) << setfill('0') << static_cast(static_cast(*it)); + } + return hexStream.str(); + } + //---------------------------------------------------------------------------- + template + bool parse_hexstr_to_binbuff(const std::basic_string& s, std::basic_string& res) + { + res.clear(); + try + { + long v = 0; + for(size_t i = 0; i < (s.size() + 1) / 2; i++) + { + CharT byte_str[3]; + size_t copied = s.copy(byte_str, 2, 2 * i); + byte_str[copied] = CharT(0); + CharT* endptr; + v = strtoul(byte_str, &endptr, 16); + if (v < 0 || 0xFF < v || endptr != byte_str + copied) + { + return false; + } + res.push_back(static_cast(v)); + } + + return true; + }catch(...) + { + return false; + } + } + //---------------------------------------------------------------------------- + template + bool parse_tpod_from_hex_string(const std::string& str_hash, t_pod_type& t_pod) + { + std::string buf; + bool res = epee::string_tools::parse_hexstr_to_binbuff(str_hash, buf); + if (!res || buf.size() != sizeof(t_pod_type)) + { + return false; + } + else + { + buf.copy(reinterpret_cast(&t_pod), sizeof(t_pod_type)); + return true; + } + } + //---------------------------------------------------------------------------- +PUSH_WARNINGS +DISABLE_GCC_WARNING(maybe-uninitialized) + template + inline bool get_xtype_from_string(OUT XType& val, const std::string& str_id) + { + if (std::is_integral::value && !std::numeric_limits::is_signed && !std::is_same::value) + { + for (char c : str_id) + { + if (!std::isdigit(c)) + return false; + } + } + + try + { + val = boost::lexical_cast(str_id); + return true; + } + catch(std::exception& /*e*/) + { + //const char* pmsg = e.what(); + return false; + } + catch(...) + { + return false; + } + + return true; + } +POP_WARNINGS + //--------------------------------------------------- + template + bool get_xnum_from_hex_string(const std::string str, int_t& res ) + { + try + { + std::stringstream ss; + ss << std::hex << str; + ss >> res; + return true; + } + catch(...) + { + return false; + } + } + //---------------------------------------------------------------------------- + template + inline bool xtype_to_string(const XType& val, std::string& str) + { + try + { + str = boost::lexical_cast(val); + } + catch(...) + { + return false; + } + + return true; + } + + typedef std::map command_line_params_a; + typedef std::map command_line_params_w; + + template + bool parse_commandline(std::map& res, int argc, char** argv) + { + t_string key; + for(int i = 1; i < argc; i++) + { + if(!argv[i]) + break; + t_string s = argv[i]; + std::string::size_type p = s.find('='); + if(std::string::npos == p) + { + res[s] = ""; + }else + { + std::string ss; + t_string nm = s.substr(0, p); + t_string vl = s.substr(p+1, s.size()); + res[nm] = vl; + } + } + return true; + } + +/* template + bool get_xparam_from_command_line(const std::map& res, const std::basic_string & key, t_type& val) + { + + } + */ + + template + bool get_xparam_from_command_line(const std::map& res, const t_string & key, t_type& val) + { + typename std::map::const_iterator it = res.find(key); + if(it == res.end()) + return false; + + if(it->second.size()) + { + return get_xtype_from_string(val, it->second); + } + + return true; + } + + template + t_type get_xparam_from_command_line(const std::map& res, const t_string & key, const t_type& default_value) + { + typename std::map::const_iterator it = res.find(key); + if(it == res.end()) + return default_value; + + if(it->second.size()) + { + t_type s; + get_xtype_from_string(s, it->second); + return s; + } + + return default_value; + } + + template + bool have_in_command_line(const std::map& res, const std::basic_string& key) + { + typename std::map::const_iterator it = res.find(key); + if(it == res.end()) + return false; + + return true; + } + + //---------------------------------------------------------------------------- +//#ifdef _WINSOCK2API_ + inline std::string get_ip_string_from_int32(uint32_t ip) + { + in_addr adr; + adr.s_addr = ip; + const char* pbuf = inet_ntoa(adr); + if(pbuf) + return pbuf; + else + return "[failed]"; + } + //---------------------------------------------------------------------------- + inline bool get_ip_int32_from_string(uint32_t& ip, const std::string& ip_str) + { + ip = inet_addr(ip_str.c_str()); + if(INADDR_NONE == ip) + return false; + + return true; + } + //---------------------------------------------------------------------------- + inline bool parse_peer_from_string(uint32_t& ip, uint32_t& port, const std::string& addres) + { + //parse ip and address + std::string::size_type p = addres.find(':'); + if(p == std::string::npos) + { + return false; + } + std::string ip_str = addres.substr(0, p); + std::string port_str = addres.substr(p+1, addres.size()); + + if(!get_ip_int32_from_string(ip, ip_str)) + { + return false; + } + + if(!get_xtype_from_string(port, port_str)) + { + return false; + } + return true; + } + +//#endif + //---------------------------------------------------------------------------- + template + inline std::string get_t_as_hex_nwidth(const t& v, std::streamsize w = 8) + { + std::stringstream ss; + ss << std::setfill ('0') << std::setw (w) << std::hex << std::noshowbase; + ss << v; + return ss.str(); + } + + inline std::string num_to_string_fast(int64_t val) + { + /* + char buff[30] = {0}; + i64toa_s(val, buff, sizeof(buff)-1, 10); + return buff;*/ + return boost::lexical_cast(val); + } + //---------------------------------------------------------------------------- + inline bool string_to_num_fast(const std::string& buff, int64_t& val) + { + //return get_xtype_from_string(val, buff); +#if (defined _MSC_VER) + val = _atoi64(buff.c_str()); +#else + val = atoll(buff.c_str()); +#endif + /* + * val = atoi64(buff.c_str()); + */ + if(buff != "0" && val == 0) + return false; + return true; + } + //---------------------------------------------------------------------------- + inline bool string_to_num_fast(const std::string& buff, int& val) + { + val = atoi(buff.c_str()); + if(buff != "0" && val == 0) + return false; + + return true; + } + //---------------------------------------------------------------------------- +#ifdef WINDOWS_PLATFORM + inline std::string system_time_to_string(const SYSTEMTIME& st) + { + + /* + TIME_ZONE_INFORMATION tzi; + GetTimeZoneInformation(&tzi); + SystemTimeToTzSpecificLocalTime(&tzi, &stUTC, &stLocal); + */ + + char szTime[25], szDate[25]; + ::GetTimeFormatA( + LOCALE_USER_DEFAULT, // locale + TIME_FORCE24HOURFORMAT, // options + &st, // time + NULL, // time format string + szTime, // formatted string buffer + 25 // size of string buffer + ); + + ::GetDateFormatA( + LOCALE_USER_DEFAULT, // locale + NULL, // options + &st, // date + NULL, // date format + szDate, // formatted string buffer + 25 // size of buffer + ); + szTime[24] = szDate[24] = 0; //be happy :) + + std::string res = szDate; + (res += " " )+= szTime; + return res; + + } +#endif + //---------------------------------------------------------------------------- + + inline bool compare_no_case(const std::string& str1, const std::string& str2) + { + + return !boost::iequals(str1, str2); + } + //---------------------------------------------------------------------------- + inline bool compare_no_case(const std::wstring& str1, const std::wstring& str2) + { + return !boost::iequals(str1, str2); + } + //---------------------------------------------------------------------------- + inline bool is_match_prefix(const std::wstring& str1, const std::wstring& prefix) + { + if(prefix.size()>str1.size()) + return false; + + if(!compare_no_case(str1.substr(0, prefix.size()), prefix)) + return true; + else + return false; + } + //---------------------------------------------------------------------------- + inline bool is_match_prefix(const std::string& str1, const std::string& prefix) + { + if(prefix.size()>str1.size()) + return false; + + if(!compare_no_case(str1.substr(0, prefix.size()), prefix)) + return true; + else + return false; + } + //---------------------------------------------------------------------------- + inline std::string& get_current_module_name() + { + static std::string module_name; + return module_name; + } + //---------------------------------------------------------------------------- + inline std::string& get_current_module_folder() + { + static std::string module_folder; + return module_folder; + } + //---------------------------------------------------------------------------- +#ifdef _WIN32 + inline std::string get_current_module_path() + { + char pname [5000] = {0}; + GetModuleFileNameA( NULL, pname, sizeof(pname)); + pname[sizeof(pname)-1] = 0; //be happy ;) + return pname; + } +#endif + //---------------------------------------------------------------------------- + inline bool set_module_name_and_folder(const std::string& path_to_process_) + { + std::string path_to_process = path_to_process_; +#ifdef _WIN32 + path_to_process = get_current_module_path(); +#endif + std::string::size_type a = path_to_process.rfind( '\\' ); + if(a == std::string::npos ) + { + a = path_to_process.rfind( '/' ); + } + if ( a != std::string::npos ) + { + get_current_module_name() = path_to_process.substr(a+1, path_to_process.size()); + get_current_module_folder() = path_to_process.substr(0, a); + return true; + }else + return false; + + } + + //---------------------------------------------------------------------------- + inline bool trim_left(std::string& str) + { + for(std::string::iterator it = str.begin(); it!= str.end() && isspace(static_cast(*it));) + str.erase(str.begin()); + + return true; + } + //---------------------------------------------------------------------------- + inline bool trim_right(std::string& str) + { + + for(std::string::reverse_iterator it = str.rbegin(); it!= str.rend() && isspace(static_cast(*it));) + str.erase( --((it++).base())); + + return true; + } + //---------------------------------------------------------------------------- + inline std::string& trim(std::string& str) + { + + trim_left(str); + trim_right(str); + return str; + } + //---------------------------------------------------------------------------- + inline std::string trim(const std::string& str_) + { + std::string str = str_; + trim_left(str); + trim_right(str); + return str; + } + //---------------------------------------------------------------------------- + template + std::string pod_to_hex(const t_pod_type& s) + { + std::string buff; + buff.assign(reinterpret_cast(&s), sizeof(s)); + return buff_to_hex_nodelimer(buff); + } + //---------------------------------------------------------------------------- + template + bool hex_to_pod(const std::string& hex_str, t_pod_type& s) + { + std::string hex_str_tr = trim(hex_str); + if(sizeof(s)*2 != hex_str.size()) + return false; + std::string bin_buff; + if(!parse_hexstr_to_binbuff(hex_str_tr, bin_buff)) + return false; + if(bin_buff.size()!=sizeof(s)) + return false; + + s = *(t_pod_type*)bin_buff.data(); + return true; + } + //---------------------------------------------------------------------------- + inline std::string get_extension(const std::string& str) + { + std::string res; + std::string::size_type pos = str.rfind('.'); + if(std::string::npos == pos) + return res; + + res = str.substr(pos+1, str.size()-pos); + return res; + } + //---------------------------------------------------------------------------- + inline std::string get_filename_from_path(const std::string& str) + { + std::string res; + std::string::size_type pos = str.rfind('\\'); + if(std::string::npos == pos) + return str; + + res = str.substr(pos+1, str.size()-pos); + return res; + } + //---------------------------------------------------------------------------- + + + + inline std::string cut_off_extension(const std::string& str) + { + std::string res; + std::string::size_type pos = str.rfind('.'); + if(std::string::npos == pos) + return str; + + res = str.substr(0, pos); + return res; + } + + //---------------------------------------------------------------------------- +#ifdef _WININET_ + inline std::string get_string_from_systemtime(const SYSTEMTIME& sys_time) + { + std::string result_string; + + char buff[100] = {0}; + BOOL res = ::InternetTimeFromSystemTimeA(&sys_time, INTERNET_RFC1123_FORMAT, buff, 99); + if(!res) + { + LOG_ERROR("Failed to load SytemTime to string"); + } + + result_string = buff; + return result_string; + + } + //------------------------------------------------------------------------------------- + inline SYSTEMTIME get_systemtime_from_string(const std::string& buff) + { + SYSTEMTIME result_time = {0}; + + BOOL res = ::InternetTimeToSystemTimeA(buff.c_str(), &result_time, NULL); + if(!res) + { + LOG_ERROR("Failed to load SytemTime from string " << buff << "interval set to 15 minutes"); + } + + return result_time; + } +#endif + +#ifdef WINDOWS_PLATFORM + static const DWORD INFO_BUFFER_SIZE = 10000; + + static const wchar_t* get_pc_name() + { + static wchar_t info[INFO_BUFFER_SIZE]; + static DWORD bufCharCount = INFO_BUFFER_SIZE; + static bool init = false; + + if (!init) { + if (!GetComputerNameW( info, &bufCharCount )) + info[0] = 0; + else + init = true; + } + + return info; + } + + static const wchar_t* get_user_name() + { + static wchar_t info[INFO_BUFFER_SIZE]; + static DWORD bufCharCount = INFO_BUFFER_SIZE; + static bool init = false; + + if (!init) { + if (!GetUserNameW( info, &bufCharCount )) + info[0] = 0; + else + init = true; + } + + return info; + } +#endif + +#ifdef _LM_ + static const wchar_t* get_domain_name() + { + static wchar_t info[INFO_BUFFER_SIZE]; + static DWORD bufCharCount = 0; + static bool init = false; + + if (!init) { + LPWSTR domain( NULL ); + NETSETUP_JOIN_STATUS status; + info[0] = 0; + + if (NET_API_STATUS result = NetGetJoinInformation( NULL, &domain, &status )) + { + LOG_ERROR("get_domain_name error: " << log_space::get_win32_err_descr(result)); + } else + { + StringCchCopyW( info, sizeof(info)/sizeof( info[0] ), domain ); + NetApiBufferFree((void*)domain); + init = true; + } + } + + return info; + } +#endif +#ifdef WINDOWS_PLATFORM + inline + std::string load_resource_string_a(int id, const char* pmodule_name = NULL) + { + //slow realization + HMODULE h = ::GetModuleHandleA( pmodule_name ); + + char buff[2000] = {0}; + + ::LoadStringA( h, id, buff, sizeof(buff)); + buff[sizeof(buff)-1] = 0; //be happy :) + return buff; + } + inline + std::wstring load_resource_string_w(int id, const char* pmodule_name = NULL) + { + //slow realization + HMODULE h = ::GetModuleHandleA( pmodule_name ); + + wchar_t buff[2000] = {0}; + + ::LoadStringW( h, id, buff, sizeof(buff) / sizeof( buff[0] ) ); + buff[(sizeof(buff)/sizeof(buff[0]))-1] = 0; //be happy :) + return buff; + } +#endif +} +} +#endif //_STRING_TOOLS_H_ diff --git a/src/contrib/epee/include/syncobj.h b/src/contrib/epee/include/syncobj.h new file mode 100644 index 0000000..b7273da --- /dev/null +++ b/src/contrib/epee/include/syncobj.h @@ -0,0 +1,243 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + + + + +#ifndef __WINH_OBJ_H__ +#define __WINH_OBJ_H__ + +#include +#include +#include +#include +#include + +namespace epee +{ + + struct simple_event + { + simple_event() : m_rised(false) + { + } + + void raise() + { + std::unique_lock lock(m_mx); + m_rised = true; + m_cond_var.notify_one(); + } + + void wait() + { + std::unique_lock lock(m_mx); + while (!m_rised) + m_cond_var.wait(lock); + m_rised = false; + } + + private: + std::mutex m_mx; + std::condition_variable m_cond_var; + bool m_rised; + }; + + class critical_region; + + class critical_section + { + boost::recursive_mutex m_section; + + public: + //to make copy fake! + critical_section(const critical_section& section) + { + } + + critical_section() + { + } + + ~critical_section() + { + } + + void lock() + { + m_section.lock(); + //EnterCriticalSection( &m_section ); + } + + void unlock() + { + m_section.unlock(); + } + + bool tryLock() + { + return m_section.try_lock(); + } + + // to make copy fake + critical_section& operator=(const critical_section& section) + { + return *this; + } + }; + + + template + class critical_region_t + { + t_lock& m_locker; + bool m_unlocked; + + critical_region_t(const critical_region_t&) {} + + public: + critical_region_t(t_lock& cs): m_locker(cs), m_unlocked(false) + { + m_locker.lock(); + } + + ~critical_region_t() + { + unlock(); + } + + void unlock() + { + if (!m_unlocked) + { + m_locker.unlock(); + m_unlocked = true; + } + } + }; + + +#if defined(WINDWOS_PLATFORM) + class shared_critical_section + { + public: + shared_critical_section() + { + ::InitializeSRWLock(&m_srw_lock); + } + ~shared_critical_section() + {} + + bool lock_shared() + { + AcquireSRWLockShared(&m_srw_lock); + return true; + } + bool unlock_shared() + { + ReleaseSRWLockShared(&m_srw_lock); + return true; + } + bool lock_exclusive() + { + ::AcquireSRWLockExclusive(&m_srw_lock); + return true; + } + bool unlock_exclusive() + { + ::ReleaseSRWLockExclusive(&m_srw_lock); + return true; + } + private: + SRWLOCK m_srw_lock; + }; + + + class shared_guard + { + public: + shared_guard(shared_critical_section& ref_sec):m_ref_sec(ref_sec) + { + m_ref_sec.lock_shared(); + } + + ~shared_guard() + { + m_ref_sec.unlock_shared(); + } + + private: + shared_critical_section& m_ref_sec; + }; + + + class exclusive_guard + { + public: + exclusive_guard(shared_critical_section& ref_sec):m_ref_sec(ref_sec) + { + m_ref_sec.lock_exclusive(); + } + + ~exclusive_guard() + { + m_ref_sec.unlock_exclusive(); + } + + private: + shared_critical_section& m_ref_sec; + }; +#endif + +#define SHARED_CRITICAL_REGION_BEGIN(x) { shared_guard critical_region_var(x) +#define EXCLUSIVE_CRITICAL_REGION_BEGIN(x) { exclusive_guard critical_region_var(x) + +#define CRITICAL_REGION_LOCAL(x) epee::critical_region_t critical_region_var(x) +#define CRITICAL_REGION_BEGIN(x) { epee::critical_region_t critical_region_var(x) +#define CRITICAL_REGION_LOCAL1(x) epee::critical_region_t critical_region_var1(x) +#define CRITICAL_REGION_BEGIN1(x) { epee::critical_region_t critical_region_var1(x) + +#define CRITICAL_REGION_END() } + + +#if defined(WINDWOS_PLATFORM) + inline const char* get_wait_for_result_as_text(DWORD res) + { + switch(res) + { + case WAIT_ABANDONED: return "WAIT_ABANDONED"; + case WAIT_TIMEOUT: return "WAIT_TIMEOUT"; + case WAIT_OBJECT_0: return "WAIT_OBJECT_0"; + case WAIT_OBJECT_0+1: return "WAIT_OBJECT_1"; + case WAIT_OBJECT_0+2: return "WAIT_OBJECT_2"; + default: return "UNKNOWN CODE"; + } + } +#endif + +} + +#endif diff --git a/src/contrib/epee/include/time_helper.h b/src/contrib/epee/include/time_helper.h new file mode 100644 index 0000000..958176d --- /dev/null +++ b/src/contrib/epee/include/time_helper.h @@ -0,0 +1,159 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + + + +#pragma once + +//#include +//#include +#include +#include +#include "pragma_comp_defs.h" + +namespace epee +{ +namespace misc_utils +{ + +#ifdef __ATLTIME_H__ + + inline + bool get_time_t_from_ole_date(DATE src, time_t& res) + { + SYSTEMTIME st = {0}; + if(TRUE != ::VariantTimeToSystemTime(src, &st)) + return false; + ATL::CTime ss(st); + res = ss.GetTime(); + return true; + } +#endif + inline + std::string get_time_str(const time_t& time_) + { + + + char tmpbuf[200] = {0}; + tm* pt = NULL; +PRAGMA_WARNING_PUSH +PRAGMA_WARNING_DISABLE_VS(4996) + pt = localtime(&time_); +PRAGMA_WARNING_POP + + if(pt) + strftime( tmpbuf, 199, "%d.%m.%Y %H:%M:%S", pt ); + else + { + std::stringstream strs; + strs << "[wrong_time: " << std::hex << time_ << "]"; + return strs.str(); + } + return tmpbuf; + } + + inline + std::string get_time_str_v2(const time_t& time_) + { + + char tmpbuf[200] = {0}; + tm* pt = NULL; +PRAGMA_WARNING_PUSH +PRAGMA_WARNING_DISABLE_VS(4996) + pt = localtime(&time_); +PRAGMA_WARNING_POP + + if(pt) + strftime( tmpbuf, 199, "%Y_%m_%d %H_%M_%S", pt ); + else + { + std::stringstream strs; + strs << "[wrong_time: " << std::hex << time_ << "]"; + return strs.str(); + } + return tmpbuf; + } + + inline + std::string get_time_str_v3(const boost::posix_time::ptime& time_) + { + return boost::posix_time::to_simple_string(time_); + } + + + + inline std::string get_internet_time_str(const time_t& time_) + { + char tmpbuf[200] = {0}; + tm* pt = NULL; +PRAGMA_WARNING_PUSH +PRAGMA_WARNING_DISABLE_VS(4996) + pt = gmtime(&time_); +PRAGMA_WARNING_POP + strftime( tmpbuf, 199, "%a, %d %b %Y %H:%M:%S GMT", pt ); + return tmpbuf; + } + + inline std::string get_time_interval_string(const time_t& time_) + { + std::string res; + time_t tail = time_; +PRAGMA_WARNING_PUSH +PRAGMA_WARNING_DISABLE_VS(4244) + int days = tail/(60*60*24); + tail = tail%(60*60*24); + int hours = tail/(60*60); + tail = tail%(60*60); + int minutes = tail/(60); + tail = tail%(60); + int seconds = tail; +PRAGMA_WARNING_POP + res = std::string() + "d" + boost::lexical_cast(days) + ".h" + boost::lexical_cast(hours) + ".m" + boost::lexical_cast(minutes) + ".s" + boost::lexical_cast(seconds); + return res; + } + +#ifdef __SQLEXT + inline + bool odbc_time_to_oledb_taime(const SQL_TIMESTAMP_STRUCT& odbc_timestamp, DATE& oledb_date) + { + + SYSTEMTIME st = {0}; + st.wYear = odbc_timestamp.year; + st.wDay = odbc_timestamp.day; + st.wHour = odbc_timestamp.hour ; + st.wMilliseconds = (WORD)odbc_timestamp.fraction ; + st.wMinute = odbc_timestamp.minute ; + st.wMonth = odbc_timestamp.month ; + st.wSecond = odbc_timestamp.second ; + + if(TRUE != ::SystemTimeToVariantTime(&st, &oledb_date)) + return false; + return true; + } + +#endif +} +} \ No newline at end of file