#include <string.h>
#include <time.h>
#include <cstdlib>
+#include <cstdio>
+
+#include <boost/algorithm/string.hpp>
-#include <simgear/debug/logstream.hxx>
#include <simgear/environment/metar.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/io/HTTPClient.hxx>
-#include <simgear/io/HTTPRequest.hxx>
+#include <simgear/io/HTTPMemoryRequest.hxx>
+#include <simgear/io/raw_socket.hxx>
#include <simgear/timing/timestamp.hxx>
using namespace std;
using namespace simgear;
-class MetarRequest : public HTTP::Request
-{
-public:
- bool complete;
- bool failed;
- string metarData;
- bool fromProxy;
-
- MetarRequest(const std::string& stationId) :
- HTTP::Request("http://weather.noaa.gov/pub/data/observations/metar/stations/" + stationId + ".TXT"),
- complete(false),
- failed(false)
- {
- fromProxy = false;
- }
-
-protected:
-
- virtual void responseHeader(const string& key, const string& value)
- {
- if (key == "x-metarproxy") {
- fromProxy = true;
- }
- }
-
- virtual void gotBodyData(const char* s, int n)
- {
- metarData += string(s, n);
- }
-
- virtual void responseComplete()
- {
- if (responseCode() == 200) {
- complete = true;
- } else {
- SG_LOG(SG_ENVIRONMENT, SG_WARN, "metar download failed:" << url() << ": reason:" << responseReason());
- failed = true;
- }
- }
-};
-
// text color
-#if defined(__linux__) || defined(__sun) || defined(__CYGWIN__) \
- || defined( __FreeBSD__ ) || defined ( sgi )
+#if defined(__linux__) || defined(__sun) || defined(__CYGWIN__) || defined( __FreeBSD__ ) || defined ( sgi )
# define R "\033[31;1m" // red
# define G "\033[32;1m" // green
# define Y "\033[33;1m" // yellow
if ((i = m->getWindDir()) == -1)
cout << "from variable directions";
else
- cout << "from the " << azimuthName(i) << " (" << i << "°)";
+ cout << "from the " << azimuthName(i) << " (" << i << "°)";
cout << " at " << rnd(d, -1) << " km/h";
cout << "\t\t" << rnd(m->getWindSpeed_kt(), -1) << " kt";
if (from != to) {
cout << "\t\t\tvariable from " << azimuthName(from);
cout << " to " << azimuthName(to);
- cout << " (" << from << "°--" << to << "°)" << endl;
+ cout << " (" << from << "°--" << to << "°)" << endl;
}
}
// temperature/humidity/air pressure
if ((d = m->getTemperature_C()) != NaN) {
- cout << "Temperature:\t\t" << d << "°C\t\t\t\t\t";
- cout << rnd(m->getTemperature_F(), -1) << "°F" << endl;
+ cout << "Temperature:\t\t" << d << "°C\t\t\t\t\t";
+ cout << rnd(m->getTemperature_F(), -1) << "°F" << endl;
if ((d = m->getDewpoint_C()) != NaN) {
- cout << "Dewpoint:\t\t" << d << "°C\t\t\t\t\t";
- cout << rnd(m->getDewpoint_F(), -1) << "°F" << endl;
+ cout << "Dewpoint:\t\t" << d << "°C\t\t\t\t\t";
+ cout << rnd(m->getDewpoint_F(), -1) << "°F" << endl;
cout << "Rel. Humidity:\t\t" << rnd(m->getRelHumidity()) << "%" << endl;
}
}
surface.push_back(buf);
}
- if (surface.size()) {
+ if (! surface.empty()) {
vector<string>::iterator rwysurf = surface.begin();
for (i = 0; rwysurf != surface.end(); rwysurf++, i++) {
if (i)
sprintf(&buf[strlen(buf)], ":%.0lf", gust_speed);
args.push_back(buf);
}
-
+
// output everything
//cout << "fgfs" << endl;
string proxy_host, proxy_port;
getproxy(proxy_host, proxy_port);
+ Socket::initSockets();
+
HTTP::Client http;
http.setProxy(proxy_host, atoi(proxy_port.c_str()));
-
+
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help"))
usage();
shown = true;
}
- try {
- MetarRequest* mr = new MetarRequest(argv[i]);
+ try
+ {
+ static const std::string NOAA_BASE_URL =
+ "http://weather.noaa.gov/pub/data/observations/metar/stations/";
+ HTTP::MemoryRequest* mr = new HTTP::MemoryRequest
+ (
+ NOAA_BASE_URL
+ + boost::to_upper_copy<std::string>(argv[i]) + ".TXT"
+ );
HTTP::Request_ptr own(mr);
http.makeRequest(mr);
-
+
// spin until the request completes, fails or times out
SGTimeStamp start(SGTimeStamp::now());
while (start.elapsedMSec() < 8000) {
http.update();
- if (mr->complete || mr->failed) {
+ if( mr->isComplete() )
break;
- }
SGTimeStamp::sleepForMSec(1);
}
-
- if (!mr->complete) {
- throw sg_io_exception("metar download failed (or timed out)");
+
+ if( !mr->isComplete() )
+ throw sg_io_exception("metar download timed out");
+ if( mr->responseCode() != 200 )
+ {
+ std::cerr << "metar download failed: "
+ << mr->url()
+ << " (" << mr->responseCode()
+ << " " << mr->responseReason() << ")"
+ << std::endl;
+ throw sg_io_exception("metar download failed");
}
- SGMetar *m = new SGMetar(mr->metarData);
-
+
+ SGMetar *m = new SGMetar(mr->responseBody());
+
//SGMetar *m = new SGMetar("2004/01/11 01:20\nLOWG 110120Z AUTO VRB01KT 0050 1600N R35/0600 FG M06/M06 Q1019 88//////\n");
if (verbose) {
- cerr << G"INPUT: " << m->getData() << ""N << endl;
+ cerr << G "INPUT: " << m->getData() << "" N << endl;
const char *unused = m->getUnusedData();
if (*unused)
- cerr << R"UNUSED: " << unused << ""N << endl;
+ cerr << R "UNUSED: " << unused << "" N << endl;
}
if (report)
delete m;
} catch (const sg_io_exception& e) {
- cerr << R"ERROR: " << e.getFormattedMessage().c_str() << ""N << endl << endl;
+ cerr << R "ERROR: " << e.getFormattedMessage().c_str() << "" N << endl << endl;
}
}
}