190 lines
6.3 KiB
C++

#ifndef GERMANAIRLINESVA_GACONNECTOR_SIMULATORDATABASE_H
#define GERMANAIRLINESVA_GACONNECTOR_SIMULATORDATABASE_H
#include <cstdint>
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "gate.h"
#include "runway.h"
/*
* Header
*
* CHAR[5] | UINT8
* --------+--------
* VGAS | VERSION
*/
/*
* Airport
*
* UINT8 | CHAR[] | UINT16 | GATE[] | UINT8 | RUNWAY[]
* --------+--------+----------+--------+---------+---------
* STRLEN | ICAO | NUMGATES | GATES | NUMRWYS | RUNWAYS
*/
namespace germanairlinesva_simdata
{
static inline void
toFile(std::map<std::string,
std::pair<std::vector<germanairlinesva_simdata::Gate>,
std::vector<germanairlinesva_simdata::Runway>>>
&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<const char *>(header), 6);
// Num Airports
std::uint16_t numAirports = airports.size();
out.write(reinterpret_cast<const char *>(&numAirports),
sizeof(numAirports));
// Airport
for (const std::pair<
const std::string,
std::pair<std::vector<germanairlinesva_simdata::Gate>,
std::vector<germanairlinesva_simdata::Runway>>>
&airport : airports) {
std::string icao = airport.first;
std::vector<germanairlinesva_simdata::Gate> gates = airport.second.first;
std::vector<germanairlinesva_simdata::Runway> runways =
airport.second.second;
// ICAO
std::uint8_t icaoLength = icao.length();
out.write(reinterpret_cast<const char *>(&icaoLength),
sizeof(icaoLength));
out.write(icao.c_str(), icaoLength);
out.write(reinterpret_cast<const char *>(&null), sizeof(null));
// Gates
std::uint16_t numGates = gates.size();
out.write(reinterpret_cast<const char *>(&numGates), sizeof(numGates));
for (germanairlinesva_simdata::Gate &gate : gates) {
out.write(reinterpret_cast<const char *>(gate.getBinaryData()),
(std::streamsize)gate.getBinaryLength());
}
// Runways
std::uint8_t numRunways = runways.size();
out.write(reinterpret_cast<const char *>(&numRunways),
sizeof(numRunways));
for (germanairlinesva_simdata::Runway &runway : runways) {
out.write(reinterpret_cast<const char *>(runway.getBinaryData()),
(std::streamsize)runway.getBinaryLength());
}
}
out.close();
}
static inline std::map<
std::string,
std::pair<std::vector<germanairlinesva_simdata::Gate>,
std::vector<germanairlinesva_simdata::Runway>>>
readVersion1(std::ifstream &in)
{
std::map<std::string,
std::pair<std::vector<germanairlinesva_simdata::Gate>,
std::vector<germanairlinesva_simdata::Runway>>>
airports;
std::uint16_t numAirports;
in.read(reinterpret_cast<char *>(&numAirports), sizeof(numAirports));
for (int i = 0; i < numAirports; i++) {
// ICAO
std::uint8_t icaoLength;
in.read(reinterpret_cast<char *>(&icaoLength), sizeof(icaoLength));
char *icao = static_cast<char *>(calloc(icaoLength + 1, sizeof(char)));
in.read(icao, icaoLength + 1);
// Gates
std::uint16_t numGates;
in.read(reinterpret_cast<char *>(&numGates), sizeof(numGates));
for (int j = 0; j < numGates; j++) {
// ICAO
std::uint8_t designatorLength;
in.read(reinterpret_cast<char *>(&designatorLength),
sizeof(designatorLength));
char *designator =
static_cast<char *>(calloc(designatorLength + 1, sizeof(char)));
in.read(designator, designatorLength + 1);
// Center
struct germanairlinesva_geodata::point center;
in.read(reinterpret_cast<char *>(&center), sizeof(center));
// Radius
std::uint8_t radius;
in.read(reinterpret_cast<char *>(&radius), sizeof(radius));
airports[icao].first.emplace_back(designator, center, radius);
}
// Runways
std::uint8_t numRunways;
in.read(reinterpret_cast<char *>(&numRunways), sizeof(numRunways));
for (int j = 0; j < numRunways; j++) {
// ICAO
std::uint8_t designatorLength;
in.read(reinterpret_cast<char *>(&designatorLength),
sizeof(designatorLength));
char *designator =
static_cast<char *>(calloc(designatorLength + 1, sizeof(char)));
in.read(designator, designatorLength + 1);
// Bounds
struct germanairlinesva_geodata::box bounds;
in.read(reinterpret_cast<char *>(&bounds), sizeof(bounds));
// Width
std::uint8_t width;
in.read(reinterpret_cast<char *>(&width), sizeof(width));
// Length
std::uint16_t length;
in.read(reinterpret_cast<char *>(&length), sizeof(length));
// True Heading
std::uint16_t trueHeading;
in.read(reinterpret_cast<char *>(&trueHeading), sizeof(trueHeading));
airports[icao].second.emplace_back(designator,
bounds,
width,
length,
trueHeading);
}
}
in.close();
return airports;
}
static inline std::map<
std::string,
std::pair<std::vector<germanairlinesva_simdata::Gate>,
std::vector<germanairlinesva_simdata::Runway>>>
fromFile(const std::string &file)
{
std::map<std::string,
std::pair<std::vector<germanairlinesva_simdata::Gate>,
std::vector<germanairlinesva_simdata::Runway>>>
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<char *>(&version), 1);
if (version == 1) {
return readVersion1(in);
}
return airports;
}
} // namespace germanairlinesva_simdata
#endif