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