9#include <initializer_list>
63 std::string_view
name() const noexcept {
68 constexpr bool isGood() const noexcept {
69 return detail::isGood(
native());
74 return detail::isUncertain(
native());
78 constexpr bool isBad() const noexcept {
79 return detail::isBad(
native());
96template <
typename WrapperType,
typename CharT>
97class StringLikeMixin {
100 using value_type = CharT;
101 using size_type = size_t;
102 using difference_type = std::ptrdiff_t;
103 using pointer = value_type*;
104 using const_pointer =
const value_type*;
105 using reference = value_type&;
106 using const_reference =
const value_type&;
107 using iterator = pointer;
108 using const_iterator = const_pointer;
109 using reverse_iterator = std::reverse_iterator<iterator>;
110 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
113 size_t size() const noexcept {
114 const auto& native =
asNative(
static_cast<const WrapperType&
>(*
this));
115 return native.length;
118 size_t length() const noexcept {
122 bool empty() const noexcept {
126 pointer data() noexcept {
127 auto& native =
asNative(
static_cast<WrapperType&
>(*
this));
128 return reinterpret_cast<pointer
>(native.data);
131 const_pointer data() const noexcept {
132 const auto& native =
asNative(
static_cast<const WrapperType&
>(*
this));
133 return reinterpret_cast<const_pointer
>(native.data);
136 reference operator[](
size_t index)
noexcept {
137 assert(index < size());
138 return data()[index];
141 const_reference operator[](
size_t index)
const noexcept {
142 assert(index < size());
143 return data()[index];
146 reference front() noexcept {
151 const_reference front() const noexcept {
156 reference back() noexcept {
158 return *(data() + size() - 1);
161 const_reference back() const noexcept {
163 return *(data() + size() - 1);
166 iterator begin() noexcept {
170 const_iterator begin() const noexcept {
174 const_iterator cbegin() const noexcept {
178 iterator end() noexcept {
179 return {data() + size()};
182 const_iterator end() const noexcept {
183 return {data() + size()};
186 const_iterator cend() const noexcept {
187 return {data() + size()};
190 reverse_iterator rbegin() noexcept {
191 return reverse_iterator(end());
194 const_reverse_iterator rbegin() const noexcept {
195 return const_reverse_iterator(end());
198 const_reverse_iterator crbegin() const noexcept {
199 return const_reverse_iterator(cend());
202 reverse_iterator rend() noexcept {
203 return reverse_iterator(begin());
206 const_reverse_iterator rend() const noexcept {
207 return const_reverse_iterator(begin());
210 const_reverse_iterator crend() const noexcept {
211 return const_reverse_iterator(cbegin());
215 void init(
size_t length) {
216 auto& native =
asNative(
static_cast<WrapperType&
>(*
this));
217 native.length = length;
219 native.data =
static_cast<uint8_t*
>(
UA_malloc(length));
220 if (data() ==
nullptr) {
221 throw BadStatus(UA_STATUSCODE_BADOUTOFMEMORY);
226 template <
typename InputIt>
227 void init(InputIt first, InputIt last) {
228 init(first, last,
typename std::iterator_traits<InputIt>::iterator_category{});
231 template <
typename InputIt,
typename Tag>
232 void init(InputIt first, InputIt last, Tag ) {
233 init(std::distance(first, last));
234 std::copy(first, last, data());
237 template <
typename InputIt>
238 void init(InputIt first, InputIt last, std::input_iterator_tag ) {
240 std::vector<uint8_t> buffer(first, last);
242 std::copy(buffer.begin(), buffer.end(), data());
256 public detail::StringLikeMixin<String, char> {
263 template <
typename InputIt>
268 String(std::initializer_list<char> values) {
269 init(values.begin(), values.end());
279 template <
typename Traits>
286 template <
typename Traits>
287 operator std::basic_string_view<char, Traits>() const noexcept {
288 return {data(), size()};
292 [[deprecated(
"use conversion with static_cast instead")]]
293 std::string_view
get() const noexcept {
294 return {data(), size()};
305 return !(lhs == rhs);
310 return static_cast<std::string_view
>(lhs) == rhs;
315 return static_cast<std::string_view
>(lhs) != rhs;
320 return lhs ==
static_cast<std::string_view
>(rhs);
325 return lhs !=
static_cast<std::string_view
>(rhs);
331template <
typename Traits>
333 using Type = std::basic_string_view<char, Traits>;
337 dst =
Type{src.data(), src.size()};
345template <
typename Traits,
typename Allocator>
347 using Type = std::basic_string<char, Traits, Allocator>;
351 dst =
Type{src.data(), src.size()};
375 dst =
NativeType{std::string_view{
static_cast<const char*
>(src), N}};
393 using UaDuration = std::chrono::duration<int64_t, std::ratio<1, 10'000'000>>;
397 template <
typename Clock,
typename Duration>
398 DateTime(std::chrono::time_point<Clock, Duration> timePoint)
407 template <
typename Clock,
typename Duration>
411 std::chrono::duration_cast<UaDuration>(timePoint.time_since_epoch()).count()
417 return DateTime(UA_DateTime_fromUnixTime(unixTime));
426 template <
typename Clock = DefaultClock,
typename Duration = UaDuration>
428 const std::chrono::time_point<Clock, Duration> unixEpoch{};
433 return unixEpoch + std::chrono::duration_cast<Duration>(sinceEpoch);
441 return UA_DateTime_toUnixTime(
get());
450 int64_t
get() const noexcept {
456 std::string
format(std::string_view
format,
bool localtime =
false)
const;
459template <
typename Clock,
typename Duration>
461 using Type = std::chrono::time_point<Clock, Duration>;
483 explicit Guid(std::array<uint8_t, 16> data) noexcept
486 static_cast<uint32_t
>(
487 (data[0] << 24U) | (data[1] << 16U) | (data[2] << 8U) | data[3]
489 static_cast<uint16_t
>((data[4] << 8U) | data[5]),
490 static_cast<uint16_t
>((data[6] << 8U) | data[7]),
492 {data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]},
495 Guid(uint32_t data1, uint16_t data2, uint16_t data3, std::array<uint8_t, 8> data4) noexcept
500 {data4[0], data4[1], data4[2], data4[3], data4[4], data4[5], data4[6], data4[7]},
517 return !(lhs == rhs);
530 :
public TypeWrapper<UA_ByteString, UA_TYPES_BYTESTRING>,
531 public detail::StringLikeMixin<ByteString, uint8_t> {
545 template <
typename InputIt>
555 template <
typename Traits>
556 explicit operator std::basic_string_view<char, Traits>() const noexcept {
557 return {
reinterpret_cast<const char*
>(data()), size()};
565 [[deprecated(
"use conversion with static_cast instead")]]
566 std::string_view
get() const noexcept {
567 return {
reinterpret_cast<const char*
>(data()), size()};
573 return (
static_cast<std::string_view
>(lhs) == rhs);
578 return (
static_cast<std::string_view
>(lhs) != rhs);
583 return (lhs ==
static_cast<std::string_view
>(rhs));
588 return (lhs !=
static_cast<std::string_view
>(rhs));
598 :
public TypeWrapper<UA_XmlElement, UA_TYPES_XMLELEMENT>,
599 public detail::StringLikeMixin<XmlElement, char> {
606 template <
typename InputIt>
618 template <
typename Traits>
625 template <
typename Traits>
626 operator std::basic_string_view<char, Traits>() const noexcept {
627 return {data(), size()};
631 [[deprecated(
"use conversion with static_cast instead")]]
632 std::string_view
get() const noexcept {
633 return {data(), size()};
643template <
typename T,
typename =
void>
644struct IsNodeIdEnum : std::false_type {};
647struct IsNodeIdEnum<T, std::void_t<decltype(namespaceOf(std::declval<T>()))>> : std::is_enum<T> {};
703 template <typename T, typename = std::enable_if_t<detail::IsNodeIdEnum<T>::value>>
711 uint32_t
hash() const noexcept {
720 [[deprecated(
"use namespaceIndex() instead")]]
730 [[deprecated(
"use identifierType() instead")]]
745 template <
typename T>
747 return const_cast<T*
>(std::as_const(*this).identifierIf<T>());
751 template <
typename T>
754 detail::IsOneOf<T, uint32_t, String, Guid, ByteString>::value,
755 "Invalid type for NodeId identifier"
758 if constexpr (std::is_same_v<T, uint32_t>) {
763 if constexpr (std::is_same_v<T, String>) {
768 if constexpr (std::is_same_v<T, Guid>) {
773 if constexpr (std::is_same_v<T, ByteString>) {
792 template <
typename T>
794 return const_cast<T&
>(std::as_const(*this).identifier<T>());
798 template <
typename T>
803 throw TypeError(
"NodeId identifier type doesn't match the requested type");
808 [[deprecated(
"use identifier<T>() or identifierIf<T>() instead")]]
810 return getIdentifierImpl();
815 template <
typename T>
816 [[deprecated(
"use identifier<T>() or identifierIf<T>() instead")]]
818 return getIdentifierAsImpl<T>();
823 template <NodeIdType E>
824 [[deprecated(
"use identifier<T>() or identifierIf<T>() instead")]]
826 return getIdentifierAsImpl<E>();
834 std::variant<uint32_t, String, Guid, ByteString> getIdentifierImpl()
const {
849 template <
typename T>
850 auto getIdentifierAsImpl()
const {
851 return std::get<T>(getIdentifierImpl());
854 template <NodeIdType E>
855 auto getIdentifierAsImpl()
const {
857 return getIdentifierAsImpl<uint32_t>();
860 return getIdentifierAsImpl<String>();
863 return getIdentifierAsImpl<Guid>();
866 return getIdentifierAsImpl<ByteString>();
873 return UA_NodeId_equal(&lhs, &rhs);
878 return !(lhs == rhs);
893 return (lhs < rhs) || (lhs == rhs);
898 return (lhs > rhs) || (lhs == rhs);
926 uint32_t
hash() const noexcept {
939 [[deprecated(
"use nodeId() instead")]]
945 [[deprecated(
"use nodeId() instead")]]
955 [[deprecated(
"use namespaceUri() instead")]]
965 [[deprecated(
"use serverIndex() instead")]]
977 return UA_ExpandedNodeId_equal(&lhs, &rhs);
982 return !(lhs == rhs);
997 return (lhs < rhs) || (lhs == rhs);
1002 return (lhs > rhs) || (lhs == rhs);
1025 [[deprecated(
"use namespaceIndex() instead")]]
1030 std::string_view
name() const noexcept {
1035 [[deprecated(
"use name() instead")]]
1043 return (lhs.namespaceIndex == rhs.namespaceIndex) && (lhs.name == rhs.name);
1048 return !(lhs == rhs);
1076 [[deprecated(
"use locale() instead")]]
1081 std::string_view
text() const noexcept {
1086 [[deprecated(
"use text() instead")]]
1094 return (lhs.locale == rhs.locale) && (lhs.text == rhs.text);
1099 return !(lhs == rhs);
1118 using TypeError::TypeError;
1178 template <
typename T>
1179 static constexpr bool isVariant =
1180 std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>,
Variant> ||
1181 std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>,
UA_Variant>;
1188 template <
typename T,
typename = std::enable_if_t<!std::is_const_v<T>>>
1195 template <
typename T,
typename = std::enable_if_t<!std::is_const_v<T>>>
1202 template <
typename T,
typename = std::enable_if_t<!isVariant<T>>>
1209 template <
typename T>
1216 template <
typename InputIt>
1223 template <
typename InputIt>
1230 [[deprecated(
"use new universal Variant constructor instead")]] [[nodiscard]]
1233 return Variant{std::forward<T>(value), std::forward<Args>(
args)...};
1235 return Variant{&value, std::forward<Args>(
args)...};
1241 [[deprecated(
"use new universal Variant constructor instead")]] [[nodiscard]]
1252 [[deprecated(
"use new universal Variant constructor instead")]] [[nodiscard]]
1254 return Variant{first, last, std::forward<Args>(
args)...};
1263 void assign(std::nullptr_t ptr)
noexcept =
delete;
1276 template <
typename T,
typename = std::enable_if_t<!std::is_const_v<T>>>
1278 if constexpr (isArrayType<T>()) {
1279 using ValueType =
typename T::value_type;
1280 assertIsRegistered<ValueType>();
1283 assertIsRegistered<T>();
1293 template <
typename T,
typename = std::enable_if_t<!std::is_const_v<T>>>
1295 if (ptr ==
nullptr) {
1297 }
else if constexpr (isArrayType<T>()) {
1311 template <
typename T>
1313 if constexpr (isArrayType<T>()) {
1314 assign(value.begin(), value.end());
1316 assertIsRegisteredOrConvertible<T>();
1317 if constexpr (detail::isRegisteredType<T>) {
1320 setScalarCopyConvertImpl(value);
1333 template <
typename T>
1335 if constexpr (isArrayType<T>()) {
1336 setArrayCopyImpl(value.begin(), value.end(),
type);
1338 setScalarCopyImpl(value,
type);
1348 template <
typename InputIt>
1350 using ValueType =
typename std::iterator_traits<InputIt>::value_type;
1351 assertIsRegisteredOrConvertible<ValueType>();
1352 if constexpr (detail::isRegisteredType<ValueType>) {
1355 setArrayCopyConvertImpl(first, last);
1366 template <
typename InputIt>
1368 setArrayCopyImpl(first, last,
type);
1373 template <
typename T,
typename = std::enable_if_t<!isVariant<T>>>
1381 template <
typename T,
typename = std::enable_if_t<!isVariant<T>>>
1388 template <
typename T,
typename... Args>
1389 [[deprecated(
"use assign overload with pointer instead")]]
1395 template <
typename T,
typename... Args>
1396 [[deprecated(
"use assign overload instead")]]
1402 template <
typename T,
typename... Args>
1403 [[deprecated(
"use assign overload with pointer instead")]]
1409 template <
typename T,
typename... Args>
1410 [[deprecated(
"use assign overload instead")]]
1416 template <
typename InputIt,
typename... Args>
1417 [[deprecated(
"use assign overload instead")]]
1419 assign(first, last, std::forward<Args>(
args)...);
1433 [[deprecated(
"use empty() instead")]]
1469 template <
typename T>
1480 [[deprecated(
"use type() instead")]]
1491 [[deprecated(
"use arrayLength() instead")]]
1502 [[deprecated(
"use arrayDimensions() instead")]]
1521 const void*
data() const noexcept {
1527 template <
typename T>
1529 assertIsRegistered<T>();
1536 template <
typename T>
1538 assertIsRegistered<T>();
1541 return *
static_cast<const T*
>(
handle()->
data);
1545 template <
typename T>
1551 template <
typename T>
1557 template <
typename T>
1558 [[deprecated(
"use scalar() instead")]]
1564 template <
typename T>
1565 [[deprecated(
"use scalar() instead")]]
1571 template <
typename T>
1572 [[deprecated(
"use to<T>() instead")]]
1579 template <
typename T>
1581 assertIsRegistered<T>();
1589 template <
typename T>
1591 assertIsRegistered<T>();
1598 template <
typename T>
1599 [[deprecated(
"use array() instead")]]
1605 template <
typename T>
1606 [[deprecated(
"use array() instead")]]
1612 template <
typename T>
1613 [[deprecated(
"use to<std::vector<T>>() instead")]]
1641 template <
typename T>
1642 [[nodiscard]] T
to()
const {
1643 if constexpr (isArrayType<T>()) {
1644 return toArrayImpl<T>();
1646 return toScalarImpl<T>();
1655 template <
typename T>
1656 static constexpr bool isScalarType() noexcept {
1657 return detail::isRegisteredType<T> || detail::isConvertibleType<T>;
1660 template <
typename T>
1661 static constexpr bool isArrayType() noexcept {
1662 return detail::isContainer<T> && !isScalarType<T>();
1665 template <
typename T>
1666 static constexpr void assertIsRegistered() {
1668 detail::isRegisteredType<T>,
1669 "Template type must be a native/wrapper type to assign or get scalar/array without copy"
1673 template <
typename T>
1674 static constexpr void assertIsRegisteredOrConvertible() {
1676 detail::isRegisteredType<T> || detail::isConvertibleType<T>,
1677 "Template type must be either a native/wrapper type or a convertible type. "
1678 "If the type is a native type: Provide the type definition (UA_DataType) manually or "
1679 "register the type with a TypeRegistry template specialization. "
1680 "If the type should be converted: Add a template specialization for TypeConverter."
1684 template <
typename T>
1685 static constexpr void assertNoVariant() {
1686 static_assert(!isVariant<T>,
"Variants cannot directly contain another variant");
1689 void checkIsScalar()
const {
1691 throw BadVariantAccess(
"Variant is not a scalar");
1695 void checkIsArray()
const {
1697 throw BadVariantAccess(
"Variant is not an array");
1701 template <
typename T>
1702 void checkIsType()
const {
1703 const auto* dt =
type();
1705 throw BadVariantAccess(
"Variant does not contain a value convertible to template type");
1709 template <
typename T>
1710 T toScalarImpl()
const;
1711 template <
typename T>
1712 T toArrayImpl()
const;
1714 template <
typename T>
1715 inline void setScalarImpl(
1718 template <
typename T>
1719 inline void setArrayImpl(
1722 template <
typename T>
1723 inline void setScalarCopyImpl(
const T& value,
const UA_DataType&
type);
1724 template <
typename T>
1725 inline void setScalarCopyConvertImpl(
const T& value);
1726 template <
typename InputIt>
1727 inline void setArrayCopyImpl(InputIt first, InputIt last,
const UA_DataType&
type);
1728 template <
typename InputIt>
1729 inline void setArrayCopyConvertImpl(InputIt first, InputIt last);
1732template <
typename T>
1733T Variant::toScalarImpl()
const {
1734 assertIsRegisteredOrConvertible<T>();
1735 if constexpr (detail::isRegisteredType<T>) {
1738 using Native =
typename TypeConverter<T>::NativeType;
1743template <
typename T>
1744T Variant::toArrayImpl()
const {
1745 using ValueType =
typename T::value_type;
1746 assertIsRegisteredOrConvertible<ValueType>();
1747 if constexpr (detail::isRegisteredType<ValueType>) {
1751 using Native =
typename TypeConverter<ValueType>::NativeType;
1754 detail::TransformIterator(
native.begin(), detail::fromNative<ValueType>),
1755 detail::TransformIterator(
native.end(), detail::fromNative<ValueType>)
1760template <
typename T>
1761void Variant::setScalarImpl(
1764 assertNoVariant<T>();
1765 assert(
sizeof(T) == type.memSize);
1767 handle()->type = &type;
1768 handle()->storageType = storageType;
1769 handle()->data = data;
1772template <
typename T>
1773void Variant::setArrayImpl(
1776 assertNoVariant<T>();
1777 assert(
sizeof(T) == type.memSize);
1779 handle()->type = &type;
1780 handle()->storageType = storageType;
1781 handle()->data = data;
1782 handle()->arrayLength = arrayLength;
1785template <
typename T>
1786void Variant::setScalarCopyImpl(
const T& value,
const UA_DataType& type) {
1787 auto native = detail::allocateUniquePtr<T>(
type);
1789 setScalarImpl(
native.release(),
type, UA_VARIANT_DATA);
1792template <
typename T>
1793void Variant::setScalarCopyConvertImpl(
const T& value) {
1794 using Native =
typename TypeConverter<T>::NativeType;
1796 auto native = detail::allocateUniquePtr<Native>(
type);
1797 *
native = detail::toNative(value);
1798 setScalarImpl(
native.release(),
type, UA_VARIANT_DATA);
1801template <
typename InputIt>
1802void Variant::setArrayCopyImpl(InputIt first, InputIt last,
const UA_DataType& type) {
1803 using ValueType =
typename std::iterator_traits<InputIt>::value_type;
1804 const size_t size = std::distance(first, last);
1805 auto native = detail::allocateArrayUniquePtr<ValueType>(size,
type);
1806 std::transform(first, last,
native.get(), [&](
const ValueType& value) {
1807 return detail::copy(value, type);
1809 setArrayImpl(
native.release(), size,
type, UA_VARIANT_DATA);
1812template <
typename InputIt>
1813void Variant::setArrayCopyConvertImpl(InputIt first, InputIt last) {
1814 using ValueType =
typename std::iterator_traits<InputIt>::value_type;
1815 using Native =
typename TypeConverter<ValueType>::NativeType;
1817 const size_t size = std::distance(first, last);
1818 auto native = detail::allocateArrayUniquePtr<Native>(size,
type);
1819 std::transform(first, last,
native.get(), [&](
const ValueType& value) {
1820 return detail::toNative(value);
1822 setArrayImpl(
native.release(), size,
type, UA_VARIANT_DATA);
1846 std::optional<StatusCode>
status
1869 [[deprecated(
"use constructor with new universal Variant constructor instead")]] [[nodiscard]]
1879 [[deprecated(
"use constructor with new universal Variant constructor instead")]] [[nodiscard]]
1962 return std::move(
value());
1967 return std::move(
value());
1971 [[deprecated(
"use value() instead")]]
1977 [[deprecated(
"use value() instead")]]
1983 [[deprecated(
"use value() instead")]]
1985 return std::move(
value());
1989 [[deprecated(
"use value() instead")]]
1991 return std::move(
value());
2000 [[deprecated(
"use sourceTimestamp() instead")]]
2011 [[deprecated(
"use serverTimestamp() instead")]]
2022 [[deprecated(
"use sourcePicoseconds() instead")]]
2033 [[deprecated(
"use serverPicoseconds() instead")]]
2044 [[deprecated(
"use status() instead")]]
2079 template <
typename T>
2080 static constexpr bool isExtensionObject =
2081 std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>,
ExtensionObject> ||
2092 template <
typename T>
2102 template <
typename T>
2104 if (ptr ==
nullptr) {
2107 assert(
sizeof(T) == type.memSize);
2117 template <
typename T,
typename = std::enable_if_t<!isExtensionObject<T>>>
2126 template <
typename T,
typename = std::enable_if_t<!isExtensionObject<T>>>
2128 auto ptr = detail::allocateUniquePtr<T>(type);
2129 *ptr = detail::copy(decoded, type);
2136 template <
typename T,
typename... Args>
2137 [[deprecated(
"use new universal ExtensionObject constructor instead")]] [[nodiscard]]
2143 template <
typename T,
typename... Args>
2144 [[deprecated(
"use new universal ExtensionObject constructor instead")]] [[nodiscard]]
2155 [[deprecated(
"use empty() instead")]]
2178 [[deprecated(
"use encoding() instead")]]
2192 [[deprecated(
"use encodedTypeId() instead")]]
2214 [[deprecated(
"use encodedBinary() or encodedXml() instead")]]
2230 [[deprecated(
"use decodedType() instead")]]
2238 template <
typename T>
2240 return isDecodedType<T>() ?
static_cast<T*
>(
decodedData()) :
nullptr;
2246 template <
typename T>
2248 return isDecodedType<T>() ?
static_cast<const T*
>(
decodedData()) :
nullptr;
2252 template <
typename T>
2253 [[deprecated(
"use decodedData<T>() instead")]]
2259 template <
typename T>
2260 [[deprecated(
"use decodedData<T>() instead")]]
2284 [[deprecated(
"use decodedData() instead")]]
2290 [[deprecated(
"use decodedData() instead")]]
2296 template <
typename T>
2297 bool isDecodedType() const noexcept {
2347 [[deprecated(
"use symbolicId() instead")]]
2357 [[deprecated(
"use namespaceUri() instead")]]
2367 [[deprecated(
"use localizedText() instead")]]
2377 [[deprecated(
"use locale() instead")]]
2387 [[deprecated(
"use additionalInfo() instead")]]
2397 [[deprecated(
"use innerStatusCode() instead")]]
2407 [[deprecated(
"use innerDiagnosticInfo() instead")]]
2421 return (lhs.min == rhs.min) && (lhs.max == rhs.max);
2428 return !(lhs == rhs);
2473 :
Wrapper(std::exchange(other.native(), {})) {}
2476 if (
this != &other) {
2484 if (
this != &other) {
2486 native() = std::exchange(other.native(), {});
2502 void clear() noexcept {
2509 result.
dimensions = detail::copyArray(array, size);
2510 result.dimensionsSize = size;
2531struct std::hash<
opcua::ExpandedNodeId> {
UA_ByteString wrapper class.
bool operator==(const ByteString &lhs, std::string_view rhs) noexcept
std::string_view get() const noexcept
std::string toBase64() const
Convert to Base64 encoded string.
bool operator!=(const ByteString &lhs, std::string_view rhs) noexcept
ByteString(InputIt first, InputIt last)
ByteString(std::string_view str)
bool operator!=(std::string_view lhs, const ByteString &rhs) noexcept
ByteString(Span< const uint8_t > bytes)
static ByteString fromBase64(std::string_view encoded)
Parse ByteString from Base64 encoded string.
bool operator==(std::string_view lhs, const ByteString &rhs) noexcept
ByteString(const char *str)
Client * asWrapper(UA_Client *client) noexcept
Convert native UA_Client pointer to its wrapper instance.
UA_DataValue wrapper class.
bool hasServerPicoseconds() const noexcept
void setSourceTimestamp(DateTime sourceTimestamp) noexcept
Set source timestamp for the value.
uint16_t serverPicoseconds() const noexcept
Get picoseconds interval added to the server timestamp.
bool hasValue() const noexcept
DateTime getServerTimestamp() const noexcept
DataValue(Variant value) noexcept
const Variant && getValue() const &&noexcept
uint16_t getServerPicoseconds() const noexcept
StatusCode status() const noexcept
Get status.
const Variant && value() const &&noexcept
Get value (rvalue).
DateTime serverTimestamp() const noexcept
Get server timestamp for the value.
bool hasSourceTimestamp() const noexcept
void setServerPicoseconds(uint16_t serverPicoseconds) noexcept
Set picoseconds interval added to the server timestamp.
uint16_t sourcePicoseconds() const noexcept
Get picoseconds interval added to the source timestamp.
const Variant & getValue() const &noexcept
Variant && value() &&noexcept
Get value (rvalue).
bool hasStatus() const noexcept
static DataValue fromScalar(Args &&... args)
Create DataValue from scalar value.
void setValue(Variant &&value) noexcept
Set value (move).
void setServerTimestamp(DateTime serverTimestamp) noexcept
Set server timestamp for the value.
Variant & getValue() &noexcept
static DataValue fromArray(Args &&... args)
Create DataValue from array.
StatusCode getStatus() const noexcept
void setStatus(StatusCode status) noexcept
Set status.
Variant & value() &noexcept
Get value.
void setSourcePicoseconds(uint16_t sourcePicoseconds) noexcept
Set picoseconds interval added to the source timestamp.
bool hasSourcePicoseconds() const noexcept
DateTime sourceTimestamp() const noexcept
Get source timestamp for the value.
uint16_t getSourcePicoseconds() const noexcept
bool hasServerTimestamp() const noexcept
void setValue(const Variant &value)
Set value (copy).
Variant && getValue() &&noexcept
DataValue(Variant value, std::optional< DateTime > sourceTimestamp, std::optional< DateTime > serverTimestamp, std::optional< uint16_t > sourcePicoseconds, std::optional< uint16_t > serverPicoseconds, std::optional< StatusCode > status) noexcept
const Variant & value() const &noexcept
Get value.
DateTime getSourceTimestamp() const noexcept
UA_DateTime wrapper class.
int64_t get() const noexcept
Get DateTime value as 100 nanosecond intervals since January 1, 1601 (UTC).
UA_DateTimeStruct toStruct() const noexcept
Convert to UA_DateTimeStruct.
static DateTime fromUnixTime(int64_t unixTime) noexcept
Get DateTime from Unix time.
static DateTime now() noexcept
Get current DateTime.
std::chrono::duration< int64_t, std::ratio< 1, 10 '000 '000 > > UaDuration
static DateTime fromTimePoint(std::chrono::time_point< Clock, Duration > timePoint)
Get DateTime from std::chrono::time_point.
int64_t toUnixTime() const noexcept
Convert to Unix time (number of seconds since January 1, 1970 UTC).
static int64_t localTimeUtcOffset() noexcept
Offset of local time to UTC.
DateTime(std::chrono::time_point< Clock, Duration > timePoint)
std::string format(std::string_view format, bool localtime=false) const
Convert to string with given format (same format codes as strftime).
std::chrono::time_point< Clock, Duration > toTimePoint() const
Convert to std::chrono::time_point.
std::chrono::system_clock DefaultClock
UA_DiagnosticInfo wrapper class.
bool hasInnerStatusCode() const noexcept
bool hasLocalizedText() const noexcept
int32_t getSymbolicId() const noexcept
int32_t symbolicId() const noexcept
int32_t getNamespaceUri() const noexcept
bool hasSymbolicId() const noexcept
int32_t locale() const noexcept
StatusCode innerStatusCode() const noexcept
const String & additionalInfo() const noexcept
bool hasLocale() const noexcept
bool hasInnerDiagnosticInfo() const noexcept
int32_t getLocalizedText() const noexcept
int32_t getLocale() const noexcept
const DiagnosticInfo * innerDiagnosticInfo() const noexcept
const String & getAdditionalInfo() const noexcept
int32_t namespaceUri() const noexcept
const DiagnosticInfo * getInnerDiagnosticInfo() const noexcept
StatusCode getInnerStatusCode() const noexcept
bool hasNamespaceUri() const noexcept
int32_t localizedText() const noexcept
bool hasAdditionalInfo() const noexcept
UA_ExpandedNodeId wrapper class.
bool operator<=(const UA_ExpandedNodeId &lhs, const UA_ExpandedNodeId &rhs) noexcept
uint32_t hash() const noexcept
ExpandedNodeId(NodeId id) noexcept
const NodeId & getNodeId() const noexcept
ExpandedNodeId(NodeId id, std::string_view namespaceUri, uint32_t serverIndex)
bool operator>=(const UA_ExpandedNodeId &lhs, const UA_ExpandedNodeId &rhs) noexcept
bool isLocal() const noexcept
bool operator!=(const UA_ExpandedNodeId &lhs, const UA_ExpandedNodeId &rhs) noexcept
uint32_t serverIndex() const noexcept
std::string toString() const
Encode ExpandedNodeId as a string like svr=1;nsu=http://test.org/UA/Data/;ns=2;i=10157.
bool operator<(const UA_ExpandedNodeId &lhs, const UA_ExpandedNodeId &rhs) noexcept
std::string_view namespaceUri() const
uint32_t getServerIndex() const noexcept
const NodeId & nodeId() const noexcept
NodeId & nodeId() noexcept
NodeId & getNodeId() noexcept
bool operator>(const UA_ExpandedNodeId &lhs, const UA_ExpandedNodeId &rhs) noexcept
std::string_view getNamespaceUri() const
bool operator==(const UA_ExpandedNodeId &lhs, const UA_ExpandedNodeId &rhs) noexcept
UA_ExtensionObject wrapper class.
bool isDecoded() const noexcept
Check if the ExtensionObject is decoded.
bool isEmpty() const noexcept
const UA_DataType * getDecodedDataType() const noexcept
ExtensionObject(T *ptr, const UA_DataType &type) noexcept
Create ExtensionObject from a pointer to a decoded object with a custom data type (no copy).
const UA_DataType * decodedType() const noexcept
Get the decoded data type.
const XmlElement * encodedXml() const noexcept
Get the encoded body in XML format.
static ExtensionObject fromDecoded(T &data, Args &&... args) noexcept
T * decodedData() noexcept
Get pointer to the decoded data with given template type.
ExtensionObject(T *ptr) noexcept
Create ExtensionObject from a pointer to a decoded object (no copy).
T * getDecodedData() noexcept
bool empty() const noexcept
Check if the ExtensionObject is empty.
const ByteString * getEncodedBody() const noexcept
ExtensionObject(const T &decoded)
Create ExtensionObject from a decoded object (copy).
const NodeId * encodedTypeId() const noexcept
Get the encoded type id.
const T * getDecodedData() const noexcept
const NodeId * getEncodedTypeId() const noexcept
void * decodedData() noexcept
Get pointer to the decoded data.
const T * decodedData() const noexcept
Get const pointer to the decoded data with given template type.
ExtensionObjectEncoding getEncoding() const noexcept
void * getDecodedData() noexcept
bool isEncoded() const noexcept
Check if the ExtensionObject is encoded (usually if the data type is unknown).
ExtensionObject(const T &decoded, const UA_DataType &type)
Create ExtensionObject from a decoded object with a custom data type (copy).
const ByteString * encodedBinary() const noexcept
Get the encoded body in binary format.
ExtensionObjectEncoding encoding() const noexcept
Get the encoding.
const void * getDecodedData() const noexcept
const void * decodedData() const noexcept
Get pointer to the decoded data.
static ExtensionObject fromDecodedCopy(const T &data, Args &&... args)
std::ostream & operator<<(std::ostream &os, const Guid &guid)
Guid(uint32_t data1, uint16_t data2, uint16_t data3, std::array< uint8_t, 8 > data4) noexcept
Guid(std::array< uint8_t, 16 > data) noexcept
bool operator==(const UA_Guid &lhs, const UA_Guid &rhs) noexcept
bool operator!=(const UA_Guid &lhs, const UA_Guid &rhs) noexcept
std::string toString() const
static Guid random() noexcept
UA_LocalizedText wrapper class.
bool operator==(const UA_LocalizedText &lhs, const UA_LocalizedText &rhs) noexcept
std::string_view text() const noexcept
std::string_view locale() const noexcept
std::string_view getLocale() const noexcept
std::string_view getText() const noexcept
bool operator!=(const UA_LocalizedText &lhs, const UA_LocalizedText &rhs) noexcept
LocalizedText(std::string_view locale, std::string_view text)
const T & identifier() const
Get identifier reference.
std::string toString() const
Encode NodeId as a string like ns=1;s=SomeNode.
NodeId(T identifier) noexcept
Create NodeId from enum class with numeric identifiers like opcua::ObjectId.
NodeIdType identifierType() const noexcept
NamespaceIndex namespaceIndex() const noexcept
NodeId(NamespaceIndex namespaceIndex, uint32_t identifier) noexcept
Create NodeId with numeric identifier.
NodeId(NamespaceIndex namespaceIndex, ByteString identifier) noexcept
Create NodeId with ByteString identifier.
bool operator!=(const UA_NodeId &lhs, const UA_NodeId &rhs) noexcept
std::variant< uint32_t, String, Guid, ByteString > getIdentifier() const
Get identifier variant.
bool operator<(const UA_NodeId &lhs, const UA_NodeId &rhs) noexcept
bool operator>(const UA_NodeId &lhs, const UA_NodeId &rhs) noexcept
NodeId(NamespaceIndex namespaceIndex, Guid identifier) noexcept
Create NodeId with Guid identifier.
const T * identifierIf() const noexcept
Get identifier pointer or nullptr on error.
auto getIdentifierAs() const
Get identifier by template type.
bool operator==(const UA_NodeId &lhs, const UA_NodeId &rhs) noexcept
bool isNull() const noexcept
bool operator>=(const UA_NodeId &lhs, const UA_NodeId &rhs) noexcept
bool operator<=(const UA_NodeId &lhs, const UA_NodeId &rhs) noexcept
T * identifierIf() noexcept
Get identifier pointer or nullptr on error.
NamespaceIndex getNamespaceIndex() const noexcept
NodeIdType getIdentifierType() const noexcept
T & identifier()
Get identifier reference.
uint32_t hash() const noexcept
NodeId(NamespaceIndex namespaceIndex, std::string_view identifier)
Create NodeId with String identifier.
UA_NumericRange wrapper class.
bool empty() const noexcept
NumericRange(UA_NumericRange &&native) noexcept
Create a NumericRange from native object (move).
NumericRange(std::string_view encodedRange)
Create a NumericRange from the encoded representation, e.g. 1:2,0:3,5.
bool operator!=(const NumericRangeDimension &lhs, const NumericRangeDimension &rhs) noexcept
NumericRange(const char *encodedRange)
This is an overloaded member function, provided for convenience. It differs from the above function o...
NumericRange(Span< const NumericRangeDimension > dimensions)
Create a NumericRange from dimensions.
Span< const NumericRangeDimension > dimensions() const noexcept
NumericRange(const NumericRange &other)
bool operator==(const NumericRangeDimension &lhs, const NumericRangeDimension &rhs) noexcept
NumericRange(NumericRange &&other) noexcept
NumericRange(const UA_NumericRange &native)
Create a NumericRange from native object (copy).
std::string toString() const
NumericRange & operator=(const NumericRange &other)
NumericRange & operator=(NumericRange &&other) noexcept
UA_QualifiedName wrapper class.
bool operator!=(const UA_QualifiedName &lhs, const UA_QualifiedName &rhs) noexcept
NamespaceIndex getNamespaceIndex() const noexcept
bool operator==(const UA_QualifiedName &lhs, const UA_QualifiedName &rhs) noexcept
NamespaceIndex namespaceIndex() const noexcept
QualifiedName(NamespaceIndex namespaceIndex, std::string_view name)
std::string_view name() const noexcept
std::string_view getName() const noexcept
View to a contiguous sequence of objects, similar to std::span in C++20.
constexpr iterator begin() const noexcept
Span(Container &) -> Span< typename Container::value_type >
constexpr iterator end() const noexcept
UA_StatusCode wrapper class.
constexpr void throwIfBad() const
Throw a BadStatus exception if the status code is bad.
constexpr bool isUncertain() const noexcept
Check if the status code is uncertain.
constexpr bool isBad() const noexcept
Check if the status code is bad.
std::string_view name() const noexcept
Get human-readable name of the StatusCode.
constexpr bool isGood() const noexcept
Check if the status code is good.
constexpr UA_StatusCode get() const noexcept
Explicitly get underlying UA_StatusCode.
constexpr StatusCode() noexcept=default
Create a StatusCode with the default status code UA_STATUSCODE_GOOD.
String & operator=(std::basic_string_view< char, Traits > str)
Assign std::string_view.
String(std::initializer_list< char > values)
bool operator==(std::string_view lhs, const String &rhs) noexcept
std::string_view get() const noexcept
bool operator==(const String &lhs, std::string_view rhs) noexcept
String(InputIt first, InputIt last)
String & operator=(const char *str)
Assign null-termined character string.
bool operator!=(const String &lhs, std::string_view rhs) noexcept
bool operator!=(std::string_view lhs, const String &rhs) noexcept
String(std::string_view str)
std::ostream & operator<<(std::ostream &os, const String &str)
bool operator!=(const UA_String &lhs, const UA_String &rhs) noexcept
bool operator==(const UA_String &lhs, const UA_String &rhs) noexcept
Exception for type-related errors.
Template base class to wrap UA_* type objects that require manual memory management.
constexpr TypeWrapper() noexcept=default
constexpr void clear() noexcept
UA_Variant wrapper class.
Variant(InputIt first, InputIt last, const UA_DataType &type)
Create Variant from a range of elements with a custom data type (copy).
bool isType(const UA_DataType &type) const noexcept
Check if the variant type is equal to the provided data type.
const void * data() const noexcept
Get pointer to the underlying data.
void assign(InputIt first, InputIt last)
Assign range to variant (copy and convert if required).
Variant(InputIt first, InputIt last)
Create Variant from a range of elements (copy).
void assign(InputIt first, InputIt last, const UA_DataType &type)
Assign range to variant with custom data type (copy).
T && scalar() &&
Get reference to scalar value with given template type (only native or wrapper types).
Variant(T *ptr, const UA_DataType &type) noexcept
Create Variant from a pointer to a scalar/array with a custom data type (no copy).
const UA_DataType * getDataType() const noexcept
const T & scalar() const &
Get reference to scalar value with given template type (only native or wrapper types).
Variant & operator=(T *value) noexcept
Assign pointer to scalar/array to variant (no copy).
const T && scalar() const &&
Get reference to scalar value with given template type (only native or wrapper types).
void setScalar(T &value, Args &&... args) noexcept
Span< const uint32_t > getArrayDimensions() const noexcept
size_t getArrayLength() const noexcept
Span< T > array()
Get reference to array with given template type (only native or wrapper types).
static Variant fromArray(T &&array, Args &&... args)
void assign(const T &value)
Assign scalar/array to variant (copy and convert if required).
static Variant fromArray(InputIt first, InputIt last, Args &&... args)
T & scalar() &
Get reference to scalar value with given template type (only native or wrapper types).
std::vector< T > getArrayCopy() const
void setArrayCopy(InputIt first, InputIt last, Args &&... args)
bool isType(const UA_DataType *type) const noexcept
Check if the variant type is equal to the provided data type.
T to() const
Converts the variant to the specified type T with automatic conversion if required.
void assign(T *ptr) noexcept
Assign pointer to scalar/array to variant (no copy).
bool isType(const NodeId &id) const noexcept
Check if the variant type is equal to the provided data type node id.
Span< const T > getArray() const
bool empty() const noexcept
Check if the variant is empty.
static Variant fromScalar(T &&value, Args &&... args)
Variant & operator=(const T &value)
Assign scalar/array to variant (copy and convert if required).
void setScalarCopy(const T &value, Args &&... args)
void setArray(T &array, Args &&... args) noexcept
size_t arrayLength() const noexcept
Get array length or 0 if variant is not an array.
const UA_DataType * type() const noexcept
Get data type.
bool isEmpty() const noexcept
Variant(T *ptr) noexcept
Create Variant from a pointer to a scalar/array (no copy).
Variant(const T &value)
Create Variant from a scalar/array (copy).
void assign(std::nullptr_t ptr, const UA_DataType &type) noexcept=delete
Span< const uint32_t > arrayDimensions() const noexcept
Get array dimensions.
bool isArray() const noexcept
Check if the variant is an array.
void setArrayCopy(const T &array, Args &&... args)
Variant(const T &value, const UA_DataType &type)
Create Variant from a scalar/array with a custom data type (copy).
Span< const T > array() const
Get reference to array with given template type (only native or wrapper types).
void assign(std::nullptr_t ptr) noexcept=delete
void assign(T *ptr, const UA_DataType &type) noexcept
Assign pointer to scalar/array to variant with custom data type (no copy).
bool isScalar() const noexcept
Check if the variant is a scalar.
void assign(const T &value, const UA_DataType &type)
Assign scalar/array to variant with custom data type (copy).
bool isType() const noexcept
Check if the variant type is equal to the provided template type.
void * data() noexcept
Get pointer to the underlying data.
const T & getScalar() const
Template base class to wrap native objects.
constexpr const UA_StatusCode & native() const noexcept
constexpr UA_DateTime * handle() noexcept
constexpr Wrapper() noexcept=default
UA_XmlElement wrapper class.
std::string_view get() const noexcept
std::ostream & operator<<(std::ostream &os, const XmlElement &xmlElement)
XmlElement(std::string_view str)
XmlElement & operator=(std::basic_string_view< char, Traits > str)
Assign std::string_view.
XmlElement(InputIt first, InputIt last)
XmlElement & operator=(const char *str)
Assign null-termined character string.
constexpr Namespace namespaceOf(DataTypeId) noexcept
Get namespace of DataTypeId.
constexpr NativeType * asNative(WrapperType *wrapper) noexcept
Cast Wrapper object pointers to native object pointers.
static UA_LogCategory const char va_list args
ExtensionObjectEncoding
Extension object encoding.
VariantPolicy
Policies for variant factory methods Variant::fromScalar, Variant::fromArray.
@ Copy
Store copy of scalar/array inside the variant.
@ Reference
Store reference to scalar/array inside the variant.
constexpr void throwIfBad(UA_StatusCode code)
Check the status code and throw a BadStatus exception if the status code is bad.
uint16_t NamespaceIndex
Namespace index.
@ NodeId
Unambiguous identifier of a node.
const UA_DataType & getDataType() noexcept
UA_Boolean hasSourcePicoseconds
UA_Boolean hasServerTimestamp
UA_UInt16 serverPicoseconds
UA_DateTime serverTimestamp
UA_UInt16 sourcePicoseconds
UA_DateTime sourceTimestamp
UA_Boolean hasSourceTimestamp
UA_Boolean hasServerPicoseconds
UA_Boolean hasNamespaceUri
UA_Boolean hasInnerDiagnosticInfo
UA_Boolean hasLocalizedText
UA_Boolean hasInnerStatusCode
UA_StatusCode innerStatusCode
UA_Boolean hasAdditionalInfo
UA_ExtensionObjectEncoding encoding
struct UA_ExtensionObject::@26::@27 encoded
union UA_ExtensionObject::@26 content
struct UA_ExtensionObject::@26::@28 decoded
enum UA_NodeIdType identifierType
union UA_NodeId::@25 identifier
UA_NumericRangeDimension * dimensions
UA_UInt32 * arrayDimensions
size_t arrayDimensionsSize
static void toNative(const Type &src, NativeType &dst)
static void toNative(Type src, NativeType &dst)
std::basic_string< char, Traits, Allocator > Type
static void fromNative(const NativeType &src, Type &dst)
static void toNative(const Type &src, NativeType &dst)
std::basic_string_view< char, Traits > Type
static void toNative(Type src, NativeType &dst)
static void fromNative(const NativeType &src, Type &dst)
std::chrono::time_point< Clock, Duration > Type
static void fromNative(const NativeType &src, Type &dst)
static void toNative(const Type &src, NativeType &dst)
Type conversion from and to native types.
std::size_t operator()(const opcua::ExpandedNodeId &id) const noexcept
std::size_t operator()(const opcua::NodeId &id) const noexcept
UA_UInt32 UA_NodeId_hash(const UA_NodeId *n)
UA_EXTENSIONOBJECT_ENCODED_XML
UA_EXTENSIONOBJECT_ENCODED_BYTESTRING
UA_EXTENSIONOBJECT_ENCODED_NOBODY
UA_EXTENSIONOBJECT_DECODED
UA_EXTENSIONOBJECT_DECODED_NODELETE
UA_Boolean UA_String_equal(const UA_String *s1, const UA_String *s2)
#define UA_EMPTY_ARRAY_SENTINEL
UA_Guid UA_Guid_random(void)
UA_UInt32 UA_ExpandedNodeId_hash(const UA_ExpandedNodeId *n)
UA_Order UA_NodeId_order(const UA_NodeId *n1, const UA_NodeId *n2)
#define UA_DATETIME_UNIX_EPOCH
UA_DateTimeStruct UA_DateTime_toStruct(UA_DateTime t)
UA_Boolean UA_NodeId_isNull(const UA_NodeId *p)
UA_EXPORT const char * UA_StatusCode_name(UA_StatusCode code)
UA_Order UA_ExpandedNodeId_order(const UA_ExpandedNodeId *n1, const UA_ExpandedNodeId *n2)
UA_DateTime UA_DateTime_now(void)
UA_Boolean UA_Guid_equal(const UA_Guid *g1, const UA_Guid *g2)
UA_Int64 UA_DateTime_localTimeUtcOffset(void)