code_util/base.h

165 lines
6.3 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);
};
#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
// Function: convert number string to integer, support hex, dec, oct and bin
//
// Parameter: str - number string.
// 0x.../...h: as hexadecimal
// ...o: as octonary
// ...b: as binary
// ...: as decimal, or as hexadecimal if has hex letter
//
// end - to receive the ending point when covert over
//
// Return: integer, default is ZERO, you should check the ending point when this value returned
uint64_t to_int(const char* str, const char** end = nullptr);
std::string transform_between_gbk_and_utf8(const char* in, bool to_utf8, int* err = nullptr);
std::string transform_between_utf16_and_utf8(const char* in, size_t bytes, bool to_utf8);
std::string to_abs_path(const char* base, const char* rel_path);
std::string to_rel_path(const char* base, const char* abs_path);
// Function: pick simple block in pair chars
//
// Parameter: head - beginning of the string, and the first character is the beginning char
//
// end - ending character of the block
//
// Return: the last positoin of the block (*ret = end), or nullptr if not matched
const char* pick_simple_block(const char* head, char end);
}