transm/util/util.cpp
2025-01-17 14:06:41 +08:00

150 lines
4.4 KiB
C++

#include "util.h"
#include <cstdint>
#include <thread>
#include <iostream>
std::shared_ptr<spdlog::logger> get_logger(const std::string& mark, const std::string& log_file)
{
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(log_file, g_BuffSize * 50, 3);
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
file_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e][%l]: %v");
console_sink->set_pattern("%^[%Y-%m-%d %H:%M:%S.%e][%l]: %v%$");
std::vector<spdlog::sink_ptr> sinks{file_sink, console_sink};
auto logger = std::make_shared<spdlog::logger>(mark, sinks.begin(), sinks.end());
logger->set_level(spdlog::level::debug);
spdlog::register_logger(logger);
return logger;
}
CTransProtocal::CTransProtocal()
{
}
CTransProtocal::~CTransProtocal()
{
}
/*
【 transm TCP 数据协议 】
header 2 char: 0xFF 0xFE
type 2 char:
mark 1 char:
from 32 char:
to 32 char:
len 4 char:
data xxxxx:
tail 2 char: 0xFF 0xFF
*/
CFrameBuffer* CTransProtocal::parse(CMutBuffer& buffer)
{
CFrameBuffer* result = nullptr;
unsigned char header[] = {0xFF, 0xFE};
unsigned char tail[] = {0xFF, 0xFF};
// 如果超出 1MB的内容都无法解析成功,则认为是有无效客户端参与链接。
size_t cur_len = static_cast<size_t>(buffer.get_len());
if (cur_len > MAX_FRAME_SIZE) {
buffer.clear();
// 这里故意延迟。
std::this_thread::sleep_for(std::chrono::seconds(600));
return result;
}
int find = buffer.index_of((const char*)header, sizeof(header));
if (find < 0) {
return result;
}
// reinterpret_cast 的指针转换直接访问内存可能导致未对齐问题(某些架构下)
int16_t type{};
char mark{};
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));
int32_t tail_index = find + 2 + 2 + 1 + 32 + 32 + 4 + len;
if (buffer.get_len() - 2 < tail_index || len < 0) {
return result;
}
if (std::memcmp(buffer.get_data() + tail_index, tail, sizeof(tail)) != 0) {
return result;
}
result = new CFrameBuffer();
if (len > 0) {
result->data_ = new char[len]();
}
result->len_ = len;
result->fid_ = std::string(buffer.get_data() + find + 2 + 2 + 1);
result->tid_ = std::string(buffer.get_data() + find + 2 + 2 + 1 + 32);
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);
}
buffer.remove_of(0, tail_index + 2);
return result;
}
bool CTransProtocal::pack(CFrameBuffer* buf, char** out_buf, int& len)
{
if (buf == nullptr) {
return false;
}
if (buf->data_ == nullptr) {
buf->len_ = 0;
}
unsigned char header[] = {0xFF, 0xFE};
unsigned char tail[] = {0xFF, 0xFF};
len = buf->len_ + 75;
*out_buf = new char[len]{};
std::memset(*out_buf, 0x0, len);
std::memcpy(*out_buf, header, 2);
std::memcpy(*out_buf + 2, &buf->type_, 2);
std::memcpy(*out_buf + 2 + 2, &buf->mark_, 1);
if (!buf->fid_.empty()) {
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 + 32, &buf->len_, 4);
if (buf->data_ != nullptr) {
std::memcpy(*out_buf + 2 + 2 + 1 + 32 + 32 + 4, buf->data_, buf->len_);
}
std::memcpy(*out_buf + len - 2, tail, 2);
return true;
}
void CTransProtocal::display_progress(float percent)
{
if (percent > 1.0 || percent < 0.0) {
return;
}
const int barWidth = 38;
int pos = barWidth * percent;
std::cout << "[";
for (int i = 0; i < barWidth; ++i) {
if (i < pos) {
std::cout << "=";
} else if (i == pos) {
std::cout << ">";
} else {
std::cout << " ";
}
}
// \r 回到行首
std::cout << "] " << int(percent * 100.0f) << " %\r";
std::cout.flush();
}
CFrameBuffer::CFrameBuffer()
{
}
CFrameBuffer::~CFrameBuffer()
{
delete[] data_;
len_ = 0;
}