Line data Source code
1 : //
2 : // DUNE DAQ modification notice:
3 : // This file has been modified from the original ATLAS config source for the DUNE DAQ project.
4 : // Fork baseline commit: 67a24e731 (2022-10-27).
5 : // Renamed since fork: no.
6 : //
7 :
8 : #include <iostream>
9 : #include <vector>
10 :
11 : #include "conffwk/ConfigObject.hpp"
12 : #include "conffwk/ConfigObjectImpl.hpp"
13 : #include "conffwk/Configuration.hpp"
14 : #include "conffwk/ConfigurationImpl.hpp"
15 : #include "conffwk/Schema.hpp"
16 :
17 : namespace dunedaq {
18 : namespace conffwk {
19 :
20 914 : ConfigObject::ConfigObject() noexcept
21 914 : : m_impl(nullptr)
22 : {
23 914 : }
24 :
25 2405 : ConfigObject::ConfigObject(const ConfigObject& other) noexcept
26 2405 : : m_impl(other.m_impl)
27 : {
28 2405 : }
29 :
30 658 : ConfigObject::ConfigObject(ConfigObjectImpl* impl) noexcept
31 658 : : m_impl(impl)
32 : {
33 658 : }
34 :
35 3959 : ConfigObject::~ConfigObject() noexcept {}
36 :
37 : ConfigObject&
38 0 : ConfigObject::operator=(const ConfigObject& other) noexcept
39 : {
40 0 : if (this != &other) {
41 0 : m_impl = other.m_impl;
42 : }
43 :
44 0 : return *this;
45 : }
46 :
47 : ConfigObject&
48 922 : ConfigObject::operator=(ConfigObjectImpl* impl) noexcept
49 : {
50 922 : if (m_impl != impl) {
51 838 : m_impl = impl;
52 : }
53 :
54 922 : return *this;
55 : }
56 :
57 : bool
58 0 : ConfigObject::operator==(const ConfigObject& other) const noexcept
59 : {
60 0 : if (this == &other || m_impl == other.m_impl)
61 : return true; // the objects or implementations are the same
62 0 : if (!m_impl || !other.m_impl)
63 : return false; // only one of objects has no implementation
64 0 : return ((UID() == other.UID()) && (class_name() == other.class_name()));
65 : }
66 :
67 : void
68 0 : ConfigObject::print_ptr(std::ostream& s) const noexcept
69 : {
70 0 : if (m_impl) {
71 0 : if (m_impl->is_deleted()) {
72 0 : s << "(deleted object " << full_name() << ')';
73 : } else {
74 0 : s << full_name();
75 : }
76 : } else {
77 0 : s << "(null)";
78 : }
79 0 : }
80 :
81 : Configuration*
82 31 : ConfigObject::get_configuration() const
83 : {
84 31 : return m_impl->m_impl->m_conf;
85 : }
86 :
87 : void
88 0 : ConfigObject::rename(const std::string& new_id)
89 : {
90 0 : get_configuration()->rename_object(*this, new_id);
91 0 : action_on_object_update(get_configuration(), new_id);
92 0 : }
93 :
94 : void
95 31 : ConfigObject::action_on_object_update(Configuration* db, const std::string& name)
96 : {
97 31 : db->action_on_update(*this, name);
98 31 : }
99 :
100 : std::ostream&
101 0 : operator<<(std::ostream& s, const ConfigObject* obj)
102 : {
103 0 : obj->print_ptr(s);
104 0 : return s;
105 : }
106 :
107 : std::ostream&
108 0 : operator<<(std::ostream& s, const ConfigObject& obj)
109 : {
110 0 : obj.print_ptr(s);
111 0 : return s;
112 : }
113 :
114 : inline static void
115 0 : print_sep(const char sep, std::ostream& s)
116 : {
117 0 : if (sep)
118 0 : s << sep;
119 0 : }
120 :
121 : template<class T>
122 : void
123 0 : print_val(const T& val, std::ostream& s)
124 : {
125 0 : s << val;
126 0 : }
127 :
128 : template<>
129 : void
130 0 : print_val<uint8_t>(const uint8_t& val, std::ostream& s)
131 : {
132 0 : s << static_cast<uint16_t>(val);
133 0 : }
134 :
135 : template<>
136 : void
137 0 : print_val<int8_t>(const int8_t& val, std::ostream& s)
138 : {
139 0 : s << static_cast<int16_t>(val);
140 0 : }
141 :
142 : template<class T>
143 : void
144 0 : print_value(const ConfigObject& const_obj, const std::string& name, const bool ismv, const char sep, std::ostream& s)
145 : {
146 0 : ConfigObject& obj = const_cast<ConfigObject&>(const_obj);
147 :
148 : try {
149 0 : if (ismv) {
150 0 : std::vector<T> value;
151 :
152 0 : obj.get(name, value);
153 :
154 0 : print_sep('(', s);
155 :
156 0 : for (unsigned int i = 0; i < value.size(); ++i) {
157 0 : if (i != 0)
158 0 : s << ", ";
159 :
160 0 : print_sep(sep, s);
161 0 : print_val<T>(value[i], s);
162 0 : print_sep(sep, s);
163 : }
164 :
165 0 : print_sep(')', s);
166 0 : } else {
167 0 : T value;
168 :
169 0 : obj.get(name, value);
170 :
171 0 : print_sep(sep, s);
172 0 : print_val<T>(value, s);
173 0 : print_sep(sep, s);
174 0 : }
175 0 : } catch (ers::Issue& ex) {
176 0 : s << "[bad_object] (could not get value of \'" << name << "\' of object \'" << &obj << "\': " << ex << ')';
177 : }
178 0 : }
179 :
180 : // workaround to avoid annoying warning about comparing this with nullptr
181 : inline bool
182 0 : is_null_obj(const ConfigObject* o)
183 : {
184 0 : return (o == nullptr || o->is_null());
185 : }
186 :
187 : void
188 0 : ConfigObject::print_ref(std::ostream& s,
189 : Configuration& conffwk,
190 : const std::string& prefix,
191 : bool show_contained_in) const noexcept
192 : {
193 0 : static bool expand_aggregation = (getenv(
194 0 : "TDAQ_CONFFWK_PRINT_EXPAND_AGGREGATIONS")); // FIXME tdaq-09-05-00 => add new parameter to conffwk and add fuse
195 :
196 : // check if it is not a reference to 0
197 0 : if (is_null_obj(this)) {
198 0 : s << prefix << "(null)";
199 0 : return;
200 : }
201 :
202 : // print out object-id and class-name
203 0 : s << prefix << "Object:\n" << prefix << " id: \'" << UID() << "\', class name: \'" << class_name() << "\'\n";
204 :
205 0 : if (show_contained_in)
206 0 : s << prefix << " contained in: \'" << contained_in() << "\'\n";
207 :
208 0 : try {
209 0 : const dunedaq::conffwk::class_t& cd(conffwk.get_class_info(class_name()));
210 :
211 : // print attributes
212 0 : for (const auto& i : cd.p_attributes) {
213 0 : const std::string& aname(i.p_name); // attribute name
214 0 : const bool ismv(i.p_is_multi_value); // attribute is multi-value
215 :
216 0 : s << prefix << " " << aname << ": ";
217 :
218 0 : switch (i.p_type) {
219 0 : case dunedaq::conffwk::string_type:
220 0 : case dunedaq::conffwk::enum_type:
221 0 : case dunedaq::conffwk::date_type:
222 0 : case dunedaq::conffwk::time_type:
223 0 : case dunedaq::conffwk::class_type:
224 0 : print_value<std::string>(*this, aname, ismv, '\"', s);
225 : break;
226 0 : case dunedaq::conffwk::bool_type:
227 0 : print_value<bool>(*this, aname, ismv, 0, s);
228 : break;
229 0 : case dunedaq::conffwk::u8_type:
230 0 : print_value<uint8_t>(*this, aname, ismv, 0, s);
231 : break;
232 0 : case dunedaq::conffwk::s8_type:
233 0 : print_value<int8_t>(*this, aname, ismv, 0, s);
234 : break;
235 0 : case dunedaq::conffwk::u16_type:
236 0 : print_value<uint16_t>(*this, aname, ismv, 0, s);
237 : break;
238 0 : case dunedaq::conffwk::s16_type:
239 0 : print_value<int16_t>(*this, aname, ismv, 0, s);
240 : break;
241 0 : case dunedaq::conffwk::u32_type:
242 0 : print_value<uint32_t>(*this, aname, ismv, 0, s);
243 : break;
244 0 : case dunedaq::conffwk::s32_type:
245 0 : print_value<int32_t>(*this, aname, ismv, 0, s);
246 : break;
247 0 : case dunedaq::conffwk::u64_type:
248 0 : print_value<uint64_t>(*this, aname, ismv, 0, s);
249 : break;
250 0 : case dunedaq::conffwk::s64_type:
251 0 : print_value<int64_t>(*this, aname, ismv, 0, s);
252 : break;
253 0 : case dunedaq::conffwk::float_type:
254 0 : print_value<float>(*this, aname, ismv, 0, s);
255 : break;
256 0 : case dunedaq::conffwk::double_type:
257 0 : print_value<double>(*this, aname, ismv, 0, s);
258 : break;
259 0 : default:
260 0 : s << "*** bad type ***";
261 : }
262 :
263 0 : s << std::endl;
264 : }
265 :
266 : // print relationships
267 0 : for (const auto& i : cd.p_relationships) {
268 0 : s << prefix << " " << i.p_name << ':';
269 0 : if (expand_aggregation == false || i.p_is_aggregation == false) {
270 0 : s << ' ';
271 0 : print_value<ConfigObject>(*this,
272 : i.p_name,
273 0 : (i.p_cardinality == dunedaq::conffwk::zero_or_many) ||
274 : (i.p_cardinality == dunedaq::conffwk::one_or_many),
275 : '\"',
276 : s);
277 0 : s << std::endl;
278 : } else {
279 0 : s << std::endl;
280 0 : std::string prefix2(prefix + " ");
281 0 : ConfigObject& obj = const_cast<ConfigObject&>(*this);
282 0 : if ((i.p_cardinality == dunedaq::conffwk::zero_or_many) || (i.p_cardinality == dunedaq::conffwk::one_or_many)) {
283 0 : std::vector<ConfigObject> value;
284 0 : obj.get(i.p_name, value);
285 0 : if (value.empty())
286 0 : s << prefix2 << "(null)\n";
287 : else
288 0 : for (const auto& x : value)
289 0 : x.print_ref(s, conffwk, prefix2, show_contained_in);
290 0 : } else {
291 0 : ConfigObject value;
292 0 : obj.get(i.p_name, value);
293 0 : if (value.is_null())
294 0 : s << prefix2 << "(null)\n";
295 : else
296 0 : value.print_ref(s, conffwk, prefix2, show_contained_in);
297 0 : }
298 0 : }
299 : }
300 0 : } catch (dunedaq::conffwk::Exception& ex) {
301 0 : s << "cannot get schema description: caught dunedaq::conffwk::Exception exception" << std::endl;
302 0 : std::cerr << "ERROR: " << ex << std::endl;
303 0 : }
304 : }
305 :
306 : ConfigObject*
307 0 : ConfigObject::get_obj_pybind(const std::string& attrname)
308 : {
309 :
310 0 : ConfigObject* newobject = new ConfigObject;
311 :
312 0 : if (newobject) {
313 0 : this->get(attrname, *newobject);
314 :
315 0 : if (newobject->is_null()) {
316 0 : delete newobject;
317 0 : return nullptr;
318 : }
319 : }
320 :
321 : return newobject;
322 : }
323 :
324 : } // namespace conffwk
325 : } // namespace dunedaq
|