HAL  v4.5.0-257-ge24279b4e
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
data_container.cpp
Go to the documentation of this file.
2 
4 
5 #include <cctype>
6 
7 namespace hal
8 {
9  namespace
10  {
11  std::string normalize_bv_value(Parameter::Type type, const std::string& value)
12  {
14  return value;
15  if (value.size() < 2 || value[0] != '0')
16  return value;
17  const char pfx = static_cast<char>(std::tolower(static_cast<unsigned char>(value[1])));
18  if (pfx != 'b' && pfx != 'o' && pfx != 'x')
19  return value;
20  std::string result;
21  result.reserve(value.size());
22  result += '0';
23  result += pfx;
24  for (std::size_t i = 2; i < value.size(); ++i)
25  result += static_cast<char>(std::toupper(static_cast<unsigned char>(value[i])));
26  return result;
27  }
28  } // namespace
29  bool DataContainer::operator==(const DataContainer& other) const
30  {
31  return m_data == other.get_data_map() && m_parameters == other.get_parameters();
32  }
33 
34  bool DataContainer::operator!=(const DataContainer& other) const
35  {
36  return !operator==(other);
37  }
38 
39  bool DataContainer::set_data(const std::string& category, const std::string& key, const std::string& value_data_type, const std::string& value, const bool log_with_info_level)
40  {
41  if (category.empty() || key.empty())
42  {
43  log_error("netlist", "key category or key is empty.");
44  return false;
45  }
46 
47  m_data[std::make_tuple(category, key)] = std::make_tuple(value_data_type, value);
48 
49  //notify_updated();
50 
51  if (log_with_info_level)
52  {
53  log_info("netlist", "added {} data '{}' ({}, {}).", value_data_type, value, category, key);
54  }
55  else
56  {
57  log_debug("netlist", "added {} data '{}' ({}, {}).", value_data_type, value, category, key);
58  }
59 
60  return true;
61  }
62 
63  bool DataContainer::delete_data(const std::string& category, const std::string& key, const bool log_with_info_level)
64  {
65  if (category.empty() || key.empty())
66  {
67  log_error("netlist", "key category or key is empty.");
68  return false;
69  }
70 
71  auto it = m_data.find(std::make_tuple(category, key));
72  if (it == m_data.end())
73  {
74  log_debug("netlist", "no key ('{}', '{}') found.", category, key);
75  return true;
76  }
77 
78  auto deleted_value = std::get<1>(it->second);
79  m_data.erase(it);
80 
81  //notify_updated();
82 
83  if (log_with_info_level)
84  {
85  log_info("netlist", "removed data '{}' ({}, {}).", deleted_value, category, key);
86  }
87  else
88  {
89  log_debug("netlist", "removed data '{}' ({}, {}).", deleted_value, category, key);
90  }
91  return true;
92  }
93 
94  const std::map<std::tuple<std::string, std::string>, std::tuple<std::string, std::string>>& DataContainer::get_data_map() const
95  {
96  return m_data;
97  }
98 
99  void DataContainer::set_data_map(const std::map<std::tuple<std::string, std::string>, std::tuple<std::string, std::string>>& map)
100  {
101  m_data = map;
102  }
103 
104  bool DataContainer::has_data(const std::string& category, const std::string& key) const
105  {
106  if (category.empty() || key.empty())
107  {
108  return false;
109  }
110 
111  if (auto it = m_data.find(std::make_tuple(category, key)); it == m_data.end())
112  {
113  return false;
114  }
115 
116  return true;
117  }
118 
119  std::tuple<std::string, std::string> DataContainer::get_data(const std::string& category, const std::string& key) const
120  {
121  if (category.empty() || key.empty())
122  {
123  log_error("netlist", "key category or key is empty.");
124  return std::make_tuple("", "");
125  }
126 
127  auto it = m_data.find(std::make_tuple(category, key));
128  if (it == m_data.end())
129  {
130  log_debug("netlist", "no value stored for key ('{}', '{}').", category, key);
131  return std::make_tuple("", "");
132  }
133  return it->second;
134  }
135 
136  Result<std::monostate> DataContainer::set_parameter(const Parameter& param, const std::string& value)
137  {
138  if (!param.validate(value))
139  {
140  return ERR("invalid parameter value");
141  }
142 
143  const std::string normalized = normalize_bv_value(param.get_type(), value);
144  m_parameters.insert_or_assign(param.get_name(), std::make_pair(param, normalized));
145 
146  return OK({});
147  }
148 
150  {
151  if (auto it = m_parameters.find(name); it != m_parameters.end())
152  {
153  return OK(it->second.second);
154  }
155 
156  return ERR("no parameter named '" + name + "'");
157  }
158 
160  {
161  auto it = m_parameters.find(param.get_name());
162  if (it == m_parameters.end())
163  {
164  return ERR("no parameter named '" + param.get_name() + "'");
165  }
166 
167  if (it->second.first != param)
168  {
169  return ERR("parameter with name '" + param.get_name() + "' exists, but does not match provided parameter declaration");
170  }
171 
172  return OK(it->second.second);
173  }
174 
176  {
177  if (auto it = m_parameters.find(name); it != m_parameters.end())
178  {
179  return OK(it->second.first);
180  }
181 
182  return ERR("no parameter named '" + name + "'");
183  }
184 
185  bool DataContainer::has_parameter(const std::string& name) const
186  {
187  return m_parameters.find(name) != m_parameters.end();
188  }
189 
190  bool DataContainer::has_parameter(const Parameter& param) const
191  {
192  const auto it = m_parameters.find(param.get_name());
193  return it != m_parameters.end() && it->second.first == param;
194  }
195 
196  bool DataContainer::delete_parameter(const std::string& name)
197  {
198  return m_parameters.erase(name) > 0;
199  }
200 
201  const std::unordered_map<std::string, std::pair<Parameter, std::string>>& DataContainer::get_parameters() const
202  {
203  return m_parameters;
204  }
205 
206 } // namespace hal
const std::map< std::tuple< std::string, std::string >, std::tuple< std::string, std::string > > & get_data_map() const
bool operator==(const DataContainer &other) const
std::tuple< std::string, std::string > get_data(const std::string &category, const std::string &key) const
bool operator!=(const DataContainer &other) const
std::map< std::tuple< std::string, std::string >, std::tuple< std::string, std::string > > m_data
Result< std::string > get_parameter_value(const std::string &name) const
std::unordered_map< std::string, std::pair< Parameter, std::string > > m_parameters
bool has_parameter(const Parameter &param) const
const std::unordered_map< std::string, std::pair< Parameter, std::string > > & get_parameters() const
Result< Parameter > get_parameter_declaration(const std::string &name) const
bool set_data(const std::string &category, const std::string &key, const std::string &data_type, const std::string &value, const bool log_with_info_level=false)
Result< std::monostate > set_parameter(const Parameter &param, const std::string &value)
bool has_data(const std::string &category, const std::string &key) const
bool delete_data(const std::string &category, const std::string &key, const bool log_with_info_level=false)
void set_data_map(const std::map< std::tuple< std::string, std::string >, std::tuple< std::string, std::string >> &map)
bool delete_parameter(const std::string &name)
#define log_error(channel,...)
Definition: log.h:78
#define log_debug(channel,...)
Definition: log.h:74
#define log_info(channel,...)
Definition: log.h:70
#define ERR(message)
Definition: result.h:60
#define OK(...)
Definition: result.h:56
Definition: defines.h:45
PinType type
std::string name
Type get_type() const
Definition: parameter.cpp:299
const std::string & get_name() const
Definition: parameter.cpp:294
bool validate(const std::string &value) const
Definition: parameter.cpp:505