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 
10 namespace Cvb
11 {
12 
13 CVB_BEGIN_INLINE_NS
14 
15 template <>
16 inline 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 
24 namespace OpcUa
25 {
26 
37 class NodeID
38 {
39  friend class OpcUa::BaseNode;
40 
41 public:
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 
118  NodeIDType Type() const
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 
176 protected:
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 
221 private:
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 
268 template<>
269 inline std::uint32_t NodeID::Identifier<std::uint32_t>() const
270 {
271  return NumericIdentifier();
272 }
273 
279 template<>
280 inline String NodeID::Identifier<String>() const
281 {
282  return StringIdentifier();
283 }
284 }
285 CVB_END_INLINE_NS
286 }
STL class.
NodeIDType
Describes the representation of a OpcUa::NodeID.
Definition: opcua.hpp:124
Namespace0NodeID
Lists "Namespace0" node ids Namespace0 node ids are a collection of mandatory and common nodeIDs....
Definition: opcua.hpp:315
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
An OPCUA NodeID object. NodeIDs provide a unique identifier for OPCUA nodes, i.e. they help with node...
Definition: node_id.hpp:37
std::uint16_t NamespaceIndex() const
Returns namespace index.
Definition: node_id.hpp:82
const int CVB_ERROR
Generic unspecified error.
Definition: exception.hpp:24
STL class.
Root namespace for the Image Manager interface.
Definition: version.hpp:11
NodeIDType Type() const
Returns type of the node id.
Definition: node_id.hpp:118
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
const int CVB_NOTSUPPORTED
A certain feature is not supported.
Definition: exception.hpp:60
NodeID of the node (BaseNode (integer, See OpcUa::DataType))
void * Handle() const noexcept
Return the C-API handle.
Definition: node_id.hpp:171
std::string ExpandedText() const
Returns expanded text of the node id.
Definition: node_id.hpp:98
static NodeIDPtr Create(Namespace0NodeID id)
Creates an id based on a predefined Namespace0 node id.
Definition: node_id.hpp:48
Special runtime exception to carry a native error code.
Definition: exception.hpp:137
Special runtime exception to carry a native error code.
Definition: exception.hpp:24
STL class.
String representation of NodeID.
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
An OPCUA BaseNode. This is the base for all other node classes. For instantiation of a specific node ...
Definition: decl_base_node.hpp:34
Numeric representation of NodeID.