/* ************************************************************************** * Copyright (C) 2023 INAF * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License * or (at your option) any later version. This program is distributed * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * * Authors: * * <>Valerio Pastore INAF-OAS Bologna valerio.pastore@inaf.it **************************************************************************** */ #include <Packet_Structure_Json.h> #include <ctime> using namespace inaf::oasbo::Packets; using Structure = std::vector<std::tuple<uint, std::string, uint>>; Structure PacketStructureJson::readStructureFromSource(std::string source) { Structure s_empty; std::ifstream file; file.open(source, std::ios::in); if (!file.is_open()) { // error handling time_t now = time(nullptr); std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[PacketStructure Json]\t" << "Could not open file: " << source << std::endl; std::cerr << "\t Returning empty structure" << std::endl; return s_empty; } uint count = 0; ordered_json data; try { file >> data; } catch (nlohmann::detail::parse_error &ex) { time_t now = time(nullptr); std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[PacketStructure Json]\t" << ex.what() << "\n\t\tReturning empty structure" << std::endl; return s_empty; } std::optional<Structure> s_tmp = convertToTupleVector(data, count); file.close(); if (s_tmp.has_value()) return s_tmp.value(); time_t now = time(nullptr); std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[PacketStructure Json]\t" << "Returning empty structure" << std::endl; return s_empty; } std::optional<Structure> PacketStructureJson::convertToTupleVector( const ordered_json &data, uint &count) { std::optional<Structure> out = Structure(); for (auto it = data.begin(); it != data.end(); ++it) { if (it.value().is_object()) { // array found if (it.value().find("size") == it.value().end() // error handling || it.value().find("fields") == it.value().end() || it.value().size() != 2) { time_t now = time(nullptr); std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[PacketStructure Json]\t" << "Error in file: " << it.value().dump() << std::endl; return std::nullopt; } for (uint i = 0; i < it.value()["size"]; i++) { // convert to tuple vector the json array std::optional<Structure> subArray = convertToTupleVector( it.value()["fields"], count).value(); if (!subArray.has_value()) return std::nullopt; std::for_each(subArray.value().begin(), subArray.value().end(), [i](std::tuple<uint, std::string, uint> &line) { std::get<1>(line).append("_#").append( std::to_string(i)); }); out.value().insert(out.value().end(), subArray.value().begin(), subArray.value().end()); } } else { // single field found if (!it.value().is_number_integer()) { // error handling time_t now = time(nullptr); std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[PacketStructure Json]\t" << "Not an int: " << it.value().dump() << std::endl; return std::nullopt; } std::string fieldName(it.key()); std::transform(fieldName.begin(), fieldName.end(), fieldName.begin(), ::tolower); out.value().push_back( std::make_tuple(count, fieldName, it.value())); count += 1; } } return out; }