mirror of
https://gitee.com/js-yhsec/energy_storage.git
synced 2026-05-28 03:09:24 +08:00
上传项目代码
This commit is contained in:
197
src/common/DataFields.cpp
Normal file
197
src/common/DataFields.cpp
Normal 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
149
src/common/DataFields.h
Normal 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
71
src/common/Logger.cpp
Normal 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
38
src/common/Logger.h
Normal 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
227
src/common/Snowflake.h
Normal 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
115
src/common/TimeUtils.cpp
Normal 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
28
src/common/TimeUtils.h
Normal 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
429
src/common/Utils.cpp
Normal 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
111
src/common/Utils.h
Normal 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_
|
||||
Reference in New Issue
Block a user