上传项目代码

This commit is contained in:
lixiaoyuan
2025-05-19 09:54:33 +08:00
commit 4a198a7271
589 changed files with 993786 additions and 0 deletions

197
src/common/DataFields.cpp Normal file
View File

@@ -0,0 +1,197 @@
#include "DataFields.h"
#include "common/Utils.h"
void DataFields::set(string key, string val)
{
map_fields_[key] = val;
}
void DataFields::set(string key, float val)
{
map_fields_[key] = std::to_string(val);
}
void DataFields::set(string key, int val)
{
map_fields_[key] = std::to_string(val);
}
void DataFields::set(string key, int64_t val)
{
map_fields_[key] = std::to_string(val);
}
string DataFields::get_str(string key)
{
if (map_fields_.count(key) > 0)
{
return map_fields_[key];
}
else
{
return "";
}
}
int DataFields::get_int(string key)
{
return map_fields_.count(key) > 0 ? Utils::toInt(map_fields_[key]) : 0;
}
float DataFields::get_float(string key)
{
return map_fields_.count(key) > 0 ? Utils::toFloat(map_fields_[key]) : 0.0f;
}
void DataFields::remove(string key)
{
auto it = map_fields_.find(key);
if (it != map_fields_.end())
{
map_fields_.erase(it);
}
}
void DataFields::append(DataFields& datafield)
{
auto& map_f = datafield.fields();
for (auto it = map_f.begin(); it != map_f.end(); it++)
{
map_fields_[it->first] = it->second;
}
}
map<string, string>& DataFields::fields()
{
return map_fields_;
}
void DataFields::check(string key, string val, string d)
{
if (map_fields_.count(key) > 0 && map_fields_[key] == val)
{
map_fields_[key] = d;
}
}
string DataFields::get_insert_sql(string tbname)
{
string key;
string val;
for (auto it = map_fields_.begin(); it != map_fields_.end(); it++)
{
if (!key.empty())
{
key += ",";
val += ",";
}
key += ("`" + it->first + "`");
if (it->second == "null" || it->second == "NULL")
{
val += "NULL";
}
else
{
val += ("'" + it->second + "'");
}
}
return "INSERT INTO `" + tbname + "` (" + key + ") VALUES(" + val + ");";
}
string DataFields::get_update_sql(string tbname, string sql_c)
{
ostringstream oss;
oss << "update " << tbname << " set ";
for (auto iter = map_fields_.begin(); iter != map_fields_.end(); iter++)
{
if (iter != map_fields_.begin())
{
oss << ",";
};
oss << "`" << iter->first << "`=";
if (iter->second == "null" || iter->second == "NULL")
{
oss << "NULL";
}
else
{
oss << "'" << iter->second << "'";
}
}
oss << " " << sql_c << ";";
return oss.str();
}
string DataFields::get_update_sql(string tbname, std::vector<std::string> vec_keys, string sql_c)
{
std::map<std::string, bool> map_keys;
for (auto& k : vec_keys) { map_keys[k] = true; }
ostringstream oss;
oss << "update " << tbname << " set ";
for (auto iter = map_fields_.begin(); iter != map_fields_.end(); iter++)
{
auto& k = iter->first;
auto& v = iter->second;
if (!map_keys[k]) { continue; }
if (iter != map_fields_.begin())
{
oss << ",";
};
oss << "`" << k << "`=";
if (v == "null" || v == "NULL")
{
oss << "NULL";
}
else
{
oss << "'" << v << "'";
}
}
oss << " " << sql_c << ";";
return oss.str();
}
void DataFields::foreach_item(function<void(string key, string val)> on_foraach)
{
for (auto it = map_fields_.begin(); it != map_fields_.end(); it++)
{
if (on_foraach)
{
on_foraach(it->first, it->second);
}
}
}
bool DataFields::is_empty(string key)
{
auto& s = map_fields_[key];
return s.empty();
}
bool DataFields::is_float_number(string key)
{
auto& s = map_fields_[key];
if (s.empty())
{
return false;
}
for (auto& c : s)
{
if (std::isdigit(c) == 0 && c != '.')
{
return false;
}
}
return true;
}
string DataFields::to_str()
{
string s;
for (auto it = map_fields_.begin(); it != map_fields_.end(); it++)
{
s += ("[" + it->first + ":" + it->second + "] ");
}
return s;
}
int DataFields::size()
{
return map_fields_.size();
}
void DataFields::clear()
{
map_fields_.clear();
}

