LCOV - code coverage report
Current view: top level - oks/src - relationship.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 19.1 % 188 36
Test Date: 2026-07-12 15:23:06 Functions: 18.8 % 16 3

            Line data    Source code
       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/relationship.hpp"
       9              : #include "oks/xml.hpp"
      10              : #include "oks/class.hpp"
      11              : #include "oks/kernel.hpp"
      12              : #include "oks/cstring.hpp"
      13              : 
      14              : #include <sstream>
      15              : 
      16              : namespace dunedaq {
      17              : namespace oks {
      18              : 
      19              : const char OksRelationship::relationship_xml_tag[]  = "relationship";
      20              : const char OksRelationship::name_xml_attr[]         = "name";
      21              : const char OksRelationship::description_xml_attr[]  = "description";
      22              : const char OksRelationship::class_type_xml_attr[]   = "class-type";
      23              : const char OksRelationship::low_cc_xml_attr[]       = "low-cc";
      24              : const char OksRelationship::high_cc_xml_attr[]      = "high-cc";
      25              : const char OksRelationship::is_composite_xml_attr[] = "is-composite";
      26              : const char OksRelationship::is_exclusive_xml_attr[] = "is-exclusive";
      27              : const char OksRelationship::is_dependent_xml_attr[] = "is-dependent";
      28              : const char OksRelationship::ordered_xml_attr[]      = "ordered";
      29              : 
      30              : 
      31              : OksRelationship::CardinalityConstraint
      32        10864 : OksRelationship::str2card(const char * s) noexcept
      33              : {
      34        10864 :   return (
      35        10864 :     oks::cmp_str3(s, "one")  ? One :
      36         5489 :     oks::cmp_str4(s, "zero") ? Zero :
      37              :     Many
      38        10864 :   );
      39              : }
      40              : 
      41              : const char *
      42            0 : OksRelationship::card2str(CardinalityConstraint cc) noexcept
      43              : {
      44            0 :   return (
      45            0 :     cc == Zero ? "zero" :
      46            0 :     cc == One  ? "one" :
      47              :     "many"
      48            0 :   );
      49              : }
      50              : 
      51            0 : OksRelationship::OksRelationship(const std::string& nm, OksClass * p) :
      52            0 :   p_name           (nm),
      53            0 :   p_low_cc         (Zero),
      54            0 :   p_high_cc        (Many),
      55            0 :   p_composite      (false),
      56            0 :   p_exclusive      (false),
      57            0 :   p_dependent      (false),
      58            0 :   p_class          (p),
      59            0 :   p_class_type     (nullptr),
      60            0 :   p_ordered        (false)
      61              : {
      62            0 :   oks::validate_not_empty(p_name, "relationship name");
      63            0 : }
      64              : 
      65            0 : OksRelationship::OksRelationship(const std::string& nm, const std::string& rc,
      66              :                                  CardinalityConstraint l_cc, CardinalityConstraint h_cc,
      67            0 :                                  bool cm, bool excl, bool dp, const std::string& desc, OksClass * p) :
      68            0 :   p_name           (nm),
      69            0 :   p_rclass         (rc),
      70            0 :   p_low_cc         (l_cc),
      71            0 :   p_high_cc        (h_cc),
      72            0 :   p_composite      (cm),
      73            0 :   p_exclusive      (excl),
      74            0 :   p_dependent      (dp),
      75            0 :   p_description    (desc),
      76            0 :   p_class          (p),
      77            0 :   p_class_type     (nullptr),
      78            0 :   p_ordered        (false)
      79              : {
      80            0 :   oks::validate_not_empty(p_name, "relationship name");
      81            0 :   oks::validate_not_empty(p_rclass, "relationship class");
      82            0 : }
      83              : 
      84              : bool
      85          315 : OksRelationship::operator==(const class OksRelationship &r) const
      86              : {
      87          315 :   return (
      88          315 :     ( this == &r ) ||
      89              :     (
      90            0 :       ( p_name == r.p_name ) &&
      91            0 :       ( p_rclass == r.p_rclass ) &&
      92            0 :       ( p_low_cc == r.p_low_cc ) &&
      93              :       ( p_high_cc == r.p_high_cc ) &&
      94              :       ( p_composite == r.p_composite ) &&
      95            0 :       ( p_exclusive == r.p_exclusive ) &&
      96            0 :       ( p_dependent == r.p_dependent ) &&
      97            0 :       ( p_description == r.p_description ) &&
      98            0 :       ( p_ordered == r.p_ordered )
      99              :    )
     100          315 :   );
     101              : }
     102              : 
     103              : std::ostream&
     104            0 : operator<<(std::ostream& s, const OksRelationship& r)
     105              : {
     106            0 :   s << "Relationship name: \"" << r.p_name << "\"\n"
     107            0 :        " class type: \"" << r.p_rclass << "\"\n"
     108            0 :        " low cardinality constraint is " << OksRelationship::card2str(r.p_low_cc) << "\n"
     109            0 :        " high cardinality constraint is " << OksRelationship::card2str(r.p_high_cc) << "\n"
     110            0 :        " is" << (r.p_composite == true ? "" : " not") << " composite reference\n"
     111            0 :        " is" << (r.p_exclusive == true ? "" : " not") << " exclusive reference\n"
     112            0 :        " is " << (r.p_dependent == true ? "dependent" : "shared") << " reference\n"
     113            0 :        " has description: \"" << r.p_description << "\"\n"
     114            0 :        " is " << (r.p_ordered == true ? "ordered" : "unordered") << std::endl;
     115              : 
     116            0 :   return s;
     117              : }
     118              : 
     119              : 
     120              : void
     121            0 : OksRelationship::save(OksXmlOutputStream& s) const
     122              : {
     123            0 :   s.put("  ");
     124              : 
     125            0 :   s.put_start_tag(relationship_xml_tag, sizeof(relationship_xml_tag) - 1);
     126              : 
     127            0 :   s.put_attribute(name_xml_attr, sizeof(name_xml_attr) - 1, p_name.c_str());
     128              : 
     129            0 :   if (!p_description.empty())
     130            0 :     s.put_attribute(description_xml_attr, sizeof(description_xml_attr) - 1, p_description.c_str());
     131              : 
     132            0 :   s.put_attribute(class_type_xml_attr, sizeof(class_type_xml_attr) - 1, p_rclass.c_str());
     133            0 :   s.put_attribute(low_cc_xml_attr, sizeof(low_cc_xml_attr) - 1, card2str(p_low_cc));
     134            0 :   s.put_attribute(high_cc_xml_attr, sizeof(high_cc_xml_attr) - 1, card2str(p_high_cc));
     135            0 :   s.put_attribute(is_composite_xml_attr, sizeof(is_composite_xml_attr) - 1, oks::xml::bool2str(p_composite));
     136            0 :   s.put_attribute(is_exclusive_xml_attr, sizeof(is_exclusive_xml_attr) - 1, oks::xml::bool2str(p_exclusive));
     137            0 :   s.put_attribute(is_dependent_xml_attr, sizeof(is_dependent_xml_attr) - 1, oks::xml::bool2str(p_dependent));
     138              : 
     139            0 :   if (p_ordered)
     140            0 :     s.put_attribute(ordered_xml_attr, sizeof(ordered_xml_attr) - 1, oks::xml::bool2str(p_ordered));
     141              : 
     142            0 :   s.put_end_tag();
     143            0 : }
     144              : 
     145              : 
     146         5432 : OksRelationship::OksRelationship(OksXmlInputStream& s, OksClass *parent) :
     147         5432 :   p_low_cc         (Zero),
     148         5432 :   p_high_cc        (Many),
     149         5432 :   p_composite      (false),
     150         5432 :   p_exclusive      (false),
     151         5432 :   p_dependent      (false),
     152         5432 :   p_class          (parent),
     153         5432 :   p_class_type     (nullptr),
     154         5432 :   p_ordered        (false)
     155              : {
     156        45970 :   try {
     157        86508 :     while(true) {
     158        45970 :       OksXmlAttribute attr(s);
     159              : 
     160              :         // check for close of tag
     161              :       
     162        45970 :       if(oks::cmp_str1(attr.name(), "/")) { break; }
     163              : 
     164              : 
     165              :         // check for known oks-relationship' attributes
     166              : 
     167        40538 :       else if(oks::cmp_str4(attr.name(), name_xml_attr)) p_name.assign(attr.value(), attr.value_len());
     168        35106 :       else if(oks::cmp_str11(attr.name(), description_xml_attr)) p_description.assign(attr.value(), attr.value_len());
     169        32601 :       else if(oks::cmp_str10(attr.name(), class_type_xml_attr)) p_rclass.assign(attr.value(), attr.value_len());
     170        27169 :       else if(oks::cmp_str6(attr.name(), low_cc_xml_attr)) p_low_cc = str2card(attr.value());
     171        21737 :       else if(oks::cmp_str7(attr.name(), high_cc_xml_attr)) p_high_cc = str2card(attr.value());
     172        16305 :       else if(oks::cmp_str12(attr.name(), is_composite_xml_attr)) p_composite = oks::xml::str2bool(attr.value());
     173        10873 :       else if(oks::cmp_str12(attr.name(), is_exclusive_xml_attr)) p_exclusive = oks::xml::str2bool(attr.value());
     174         5441 :       else if(oks::cmp_str12(attr.name(), is_dependent_xml_attr)) p_dependent = oks::xml::str2bool(attr.value());
     175            9 :       else if(oks::cmp_str7(attr.name(), ordered_xml_attr)) p_ordered = oks::xml::str2bool(attr.value());
     176            0 :       else if(!strcmp(attr.name(), "multi-value-implementation")) {
     177            0 :         s.error_msg("OksRelationship::OksRelationship(OksXmlInputStream&)")
     178            0 :              << "Obsolete oks-relationship\'s attribute \'" << attr.name() << "\'\n";
     179              :       }
     180              :       else {
     181            0 :         s.throw_unexpected_attribute(attr.name());
     182              :       }
     183        40538 :     }
     184              :   }
     185            0 :   catch(oks::exception & e) {
     186            0 :     throw oks::FailedRead("xml attribute", e);
     187            0 :   }
     188            0 :   catch (std::exception & e) {
     189            0 :     throw oks::FailedRead("xml attribute", e.what());
     190            0 :   }
     191              : 
     192              : 
     193              :     // check validity of read values
     194              : 
     195         5432 :   try {
     196         5432 :     oks::validate_not_empty(p_name, "relationship name");
     197         5432 :     oks::validate_not_empty(p_rclass, "relationship class");
     198              :   }
     199            0 :   catch(std::exception& ex) {
     200            0 :     throw oks::FailedRead("oks relationship", oks::BadFileData(ex.what(), s.get_line_no(), s.get_line_pos()));
     201            0 :   }
     202         5432 : }
     203              : 
     204              : 
     205              : void
     206            0 : OksRelationship::set_name(const std::string& new_name)
     207              : {
     208              :     // ignore when name is the same
     209              : 
     210            0 :   if(p_name == new_name) return;
     211              : 
     212              : 
     213              :     // additional checks are required,
     214              :     // if the relationship already belongs to some class
     215              : 
     216            0 :   if(p_class) {
     217              : 
     218              :       // check maximum allowed length for relationship name
     219              : 
     220            0 :     try {
     221            0 :       oks::validate_not_empty(new_name, "name");
     222              :     }
     223            0 :     catch(std::exception& ex) {
     224            0 :       throw oks::SetOperationFailed("OksRelationship::set_name", ex.what());
     225            0 :     }
     226              : 
     227              : 
     228              :       // having a direct relationship with the same name is an error
     229              : 
     230            0 :     if(p_class->find_direct_relationship(new_name) != 0) {
     231            0 :       std::ostringstream text;
     232            0 :       text << "Class \"" << p_class->get_name() << "\" already has direct relationship \"" << new_name << '\"';
     233            0 :       throw oks::SetOperationFailed("OksRelationship::set_name", text.str());
     234            0 :     }
     235              : 
     236              : 
     237              :       // check possibility to lock the file
     238              : 
     239            0 :     p_class->lock_file("OksRelationship::set_name");
     240              : 
     241              : 
     242              :       // probably a non-direct relationship already exists
     243              : 
     244            0 :     OksRelationship * r = p_class->find_relationship(new_name);
     245              : 
     246              : 
     247              :       // change the name
     248              : 
     249            0 :     p_name = new_name;
     250              : 
     251              : 
     252              :       // registrate the change
     253              : 
     254            0 :     p_class->registrate_class_change(OksClass::ChangeRelationshipsList, (const void *)r);
     255              :   }
     256              :   else {
     257            0 :     p_name = new_name;
     258              :   }
     259              : }
     260              : 
     261              : void
     262            0 : OksRelationship::set_type(const std::string& cn)
     263              : {
     264            0 :   if(p_rclass == cn) return;
     265              : 
     266            0 :   if(!p_class || !p_class->p_kernel || (p_class_type = p_class->p_kernel->find_class(cn)) != 0) {
     267            0 :     if(p_class) p_class->lock_file("OksRelationship::set_type");
     268              : 
     269            0 :     p_rclass = cn;
     270              : 
     271            0 :     if(p_class) {
     272            0 :       p_class->registrate_class_change(OksClass::ChangeRelationshipClassType, (const void *)this);
     273            0 :       p_class->registrate_relationship_change(this);
     274              :     }
     275              :   }
     276              :   else {
     277            0 :     std::ostringstream text;
     278            0 :     text << "cannot find class \"" << cn << '\"';
     279            0 :     throw oks::SetOperationFailed("OksRelationship::set_type", text.str());
     280            0 :   }
     281              : }
     282              :         
     283              : void
     284            0 : OksRelationship::set_description(const std::string& desc)
     285              : {
     286            0 :   if(p_description != desc) {
     287            0 :     if(p_class) p_class->lock_file("OksRelationship::set_description");
     288              : 
     289            0 :     p_description = desc;
     290              : 
     291            0 :     if(p_class) p_class->registrate_class_change(OksClass::ChangeRelationshipDescription, (const void *)this);
     292              :   }
     293            0 : }
     294              :         
     295              : void
     296            0 : OksRelationship::set_low_cardinality_constraint(CardinalityConstraint l_cc)
     297              : {
     298            0 :   if(p_low_cc != l_cc) {
     299            0 :     if(p_class) p_class->lock_file("OksRelationship::set_low_cardinality_constraint");
     300              : 
     301            0 :     CardinalityConstraint old_cc = p_low_cc;
     302              : 
     303            0 :     p_low_cc = l_cc;
     304              : 
     305            0 :     if(p_class) {
     306            0 :       p_class->registrate_class_change(OksClass::ChangeRelationshipLowCC, (const void *)this);
     307              :                 
     308            0 :       if(p_low_cc == Many || old_cc == Many) p_class->registrate_relationship_change(this);
     309              :     }
     310              :   }
     311            0 : }
     312              :         
     313              : void
     314            0 : OksRelationship::set_high_cardinality_constraint(CardinalityConstraint h_cc)
     315              : {
     316            0 :   if(p_high_cc != h_cc) {
     317            0 :     if(p_class) p_class->lock_file("OksRelationship::set_high_cardinality_constraint");
     318              : 
     319            0 :     CardinalityConstraint old_cc = p_high_cc;
     320              : 
     321            0 :     p_high_cc = h_cc;
     322              :         
     323            0 :     if(p_class) {
     324            0 :       p_class->registrate_class_change(OksClass::ChangeRelationshipHighCC, (const void *)this);
     325              : 
     326            0 :       if(p_high_cc == Many || old_cc == Many) p_class->registrate_relationship_change(this);
     327              :     }
     328              :   }
     329            0 : }
     330              :         
     331              : void
     332            0 : OksRelationship::set_is_composite(bool cm)
     333              : {
     334            0 :   if(p_composite != cm) {
     335            0 :     if(p_class) p_class->lock_file("OksRelationship::set_is_composite");
     336              : 
     337            0 :     p_composite = cm;
     338              : 
     339            0 :     if(p_class) p_class->registrate_class_change(OksClass::ChangeRelationshipComposite, (const void *)this);
     340              :   }
     341            0 : }
     342              :         
     343              : void
     344            0 : OksRelationship::set_is_exclusive(bool ex)
     345              : {
     346            0 :   if(p_exclusive != ex) {
     347            0 :     if(p_class) p_class->lock_file("OksRelationship::set_is_exclusive");
     348              : 
     349            0 :     p_exclusive = ex;
     350              : 
     351            0 :     if(p_class) p_class->registrate_class_change(OksClass::ChangeRelationshipExclusive, (const void *)this);
     352              :   }
     353            0 : }
     354              :         
     355              : void
     356            0 : OksRelationship::set_is_dependent(bool dp)
     357              : {
     358            0 :   if(p_dependent != dp) {
     359            0 :     if(p_class) p_class->lock_file("OksRelationship::set_is_dependent");
     360              : 
     361            0 :     p_dependent = dp;
     362              : 
     363            0 :     if(p_class) p_class->registrate_class_change(OksClass::ChangeRelationshipDependent, (const void *)this);
     364              :   }
     365            0 : }
     366              : 
     367              : } // namespace oks
     368              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1