#ifndef GERMANAIRLINESVA_FILE_SIMULATORDATABASE_H #define GERMANAIRLINESVA_FILE_SIMULATORDATABASE_H #include #include #include #include #include #include #include #include "simdata/gate.h" #include "simdata/runway.h" /* * Header * * CHAR[5] | UINT8 * --------+-------- * VGAS | VERSION */ /* * Airport * * UINT8 | CHAR[] | UINT16 | GATE[] | UINT8 | RUNWAY[] * --------+--------+----------+--------+---------+--------- * STRLEN | ICAO | NUMGATES | GATES | NUMRWYS | RUNWAYS */ namespace germanairlinesva { namespace file { namespace simdata { static inline void toFile( std::map< std::string, std::pair, std::vector>> &airports, const std::string &file) { std::uint8_t null = 0; std::ofstream out(file, std::fstream::binary); // File Header, Last member is version std::uint8_t header[] = {'V', 'G', 'A', 'S', '\0', 1}; out.write(reinterpret_cast(header), 6); // Num Airports std::uint16_t numAirports = airports.size(); out.write(reinterpret_cast(&numAirports), sizeof(numAirports)); // Airport for (const std::pair< const std::string, std::pair, std::vector>> &airport : airports) { std::string icao = airport.first; std::vector gates = airport.second.first; std::vector runways = airport.second.second; // ICAO std::uint8_t icaoLength = icao.length(); out.write(reinterpret_cast(&icaoLength), sizeof(icaoLength)); out.write(icao.c_str(), icaoLength); out.write(reinterpret_cast(&null), sizeof(null)); // Gates std::uint16_t numGates = gates.size(); out.write(reinterpret_cast(&numGates), sizeof(numGates)); for (germanairlinesva::file::simdata::Gate &gate : gates) { gate.toFile(out); } // Runways std::uint8_t numRunways = runways.size(); out.write(reinterpret_cast(&numRunways), sizeof(numRunways)); for (germanairlinesva::file::simdata::Runway &runway : runways) { runway.toFile(out); } } out.close(); } static inline std::map< std::string, std::pair, std::vector>> readVersion1(std::ifstream &in) { std::map, std::vector>> airports; std::uint16_t numAirports; in.read(reinterpret_cast(&numAirports), sizeof(numAirports)); for (int i = 0; i < numAirports; i++) { // ICAO std::uint8_t icaoLength; in.read(reinterpret_cast(&icaoLength), sizeof(icaoLength)); char *icao = static_cast(calloc(icaoLength + 1, sizeof(char))); in.read(icao, icaoLength + 1); // Gates std::uint16_t numGates; in.read(reinterpret_cast(&numGates), sizeof(numGates)); for (int j = 0; j < numGates; j++) { std::string designator = readString(in); struct germanairlinesva::geodata::point center = read(in); std::uint8_t radius = read(in); airports[icao].first.emplace_back(designator, center, radius); } // Runways std::uint8_t numRunways; in.read(reinterpret_cast(&numRunways), sizeof(numRunways)); for (int j = 0; j < numRunways; j++) { std::string designator = readString(in); // Bounds struct germanairlinesva::geodata::box bounds = read(in); std::uint8_t width = read(in); std::uint16_t length = read(in); std::uint16_t trueHeading = read(in); airports[icao].second.emplace_back(designator, bounds, width, length, trueHeading); } } in.close(); return airports; } static inline std::map< std::string, std::pair, std::vector>> fromFile(const std::string &file) { std::map, std::vector>> airports; std::ifstream in(file, std::ifstream::binary); // File Header char ident[5]; in.read(ident, 5); if (strcmp(ident, "VGAS") != 0) { throw std::invalid_argument("Wrong file"); } std::uint8_t version; in.read(reinterpret_cast(&version), 1); if (version == 1) { return readVersion1(in); } return airports; } } // namespace simdata } // namespace file } // namespace germanairlinesva #endif