149
src/common/DataFields.h Normal file
View File

@@ -0,0 +1,149 @@
#ifndef _DataFields_H_
#define _DataFields_H_
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <functional>
using namespace std;
struct PageInfo
{
int total = 0;
int page_id = 1;
int page_size = 10;
int page_max = 0;
};
class DataFields
{
public:
/**
* 设置索引名称和值
* @param: [string key] 索引名称
* @param: [string val] 值
*/
void set(string key, string val);
/**
* 设置索引名称和值
* @param: [string key] 索引名称
* @param: [float val] 值
*/
void set(string key, float val);
/**
* 设置索引名称和值
* @param: [string key] 索引名称
* @param: [int val] 值
*/
void set(string key, int val);
/**
* 设置索引名称和值
* @param: [string key] 索引名称
* @param: [int64_t val] 值
*/
void set(string key, int64_t val);
/**
* 获取 string 值
* @param: [string key] 索引名称
*/
string get_str(string key);
/**
* 获取 int 值
* @param: [string key] 索引名称
*/
int get_int(string key);
/**
* 获取 float 值
* @param: [string key] 索引名称
*/
float get_float(string key);
/**
* 删除指定索引的值
* @param: [string key] 索引名称
*/
void remove(string key);
/**
* 追加合并
* @param: [DataFields& fields] 要合并的数据
*/
void append(DataFields& fields);
/**
* 获取数据项map
*/
map<string, string>& fields();
/**
* 检查某一数据项的值进行替换如果该项的值是val则替换成成d
* @param: [string key] 索引名称
* @param: [string val] 要检查的值
* @param: [string d] 替换的值
*/
void check(string key, string val, string d);
/**
* 转换成插入数据的 sql 语句
* @param: [string tbname] 数据表名称
*/
string get_insert_sql(string tbname);
/**
* 转换成更新数据的 sql 语句
* @param: [string tbname] 数据表名称
* @param: [string sql_c] sql的更新条件例如 where id='1'
*/
string get_update_sql(string tbname, string sql_c);
/**
* 转换成更新数据的 sql 语句
* @param: [string tbname] 数据表名称
* @param: [string vec_keys] 需要更新的字段名称
* @param: [string sql_c] sql的更新条件例如 where id='1'
*/
string get_update_sql(string tbname, std::vector<std::string> vec_keys, string sql_c);
/**
* 遍历数据项
* @param: [function... on_foraach] 回调函数
*/
void foreach_item(function<void(string key, string val)> on_foraach);
/**
* 判断是否含有数据项
* @param: [string key] 索引名称
*/
bool is_empty(string key);
/**
* 判断数据项是否是float数值类型
* @param: [string key] 索引名称
*/
bool is_float_number(string key);
/**
* 转换成键值对的字符串格式
*/
string to_str();
/**
* 获取数据项的大小
*/
int size();
void clear();
private:
map<string, string> map_fields_;
};
#endif

71
src/common/Logger.cpp Normal file
View File

@@ -0,0 +1,71 @@
#include "Logger.h"
#include <windows.h>
#include <mutex>
#include "Utils.h"
//#include "common/spdlogger.h"
std::mutex g_mutex;
Logger::Logger(Logger::ELogType logtype, std::string filename, int line) : line_(line)
{
auto index = filename.find_last_of('\\');
if (index != std::string::npos)
{
filename_ = filename.substr(index + 1);
}
else
{
filename_ = filename;
}
log_type_ = logtype;
}
Logger::~Logger()
{
if (log_type_ == ELogType::E_LOG_OFF)
{
return;
}
static std::string strLogType[int(ELogType::E_LOG_OFF)] = { "DEBUG", "INFO", "WARN", "ERROR" };
// std::lock_guard<std::mutex> lock(g_mutex); // 虚构时自动解锁
g_mutex.lock();
//BACKGROUND代表背景FOREGROUND代表前景
//SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);//设置黄色(红色+绿色)
//SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
std::string text = oss_.str();
if (log_type_ == ELogType::E_LOG_DEBUG)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
//Spdlogger::debug(text.c_str());
}
else if (log_type_ == ELogType::E_LOG_INFO)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN);
//Spdlogger::info(text.c_str());
}
else if (log_type_ == ELogType::E_LOG_WARN)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN);
//Spdlogger::warn(text.c_str());
}
else if (log_type_ == ELogType::E_LOG_ERROR)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
//Spdlogger::error(text.c_str());
}
else
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
}
//std::cout << "[" << filename_ << ":" << line_ << "] [" << Utils::time_now_string_ms() << "][" << strLogType[int(log_type_)] << "] ";
std::cout << "[" << Utils::timeNowStrMS() << "][" << strLogType[int(log_type_)] << "] ";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
std::cout << "- " << text << std::endl << std::flush;
g_mutex.unlock();
}

