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

Generated by: LCOV version 2.0-1