DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
method.cpp
Go to the documentation of this file.
1// DUNE DAQ modification notice:
2// This file has been modified from the original ATLAS oks source for the DUNE DAQ project.
3// Fork baseline commit: oks-08-03-04 (2022-04-14).
4// Renamed since fork: no.
5
6#define _OksBuildDll_
7
8#include "oks/method.hpp"
9#include "oks/xml.hpp"
10#include "oks/class.hpp"
11#include "oks/cstring.hpp"
12
13#include <stdexcept>
14#include <sstream>
15
16namespace dunedaq {
17namespace oks {
18
19const char OksMethodImplementation::method_impl_xml_tag[] = "method-implementation";
20const char OksMethodImplementation::language_xml_attr[] = "language";
21const char OksMethodImplementation::prototype_xml_attr[] = "prototype";
22const char OksMethodImplementation::body_xml_attr[] = "body";
23
24const char OksMethod::method_xml_tag[] = "method";
25const char OksMethod::name_xml_attr[] = "name";
26const char OksMethod::description_xml_attr[] = "description";
27
28
29OksMethodImplementation::OksMethodImplementation(const std::string& language, const std::string& prototype, const std::string& body, OksMethod * p) :
30 p_language (language),
31 p_prototype (prototype),
32 p_body (body),
33 p_method (p)
34{
35 oks::validate_not_empty(p_language, "method implementation language");
36 oks::validate_not_empty(p_prototype, "method implementation prototype");
37}
38
39bool
41{
42 return (
43 ( this == &i ) ||
45 );
46}
47
48std::ostream&
49operator<<(std::ostream& s, const OksMethodImplementation& i)
50{
51 s << " Method implementation:\n"
52 " language: \"" << i.get_language() << "\"\n"
53 " prototype: \"" << i.get_prototype() << "\"\n"
54 " body: \"" << i.get_body() << "\"\n";
55
56 return s;
57}
58
59
60void
62{
63 s.put(" ");
64
65 s.put_start_tag(method_impl_xml_tag, sizeof(method_impl_xml_tag)-1);
66
67 s.put_attribute( language_xml_attr, sizeof(language_xml_attr)-1, get_language().c_str() );
68 s.put_attribute( prototype_xml_attr, sizeof(prototype_xml_attr)-1, get_prototype().c_str() );
69 s.put_attribute( body_xml_attr, sizeof(body_xml_attr)-1, get_body().c_str() );
70
71 s.put_end_tag();
72}
73
74
76 p_method (parent)
77{
78 try {
79 while(true) {
80 OksXmlAttribute attr(s);
81
82 // check for close of tag
83
84 if(oks::cmp_str1(attr.name(), "/")) { break; }
85
86 // check for known oks-method-implementation' attributes
87
88 else if( oks::cmp_str8(attr.name(), language_xml_attr) ) p_language.assign(attr.value(), attr.value_len());
89 else if( oks::cmp_str9(attr.name(), prototype_xml_attr) ) p_prototype.assign(attr.value(), attr.value_len());
90 else if( oks::cmp_str4(attr.name(), body_xml_attr) ) p_body.assign(attr.value(), attr.value_len());
91 else {
92 s.throw_unexpected_attribute(attr.name());
93 }
94 }
95 }
96 catch(oks::exception & e) {
97 throw oks::FailedRead("xml method implementation", e);
98 }
99 catch (std::exception & e) {
100 throw oks::FailedRead("xml method implementation", e.what());
101 }
102
103 try {
104 oks::validate_not_empty(p_language, "method implementation language");
105 oks::validate_not_empty(p_prototype, "method implementation prototype");
106 }
107 catch(std::exception& ex) {
108 throw oks::FailedRead("oks method implementation", oks::BadFileData(ex.what(), s.get_line_no(), s.get_line_pos()));
109 }
110}
111
112
113OksMethod::OksMethod(const std::string& nm, OksClass * p) :
114 p_class (p),
115 p_name (nm),
116 p_implementations (nullptr)
117{
118 try {
119 oks::validate_not_empty(p_name, "method name");
120 }
121 catch(std::exception& ex) {
122 Oks::error_msg("OksMethod::OksMethod()") << ex.what() << std::endl;
123 }
124}
125
126OksMethod::OksMethod(const std::string& nm, const std::string& desc, OksClass * p) :
127 p_class (p),
128 p_name (nm),
129 p_description (desc),
130 p_implementations (nullptr)
131{
132 oks::validate_not_empty(p_name, "method name");
133}
134
136{
138 while(!p_implementations->empty()) {
140 p_implementations->pop_front();
141 delete i;
142 }
143
144 delete p_implementations;
145 }
146}
147
148
149bool
150OksMethod::operator==(const class OksMethod &m) const
151{
152 // check if compare with self
153
154 if(this == &m) return true;
155
156
157 // check if attributes are different
158
159 if(p_name != m.p_name || p_description != m.p_description) return false;
160
161
162 // check if methods have no implementations
163
164 if(p_implementations == 0 && m.p_implementations == 0) return true;
165
166
167 // check if only one method has implementation
168
169 if(p_implementations == 0 || m.p_implementations == 0) return false;
170
171
172 // check if numbers of implementations are different
173
174 if(p_implementations->size() != m.p_implementations->size()) return false;
175
176
177 // check implementations
178
179 std::list<OksMethodImplementation *>::const_iterator i1 = p_implementations->begin();
180 std::list<OksMethodImplementation *>::const_iterator i2 = m.p_implementations->begin();
181
182 for(;i1 != p_implementations->end(); ++i1, ++i2) {
183 if( !(*(*i1) == *(*i2)) ) return false;
184 }
185
186 return true;
187}
188
189std::ostream&
190operator<<(std::ostream& s, const OksMethod& m)
191{
192 s << "Method name: \"" << m.p_name << "\"\n"
193 " description: \"" << m.p_description << "\"\n";
194
195 if(m.p_implementations) {
196 s << " implementations:\n";
197
198 for(std::list<OksMethodImplementation *>::const_iterator i = m.p_implementations->begin(); i != m.p_implementations->end(); ++i)
199 s << *(*i);
200 }
201 else
202 s << " there are no implementation(s)\n";
203
204 return s;
205}
206
207
208void
210{
211 s.put_raw(' ');
212 s.put_raw(' ');
213
214 s.put_start_tag(method_xml_tag, sizeof(method_xml_tag)-1);
215
216 s.put_attribute(name_xml_attr, sizeof(name_xml_attr)-1, p_name.c_str());
217 s.put_attribute(description_xml_attr, sizeof(description_xml_attr)-1, p_description.c_str());
218
219 s.put_raw('>');
220 s.put_raw('\n');
221
223 for(std::list<OksMethodImplementation *>::iterator i = p_implementations->begin(); i != p_implementations->end(); ++i)
224 (*i)->save(s);
225 }
226
227 s.put_raw(' ');
228 s.put_raw(' ');
229
230 s.put_last_tag(method_xml_tag, sizeof(method_xml_tag)-1);
231}
232
233
235 p_class (parent),
237{
238 try {
239 while(true) {
240 OksXmlAttribute attr(s);
241
242 // check for close of tag
243
244 if(oks::cmp_str1(attr.name(), ">")) { break; }
245
246 // check for known oks-relationship' attributes
247
248 else if(oks::cmp_str4(attr.name(), name_xml_attr)) p_name.assign(attr.value(), attr.value_len());
249 else if(oks::cmp_str11(attr.name(), description_xml_attr)) p_description.assign(attr.value(), attr.value_len());
250 else {
251 s.throw_unexpected_attribute(attr.name());
252 }
253 }
254 }
255 catch(oks::exception & e) {
256 throw oks::FailedRead("xml method", e);
257 }
258 catch (std::exception & e) {
259 throw oks::FailedRead("xml method", e.what());
260 }
261
262 // check validity of read values
263
264 try {
265 oks::validate_not_empty(p_name, "method name");
266 }
267 catch(std::exception& ex) {
268 throw oks::FailedRead("oks method", oks::BadFileData(ex.what(), s.get_line_no(), s.get_line_pos()));
269 }
270
271
272 // read 'body' and 'method-actions'
273
274 {
275 while(true) try {
276 const char * tag_start = s.get_tag_start();
277
278 if(oks::cmp_str7(tag_start, "/method")) { break; }
279
280 else if(!strcmp(tag_start, "method-implementation")) {
281 if(!p_implementations) p_implementations = new std::list<OksMethodImplementation *>();
282 p_implementations->push_back(new OksMethodImplementation(s, this));
283 }
284
285 else {
286 std::ostringstream text;
287 text << "Unexpected tag \'" << tag_start << "\' inside method \'" << p_name << "\'\n";
288 throw std::runtime_error( text.str().c_str() );
289 }
290
291 }
292 catch (oks::exception & e) {
293 throw oks::FailedRead("method tag", e);
294 }
295 catch (std::exception & e) {
296 throw oks::FailedRead("method tag", e.what());
297 }
298 }
299}
300
301
302void
303OksMethod::set_name(const std::string& new_name)
304{
305 // ignore when name is the same
306
307 if(p_name == new_name) return;
308
309
310 // additional checks are required,
311 // if the method already belongs to some class
312
313 if(p_class) {
314
315 // check allowed length for attribute name
316
317 try {
318 oks::validate_not_empty(new_name, "name");
319 }
320 catch(std::exception& ex) {
321 throw oks::SetOperationFailed("OksMethod::set_name", ex.what());
322 }
323
324
325 // having a direct method with the same name is an error
326
327 if(p_class->find_direct_method(new_name) != 0) {
328 std::ostringstream text;
329 text << "Class \"" << p_class->get_name() << "\" already has direct method \"" << new_name << '\"';
330 throw oks::SetOperationFailed("OksMethod::set_name", text.str());
331 }
332
333
334 // check that it is possible to lock the file
335
336 p_class->lock_file("OksMethod::set_name");
337
338
339 // probably a non-direct method already exists
340
341 OksMethod * m = p_class->find_method(new_name);
342
343
344 // change the name
345
346 p_name = new_name;
347
348
349 // registrate the change
350
351 p_class->registrate_class_change(OksClass::ChangeMethodsList, (const void *)m);
352 }
353 else {
354 p_name = new_name;
355 }
356}
357
359OksMethod::find_implementation(const std::string& language) const
360{
362 for(std::list<OksMethodImplementation *>::iterator i = p_implementations->begin(); i != p_implementations->end(); ++i)
363 if(language == (*i)->get_language()) return *i;
364 }
365
366 return 0;
367}
368
369void
370OksMethod::add_implementation(const std::string& language, const std::string& prototype, const std::string& body)
371{
372 if(find_implementation(language)) {
373 std::ostringstream text;
374 text << "Cannot add implementation on language \"" << language << "\" since it already exists.";
375 throw oks::SetOperationFailed("OksMethod::add_implementation", text.str());
376 }
377
378 if(p_class) p_class->lock_file("OksMethod::add_implementation");
379
380 if(!p_implementations) {
381 p_implementations = new std::list<OksMethodImplementation *>();
382 }
383
384 OksMethodImplementation * i = new OksMethodImplementation(language, prototype, body);
385
386 p_implementations->push_back(i);
387 i->p_method = this;
388
389 if(p_class) p_class->registrate_class_change(OksClass::ChangeMethodImplementation, (const void *)this);
390}
391
392void
393OksMethod::remove_implementation(const std::string& language)
394{
396
397 if(i == 0) {
398 std::ostringstream text;
399 text << "Cannot remove implementation on language \"" << language << "\" since it does not exist.";
400 throw oks::SetOperationFailed("OksMethod::remove_implementation", text.str());
401 }
402
403 if(p_class) p_class->lock_file("OksMethod::remove_implementation");
404
405 p_implementations->remove(i);
406
407 if(p_implementations->empty()) {
408 delete p_implementations;
410 }
411
412 if(p_class) p_class->registrate_class_change(OksClass::ChangeMethodImplementation, (const void *)this);
413}
414
415
416void
417OksMethod::set_description(const std::string& desc)
418{
419 if(p_description != desc) {
420 if(p_class) p_class->lock_file("OksMethod::set_description");
421
422 p_description = desc;
423
424 if(p_class) p_class->registrate_class_change(OksClass::ChangeMethodDescription, (const void *)this);
425 }
426}
427
428void
430{
431 if(p_language != s) {
432 if(p_method) {
433 if(p_method->find_implementation(s) != 0) {
434 std::ostringstream text;
435 text << "cannot rename \"" << p_method->p_name << "\" method implementation to language \"" << s << "\" "
436 "since the method already has implementation with such language.";
437 throw oks::SetOperationFailed("OksMethodImplementation::set_language", text.str());
438 }
439
440 try {
441 oks::validate_not_empty(s, "language");
442 }
443 catch(std::exception& ex) {
444 throw oks::SetOperationFailed("OksMethodImplementation::set_language", ex.what());
445 }
446
447 if(p_method->p_class) p_method->p_class->lock_file("OksMethodImplementation::set_language");
448 }
449
450 p_language = s;
451
452 if(p_method && p_method->p_class) {
453 p_method->p_class->registrate_class_change(OksClass::ChangeMethodImplementation, (const void *)this);
454 }
455 }
456}
457
458void
460{
461 if(p_prototype != s) {
462 try {
463 oks::validate_not_empty(s, "prototype");
464 }
465 catch(std::exception& ex) {
466 throw oks::SetOperationFailed("OksMethodImplementation::set_prototype", ex.what());
467 }
468
469 if(p_method && p_method->p_class) p_method->p_class->lock_file("OksMethodImplementation::set_prototype");
470
471 p_prototype = s;
472
473 if(p_method && p_method->p_class) {
474 p_method->p_class->registrate_class_change(OksClass::ChangeMethodImplementation, (const void *)this);
475 }
476 }
477}
478
479void
481{
482 if(p_body != s) {
483 if(p_method && p_method->p_class) p_method->p_class->lock_file("OksMethodImplementation::set_body");
484
485 p_body = s;
486
487 if(p_method && p_method->p_class) {
488 p_method->p_class->registrate_class_change(OksClass::ChangeMethodImplementation, (const void *)this);
489 }
490 }
491}
492
493} // namespace oks
494} // namespace dunedaq
OKS method implementation class.
Definition method.hpp:40
const std::string & get_body() const noexcept
Definition method.hpp:104
OksMethodImplementation(const std::string &language, const std::string &prototype, const std::string &body, OksMethod *p=nullptr)
OKS method implementation constructor.
Definition method.cpp:29
const std::string & get_language() const noexcept
Definition method.hpp:68
void set_prototype(const std::string &prototype)
Set method implementation prototype.
Definition method.cpp:459
const std::string & get_prototype() const noexcept
Definition method.hpp:87
void set_language(const std::string &language)
Set method implementation language.
Definition method.cpp:429
bool operator==(const class OksMethodImplementation &) const
Definition method.cpp:40
static const char prototype_xml_attr[]
Definition method.hpp:138
void save(OksXmlOutputStream &) const
Definition method.cpp:61
static const char language_xml_attr[]
Definition method.hpp:137
void set_body(const std::string &body)
Set method implementation body.
Definition method.cpp:480
static const char body_xml_attr[]
Definition method.hpp:139
static const char method_impl_xml_tag[]
Definition method.hpp:136
friend class OksClass
Definition method.hpp:160
void set_name(const std::string &name)
Set method name.
Definition method.cpp:303
static const char name_xml_attr[]
Definition method.hpp:297
static const char description_xml_attr[]
Definition method.hpp:298
static const char method_xml_tag[]
Definition method.hpp:296
void set_description(const std::string &description)
Set method description.
Definition method.cpp:417
void add_implementation(const std::string &language, const std::string &prototype, const std::string &body)
Add method implementation.
Definition method.cpp:370
void remove_implementation(const std::string &language)
Remove method implementation.
Definition method.cpp:393
bool operator==(const class OksMethod &) const
Definition method.cpp:150
friend class OksMethodImplementation
Definition method.hpp:161
OksMethodImplementation * find_implementation(const std::string &language) const
Find method implementation.
Definition method.cpp:359
std::list< OksMethodImplementation * > * p_implementations
Definition method.hpp:285
void save(OksXmlOutputStream &) const
Definition method.cpp:209
std::string p_description
Definition method.hpp:284
OksMethod(const std::string &name, OksClass *p=nullptr)
OKS method constructor.
Definition method.cpp:113
static std::ostream & error_msg(const char *)
Definition kernel.cpp:561
virtual const char * what() const noexcept
bool cmp_str8(const char *s1, const char s2[9])
Definition cstring.hpp:66
bool cmp_str1(const char *s1, const char s2[2])
Definition cstring.hpp:14
bool cmp_str4(const char *s1, const char s2[5])
Definition cstring.hpp:34
bool cmp_str9(const char *s1, const char s2[10])
Definition cstring.hpp:74
void validate_not_empty(const std::string &value, const char *name)
std::ostream & operator<<(std::ostream &s, const oks::exception &ex)
bool cmp_str11(const char *s1, const char s2[12])
Definition cstring.hpp:82
bool cmp_str7(const char *s1, const char s2[8])
Definition cstring.hpp:58
Including Qt Headers.
Definition module.cpp:16
Definition ral.hpp:35
size_t value_len() const
Definition xml.hpp:309