38
src/common/Logger.h Normal file
View File

@@ -0,0 +1,38 @@
#ifndef _Logger_H_
#define _Logger_H_
#include <sstream>
#include <iostream>
#include <ostream>
#include <string>
class Logger
{
public:
enum class ELogType
{
E_LOG_DEBUG = 0,
E_LOG_INFO,
E_LOG_WARN,
E_LOG_ERROR,
E_LOG_OFF
};
public:
Logger(Logger::ELogType logType, std::string filename, int line);
~Logger();
std::stringstream& Stream() { return oss_; }
private:
std::stringstream oss_;
ELogType log_type_;
std::string filename_;
int line_;
};
#define XLOGD() Logger(Logger::ELogType::E_LOG_DEBUG, __FILE__, __LINE__).Stream()
#define XLOGI() Logger(Logger::ELogType::E_LOG_INFO, __FILE__, __LINE__).Stream()
#define XLOGW() Logger(Logger::ELogType::E_LOG_WARN, __FILE__, __LINE__).Stream()
#define XLOGE() Logger(Logger::ELogType::E_LOG_ERROR, __FILE__, __LINE__).Stream()
#endif

227
src/common/Snowflake.h Normal file
View File

@@ -0,0 +1,227 @@
#ifndef _JW_CORE_ID_WORKER_H_
#define _JW_CORE_ID_WORKER_H_
#include <mutex>
#include <atomic>
#include <chrono>
#include <exception>
#include <sstream>
#include <string>
// 如果不使用 mutex, 则开启下面这个定义, 但是我发现, 还是开启 mutex 功能, 速度比较快
// #define SNOWFLAKE_ID_WORKER_NO_LOCK
/**
* @brief 分布式id生成类
* https://segmentfault.com/a/1190000011282426
* https://github.com/twitter/snowflake/blob/snowflake-2010/src/main/scala/com/twitter/service/snowflake/IdWorker.scala
*
* 64bit id: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
* || || || | | |
* |└---------------------------时间戳--------------------------┘└中心-┘└机器-┘ └----序列号----┘
* |
* 不用
* SnowFlake的优点: 整体上按照时间自增排序, 并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分), 并且效率较高, 经测试, SnowFlake每秒能够产生26万ID左右.
*/
class Snowflake
{
public:
static Snowflake& instance()
{
static Snowflake sf;
return sf;
}
typedef unsigned int UInt;
typedef unsigned long long int UInt64;
#ifdef SNOWFLAKE_ID_WORKER_NO_LOCK
typedef std::atomic<UInt> AtomicUInt;
typedef std::atomic<UInt64> AtomicUInt64;
#else
typedef UInt AtomicUInt;
typedef UInt64 AtomicUInt64;
#endif
void set_worker_id(UInt workerId)
{
this->workerId = workerId;
}
void set_datacenter_id(UInt datacenterId)
{
this->datacenterId = datacenterId;
}
string nextIdStr()
{
return std::to_string(next_id());
}
/**
* 获得下一个ID (该方法是线程安全的)
*
* @return SnowflakeId
*/
UInt64 next_id()
{
#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK
std::unique_lock<std::mutex> lock {mutex};
AtomicUInt64 timestamp {0};
#else
static AtomicUInt64 timestamp {0};
#endif
timestamp = time_now_ms();
// 如果当前时间小于上一次ID生成的时间戳说明系统时钟回退过这个时候应当抛出异常
if (timestamp < lastTimestamp)
{
std::ostringstream s;
s << "clock moved backwards. Refusing to generate id for " << lastTimestamp - timestamp << " milliseconds";
throw std::exception(std::runtime_error(s.str()));
}
if (lastTimestamp == timestamp)
{
// 如果是同一时间生成的,则进行毫秒内序列
sequence = (sequence + 1) & sequenceMask;
if (0 == sequence)
{
// 毫秒内序列溢出, 阻塞到下一个毫秒,获得新的时间戳
timestamp = next_millis(lastTimestamp);
}
}
else
{
sequence = 0;
}
#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK
lastTimestamp = timestamp;
#else
lastTimestamp = timestamp.load();
#endif
// 移位并通过或运算拼到一起组成64位的ID
//return ((timestamp - twepoch) << timestampLeftShift)
// | (datacenterId << datacenterIdShift)
// | (workerId << workerIdShift)
// | sequence;
return ((timestamp - twepoch) << sequenceBits)
//| (datacenterId << datacenterIdShift)
//| (workerId << workerIdShift)
| sequence;
}
protected:
Snowflake() : workerId(0), datacenterId(0), sequence(0), lastTimestamp(0)
{
}
/**
* 返回以毫秒为单位的当前时间
*
* @return 当前时间(毫秒)
*/
UInt64 time_now_ms() const
{
//auto t = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now());
auto t = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
return t.time_since_epoch().count();
}
/**
* 阻塞到下一个毫秒,直到获得新的时间戳
*
* @param lastTimestamp 上次生成ID的时间截
* @return 当前时间戳
*/
UInt64 next_millis(UInt64 lastTimestamp) const
{
UInt64 timestamp = time_now_ms();
while (timestamp <= lastTimestamp)
{
timestamp = time_now_ms();
}
return timestamp;
}
private:
#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK
std::mutex mutex;
#endif
/**
* 开始时间截 (2010-01-01 00:00:00.000) 1262275200000
*/
const UInt64 twepoch = 1262275200000;
/**
* 机器id所占的位数
*/
const UInt workerIdBits = 5;
/**
* 数据中心id所占的位数
*/
const UInt datacenterIdBits = 5;
/**
* 序列所占的位数
*/
const UInt sequenceBits = 12;
/**
* 机器ID向左移12位
*/
const UInt workerIdShift = sequenceBits;
/**
* 数据标识id向左移17位
*/
const UInt datacenterIdShift = workerIdShift + workerIdBits;
/**
* 时间截向左移22位
*/
const UInt timestampLeftShift = datacenterIdShift + datacenterIdBits;
/**
* 支持的最大机器id结果是31
*/
const UInt maxWorkerId = -1 ^ (-1 << workerIdBits);
/**
* 支持的最大数据中心id结果是31
*/
const UInt maxDatacenterId = -1 ^ (-1 << datacenterIdBits);
/**
* 生成序列的掩码这里为4095
*/
const UInt sequenceMask = -1 ^ (-1 << sequenceBits);
/**
* 工作机器id(0~31)
*/
UInt workerId;
/**
* 数据中心id(0~31)
*/
UInt datacenterId;
/**
* 毫秒内序列(0~4095)
*/
AtomicUInt sequence {0};
/**
* 上次生成ID的时间截
*/
AtomicUInt64 lastTimestamp {0};
};
#endif // _JW_CORE_ID_WORKER_H_

