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

View File

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