HAL
utils.h
Go to the documentation of this file.
1 // MIT License
2 //
3 // Copyright (c) 2019 Ruhr University Bochum, Chair for Embedded Security. All Rights reserved.
4 // Copyright (c) 2019 Marc Fyrbiak, Sebastian Wallat, Max Hoffmann ("ORIGINAL AUTHORS"). All rights reserved.
5 // Copyright (c) 2021 Max Planck Institute for Security and Privacy. All Rights reserved.
6 // Copyright (c) 2021 Jörn Langheinrich, Julian Speith, Nils Albartus, René Walendy, Simon Klix ("ORIGINAL AUTHORS"). All Rights reserved.
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
25 
30 #pragma once
31 
32 #include "hal_core/defines.h"
34 
35 #include <algorithm>
36 #include <functional>
37 #include <set>
38 #include <sstream>
39 #include <string>
40 #include <unordered_set>
41 #include <vector>
42 
43 namespace hal
44 {
48  namespace utils
49  {
57  template<typename T>
58  CORE_API inline bool unordered_vector_erase(std::vector<T>& vec, T element)
59  {
60  auto it = std::find(vec.begin(), vec.end(), element);
61  if (it == vec.end())
62  {
63  return false;
64  }
65  *it = vec.back();
66  vec.pop_back();
67  return true;
68  }
69 
77  template<typename T>
78  bool vectors_have_same_content(std::vector<T> vec_1, std::vector<T> vec_2)
79  {
80  if (vec_1.size() != vec_2.size())
81  {
82  return false;
83  }
84 
85  std::sort(vec_1.begin(), vec_1.end());
86  std::sort(vec_2.begin(), vec_2.end());
87 
88  return vec_1 == vec_2;
89  }
90 
98  CORE_API inline u64 get_bit(const u64 value, const u64 index)
99  {
100  return (value >> index) & 1;
101  }
102 
110  CORE_API inline u64 set_bit(const u64 value, const u64 index)
111  {
112  return value | ((u64)1 << index);
113  }
114 
122  CORE_API inline u64 clear_bit(const u64 value, const u64 index)
123  {
124  return value & ~((u64)1 << index);
125  }
126 
134  CORE_API inline u64 toggle_bit(const u64 value, const u64 index)
135  {
136  return value ^ ((u64)1 << index);
137  }
138 
146  template<typename T>
147  CORE_API bool ends_with(const T& s, const T& end)
148  {
149  if (s.length() >= end.length())
150  {
151  return (0 == s.compare(s.length() - end.length(), end.length(), end));
152  }
153  else
154  {
155  return false;
156  }
157  }
158 
166  template<typename T>
167  CORE_API bool starts_with(const T& s, const T& start)
168  {
169  if (s.length() >= start.length())
170  {
171  return (0 == s.compare(0, start.length(), start));
172  }
173  else
174  {
175  return false;
176  }
177  }
178 
185  template<typename T>
186  CORE_API bool is_digits(const T& s)
187  {
188  return std::all_of(s.begin(), s.end(), ::isdigit);
189  }
190 
197  template<typename T>
198  CORE_API bool is_integer(const T& s)
199  {
200  if (s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+')))
201  {
202  return false;
203  }
204 
205  char* p;
206  strtol(s.c_str(), &p, 10);
207 
208  return (*p == 0);
209  }
210 
217  template<typename T>
218  CORE_API bool is_floating_point(const T& s)
219  {
220  std::stringstream ss(s.c_str());
221  float f;
222  ss >> f;
223  return (ss.eof() && !ss.fail());
224  }
225 
236  template<typename T>
237  CORE_API std::vector<T> split(const T& s, const char delim, bool obey_brackets = false)
238  {
239  std::vector<T> result;
240  T item = "";
241 
242  if (obey_brackets)
243  {
244  int bracket_level = 0;
245 
246  for (size_t i = 0; i < s.length(); ++i)
247  {
248  char c = s.at(i);
249  switch (c)
250  {
251  case '(':
252  case '{':
253  case '[':
254  ++bracket_level;
255  break;
256  case ')':
257  case '}':
258  case ']':
259  --bracket_level;
260  break;
261  default:
262  break;
263  }
264  if (bracket_level < 0)
265  {
266  bracket_level = 0;
267  }
268  if (c == delim)
269  {
270  // No constant expression, therefore not usable in switch case
271  if (bracket_level == 0)
272  {
273  result.push_back(item);
274  item = "";
275  }
276  else
277  {
278  item.push_back(c);
279  }
280  }
281  else
282  {
283  item.push_back(c);
284  }
285  }
286  if (!item.empty())
287  {
288  result.push_back(item);
289  }
290  }
291  else
292  {
293  std::stringstream ss(s);
294  while (std::getline(ss, item, delim))
295  {
296  result.push_back(item);
297  }
298  }
299  if (s.back() == delim)
300  {
301  result.push_back("");
302  }
303  return result;
304  }
305 
313  template<typename T>
314  CORE_API T ltrim(const T& s, const char* to_remove = " \t\r\n")
315  {
316  size_t start = s.find_first_not_of(to_remove);
317 
318  if (start != std::string::npos)
319  {
320  return s.substr(start, s.size() - start);
321  }
322  else
323  {
324  return "";
325  }
326  }
327 
335  template<typename T>
336  CORE_API T rtrim(const T& s, const char* to_remove = " \t\r\n")
337  {
338  size_t end = s.find_last_not_of(to_remove);
339 
340  if (end != std::string::npos)
341  {
342  return s.substr(0, end + 1);
343  }
344  else
345  {
346  return "";
347  }
348  }
349 
357  template<typename T>
358  CORE_API T trim(const T& s, const char* to_remove = " \t\r\n")
359  {
360  size_t start = s.find_first_not_of(to_remove);
361  size_t end = s.find_last_not_of(to_remove);
362 
363  if (start != T::npos)
364  {
365  return s.substr(start, end - start + 1);
366  }
367  else
368  {
369  return "";
370  }
371  }
372 
381  template<typename T>
382  CORE_API T replace(const T& str, const T& search, const T& replace)
383  {
384  auto s = str;
385  size_t pos = 0;
386 
387  if (search.empty())
388  {
389  return str;
390  }
391 
392  while ((pos = s.find(search, pos)) != T::npos)
393  {
394  s.replace(pos, search.length(), replace);
395  pos += replace.length();
396  }
397 
398  return s;
399  }
400 
411  template<typename Iterator, class Transform>
412  CORE_API std::string join(const std::string& joiner, const Iterator& begin, const Iterator& end, const Transform& transform)
413  {
414  std::stringstream ss;
415  bool first = true;
416  for (auto it = begin; it != end; ++it)
417  {
418  if (!first)
419  {
420  ss << joiner;
421  }
422  first = false;
423  ss << transform(*it);
424  }
425  return ss.str();
426  }
427 
437  template<typename T, class Transform>
438  CORE_API std::string join(const std::string& joiner, const T& items, const Transform& transform)
439  {
440  return join(joiner, items.begin(), items.end(), transform);
441  }
442 
450  template<typename T>
451  CORE_API std::string join(const std::string& joiner, const T& items)
452  {
453  return join(joiner, items.begin(), items.end(), [](const auto& v) { return v; });
454  }
455 
462  template<typename T>
463  CORE_API T to_upper(const T& s)
464  {
465  T result = s;
466  std::transform(result.begin(), result.end(), result.begin(), [](char c) { return std::toupper(c); });
467  return result;
468  }
469 
476  template<typename T>
477  CORE_API T to_lower(const T& s)
478  {
479  T result = s;
480  std::transform(result.begin(), result.end(), result.begin(), [](char c) { return std::tolower(c); });
481  return result;
482  }
483 
491  template<typename T>
492  CORE_API u32 num_of_occurrences(const T& s, const T& substr)
493  {
495  auto position = s.find(substr, 0);
496 
497  while (position != std::string::npos)
498  {
500  position = s.find(substr, position + 1);
501  }
502 
503  return num_of_occurrences;
504  }
505 
512  template<typename T, template<typename, typename...> class Container, typename... Args>
513  CORE_API inline std::vector<T> to_vector(const Container<T, Args...>& container)
514  {
515  return std::vector<T>(container.begin(), container.end());
516  }
517 
524  template<typename T, template<typename, typename...> class Container, typename... Args>
525  CORE_API inline std::set<T> to_set(const Container<T, Args...>& container)
526  {
527  return std::set<T>(container.begin(), container.end());
528  }
529 
538  template<typename T1, typename T2>
539  CORE_API bool is_subset(const T1& subset, const T2& superset)
540  {
541  for (const auto& element : subset)
542  {
543  if (std::find(std::begin(superset), std::end(superset), element) == std::end(superset))
544  {
545  return false; // Element not found in superset
546  }
547  }
548  return true; // All elements found; subset is indeed a subset of superset
549  }
550 
557  CORE_API bool file_exists(const std::string& filename);
558 
565  CORE_API bool folder_exists_and_is_accessible(const std::filesystem::path& path);
566 
574  CORE_API std::filesystem::path which(const std::string& name, const std::string& path = "");
575 
581  CORE_API std::filesystem::path get_binary_directory();
582 
591  CORE_API std::filesystem::path get_base_directory();
592 
599  CORE_API std::filesystem::path get_library_directory();
600 
607  CORE_API std::filesystem::path get_share_directory();
608 
614  CORE_API std::filesystem::path get_user_share_directory();
615 
622  CORE_API std::filesystem::path get_config_directory();
623 
629  CORE_API std::filesystem::path get_user_config_directory();
630 
638  CORE_API std::filesystem::path get_default_log_directory(std::filesystem::path source_file = "");
639 
645  CORE_API std::vector<std::filesystem::path> get_gate_library_directories();
646 
652  CORE_API std::vector<std::filesystem::path> get_plugin_directories();
653 
660  CORE_API std::filesystem::path get_first_directory_exists(std::vector<std::filesystem::path> path_hints);
661 
669  CORE_API std::filesystem::path get_file(std::string file_name, std::vector<std::filesystem::path> path_hints);
670 
678  CORE_API Result<std::filesystem::path> get_unique_temp_directory(const std::string& prefix = "", const u32 max_attempts = 5);
679 
685  CORE_API std::string get_open_source_licenses();
686 
691  {
692  public:
693  using iterator = std::filesystem::recursive_directory_iterator;
694 
700  RecursiveDirectoryRange(std::filesystem::path path) : p_(path)
701  {
702  }
703 
711  {
712  return std::filesystem::recursive_directory_iterator(p_);
713  }
714 
721  {
722  return std::filesystem::recursive_directory_iterator();
723  }
724 
725  private:
726  std::filesystem::path p_;
727  };
728 
733  {
734  public:
735  using iterator = std::filesystem::directory_iterator;
736 
742  DirectoryRange(std::filesystem::path path) : p_(path)
743  {
744  }
745 
754  {
755  return std::filesystem::directory_iterator(p_);
756  }
757 
764  {
765  return std::filesystem::directory_iterator();
766  }
767 
768  private:
769  std::filesystem::path p_;
770  };
771 
777  {
778  int h;
779  int s;
780  int v;
781 
782  Color(int _h = 0, int _s = 0, int _v = 0) : h(_h), s(_s), v(_v)
783  {
784  }
785 
786  std::string toString()
787  {
788  return "h=" + std::to_string(h) + " s=" + std::to_string(s) + " v=" + std::to_string(v);
789  }
790  };
791 
800  CORE_API Result<u64> wrapped_stoull(const std::string& s, const u32 base = 10);
801 
810  CORE_API Result<u32> wrapped_stoul(const std::string& s, const u32 base = 10);
811  } // namespace utils
812 } // namespace hal
#define CORE_API
Definition: arch_linux.h:28
DirectoryRange(std::filesystem::path path)
Definition: utils.h:742
std::filesystem::directory_iterator iterator
Definition: utils.h:735
std::filesystem::recursive_directory_iterator iterator
Definition: utils.h:693
RecursiveDirectoryRange(std::filesystem::path path)
Definition: utils.h:700
uint64_t u64
Definition: defines.h:42
CORE_API T replace(const T &str, const T &search, const T &replace)
Definition: utils.h:382
CORE_API bool ends_with(const T &s, const T &end)
Definition: utils.h:147
CORE_API bool is_digits(const T &s)
Definition: utils.h:186
CORE_API T ltrim(const T &s, const char *to_remove=" \t\r\n")
Definition: utils.h:314
CORE_API bool starts_with(const T &s, const T &start)
Definition: utils.h:167
std::filesystem::path get_config_directory()
Definition: utils.cpp:163
CORE_API u64 set_bit(const u64 value, const u64 index)
Definition: utils.h:110
std::filesystem::path get_user_share_directory()
Definition: utils.cpp:156
bool vectors_have_same_content(std::vector< T > vec_1, std::vector< T > vec_2)
Definition: utils.h:78
CORE_API T trim(const T &s, const char *to_remove=" \t\r\n")
Definition: utils.h:358
std::filesystem::path get_first_directory_exists(std::vector< std::filesystem::path > path_hints)
Definition: utils.cpp:206
CORE_API std::vector< T > split(const T &s, const char delim, bool obey_brackets=false)
Definition: utils.h:237
CORE_API std::set< T > to_set(const Container< T, Args... > &container)
Definition: utils.h:525
CORE_API u32 num_of_occurrences(const T &s, const T &substr)
Definition: utils.h:492
CORE_API T rtrim(const T &s, const char *to_remove=" \t\r\n")
Definition: utils.h:336
CORE_API u64 toggle_bit(const u64 value, const u64 index)
Definition: utils.h:134
std::filesystem::path get_share_directory()
Definition: utils.cpp:148
Result< std::filesystem::path > get_unique_temp_directory(const std::string &prefix, const u32 max_attmeps)
Definition: utils.cpp:275
CORE_API u64 get_bit(const u64 value, const u64 index)
Definition: utils.h:98
CORE_API std::string join(const std::string &joiner, const Iterator &begin, const Iterator &end, const Transform &transform)
Definition: utils.h:412
std::vector< std::filesystem::path > get_gate_library_directories()
Definition: utils.cpp:185
std::filesystem::path get_base_directory()
Definition: utils.cpp:99
std::string get_open_source_licenses()
Definition: utils.cpp:298
std::filesystem::path get_library_directory()
Definition: utils.cpp:128
Result< u64 > wrapped_stoull(const std::string &s, const u32 base)
Definition: utils.cpp:695
std::filesystem::path get_user_config_directory()
Definition: utils.cpp:171
Result< u32 > wrapped_stoul(const std::string &s, const u32 base)
Definition: utils.cpp:713
CORE_API bool is_integer(const T &s)
Definition: utils.h:198
CORE_API T to_lower(const T &s)
Definition: utils.h:477
CORE_API bool unordered_vector_erase(std::vector< T > &vec, T element)
Definition: utils.h:58
CORE_API u64 clear_bit(const u64 value, const u64 index)
Definition: utils.h:122
std::vector< std::filesystem::path > get_plugin_directories()
Definition: utils.cpp:194
std::filesystem::path which(const std::string &name, const std::string &path)
Definition: utils.cpp:242
CORE_API bool is_floating_point(const T &s)
Definition: utils.h:218
CORE_API T to_upper(const T &s)
Definition: utils.h:463
std::filesystem::path get_default_log_directory(std::filesystem::path source_file)
Definition: utils.cpp:178
CORE_API std::vector< T > to_vector(const Container< T, Args... > &container)
Definition: utils.h:513
bool folder_exists_and_is_accessible(const std::filesystem::path &folder)
Definition: utils.cpp:36
bool file_exists(const std::string &filename)
Definition: utils.cpp:30
std::filesystem::path get_binary_directory()
Definition: utils.cpp:69
std::filesystem::path get_file(std::string file_name, std::vector< std::filesystem::path > path_hints)
Definition: utils.cpp:219
CORE_API bool is_subset(const T1 &subset, const T2 &superset)
Definition: utils.h:539
Definition: utils.py:1
quint32 u32
std::string name
Color(int _h=0, int _s=0, int _v=0)
Definition: utils.h:782
std::string toString()
Definition: utils.h:786