nx_video_source_sdk  1.0
Video Source SDK
plugin_tools.h
Go to the documentation of this file.
1 // Copyright 2018-present Network Optix, Inc. Licensed under MPL 2.0: www.mozilla.org/MPL/2.0/
2 
3 #pragma once
4 
9 // TODO: Remove this file when Storage and Camera SDKs are merged into Analytics SDK.
10 
11 #if defined(_WIN32)
12  #define NOMINMAX //< Needed to prevent windows.h from defining macros min() and max().
13  #include <Windows.h>
14 #endif
15 
16 #include <cstdlib>
17 #include <cstring>
18 #include <cerrno>
19 #include <sstream>
20 #include <iomanip>
21 #include <limits>
22 #include <type_traits>
23 
24 #include "plugin_api.h"
25 
26 namespace nxpt {
27 
28 namespace atomic {
29 
30 #ifdef _WIN32
31  typedef volatile LONG AtomicLong;
32 #elif __GNUC__
33  typedef volatile long AtomicLong;
34 #else
35  #error "Unsupported compiler is used."
36 #endif
37 
39 static AtomicLong inc(AtomicLong* val)
40 {
41  #ifdef _WIN32
42  return InterlockedIncrement(val);
43  #elif __GNUC__
44  return __sync_add_and_fetch(val, 1);
45  #endif
46 }
47 
49 static AtomicLong dec(AtomicLong* val)
50 {
51  #ifdef _WIN32
52  return InterlockedDecrement(val);
53  #elif __GNUC__
54  return __sync_sub_and_fetch(val, 1);
55  #endif
56 }
57 
58 } // namespace atomic
59 
68 {
69 public:
70  CommonRefManager(const CommonRefManager&) = delete;
71  CommonRefManager& operator=(const CommonRefManager&) = delete;
72 
78  m_refCount(1),
79  m_objToWatch(objToWatch),
80  m_refCountingDelegate(0)
81  {
82  }
83 
88  CommonRefManager(CommonRefManager* refCountingDelegate):
89  m_refCountingDelegate(refCountingDelegate)
90  {
91  }
92 
94  int addRef() const
95  {
96  return m_refCountingDelegate
97  ? m_refCountingDelegate->addRef()
98  : atomic::inc(&m_refCount);
99  }
100 
105  int releaseRef() const
106  {
107  if (m_refCountingDelegate)
108  return m_refCountingDelegate->releaseRef();
109 
110  const int newRefCounter = atomic::dec(&m_refCount);
111  if (newRefCounter == 0)
112  delete m_objToWatch;
113  return newRefCounter;
114  }
115 
116  int refCount() const
117  {
118  if (m_refCountingDelegate)
119  return m_refCountingDelegate->refCount();
120  return m_refCount;
121  }
122 
123 private:
124  mutable atomic::AtomicLong m_refCount;
125  nxpl::PluginInterface* m_objToWatch;
126  CommonRefManager* m_refCountingDelegate;
127 };
128 
129 template <typename T>
130 class CommonRefCounter: public T
131 {
132 public:
133  CommonRefCounter(const CommonRefCounter&) = delete;
134  CommonRefCounter& operator=(const CommonRefCounter&) = delete;
136  CommonRefCounter& operator=(CommonRefCounter&&) = delete;
137  virtual ~CommonRefCounter() = default;
138 
139  virtual int addRef() const override { return m_refManager.addRef(); }
140  virtual int releaseRef() const override { return m_refManager.releaseRef(); }
141 
142  int refCount() const { return m_refManager.refCount(); }
143 
144 protected:
145  CommonRefManager m_refManager;
146 
147  CommonRefCounter(): m_refManager(static_cast<T*>(this)) {}
148  CommonRefCounter(CommonRefManager* refManager): m_refManager(refManager) {}
149 };
150 
155 template<typename RefCountableInterface>
156 int refCount(const nxpl::PluginInterface* object)
157 {
158  if (object == nullptr)
159  return 0;
160 
161  if (const auto commonRefCounter = dynamic_cast<CommonRefCounter<RefCountableInterface>*>(object))
162  return commonRefCounter->refCount();
163 
164  (void) object->addRef();
165  return object->releaseRef();
166 }
167 
168 enum NxGuidFormatOption
169 {
170  uppercase = 0x1,
171  hyphens = 0x2,
172  braces = 0x4,
173  applyAll = uppercase | hyphens | braces
174 };
175 
177 {
178 public:
179  static nxpl::NX_GUID nullGuid()
180  {
181  return {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}};
182  }
183 
184  static nxpl::NX_GUID fromRawData(const char* data)
185  {
186  nxpl::NX_GUID result;
187  memcpy(result.bytes, data, sizeof(result.bytes));
188  return result;
189  }
190 
191  static nxpl::NX_GUID fromStdString(const std::string& guidStr)
192  {
193  static const auto kMinGuidStrSize = 32;
194  static const auto kGuidBytesNumber = 16;
195 
196  if (guidStr.size() < kMinGuidStrSize)
197  return NxGuidHelper::nullGuid();
198 
199  nxpl::NX_GUID guid;
200  int currentByteIndex = 0;
201  std::string currentByteString;
202  for (std::string::size_type i = 0; i < guidStr.size(); ++i)
203  {
204  if (guidStr[i] == '{' || guidStr[i] == '}' || guidStr[i] == '-'
205  || guidStr[i] == '\t' || guidStr[i] == '\n' || guidStr[i] == 'r'
206  || guidStr[i] == ' ')
207  {
208  continue;
209  }
210 
211  if (currentByteIndex >= kGuidBytesNumber)
212  return NxGuidHelper::nullGuid();
213 
214  currentByteString += guidStr[i];
215  if (currentByteString.size() == 2)
216  {
217  char* pEnd = nullptr;
218  errno = 0; //< Required before strtol().
219  const long v = std::strtol(currentByteString.c_str(), &pEnd, /*base*/ 16);
220  const bool hasError = v > std::numeric_limits<unsigned char>::max()
221  || v < std::numeric_limits<unsigned char>::min()
222  || errno != 0
223  || *pEnd != '\0';
224 
225  if (hasError)
226  return NxGuidHelper::nullGuid();
227 
228  guid.bytes[currentByteIndex] = (unsigned char) v;
229  ++currentByteIndex;
230  currentByteString.clear();
231  }
232  }
233 
234  if (currentByteIndex != kGuidBytesNumber)
235  return NxGuidHelper::nullGuid();
236 
237  return guid;
238  }
239 };
240 
241 static std::string toStdString(
242  const nxpl::NX_GUID& guid,
243  unsigned int format = NxGuidFormatOption::applyAll)
244 {
245  std::stringstream ss;
246  ss << std::hex << std::setfill('0');
247 
248  if (format & NxGuidFormatOption::braces)
249  ss << '{';
250 
251  if (format & NxGuidFormatOption::uppercase)
252  ss << std::uppercase;
253 
254  for (int i = 0; i < 4; ++i)
255  {
256  ss << std::setw(2);
257  ss << static_cast<unsigned int>(guid.bytes[i]);
258  }
259 
260  if (format & NxGuidFormatOption::hyphens)
261  ss << '-';
262 
263  for (int i = 0; i < 2; ++i)
264  {
265  ss << std::setw(2);
266  ss << static_cast<unsigned int>(guid.bytes[4 + i]);
267  }
268 
269  if (format & NxGuidFormatOption::hyphens)
270  ss << "-";
271 
272  for (int i = 0; i < 2; ++i)
273  {
274  ss << std::setw(2);
275  ss << static_cast<unsigned int>(guid.bytes[6 + i]);
276  }
277 
278  if (format & NxGuidFormatOption::hyphens)
279  ss << "-";
280 
281  for (int i = 0; i < 2; ++i)
282  {
283  ss << std::setw(2);
284  ss << static_cast<unsigned int>(guid.bytes[8 + i]);
285  }
286 
287  if (format & NxGuidFormatOption::hyphens)
288  ss << "-";
289 
290  for (int i = 0; i < 6; ++i)
291  {
292  ss << std::setw(2);
293  ss << static_cast<unsigned int>(guid.bytes[10 + i]);
294  }
295 
296  if (format & NxGuidFormatOption::braces)
297  ss << '}';
298 
299  return ss.str();
300 }
301 
302 } // namespace nxpt
303 
304 namespace nxpl {
305 
306 inline bool operator==(const nxpl::NX_GUID& id1, const nxpl::NX_GUID& id2)
307 {
308  return memcmp(id1.bytes, id2.bytes, sizeof(id1.bytes)) == 0;
309 }
310 
311 inline std::ostream& operator<<(std::ostream& os, const nxpl::NX_GUID& id)
312 {
313  return os << nxpt::toStdString(id);
314 }
315 
316 } // namespace nxpl
317 
318 namespace std {
319 
320 template<>
321 struct hash<nxpl::NX_GUID>
322 {
323  std::size_t operator()(const nxpl::NX_GUID& guid) const
324  {
325  std::size_t h;
326 
327  for (size_t i = 0; i < sizeof(guid.bytes); ++i)
328  h = (h + (324723947 + guid.bytes[i])) ^ 93485734985;
329 
330  return h;
331  }
332 };
333 
334 } // namespace std
virtual int addRef() const =0
Increment reference counter.
static AtomicLong inc(AtomicLong *val)
Definition: plugin_tools.h:39
unsigned char bytes[16]
GUID bytes.
Definition: plugin_api.h:29
Definition: plugin_tools.h:318
Base class for every interface, provided by plugin.
Definition: plugin_api.h:44
static AtomicLong dec(AtomicLong *val)
Definition: plugin_tools.h:49
CommonRefManager(nxpl::PluginInterface *objToWatch)
Definition: plugin_tools.h:77
GUID of plugin interface.
Definition: plugin_api.h:26
VMS dynamic plugin API (c++)
Definition: plugin_api.h:23
Definition: plugin_tools.h:176
Definition: plugin_tools.h:130
CommonRefManager(CommonRefManager *refCountingDelegate)
Definition: plugin_tools.h:88
Definition: plugin_tools.h:67
int addRef() const
Definition: plugin_tools.h:94
Definition: plugin_tools.h:26
int releaseRef() const
Definition: plugin_tools.h:105