AJA NTV2 SDK  17.0.1.1246
NTV2 SDK 17.0.1.1246
common.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
8 #include "common.h"
9 
10 #include <algorithm>
11 #include <cstring>
12 #include <sstream>
13 #include <string>
14 
15 #include <stdlib.h>
16 #include <wchar.h>
17 
18 // check for C++11 compatibility
19 #if defined(_MSC_VER) && _MSC_VER >= 1800
20  // Visual Studio 2013 (_MSC_VER 1800) has the C++11 support we
21  // need, even though it reports 199711L for __cplusplus
22  #define AJA_BASE_USECPP_11 1
23 #elif defined(__clang__)
24  // Note that the __clang__ test needs to go before the __GNUC__ test since it also defines __GNUC__
25  #if __cplusplus >= 201402L
26  #if __has_include(<codecvt>)
27  #define AJA_BASE_USECPP_11 1
28  #endif
29  #elif __cplusplus >= 201103L
30  // For clang only turn on C++11 support if using libc++
31  // libstdc++ does not always have support for <codecvt>
32  #if defined(_LIBCPP_VERSION)
33  #define AJA_BASE_USECPP_11 1
34  #endif
35  #endif
36 #elif defined(__GNUC__)
37  // GCC < 5 says it supports C++11 but does not support "Standard code conversion facets"
38  // aka the stuff in <codecvt> we need. The facet support was added in 5.0
39  #if __GNUC__ >= 5
40  #define AJA_BASE_USECPP_11 1
41  #endif
42 #elif __cplusplus >= 201103L
43  // By this point we should be at a compiler that tells the truth (does that exist?)
44  #define AJA_BASE_USECPP_11 1
45 #endif
46 
47 // use C++11 functionality if available
48 #if defined(AJA_BASE_USECPP_11)
49  #include <locale>
50  #include <codecvt>
51 #else
52  #if defined(AJA_WINDOWS)
53  #include <Windows.h>
54  #endif
55 #endif
56 
57 namespace aja
58 {
59 
60 // string starts with
61 bool starts_with(const std::string &str, const std::string &needle)
62 {
63  return (str.substr(0, needle.size()) == needle);
64 }
65 bool starts_with(const std::string &str, const char needle)
66 {
67  if (str.length() > 0)
68  return str[0] == needle;
69  return false;
70 }
71 bool starts_with(const std::wstring& wstr, const std::wstring& needle)
72 {
73  return (wstr.substr(0, needle.size()) == needle);
74 }
75 bool starts_with(const std::wstring& wstr, const wchar_t needle)
76 {
77  if (wstr.length() > 0)
78  return wstr[0] == needle;
79  return false;
80 }
81 
82 // string ends with
83 bool ends_with(const std::string& str, const std::string& needle)
84 {
85  if (needle.length() < str.length()) {
86  size_t idx = str.length()-needle.length();
87  return str.rfind(needle, idx) == idx;
88  }
89  return false;
90 }
91 bool ends_with(const std::string& str, const char needle)
92 {
93  size_t idx = str.length() - 1;
94  return str.rfind(needle, idx) == idx;
95 }
96 bool ends_with(const std::wstring& wstr, const std::wstring& needle)
97 {
98  if (needle.length() < wstr.length()) {
99  size_t idx = wstr.length() - needle.length();
100  return wstr.rfind(needle, idx) == idx;
101  }
102  return false;
103 }
104 bool ends_with(const std::wstring& wstr, const wchar_t needle)
105 {
106  size_t idx = wstr.length() - 1;
107  return wstr.rfind(needle, idx) == idx;
108 }
109 
110 std::string& replace(std::string& str, const std::string& from, const std::string& to)
111 {
112  if (!from.empty())
113  {
114  for (size_t pos = 0; (pos = str.find(from, pos)) != std::string::npos; pos += to.size())
115  {
116  str.replace(pos, from.size(), to);
117  }
118  }
119  return str;
120 }
121 
122 int stoi (const std::string & str, std::size_t * idx, int base)
123 {
124  return (int)aja::stol(str, idx, base);
125 }
126 
127 long stol (const std::string & str, std::size_t * idx, int base)
128 {
129  char* pEnd = NULL;
130  long retVal = ::strtol(str.c_str(), &pEnd, base);
131  if (idx && pEnd)
132  {
133  *idx = pEnd - str.c_str();
134  }
135  return retVal;
136 }
137 /*
138 long long stoll (const std::string & str, std::size_t * idx, int base)
139 {
140  return (long long)aja::stol(str, idx, base);
141 }
142 */
143 unsigned long stoul (const std::string & str, std::size_t * idx, int base)
144 {
145  char* pEnd = NULL;
146  unsigned long retVal = ::strtoul(str.c_str(), &pEnd, base);
147  if (idx && pEnd)
148  {
149  *idx = pEnd - str.c_str();
150  }
151  return retVal;
152 }
153 
154 unsigned long long stoull (const std::string & str, std::size_t * idx, int base)
155 {
156  return (unsigned long long)aja::stoul(str, idx, base);
157 }
158 
159 float stof (const std::string & str, std::size_t * idx)
160 {
161  return (float)aja::stod(str, idx);
162 }
163 
164 double stod (const std::string & str, std::size_t * idx)
165 {
166  char* pEnd = NULL;
167  double retVal = ::strtod(str.c_str(), &pEnd);
168  if (idx && pEnd)
169  {
170  *idx = pEnd - str.c_str();
171  }
172  return retVal;
173 }
174 
175 long double stold (const std::string & str, std::size_t * idx)
176 {
177  return (long double)aja::stod(str, idx);
178 }
179 
180 std::string to_string (bool val)
181 {
182  return val ? "true" : "false";
183 }
184 
185 std::string to_string (int val)
186 {
187  std::ostringstream oss; oss << val;
188  return oss.str();
189 }
190 
191 std::string to_string (long val)
192 {
193  std::ostringstream oss; oss << val;
194  return oss.str();
195 }
196 
197 std::string to_string (long long val)
198 {
199  std::ostringstream oss; oss << val;
200  return oss.str();
201 }
202 
203 std::string to_string (unsigned val)
204 {
205  std::ostringstream oss; oss << val;
206  return oss.str();
207 }
208 
209 std::string to_string (unsigned long val)
210 {
211  std::ostringstream oss; oss << val;
212  return oss.str();
213 }
214 
215 std::string to_string (unsigned long long val)
216 {
217  std::ostringstream oss; oss << val;
218  return oss.str();
219 }
220 
221 std::string to_string (float val)
222 {
223  std::ostringstream oss;
224  oss.precision(6);
225  oss.setf(std::ios::fixed, std::ios::floatfield);
226  oss << val;
227  return oss.str();
228 }
229 
230 std::string to_string (double val)
231 {
232  std::ostringstream oss;
233  oss.precision(6);
234  oss.setf(std::ios::fixed, std::ios::floatfield);
235  oss << val;
236  return oss.str();
237 }
238 
239 std::string to_string (long double val)
240 {
241  std::ostringstream oss;
242  oss.precision(6);
243  oss.setf(std::ios::fixed, std::ios::floatfield);
244  oss << val;
245  return oss.str();
246 }
247 
248 bool string_to_wstring (const std::string & str, std::wstring & wstr)
249 {
250 // use C++11 functionality if available
251 #if defined(AJA_BASE_USECPP_11)
252  std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converterX;
253  wstr = converterX.from_bytes(str);
254  return true;
255 #else
256  #if defined(AJA_WINDOWS)
257  const char *tmpPtr = str.c_str();
258  uint32_t codePage = CP_UTF8;
259  uint32_t flags = 0;
260  size_t len = MultiByteToWideChar(codePage, flags, tmpPtr, (int)str.length(), NULL, 0);
261  wstr.resize(len);
262  int retVal = MultiByteToWideChar(codePage, flags, tmpPtr, (int)str.length(), &wstr[0], (int)len);
263  if (retVal == 0)
264  return false;
265 
266  return true;
267  #else
268  std::mbstate_t state = std::mbstate_t();
269  mbrlen(NULL, 0, &state);
270  const char *tmpPtr = str.c_str();
271  int len = (int)mbsrtowcs(NULL, &tmpPtr, 0, &state);
272  if (len == -1)
273  return false;
274 
275  wstr.resize((size_t)len);
276  int num_chars = (int)mbsrtowcs(&wstr[0], &tmpPtr, wstr.length(), &state);
277  if (num_chars < 0)
278  return false;
279 
280  return true;
281  #endif
282 #endif
283 }
284 
285 bool wstring_to_string (const std::wstring & wstr, std::string & str)
286 {
287 // use C++11 functionality if available
288 #if defined(AJA_BASE_USECPP_11)
289  std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converterX;
290  str = converterX.to_bytes(wstr);
291  return true;
292 #else
293  #if defined(AJA_WINDOWS)
294  const wchar_t *tmpPtr = wstr.c_str();
295  uint32_t codePage = CP_UTF8;
296  uint32_t flags = 0;
297  size_t len = WideCharToMultiByte(codePage, flags, tmpPtr, (int)wstr.length(), NULL, 0, NULL, NULL);
298  str.resize(len);
299  int retVal = WideCharToMultiByte(codePage, flags, tmpPtr, (int)wstr.length(), &str[0], (int)len, NULL, NULL);
300  if (retVal == 0)
301  return false;
302 
303  return true;
304  #else
305  std::mbstate_t state = std::mbstate_t();
306  mbrlen(NULL, 0, &state);
307  const wchar_t *tmpPtr = wstr.c_str();
308  int len = (int)wcsrtombs(NULL, &tmpPtr, 0, &state);
309  if (len == -1)
310  return false;
311 
312  str.resize((size_t)len);
313  int num_chars = (int)wcsrtombs(&str[0], &tmpPtr, str.length(), &state);
314  if (num_chars < 0)
315  return false;
316 
317  return true;
318  #endif
319 #endif
320 }
321 
322 inline size_t local_min (const size_t & a, const size_t & b)
323 {
324 #if defined(AJA_WINDOWS) && !defined(AJA_BASE_USECPP_11)
325  // By including the Windows.h header that brings in the min() macro which prevents us from using std::min()
326  // so implement our own
327  size_t size = b;
328  if (a < b)
329  size = a;
330  return size;
331 #else
332  return std::min(a, b);
333 #endif
334 }
335 
336 bool string_to_cstring (const std::string & str, char * c_str, size_t c_str_size)
337 {
338  if(c_str == NULL || c_str_size < 1)
339  return false;
340 
341  size_t maxSize = local_min(str.size(), c_str_size-1);
342  for(size_t i=0;i<maxSize;++i)
343  {
344  c_str[i] = str[i];
345  }
346  c_str[maxSize] = '\0';
347  return true;
348 }
349 
350 void split (const std::string & str, const char delim, std::vector<std::string> & elems)
351 {
352  elems.clear();
353  std::stringstream ss(str);
354  std::string item;
355  while(std::getline(ss, item, delim))
356  {
357  elems.push_back(item);
358  }
359 
360  // if last character in string matches the split delim add an empty string
361  if (str.length() > 0 && str[str.length()-1] == delim)
362  {
363  elems.push_back("");
364  }
365 }
366 
367 void split (const std::wstring & str, const wchar_t delim, std::vector<std::wstring> & elems)
368 {
369  elems.clear();
370  std::wstringstream ss(str);
371  std::wstring item;
372  while(std::getline(ss, item, delim))
373  {
374  elems.push_back(item);
375  }
376 
377  // if last character in wstring matches the split delim add an empty string
378  if (str.length() > 0 && str[str.length()-1] == delim)
379  {
380  elems.push_back(L"");
381  }
382 }
383 
384 std::vector<std::string> split (const std::string & str, const char delim)
385 {
386  std::vector<std::string> elems;
387  split(str, delim, elems);
388  return elems;
389 }
390 
391 std::vector<std::wstring> split (const std::wstring & str, const wchar_t delim)
392 {
393  std::vector<std::wstring> elems;
394  split(str, delim, elems);
395  return elems;
396 }
397 
398 std::vector<std::string> split (const std::string & inStr, const std::string & inDelim)
399 {
400  std::vector<std::string> result;
401  size_t startPos(0);
402  size_t delimPos(inStr.find(inDelim, startPos));
403  while (delimPos != std::string::npos)
404  {
405  const std::string item (inStr.substr(startPos, delimPos - startPos));
406  result.push_back(item);
407  startPos = delimPos + inDelim.length();
408  delimPos = inStr.find(inDelim, startPos);
409  }
410  if (startPos < inStr.length()) // add last piece
411  result.push_back(inStr.substr(startPos, inStr.length()-startPos));
412  else if (startPos == inStr.length()) // if last character in string matches the split delim add an empty string
413  result.push_back(std::string());
414  return result;
415 }
416 
417 std::vector<std::wstring> split (const std::wstring & inStr, const std::wstring & inDelim)
418 {
419  std::vector<std::wstring> result;
420  size_t startPos(0);
421  size_t delimPos(inStr.find(inDelim, startPos));
422  while (delimPos != std::wstring::npos)
423  {
424  const std::wstring item (inStr.substr(startPos, delimPos - startPos));
425  result.push_back(item);
426  startPos = delimPos + inDelim.length();
427  delimPos = inStr.find(inDelim, startPos);
428  }
429  if (startPos < inStr.length()) // add last piece
430  result.push_back(inStr.substr(startPos, inStr.length()-startPos));
431  else if (startPos == inStr.length()) // if last character in string matches the split delim add an empty string
432  result.push_back(std::wstring());
433  return result;
434 }
435 
436 std::string & lower (std::string & str)
437 {
438  std::transform (str.begin(), str.end(), str.begin(), ::tolower);
439  return str;
440 }
441 
442 std::string & upper (std::string & str)
443 {
444  std::transform (str.begin(), str.end(), str.begin(), ::toupper);
445  return str;
446 }
447 
448 std::string & lstrip (std::string & str, const std::string & ws)
449 {
450  str.erase(0, str.find_first_not_of(ws));
451  return str;
452 }
453 
454 std::string & rstrip (std::string & str, const std::string & ws)
455 {
456  if (!str.empty())
457  str.erase (str.find_last_not_of(ws)+1, str.length()-1);
458  return str;
459 }
460 
461 std::string & strip (std::string & str, const std::string & ws)
462 {
463  lstrip(str,ws);
464  rstrip(str,ws);
465  return str;
466 }
467 
468 std::string join (const std::vector<std::string> & parts, const std::string & delim)
469 {
470  std::ostringstream oss;
471  for (std::vector<std::string>::const_iterator it(parts.begin()); it != parts.end(); )
472  {
473  oss << *it;
474  if (++it != parts.end())
475  oss << delim;
476  }
477  return oss.str();
478 }
479 
480 std::string join (const std::set<std::string> & parts, const std::string & delim)
481 {
482  std::ostringstream oss;
483  for (std::set<std::string>::const_iterator it(parts.begin()); it != parts.end(); )
484  {
485  oss << *it;
486  if (++it != parts.end())
487  oss << delim;
488  }
489  return oss.str();
490 }
491 
492 char* safer_strncpy(char* target, const char* source, size_t num, size_t maxSize)
493 {
494  int32_t lastIndex = (int32_t)maxSize-1;
495 
496  if (lastIndex < 0 || target == NULL)
497  {
498  return target;
499  }
500 
501  if (num >= maxSize)
502  num = (size_t)lastIndex;
503 
504  char *retVal = strncpy(target, source, num);
505  // make sure always null terminated
506  target[num] = '\0';
507 
508  return retVal;
509 }
510 
511 } //end aja namespace
aja::stoul
unsigned long stoul(const std::string &str, std::size_t *idx, int base)
Definition: common.cpp:143
aja::lstrip
std::string & lstrip(std::string &str, const std::string &ws)
Definition: common.cpp:448
aja::strip
std::string & strip(std::string &str, const std::string &ws)
Definition: common.cpp:461
NULL
#define NULL
Definition: ntv2caption608types.h:19
aja::join
std::string join(const std::vector< std::string > &parts, const std::string &delim)
Definition: common.cpp:468
aja::split
void split(const std::string &str, const char delim, std::vector< std::string > &elems)
Definition: common.cpp:350
aja::wstring_to_string
bool wstring_to_string(const std::wstring &wstr, std::string &str)
Definition: common.cpp:285
aja::safer_strncpy
char * safer_strncpy(char *target, const char *source, size_t num, size_t maxSize)
Definition: common.cpp:492
aja::stoi
int stoi(const std::string &str, std::size_t *idx, int base)
Definition: common.cpp:122
aja::string_to_cstring
bool string_to_cstring(const std::string &str, char *c_str, size_t c_str_size)
Definition: common.cpp:336
aja::lower
std::string & lower(std::string &str)
Definition: common.cpp:436
aja::replace
std::string & replace(std::string &str, const std::string &from, const std::string &to)
Definition: common.cpp:110
aja::stol
long stol(const std::string &str, std::size_t *idx, int base)
Definition: common.cpp:127
aja::upper
std::string & upper(std::string &str)
Definition: common.cpp:442
aja::string_to_wstring
bool string_to_wstring(const std::string &str, std::wstring &wstr)
Definition: common.cpp:248
aja::stoull
unsigned long long stoull(const std::string &str, std::size_t *idx, int base)
Definition: common.cpp:154
aja::stof
float stof(const std::string &str, std::size_t *idx)
Definition: common.cpp:159
aja::rstrip
std::string & rstrip(std::string &str, const std::string &ws)
Definition: common.cpp:454
common.h
Private include file for all ajabase sources.
aja::ends_with
bool ends_with(const std::string &str, const std::string &needle)
Definition: common.cpp:83
aja
Definition: common.cpp:57
aja::stold
long double stold(const std::string &str, std::size_t *idx)
Definition: common.cpp:175
aja::starts_with
bool starts_with(const std::string &str, const std::string &needle)
Definition: common.cpp:61
aja::to_string
std::string to_string(bool val)
Definition: common.cpp:180
aja::local_min
size_t local_min(const size_t &a, const size_t &b)
Definition: common.cpp:322
aja::stod
double stod(const std::string &str, std::size_t *idx)
Definition: common.cpp:164