109 lines
3.1 KiB
C++
109 lines
3.1 KiB
C++
#include "airline_lookup.h"
|
|
#include "sd_storage.h"
|
|
#include "config.h"
|
|
#include <SD.h>
|
|
|
|
namespace AirlineLookup {
|
|
|
|
namespace {
|
|
constexpr uint8_t CACHE_SIZE = 16;
|
|
|
|
struct AirlineCacheEntry {
|
|
char icao[4] = {0};
|
|
char name[24] = {0};
|
|
bool used = false;
|
|
};
|
|
struct TypeCacheEntry {
|
|
char type[5] = {0};
|
|
uint16_t seats = 0;
|
|
bool used = false;
|
|
};
|
|
|
|
AirlineCacheEntry airlineCache[CACHE_SIZE];
|
|
TypeCacheEntry typeCache[CACHE_SIZE];
|
|
|
|
uint8_t hash3(const char* s) {
|
|
uint32_t h = 2166136261u;
|
|
for (int i = 0; i < 3 && s[i]; i++) h = (h ^ s[i]) * 16777619u;
|
|
return h % CACHE_SIZE;
|
|
}
|
|
|
|
bool lookupCsv(const char* path, const char* key, char* outValue, size_t outLen) {
|
|
if (!SdStorage::isMounted()) return false;
|
|
File f = SD.open(path);
|
|
if (!f) return false;
|
|
|
|
bool found = false;
|
|
f.readStringUntil('\n');
|
|
while (f.available()) {
|
|
String line = f.readStringUntil('\n');
|
|
int comma = line.indexOf(',');
|
|
if (comma < 0) continue;
|
|
String k = line.substring(0, comma);
|
|
k.trim();
|
|
if (k.equalsIgnoreCase(key)) {
|
|
String v = line.substring(comma + 1);
|
|
v.trim();
|
|
strncpy(outValue, v.c_str(), outLen - 1);
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
f.close();
|
|
return found;
|
|
}
|
|
void extractAirlinePrefix(const char* callsign, char* out /* size 4 */) {
|
|
int i = 0;
|
|
for (; i < 3 && callsign[i] && isalpha((unsigned char)callsign[i]); i++) {
|
|
out[i] = callsign[i];
|
|
}
|
|
out[i] = '\0';
|
|
}
|
|
}
|
|
|
|
void init() {
|
|
clearCache();
|
|
}
|
|
|
|
void clearCache() {
|
|
memset(airlineCache, 0, sizeof(airlineCache));
|
|
memset(typeCache, 0, sizeof(typeCache));
|
|
}
|
|
|
|
void resolve(Aircraft& a) {
|
|
char prefix[4];
|
|
extractAirlinePrefix(a.callsign, prefix);
|
|
if (prefix[0]) {
|
|
uint8_t slot = hash3(prefix);
|
|
AirlineCacheEntry& c = airlineCache[slot];
|
|
if (c.used && strncmp(c.icao, prefix, 3) == 0) {
|
|
strncpy(a.airlineName, c.name, sizeof(a.airlineName) - 1);
|
|
} else {
|
|
char name[24] = {0};
|
|
if (lookupCsv(Config::SD_AIRLINES_CSV, prefix, name, sizeof(name))) {
|
|
strncpy(a.airlineName, name, sizeof(a.airlineName) - 1);
|
|
strncpy(c.icao, prefix, 3);
|
|
strncpy(c.name, name, sizeof(c.name) - 1);
|
|
c.used = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (a.typeCode[0]) {
|
|
uint8_t slot = hash3(a.typeCode);
|
|
TypeCacheEntry& c = typeCache[slot];
|
|
if (c.used && strncmp(c.type, a.typeCode, 4) == 0) {
|
|
a.estSeats = c.seats;
|
|
} else {
|
|
char seatsStr[8] = {0};
|
|
if (lookupCsv(Config::SD_AIRCRAFT_TYPES_CSV, a.typeCode, seatsStr, sizeof(seatsStr))) {
|
|
a.estSeats = atoi(seatsStr);
|
|
strncpy(c.type, a.typeCode, 4);
|
|
c.seats = a.estSeats;
|
|
c.used = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
} |