115
src/common/TimeUtils.cpp Normal file
View File

@@ -0,0 +1,115 @@
#include "TimeUtils.h"
#include <chrono>
#include <sstream>
#include <iomanip>
int64_t TimeUtils::now()
{
// return std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
return std::chrono::time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now()).time_since_epoch().count();
}
int64_t TimeUtils::now_ms()
{
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
//return std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
}
std::string TimeUtils::now_datetime(char c1/* = '/'*/, char c2/* = ':'*/, char c3/* = ' '*/)
{
std::stringstream ss;
ss << "%Y" << c1 << "%m" << c1 << "%d" << c3 << "%H" << c2 << "%M" << c2 << "%S";
std::string fmt = ss.str();
ss.str("");
auto t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
ss << std::put_time(std::localtime(&t), fmt.c_str());
return ss.str();
}
std::string TimeUtils::now_date(char c1/* = '/'*/)
{
std::stringstream ss;
ss << "%Y" << c1 << "%m" << c1 << "%d";
std::string fmt = ss.str();
ss.str("");
auto t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
ss << std::put_time(std::localtime(&t), fmt.c_str());
return ss.str();
}
int64_t TimeUtils::datetime2ts(std::string s)
{
// YYYY-mm-dd HH:MM:SS
if (s.size() < 19) { return 0; }
s[4] = s[7] = '-';
s[10] = ' ';
s[13] = s[16] = ':';
std::tm t;
std::stringstream ss(s);
ss >> std::get_time(&t, "%Y-%m-%d %H:%M:%S");
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&t));
return std::chrono::duration_cast<std::chrono::seconds>(tp.time_since_epoch()).count();
}
int64_t TimeUtils::datetime2tms(std::string s)
{
if (s.size() < 19) { return 0; }
s[4] = s[7] = '-';
s[10] = ' ';
s[13] = s[16] = ':';
std::tm t;
std::stringstream ss(s);
ss >> std::get_time(&t, "%Y-%m-%d %H:%M:%S");
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&t));
return std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch()).count();
}
std::string TimeUtils::ts2datetime(int64_t ts, std::string fmt /*= "%Y-%m-%d %H:%M:%S"*/)
{
// std::localtime : 本地时区的时间
// std::gmtime : 格林威治时间
time_t t(ts);
std::stringstream ss;
ss << std::put_time(std::localtime(&t), fmt.c_str());
return ss.str();
}
std::string TimeUtils::ts2date(int64_t ts)
{
time_t t(ts);
std::stringstream ss;
ss << std::put_time(std::localtime(&t), "%Y-%m-%d");
return ss.str();
}
std::string TimeUtils::duration_str(int64_t t)
{
auto h = t / 3600;
auto m = (t % 3600) / 60;
auto s = (t % 3600) % 60;
std::string str = std::to_string(s) + "";
if (m > 0 || h > 0)
{
str = std::to_string(m) + "" + str;
}
if (h > 0)
{
str = std::to_string(h) + "小时" + str;
}
return str;
}
int64_t TimeUtils::tick(std::function<void()> func)
{
if (!func)
{
return 0;
}
auto start = std::chrono::steady_clock::now();
func();
auto end = std::chrono::steady_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
}

