HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
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 {
44  template<class>
45  class CallbackHook;
46 
53  template<class R, class... ArgTypes>
54  class CallbackHook<R(ArgTypes...)>
55  {
56  public:
65  u64 add_callback(const std::function<R(ArgTypes...)>& callback, u64 id = CALLBACK_HOOK_INVALID_IDX)
66  {
67  if (id == CALLBACK_HOOK_INVALID_IDX)
68  {
69  id = 1;
70  while (m_callbacks.find(id) != m_callbacks.end())
71  {
72  ++id;
73  }
74  }
75  m_callbacks[id] = callback;
76  return id;
77  }
78 
86  void add_callback(const std::string& name, const std::function<R(ArgTypes...)>& callback)
87  {
88  auto it = m_name_to_id_map.find(name);
89  if (it != m_name_to_id_map.end())
90  {
91  remove_callback(it->second);
92  }
93  m_name_to_id_map[name] = add_callback(callback);
94  }
95 
101  void remove_callback(const u64 id)
102  {
103  auto it = m_callbacks.find(id);
104  if (it != m_callbacks.end())
105  {
106  m_callbacks.erase(it);
107  for (auto it2 = m_name_to_id_map.begin(); it2 != m_name_to_id_map.end(); it2++)
108  {
109  if ((*it2).second == id)
110  {
111  m_name_to_id_map.erase(it2);
112  break;
113  }
114  }
115  }
116  }
117 
123  void remove_callback(const std::string& id)
124  {
125  auto it = m_name_to_id_map.find(id);
126  if (it != m_name_to_id_map.end())
127  {
128  remove_callback((*it).second);
129  }
130  }
131 
137  void inline operator()(ArgTypes... args)
138  {
139  if (this->size() == 0)
140  {
141  return;
142  }
143  for (const auto& i : m_callbacks)
144  {
145  (i.second)(args...);
146  }
147  }
148 
157  R inline call(const u64 idx, ArgTypes... args)
158  {
159  auto it = m_callbacks.find(idx);
160  if (it == m_callbacks.end())
161  {
162  return R();
163  }
164  return (it->second)(args...);
165  }
166 
175  R inline call(const std::string& idx, ArgTypes... args)
176  {
177  auto it = m_name_to_id_map.find(idx);
178  if (it == m_name_to_id_map.end())
179  {
180  return R();
181  }
182  return call((*it).second, args...);
183  }
184 
192  {
193  return m_callbacks.find(id) != m_callbacks.end();
194  }
195 
202  bool is_callback_registered(const std::string& name)
203  {
204  return m_name_to_id_map.find(name) != m_name_to_id_map.end();
205  }
206 
212  size_t size()
213  {
214  return m_callbacks.size();
215  }
216 
222  std::set<u64> get_ids()
223  {
224  std::set<u64> res;
225  for (const auto& it : m_callbacks)
226  {
227  res.insert(it.first);
228  }
229  return res;
230  }
231 
238  std::string get_name(u64 id)
239  {
240  for (const auto& it : m_name_to_id_map)
241  {
242  if (it.second == id)
243  {
244  return it.first;
245  }
246  }
247  return "";
248  }
249 
250  private:
251  std::map<u64, std::function<R(ArgTypes...)>> m_callbacks;
252 
253  std::map<std::string, u64> m_name_to_id_map;
254  };
255 } // namespace hal
#define CALLBACK_HOOK_INVALID_IDX
Definition: callback_hook.h:35
u32 size
u64 add_callback(const std::function< R(ArgTypes...)> &callback, u64 id=CALLBACK_HOOK_INVALID_IDX)
Definition: callback_hook.h:65
bool is_callback_registered(const u64 id)
void add_callback(const std::string &name, const std::function< R(ArgTypes...)> &callback)
Definition: callback_hook.h:86
void remove_callback(const std::string &id)
void operator()(ArgTypes... args)
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
Definition: defines.h:45
std::string name
i32 id