ProfinetConnector/src/user_data/user_data.hpp

138 lines
4.0 KiB
C++
Raw Normal View History

#pragma once
#include <string>
#include <cstdint>
#include <vector>
#include <map>
#include <memory>
#include "../nlohmann_json/json.hpp"
struct UserDataBit {
const std::string Name;
const uint32_t Pos;
};
/**
* @brief Класс представления данных внутри датаграммы циклического обмена профинет в виде
* пользовательского набора стандартных типов. Нужен для выполнения RpcJson запросов оканчивающихся на
* Named.
*
*/
class UserData {
public:
enum class UserDataTypes
{
BOOL,
UINT8,
UINT16,
UINT32,
UINT64,
INT8,
INT16,
INT32,
INT64,
FLOAT32,
FLOAT64,
};
UserData(std::string& Name, std::string& DataType, uint16_t offset) :
name{Name},
type{data_corr.at(DataType)},
size{data_size.at(type)},
data_offset_{offset}
{
data_.uint64 = 0;
};
union AnyData {
bool boolean;
uint8_t uint8[8];
uint16_t uint16[4];
uint32_t uint32[2];
uint64_t uint64;
uint8_t int8[8];
uint16_t int16[4];
uint32_t int32[2];
uint64_t int64;
float float32;
double float64;
};
//void init(std::string& Name, std::string& DataType, uint16_t offset);
bool convertBinaryToJson(const std::vector<uint8_t>& vect_inp, nlohmann::json& j_out);
bool convertJsonToBinary(const nlohmann::json& j_inp, std::vector<uint8_t>& vect_out);
bool putBit(std::string& bit_name, uint32_t bit_pos);
static int getDataSize(const std::string& type_name);
private:
/**
* @brief Извлекает данные в вектор с учетом оффсета и эндиана
*
* @param vect
*/
void extractData(std::vector<uint8_t>& vect);
/**
* @brief Берет данные из вектора с учетом оффсета и эндиана
*
* @param vect
*/
void insertData(const std::vector<uint8_t>& vect);
/**
* @brief Кладет внутренние бинарные данные в rpc json
*
* @param j
* @return true
* @return false
*/
bool toRpcJson(nlohmann::json& j) const;
/**
* @brief Преобразовывает данные их rpc json в бинарные данные
*
* @param j
* @return true
* @return false
*/
bool fromRpcJson(const nlohmann::json& j);
private:
static const std::map<UserDataTypes, uint32_t> data_size;
static const std::map<std::string, UserDataTypes> data_corr;
public:
const std::string name; /// Имя данных
const UserDataTypes type; /// Тип данных
const uint32_t size; /// Размер данных
private:
AnyData data_; /// Данные
std::vector<UserDataBit> bits_; ///
const uint16_t data_offset_; /// Офсет от начала датаграммы откуда начинаются данные
};
struct SubmoduleUserData
{
std::map<std::string, UserData> inp_data_map; /// Ключ - имя данных внутри датаграммы
std::map<std::string, UserData> out_data_map; /// Ключ - имя данных внутри датаграммы
std::map<uint32_t, UserData> params_map; /// Ключ - индекс параметра подмодуля
};
enum
{
USER_DATA_ID_SUBMOD,
USER_DATA_ID_MOD,
USER_DATA_ID_TOTAL
};
using UserDataMap = std::map<uint64_t, SubmoduleUserData>; /// Ключ - битовое поле, где стартшие 32-бита - module_id, а младшие - submodule_id
SubmoduleUserData& UserData_addNewSubmod(uint32_t mod_id, uint32_t submod_id, UserDataMap& user_data_map);
SubmoduleUserData& UserData_getSubmod(uint32_t mod_id, uint32_t submod_id, UserDataMap& user_data_map);