28
src/common/TimeUtils.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef _TimeUtils_H_
#define _TimeUtils_H_
#include <string>
#include <functional>
class TimeUtils
{
public:
static int64_t now();
static int64_t now_ms();
static std::string now_datetime(char c1 = '-', char c2 = ':', char c3 = ' ');
static std::string now_date(char c1 = '-');
static int64_t datetime2ts(std::string s);
static int64_t datetime2tms(std::string s);
static std::string ts2datetime(int64_t ts, std::string fmt = "%Y-%m-%d %H:%M:%S");
static std::string ts2date(int64_t ts);
static std::string duration_str(int64_t t);
static int64_t tick(std::function<void()> func);
};
#endif // !_TimeUtils_H_

429
src/common/Utils.cpp Normal file
View File

@@ -0,0 +1,429 @@
#include "Utils.h"
#include <thread>
#include <chrono>
#include <iostream>
using namespace std;
string Utils::toStr(int v)
{
return std::to_string(v);
}
string Utils::toStr(float v, int precision)
{
stringstream ss;
ss.precision(precision);
ss.setf(std::ios::fixed);
ss << v;
return ss.str();
}
string Utils::toStr(double v, int precision)
{
stringstream ss;
ss.precision(precision);
ss.setf(std::ios::fixed);
ss << v;
return ss.str();
}
int Utils::toInt(const std::string& str)
{
stringstream ss(str);
int ret = 0;
ss >> ret;
return ret;
}
float Utils::toFloat(const string& str)
{
stringstream ss(str);
float ret = 0.0f;
ss >> ret;
return ret;
}
double Utils::toDouble(const std::string& str)
{
stringstream ss(str);
double ret = 0.0;
ss >> ret;
return ret;
}
int64_t Utils::hexbinToInt(const string& str, bool swap/*=false*/)
{
int64_t v = 0;
for (size_t i = 0; i < str.size(); i++)
{
if (swap)
{
v = v + (str[str.size() - 1 - i] << (str.size() - 1 - i) * 8);
}
else
{
v = v + (str[i] << (str.size() - 1 - i) * 8);
}
}
return v;
}
int Utils::hexstrToInt(const std::string& str)
{
stringstream ss;
int ret;
ss << hex << str.c_str();
ss >> ret;
return ret;
}
#include <iostream>
string Utils::from_hex_text(string s)
{
vector<unsigned char> result;
string tmp;
stringstream ss;
int v;
for (auto ch : s)
{
if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'))
{
tmp += ch;
if (tmp.size() == 2)
{
ss.clear();
ss.str("");
ss << hex << tmp;
ss >> v;
result.emplace_back((unsigned char)v);
tmp.clear();
}
}
}
return string(result.begin(), result.end());
}
//string Utils::fromHexText1(string s)
//{
// vector<unsigned char> result;
// string tmp = s;
// stringstream ss;
// int v;
// size_t pos = 0;
// while (!tmp.empty())
// {
// if (pos >= tmp.size()) {
// ss.clear();
// ss.str("");
// ss << hex << tmp;
// ss >> v;
// result.emplace_back((unsigned char)v);
// tmp = "";
// break;
// }
// auto& ch = tmp[pos];
// bool flag = (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F');
// if (!flag) {
// ss.clear();
// ss.str("");
// ss << hex << tmp.substr(0, pos);
// ss >> v;
// tmp = tmp.substr(pos + 1);
// result.emplace_back((unsigned char)v);
// pos = 0;
// }
// ++pos;
// }
// return string(result.begin(), result.end());
//}
string Utils::to_hex_text(string s, string d/* = " "*/)
{
stringstream ss;
for (unsigned int i = 0; i < s.size(); ++i)
{
unsigned char ch = s[i];
ss << std::setw(2) << std::setfill('0') << std::hex << std::uppercase << (int)ch << ((i < s.size() - 1) ? d : "");
}
return ss.str();
}
void time_point_to_duration()
{
auto tp = std::chrono::system_clock::now();
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(tp.time_since_epoch());
cout << seconds.count() << " s" << endl;//seconds from 1970
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
cout << ms.count() << " ms" << endl;
auto us = std::chrono::duration_cast<std::chrono::microseconds>(tp.time_since_epoch());
cout << us.count() << " us" << endl;
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(tp.time_since_epoch());
cout << ns.count() << " ns" << endl;
cout << tp.time_since_epoch().count() << " default is ns" << endl;
}
void duration_to_time_point()
{
std::uint64_t ticker = 1609756793160376465;
auto ns = std::chrono::nanoseconds(ticker);
auto tp1 = std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>(ns);
auto tp2 = tp1 - std::chrono::hours(1);//time point before one hour
cout << "tp1=" << tp1.time_since_epoch().count() << endl << "tp2=" << tp2.time_since_epoch().count() << endl;
}
void format_time_point()
{
auto tp = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(tp);
std::stringstream ss;
ss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S");
cout << ss.str() << endl;
}
void parse_from_string()
{
std::stringstream ss;
ss << "2021-01-06 18:47:35";
std::tm tm{};
ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S");
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));
cout << tp.time_since_epoch().count() << endl;
}
int64_t Utils::timeNow()
{
// return std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
return std::chrono::time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now()).time_since_epoch().count();
}
int64_t Utils::timeNowMS()
{
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
//return std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
}
string Utils::timeNowStr(std::string fmt /*= "%Y-%m-%dT%H:%M:%S"*/)
{
auto t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
std::stringstream ss;
ss << std::put_time(std::localtime(&t), fmt.c_str());
return ss.str();
}
string Utils::timeNowStrMS(std::string fmt /*= "%Y-%m-%dT%H:%M:%S"*/)
{
auto tpNow = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(tpNow);
std::stringstream ss;
ss << std::put_time(std::localtime(&time), fmt.c_str());
auto tms = std::chrono::duration_cast<std::chrono::milliseconds>(tpNow.time_since_epoch());
auto tseconds = std::chrono::duration_cast<std::chrono::seconds>(tpNow.time_since_epoch());
ss << "." << std::setfill('0') << std::setw(3) << (tms - tseconds).count();
return ss.str();
}
string Utils::timeStr(int64_t ts, std::string fmt /*= "%Y-%m-%d %H:%M:%S"*/)
{
// std::localtime : 本地时区的时间
// std::gmtime : 格林威治时间
time_t t(ts);
std::stringstream ss;
ss << std::put_time(std::localtime(&t), fmt.c_str());
return ss.str();
}
string Utils::time_to_string(int64_t dt, std::string fmt /*= "%Y-%m-%d %H:%M:%S"*/)
{
auto ms = std::chrono::milliseconds(dt);
auto tp = std::chrono::time_point<std::chrono::system_clock>(ms);
time_t t = std::chrono::system_clock::to_time_t(tp);
std::stringstream ss;
ss << std::put_time(std::localtime(&t), fmt.c_str());
return ss.str();
}
// 2023-12-12 12:12:12
int64_t Utils::time(string dt, int zone)
{
if (dt.empty())
{
return std::chrono::time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now()).time_since_epoch().count();
}
else
{
static string FMT_D = "yyyy-MM-dd";
static string FMT_DT = "yyyy-MM-dd HH:mm:ss";
static string FMT_DS = "yyyy-MM-dd HH:mm:ss.SSS";
string fmt;
if (dt.size() == FMT_D.size())
{
fmt = "%Y-%m-%d";
dt[4] = dt[7] = '-';
}
else if (dt.size() == FMT_DT.size())
{
fmt = "%Y-%m-%d %H:%M:%S";
dt[4] = dt[7] = '-';
dt[10] = ' ';
dt[13] = dt[16] = ':';
}
else if (dt.size() == FMT_DT.size())
{
}
else
{
return -1;
}
stringstream ss(dt);
std::tm t {};
ss >> std::get_time(&t, fmt.c_str());
t.tm_hour += zone;
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&t));
return std::chrono::duration_cast<std::chrono::seconds>(tp.time_since_epoch()).count();
//return std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch()).count();
}
}
bool Utils::time_string_to_tm(string dt, std::tm& t)
{
t.tm_year = 1900;
t.tm_mon = 1;
t.tm_mday = 1;
static string FORMAT_D = "yyyy-mm-dd";
static string FORMAT_DT = "yyyy-mm-dd HH:MM:SS";
string fmt;
if (dt.size() == FORMAT_D.size())
{
fmt = "%Y-%m-%d";
dt[4] = dt[7] = '-';
}
else if (dt.size() >= FORMAT_DT.size())
{
fmt = "%Y-%m-%d %H:%M:%S";
dt[4] = dt[7] = '-';
dt[10] = ' ';
dt[13] = dt[16] = ':';
}
else
{
return false;
}
stringstream ss;
ss << dt;
ss >> std::get_time(&t, fmt.c_str());
t.tm_year += 1900;
t.tm_mon += 1;
return true;
}
void Utils::sleep_ms(int ms)
{
// 计算时间间隔:
//auto start = std::chrono::high_resolution_clock::now();
//auto end = std::chrono::high_resolution_clock::now();
//std::chrono::duration<double, std::milli> elapsed = end - start;
//int64_t t = elapsed.count();
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}
#include <Windows.h>
unsigned short Utils::crc16(unsigned char* data, unsigned int len)
{
if (data == NULL || len == 0)
{
return 0;
}
unsigned short crc = 0xffff;
unsigned short FACTOR = 0xa001;
for (int i = 0; i < len; i++)
{
crc ^= data[i];
for (int j = 0; j < 8; j++)
{
if ((crc & 0x0001) != 0)
{
crc >>= 1;
crc ^= FACTOR;
}
else
{
crc >>= 1;
}
}
}
//(unsigned char)(CRC & 0x00ff);
//(unsigned char)(CRC >> 8);
return crc;
}
string Utils::gbkToUtf8(string s)
{
int n = MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, NULL, 0);
WCHAR* str1 = new WCHAR[n];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, str1, n);
n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
vector<char> s_utf8(n, 0);
WideCharToMultiByte(CP_UTF8, 0, str1, -1, &s_utf8[0], n, NULL, NULL);
delete[]str1;
str1 = NULL;
return string(s_utf8.begin(), s_utf8.end());
}
string Utils::utf8ToGbk(string s)
{
string s_gbk = "";
int n = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0);
WCHAR* str1 = new WCHAR[n];
MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, str1, n);
n = WideCharToMultiByte(CP_ACP, 0, str1, -1, NULL, 0, NULL, NULL);
char* str2 = new char[n];
WideCharToMultiByte(CP_ACP, 0, str1, -1, str2, n, NULL, NULL);
s_gbk = str2;
delete[] str1;
str1 = NULL;
delete[] str2;
str2 = NULL;
return s_gbk;
}
#include <random>
int Utils::random(int min, int max)
{
//生成 a 到 b 之间(包含)均匀分布的随机数
uniform_int_distribution<unsigned> rand_u(min, max);
static default_random_engine rand_e; // 生成无符号随机整数
return rand_u(rand_e);
}
void Utils::split(string buf, string c, vector<string>& res)
{
if (buf.size() == 0 || c.size() == 0)
{
return;
}
string tmp = buf;
while (true)
{
auto pos = tmp.find(c);
if (pos == string::npos)
{
res.push_back(tmp);
break;
}
res.push_back((pos == 0) ? "" : tmp.substr(0, pos));
tmp = tmp.substr(pos + c.size());
}
}

