differential code coverage report with master
Current view: top level - source/packaging - ext_list.cpp (source / functions) Coverage Total Hit UBC CBC
Current: coverage.info Lines: 63.9 % 83 53 30 53
Current Date: 2025-12-15 23:01:28 Functions: 35.7 % 14 5 9 5
Baseline: coverage_master.info Branches: 83.3 % 78 65 26 130
Baseline Date: 2025-12-15 23:01:27

             Branch data    TLA  Line data    Source code
       1                 :                : #include <xlnt/packaging/ext_list.hpp>
       2                 :                : #include <algorithm>
       3                 :                : 
       4                 :                : #include <detail/external/include_libstudxml.hpp>
       5                 :                : 
       6                 :                : namespace {
       7                 :                : // send elements straight from parser to serialiser without modification
       8                 :                : // runs until the end of the current open element
       9                 :CBC           6 : xlnt::uri roundtrip(xml::parser &p, xml::serializer &s)
      10                 :                : {
      11                 :              6 :     xlnt::uri ext_uri;
      12                 :              6 :     int nest_level = 0;
      13   [ +  +  +  +  :             30 :     while (nest_level > 0 || (p.peek() != xml::parser::event_type::end_element && p.peek() != xml::parser::event_type::eof))
          +  +  +  -  +  
                      + ]
      14                 :                :     {
      15   [ +  +  +  -  :             24 :         switch (p.next())
             -  -  -  - ]
      16                 :                :         {
      17                 :             12 :         case xml::parser::start_element: {
      18                 :             12 :             ++nest_level;
      19         [ +  + ]:             12 :             auto attribs = p.attribute_map();
      20            [ + ]:             12 :             s.start_element(p.qname());
      21         [ +  + ]:             12 :             if (nest_level == 1)
      22                 :                :             {
      23   [ +  +  +  + ]:             12 :                 ext_uri = xlnt::uri(attribs.at(xml::qname("uri")).value);
      24                 :                :             }
      25            [ + ]:             12 :             auto current_ns = p.namespace_();
      26            [ + ]:             12 :             p.peek(); // to look into the new namespace
      27            [ + ]:             12 :             auto new_ns = p.namespace_(); // only before attributes?
      28         [ +  + ]:             12 :             if (new_ns != current_ns)
      29                 :                :             {
      30            [ + ]:              6 :                 auto pref = p.prefix();
      31            [ + ]:              6 :                 s.namespace_decl(new_ns, pref);
      32                 :              6 :             }
      33         [ +  + ]:             36 :             for (auto &ele : attribs)
      34                 :                :             {
      35            [ + ]:             24 :                 s.attribute(ele.first, ele.second.value);
      36                 :                :             }
      37                 :             12 :             break;
      38                 :             12 :         }
      39                 :             12 :         case xml::parser::end_element: {
      40                 :             12 :             --nest_level;
      41            [ + ]:             12 :             s.end_element();
      42                 :             12 :             break;
      43                 :                :         }
      44                 :UBC           0 :         case xml::parser::start_namespace_decl: {
      45            [ # ]:              0 :             s.namespace_decl(p.namespace_(), p.prefix());
      46                 :              0 :             break;
      47                 :                :         }
      48                 :              0 :         case xml::parser::end_namespace_decl: { // nothing required here
      49                 :              0 :             break;
      50                 :                :         }
      51                 :              0 :         case xml::parser::characters: {
      52            [ # ]:              0 :             s.characters(p.value());
      53                 :              0 :             break;
      54                 :                :         }
      55                 :              0 :         case xml::parser::eof:
      56                 :              0 :             return ext_uri;
      57                 :              0 :         case xml::parser::start_attribute:
      58                 :                :         case xml::parser::end_attribute:
      59                 :                :         default:
      60                 :              0 :             break;
      61                 :                :         }
      62                 :                :     }
      63                 :CBC           6 :     return ext_uri;
      64                 :UBC           0 : }
      65                 :                : } // namespace
      66                 :                : 
      67                 :                : namespace xlnt {
      68                 :                : 
      69                 :CBC           4 : ext_list::ext::ext(xml::parser &parser, const std::string &ns)
      70                 :                : {
      71            [ + ]:              4 :     std::ostringstream serialisation_stream;
      72         [ +  + ]:              8 :     xml::serializer s(serialisation_stream, "", 0);
      73      [ +  +  + ]:              8 :     s.start_element(xml::qname(ns, "wrap")); // wrapper for the xmlns declaration
      74         [ +  + ]:              4 :     s.namespace_decl(ns, "");
      75            [ + ]:              4 :     extension_ID_ = roundtrip(parser, s);
      76      [ +  +  + ]:              4 :     s.end_element(xml::qname(ns, "wrap"));
      77            [ + ]:              4 :     serialised_value_ = serialisation_stream.str();
      78                 :              4 : }
      79                 :                : 
      80                 :UBC           0 : ext_list::ext::ext(const uri &ID, const std::string &serialised)
      81            [ # ]:              0 :     : extension_ID_(ID), serialised_value_(serialised)
      82                 :                : {
      83                 :              0 : }
      84                 :                : 
      85                 :CBC           2 : void ext_list::ext::serialise(xml::serializer &serialiser, const std::string &ns)
      86                 :                : {
      87            [ + ]:              2 :     std::istringstream ser(serialised_value_);
      88         [ +  + ]:              6 :     xml::parser p(ser, "", xml::parser::receive_default);
      89      [ +  +  + ]:              2 :     p.next_expect(xml::parser::event_type::start_element, xml::qname(ns, "wrap"));
      90            [ + ]:              2 :     roundtrip(p, serialiser);
      91      [ +  +  + ]:              2 :     p.next_expect(xml::parser::event_type::end_element, xml::qname(ns, "wrap"));
      92                 :              2 : }
      93                 :                : 
      94                 :              4 : ext_list::ext_list(xml::parser &parser, const std::string &ns)
      95                 :                : {
      96                 :                :     // begin with the start element already parsed
      97      [ +  +  + ]:              8 :     while (parser.peek() == xml::parser::start_element)
      98                 :                :     {
      99         [ +  + ]:              4 :         extensions_.push_back(ext(parser, ns));
     100                 :                :     }
     101                 :                :     // end without parsing the end element
     102                 :              4 : }
     103                 :                : 
     104                 :              2 : void ext_list::serialize(xml::serializer &serialiser, const std::string &ns)
     105                 :                : {
     106         [ +  + ]:              2 :     serialiser.start_element(ns, "extLst");
     107         [ +  + ]:              4 :     for (auto &ext : extensions_)
     108                 :                :     {
     109            [ + ]:              2 :         ext.serialise(serialiser, ns);
     110                 :                :     }
     111                 :              2 :     serialiser.end_element();
     112                 :              2 : }
     113                 :                : 
     114                 :UBC           0 : void ext_list::add_extension(const uri &ID, const std::string &element)
     115                 :                : {
     116         [ #  # ]:              0 :     extensions_.push_back(ext{ID, element});
     117                 :              0 : }
     118                 :                : 
     119                 :              0 : bool ext_list::has_extension(const uri &extension_uri) const
     120                 :                : {
     121            [ # ]:              0 :     return extensions_.end() != std::find_if(extensions_.begin(), extensions_.end(), [&extension_uri](const ext &ext) { return extension_uri == ext.extension_ID_; });
     122                 :                : }
     123                 :                : 
     124                 :              0 : const ext_list::ext &ext_list::extension(const uri &extension_uri) const
     125                 :                : {
     126            [ # ]:              0 :     return *std::find_if(extensions_.begin(), extensions_.end(),
     127                 :              0 :         [&extension_uri](const ext &ext) { return extension_uri == ext.extension_ID_; });
     128                 :                : }
     129                 :                : 
     130                 :              0 : const std::vector<ext_list::ext> &ext_list::extensions() const
     131                 :                : {
     132                 :              0 :     return extensions_;
     133                 :                : }
     134                 :                : 
     135                 :              0 : bool ext_list::operator==(const ext_list &rhs) const
     136                 :                : {
     137                 :              0 :     return extensions_ == rhs.extensions_;
     138                 :                : }
     139                 :                : 
     140                 :              0 : bool ext_list::operator!=(const ext_list &rhs) const
     141                 :                : {
     142                 :              0 :     return !(*this == rhs);
     143                 :                : }
     144                 :                : 
     145                 :                : } // namespace xlnt
        

Generated by: LCOV version 2.3.1-beta