Remove using std:: from the metar header, remove HTTP support, add very basic unit-test harness.
This commit is contained in:
parent
7984f055e2
commit
63a8209a83
@ -5,3 +5,12 @@ set(HEADERS metar.hxx precipitation.hxx)
|
|||||||
set(SOURCES metar.cxx precipitation.cxx)
|
set(SOURCES metar.cxx precipitation.cxx)
|
||||||
|
|
||||||
simgear_component(environment environment "${SOURCES}" "${HEADERS}")
|
simgear_component(environment environment "${SOURCES}" "${HEADERS}")
|
||||||
|
|
||||||
|
add_executable(test_metar test_metar.cxx)
|
||||||
|
target_link_libraries(test_metar
|
||||||
|
sgenvironment sgstructure sgmisc sgdebug
|
||||||
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
|
${ZLIB_LIBRARY}
|
||||||
|
${RT_LIBRARY})
|
||||||
|
|
||||||
|
add_test(metar ${EXECUTABLE_OUTPUT_PATH}/test_metar)
|
@ -32,7 +32,6 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include <simgear/io/sg_socket.hxx>
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/structure/exception.hxx>
|
#include <simgear/structure/exception.hxx>
|
||||||
|
|
||||||
@ -40,32 +39,28 @@
|
|||||||
|
|
||||||
#define NaN SGMetarNaN
|
#define NaN SGMetarNaN
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using std::map;
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The constructor takes a Metar string, or a four-letter ICAO code. In the
|
* The constructor takes a Metar string
|
||||||
* latter case the metar string is downloaded from
|
|
||||||
* http://weather.noaa.gov/pub/data/observations/metar/stations/.
|
|
||||||
* The constructor throws sg_io_exceptions on failure. The "METAR"
|
* The constructor throws sg_io_exceptions on failure. The "METAR"
|
||||||
* keyword has no effect (apart from incrementing the group counter
|
* keyword has no effect (apart from incrementing the group counter
|
||||||
* @a grpcount) and can be left away. A keyword "SPECI" is
|
* @a grpcount) and can be left away. A keyword "SPECI" is
|
||||||
* likewise accepted.
|
* likewise accepted.
|
||||||
*
|
*
|
||||||
* @param m ICAO station id or metar string
|
* @param m ICAO station id or metar string
|
||||||
* @param proxy proxy host (optional; default: "")
|
|
||||||
* @param port proxy port (optional; default: "80")
|
|
||||||
* @param auth proxy authorization information (optional; default: "")
|
|
||||||
*
|
*
|
||||||
* @par Examples:
|
* @par Examples:
|
||||||
* @code
|
* @code
|
||||||
* SGMetar *m = new SGMetar("METAR KSFO 061656Z 19004KT 9SM SCT100 OVC200 08/03 A3013");
|
* SGMetar *m = new SGMetar("METAR KSFO 061656Z 19004KT 9SM SCT100 OVC200 08/03 A3013");
|
||||||
* double t = m->getTemperature_F();
|
* double t = m->getTemperature_F();
|
||||||
* delete m;
|
* delete m;
|
||||||
*
|
|
||||||
* SGMetar n("KSFO", "proxy.provider.foo", "3128", "proxy-password");
|
|
||||||
* double d = n.getDewpoint_C();
|
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
SGMetar::SGMetar(const string& m, const string& proxy, const string& port,
|
SGMetar::SGMetar(const string& m) :
|
||||||
const string& auth, const time_t time) :
|
|
||||||
_grpcount(0),
|
_grpcount(0),
|
||||||
_x_proxy(false),
|
_x_proxy(false),
|
||||||
_year(-1),
|
_year(-1),
|
||||||
@ -87,16 +82,10 @@ SGMetar::SGMetar(const string& m, const string& proxy, const string& port,
|
|||||||
_snow(false),
|
_snow(false),
|
||||||
_cavok(false)
|
_cavok(false)
|
||||||
{
|
{
|
||||||
if (m.length() == 4 && isalnum(m[0]) && isalnum(m[1]) && isalnum(m[2]) && isalnum(m[3])) {
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
_icao[i] = toupper(m[i]);
|
|
||||||
_icao[4] = '\0';
|
|
||||||
_data = loadData(_icao, proxy, port, auth, time);
|
|
||||||
} else {
|
|
||||||
_data = new char[m.length() + 2]; // make room for " \0"
|
_data = new char[m.length() + 2]; // make room for " \0"
|
||||||
strcpy(_data, m.c_str());
|
strcpy(_data, m.c_str());
|
||||||
_url = _data;
|
_url = _data;
|
||||||
}
|
|
||||||
normalizeData();
|
normalizeData();
|
||||||
|
|
||||||
_m = _data;
|
_m = _data;
|
||||||
@ -169,85 +158,6 @@ void SGMetar::useCurrentDate()
|
|||||||
_month = now.tm_mon + 1;
|
_month = now.tm_mon + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If called with "KSFO" loads data from
|
|
||||||
* @code
|
|
||||||
* http://weather.noaa.gov/pub/data/observations/metar/stations/KSFO.TXT.
|
|
||||||
* @endcode
|
|
||||||
* Throws sg_io_exception on failure. Gives up after waiting longer than 10 seconds.
|
|
||||||
*
|
|
||||||
* @param id four-letter ICAO Metar station code, e.g. "KSFO".
|
|
||||||
* @param proxy proxy host (optional; default: "")
|
|
||||||
* @param port proxy port (optional; default: "80")
|
|
||||||
* @param auth proxy authorization information (optional; default: "")
|
|
||||||
* @return pointer to Metar data string, allocated by new char[].
|
|
||||||
* @see rfc2068.txt for proxy spec ("Proxy-Authorization")
|
|
||||||
*/
|
|
||||||
char *SGMetar::loadData(const char *id, const string& proxy, const string& port,
|
|
||||||
const string& auth, time_t time)
|
|
||||||
{
|
|
||||||
const int buflen = 512;
|
|
||||||
char buf[2 * buflen];
|
|
||||||
|
|
||||||
string metar_server = "weather.noaa.gov";
|
|
||||||
string host = proxy.empty() ? metar_server : proxy;
|
|
||||||
string path = "/pub/data/observations/metar/stations/";
|
|
||||||
|
|
||||||
path += string(id) + ".TXT";
|
|
||||||
_url = "http://" + metar_server + path;
|
|
||||||
|
|
||||||
SGSocket *sock = new SGSocket(host, port.empty() ? "80" : port, "tcp");
|
|
||||||
sock->set_timeout(10000);
|
|
||||||
if (!sock->open(SG_IO_OUT)) {
|
|
||||||
delete sock;
|
|
||||||
throw sg_io_exception("cannot connect to ", sg_location(host));
|
|
||||||
}
|
|
||||||
|
|
||||||
string get = "GET ";
|
|
||||||
if (!proxy.empty())
|
|
||||||
get += "http://" + metar_server;
|
|
||||||
|
|
||||||
sprintf(buf, "%ld", time);
|
|
||||||
get += path + " HTTP/1.0\015\012X-Time: " + buf + "\015\012";
|
|
||||||
get += "Host: " + metar_server + "\015\012";
|
|
||||||
|
|
||||||
if (!auth.empty())
|
|
||||||
get += "Proxy-Authorization: " + auth + "\015\012";
|
|
||||||
|
|
||||||
get += "\015\012";
|
|
||||||
sock->writestring(get.c_str());
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// skip HTTP header
|
|
||||||
while ((i = sock->readline(buf, buflen))) {
|
|
||||||
if (i <= 2 && isspace(buf[0]) && (!buf[1] || isspace(buf[1])))
|
|
||||||
break;
|
|
||||||
if (!strncmp(buf, "X-MetarProxy: ", 13))
|
|
||||||
_x_proxy = true;
|
|
||||||
}
|
|
||||||
if (i) {
|
|
||||||
i = sock->readline(buf, buflen);
|
|
||||||
if (i)
|
|
||||||
sock->readline(&buf[i], buflen);
|
|
||||||
}
|
|
||||||
|
|
||||||
sock->close();
|
|
||||||
delete sock;
|
|
||||||
|
|
||||||
char *b = buf;
|
|
||||||
scanBoundary(&b);
|
|
||||||
if (*b == '<')
|
|
||||||
throw sg_io_exception("no metar data available from ",
|
|
||||||
sg_location(_url));
|
|
||||||
|
|
||||||
char *metar = new char[strlen(b) + 2]; // make room for " \0"
|
|
||||||
strcpy(metar, b);
|
|
||||||
return metar;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
|
@ -29,18 +29,12 @@
|
|||||||
|
|
||||||
#include <simgear/constants.h>
|
#include <simgear/constants.h>
|
||||||
|
|
||||||
using std::vector;
|
|
||||||
using std::map;
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
const double SGMetarNaN = -1E20;
|
|
||||||
#define NaN SGMetarNaN
|
|
||||||
|
|
||||||
struct Token {
|
struct Token {
|
||||||
const char *id;
|
const char *id;
|
||||||
const char *text;
|
const char *text;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const double SGMetarNaN = -1E20;
|
||||||
|
|
||||||
class SGMetar;
|
class SGMetar;
|
||||||
|
|
||||||
@ -48,7 +42,7 @@ class SGMetarVisibility {
|
|||||||
friend class SGMetar;
|
friend class SGMetar;
|
||||||
public:
|
public:
|
||||||
SGMetarVisibility() :
|
SGMetarVisibility() :
|
||||||
_distance(NaN),
|
_distance(SGMetarNaN),
|
||||||
_direction(-1),
|
_direction(-1),
|
||||||
_modifier(EQUALS),
|
_modifier(EQUALS),
|
||||||
_tendency(NONE) {}
|
_tendency(NONE) {}
|
||||||
@ -70,8 +64,8 @@ public:
|
|||||||
void set(double dist, int dir = -1, int mod = -1, int tend = -1);
|
void set(double dist, int dir = -1, int mod = -1, int tend = -1);
|
||||||
|
|
||||||
inline double getVisibility_m() const { return _distance; }
|
inline double getVisibility_m() const { return _distance; }
|
||||||
inline double getVisibility_ft() const { return _distance == NaN ? NaN : _distance * SG_METER_TO_FEET; }
|
inline double getVisibility_ft() const { return _distance == SGMetarNaN ? SGMetarNaN : _distance * SG_METER_TO_FEET; }
|
||||||
inline double getVisibility_sm() const { return _distance == NaN ? NaN : _distance * SG_METER_TO_SM; }
|
inline double getVisibility_sm() const { return _distance == SGMetarNaN ? SGMetarNaN : _distance * SG_METER_TO_SM; }
|
||||||
inline int getDirection() const { return _direction; }
|
inline int getDirection() const { return _direction; }
|
||||||
inline int getModifier() const { return _modifier; }
|
inline int getModifier() const { return _modifier; }
|
||||||
inline int getTendency() const { return _tendency; }
|
inline int getTendency() const { return _tendency; }
|
||||||
@ -93,8 +87,8 @@ public:
|
|||||||
_deposit_string(0),
|
_deposit_string(0),
|
||||||
_extent(-1),
|
_extent(-1),
|
||||||
_extent_string(0),
|
_extent_string(0),
|
||||||
_depth(NaN),
|
_depth(SGMetarNaN),
|
||||||
_friction(NaN),
|
_friction(SGMetarNaN),
|
||||||
_friction_string(0),
|
_friction_string(0),
|
||||||
_comment(0),
|
_comment(0),
|
||||||
_wind_shear(false) {}
|
_wind_shear(false) {}
|
||||||
@ -146,14 +140,14 @@ public:
|
|||||||
static const char * COVERAGE_BROKEN_STRING;
|
static const char * COVERAGE_BROKEN_STRING;
|
||||||
static const char * COVERAGE_OVERCAST_STRING;
|
static const char * COVERAGE_OVERCAST_STRING;
|
||||||
|
|
||||||
SGMetarCloud() : _coverage(COVERAGE_NIL), _altitude(NaN), _type(0), _type_long(0) {}
|
SGMetarCloud() : _coverage(COVERAGE_NIL), _altitude(SGMetarNaN), _type(0), _type_long(0) {}
|
||||||
|
|
||||||
void set(double alt, Coverage cov = COVERAGE_NIL );
|
void set(double alt, Coverage cov = COVERAGE_NIL );
|
||||||
|
|
||||||
inline Coverage getCoverage() const { return _coverage; }
|
inline Coverage getCoverage() const { return _coverage; }
|
||||||
static Coverage getCoverage( const std::string & coverage );
|
static Coverage getCoverage( const std::string & coverage );
|
||||||
inline double getAltitude_m() const { return _altitude; }
|
inline double getAltitude_m() const { return _altitude; }
|
||||||
inline double getAltitude_ft() const { return _altitude == NaN ? NaN : _altitude * SG_METER_TO_FEET; }
|
inline double getAltitude_ft() const { return _altitude == SGMetarNaN ? SGMetarNaN : _altitude * SG_METER_TO_FEET; }
|
||||||
inline const char *getTypeString() const { return _type; }
|
inline const char *getTypeString() const { return _type; }
|
||||||
inline const char *getTypeLongString() const { return _type_long; }
|
inline const char *getTypeLongString() const { return _type_long; }
|
||||||
|
|
||||||
@ -167,8 +161,7 @@ protected:
|
|||||||
|
|
||||||
class SGMetar {
|
class SGMetar {
|
||||||
public:
|
public:
|
||||||
SGMetar(const string& m, const string& proxy = "", const string& port = "",
|
SGMetar(const std::string& m);
|
||||||
const string &auth = "", const time_t time = 0);
|
|
||||||
~SGMetar();
|
~SGMetar();
|
||||||
|
|
||||||
enum ReportType {
|
enum ReportType {
|
||||||
@ -189,8 +182,8 @@ public:
|
|||||||
Weather() { intensity = NIL; vincinity = false; }
|
Weather() { intensity = NIL; vincinity = false; }
|
||||||
Intensity intensity;
|
Intensity intensity;
|
||||||
bool vincinity;
|
bool vincinity;
|
||||||
vector<string> descriptions;
|
std::vector<std::string> descriptions;
|
||||||
vector<string> phenomena;
|
std::vector<std::string> phenomena;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const char *getData() const { return _data; }
|
inline const char *getData() const { return _data; }
|
||||||
@ -206,14 +199,14 @@ public:
|
|||||||
|
|
||||||
inline int getWindDir() const { return _wind_dir; }
|
inline int getWindDir() const { return _wind_dir; }
|
||||||
inline double getWindSpeed_mps() const { return _wind_speed; }
|
inline double getWindSpeed_mps() const { return _wind_speed; }
|
||||||
inline double getWindSpeed_kmh() const { return _wind_speed == NaN ? NaN : _wind_speed * SG_MPS_TO_KMH; }
|
inline double getWindSpeed_kmh() const { return _wind_speed == SGMetarNaN ? SGMetarNaN : _wind_speed * SG_MPS_TO_KMH; }
|
||||||
inline double getWindSpeed_kt() const { return _wind_speed == NaN ? NaN : _wind_speed * SG_MPS_TO_KT; }
|
inline double getWindSpeed_kt() const { return _wind_speed == SGMetarNaN ? SGMetarNaN : _wind_speed * SG_MPS_TO_KT; }
|
||||||
inline double getWindSpeed_mph() const { return _wind_speed == NaN ? NaN : _wind_speed * SG_MPS_TO_MPH; }
|
inline double getWindSpeed_mph() const { return _wind_speed == SGMetarNaN ? SGMetarNaN : _wind_speed * SG_MPS_TO_MPH; }
|
||||||
|
|
||||||
inline double getGustSpeed_mps() const { return _gust_speed; }
|
inline double getGustSpeed_mps() const { return _gust_speed; }
|
||||||
inline double getGustSpeed_kmh() const { return _gust_speed == NaN ? NaN : _gust_speed * SG_MPS_TO_KMH; }
|
inline double getGustSpeed_kmh() const { return _gust_speed == SGMetarNaN ? SGMetarNaN : _gust_speed * SG_MPS_TO_KMH; }
|
||||||
inline double getGustSpeed_kt() const { return _gust_speed == NaN ? NaN : _gust_speed * SG_MPS_TO_KT; }
|
inline double getGustSpeed_kt() const { return _gust_speed == SGMetarNaN ? SGMetarNaN : _gust_speed * SG_MPS_TO_KT; }
|
||||||
inline double getGustSpeed_mph() const { return _gust_speed == NaN ? NaN : _gust_speed * SG_MPS_TO_MPH; }
|
inline double getGustSpeed_mph() const { return _gust_speed == SGMetarNaN ? SGMetarNaN : _gust_speed * SG_MPS_TO_MPH; }
|
||||||
|
|
||||||
inline int getWindRangeFrom() const { return _wind_range_from; }
|
inline int getWindRangeFrom() const { return _wind_range_from; }
|
||||||
inline int getWindRangeTo() const { return _wind_range_to; }
|
inline int getWindRangeTo() const { return _wind_range_to; }
|
||||||
@ -224,11 +217,11 @@ public:
|
|||||||
inline const SGMetarVisibility *getDirVisibility() const { return _dir_visibility; }
|
inline const SGMetarVisibility *getDirVisibility() const { return _dir_visibility; }
|
||||||
|
|
||||||
inline double getTemperature_C() const { return _temp; }
|
inline double getTemperature_C() const { return _temp; }
|
||||||
inline double getTemperature_F() const { return _temp == NaN ? NaN : 1.8 * _temp + 32; }
|
inline double getTemperature_F() const { return _temp == SGMetarNaN ? SGMetarNaN : 1.8 * _temp + 32; }
|
||||||
inline double getDewpoint_C() const { return _dewp; }
|
inline double getDewpoint_C() const { return _dewp; }
|
||||||
inline double getDewpoint_F() const { return _dewp == NaN ? NaN : 1.8 * _dewp + 32; }
|
inline double getDewpoint_F() const { return _dewp == SGMetarNaN ? SGMetarNaN : 1.8 * _dewp + 32; }
|
||||||
inline double getPressure_hPa() const { return _pressure == NaN ? NaN : _pressure / 100; }
|
inline double getPressure_hPa() const { return _pressure == SGMetarNaN ? SGMetarNaN : _pressure / 100; }
|
||||||
inline double getPressure_inHg() const { return _pressure == NaN ? NaN : _pressure * SG_PA_TO_INHG; }
|
inline double getPressure_inHg() const { return _pressure == SGMetarNaN ? SGMetarNaN : _pressure * SG_PA_TO_INHG; }
|
||||||
|
|
||||||
inline int getRain() const { return _rain; }
|
inline int getRain() const { return _rain; }
|
||||||
inline int getHail() const { return _hail; }
|
inline int getHail() const { return _hail; }
|
||||||
@ -237,13 +230,13 @@ public:
|
|||||||
|
|
||||||
double getRelHumidity() const;
|
double getRelHumidity() const;
|
||||||
|
|
||||||
inline const vector<SGMetarCloud>& getClouds() const { return _clouds; }
|
inline const std::vector<SGMetarCloud>& getClouds() const { return _clouds; }
|
||||||
inline const map<string, SGMetarRunway>& getRunways() const { return _runways; }
|
inline const std::map<std::string, SGMetarRunway>& getRunways() const { return _runways; }
|
||||||
inline const vector<string>& getWeather() const { return _weather; }
|
inline const std::vector<std::string>& getWeather() const { return _weather; }
|
||||||
inline const vector<struct Weather> getWeather2() const { return _weather2; }
|
inline const std::vector<struct Weather> getWeather2() const { return _weather2; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
string _url;
|
std::string _url;
|
||||||
int _grpcount;
|
int _grpcount;
|
||||||
bool _x_proxy;
|
bool _x_proxy;
|
||||||
char *_data;
|
char *_data;
|
||||||
@ -267,15 +260,15 @@ protected:
|
|||||||
int _hail;
|
int _hail;
|
||||||
int _snow;
|
int _snow;
|
||||||
bool _cavok;
|
bool _cavok;
|
||||||
vector<struct Weather> _weather2;
|
std::vector<struct Weather> _weather2;
|
||||||
|
|
||||||
SGMetarVisibility _min_visibility;
|
SGMetarVisibility _min_visibility;
|
||||||
SGMetarVisibility _max_visibility;
|
SGMetarVisibility _max_visibility;
|
||||||
SGMetarVisibility _vert_visibility;
|
SGMetarVisibility _vert_visibility;
|
||||||
SGMetarVisibility _dir_visibility[8];
|
SGMetarVisibility _dir_visibility[8];
|
||||||
vector<SGMetarCloud> _clouds;
|
std::vector<SGMetarCloud> _clouds;
|
||||||
map<string, SGMetarRunway> _runways;
|
std::map<std::string, SGMetarRunway> _runways;
|
||||||
vector<string> _weather;
|
std::vector<std::string> _weather;
|
||||||
|
|
||||||
bool scanPreambleDate();
|
bool scanPreambleDate();
|
||||||
bool scanPreambleTime();
|
bool scanPreambleTime();
|
||||||
@ -303,10 +296,7 @@ protected:
|
|||||||
int scanNumber(char **str, int *num, int min, int max = 0);
|
int scanNumber(char **str, int *num, int min, int max = 0);
|
||||||
bool scanBoundary(char **str);
|
bool scanBoundary(char **str);
|
||||||
const struct Token *scanToken(char **str, const struct Token *list);
|
const struct Token *scanToken(char **str, const struct Token *list);
|
||||||
char *loadData(const char *id, const string& proxy, const string& port,
|
|
||||||
const string &auth, time_t time);
|
|
||||||
void normalizeData();
|
void normalizeData();
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef NaN
|
|
||||||
#endif // _METAR_HXX
|
#endif // _METAR_HXX
|
||||||
|
68
simgear/environment/test_metar.cxx
Normal file
68
simgear/environment/test_metar.cxx
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <simgear_config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# define random rand
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <simgear/misc/sg_dir.hxx>
|
||||||
|
#include <simgear/structure/exception.hxx>
|
||||||
|
|
||||||
|
#include "metar.hxx"
|
||||||
|
|
||||||
|
using std::cout;
|
||||||
|
using std::cerr;
|
||||||
|
using std::endl;
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
#define COMPARE(a, b) \
|
||||||
|
if ((a) != (b)) { \
|
||||||
|
cerr << "failed:" << #a << " != " << #b << endl; \
|
||||||
|
cerr << "\tgot:" << a << endl; \
|
||||||
|
exit(1); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define VERIFY(a) \
|
||||||
|
if (!(a)) { \
|
||||||
|
cerr << "failed:" << #a << endl; \
|
||||||
|
exit(1); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_basic()
|
||||||
|
{
|
||||||
|
SGMetar m1("2011/10/20 11:25 EHAM 201125Z 27012KT 240V300 9999 VCSH FEW025CB SCT048 10/05 Q1025 TEMPO VRB03KT");
|
||||||
|
COMPARE(m1.getYear(), 2011);
|
||||||
|
COMPARE(m1.getMonth(), 10);
|
||||||
|
COMPARE(m1.getDay(), 20);
|
||||||
|
COMPARE(m1.getHour(), 11);
|
||||||
|
COMPARE(m1.getMinute(), 25);
|
||||||
|
COMPARE(m1.getReportType(), -1); // should default to NIL?
|
||||||
|
|
||||||
|
COMPARE(m1.getWindDir(), 270);
|
||||||
|
COMPARE(m1.getWindSpeed_kt(), 12);
|
||||||
|
|
||||||
|
COMPARE(m1.getTemperature_C(), 10);
|
||||||
|
COMPARE(m1.getDewpoint_C(), 5);
|
||||||
|
COMPARE(m1.getPressure_hPa(), 1025);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
test_basic();
|
||||||
|
} catch (sg_exception& e) {
|
||||||
|
cerr << "got exception:" << e.getMessage() << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user