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.
next
James Turner 3 years ago
parent 119f3d9814
commit 6fe7c307b2

@ -96,14 +96,14 @@ 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;
normalizeData();
_data.resize(m.length() + 2); // make room for " \0"
strcpy(_data.data(), m.c_str());
_url = m;
_m = _data;
_icao[0] = '\0';
normalizeData();
_m = _data.data();
_icao[0] = '\0';
// NOAA preample
if (!scanPreambleDate())
@ -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,7 +124,15 @@ SGMetar::SGMetar(const string& m) :
while (scanRwyVisRange()) ;
while (scanWeather()) ;
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();
while (scanSkyCondition()) ;
while (scanRunwayReport()) ;
@ -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,17 +491,24 @@ 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++); )
while (*src == ' ' && src[1] == ' ')
// TODO : use strutils::simplify here
char* src = _data.data();
char* dest = src;
for (; (*dest++ = *src++);) {
while (*src == ' ' && src[1] == ' ')
src++;
for (dest--; isspace(*--dest); ) ;
}
for (dest--; isspace(*--dest); ) ;
*++dest = ' ';
*++dest = '\0';
}

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

Loading…
Cancel
Save