stub_analytics_plugin  1.6
Network Optix Video Analytics SDK
debug.h
Go to the documentation of this file.
1 // Copyright 2018-present Network Optix, Inc.
2 #pragma once
3 
12 #include <iostream>
13 #include <cstdint>
14 #include <functional>
15 #include <sstream>
16 #include <memory>
17 
18 #if defined(QT_CORE_LIB)
19  // To be supported in toString() and NX_PRINT_VALUE.
20  #include <QtCore/QByteArray>
21  #include <QtCore/QString>
22  #include <QtCore/QUrl>
23 #endif
24 
25 #if !defined(NX_KIT_API)
26  #define NX_KIT_API /*empty*/
27 #endif
28 
29 namespace nx {
30 namespace kit {
31 namespace debug {
32 
33 //-------------------------------------------------------------------------------------------------
34 // Tools
35 
36 NX_KIT_API uint8_t* unalignedPtr(void* data);
37 
38 NX_KIT_API std::string format(std::string formatStr, ...);
39 
40 NX_KIT_API bool isAsciiPrintable(int c);
41 
43 NX_KIT_API char pathSeparator();
44 
45 NX_KIT_API size_t commonPrefixSize(const std::string& s1, const std::string& s2);
46 
51 NX_KIT_API const char* relativeSrcFilename(const char* file);
52 
53 NX_KIT_API std::string fileBaseNameWithoutExt(const char* file);
54 
55 //-------------------------------------------------------------------------------------------------
56 // Output
57 
59 #if defined(NX_PRINT_TO_QDEBUG)
60  #define NX_DEBUG_STREAM qDebug().nospace().noquote()
61  #define NX_DEBUG_ENDL /*empty*/
62  static inline QDebug operator<<(QDebug d, const std::string& s)
63  {
64  return d << QString::fromStdString(s);
65  }
66 #endif
67 
68 #if !defined(NX_DEBUG_INI)
69 
70  #define NX_DEBUG_INI ini().
71 #endif
72 
73 #if !defined(NX_DEBUG_ENABLE_OUTPUT)
74 
75  #define NX_DEBUG_ENABLE_OUTPUT NX_DEBUG_INI enableOutput
76 #endif
77 
78 #if !defined(NX_PRINT_PREFIX)
79 
80  #define NX_PRINT_PREFIX nx::kit::debug::detail::printPrefix(__FILE__)
81 #endif
82 
83 #if !defined(NX_DEBUG_STREAM)
84 
85  #define NX_DEBUG_STREAM *nx::kit::debug::stream()
86 #endif
87 
88 #if !defined(NX_DEBUG_ENDL)
89 
90  #define NX_DEBUG_ENDL << std::endl
91 #endif
92 
97 NX_KIT_API std::ostream*& stream();
98 
99 #if !defined(NX_PRINT)
100 
104  #define NX_PRINT /* << args... */ \
105  /* Allocate a temp value, which prints endl in its destructor, in the "<<" expression. */ \
106  ( []() { struct Endl { ~Endl() { NX_DEBUG_STREAM NX_DEBUG_ENDL; } }; \
107  return std::make_shared<Endl>(); }() ) /*operator,*/, \
108  NX_DEBUG_STREAM << NX_PRINT_PREFIX
109 #endif
110 
114 #define NX_OUTPUT /* << args... */ \
115  if (!(NX_DEBUG_ENABLE_OUTPUT)) {} else NX_PRINT
116 
117 //-------------------------------------------------------------------------------------------------
118 // Assertions
119 
127 #define NX_KIT_ASSERT(...) \
128  NX_KIT_DEBUG_DETAIL_MSVC_EXPAND(NX_KIT_DEBUG_DETAIL_GET_3RD_ARG( \
129  __VA_ARGS__, NX_KIT_DEBUG_DETAIL_ASSERT2, NX_KIT_DEBUG_DETAIL_ASSERT1, \
130  /* Helps to generate a reasonable compiler error. */ args_required)(__VA_ARGS__))
131 
132 //-------------------------------------------------------------------------------------------------
133 // Print info
134 
138 #define LL \
139  NX_PRINT << "####### LL line " << __LINE__ \
140  << NX_KIT_DEBUG_DETAIL_THREAD_ID() \
141  << ", file " << nx::kit::debug::relativeSrcFilename(__FILE__);
142 
146 template<typename T>
147 std::string toString(T value);
148 
152 #define NX_PRINT_VALUE(VALUE) \
153  NX_PRINT << "####### " #VALUE ": " << nx::kit::debug::toString((VALUE))
154 
158 #define NX_PRINT_HEX_DUMP(TAG, BYTES, SIZE) \
159  nx::kit::debug::detail::printHexDump( \
160  NX_KIT_DEBUG_DETAIL_PRINT_FUNC, (TAG), (const char*) (BYTES), (int) (SIZE))
161 
162 //-------------------------------------------------------------------------------------------------
163 // Time
164 
165 #if !defined(NX_DEBUG_ENABLE_TIME)
166 
167  #define NX_DEBUG_ENABLE_TIME NX_DEBUG_INI enableTime
168 #endif
169 
173 #define NX_TIME_BEGIN(TAG) \
174  nx::kit::debug::detail::Timer nxTimer_##TAG( \
175  (NX_DEBUG_ENABLE_TIME), NX_KIT_DEBUG_DETAIL_PRINT_FUNC, #TAG)
176 
181 #define NX_TIME_MARK(TAG, MARK) do \
182 { \
183  if (NX_DEBUG_ENABLE_TIME) \
184  nxTimer_##TAG.mark((MARK)); \
185 } while (0)
186 
190 #define NX_TIME_END(TAG) do \
191 { \
192  if (NX_DEBUG_ENABLE_TIME) \
193  nxTimer_##TAG.finish(); \
194 } while (0)
195 
196 //-------------------------------------------------------------------------------------------------
197 // Fps
198 
199 #if !defined(NX_DEBUG_ENABLE_FPS)
200 
201  #define NX_DEBUG_ENABLE_FPS NX_DEBUG_INI enableFps
202 #endif
203 
208 #define NX_FPS(TAG, /*OPTIONAL_MARK*/...) do \
209 { \
210  if (NX_KIT_DEBUG_DETAIL_CONCAT(NX_DEBUG_ENABLE_FPS, TAG)) \
211  { \
212  static nx::kit::debug::detail::Fps fps( \
213  NX_KIT_DEBUG_DETAIL_PRINT_FUNC, #TAG); \
214  fps.mark(__VA_ARGS__); \
215  } \
216 } while (0)
217 
218 //-------------------------------------------------------------------------------------------------
219 // Implementation
220 
225 #define NX_KIT_DEBUG_DETAIL_MSVC_EXPAND(ARG) ARG
226 
228 #define NX_KIT_DEBUG_DETAIL_GET_3RD_ARG(ARG1, ARG2, ARG3, ...) ARG3
229 
230 #define NX_KIT_DEBUG_DETAIL_ASSERT1(CONDITION) \
231  NX_KIT_DEBUG_DETAIL_ASSERT(CONDITION, "")
232 
233 #define NX_KIT_DEBUG_DETAIL_ASSERT2(CONDITION, MESSAGE) \
234  NX_KIT_DEBUG_DETAIL_ASSERT(CONDITION, MESSAGE)
235 
236 #define NX_KIT_DEBUG_DETAIL_ASSERT(CONDITION, MESSAGE) do \
237 { \
238  if (!(CONDITION)) \
239  { \
240  nx::kit::debug::detail::assertionFailed( \
241  NX_KIT_DEBUG_DETAIL_PRINT_FUNC, #CONDITION, (MESSAGE), __FILE__, __LINE__); \
242  } \
243 } while (0)
244 
245 #define NX_KIT_DEBUG_DETAIL_CONCAT(X, Y) NX_KIT_DEBUG_DETAIL_CONCAT2(X, Y)
246 #define NX_KIT_DEBUG_DETAIL_CONCAT2(X, Y) X##Y
247 
248 template<typename T>
249 std::string toString(T value)
250 {
251  std::ostringstream outputString;
252  outputString << value;
253  return outputString.str();
254 }
255 
256 NX_KIT_API std::string toString(std::string s);
257 NX_KIT_API std::string toString(char c);
258 NX_KIT_API std::string toString(const char* s);
259 NX_KIT_API std::string toString(char* s);
260 NX_KIT_API std::string toString(const void* ptr);
261 NX_KIT_API std::string toString(bool b);
262 
263 #if defined(QT_CORE_LIB)
264 
265 static inline std::string toString(const QByteArray& b)
266 {
267  return toString(b.toStdString());
268 }
269 
270 static inline std::string toString(const QString& s)
271 {
272  return toString(s.toUtf8().constData());
273 }
274 
275 static inline std::string toString(const QUrl& u)
276 {
277  return toString(u.toEncoded().toStdString());
278 }
279 
280 #endif // defined(QT_CORE_LIB)
281 
282 template<typename P>
283 std::string toString(P* ptr)
284 {
285  return toString((const void*) ptr);
286 }
287 
288 namespace detail {
289 
290 typedef std::function<void(const char*)> PrintFunc;
291 
292 #define NX_KIT_DEBUG_DETAIL_PRINT_FUNC [&](const char* message) { NX_PRINT << message; }
293 
295 NX_KIT_API std::string printPrefix(const char* file);
296 
297 NX_KIT_API void assertionFailed(
298  PrintFunc printFunc, const char* conditionStr, const std::string& message,
299  const char* file, int line);
300 
301 class NX_KIT_API Timer
302 {
303 public:
304  Timer(bool enabled, PrintFunc printFunc, const char* tag);
305  ~Timer();
306  void mark(const char* markStr);
307  void finish();
308 
309 private:
310  struct Impl;
311  Impl* const d;
312 };
313 
314 class NX_KIT_API Fps
315 {
316 public:
317  Fps(PrintFunc printFunc, const char* tag);
318  ~Fps();
319  void mark(const char* markStr = nullptr);
320 
321 private:
322  struct Impl;
323  Impl* const d;
324 };
325 
326 NX_KIT_API void printHexDump(
327  PrintFunc printFunc, const char* caption, const char* bytes, int size);
328 
329 } // namespace detail
330 
331 } // namespace debug
332 } // namespace kit
333 } // namespace nx
334 
335 #if defined(__linux__)
336  #include <pthread.h>
337  #define NX_KIT_DEBUG_DETAIL_THREAD_ID() \
338  nx::kit::debug::format(", thread %llx", (long long) pthread_self())
339 #elif defined(QT_CORE_LIB)
340  #include <QtCore/QThread>
341  #define NX_KIT_DEBUG_DETAIL_THREAD_ID() \
342  nx::kit::debug::format(", thread %llx", (long long) QThread::currentThreadId())
343 #else
344  // No threading libs available - do not print thread id.
345  #define NX_KIT_DEBUG_DETAIL_THREAD_ID() ""
346 #endif
Definition: debug.h:314
Definition: debug.cpp:367
Definition: debug.cpp:292
Definition: debug.cpp:14
Definition: debug.h:301