LCOV - code coverage report
Current view: top level - src/esys/repo/manifest - directoryfilexmlimpl_manifest.cpp (source / functions) Hit Total Coverage
Test: esysrepo_coverage.info Lines: 113 120 94.2 %
Date: 2026-08-01 10:43:40 Functions: 11 11 100.0 %

          Line data    Source code
       1             : /*!
       2             :  * \file esys/repo/manifest/directoryfilexmlimpl_manifest.cpp
       3             :  * \brief
       4             :  *
       5             :  * \cond
       6             :  * __legal_b__
       7             :  *
       8             :  * Copyright (c) 2023 Michel Gillet
       9             :  * Distributed under the MIT License.
      10             :  * (See accompanying file LICENSE.txt or
      11             :  * copy at https://opensource.org/licenses/MIT)
      12             :  *
      13             :  * __legal_e__
      14             :  * \endcond
      15             :  *
      16             :  */
      17             : 
      18             : #include "esys/repo/esysrepo_prec.h"
      19             : #include "esys/repo/manifest/directoryfilexmlimpl.h"
      20             : 
      21             : #include <esysfile/xml/writer.h>
      22             : #include <esysfile/xml/file.h>
      23             : #include <esysfile/xml/attr.h>
      24             : 
      25             : namespace esys::repo::manifest
      26             : {
      27             : 
      28           4 : DirectoryFileXMLImpl::DirectoryFileXMLImpl(DirectoryFileXML *self)
      29           4 :     : m_self(self)
      30             : {
      31           4 : }
      32             : 
      33           4 : DirectoryFileXMLImpl::~DirectoryFileXMLImpl() = default;
      34             : 
      35           3 : Result DirectoryFileXMLImpl::read(const std::string &path)
      36             : {
      37           3 :     esysfile::xml::File xml_file;
      38             : 
      39           3 :     xml_file.set_root_node_name("esysrepo_manifest_dir");
      40           3 :     int result = xml_file.read(path);
      41           3 :     if (result < 0)
      42             :     {
      43             :         // self()->add_error(result, "XML parsing failed.");
      44           0 :         return ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_ERROR_PARSING_FILE, path);
      45             :     }
      46             : 
      47           4 :     if (self()->get_directory() == nullptr)
      48           6 :         self()->set_directory(std::make_shared<Directory>());
      49             :     else
      50           2 :         self()->get_directory()->clear();
      51             : 
      52           6 :     return read(xml_file.get_data());
      53           3 : }
      54             : 
      55           4 : Result DirectoryFileXMLImpl::read(std::shared_ptr<esysfile::xml::Data> data)
      56             : {
      57           4 :     Result result;
      58           4 :     auto directory = self()->get_directory();
      59           4 :     auto name = data->get_attr("name");
      60             : 
      61           4 :     if (name != nullptr) directory->set_name(name->get_value());
      62             : 
      63           8 :     for (auto el : data->get_elements())
      64             :     {
      65           4 :         if (el->get_name() == "projects")
      66          12 :             result = read_projects(el);
      67             :         else
      68           0 :             result = ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_ELEMENT_UNKNOWN, el->get_name());
      69           4 :         if (result.error())
      70             :         {
      71           0 :             return result;
      72             :         }
      73           4 :     }
      74           4 :     return ESYSREPO_RESULT(ResultCode::OK);
      75           8 : }
      76             : 
      77           4 : Result DirectoryFileXMLImpl::read_projects(std::shared_ptr<esysfile::xml::Element> el)
      78             : {
      79           4 :     if (el->get_name() != "projects") return ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR);
      80             : 
      81           4 :     auto directory = self()->get_directory();
      82             : 
      83          26 :     for (auto project_el : el->get_elements())
      84             :     {
      85          22 :         if (project_el->get_name() != "project")
      86           0 :             return ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_ELEMENT_UNKNOWN, el->get_name());
      87             : 
      88          22 :         auto item = std::make_shared<Directory::Item>();
      89          22 :         auto name_attr = project_el->get_attr("name");
      90          22 :         item->set_name(name_attr->get_value());
      91             : 
      92          22 :         auto urls_el = project_el->get_element("urls");
      93             : 
      94          66 :         for (auto url_el : urls_el->get_elements())
      95             :         {
      96          44 :             auto type_attr = url_el->get_attr("type");
      97          44 :             if (type_attr == nullptr) return ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_MISSING_ATTR, "type");
      98             : 
      99          44 :             auto link_attr = url_el->get_attr("link");
     100          44 :             if (link_attr == nullptr) return ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_MISSING_ATTR, "link");
     101             : 
     102          44 :             if (type_attr->get_value() == "ssh")
     103          22 :                 item->set_url_ssh(link_attr->get_value());
     104          22 :             else if (type_attr->get_value() == "https")
     105          22 :                 item->set_url_https(link_attr->get_value());
     106             :             else
     107             :             {
     108           0 :                 return ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_UNKNOWN_URL_TYPE, type_attr->get_value());
     109             :             }
     110         132 :         }
     111             : 
     112          66 :         directory->add_item(item);
     113          88 :     }
     114             : 
     115           4 :     return ESYSREPO_RESULT(ResultCode::OK);
     116           4 : }
     117             : 
     118           1 : Result DirectoryFileXMLImpl::read(std::istream &is)
     119             : {
     120           1 :     esysfile::xml::File xml_file;
     121             : 
     122           1 :     xml_file.set_root_node_name("esysrepo_manifest_dir");
     123           1 :     int result = xml_file.read(is);
     124           1 :     if (result < 0)
     125             :     {
     126           0 :         return ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_ERROR_PARSING_STREAM);
     127             :     }
     128             : 
     129           2 :     if (self()->get_directory() == nullptr)
     130           0 :         self()->set_directory(std::make_shared<Directory>());
     131             :     else
     132           2 :         self()->get_directory()->clear();
     133             : 
     134           2 :     return read(xml_file.get_data());
     135           1 : }
     136             : 
     137           1 : Result DirectoryFileXMLImpl::write(const std::string &path)
     138             : {
     139           1 :     Result result = write_xml();
     140           1 :     if (result.error()) return ESYSREPO_RESULT(result);
     141             : 
     142           1 :     esysfile::xml::Writer writer;
     143             : 
     144           1 :     writer.set_indent(4);
     145           2 :     int result_int = writer.write(path, m_xml_data);
     146           1 :     if (result_int < 0) return ESYSREPO_RESULT(ResultCode::RAW_INT_ERROR, result_int);
     147           1 :     return ESYSREPO_RESULT(ResultCode::OK);
     148           1 : }
     149             : 
     150           1 : Result DirectoryFileXMLImpl::write(std::ostream &os)
     151             : {
     152           1 :     Result result = write_xml();
     153           1 :     if (result.error()) return ESYSREPO_RESULT(result);
     154             : 
     155           1 :     esysfile::xml::Writer writer;
     156             : 
     157           1 :     writer.set_indent(4);
     158           2 :     int result_int = writer.write(os, m_xml_data);
     159           1 :     if (result_int < 0) return ESYSREPO_RESULT(ResultCode::RAW_INT_ERROR, result_int);
     160           1 :     return ESYSREPO_RESULT(ResultCode::OK);
     161           1 : }
     162             : 
     163          22 : DirectoryFileXML *DirectoryFileXMLImpl::self() const
     164             : {
     165          22 :     return m_self;
     166             : }
     167             : 
     168           2 : Result DirectoryFileXMLImpl::write(std::shared_ptr<esysfile::xml::Element> parent_el,
     169             :                                    std::shared_ptr<Directory> directory)
     170             : {
     171           2 :     auto projects_el = std::make_shared<esysfile::xml::Element>();
     172           4 :     parent_el->add_element(projects_el);
     173             : 
     174           2 :     projects_el->set_name("projects");
     175             : 
     176          12 :     for (auto const &item : directory->get_items())
     177             :     {
     178          10 :         auto project_el = std::make_shared<esysfile::xml::Element>();
     179          20 :         projects_el->add_element(project_el);
     180             : 
     181          10 :         project_el->set_name("project");
     182          10 :         project_el->add_attr("name", item->get_name());
     183             : 
     184          10 :         auto urls_el = std::make_shared<esysfile::xml::Element>();
     185          20 :         project_el->add_element(urls_el);
     186             : 
     187          10 :         urls_el->set_name("urls");
     188             : 
     189          10 :         auto url_ssh_el = std::make_shared<esysfile::xml::Element>();
     190          20 :         urls_el->add_element(url_ssh_el);
     191             : 
     192          10 :         url_ssh_el->set_name("url");
     193          10 :         url_ssh_el->add_attr("type", "ssh");
     194          10 :         url_ssh_el->add_attr("link", item->get_url_ssh());
     195             : 
     196          10 :         if (!item->get_url_https().empty())
     197             :         {
     198          10 :             auto url_https_el = std::make_shared<esysfile::xml::Element>();
     199          20 :             urls_el->add_element(url_https_el);
     200             : 
     201          10 :             url_https_el->set_name("url");
     202          10 :             url_https_el->add_attr("type", "https");
     203          20 :             url_https_el->add_attr("link", item->get_url_https());
     204          10 :         }
     205          30 :     }
     206             : 
     207           2 :     return ESYSREPO_RESULT(ResultCode::OK);
     208           2 : }
     209             : 
     210           2 : Result DirectoryFileXMLImpl::write_xml()
     211             : {
     212           4 :     if (self()->get_directory() == nullptr) return ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_DATA_NULLPTR);
     213             : 
     214           2 :     m_xml_data = std::make_shared<esysfile::xml::Data>();
     215           2 :     m_xml_data->set_root_node_name("esysrepo_manifest_dir");
     216           2 :     m_xml_data->set_root_attr_name(self()->get_directory()->get_name());
     217             : 
     218           6 :     auto result = write(m_xml_data, self()->get_directory());
     219             : 
     220           4 :     return ESYSREPO_RESULT(result);
     221           2 : }
     222             : 
     223             : } // namespace esys::repo::manifest

Generated by: LCOV version 1.14