uatools 1.0.0
 
Loading...
Searching...
No Matches
variantConverter.hpp
Go to the documentation of this file.
1
8
9#ifndef ESO_UATOOLS_PROTOCOL_OPEN62541_VARIANT_CONVERTER_H_
10#define ESO_UATOOLS_PROTOCOL_OPEN62541_VARIANT_CONVERTER_H_
11
12#include <string>
13#include <thread>
14#include <atomic>
15#include <chrono>
16#include <iostream>
17
18#include <boost/variant.hpp>
19
20#ifdef UA_ENABLE_AMALGAMATION
21# include <open62541.h>
22#else
23# include <open62541/types.h>
24#endif
25
28
29
31
32template<typename>
33inline constexpr bool always_false_v = false;
34
35// ---------- Scalar Mapping ----------
36template<typename T>
38
39template<> struct UaScalarTraits<bool> { using UaT = UA_Boolean; static constexpr auto Type = UA_TYPES_BOOLEAN; };
40template<> struct UaScalarTraits<int> { using UaT = UA_Int32; static constexpr auto Type = UA_TYPES_INT32; };
41template<> struct UaScalarTraits<unsigned int> { using UaT = UA_UInt32; static constexpr auto Type = UA_TYPES_UINT32; };
42template<> struct UaScalarTraits<short> { using UaT = UA_Int16; static constexpr auto Type = UA_TYPES_INT16; };
43template<> struct UaScalarTraits<double> { using UaT = UA_Double; static constexpr auto Type = UA_TYPES_DOUBLE; };
44template<> struct UaScalarTraits<std::string> { using UaT = UA_String; static constexpr auto Type = UA_TYPES_STRING; };
45template<> struct UaScalarTraits<uint16_t> { using UaT = UA_UInt16; static constexpr auto Type = UA_TYPES_UINT16; };
46template<> struct UaScalarTraits<float> { using UaT = UA_Float; static constexpr auto Type = UA_TYPES_FLOAT; };
47template<> struct UaScalarTraits<int8_t> { using UaT = UA_SByte; static constexpr auto Type = UA_TYPES_SBYTE; };
48template<> struct UaScalarTraits<uint8_t> { using UaT = UA_Byte; static constexpr auto Type = UA_TYPES_BYTE; };
49
50// ---------- Vector Trait Detection ----------
51template<typename T>
52struct is_std_vector : std::false_type {};
53
54template<typename T, typename A>
55struct is_std_vector<std::vector<T, A>> : std::true_type {};
56
57template<typename T>
59
65
69template<typename CType, typename UaType, const int TypeIndex>
71public:
72 static void ToUaVariant(const protocol::base::Variant src, UA_Variant& dst) {
73 UaType value = std::get<CType>(src);
74 UA_Variant_setScalarCopy(&dst, &value,
75 &UA_TYPES[TypeIndex]);
76 }
77
78 static void FromUaVariant(const UA_Variant src, protocol::base::Variant& dst) {
79 if (src.type == &UA_TYPES[TypeIndex]) {
80 UaType value = *reinterpret_cast<const UaType*>(src.data);
81 dst = CType(value); // construct CType from UaType
82 }
83 }
84};
85
86// Template specialization for converting strings
87template<>
88class VariantScalarConverter<std::string,UA_String,UA_TYPES_STRING> {
89public:
90
91 static void ToUaVariant(const protocol::base::Variant& src, UA_Variant& dst)
92 {
93 const std::string& s = std::get<std::string>(src);
94 UA_String value = UA_STRING_ALLOC(s.c_str());
95 UA_Variant_setScalarCopy(&dst, &value, &UA_TYPES[UA_TYPES_STRING]);
96 }
97
98 static void FromUaVariant(const UA_Variant& src, protocol::base::Variant& dst)
99 {
100 if (src.type == &UA_TYPES[UA_TYPES_STRING]) {
101 const UA_String& ua = *reinterpret_cast<const UA_String*>(src.data);
102 dst = std::string(reinterpret_cast<const char*>(ua.data), ua.length);
103 }
104 }
105};
106
110template<typename CType, typename UaType, const int TypeIndex>
112public:
113 static void ToUaVariant(const protocol::base::Variant& src, UA_Variant& dst)
114 {
115 const auto& vec = std::get<std::vector<CType>>(src);
116
117 UA_Variant_setArrayCopy(
118 &dst,
119 vec.data(),
120 static_cast<UA_Int32>(vec.size()),
121 &UA_TYPES[TypeIndex]
122 );
123 }
124
125 static void FromUaVariant(const UA_Variant& src, protocol::base::Variant& dst)
126 {
127 if (src.type == &UA_TYPES[TypeIndex] && src.arrayLength > 0) {
128 const UaType* data = reinterpret_cast<const UaType*>(src.data);
129
130 std::vector<CType> vec;
131 vec.reserve(src.arrayLength);
132
133 for (size_t i = 0; i < src.arrayLength; ++i) {
134 vec.emplace_back(static_cast<CType>(data[i]));
135 }
136
137 dst = std::move(vec);
138 }
139 }
140};
141
145template<int TypeIndex>
146class VariantArrayConverter<bool, UA_Boolean, TypeIndex> {
147public:
148 static void ToUaVariant(const protocol::base::Variant& src, UA_Variant& dst) {
149 const auto& vec = std::get<std::vector<bool>>(src);
150
151 // ✅ FORCE REAL BYTE STORAGE (never vector<bool>)
152 std::vector<uint8_t> tmp(vec.size());
153 for (size_t i = 0; i < vec.size(); ++i) {
154 tmp[i] = static_cast<uint8_t>(vec[i]);
155 }
156
157 UA_Variant_setArrayCopy(
158 &dst,
159 tmp.data(), // ✅ REAL contiguous memory
160 tmp.size(),
161 &UA_TYPES[TypeIndex]
162 );
163 }
164
165 static void FromUaVariant(const UA_Variant& src,
167 if (src.type == &UA_TYPES[TypeIndex] && src.arrayLength > 0) {
168
169 const uint8_t* data =
170 static_cast<const uint8_t*>(src.data);
171
172 std::vector<bool> vec(src.arrayLength);
173 for (size_t i = 0; i < src.arrayLength; ++i) {
174 vec[i] = data[i] != 0;
175 }
176
177 dst = std::move(vec);
178 }
179 }
180};
181
182
183
187template<>
188class VariantArrayConverter<std::string, UA_String, UA_TYPES_STRING> {
189public:
190 static void ToUaVariant(const protocol::base::Variant& src, UA_Variant& dst)
191 {
192 const auto& vec = std::get<std::vector<std::string>>(src);
193
194 std::vector<UA_String> uaVec;
195 uaVec.reserve(vec.size());
196
197 for (const auto& s : vec) {
198 uaVec.emplace_back(UA_STRING_ALLOC(s.c_str()));
199 }
200
201 UA_Variant_setArrayCopy(
202 &dst,
203 uaVec.data(),
204 static_cast<UA_Int32>(uaVec.size()),
205 &UA_TYPES[UA_TYPES_STRING]
206 );
207
208 // Clean up temporary UA_String allocations
209 for (auto& s : uaVec) {
210 UA_String_clear(&s);
211 }
212 }
213
214 static void FromUaVariant(const UA_Variant& src, protocol::base::Variant& dst)
215 {
216 if (src.type == &UA_TYPES[UA_TYPES_STRING] && src.arrayLength > 0) {
217 const UA_String* data = reinterpret_cast<const UA_String*>(src.data);
218
219 std::vector<std::string> vec;
220 vec.reserve(src.arrayLength);
221
222 for (size_t i = 0; i < src.arrayLength; ++i) {
223 vec.emplace_back(
224 reinterpret_cast<const char*>(data[i].data),
225 data[i].length
226 );
227 }
228
229 dst = std::move(vec);
230 }
231 }
232};
233
234
235
236} // namespace
237
238#endif // ESO_UATOOLS_PROTOCOL_OPEN62541_VARIANT_CONVERTER_H_
static void FromUaVariant(const UA_Variant &src, protocol::base::Variant &dst)
Definition variantConverter.hpp:165
static void ToUaVariant(const protocol::base::Variant &src, UA_Variant &dst)
Definition variantConverter.hpp:148
static void FromUaVariant(const UA_Variant &src, protocol::base::Variant &dst)
Definition variantConverter.hpp:214
static void ToUaVariant(const protocol::base::Variant &src, UA_Variant &dst)
Definition variantConverter.hpp:190
Converts a variant holding a vector (OPC UA array).
Definition variantConverter.hpp:111
static void FromUaVariant(const UA_Variant &src, protocol::base::Variant &dst)
Definition variantConverter.hpp:125
static void ToUaVariant(const protocol::base::Variant &src, UA_Variant &dst)
Definition variantConverter.hpp:113
static void FromUaVariant(const UA_Variant &src, protocol::base::Variant &dst)
Definition variantConverter.hpp:98
static void ToUaVariant(const protocol::base::Variant &src, UA_Variant &dst)
Definition variantConverter.hpp:91
Converts a variant holding a scalar value.
Definition variantConverter.hpp:70
static void ToUaVariant(const protocol::base::Variant src, UA_Variant &dst)
Definition variantConverter.hpp:72
static void FromUaVariant(const UA_Variant src, protocol::base::Variant &dst)
Definition variantConverter.hpp:78
std::variant< bool, std::int8_t, std::uint8_t, short, unsigned short, int, unsigned int, float, double, std::string, std::vector< bool >, std::vector< short >, std::vector< int >, std::vector< unsigned int >, std::vector< float >, std::vector< double >, std::vector< std::string > > Variant
Definition icomm_adapter_min_v1.hpp:53
Definition iDataChangeHandler.hpp:27
constexpr bool always_false_v
Definition variantConverter.hpp:33
constexpr bool is_std_vector_v
Definition variantConverter.hpp:58
UA_Boolean UaT
Definition variantConverter.hpp:39
static constexpr auto Type
Definition variantConverter.hpp:39
UA_Double UaT
Definition variantConverter.hpp:43
static constexpr auto Type
Definition variantConverter.hpp:43
static constexpr auto Type
Definition variantConverter.hpp:46
UA_Float UaT
Definition variantConverter.hpp:46
UA_SByte UaT
Definition variantConverter.hpp:47
static constexpr auto Type
Definition variantConverter.hpp:47
UA_Int32 UaT
Definition variantConverter.hpp:40
static constexpr auto Type
Definition variantConverter.hpp:40
static constexpr auto Type
Definition variantConverter.hpp:42
UA_Int16 UaT
Definition variantConverter.hpp:42
UA_String UaT
Definition variantConverter.hpp:44
static constexpr auto Type
Definition variantConverter.hpp:44
UA_UInt16 UaT
Definition variantConverter.hpp:45
static constexpr auto Type
Definition variantConverter.hpp:45
static constexpr auto Type
Definition variantConverter.hpp:48
UA_Byte UaT
Definition variantConverter.hpp:48
static constexpr auto Type
Definition variantConverter.hpp:41
UA_UInt32 UaT
Definition variantConverter.hpp:41
Definition variantConverter.hpp:37
Definition variantConverter.hpp:52