GermanAirlinesVA-GAConnector/file/simulatorDatabase.hpp
2022-01-03 17:17:35 +01:00

192 lines
6.9 KiB
C++

#ifndef GERMANAIRLINESVA_GACONNECTOR_SIMULATORDATABASE_H
#define GERMANAIRLINESVA_GACONNECTOR_SIMULATORDATABASE_H
#include "gate.hpp"
#include "runway.hpp"
#include "stringExtensions.hpp"
#define CURRENT_VERSION 1
#include <cstdint>
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>
/*
* Header
*
* CHAR[5] | UINT8
* --------+--------
* VGAS | VERSION
*/
/*
* Airport
*
* UINT8 | CHAR[] | UINT16 | GATE[] | UINT8 | RUNWAY[]
* --------+--------+----------+--------+---------+---------
* STRLEN | ICAO | NUMGATES | GATES | NUMRWYS | RUNWAYS
*/
namespace simulatorDatabase
{
static inline void toFile(
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
&airports,
const std::string &file)
{
std::uint8_t null = 0;
std::ofstream out(file, std::fstream::binary);
// File Header
std::uint8_t header[] = {'V', 'G', 'A', 'S', 0, CURRENT_VERSION};
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<Gate>, std::vector<Runway>>>
&airport : airports) {
std::string icao = airport.first;
std::vector<Gate> gates = airport.second.first;
std::vector<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 (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 (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<Gate>, std::vector<Runway>>>
readVersion1(std::ifstream &in)
{
std::map<std::string, std::pair<std::vector<Gate>, std::vector<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);
// Latitude
double latitude;
in.read(reinterpret_cast<char *>(&latitude), sizeof(latitude));
// Latitude
double longitude;
in.read(reinterpret_cast<char *>(&longitude),
sizeof(longitude));
airports[icao].first.emplace_back(designator,
latitude,
longitude);
}
// 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);
// Latitude
double latitude;
in.read(reinterpret_cast<char *>(&latitude), sizeof(latitude));
// Latitude
double longitude;
in.read(reinterpret_cast<char *>(&longitude),
sizeof(longitude));
// 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,
latitude,
longitude,
width,
length,
trueHeading);
}
}
in.close();
return airports;
}
static inline std::map<std::string,
std::pair<std::vector<Gate>, std::vector<Runway>>>
fromFile(const std::string &file)
{
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
airports;
std::ifstream in(file);
// 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 simulatorDatabase
#endif