HAL
callback_hook.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 
26 #pragma once
27 
28 #include "hal_core/defines.h"
29 
30 #include <functional>
31 #include <map>
32 #include <set>
33 #include <string>
34 
35 #define CALLBACK_HOOK_INVALID_IDX 0x0
36 
37 namespace hal
38 {
39  template<class>
40  class CallbackHook;
41 
45  template<class R, class... ArgTypes>
46  class CallbackHook<R(ArgTypes...)>
47  {
48  public:
57  u64 add_callback(const std::function<R(ArgTypes...)>& callback, u64 id = CALLBACK_HOOK_INVALID_IDX)
58  {
59  if (id == CALLBACK_HOOK_INVALID_IDX)
60  {
61  id = 1;
62  while (m_callbacks.find(id) != m_callbacks.end())
63  {
64  ++id;
65  }
66  }
67  m_callbacks[id] = callback;
68  return id;
69  }
70 
78  void add_callback(const std::string& name, const std::function<R(ArgTypes...)>& callback)
79  {
80  auto it = m_name_to_id_map.find(name);
81  if (it != m_name_to_id_map.end())
82  {
83  remove_callback(it->second);
84  }
85  m_name_to_id_map[name] = add_callback(callback);
86  }
87 
93  void remove_callback(const u64 id)
94  {
95  auto it = m_callbacks.find(id);
96  if (it != m_callbacks.end())
97  {
98  m_callbacks.erase(it);
99  for (auto it2 = m_name_to_id_map.begin(); it2 != m_name_to_id_map.end(); it2++)
100  {
101  if ((*it2).second == id)
102  {
103  m_name_to_id_map.erase(it2);
104  break;
105  }
106  }
107  }
108  }
109 
115  void remove_callback(const std::string& id)
116  {
117  auto it = m_name_to_id_map.find(id);
118  if (it != m_name_to_id_map.end())
119  {
120  remove_callback((*it).second);
121  }
122  }
123 
129  void inline operator()(ArgTypes... args)
130  {
131  if (this->size() == 0)
132  {
133  return;
134  }
135  for (const auto& i : m_callbacks)
136  {
137  (i.second)(args...);
138  }
139  }
140 
149  R inline call(const u64 idx, ArgTypes... args)
150  {
151  auto it = m_callbacks.find(idx);
152  if (it == m_callbacks.end())
153  {
154  return R();
155  }
156  return (it->second)(args...);
157  }
158 
167  R inline call(const std::string& idx, ArgTypes... args)
168  {
169  auto it = m_name_to_id_map.find(idx);
170  if (it == m_name_to_id_map.end())
171  {
172  return R();
173  }
174  return call((*it).second, args...);
175  }
176 
184  {
185  return m_callbacks.find(id) != m_callbacks.end();
186  }
187 
194  bool is_callback_registered(const std::string& name)
195  {
196  return m_name_to_id_map.find(name) != m_name_to_id_map.end();
197  }
198 
204  size_t size()
205  {
206  return m_callbacks.size();
207  }
208 
214  std::set<u64> get_ids()
215  {
216  std::set<u64> res;
217  for (const auto& it : m_callbacks)
218  {
219  res.insert(it.first);
220  }
221  return res;
222  }
223 
230  std::string get_name(u64 id)
231  {
232  for (const auto& it : m_name_to_id_map)
233  {
234  if (it.second == id)
235  {
236  return it.first;
237  }
238  }
239  return "";
240  }
241 
242  private:
243  std::map<u64, std::function<R(ArgTypes...)>> m_callbacks;
244 
245  std::map<std::string, u64> m_name_to_id_map;
246  };
247 } // namespace hal
#define CALLBACK_HOOK_INVALID_IDX
Definition: callback_hook.h:35
bool is_callback_registered(const u64 id)
void add_callback(const std::string &name, const std::function< R(ArgTypes...)> &callback)
Definition: callback_hook.h:78
void remove_callback(const u64 id)
Definition: callback_hook.h:93
void remove_callback(const std::string &id)
void operator()(ArgTypes... args)
u64 add_callback(const std::function< R(ArgTypes...)> &callback, u64 id=0x0)
Definition: callback_hook.h:57
bool is_callback_registered(const std::string &name)
R call(const std::string &idx, ArgTypes... args)
R call(const u64 idx, ArgTypes... args)
uint64_t u64
Definition: defines.h:42
std::string name
i32 id