open62541pp 0.15.0
C++ wrapper of open62541
Loading...
Searching...
No Matches
attribute_handler.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <type_traits>
5#include <utility> // exchange, move
6#include <vector>
7
9#include "open62541pp/common.hpp" // AttributeId, WriteMask, EventNotifier, AccessLevel
13#include "open62541pp/types.hpp"
14
16
17inline Result<Variant> getVariant(DataValue&& dv) noexcept {
18 if (dv.getStatus().isBad()) {
19 return BadResult(dv.getStatus());
20 }
21 if (!dv.hasValue()) {
23 }
24 return std::move(dv).getValue();
25}
26
27template <typename T>
28inline Result<T> tryGetScalar(Variant&& var) noexcept {
29 return opcua::detail::tryInvoke([&] { return std::move(var).getScalar<T>(); });
30}
31
32template <typename T>
33inline Result<std::vector<T>> tryGetArray(Variant&& var) noexcept {
34 return opcua::detail::tryInvoke([&] { return std::move(var).getArrayCopy<T>(); });
35}
36
38 DataValue dv;
39 dv.setStatus(code);
40 return dv;
41}
42
43/**
44 * Attribute handler to convert DataValue objects to/from the attribute specific types.
45 * Template specializations must be provided for all AttributeIds.
46 */
47template <AttributeId Attribute>
49
51 using Type = Variant;
52
53 static Result<Variant> fromDataValue(DataValue&& dv) noexcept {
54 return getVariant(std::move(dv));
55 }
56
57 static DataValue toDataValue(const Variant& value) noexcept {
58 DataValue dv;
59 dv->value = value; // shallow copy
60 dv->value.storageType = UA_VARIANT_DATA_NODELETE; // prevent double delete
61 dv->hasValue = true;
62 return dv;
63 }
64};
65
66template <typename T, typename Enable = void>
68 using Type = T;
69
70 static Result<Type> fromDataValue(DataValue&& dv) noexcept {
71 return getVariant(std::move(dv)).andThen(tryGetScalar<T>);
72 }
73
74 template <typename U>
75 static DataValue toDataValue(U&& value) noexcept {
76 return opcua::detail::tryInvoke([&] {
77 return DataValue::fromScalar(std::forward<U>(value));
78 })
80 .value();
81 }
82};
83
84template <typename T>
85struct AttributeHandlerScalar<T, std::enable_if_t<std::is_enum_v<T>>> {
86 using Type = T;
87 using UnderlyingType = std::underlying_type_t<Type>;
89
90 static Result<Type> fromDataValue(DataValue&& dv) noexcept {
91 return UnderlyingHandler::fromDataValue(std::move(dv)).transform([](auto value) {
92 return static_cast<Type>(value);
93 });
94 }
95
96 static DataValue toDataValue(Type value) noexcept {
97 return UnderlyingHandler::toDataValue(static_cast<UnderlyingType>(value));
98 }
99};
100
101template <typename T>
106
107 static Result<Type> fromDataValue(DataValue&& dv) noexcept {
108 return UnderlyingHandler::fromDataValue(std::move(dv)).transform([](auto value) {
109 return Bitmask<T>(value);
110 });
111 }
112
113 static DataValue toDataValue(Type value) noexcept {
114 return UnderlyingHandler::toDataValue(value.get());
115 }
116};
117
118template <>
120
121template <>
124
125 static Result<Type> fromDataValue(DataValue&& dv) noexcept {
126 return getVariant(std::move(dv)).transform([](const Variant& var) {
127 // workaround to read enum from variant...
128 return *static_cast<const NodeClass*>(var.data());
129 });
130 }
131};
132
133template <>
135
136template <>
138
139template <>
141
142template <>
144
145template <>
147
148template <>
150
151template <>
153
154template <>
156
157template <>
159
160template <>
162 : AttributeHandlerScalar<Bitmask<EventNotifier>> {};
163
164template <>
166
167template <>
169
170template <>
172
173template <>
175 using Type = std::vector<uint32_t>;
176
177 static Result<Type> fromDataValue(DataValue&& dv) noexcept {
178 return getVariant(std::move(dv)).andThen(tryGetArray<uint32_t>);
179 }
180
181 static DataValue toDataValue(Span<const uint32_t> dimensions) noexcept {
182 return opcua::detail::tryInvoke([&] { return DataValue::fromArray(dimensions); })
184 .value();
185 }
186};
187
188template <>
190
191template <>
194
195template <>
197
198template <>
200
201template <>
203
204template <>
206
207template <>
209
210} // namespace opcua::services::detail
Represents a bad result stored in Result.
Definition result.hpp:17
Bitmask using (scoped) enums.
Definition bitmask.hpp:125
std::underlying_type_t< T > Underlying
Definition bitmask.hpp:130
UA_DataType wrapper class.
Definition datatype.hpp:25
UA_DataValue wrapper class.
Definition types.hpp:1478
bool hasValue() const noexcept
Definition types.hpp:1525
static DataValue fromScalar(Args &&... args)
Create DataValue from scalar value.
Definition types.hpp:1514
static DataValue fromArray(Args &&... args)
Create DataValue from array.
Definition types.hpp:1521
void setStatus(StatusCode status) noexcept
Set status.
Definition types.hpp:1631
UA_NodeId wrapper class.
Definition types.hpp:590
The template class Result encapsulates a StatusCode and optionally a value.
Definition result.hpp:53
View to a contiguous sequence of objects, similar to std::span in C++20.
Definition span.hpp:26
UA_StatusCode wrapper class.
Definition types.hpp:44
UA_Variant wrapper class.
Definition types.hpp:887
void * data() noexcept
Get pointer to the underlying data.
Definition types.hpp:1007
auto tryInvoke(F &&func, Args &&... args) noexcept -> typename ResultType< std::invoke_result_t< F, Args... > >::Type
Invoke a function and capture its Result (value or status code).
DataValue createDataValueFromStatus(StatusCode code) noexcept
Result< T > tryGetScalar(Variant &&var) noexcept
Result< Variant > getVariant(DataValue &&dv) noexcept
Result< std::vector< T > > tryGetArray(Variant &&var) noexcept
NodeClass
Node class.
Definition common.hpp:138
AccessLevel
Access level.
Definition common.hpp:161
EventNotifier
Event notifier.
Definition common.hpp:241
ValueRank
Value rank.
Definition common.hpp:224
WriteMask
Write mask.
Definition common.hpp:183
AttributeId
Attribute identifiers.
Definition common.hpp:28
@ UserExecutable
Indicates if the method is currently executable taking user access rights into account.
@ Historizing
Indicates whether the server is actively collecting data for the history of the variable.
@ Executable
Indicates if the method is currently executable.
@ DisplayName
The localized name of the node.
@ BrowseName
A non-localised human-readable name used to browse the address space.
@ Value
The most recent value of the variable that the server has.
@ MinimumSamplingInterval
Specifies (in milliseconds) how fast the server can reasonably sample the value for changes.
@ IsAbstract
If a reference is abstract, no reference of this type shall exist, only of its subtypes.
@ InverseName
The inverse name describes the reference type as seen from the target node.
@ Description
Explains the meaning of the node in a localized text.
@ UserWriteMask
Exposes the possibilities of a client to write the attributes of the node.
@ ArrayDimensions
Specifies the maximum supported length of each dimension of the Value attribute.
@ ContainsNoLoops
Indicates that by following the references in the context of the view there are no loops.
@ UserAccessLevel
Indicates how the value of a variable can be accessed (read/write) and if it contains current and/or ...
@ DataTypeDefinition
Provides the meta data and encoding information for custom data types.
@ Symmetric
If a reference is symmetric, it can seen from both the source and target node.
#define UA_STATUSCODE_BADUNEXPECTEDERROR
static Result< Type > fromDataValue(DataValue &&dv) noexcept
static Result< Type > fromDataValue(DataValue &&dv) noexcept
static DataValue toDataValue(U &&value) noexcept
static DataValue toDataValue(const Variant &value) noexcept
static Result< Variant > fromDataValue(DataValue &&dv) noexcept
static DataValue toDataValue(Span< const uint32_t > dimensions) noexcept
Attribute handler to convert DataValue objects to/from the attribute specific types.
UA_VARIANT_DATA_NODELETE