code_scanner/common/referer.h

177 lines
6.5 KiB
C++

#pragma once
// Objects life management
//
// created on 2022-11-29
//
#include <semaphore.h>
#include <mutex>
#define ALIGN_INT(val, n) ((((val) + (n) - 1) / (n)) * (n))
#define SIZE_KB(n) ((n) * 1024)
#define SIZE_MB(n) SIZE_KB((n) * 1024)
#define SIZE_GB(n) SIZE_MB((n) * 1024)
#define WAIT_INFINITE 0
#define SEC_2_MS(s) ((s) * 1000)
#define MSEC_2_US(ms) ((ms) * 1000)
#define USEC_2_NS(us) ((us) * 1000)
#define SEC_2_US(s) MSEC_2_US(SEC_2_MS(s))
#define SEC_2_NS(s) USEC_2_NS(MSEC_2_US(SEC_2_MS(s)))
#define MSEC_2_NS(ms) USEC_2_NS(MSEC_2_US(ms))
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef std::mutex MUTEX;
typedef std::lock_guard<MUTEX> LOCKER;
// object life referer
//
// derived from 'refer' if your class used in multi-threads
//
class refer
{
volatile int32_t ref_;
MUTEX mutex_;
protected:
refer();
virtual ~refer();
virtual void on_born(void);
virtual void on_dead(void);
public:
virtual int32_t add_ref(void);
virtual int32_t release(void);
};
#include <sys/time.h>
class chronograph
{
struct timeval bgn_;
public:
chronograph();
~chronograph();
static bool now(struct timeval* 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);
};
class sane_cfg_provider : public refer
{
public:
sane_cfg_provider()
{}
virtual ~sane_cfg_provider()
{}
public:
// Function: get all or given name configuration value
//
// Parameters: buf - to receive the configuration value or all configuration JSON
//
// len - [in] bytes of 'buf', [out] - content bytes in 'buf', or minimum size needed
//
// cfg_name - given configuration name, if set, put current value of the configuration in 'buf',
// or put all configurations JSON text in 'buf' if was nullptr. refer to SANE-config
//
// Return: 0 - on success
// EINVAL - if paramter 'len' was nullptr
// ENOMEM - if size of 'buf' was too small, the minimum size needed is stored in 'len'
// ENOENT - the configuration named 'cfg_name' has not found
virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr) = 0;
// Function: set value of configuration named 'cfg_name'
//
// Parameters: cfg_name - the configuration name
//
// data - the value address, nullptr is for restore to default value
// (bool*), (int*), (double*), (char*)
//
// len - bytes in 'data'
//
// Return: 0 - on success
// EINVAL - parameter was invalid. 'cfg_name' was nullptr
// ENOENT - configuration 'cfg_name' was not found
// EUCLEAN - content in 'data' was not exact, the exact value is stored in 'data', and bytes in 'len'
virtual int32_t set_config(const char* cfg_name, void* data, size_t* len) = 0;
};
#include <string>
namespace sys_util
{
int32_t enum_modules(bool(*on_found)(const char* path_module_name, bool is_dir, void* param),// return false to stop enumeratin
void* param, // user defined data, passed into callback on_found
unsigned pid = -1 // process id, -1 is self
); // return errno
int32_t enum_files(const char* dir // dir path
, bool(*on_found)(const char* path_name, bool is_dir, void* param)// return false to stop enumeratin
, void* param // user defined data, passed into callback on_found
, bool recursive = true // walk recursive
); // return errno
int32_t enum_processes(bool(*on_found)(uint64_t pid, const char* path_name, void* param), void* param);
uint32_t enum_threads(uint64_t pid, bool(*on_found)(uint64_t tid, void* start_addr, void* param), void* param);
uint32_t get_thread_callstack(uint64_t pid, uint64_t tid, bool(*on_found)(uint64_t off, const char* module, void* param), void* param);
uint32_t read_line(const char* file, bool(*on_line)(char* line, void* param), void* param);
std::string get_module_path(const char* module_name = nullptr
, unsigned pid = -1); // get module full path, nullptr is for main-exe
std::string read_link(const char* lnk);
size_t get_page_size(void);
bool create_folder(const char* dir);
// Function: pick single-line info file data, return count of set-value variable
//
// Parameters: file - full path of local file
//
// line_max - max bytes of a line in file 'file'
//
// fmt - line fromat string, e.g. "model name : %60[\x20-\x7e]", "MemoryTotal: %ld", "address sizes : %d bits physical, %d bits virtual", ...
//
// args - variable list
//
// Return: count of the variable which got the value
template<typename ... Args>
int32_t get_inf_file_data(const char* file, size_t line_max, const char* fmt, Args ... args)
{
std::string buf("\0", line_max + 8);
FILE* src = fopen(file, "rb");
int32_t count = 0;
if (!src)
return 0;
while (fgets(&buf[0], line_max, src))
{
count = sscanf(&buf[0], fmt, args ...);
if (count > 0)
break;
}
fclose(src);
return count;
}
int32_t get_memory_info(uint64_t* total, uint64_t* available);
std::string format_readable_bytes(uint64_t bytes); // convert to readable text: 512B, 1.21KB, 1.10MB, 3.45GB, 1,234.56GB ...
std::string get_command_output(const char* cmd, uint16_t max_line_len = 256, bool one_line = true);
// trim string, return whether space trimmed
bool trim_left(std::string& str, const char* space = " \t");
bool trim_right(std::string& str, const char* space = " \t");
uint64_t from_hex_str(const char* hex, const char** end = nullptr); // convert 0x100 to 256. parameter 'end' to receive the stopped position
}