Skip to content
Snippets Groups Projects
Packet_Structure_Json.cpp 3.01 KiB
Newer Older
astri's avatar
astri committed
#include <Packet_Structure_Json.h>
Valerio Pastore's avatar
Valerio Pastore committed
#include <ctime>
Valerio Pastore's avatar
Valerio Pastore committed

using namespace inaf::oasbo::Packets;
using Structure = std::vector<std::tuple<uint, std::string, uint>>;
Valerio Pastore's avatar
Valerio Pastore committed

Structure PacketStructureJson::readStructureFromSource(std::string source) {
	Structure s_empty;
Valerio Pastore's avatar
Valerio Pastore committed
	std::ifstream file;
	file.open(source, std::ios::in);
Valerio Pastore's avatar
Valerio Pastore committed
	if (!file.is_open()) { // error handling
Valerio Pastore's avatar
Valerio Pastore committed
	    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;
Valerio Pastore's avatar
Valerio Pastore committed
	}
Valerio Pastore's avatar
Valerio Pastore committed
	uint count = 0;
astri's avatar
astri committed
	my_json data;
	try {
		file >> data;
	} catch (nlohmann::detail::parse_error &ex) {
Valerio Pastore's avatar
Valerio Pastore committed
	    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);
Valerio Pastore's avatar
Valerio Pastore committed
	file.close();
	if (s_tmp.has_value())
		return s_tmp.value();
Valerio Pastore's avatar
Valerio Pastore committed
    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(
astri's avatar
astri committed
		const my_json &data, uint &count) {
	std::optional<Structure> out = Structure();
astri's avatar
astri committed
	for (auto it = data.begin(); it != data.end(); ++it) {
Valerio Pastore's avatar
Valerio Pastore committed
		if (it.value().is_object()) { // array found
			if (it.value().find("size") == it.value().end() // error handling
					|| it.value().find("fields") == it.value().end()
astri's avatar
astri committed
					|| it.value().size() != 2) {
Valerio Pastore's avatar
Valerio Pastore committed
			    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;
Valerio Pastore's avatar
Valerio Pastore committed
			}
Valerio Pastore's avatar
Valerio Pastore committed
			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(),
Valerio Pastore's avatar
Valerio Pastore committed
						[i](std::tuple<uint, std::string, uint> &line) {
							std::get<1>(line).append("_#").append(
									std::to_string(i));
Valerio Pastore's avatar
Valerio Pastore committed
						});
				out.value().insert(out.value().end(), subArray.value().begin(),
						subArray.value().end());
Valerio Pastore's avatar
Valerio Pastore committed
			}
Valerio Pastore's avatar
Valerio Pastore committed
		} else { // single field found
			if (!it.value().is_number_integer()) { // error handling
Valerio Pastore's avatar
Valerio Pastore committed
			    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;
Valerio Pastore's avatar
Valerio Pastore committed
			}
astri's avatar
astri committed
			std::string fieldName(it.key());
Valerio Pastore's avatar
Valerio Pastore committed
			std::transform(fieldName.begin(), fieldName.end(),
					fieldName.begin(), ::tolower);
			out.value().push_back(
Valerio Pastore's avatar
Valerio Pastore committed
					std::make_tuple(count, fieldName, it.value())); 
Valerio Pastore's avatar
Valerio Pastore committed
			count += 1;
		}
	}
	return out;
}