Line data Source code
1 : /*! 2 : * \file esys/repo/pinsfile.cpp 3 : * \brief 4 : * 5 : * \cond 6 : * __legal_b__ 7 : * 8 : * Copyright (c) 2026 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/pinsfile.h" 20 : 21 : #include <nlohmann/json.hpp> 22 : 23 : #include <boost/filesystem.hpp> 24 : 25 : #include <fstream> 26 : #include <iomanip> 27 : 28 : using json = nlohmann::json; 29 : 30 : namespace esys::repo 31 : { 32 : 33 59 : PinsFile::PinsFile() = default; 34 : 35 118 : PinsFile::~PinsFile() = default; 36 : 37 59 : void PinsFile::set_path(const std::string &path) 38 : { 39 59 : m_path = path; 40 59 : } 41 : 42 120 : const std::string &PinsFile::get_path() const 43 : { 44 120 : return m_path; 45 : } 46 : 47 1 : void PinsFile::set_pins(std::shared_ptr<RevisionPins> pins) 48 : { 49 1 : m_pins = pins; 50 1 : } 51 : 52 5 : std::shared_ptr<RevisionPins> PinsFile::get_pins() const 53 : { 54 5 : return m_pins; 55 : } 56 : 57 115 : std::shared_ptr<RevisionPins> PinsFile::get_or_new_pins() 58 : { 59 115 : if (m_pins == nullptr) m_pins = std::make_shared<RevisionPins>(); 60 115 : return m_pins; 61 : } 62 : 63 58 : Result PinsFile::open(const std::string &path) 64 : { 65 58 : if (!path.empty()) set_path(path); 66 : 67 58 : auto pins = get_or_new_pins(); 68 58 : pins->clear(); 69 : 70 58 : if (get_path().empty()) return ESYSREPO_RESULT(ResultCode::EMPTY_PATH); 71 58 : if (!boost::filesystem::exists(get_path())) return ESYSREPO_RESULT(ResultCode::OK); 72 : 73 1 : std::ifstream fin(get_path()); 74 1 : if (!fin.is_open()) return ESYSREPO_RESULT(ResultCode::ERROR_OPENING_FILE, get_path()); 75 : 76 1 : json obj; 77 1 : try 78 : { 79 1 : fin >> obj; 80 : } 81 0 : catch (json::parse_error &) 82 : { 83 0 : return ESYSREPO_RESULT(ResultCode::CMDPIN_PINS_FILE_PARSE_ERROR, get_path()); 84 0 : } 85 : 86 1 : if (!obj.contains("pins") || !obj["pins"].is_array()) return ESYSREPO_RESULT(ResultCode::OK); 87 : 88 4 : for (auto &item : obj["pins"]) 89 : { 90 1 : if (!item.is_object()) continue; 91 1 : auto pin = std::make_shared<RevisionPin>(); 92 1 : if (item.contains("selector")) 93 : { 94 1 : PinSelector selector = PinSelector::NOT_SET; 95 1 : if (!pin_selector_from_string(item["selector"].get<std::string>(), selector)) 96 0 : return ESYSREPO_RESULT(ResultCode::CMDPIN_PINS_FILE_PARSE_ERROR, get_path()); 97 1 : pin->set_selector(selector); 98 : } 99 2 : if (item.contains("value")) pin->set_value(item["value"].get<std::string>()); 100 2 : if (item.contains("rev")) pin->set_rev(item["rev"].get<std::string>()); 101 2 : if (item.contains("path")) pin->set_path(item["path"].get<std::string>()); 102 3 : pins->add(pin); 103 1 : } 104 : 105 1 : return ESYSREPO_RESULT(ResultCode::OK); 106 59 : } 107 : 108 1 : Result PinsFile::write(const std::string &path) 109 : { 110 1 : if (!path.empty()) set_path(path); 111 1 : if (get_path().empty()) return ESYSREPO_RESULT(ResultCode::EMPTY_PATH); 112 2 : if (get_pins() == nullptr) return ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR); 113 : 114 1 : json root; 115 1 : json arr = json::array(); 116 3 : for (auto &pin : get_pins()->get_pins()) 117 : { 118 1 : if (pin == nullptr) continue; 119 1 : json item; 120 2 : item["selector"] = to_string(pin->get_selector()); 121 2 : item["value"] = pin->get_value(); 122 2 : item["rev"] = pin->get_rev(); 123 2 : item["path"] = pin->get_path(); 124 1 : arr.push_back(item); 125 1 : } 126 1 : root["pins"] = arr; 127 : 128 1 : std::ofstream ofs; 129 1 : if (boost::filesystem::exists(get_path())) 130 0 : ofs.open(get_path().c_str(), std::ios_base::trunc); 131 : else 132 1 : ofs.open(get_path().c_str(), std::ios_base::out); 133 : 134 1 : if (!ofs.is_open()) return ESYSREPO_RESULT(ResultCode::ERROR_OPENING_FILE, get_path()); 135 : 136 1 : ofs << std::setw(4); 137 1 : ofs << root; 138 1 : ofs.close(); 139 1 : return ESYSREPO_RESULT(ResultCode::OK); 140 2 : } 141 : 142 : } // namespace esys::repo