111
src/common/Utils.h Normal file
View File

@@ -0,0 +1,111 @@
#ifndef _Utils_H_
#define _Utils_H_
#include <vector>
#include <string>
#include <sstream>
#include <string.h>
#include <iomanip>
#include <functional>
#include <thread>
//#include "Crypto.h"
using namespace std;
class Utils
{
public:
static string toStr(int v);
static string toStr(float v, int precision = 2);
static string toStr(double v, int precision = 2);
static int toInt(const std::string& str);
static float toFloat(const string& str);
static double toDouble(const string& str);
static int64_t hexbinToInt(const string& str, bool swap = false);
static int hexstrToInt(const string& str);
static string from_hex_text(string s);
static string to_hex_text(string s, string d = " ");
template<typename T>
static void append_bytes(vector<unsigned char>& dest, const T& src, int len)
{
int start = static_cast<int>(dest.size());
dest.resize(start + len);
memcpy_s(&dest[start], len, &src, len);
}
static int64_t timeNow();
static int64_t timeNowMS();
static string timeNowStr(std::string fmt = "%Y-%m-%d %H:%M:%S");
static string timeNowStrMS(std::string fmt = "%Y-%m-%d %H:%M:%S");
static string timeStr(int64_t ts, std::string fmt = "%Y-%m-%d %H:%M:%S");
static int64_t time(string dt="", int zone = 0);
static string time_to_string(int64_t dt, std::string fmt="%Y-%m-%d %H:%M:%S");
static bool time_string_to_tm(string dt, std::tm& t);
std::string duration_str(int64_t t)
{
auto h = t / 3600;
auto m = (t % 3600) / 60;
auto s = (t % 3600) % 60;
std::string str = std::to_string(s) + "";
if (m > 0 || h > 0)
{
str = std::to_string(m) + "" + str;
}
if (h > 0)
{
str = std::to_string(h) + "小时" + str;
}
return str;
}
static unsigned short crc16(unsigned char* data, unsigned int len);
static string Utils::gbkToUtf8(string s);
static string Utils::utf8ToGbk(string s);
static void sleep_ms(int ms);
static int random(int min, int max);
static void split(string buf, string c, vector<string>& res);
};
class TimeTick
{
public:
int64_t tickMS_ = 0;
TimeTick()
{
tickMS_ = Utils::timeNowMS();
}
bool elapse(int64_t ms, bool reset = true)
{
auto tick_now = Utils::timeNowMS();
bool res = tick_now - tickMS_ > ms;
if (res && reset)
{
tickMS_ = tick_now;
}
return res;
}
void reset()
{
tickMS_ = Utils::timeNowMS();
}
};
#endif // !!! _Utils_H_