CVB++ 14.0
node_id.hpp
1#pragma once
2
3#include <type_traits>
4
5#include "../global.hpp"
6
7#include "opcua.hpp"
8#include "exception.hpp"
9
10namespace Cvb
11{
12
13CVB_BEGIN_INLINE_NS
14
15template <>
16inline HandleGuard<OpcUa::NodeID>::HandleGuard(void * handle) noexcept
17 : HandleGuard<OpcUa::NodeID>(handle, [](void* handle)
18{
19 CVB_CALL_CAPI(ReleaseObject(handle));
20})
21{
22}
23
24namespace OpcUa
25{
26
37class NodeID
38{
39 friend class OpcUa::BaseNode;
40
41public:
43
49 {
50 return std::shared_ptr<NodeID>(new NodeID(id));
51 }
52
54
60 static NodeIDPtr Create(std::uint16_t namespaceIndex, std::uint32_t identifier)
61 {
62 return std::shared_ptr<NodeID>(new NodeID(namespaceIndex, identifier));
63 }
64
66
72 static NodeIDPtr Create(std::uint16_t namespaceIndex, const Cvb::String & identifier)
73 {
74 return std::shared_ptr<NodeID>(new NodeID(namespaceIndex, identifier));
75 }
76
78
83 {
84 CExports::cvbuint16_t namesapceIndex = 0;
85 int ret = CVB_CALL_CAPI(CVOPCGetNamespaceIndex(Handle(), namesapceIndex));
86 if (ret < 0)
87 throw OpcUaException(ret);
88 return static_cast<std::uint16_t>(namesapceIndex);
89 }
90
91
93
99 {
100 std::size_t bufferSize = 0;
101 int ret = CVB_CALL_CAPI(CVOPCGetNodeIdExpandedText(Handle(), reinterpret_cast<char*>(0), bufferSize));
102 if (ret < 0)
103 throw OpcUaException(ret);
104
105 std::vector<char> buffer(bufferSize);
106 ret = CVB_CALL_CAPI(CVOPCGetNodeIdExpandedText(Handle(), buffer.data(), bufferSize));
107 if (ret < 0)
108 throw OpcUaException(ret);
109
110 return std::string(buffer.data());
111 }
112
114
119 {
120 CExports::TCVOPCNodeIdType type;
121 int ret = CVB_CALL_CAPI(CVOPCIdType(Handle(), type));
122 if (ret < 0)
123 throw OpcUaException(ret);
124
125 return static_cast<NodeIDType>(type);
126 }
127
133 template<typename T>
134 T Identifier() const
135 {
136 T retVal;
137 int ret = -1;
138 if (Type() == NodeIDType::Numeric) // TODO expand types
139 {
140 ret = CVB_CALL_CAPI(CVOPCNodeIdAsInteger(Handle(), retVal));
141 }
142 else if (Type() == NodeIDType::String)
143 {
144 std::size_t size = 0;
145 ret = CVB_CALL_CAPI(CVOPCNodeIdAsStringTyped(Handle(), reinterpret_cast<Cvb::Char*>(nullptr), size));
146 if (ret < 0)
147 {
148 throw OpcUa::OpcUaException(ret);
149 }
150 std::vector<Char> data(size);
151 ret = CVB_CALL_CAPI(CVOPCNodeIdAsStringTyped(Handle(), data.data(), size));
152 retVal = T(data.data());
153 }
154 else
155 {
156 throw CvbException("Unsupported OPCUA identifier data type!", ErrorCodes::CVB_ERROR);
157 }
158
159 if (ret < 0)
160 {
161 throw OpcUa::OpcUaException(ret);
162 }
163
164 return retVal;
165 }
166
171 void * Handle() const noexcept
172 {
173 return handle_.Handle();
174 }
175
176protected:
178 static NodeIDPtr FromHandle(void * handle)
179 {
180 return std::shared_ptr<NodeID>(new NodeID(HandleGuard<OpcUa::NodeID>(handle)));
181 }
182
183 explicit NodeID(Namespace0NodeID id)
184 : NodeID([&]
185 {
186 HandleGuard<NodeID> guard(CExports::CreateCVOPCNodeId(static_cast<CExports::TCVOpc_NS0_NodeId>(id)));
187 if (!guard.Handle())
188 throw OpcUaException(ErrorCodes::CVB_ERROR);
189 return guard;
190 })
191 {
192 }
193
194 explicit NodeID(std::uint16_t namespaceIndex, std::uint32_t identifier)
195 : NodeID([&]
196 {
197 HandleGuard<NodeID> guard(CExports::CreateCVOPCNodeIdNumeric(namespaceIndex, identifier));
198 if (!guard.Handle())
199 throw OpcUaException(ErrorCodes::CVB_ERROR);
200 return guard;
201 })
202 {
203 }
204
205 explicit NodeID(std::uint16_t namespaceIndex, const Cvb::String & identifier)
206 : NodeID([&]
207 {
208 HandleGuard<NodeID> guard(CExports::CreateCVOPCNodeIdTyped(namespaceIndex, identifier.c_str()));
209 if (!guard.Handle())
210 throw OpcUaException(ErrorCodes::CVB_ERROR);
211 return guard;
212 })
213 {
214 }
215
216 explicit NodeID(HandleGuard<NodeID> && guard) noexcept
217 : handle_(std::move(guard))
218 {
219 }
220
221private:
222
223 explicit NodeID(std::function<HandleGuard<NodeID>()> creator)
224 : NodeID(creator())
225 {
226 }
227
228 void NativeCall(std::function<CExports::cvbres_t()> fn) const
229 {
230 auto result = fn();
231 if (result < 0)
232 throw OpcUaException(ErrorCodes::CVB_NOTSUPPORTED);
233 }
234
235 String StringIdentifier() const
236 {
237 std::size_t bufferSize = 0;
238 int ret = CVB_CALL_CAPI(CVOPCNodeIdAsStringTyped(Handle(), reinterpret_cast<Char*>(0), bufferSize));
239 if (ret < 0)
240 throw OpcUaException(ret);
241
242 std::vector<Char> buffer(bufferSize);
243 ret = CVB_CALL_CAPI(CVOPCNodeIdAsStringTyped(Handle(), buffer.data(), bufferSize));
244 if (ret < 0)
245 throw OpcUaException(ret);
246
247 return String(buffer.data());
248 }
249
250 std::uint32_t NumericIdentifier() const
251 {
252 CExports::cvbuint32_t tmpIdentifier = 0;
253 int ret = CVB_CALL_CAPI(CVOPCNodeIdAsInteger(Handle(), tmpIdentifier));
254 if (ret < 0)
255 throw OpcUaException(ret);
256 return tmpIdentifier;
257 }
258
259 HandleGuard<NodeID> handle_;
261};
262
268template<>
269inline std::uint32_t NodeID::Identifier<std::uint32_t>() const
270{
271 return NumericIdentifier();
272}
273
279template<>
280inline String NodeID::Identifier<String>() const
281{
282 return StringIdentifier();
283}
284}
285CVB_END_INLINE_NS
286}
Special runtime exception to carry a native error code.
Definition: exception.hpp:139
An OPCUA BaseNode. This is the base for all other node classes. For instantiation of a specific node ...
Definition: decl_base_node.hpp:35
An OPCUA NodeID object. NodeIDs provide a unique identifier for OPCUA nodes, i.e. they help with node...
Definition: node_id.hpp:38
static NodeIDPtr Create(std::uint16_t namespaceIndex, const Cvb::String &identifier)
Creates a NodeID based on a namespace index and an identifier.
Definition: node_id.hpp:72
T Identifier() const
Returns the id of the node id. For determining the type of the id, see OpcUa::NodeID::Type().
Definition: node_id.hpp:134
std::string ExpandedText() const
Returns expanded text of the node id.
Definition: node_id.hpp:98
std::uint16_t NamespaceIndex() const
Returns namespace index.
Definition: node_id.hpp:82
static NodeIDPtr Create(Namespace0NodeID id)
Creates an id based on a predefined Namespace0 node id.
Definition: node_id.hpp:48
static NodeIDPtr Create(std::uint16_t namespaceIndex, std::uint32_t identifier)
Creates an id based on a namespace id and an identifier.
Definition: node_id.hpp:60
void * Handle() const noexcept
Return the C-API handle.
Definition: node_id.hpp:171
NodeIDType Type() const
Returns type of the node id.
Definition: node_id.hpp:118
Special runtime exception to carry a native error code.
Definition: exception.hpp:25
const int CVB_ERROR
Generic unspecified error.
Definition: exception.hpp:24
const int CVB_NOTSUPPORTED
A certain feature is not supported.
Definition: exception.hpp:60
@ NodeID
NodeID of the node (BaseNode (integer, See OpcUa::DataType))
NodeIDType
Describes the representation of a OpcUa::NodeID.
Definition: opcua.hpp:125
@ String
String representation of NodeID.
@ Numeric
Numeric representation of NodeID.
Namespace0NodeID
Lists "Namespace0" node ids Namespace0 node ids are a collection of mandatory and common nodeIDs....
Definition: opcua.hpp:316
Root namespace for the Image Manager interface.
Definition: c_barcode.h:24
char Char
Character type for wide characters or unicode characters.
Definition: string.hpp:59
std::string String
String for wide characters or unicode characters.
Definition: string.hpp:45