remove:不使用boost filesystem.

This commit is contained in:
taynpg 2025-05-18 00:25:33 +08:00
parent 15085a1f8f
commit 655cfe6fad
21 changed files with 393 additions and 272 deletions

View File

@ -1,6 +1,6 @@
{
"files.autoSave": "onFocusChange",
"editor.fontSize": 13,
"editor.fontSize": 14,
"editor.fontFamily": "'Monaspace Krypton Light', 'Monaspace Krypton Light', 'Monaspace Krypton Light'",
"terminal.integrated.fontFamily": "Monaspace Krypton Light",
"cmake.configureOnOpen": true,

View File

@ -20,12 +20,7 @@ add_compile_options(-finput-charset=utf-8)
add_compile_options(-fexec-charset=gbk)
add_compile_options(-Wa,-mbig-obj)
set(COMPILER_ID "mingw")
endif()
if(DEFINED USE_BOOST)
message(STATUS "use boost library ${USE_BOOST}")
add_definitions(-DUSE_BOOST)
include(config/MBoost.cmake)
include(config/Mingw.cmake)
endif()
string(TOLOWER ${COMPILER_ID} COMPILER_ID)
@ -70,6 +65,19 @@ else()
add_subdirectory(http-server)
endif()
if(WIN32)
execute_process(COMMAND cmd /c ver
OUTPUT_VARIABLE VER_OUTPUT
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(VER_OUTPUT MATCHES "XP")
message(STATUS "Windows XP platform.")
add_definitions(-D_WIN32_WINNT=0x0501)
else()
message(STATUS "Windows NT platform.")
add_definitions(-D_WIN32_WINNT=0x0601)
endif()
endif()
if (DEFINED USE_TRANSM_TEST)
message(STATUS "USE USE_TRANSM_TEST ${USE_TRANSM_TEST}")
add_definitions(-DUSE_TRANSM_TEST)
@ -104,13 +112,9 @@ else()
install(TARGETS tss-http DESTINATION bin)
endif()
if (DEFINED USE_BOOST)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_SYSTEM_NAME MATCHES "Windows")
install(FILES ${MINGW32_DLLS} DESTINATION bin)
endif()
if (DEFINED USE_GUI)
message(STATUS "USE GUI ${USE_GUI}")
#add_subdirectory(gui)
endif()
# ********************************************************** pack infomation
if(CMAKE_SIZEOF_VOID_P EQUAL 8)

View File

@ -6,11 +6,6 @@ set(CMAKE_CXX_STANDARD 17)
if (MSVC)
add_compile_options(/source-charset:utf-8)
endif()
if(DEFINED USE_BOOST)
message(STATUS "tsc use boost lib.")
include_directories(${MBOOST_INCLUDE_DIR})
link_directories(${MBOOST_LIB_DIR})
endif()
add_executable(tsc main.cpp client.h client.cpp config.h config.cpp)
target_link_libraries(tsc PRIVATE trans_net trans_util filecomplete)
@ -20,10 +15,7 @@ endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_SYSTEM_NAME MATCHES "Windows")
target_link_libraries(tsc PRIVATE ws2_32 wsock32)
endif()
if(DEFINED USE_BOOST)
target_link_directories(tsc PRIVATE ${MBOOST_LIB_DIR})
target_link_libraries(tsc PRIVATE ${MBOOST_LIBS})
endif()
if (DEFINED GRAB_CRASH)
message(STATUS "tsc link crashelper")
target_link_libraries(tsc PRIVATE crashelper)

View File

