#ifndef GERMANAIRLINESVA_FILE_SIMDATA_SIMDATABASE_H #define GERMANAIRLINESVA_FILE_SIMDATA_SIMDATABASE_H #include #include #include #include #include #include #include #include #include #include #include "config/config.hpp" #include "constants.h" #include "simdata/gate.hpp" #include "simdata/runway.hpp" #ifdef XP #include "simdata/simdataXP.hpp" #endif #ifndef MSFS #include "simdata/simdataESP.hpp" #endif /* * 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 { class SimDatabase { private: std::map, std::vector>> airports; inline void readVersion1(std::ifstream &in) { std::uint16_t numAirports = read(in); for (int i = 0; i < numAirports; i++) { // ICAO std::string icao = readString(in); // Gates std::uint16_t numGates = read(in); for (int j = 0; j < numGates; j++) { std::string designator = readString(in); struct geodata::point center = read(in); std::uint8_t radius = read(in); this->airports[icao].first.emplace_back(designator, center, radius); } // Runways std::uint8_t numRunways = read(in); for (int j = 0; j < numRunways; j++) { std::string designator = readString(in); // Center struct geodata::box bounds = read(in); std::uint8_t width = read(in); std::uint16_t length = read(in); double trueHeading = read(in); this->airports[icao].second.emplace_back(designator, bounds, width, length, trueHeading); } } in.close(); } inline void fromFile(const char *file) { std::string path(BASE_DIRECTORY); path.append(file); std::ifstream in(path, std::ifstream::binary); std::string ident = readString(in, 4); if (ident.compare(SIMDATABASE_HEADER) != 0) { throw std::invalid_argument("Wrong file"); } std::uint8_t version = read(in); if (version == 1) { this->readVersion1(in); } } public: inline SimDatabase(int simVersion, const char *hash, std::shared_ptr &configuration, std::function toLog) { if (strcmp(configuration->getScenery().c_str(), hash) != 0 || !util::fileExists(BASE_DIRECTORY SIMDATABASE)) { #ifdef XP scan(simVersion < 12000 ? XPLANE11_BASE_SCENERY : XPLANE12_BASE_SCENERY, XPLANE_CUSTOM_SCENERY, BASE_DIRECTORY "log.txt", airports); #endif #ifndef MSFS scan(BASE_DIRECTORY MAKERWYS_R5, BASE_DIRECTORY MAKERWYS_G5, BASE_DIRECTORY "db_log.txt", airports); #endif configuration->updateScenery(hash); #ifdef XP this->toFile(SIMDATABASE); #endif #ifndef MSFS switch (simVersion) { case FSX_VERSION: this->toFile(FSX_PREFIX SIMDATABASE); break; case FSXSE_VERSION: this->toFile(FSXSE_PREFIX SIMDATABASE); break; case P3D3_VERSION: this->toFile(P3D3_PREFIX SIMDATABASE); break; case P3D4_VERSION: this->toFile(P3D4_PREFIX SIMDATABASE); break; case P3D5_VERSION: this->toFile(P3D5_PREFIX SIMDATABASE); break; } #endif toLog("Sim Database updated"); } else { #ifdef XP this->fromFile(SIMDATABASE); #endif #ifndef MSFS switch (simVersion) { case FSX_VERSION: this->fromFile(FSX_PREFIX SIMDATABASE); break; case FSXSE_VERSION: this->fromFile(FSXSE_PREFIX SIMDATABASE); break; case P3D3_VERSION: this->fromFile(P3D3_PREFIX SIMDATABASE); break; case P3D4_VERSION: this->fromFile(P3D4_PREFIX SIMDATABASE); break; case P3D5_VERSION: this->fromFile(P3D5_PREFIX SIMDATABASE); break; } #endif toLog("Sim Database loaded"); } } inline void toFile(const char *file) const { std::string path(BASE_DIRECTORY); path.append(file); std::ofstream out(path, std::fstream::binary); // File Header out.write(SIMDATABASE_HEADER, 4); out.write("\1", 1); // Num Airports write(out, airports.size()); // Airport for (const std::pair< const std::string, std::pair, std::vector>> &airport : airports) { std::string icao = airport.first; const std::vector gates = airport.second.first; const std::vector runways = airport.second.second; // ICAO writeString(out, icao); // Gates write(out, gates.size()); for (const Gate &gate : gates) { gate.toFile(out); } // Runways write(out, runways.size()); for (const Runway &runway : runways) { runway.toFile(out); } } out.close(); } inline std::size_t getCount() const { return this->airports.size(); } inline const std::pair, const std::vector> operator[](std::string key) { auto it = this->airports.find(key); if (it != this->airports.end()) { return this->airports[key]; } else { return std::pair, std::vector>(); } } }; } // namespace simdata } // namespace file } // namespace germanairlinesva #endif