154 lines
4.6 KiB
PHP

<?php
namespace germanairlinesva\file\logbook;
require_once "Recording.php";
class Logbook
{
private const file_name = "/logbook.bin";
private const recordings_directory = "/recordings/";
private const ident = "VGAL";
private const header_unpack = "a4ident/Cversion";
private const variable_string_size_unpack = "Clength";
private const flight_start_unpack = "a10date/a1flightType/a4flightNumber/a4aircraftType/a6aircraftRegistration";
private const flight_middle_unpack = "a5offBlockTime/a5outTime/a5inTime/a5onBlockTime/gtotalFlightTime/" .
"gtaxiOutFuel/ginFlightFuel/gtaxiInFuel/gtotalFuel/gtaxiOutDistance/ginFlightDistance/gtaxiInDistance/" .
"gtotalDistance/gmaxLandingRate/Ctouchdowns/gmaxLandingGees";
private const flight_end_unpack = "gpoints/Cflags";
private string $directory_name = "";
private array $flights = [];
public function __construct(string $directory)
{
$this->directory_name = $directory;
$this->read();
}
/**
* Generates a json representation
*
* @return array json representation
*/
public function to_json(): array
{
$retVal = [];
foreach ($this->flights as $flight) {
try {
$rec = new \germanairlinesva\file\recording\Recording($this->directory_name .
Logbook::recordings_directory . $flight["recordingFilename"] . ".rec");
$flight["recording"] = $rec->to_json();
} catch (\InvalidArgumentException) {
}
array_push($retVal, $flight);
}
return $retVal;
}
/**
* Generates a string json representation
*
* @return string json string representation
*/
public function to_json_string(): string
{
return json_encode($this->to_json());
}
/**
* Reads logbook
*/
private function read()
{
$file = fopen($this->directory_name . Logbook::file_name, "rb");
flock($file, LOCK_SH);
$version = $this->read_header($file);
if ($version == 1) {
while ($this->read_flight_1($file) != false);
}
flock($file, LOCK_UN);
fclose($file);
}
/**
* Reads one flight entry
*
* @param resource $file File handle
*
* @return true if not EOF
* @return false if EOF
*
* @throws InvalidArgumentException If file is not a resource
*/
private function read_flight_1($file): bool
{
if (false === is_resource($file)) {
throw new \InvalidArgumentException(sprintf('Argument must be a valid resource type. %s given.', gettype($file)));
}
$retVal = [];
$data = fread($file, 25);
if ($data) {
$retVal = array_merge($retVal, unpack(Logbook::flight_start_unpack, $data));
$size = unpack(Logbook::variable_string_size_unpack, fread($file, 1))["length"];
$retVal["departureAirport"] = fread($file, $size);
$size = unpack(Logbook::variable_string_size_unpack, fread($file, 1))["length"];
$retVal["departureGate"] = fread($file, $size);
$size = unpack(Logbook::variable_string_size_unpack, fread($file, 1))["length"];
$retVal["departureRunway"] = fread($file, $size);
$size = unpack(Logbook::variable_string_size_unpack, fread($file, 1))["length"];
$retVal["arrivalAirport"] = fread($file, $size);
$size = unpack(Logbook::variable_string_size_unpack, fread($file, 1))["length"];
$retVal["arrivalGate"] = fread($file, $size);
$size = unpack(Logbook::variable_string_size_unpack, fread($file, 1))["length"];
$retVal["arrivalRunway"] = fread($file, $size);
$retVal = array_merge($retVal, unpack(Logbook::flight_middle_unpack, fread($file, 65)));
$size = unpack(Logbook::variable_string_size_unpack, fread($file, 1))["length"];
$retVal["recordingFilename"] = fread($file, $size);
$retVal = array_merge($retVal, unpack(Logbook::flight_end_unpack, fread($file, 5)));
array_push($this->flights, $retVal);
return true;
}
return false;
}
/**
* Reads the file header
*
* @param resource $file File handle
*
* @return string File version
*
* @throws InvalidArgumentException If file is not a resource
* @throws UnexpectedValueException If ident mismatches
*/
private function read_header($file): string
{
if (false === is_resource($file)) {
throw new \InvalidArgumentException(sprintf('Argument must be a valid resource type. %s given.', gettype($file)));
}
$header = unpack(Logbook::header_unpack, fread($file, 5));
if ($header["ident"] !== Logbook::ident) {
throw
new \UnexpectedValueException(sprintf("Ident mismatch. Got %s, expected %s", $header["ident"], Logbook::ident));
}
return $header["version"];
}
}