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