@ -1,19 +1,13 @@
#include "client.h"
#include <filesystem>
#include <fstream>
#include <iostream>
#include <of_path.h>
#include <of_str.h>
#include <of_util.h>
#include <version.h>
#ifdef USE_BOOST
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
#else
#include <filesystem>
namespace fs = std::filesystem;
#endif
TransmClient::TransmClient() : msg_info_("")
{
@ -126,7 +120,8 @@ void TransmClient::print_help(bool detail)
TLOGI("{}", sp);
}
bool TransmClient::base_init(const std::string& ip, const std::string& port, const std::string& config_dir)
bool TransmClient::base_init(const std::string& ip, const std::string& port,
const std::string& config_dir)
{
fs::path fp(config_dir);
config_path_ = fp.append("history.txt").string();
@ -158,7 +153,8 @@ bool TransmClient::base_init(const std::string& ip, const std::string& port, con
return true;
}
void TransmClient::run(const std::string& ip, const std::string& port, const std::string& config_dir)
void TransmClient::run(const std::string& ip, const std::string& port,
const std::string& config_dir)
{
if (!base_init(ip, port, config_dir)) {
return;
@ -178,7 +174,8 @@ void TransmClient::run(const std::string& ip, const std::string& port, const std
break;
}
if (!th_run_ || !client_->is_normal()) {
TLOGW("The link has been closed and cannot be continued. It will automatically exit.");
TLOGW("The link has been closed and cannot be continued. It will "
"automatically exit.");
break;
}
std::string cmd_input(readline);
@ -222,11 +219,13 @@ void TransmClient::run(const std::string& ip, const std::string& port, const std
TLOGD("At => {}", COfPath::to_full("."));
continue;
}
if (cmd_input == "Get" || cmd_input == "get" || cmd_input == "g" || cmd_input == "G") {
if (cmd_input == "Get" || cmd_input == "get" || cmd_input == "g" ||
cmd_input == "G") {
get_clients();
continue;
}
if (cmd_input == "Clear" || cmd_input == "clear" || cmd_input == "c" || cmd_input == "C") {
if (cmd_input == "Clear" || cmd_input == "clear" || cmd_input == "c" ||
cmd_input == "C") {
cmd_clear_submited();
continue;
}
@ -274,7 +273,8 @@ void TransmClient::run(const std::string& ip, const std::string& port, const std
}
#ifdef USE_TRANSM_TEST
bool TransmClient::connect_for_test(const std::string& ip, const std::string& port,
bool TransmClient::connect_for_test(const std::string& ip,
const std::string& port,
const std::string& config_dir)
{
if (!base_init(ip, port, config_dir)) {
@ -384,7 +384,8 @@ bool TransmClient::cmd_sub_list(const std::string& param)
{
std::lock_guard<std::mutex> lock(mutex_);
for (const auto& item : up_) {
if (item.second->trans_state_ == TRANS_REDAY || item.second->trans_state_ == TRANS_ING) {
if (item.second->trans_state_ == TRANS_REDAY ||
item.second->trans_state_ == TRANS_ING) {
TLOGW("Have Task Upping, Please wait!");
return false;
}
@ -436,7 +437,8 @@ bool TransmClient::cmd_clear_submited()
{
std::lock_guard<std::mutex> lock(mutex_);
for (const auto& item : up_) {
if (item.second->trans_state_ == TRANS_REDAY || item.second->trans_state_ == TRANS_ING) {
if (item.second->trans_state_ == TRANS_REDAY ||
item.second->trans_state_ == TRANS_ING) {
TLOGW("Have Task Upping, Please wait!");
return false;
}
@ -520,13 +522,15 @@ bool TransmClient::cmd_upload_files(const std::string& param)
return true;
}
bool TransmClient::down_one_file(int remote_id, const std::string& file, const std::string& local_dir)
bool TransmClient::down_one_file(int remote_id, const std::string& file,
const std::string& local_dir)
{
std::string ret_id{};
std::string ret_uuid{};
if (clients_.count(remote_id) == 0) {
TLOGW("{} No Index Found {}, Try {}", __LINE__, remote_id, list_server_id_);
TLOGW("{} No Index Found {}, Try {}", __LINE__, remote_id,
list_server_id_);
ret_id = list_server_id_;
ret_uuid = list_server_uuid_;
} else {
@ -541,13 +545,17 @@ bool TransmClient::down_one_file(int remote_id, const std::string& file, const s
if (local_dir.empty()) {
down_->cur_file_ = COfPath::to_full(remote_file.filename().string());
} else {
down_->cur_file_ = fs::path(local_dir).append(remote_file.filename().string()).string();
down_->cur_file_ = fs::path(local_dir)
.append(remote_file.filename().string())
.string();
}
// 这里要先检查羁绊
if (ret_uuid == uuid_ && COfPath::is_same_dir(remote_file.string(), down_->cur_file_)) {
if (ret_uuid == uuid_ &&
COfPath::is_same_dir(remote_file.string(), down_->cur_file_)) {
// 处在同一个机器上的同目录下
TLOGE("You Can't Operate File In Same Dir And In Same Machine.", down_->cur_remote_file_);
TLOGE("You Can't Operate File In Same Dir And In Same Machine.",
down_->cur_remote_file_);
return false;
}
@ -565,7 +573,8 @@ bool TransmClient::down_one_file(int remote_id, const std::string& file, const s
msg_info.str = file;
serialize(msg_info, &buf->data_, buf->len_);
if (!send_frame(buf.get())) {
TLOGE("{} request open file [{}] send failed.", __FUNCTION__, down_->cur_remote_file_);
TLOGE("{} request open file [{}] send failed.", __FUNCTION__,
down_->cur_remote_file_);
down_->cur_remote_id_.clear();
down_->cur_remote_file_.clear();
return false;
@ -575,7 +584,8 @@ bool TransmClient::down_one_file(int remote_id, const std::string& file, const s
cur_down_size_ = 0;
float percent = 0.0;
fc_disable_cur();
while (down_->trans_state_ != TRANS_DONE && down_->trans_state_ != TRANS_FAILED) {
while (down_->trans_state_ != TRANS_DONE &&
down_->trans_state_ != TRANS_FAILED) {
std::this_thread::sleep_for(std::chrono::milliseconds(down_check_wait));
if (cur_file_size_ > 0) {
percent = (float)cur_down_size_ / cur_file_size_;
@ -593,7 +603,8 @@ bool TransmClient::down_one_file(int remote_id, const std::string& file, const s
}
fc_enable_cur();
if (cur_down_size_ > 0 && cur_file_size_ == cur_down_size_) {
TLOGW("down one file success, total:[{}/{}]", cur_down_size_, cur_file_size_);
TLOGW("down one file success, total:[{}/{}]", cur_down_size_,
cur_file_size_);
return true;
} else {
TLOGW("down one file {} failed, size not matched.", down_->cur_file_);
@ -754,8 +765,8 @@ bool TransmClient::cmd_sub_task(const std::string& param, bool is_send)
return true;
}
bool TransmClient::variable_and_parse_files(const std::string& content,
std::map<std::string, std::string>& files)
bool TransmClient::variable_and_parse_files(
const std::string& content, std::map<std::string, std::string>& files)
{
auto vec = COfStr::split(content, "\n");
bool valid = true;
@ -781,7 +792,8 @@ bool TransmClient::variable_and_parse_files(const std::string& content,
return valid;
}
bool TransmClient::down_update_file(const std::map<std::string, std::string>& files)
bool TransmClient::down_update_file(
const std::map<std::string, std::string>& files)
{
std::shared_ptr<CFrameBuffer> buf = std::make_shared<CFrameBuffer>();
buf->tid_ = list_server_id_;
@ -813,7 +825,8 @@ bool TransmClient::down_update_file(const std::map<std::string, std::string>& fi
return suc;
}
bool TransmClient::get_dir_files(const std::string& dir, std::string& out, std::string& error)
bool TransmClient::get_dir_files(const std::string& dir, std::string& out,
std::string& error)
{
fs::path p(dir);
out.clear();
@ -872,7 +885,8 @@ bool TransmClient::cmd_down_list(const std::string& param)
}
int index = std::stoi(tvec[0]);
std::string lists = tvec[1];
std::string local = tvec.size() > 2 ? COfPath::to_full(tvec[2]) : COfPath::to_full("");
std::string local =
tvec.size() > 2 ? COfPath::to_full(tvec[2]) : COfPath::to_full("");
if (!clients_.count(index)) {
TLOGE("{} No Index Found {}.", __LINE__, index);
@ -1214,10 +1228,12 @@ void TransmClient::handle_frame(CFrameBuffer* buf)
std::lock_guard<std::mutex> lock(mutex_);
up_[buf->fid_] = std::make_shared<TransInfomation>();
up_[buf->fid_]->cur_file_ = msg_info.str;
up_[buf->fid_]->file_.open(up_[buf->fid_]->cur_file_, std::ios::in | std::ios::binary);
up_[buf->fid_]->file_.open(up_[buf->fid_]->cur_file_,
std::ios::in | std::ios::binary);
up_[buf->fid_]->trans_state_ = TRANS_REDAY;
if (!up_[buf->fid_]->file_.is_open()) {
TLOGE("Ready Send File {} Open Failed.", up_[buf->fid_]->cur_file_);
TLOGE("Ready Send File {} Open Failed.",
up_[buf->fid_]->cur_file_);
buf->type_ = TYPE_OPEN_FAILED;
std::swap(buf->tid_, buf->fid_);
if (!send_frame(buf)) {
@ -1229,7 +1245,8 @@ void TransmClient::handle_frame(CFrameBuffer* buf)
keys = buf->fid_;
}
if (!keys.empty()) {
ths_.emplace_back([this, keys]() { send_file_data_th(keys.c_str()); });
ths_.emplace_back(
[this, keys]() { send_file_data_th(keys.c_str()); });
}
break;
}
@ -1320,7 +1337,8 @@ void TransmClient::handle_frame(CFrameBuffer* buf)
if (update_list_th_.joinable()) {
update_list_th_.join();
}
update_list_th_ = std::thread([this, files]() { down_update_file(files); });
update_list_th_ =
std::thread([this, files]() { down_update_file(files); });
break;
}
case TYPE_CONFIRM_UPDATE_LIST: {
@ -1346,7 +1364,8 @@ void TransmClient::handle_frame(CFrameBuffer* buf)
break;
}
case TYPE_BUSY_UPDATE_LIST: {
TLOGI("remote {} are busy, will not exec task {}", buf->fid_, list_file_);
TLOGI("remote {} are busy, will not exec task {}", buf->fid_,
list_file_);
break;
}
case TYPE_FILE_INFO: {
@ -1371,7 +1390,8 @@ void TransmClient::handle_frame(CFrameBuffer* buf)
break;
}
default:
TLOGE("UnSupport Type {}, Current Version v{}", static_cast<int>(buf->type_), VERSION_NUM);
TLOGE("UnSupport Type {}, Current Version v{}",
static_cast<int>(buf->type_), VERSION_NUM);
break;
}
}
@ -1419,8 +1439,8 @@ void TransmClient::send_file_data_th(const char* keys)
#endif
std::string info_result = plat + "," + str_size + "," + str_perm;
TLOGI("To {} File Size: {} [{}], permissions:{}", str_key, ofen::OfUtil::get_file_size(size), size,
str_perm);
TLOGI("To {} File Size: {} [{}], permissions:{}", str_key,
ofen::OfUtil::get_file_size(size), size, str_perm);
msg_info.str = info_result;
serialize(msg_info, &buf->data_, buf->len_);
if (!send_frame(buf.get())) {
@ -1493,13 +1513,15 @@ void TransmClient::judget_down_active()
}
}
std::string TransmClient::variable_handle(const std::string& task_list_path, const std::string& source,
std::string TransmClient::variable_handle(const std::string& task_list_path,
const std::string& source,
bool is_local)
{
std::string result(source);
// 支持的变量如下:
// ${HOME} 用户目录(发送端接收端均支持)
// ${CURRENT} 任务文件所在目录(该变量仅支持发送端,因为接收端没有任务文件所在路径)
// ${CURRENT}
// 任务文件所在目录(该变量仅支持发送端,因为接收端没有任务文件所在路径)
if (is_local && source.find("${HOME}") != std::string::npos) {
result = COfStr::replace(result, "${HOME}", COfPath::get_home());
}
@ -1514,7 +1536,8 @@ std::string TransmClient::variable_handle(const std::string& task_list_path, con
return result;
}
std::string TransmClient::handle_user_select(const std::unordered_map<int, std::string>& source, bool is_send)
std::string TransmClient::handle_user_select(
const std::unordered_map<int, std::string>& source, bool is_send)
{
std::string handled_content{};
std::string input{};
@ -1558,11 +1581,13 @@ std::string TransmClient::handle_user_select(const std::unordered_map<int, std::
handled_content.append(source.at(key) + "\n");
} else {
// 如果mre中没有这个key
TLOGE("Invalid input, please enter valid numbers or '0' for all.");
TLOGE("Invalid input, please enter valid numbers or "
"'0' for all.");
break;
}
} catch (const std::exception& e) {
TLOGE("Invalid input, please enter valid numbers or '0' for all.");
TLOGE("Invalid input, please enter valid numbers or '0' "
"for all.");
break;
}
}
@ -1578,7 +1603,8 @@ CFileOpr::CFileOpr() = default;
CFileOpr::~CFileOpr() = default;
bool CFileOpr::get_file_list(const std::string& input, std::vector<std::string>& out)
bool CFileOpr::get_file_list(const std::string& input,
std::vector<std::string>& out)
{
out.clear();
auto backup = COfStr::trim(input);
@ -1600,14 +1626,17 @@ bool CFileOpr::get_file_list(const std::string& input, std::vector<std::string>&
}
#endif
if (ret.find("?") != std::string::npos || ret.find("*") != std::string::npos) {
if (ret.find("?") != std::string::npos ||
ret.find("*") != std::string::npos) {
auto fv = COfPath::match_files(ret);
for (const auto& v : fv) {
TLOGI("match file: {}", v);
}
std::string cof;
while (true) {
TLOGI("Detected regex's file (num = {}), please confirm if it is correct? ", fv.size());
TLOGI("Detected regex's file (num = {}), please confirm if it "
"is correct? ",
fv.size());
TLOGW("support input in [y,Y,end]", fv.size());
std::getline(std::cin, cof);
if (cof == "y" || cof == "Y") {

View File

@ -45,7 +45,8 @@ public:
~TransmClient();
public:
void run(const std::string& ip, const std::string& port, const std::string& config_dir);
void run(const std::string& ip, const std::string& port,
const std::string& config_dir);
bool get_clients();
bool cmd_fetch_files(const std::string& param);
bool cmd_sub_list(const std::string& param);
@ -56,11 +57,14 @@ public:
bool cmd_down_list(const std::string& param);
private:
bool variable_and_parse_files(const std::string& content, std::map<std::string, std::string>& files);
bool variable_and_parse_files(const std::string& content,
std::map<std::string, std::string>& files);
bool down_update_file(const std::map<std::string, std::string>& files);
bool get_dir_files(const std::string& dir, std::string& out, std::string& error);
bool get_dir_files(const std::string& dir, std::string& out,
std::string& error);
void report_trans_ret(TransState state, const std::string& key = "");
bool down_one_file(int remote_id, const std::string& file, const std::string& local_dir = "");
bool down_one_file(int remote_id, const std::string& file,
const std::string& local_dir = "");
private:
bool send_frame(CFrameBuffer* buf);
@ -71,15 +75,19 @@ private:
std::string read_uuid();
void get_id();
void print_help(bool detail);
bool base_init(const std::string& ip, const std::string& port, const std::string& config_dir);
bool base_init(const std::string& ip, const std::string& port,
const std::string& config_dir);
private:
void handle_frame(CFrameBuffer* buf);
void send_file_data_th(const char* keys);
void hearts();
void judget_down_active();
std::string variable_handle(const std::string& task_list_path, const std::string& source, bool is_local);
std::string handle_user_select(const std::unordered_map<int, std::string>& source, bool is_send);
std::string variable_handle(const std::string& task_list_path,
const std::string& source, bool is_local);
std::string
handle_user_select(const std::unordered_map<int, std::string>& source,
bool is_send);
private:
std::mutex mutex_;
@ -122,7 +130,8 @@ public:
};
public:
bool connect_for_test(const std::string& ip, const std::string& port, const std::string& config_dir);
bool connect_for_test(const std::string& ip, const std::string& port,
const std::string& config_dir);
void disconnect_for_test();
int test_index_by_id(const std::string& id);
std::string test_get_own_id() const;
@ -141,5 +150,6 @@ public:
~CFileOpr();
public:
static bool get_file_list(const std::string& input, std::vector<std::string>& out);
static bool get_file_list(const std::string& input,
std::vector<std::string>& out);
};

View File

@ -1,14 +1,8 @@
#include "config.h"
#include <cassert>
#ifdef USE_BOOST
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
#else
#include <filesystem>
namespace fs = std::filesystem;
#endif
ClientConfig::ClientConfig()
{
@ -59,7 +53,8 @@ bool ClientConfig::read_ini(std::vector<TransmSet>& set)
return true;
}
long ClientConfig::have_ini(const std::vector<TransmSet>& set, const std::string& ip, long port)
long ClientConfig::have_ini(const std::vector<TransmSet>& set,
const std::string& ip, long port)
{
long id = -1;
for (const auto& item : set) {
@ -78,13 +73,15 @@ bool ClientConfig::write_ini(const std::vector<TransmSet>& set)
std::string key = "GROUP" + std::to_string(start);
ini_handle_.SetValue(key.c_str(), "IP", set[start].ip.c_str());
ini_handle_.SetLongValue(key.c_str(), "PORT", set[start].port);
ini_handle_.SetValue(key.c_str(), "COMMENT", set[start].comment.c_str());
ini_handle_.SetValue(key.c_str(), "COMMENT",
set[start].comment.c_str());
}
ini_handle_.SaveFile(config_path_.c_str());
return true;
}
long ClientConfig::append_ini(const std::string& ip, long port, const std::string& comment)
long ClientConfig::append_ini(const std::string& ip, long port,
const std::string& comment)
{
assert(init_ == true);
long id = -1;
@ -116,15 +113,17 @@ bool ClientConfig::remove_ini(long num)
if (!read_ini(set)) {
return false;
}
set.erase(
std::remove_if(set.begin(), set.end(), [&num](const TransmSet& item) { return item.grp_id == num; }),
set.end());
set.erase(std::remove_if(
set.begin(), set.end(),
[&num](const TransmSet& item) { return item.grp_id == num; }),
set.end());
ini_handle_.Reset();
ini_handle_.SetLongValue("BASE", "GROUPS", static_cast<long>(set.size()));
return write_ini(set);
}
bool ClientConfig::get_ini(const std::vector<TransmSet>& set, long num, TransmSet& use)
bool ClientConfig::get_ini(const std::vector<TransmSet>& set, long num,
TransmSet& use)
{
bool find = false;
for (const auto& item : set) {
@ -154,7 +153,8 @@ bool ClientConfig::save_last_use(const std::string& ip, long port)
bool ClientConfig::get_last_use(std::string& ip, long& port)
{
assert(init_ == true);
if (!ini_handle_.KeyExists("Base", "LastUseIP") || !ini_handle_.KeyExists("Base", "LastUsePort")) {
if (!ini_handle_.KeyExists("Base", "LastUseIP") ||
!ini_handle_.KeyExists("Base", "LastUsePort")) {
TLOGE("Not Found Last Use Record.");
return false;
}

View File

@ -17,36 +17,40 @@
#endif
#if defined(GRAB_CRASH)
#ifdef USE_BOOST
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
#else
#include <filesystem>
namespace fs = std::filesystem;
#endif
#include <crashelper.h>
#endif
std::shared_ptr<ClientConfig> g_Config = nullptr;
int parse_cmd(int argc, char** argv, CmdParam& param)
{
std::string intro(fmt::format("tsc cmd introduce, version: {}\nopensource: {}", VERSION_NUM, VERSION_URL));
std::string intro(
fmt::format("tsc cmd introduce, version: {}\nopensource: {}",
VERSION_NUM, VERSION_URL));
CLI::App app(intro);
app.add_option("-u, --use", param.use_config, "使用服务器地址组(值为使用--show中显示的序号)");
app.add_option("-a, --append", param.appendValue, "添加服务器地址组(地址格式:127.0.0.1:9898:注释)");
app.add_option("-u, --use", param.use_config,
"使用服务器地址组(值为使用--show中显示的序号)");
app.add_option("-a, --append", param.appendValue,
"添加服务器地址组(地址格式:127.0.0.1:9898:注释)");
app.add_flag("-s, --show", param.showValue, "查看服务器地址组");
app.add_option("-r, --remove", param.removeValue, "移除服务器地址组(值为使用--show中显示的序号)");
app.add_flag("-d, --direct", param.direct_use, "添加服务器时直接使用此服务器。");
app.add_flag("-l, --last", param.last_use, "直接使用之前最后一次使用的服务器。");
app.add_option("-r, --remove", param.removeValue,
"移除服务器地址组(值为使用--show中显示的序号)");
app.add_flag("-d, --direct", param.direct_use,
"添加服务器时直接使用此服务器。");
app.add_flag("-l, --last", param.last_use,
"直接使用之前最后一次使用的服务器。");
app.add_flag("-n, --null", param.null_use, "先运行在选择服务器。");
app.add_option("-c, --connect", param.connectValue, "直连服务器((地址格式:127.0.0.1:9898)。");
app.add_option("-c, --connect", param.connectValue,
"直连服务器((地址格式:127.0.0.1:9898)。");
if (argc == 1) {
std::cout << app.help() << std::endl;
return 0;
}
// 这里的 CLI11_PARSE 在程序没有输入或者仅输入--help(-h)时,会直接返回,后面代码都不会执行。
// 这里的 CLI11_PARSE
// 在程序没有输入或者仅输入--help(-h)时,会直接返回,后面代码都不会执行。
// 当有自定义的参数被输入时,后面代码会执行。
try {
CLI11_PARSE(app, argc, argv);
@ -57,7 +61,8 @@ int parse_cmd(int argc, char** argv, CmdParam& param)
return 0;
}
bool select_server(const std::vector<TransmSet>& sets, std::string& ip, long& port)
bool select_server(const std::vector<TransmSet>& sets, std::string& ip,
long& port)
{
TLOGI("Please Select a Server:");
if (sets.empty()) {
@ -70,7 +75,8 @@ bool select_server(const std::vector<TransmSet>& sets, std::string& ip, long& po
if (server.comment.empty()) {
TLOGI("[{}] {}:{}", i + 1, server.ip, server.port);
} else {
TLOGI("[{}] {}:{} ({})", i + 1, server.ip, server.port, server.comment);
TLOGI("[{}] {}:{} ({})", i + 1, server.ip, server.port,
server.comment);
}
}
@ -86,8 +92,10 @@ bool select_server(const std::vector<TransmSet>& sets, std::string& ip, long& po
}
// 检查输入是否为空或非数字
if (input.empty() || !std::all_of(input.begin(), input.end(), ::isdigit)) {
TLOGE("Invalid input '{}'. Please enter a valid number or 'exit'.", input);
if (input.empty() ||
!std::all_of(input.begin(), input.end(), ::isdigit)) {
TLOGE("Invalid input '{}'. Please enter a valid number or 'exit'.",
input);
continue;
}
@ -96,7 +104,9 @@ bool select_server(const std::vector<TransmSet>& sets, std::string& ip, long& po
// 检查数字是否在有效范围内
if (choice < 1 || choice > static_cast<int>(sets.size())) {
TLOGE("Invalid choice '{}'. Please select a number between 1 and {}.", choice, sets.size());
TLOGE(
"Invalid choice '{}'. Please select a number between 1 and {}.",
choice, sets.size());
continue;
}
@ -119,7 +129,8 @@ bool exec_cmd(CmdParam& param, bool& run)
return false;
}
for (const auto& item : set) {
TLOGI("{} => {}:{} {}", item.group, item.ip, item.port, item.comment);
TLOGI("{} => {}:{} {}", item.group, item.ip, item.port,
item.comment);
}
return true;
}
@ -132,7 +143,8 @@ bool exec_cmd(CmdParam& param, bool& run)
return false;
}
if (!param.appendValue.empty()) {
std::regex pattern(R"((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d+)(?::(.*))?)");
std::regex pattern(
R"((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d+)(?::(.*))?)");
std::smatch matches;
std::string ip, port, comment;
if (std::regex_match(param.appendValue, matches, pattern)) {
@ -151,7 +163,8 @@ bool exec_cmd(CmdParam& param, bool& run)
}
if (!param.removeValue.empty()) {
if (!g_Config->remove_ini(std::stol(param.removeValue))) {
TLOGW("remove config num=[{}] failed, please check!", param.removeValue);
TLOGW("remove config num=[{}] failed, please check!",
param.removeValue);
return false;
}
TLOGI("remove config num=[{}] success!", param.removeValue);
@ -206,7 +219,8 @@ int main(int argc, char* argv[])
std::regex pattern(R"((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d+))");
std::smatch matches;
if (std::regex_match(param.connectValue, matches, pattern) && matches.size() == 3) {
if (std::regex_match(param.connectValue, matches, pattern) &&
matches.size() == 3) {
ip = matches[1].str();
port = std::stol(matches[2].str());
run = true;
@ -250,7 +264,8 @@ int main(int argc, char* argv[])
}
g_Config->save_last_use(ip, port);
}
TLOGI("Build At {} {} under {} on {}", __DATE__, __TIME__, VERSION_GIT_COMMIT, VERSION_GIT_BRANCH);
TLOGI("Build At {} {} under {} on {}", __DATE__, __TIME__,
VERSION_GIT_COMMIT, VERSION_GIT_BRANCH);
TLOGI("use ip => [{}], port => [{}]", ip, port);
std::shared_ptr<TransmClient> client = std::make_shared<TransmClient>();
client->run(ip, std::to_string(port), g_Config->get_config_dir());

View File

@ -1,6 +1,3 @@
set(MBOOST_INCLUDE_DIR "C:/boost/include/boost-1_83")
set(MBOOST_LIB_DIR "C:/boost/lib")
set(MBOOST_LIBS "boost_filesystem-mgw7-mt-x32-1_83")
get_filename_component(CXX_COMPILER_PATH ${CMAKE_CXX_COMPILER} DIRECTORY)
set(MINGW32_DLLS
"${CXX_COMPILER_PATH}/libgcc_s_dw2-1.dll"

@ -1 +1 @@
Subproject commit b9e7bdb7349cc0c469800e42b309676fb5495be8
Subproject commit 1d84054da9ec3a70ae1311d6166a9404a10a356c

@ -1 +1 @@
Subproject commit 4b6612cc63f21b4d092a0b5731ceb7f817f20d23
Subproject commit 1a35e4371945b7c439a95a3e42612e9870e03e65

View File

@ -1,7 +1,7 @@
@echo off
cmake -Bxpbuild -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DXP_SYSTEM=ON -DUSE_BOOST=ON
cd xpbuild
cmake -BMinGWBuild -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
cd MinGWBuild
cpack
if %errorlevel% neq 0 (
echo Error: cmake build failed.

2
ofen

@ -1 +1 @@
Subproject commit fbc26d565f7b73418dd9bfaee3fc67b77a56daba
Subproject commit e1624c71451febf956a98bc692c0e886366f4c34

View File

@ -6,17 +6,9 @@ set(CMAKE_CXX_STANDARD 17)
if (MSVC)
add_compile_options(/source-charset:utf-8)
endif()
if(DEFINED USE_BOOST)
message(STATUS "tss use boost lib.")
include_directories(${MBOOST_INCLUDE_DIR})
endif()
add_executable(tss main.cpp server.h server.cpp)
target_link_libraries(tss PRIVATE trans_net trans_util)
if(DEFINED USE_BOOST)
target_link_directories(tss PRIVATE ${MBOOST_LIB_DIR})
target_link_libraries(tss PRIVATE ${MBOOST_LIBS})
endif()
if (UNIX)
target_link_libraries(tss PRIVATE pthread)
endif()

View File

@ -3,7 +3,9 @@
#include "server.h"
#include "version.h"
#include <filesystem>
#include <of_path.h>
namespace fs = std::filesystem;
#ifdef _WIN32
#include <fcntl.h>
@ -18,14 +20,6 @@
#include <crashelper.h>
#endif
#ifdef USE_BOOST
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
#else
#include <filesystem>
namespace fs = std::filesystem;
#endif
void msignal_handler(int signal)
{
fc_recovery_color();
@ -41,6 +35,8 @@ int main(int argc, char* argv[])
backward::SetDumpLogSavePath(err);
CRASHELPER_MARK_ENTRY();
sh.register_user_sig_handler([](int sig) { msignal_handler(sig); });
#else
signal(SIGINT, msignal_handler);
#endif
#ifdef _WIN32
@ -56,7 +52,8 @@ int main(int argc, char* argv[])
delete p;
});
TLOGI("Build At {} {} under {} on {}", __DATE__, __TIME__, VERSION_GIT_COMMIT, VERSION_GIT_BRANCH);
TLOGI("Build At {} {} under {} on {}", __DATE__, __TIME__,
VERSION_GIT_COMMIT, VERSION_GIT_BRANCH);
int port = 9898;
if (argc < 2) {
TLOGI("Use Default Port:{}", port);

View File

@ -53,35 +53,43 @@ bool base_connect()
}
server_th = std::thread(server_run);
if (value_wait<bool>([]() -> bool { return server_suc; }, true, std::equal_to<bool>(), max_wait,
if (value_wait<bool>([]() -> bool { return server_suc; }, true,
std::equal_to<bool>(), max_wait,
wait_interval) == false) {
return false;
}
clientA = std::make_shared<TransmClient>();
if (clientA->connect_for_test(ip, std::to_string(port), config->get_config_dir()) == false) {
if (clientA->connect_for_test(ip, std::to_string(port),
config->get_config_dir()) == false) {
return false;
}
clientB = std::make_shared<TransmClient>();
if (clientB->connect_for_test(ip, std::to_string(port), config->get_config_dir()) == false) {
if (clientB->connect_for_test(ip, std::to_string(port),
config->get_config_dir()) == false) {
return false;
}
if (value_wait<std::string>([]() -> std::string { return clientA->test_get_own_id(); }, std::string(),
std::not_equal_to<std::string>(), max_wait, wait_interval) == false) {
if (value_wait<std::string>(
[]() -> std::string { return clientA->test_get_own_id(); },
std::string(), std::not_equal_to<std::string>(), max_wait,
wait_interval) == false) {
return false;
}
if (value_wait<std::string>([]() -> std::string { return clientB->test_get_own_id(); }, std::string(),
std::not_equal_to<std::string>(), max_wait, wait_interval) == false) {
if (value_wait<std::string>(
[]() -> std::string { return clientB->test_get_own_id(); },
std::string(), std::not_equal_to<std::string>(), max_wait,
wait_interval) == false) {
return false;
}
str_id_a = clientA->test_get_own_id();
std::cout << "clientA id: " << str_id_a << std::endl;
if (value_wait<int>([]() -> int { return clientB->test_index_by_id(str_id_a); }, -1,
std::not_equal_to<int>(), max_wait, wait_interval) == false) {
if (value_wait<int>(
[]() -> int { return clientB->test_index_by_id(str_id_a); }, -1,
std::not_equal_to<int>(), max_wait, wait_interval) == false) {
return false;
}
ida_in_b = clientB->test_index_by_id(str_id_a);
@ -173,9 +181,12 @@ bool test_up_task(bool encrypt)
}
if (value_wait<TransmClient::TaskState>(
[&]() -> TransmClient::TaskState { return clientB->get_task_state(); },
TransmClient::TaskState::TASK_STATE_IDLE, std::not_equal_to<TransmClient::TaskState>(),
max_wait * 2, wait_interval) == false) {
[&]() -> TransmClient::TaskState {
return clientB->get_task_state();
},
TransmClient::TaskState::TASK_STATE_IDLE,
std::not_equal_to<TransmClient::TaskState>(), max_wait * 2,
wait_interval) == false) {
return false;
}
@ -192,7 +203,8 @@ bool test_up_task(bool encrypt)
return false;
}
std::cout << "****** up task done encrypt:" << encrypt << " ******" << std::endl;
std::cout << "****** up task done encrypt:" << encrypt << " ******"
<< std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
return true;
}
@ -213,7 +225,8 @@ bool random_ralated_files()
fs::remove(test_task_file);
}
std::ofstream ofs(test_task_file);
ofs << "${CURRENT}/" << test_filea << "|" << test_sub_dir + "/" << std::endl;
ofs << "${CURRENT}/" << test_filea << "|" << test_sub_dir + "/"
<< std::endl;
ofs << test_fileb << "|" << test_sub_dir + "/" << std::endl;
ofs.close();
return true;

View File

@ -54,7 +54,8 @@ bool test_speed(SpeedRet& ret)
hash(key.c_str(), ik);
fs::path decrypted_path = fs::path(test_file).replace_filename(
fs::path(test_file).stem().string() + "_decrypted" + fs::path(test_file).extension().string());
fs::path(test_file).stem().string() + "_decrypted" +
fs::path(test_file).extension().string());
std::ofstream decrypted_file(decrypted_path, std::ios::binary);
if (!decrypted_file) {
@ -70,7 +71,8 @@ bool test_speed(SpeedRet& ret)
// 测试数据缓冲区(额外预留16字节空间)
std::vector<uint8_t> original_block(BLOCK_SIZE);
std::vector<uint8_t> processing_block(BLOCK_SIZE + IV_SIZE); // 加密/解密处理缓冲区
std::vector<uint8_t> processing_block(BLOCK_SIZE +
IV_SIZE); // 加密/解密处理缓冲区
size_t total_bytes = 0;
size_t blocks_processed = 0;
@ -80,39 +82,49 @@ bool test_speed(SpeedRet& ret)
auto total_decrypt_time = std::chrono::microseconds(0);
while (in_file) {
in_file.read(reinterpret_cast<char*>(original_block.data()), BLOCK_SIZE - IV_SIZE);
in_file.read(reinterpret_cast<char*>(original_block.data()),
BLOCK_SIZE - IV_SIZE);
size_t bytes_read = in_file.gcount();
if (bytes_read == 0)
break;
memcpy(processing_block.data() + IV_SIZE, original_block.data(), bytes_read);
memcpy(processing_block.data() + IV_SIZE, original_block.data(),
bytes_read);
auto start_encrypt = std::chrono::high_resolution_clock::now();
if (!encrypt(ik, processing_block.data(), bytes_read + IV_SIZE)) {
std::cerr << "Encryption failed at block " << blocks_processed << std::endl;
std::cerr << "Encryption failed at block " << blocks_processed
<< std::endl;
verification_passed = false;
break;
}
auto end_encrypt = std::chrono::high_resolution_clock::now();
total_encrypt_time +=
std::chrono::duration_cast<std::chrono::microseconds>(end_encrypt - start_encrypt);
std::chrono::duration_cast<std::chrono::microseconds>(
end_encrypt - start_encrypt);
auto start_decrypt = std::chrono::high_resolution_clock::now();
if (!decrypt(ik, processing_block.data(), bytes_read + IV_SIZE)) {
std::cerr << "Decryption failed at block " << blocks_processed << std::endl;
std::cerr << "Decryption failed at block " << blocks_processed
<< std::endl;
verification_passed = false;
break;
}
auto end_decrypt = std::chrono::high_resolution_clock::now();
total_decrypt_time +=
std::chrono::duration_cast<std::chrono::microseconds>(end_decrypt - start_decrypt);
std::chrono::duration_cast<std::chrono::microseconds>(
end_decrypt - start_decrypt);
if (memcmp(original_block.data(), processing_block.data() + IV_SIZE, bytes_read) != 0) {
std::cerr << "Data mismatch at block " << blocks_processed << std::endl;
if (memcmp(original_block.data(), processing_block.data() + IV_SIZE,
bytes_read) != 0) {
std::cerr << "Data mismatch at block " << blocks_processed
<< std::endl;
verification_passed = false;
break;
}
decrypted_file.write(reinterpret_cast<const char*>(processing_block.data() + IV_SIZE), bytes_read);
decrypted_file.write(
reinterpret_cast<const char*>(processing_block.data() + IV_SIZE),
bytes_read);
total_bytes += bytes_read;
blocks_processed++;
}
@ -129,10 +141,10 @@ bool test_speed(SpeedRet& ret)
#endif
// 计算吞吐量(只计算有效数据部分)
double encrypt_throughput =
(double)total_bytes / (1024 * 1024) / (total_encrypt_time.count() / 1000000.0);
double decrypt_throughput =
(double)total_bytes / (1024 * 1024) / (total_decrypt_time.count() / 1000000.0);
double encrypt_throughput = (double)total_bytes / (1024 * 1024) /
(total_encrypt_time.count() / 1000000.0);
double decrypt_throughput = (double)total_bytes / (1024 * 1024) /
(total_decrypt_time.count() / 1000000.0);
ret.encry_speed = encrypt_throughput;
ret.decry_speed = decrypt_throughput;

View File

@ -1,19 +1,13 @@
#ifndef ASSISTANT_H
#define ASSISTANT_H
#include <filesystem>
#include <fstream>
#include <functional>
#include <random>
#include <string>
#include <thread>
#ifdef USE_BOOST
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
#else
#include <filesystem>
namespace fs = std::filesystem;
#endif
/**
* @brief
@ -40,8 +34,9 @@ bool random_file(const std::string& file, size_t size);
* @return false
*/
template <typename T, typename Compare = std::equal_to<T>>
bool value_wait(const std::function<T()>& value_ref, const T& expected, Compare comparator = Compare(),
unsigned long timeout_ms = 0, unsigned long interval_ms = 100)
bool value_wait(const std::function<T()>& value_ref, const T& expected,
Compare comparator = Compare(), unsigned long timeout_ms = 0,
unsigned long interval_ms = 100)
{
auto start = std::chrono::steady_clock::now();
@ -53,9 +48,10 @@ bool value_wait(const std::function<T()>& value_ref, const T& expected, Compare
}
if (timeout_ms > 0) {
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - start)
.count();
auto elapsed =
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - start)
.count();
if (elapsed >= timeout_ms) {
return false;
@ -103,7 +99,8 @@ private:
};
#define _SCOPE_EXIT_CONCAT(a, b) a##b
#define _MAKE_ON_SCOPE_EXIT(line) ScopeExit _SCOPE_EXIT_CONCAT(exit_defer_, line) = [&]()
#define _MAKE_ON_SCOPE_EXIT(line) \
ScopeExit _SCOPE_EXIT_CONCAT(exit_defer_, line) = [&]()
#define ON_SCOPE_EXIT _MAKE_ON_SCOPE_EXIT(__LINE__)
#endif // ASSISTANT_H

View File

@ -1,10 +1,12 @@
/*
This is an implementation of the AES algorithm, specifically ECB, CTR and CBC mode.
Block size can be chosen in aes.h - available choices are AES128, AES192, AES256.
This is an implementation of the AES algorithm, specifically ECB, CTR and CBC
mode. Block size can be chosen in aes.h - available choices are AES128, AES192,
AES256.
The implementation is verified against the test vectors in:
National Institute of Standards and Technology Special Publication 800-38A 2001 ED
National Institute of Standards and Technology Special Publication 800-38A
2001 ED
ECB-AES128
----------
@ -42,7 +44,8 @@ NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
/*****************************************************************************/
/* Defines: */
/*****************************************************************************/
// The number of columns comprising a state in AES. This is a constant in AES. Value=4
// The number of columns comprising a state in AES. This is a constant in AES.
// Value=4
#define Nb 4
#if defined(AES256) && (AES256 == 1)
@ -58,7 +61,8 @@ NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
// jcallan@github points out that declaring Multiply as a function
// reduces code size considerably with the Keil ARM compiler.
// See this link for more information: https://github.com/kokke/tiny-AES-C/pull/3
// See this link for more information:
// https://github.com/kokke/tiny-AES-C/pull/3
#ifndef MULTIPLY_AS_A_FUNCTION
#define MULTIPLY_AS_A_FUNCTION 0
#endif
@ -69,59 +73,77 @@ NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
// state - array holding the intermediate results during decryption.
typedef uint8_t state_t[4][4];
// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM
// The numbers below can be computed dynamically trading ROM for RAM -
// This can be useful in (embedded) bootloader applications, where ROM is often limited.
// The lookup-tables are marked const so they can be placed in read-only storage
// instead of RAM The numbers below can be computed dynamically trading ROM for
// RAM - This can be useful in (embedded) bootloader applications, where ROM is
// often limited.
static const uint8_t sbox[256] = {
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};
// 0 1 2 3 4 5 6 7 8 9 A B C
// D E F
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,
0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,
0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
0xb0, 0x54, 0xbb, 0x16};
static const uint8_t rsbox[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d};
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e,
0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32,
0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49,
0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50,
0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05,
0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41,
0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8,
0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b,
0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59,
0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d,
0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63,
0x55, 0x21, 0x0c, 0x7d};
// The round constant word array, Rcon[i], contains the values given by
// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
static const uint8_t Rcon[11] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
// x to the power (i-1) being powers of x (x is denoted as {02}) in the field
// GF(2^8)
static const uint8_t Rcon[11] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10,
0x20, 0x40, 0x80, 0x1b, 0x36};
/*
* Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12),
* that you can remove most of the elements in the Rcon array, because they are unused.
* Jordan Goulder points out in PR #12
* (https://github.com/kokke/tiny-AES-C/pull/12), that you can remove most of
* the elements in the Rcon array, because they are unused.
*
* From Wikipedia's article on the Rijndael key schedule @
* https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon
*
* "Only the first some of these constants are actually used – up to rcon[10] for AES-128 (as 11 round keys
* are needed), up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm."
* "Only the first some of these constants are actually used – up to rcon[10]
* for AES-128 (as 11 round keys are needed), up to rcon[8] for AES-192, up to
* rcon[7] for AES-256. rcon[0] is not used in AES algorithm."
*/
/*****************************************************************************/
@ -142,7 +164,8 @@ static uint8_t getSBoxInvert(uint8_t num)
*/
#define getSBoxInvert(num) (rsbox[(num)])
// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
// This function produces Nb(Nr+1) round keys. The round keys are used in each
// round to decrypt the states.
static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
{
unsigned i, j, k;
@ -180,7 +203,8 @@ static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
}
// SubWord() is a function that takes a four-byte input word and
// applies the S-box to each of the four bytes to produce an output word.
// applies the S-box to each of the four bytes to produce an output
// word.
// Function Subword()
{
@ -312,27 +336,33 @@ static void MixColumns(state_t* state)
}
// Multiply is used to multiply numbers in the field GF(2^8)
// Note: The last call to xtime() is unneeded, but often ends up generating a smaller binary
// The compiler seems to be able to vectorize the operation better this way.
// See https://github.com/kokke/tiny-AES-c/pull/34
// Note: The last call to xtime() is unneeded, but often ends up generating a
// smaller binary
// The compiler seems to be able to vectorize the operation better this
// way. See https://github.com/kokke/tiny-AES-c/pull/34
#if MULTIPLY_AS_A_FUNCTION
static uint8_t Multiply(uint8_t x, uint8_t y)
{
return (((y & 1) * x) ^ ((y >> 1 & 1) * xtime(x)) ^ ((y >> 2 & 1) * xtime(xtime(x))) ^
return (((y & 1) * x) ^ ((y >> 1 & 1) * xtime(x)) ^
((y >> 2 & 1) * xtime(xtime(x))) ^
((y >> 3 & 1) * xtime(xtime(xtime(x)))) ^
((y >> 4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */
((y >> 4 & 1) *
xtime(xtime(xtime(
xtime(x)))))); /* this last call to xtime() can be omitted */
}
#else
#define Multiply(x, y) \
(((y & 1) * x) ^ ((y >> 1 & 1) * xtime(x)) ^ ((y >> 2 & 1) * xtime(xtime(x))) ^ \
((y >> 3 & 1) * xtime(xtime(xtime(x)))) ^ ((y >> 4 & 1) * xtime(xtime(xtime(xtime(x))))))
#define Multiply(x, y) \
(((y & 1) * x) ^ ((y >> 1 & 1) * xtime(x)) ^ \
((y >> 2 & 1) * xtime(xtime(x))) ^ \
((y >> 3 & 1) * xtime(xtime(xtime(x)))) ^ \
((y >> 4 & 1) * xtime(xtime(xtime(xtime(x))))))
#endif
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
// MixColumns function mixes the columns of the state matrix.
// The method used to multiply may be difficult to understand for the inexperienced.
// Please use the references to gain more information.
// The method used to multiply may be difficult to understand for the
// inexperienced. Please use the references to gain more information.
static void InvMixColumns(state_t* state)
{
int i;
@ -343,10 +373,14 @@ static void InvMixColumns(state_t* state)
c = (*state)[i][2];
d = (*state)[i][3];
(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^
Multiply(c, 0x0d) ^ Multiply(d, 0x09);
(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^
Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^
Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^
Multiply(c, 0x09) ^ Multiply(d, 0x0e);
}
}
@ -449,13 +483,15 @@ static void InvCipher(state_t* state, uint8_t* RoundKey)
void AES_ECB_encrypt(struct AES_ctx* ctx, uint8_t* buf)
{
// The next function call encrypts the PlainText with the Key using AES algorithm.
// The next function call encrypts the PlainText with the Key using AES
// algorithm.
Cipher((state_t*)buf, ctx->RoundKey);
}
void AES_ECB_decrypt(struct AES_ctx* ctx, uint8_t* buf)
{
// The next function call decrypts the PlainText with the Key using AES algorithm.
// The next function call decrypts the PlainText with the Key using AES
// algorithm.
InvCipher((state_t*)buf, ctx->RoundKey);
}
@ -466,7 +502,8 @@ void AES_ECB_decrypt(struct AES_ctx* ctx, uint8_t* buf)
static void XorWithIv(uint8_t* buf, uint8_t* Iv)
{
uint8_t i;
for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size
for (i = 0; i < AES_BLOCKLEN;
++i) // The block in AES is always 128bit no matter the key size
{
buf[i] ^= Iv[i];
}
@ -504,8 +541,8 @@ void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
#if defined(CTR) && (CTR == 1)
/* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be
* reused with the same key */
/* Symmetrical operation: same function for encrypting as for decrypting. Note
* any IV/nonce should never be reused with the same key */
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
{
uint8_t buffer[AES_BLOCKLEN];

View File

@ -7,10 +7,11 @@
//
// CBC enables AES encryption in CBC-mode of operation.
// CTR enables encryption in counter-mode.
// ECB enables the basic ECB 16-byte block algorithm. All can be enabled simultaneously.
// ECB enables the basic ECB 16-byte block algorithm. All can be enabled
// simultaneously.
// The #ifndef-guard allows it to be configured before #include'ing or at compile time.
// #ifndef CBC
// The #ifndef-guard allows it to be configured before #include'ing or at
// compile time. #ifndef CBC
// #define CBC 1
// #endif
@ -53,7 +54,8 @@ struct AES_ctx {
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key);
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv);
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key,
const uint8_t* iv);
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv);
#endif
@ -68,8 +70,9 @@ void AES_ECB_decrypt(struct AES_ctx* ctx, uint8_t* buf);
#if defined(CBC) && (CBC == 1)
// buffer size MUST be mutile of AES_BLOCKLEN;
// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv()
// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for
// padding scheme NOTES: you need to set IV in ctx via AES_init_ctx_iv() or
// AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
@ -79,8 +82,9 @@ void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
#if defined(CTR) && (CTR == 1)
// Same function for encrypting as for decrypting.
// IV is incremented for every block, and used after encryption as XOR-compliment for output
// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// IV is incremented for every block, and used after encryption as
// XOR-compliment for output Suggesting
// https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);

View File

@ -48,7 +48,8 @@ CFrameBuffer* CTransProtocal::parse(CMutBuffer& buffer)
int32_t len{};
std::memcpy(&type, buffer.get_data() + find + 2, sizeof(type));
std::memcpy(&mark, buffer.get_data() + find + 2 + 2, sizeof(mark));
std::memcpy(&len, buffer.get_data() + find + 2 + 2 + 1 + 32 + 32, sizeof(len));
std::memcpy(&len, buffer.get_data() + find + 2 + 2 + 1 + 32 + 32,
sizeof(len));
int32_t tail_index = find + 2 + 2 + 1 + 32 + 32 + 4 + len;
if (buffer.get_len() - 2 < tail_index || len < 0) {
@ -67,7 +68,8 @@ CFrameBuffer* CTransProtocal::parse(CMutBuffer& buffer)
result->mark_ = mark;
result->type_ = static_cast<FrameType>(type);
if (len > 0) {
std::memcpy(result->data_, buffer.get_data() + find + 2 + 2 + 1 + 4 + 32 + 32, len);
std::memcpy(result->data_,
buffer.get_data() + find + 2 + 2 + 1 + 4 + 32 + 32, len);
}
buffer.remove_of(0, tail_index + 2);
return result;
@ -93,7 +95,8 @@ bool CTransProtocal::pack(CFrameBuffer* buf, char** out_buf, int& len)
std::memcpy(*out_buf + 2 + 2 + 1, buf->fid_.data(), buf->fid_.size());
}
if (!buf->tid_.empty()) {
std::memcpy(*out_buf + 2 + 2 + 1 + 32, buf->tid_.data(), buf->tid_.size());
std::memcpy(*out_buf + 2 + 2 + 1 + 32, buf->tid_.data(),
buf->tid_.size());
}
std::memcpy(*out_buf + 2 + 2 + 1 + 32 + 32, &buf->len_, 4);
if (buf->data_ != nullptr) {
@ -142,13 +145,15 @@ void serialize(CMessageInfo& msg_info, char** out_buf, int& len, bool reuse_mem)
info.str = localtou8(info.str);
// 计算总长度
len = sizeof(int) * 4 + info.id.size() + info.uuid.size() + info.str.size() + info.data.size() + kz + 1;
len = sizeof(int) * 4 + info.id.size() + info.uuid.size() +
info.str.size() + info.data.size() + kz + 1;
// 《这里为了效率》,
// 认为如果 *out_buf 不为空,则直接使用,且长度符合要求
// 调用方负责确保内存够用性(len <= 可用最大空间长度)和内存可用性。
// 即,如果调用方及高频率调用 serialize, 且每次 len <= 已分配空间就复用内存,完了再释放。
// 低频率或者 len 不固定时,每次都释放内存,并置 nullptr。
// 即,如果调用方及高频率调用 serialize, 且每次 len <=
// 已分配空间就复用内存,完了再释放。 低频率或者 len
// 不固定时,每次都释放内存,并置 nullptr。
if (*out_buf) {
if (!reuse_mem) {
delete[] *out_buf;
@ -327,7 +332,8 @@ void rdm(uint8_t* o, size_t size)
// std::mt19937 gen(rd());
std::mt19937_64 gen(rd());
std::uniform_int_distribution<int> dist(0, 255);
std::generate(o, o + size, [&]() { return static_cast<uint8_t>(dist(gen)); });
std::generate(o, o + size,
[&]() { return static_cast<uint8_t>(dist(gen)); });
}
bool encrypt(const uint8_t* k, uint8_t* m, size_t len)

View File

@ -53,7 +53,8 @@ struct CMessageInfo {
std::string data;
};
void serialize(CMessageInfo& msg_info, char** out_buf, int& len, bool reuse_mem = false);
void serialize(CMessageInfo& msg_info, char** out_buf, int& len,
bool reuse_mem = false);
bool deserialize(char* data, int len, CMessageInfo& msg_info);
std::string u8tolocal(const std::string& str);
std::string localtou8(const std::string& str);
@ -110,39 +111,54 @@ inline std::string now_str()
{
auto now = std::chrono::system_clock::now();
auto time_t_now = std::chrono::system_clock::to_time_t(now);
auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) %
1000;
std::ostringstream timestamp;
timestamp << std::put_time(std::localtime(&time_t_now), "[%m-%d %H:%M:%S") << "." << std::setfill('0') << std::setw(3)
timestamp << std::put_time(std::localtime(&time_t_now), "[%m-%d %H:%M:%S")
<< "." << std::setfill('0') << std::setw(3)
<< milliseconds.count() << "] ";
return timestamp.str();
}
template <typename... Args> void TLOGI(const std::string& format, Args&&... args)
template <typename... Args>
void TLOGI(const std::string& format, Args&&... args)
{
fc_lock_print();
std::cout << ConsoleColor::Green << fmt::format(now_str() + format, std::forward<Args>(args)...) << std::endl;
std::cout << ConsoleColor::Green
<< fmt::format(now_str() + format, std::forward<Args>(args)...)
<< std::endl;
fc_unlock_print();
}
template <typename... Args> void TLOGW(const std::string& format, Args&&... args)
template <typename... Args>
void TLOGW(const std::string& format, Args&&... args)
{
fc_lock_print();
std::cout << ConsoleColor::Yellow << fmt::format(now_str() + format, std::forward<Args>(args)...) << std::endl;
std::cout << ConsoleColor::Yellow
<< fmt::format(now_str() + format, std::forward<Args>(args)...)
<< std::endl;
fc_unlock_print();
}
template <typename... Args> void TLOGE(const std::string& format, Args&&... args)
template <typename... Args>
void TLOGE(const std::string& format, Args&&... args)
{
fc_lock_print();
std::cout << ConsoleColor::Red << fmt::format(now_str() + format, std::forward<Args>(args)...) << std::endl;
std::cout << ConsoleColor::Red
<< fmt::format(now_str() + format, std::forward<Args>(args)...)
<< std::endl;
fc_unlock_print();
}
template <typename... Args> void TLOGD(const std::string& format, Args&&... args)
template <typename... Args>
void TLOGD(const std::string& format, Args&&... args)
{
fc_lock_print();
std::cout << ConsoleColor::Cyan << fmt::format(now_str() + format, std::forward<Args>(args)...) << std::endl;
std::cout << ConsoleColor::Cyan
<< fmt::format(now_str() + format, std::forward<Args>(args)...)
<< std::endl;
fc_unlock_print();
}