XNSim/Release/include/XNCore/XNDDSInterface.h

242 lines
5.9 KiB
C
Raw Normal View History

2025-04-28 12:25:20 +08:00
#pragma once
2025-05-19 09:49:54 +08:00
#include <string>
#include <vector>
#include <unordered_map>
#include <mutex>
#include <sstream>
#include <iomanip>
#include <array>
#include <functional>
#include <cstring>
#include <iostream>
2025-04-28 12:25:20 +08:00
#include <fastcdr/xcdr/optional.hpp>
2025-05-19 09:49:54 +08:00
// 定义UDP包的最大大小
constexpr size_t MAX_UDP_PACKET_SIZE = 40000;
2025-04-28 12:25:20 +08:00
template <typename T>
struct is_std_array : std::false_type {
};
template <typename T, std::size_t N>
struct is_std_array<std::array<T, N>> : std::true_type {
};
// 变量模板简化使用
template <typename T>
inline constexpr bool is_std_array_v = is_std_array<T>::value;
2025-05-19 09:49:54 +08:00
// 获取类型大小的辅助函数
template <typename T>
constexpr size_t getTypeSize()
{
if constexpr (is_std_array_v<T>) {
// 对于std::array计算所有元素的总大小
return getTypeSize<typename T::value_type>() * std::tuple_size<T>::value;
} else {
return sizeof(T);
}
}
class XNDDSInterface
2025-04-28 12:25:20 +08:00
{
public:
2025-05-19 09:49:54 +08:00
XNDDSInterface() = default;
virtual ~XNDDSInterface() = default;
2025-04-28 12:25:20 +08:00
template <typename T>
2025-05-19 09:49:54 +08:00
void getByteArray(eprosima::fastcdr::optional<T> data, uint8_t *buffer, size_t bufferSize)
2025-04-28 12:25:20 +08:00
{
2025-05-19 09:49:54 +08:00
if (bufferSize < getTypeSize<T>())
return;
2025-04-28 12:25:20 +08:00
if constexpr (std::is_arithmetic_v<T>) {
if (data) {
2025-05-19 09:49:54 +08:00
std::memcpy(buffer, &data.value(), sizeof(T));
2025-04-28 12:25:20 +08:00
} else {
2025-05-19 09:49:54 +08:00
T zero = 0;
std::memcpy(buffer, &zero, sizeof(T));
2025-04-28 12:25:20 +08:00
}
2025-05-19 09:49:54 +08:00
} else if constexpr (is_std_array_v<T>) {
2025-04-28 12:25:20 +08:00
if (data) {
2025-05-19 09:49:54 +08:00
getByteArrayFromStdArray(data.value(), buffer, bufferSize);
2025-04-28 12:25:20 +08:00
} else {
T zero = {};
2025-05-19 09:49:54 +08:00
getByteArrayFromStdArray(zero, buffer, bufferSize);
2025-04-28 12:25:20 +08:00
}
}
}
template <typename T, std::size_t N>
2025-05-19 09:49:54 +08:00
void getByteArrayFromStdArray(std::array<T, N> data, uint8_t *buffer, size_t bufferSize)
2025-04-28 12:25:20 +08:00
{
2025-05-19 09:49:54 +08:00
if (bufferSize < getTypeSize<T>() * N)
return;
2025-04-28 12:25:20 +08:00
for (std::size_t i = 0; i < N; ++i) {
if constexpr (std::is_arithmetic_v<T>) {
2025-05-19 09:49:54 +08:00
std::memcpy(buffer + i * getTypeSize<T>(), &data[i], getTypeSize<T>());
2025-04-28 12:25:20 +08:00
} else {
2025-05-19 09:49:54 +08:00
getByteArrayFromStdArray(data[i], buffer + i * getTypeSize<T>(), getTypeSize<T>());
2025-04-28 12:25:20 +08:00
}
}
}
2025-05-19 09:49:54 +08:00
void getUDPPackage(uint8_t *buffer, size_t bufferSize)
2025-04-28 12:25:20 +08:00
{
2025-05-19 09:49:54 +08:00
if (bufferSize < MAX_UDP_PACKET_SIZE)
return;
size_t currentPos = 0;
// 复制头部
if (headerSize >= 5) {
std::memcpy(buffer, header, 5);
currentPos = 5;
}
// 复制数据
2025-04-28 12:25:20 +08:00
for (auto func : getByteArrayFunction) {
2025-05-19 09:49:54 +08:00
if (currentPos + func.size <= MAX_UDP_PACKET_SIZE) {
func.func(buffer + currentPos, func.size);
currentPos += func.size;
} else {
break; // 超出最大包大小
}
}
// 更新包大小
if (currentPos >= 5) {
buffer[4] = static_cast<uint8_t>(currentPos);
2025-04-28 12:25:20 +08:00
}
}
template <typename T>
2025-05-19 09:49:54 +08:00
std::string getString(eprosima::fastcdr::optional<T> data)
2025-04-28 12:25:20 +08:00
{
if constexpr (std::is_arithmetic_v<T>) {
if (data) {
2025-05-19 09:49:54 +08:00
return std::to_string(data.value());
2025-04-28 12:25:20 +08:00
} else {
2025-05-19 09:49:54 +08:00
return std::to_string(0);
2025-04-28 12:25:20 +08:00
}
} else if constexpr (std::is_same_v<T, std::string>) {
if (data) {
2025-05-19 09:49:54 +08:00
return getStringFromStdArray(data.value());
2025-04-28 12:25:20 +08:00
} else {
T zero = {};
2025-05-19 09:49:54 +08:00
return getStringFromStdArray(zero);
2025-04-28 12:25:20 +08:00
}
}
2025-05-19 09:49:54 +08:00
return std::string();
2025-04-28 12:25:20 +08:00
}
template <typename T, std::size_t N>
2025-05-19 09:49:54 +08:00
std::string getStringFromStdArray(std::array<T, N> data)
2025-04-28 12:25:20 +08:00
{
2025-05-19 09:49:54 +08:00
std::stringstream ss;
2025-04-28 12:25:20 +08:00
for (std::size_t i = 0; i < N; ++i) {
2025-05-19 09:49:54 +08:00
if (i > 0)
ss << ",";
2025-04-28 12:25:20 +08:00
if constexpr (std::is_arithmetic_v<T>) {
2025-05-19 09:49:54 +08:00
ss << data[i];
2025-04-28 12:25:20 +08:00
} else {
2025-05-19 09:49:54 +08:00
ss << getStringFromStdArray(data[i]);
2025-04-28 12:25:20 +08:00
}
}
2025-05-19 09:49:54 +08:00
return ss.str();
2025-04-28 12:25:20 +08:00
}
2025-05-19 09:49:54 +08:00
std::string getData(const std::string &varName)
2025-04-28 12:25:20 +08:00
{
2025-05-19 09:49:54 +08:00
int index1 = -1;
int index2 = -1;
std::string trueVarName = varName;
size_t startPos = varName.find('[');
if (startPos != std::string::npos) {
size_t midPos = varName.find("][", startPos);
size_t endPos = varName.find_last_of(']');
if (midPos != std::string::npos) {
try {
index1 = std::stoi(varName.substr(startPos + 1, midPos - startPos - 1));
index2 = std::stoi(varName.substr(midPos + 2, endPos - midPos - 2));
} catch (...) {
std::cerr << "无法解析数组索引: " << varName << std::endl;
2025-04-28 12:25:20 +08:00
index1 = 0;
index2 = 0;
}
2025-05-19 09:49:54 +08:00
} else if (endPos != std::string::npos) {
try {
index1 = std::stoi(varName.substr(startPos + 1, endPos - startPos - 1));
} catch (...) {
std::cerr << "无法解析数组索引: " << varName << std::endl;
2025-04-28 12:25:20 +08:00
index1 = 0;
}
}
2025-05-19 09:49:54 +08:00
trueVarName = varName.substr(0, startPos);
2025-04-28 12:25:20 +08:00
}
2025-05-19 09:49:54 +08:00
2025-04-28 12:25:20 +08:00
auto it = getDataFunction.find(trueVarName);
if (it == getDataFunction.end()) {
2025-05-19 09:49:54 +08:00
return std::string();
2025-04-28 12:25:20 +08:00
}
2025-05-19 09:49:54 +08:00
std::lock_guard<std::mutex> lock(mutex);
std::string result = it->second();
2025-04-28 12:25:20 +08:00
if (index1 < 0) {
2025-05-19 09:49:54 +08:00
return result;
}
std::vector<std::string> list;
std::stringstream ss(result);
std::string item;
while (std::getline(ss, item, ',')) {
list.push_back(item);
}
if (index1 >= static_cast<int>(list.size())) {
std::cerr << "数组索引超出范围: " << varName << std::endl;
return std::string();
}
if (index2 < 0) {
2025-04-28 12:25:20 +08:00
return list[index1];
}
2025-05-19 09:49:54 +08:00
std::vector<std::string> list2;
std::stringstream ss2(list[index1]);
while (std::getline(ss2, item, ' ')) {
list2.push_back(item);
}
if (index2 >= static_cast<int>(list2.size())) {
std::cerr << "数组索引超出范围: " << varName << std::endl;
return std::string();
}
return list2[index2];
2025-04-28 12:25:20 +08:00
}
protected:
2025-05-19 09:49:54 +08:00
struct ByteArrayFunc {
std::function<void(uint8_t *, size_t)> func;
size_t size;
};
std::unordered_map<std::string, std::function<std::string()>> getDataFunction;
std::vector<ByteArrayFunc> getByteArrayFunction;
std::mutex mutex;
uint8_t header[5]{}; // 固定大小的头部
size_t headerSize = 0;
2025-04-28 12:25:20 +08:00
};
#define MAP_GET_DATA_FUNC(NAME) \
2025-05-19 09:49:54 +08:00
getDataFunction[#NAME] = [this]() { return getString(data.NAME()); }; \
getByteArrayFunction.push_back( \
{[this](uint8_t *buffer, size_t size) { getByteArray(data.NAME(), buffer, size); }, \
getTypeSize<decltype(data.NAME())>()})