SGmetar: catch bad temp/pressure data and throw

Also replace raw pointer with managed storage for the raw data, to
avoid manual clean-up on exception-throw paths.
This commit is contained in:
James Turner 2021-10-15 12:12:28 +01:00
parent 119f3d9814
commit 6fe7c307b2
2 changed files with 34 additions and 22 deletions

View File

@ -96,14 +96,14 @@ SGMetar::SGMetar(const string& m) :
_snow(false), _snow(false),
_cavok(false) _cavok(false)
{ {
_data = new char[m.length() + 2]; // make room for " \0" _data.resize(m.length() + 2); // make room for " \0"
strcpy(_data, m.c_str()); strcpy(_data.data(), m.c_str());
_url = _data; _url = m;
normalizeData();
_m = _data; normalizeData();
_icao[0] = '\0';
_m = _data.data();
_icao[0] = '\0';
// NOAA preample // NOAA preample
if (!scanPreambleDate()) if (!scanPreambleDate())
@ -113,7 +113,6 @@ SGMetar::SGMetar(const string& m) :
// METAR header // METAR header
scanType(); scanType();
if (!scanId() || !scanDate()) { if (!scanId() || !scanDate()) {
delete[] _data;
throw sg_io_exception("metar data bogus ", sg_location(_url)); throw sg_io_exception("metar data bogus ", sg_location(_url));
} }
scanModifier(); scanModifier();
@ -125,7 +124,15 @@ SGMetar::SGMetar(const string& m) :
while (scanRwyVisRange()) ; while (scanRwyVisRange()) ;
while (scanWeather()) ; while (scanWeather()) ;
while (scanSkyCondition()) ; while (scanSkyCondition()) ;
scanTemperature();
if (!scanTemperature()) {
throw sg_io_exception("metar temperature data malformed or missing ", sg_location(_url));
}
if (!scanPressure()) {
throw sg_io_exception("metar pressure data malformed or missing ", sg_location(_url));
}
scanTemperature();
scanPressure(); scanPressure();
while (scanSkyCondition()) ; while (scanSkyCondition()) ;
while (scanRunwayReport()) ; while (scanRunwayReport()) ;
@ -139,11 +146,10 @@ SGMetar::SGMetar(const string& m) :
scanRemark(); scanRemark();
if (_grpcount < 4) { if (_grpcount < 4) {
delete[] _data;
throw sg_io_exception("metar data incomplete ", sg_location(_url)); throw sg_io_exception("metar data incomplete ", sg_location(_url));
} }
_url = ""; _url.clear();
} }
@ -155,7 +161,6 @@ SGMetar::~SGMetar()
_clouds.clear(); _clouds.clear();
_runways.clear(); _runways.clear();
_weather.clear(); _weather.clear();
delete[] _data;
} }
@ -486,17 +491,24 @@ void SGMetar::useCurrentDate()
_month = now.tm_mon + 1; _month = now.tm_mon + 1;
} }
const char* SGMetar::getRawDataPtr()
{
return _data.data();
}
/** /**
* Replace any number of subsequent spaces by just one space, and add * Replace any number of subsequent spaces by just one space, and add
* a trailing space. This makes scanning for things like "ALL RWY" easier. * a trailing space. This makes scanning for things like "ALL RWY" easier.
*/ */
void SGMetar::normalizeData() void SGMetar::normalizeData()
{ {
char *src, *dest; // TODO : use strutils::simplify here
for (src = dest = _data; (*dest++ = *src++); ) char* src = _data.data();
while (*src == ' ' && src[1] == ' ') char* dest = src;
for (; (*dest++ = *src++);) {
while (*src == ' ' && src[1] == ' ')
src++; src++;
for (dest--; isspace(*--dest); ) ; }
for (dest--; isspace(*--dest); ) ;
*++dest = ' '; *++dest = ' ';
*++dest = '\0'; *++dest = '\0';
} }

View File

@ -186,9 +186,9 @@ public:
std::vector<std::string> phenomena; std::vector<std::string> phenomena;
}; };
inline const char *getData() const { return _data; } const char* getRawDataPtr();
inline const char *getUnusedData() const { return _m; }
inline bool getProxy() const { return _x_proxy; } inline bool getProxy() const { return _x_proxy; }
inline const char *getId() const { return _icao; } inline const char *getId() const { return _icao; }
inline int getYear() const { return _year; } inline int getYear() const { return _year; }
inline int getMonth() const { return _month; } inline int getMonth() const { return _month; }
@ -244,9 +244,9 @@ protected:
std::string _url; std::string _url;
int _grpcount; int _grpcount;
bool _x_proxy; bool _x_proxy;
char *_data; std::vector<char> _data;
char *_m; char* _m;
char _icao[5]; char _icao[5];
int _year; int _year;
int _month; int _month;
int _day; int _day;