48#include "D4BaseTypeFactory.h"
51#include "D4Sequence.h"
53#include "HTTPConnect.h"
55#include "StdinResponse.h"
61const char *version = CVER
" (" DVR
" DAP/" DAP_PROTOCOL_VERSION
")";
63static void usage(
const string &) {
64 const char *message = R
"(
65 Usage: getdap4 [dD vVmzsM][-c <expr>][-m <num>] <url> [<url> ...]
66 getdap4 [dD vVmzsM][-c <expr>][-m <num>] <file> [<file> ...]
68 In the first form of the command, dereference the URL and perform
69 the requested operations. This includes routing the returned
70 information through the DAP processing library (parsing the
71 returned objects, et c.). If none of d, or D are used with a URL,
72 then the DAP library routines are NOT used and the URLs contents
73 are dumped to standard output.
75 Note: If the URL contains a query string the query string will be
76 preserved in the request. However, if the query string contains
77 DAP4 keys they may interfere with the operation of getdap4. A
78 warning will be written to stderr when getdap4 identifies the
79 presence of a DAP4 query key in the submitted URL's query string.
81 In the second form of the command, assume the files are DAP4 data
82 responses (stored in files or read from pipes)
85 d: For each URL, get the (DAP4) DMR object. Does not get data.
86 D: For each URL, get the DAP4 Data response.
89 V: Version of this client
90 i: For each URL, get the server version.
91 m: Request the same URL <num> times.
92 z: Ask the server to compress data.
93 s: Print Sequences using numbered rows.
94 M: Assume data read from a file has no MIME headers; use only
97 c: <expr> is a constraint expression. Used with -d/D
98 NB: You can use a `?' for the CE also.
99 S: Used in conjunction with -d and will report the total size
100 of the data referenced in the DMR.)";
102 cerr << message << endl;
106bool read_data(FILE *fp) {
108 fprintf(stderr,
"getdap4: Whoa!!! Null stream pointer.\n");
115 while (fp && !feof(fp) && fread(&c, 1, 1, fp))
121static void read_response_from_file(
D4Connect *url,
DMR &dmr,
Response &r,
bool mime_headers,
bool get_dap4_data,
125 url->read_data(dmr, r);
127 url->read_dmr(dmr, r);
129 throw Error(
"Only supports Data or DMR responses");
132 url->read_data_no_mime(dmr, r);
134 url->read_dmr_no_mime(dmr, r);
136 throw Error(
"Only supports Data or DMR responses");
140static void print_group_data(
D4Group *g,
bool print_rows =
false) {
141 for (Constructor::Vars_iter i = g->
var_begin(), e = g->
var_end(); i != e; i++) {
142 if (print_rows && (*i)->type() == dods_sequence_c)
143 dynamic_cast<D4Sequence &
>(**i).print_val_by_rows(cout);
145 (*i)->print_val(cout);
148 for (D4Group::groupsIter gi = g->
grp_begin(), ge = g->
grp_end(); gi != ge; ++gi) {
149 print_group_data(*gi, print_rows);
153static void print_data(
DMR &dmr,
bool print_rows =
false) {
154 cout <<
"The data:" << endl;
158 print_group_data(g, print_rows);
160 cout << endl << flush;
173unsigned long long get_size(
D4Group *grp,
bool constrained =
false) {
174 unsigned long long w = 0;
176 for (
auto var_itr = grp->
var_begin(); var_itr != grp->
var_end(); var_itr++) {
178 if ((*var_itr)->send_p())
179 w += (*var_itr)->width(constrained);
181 w += (*var_itr)->width(constrained);
184 for (
auto grp_itr = grp->
grp_begin(); grp_itr != grp->
grp_end(); grp_itr++) {
185 w += get_size(*grp_itr, constrained);
191unsigned long long get_size(
DMR &dmr,
bool constrained =
false) {
return get_size(dmr.
root(), constrained); }
193int main(
int argc,
char *argv[]) {
196 bool get_dmr =
false;
197 bool get_dap4_data =
false;
198 bool verbose =
false;
199 bool accept_deflate =
false;
200 bool print_rows =
false;
201 bool mime_headers =
true;
202 bool report_errors =
false;
204 int dap_client_major = 4;
205 int dap_client_minor = 0;
207 bool compute_size =
false;
210 _setmode(_fileno(stdout), _O_BINARY);
213 while ((option_char = getopt(argc, argv,
"dDvVrm:Mzsc:S")) != -1) {
214 switch (option_char) {
219 get_dap4_data =
true;
225 cerr <<
"getdap4 version: " << version << endl;
231 report_errors =
true;
234 times = atoi(optarg);
237 accept_deflate =
true;
243 mime_headers =
false;
260 for (
int i = optind; i < argc; ++i) {
262 cerr <<
"Fetching: " << argv[i] << endl;
264 string name = argv[i];
271 if (dap_client_major > 2)
274 if (url->is_local()) {
276 cerr <<
"Assuming " << argv[i] <<
" is a file that contains a response object; decoding." << endl;
282 if (strcmp(argv[i],
"-") == 0) {
285 if (!r.get_cpp_stream())
286 throw Error(
"Could not open standard input.");
288 read_response_from_file(url, dmr, r, mime_headers, get_dap4_data, get_dmr);
290 fstream f(argv[i], std::ios_base::in);
291 if (!f.is_open() || f.bad() || f.eof())
292 throw Error((
string)
"Could not open: " + argv[i]);
296 read_response_from_file(url, dmr, r, mime_headers, get_dap4_data, get_dmr);
301 <<
" Server version: " << url->
get_version().c_str() << endl;
306 cout << xml.get_doc() << endl;
309 print_data(dmr, print_rows);
317 }
else if (get_dmr) {
318 for (
int j = 0; j < times; ++j) {
322 url->request_dmr(dmr, expr);
327 cout <<
"DMR:" << endl;
332 cout << xml.get_doc() << endl;
334 cout <<
"DMR References " << get_size(dmr) <<
" bytes of data," << endl;
343 }
else if (get_dap4_data) {
344 for (
int j = 0; j < times; ++j) {
348 url->request_dap4_data(dmr, expr);
353 cout <<
"DMR:" << endl;
358 cout << xml.get_doc() << endl;
360 print_data(dmr, print_rows);
373 http.set_accept_deflate(accept_deflate);
375 if (dap_client_major > 2)
378 string url_string = argv[i];
379 for (
int j = 0; j < times; ++j) {
383 vector<string> *headers = r->get_headers();
384 copy(headers->begin(), headers->end(), ostream_iterator<string>(cout,
"\n"));
386 if (!read_data(r->get_stream())) {
412 cerr <<
"Exiting." << endl;
414 }
catch (exception &e) {
416 cerr <<
"C++ library exception: " << e.what() << endl;
417 cerr <<
"Exiting." << endl;
std::string get_protocol()
void set_accept_deflate(bool deflate)
void set_xdap_protocol(int major, int minor)
std::string get_version()
groupsIter grp_begin()
Get an iterator to the start of the values.
groupsIter grp_end()
Get an iterator to the end of the values.
void print_dap4(XMLWriter &xml, bool constrained=false)
A class for error processing.
ErrorCode get_error_code() const
std::string get_error_message() const
Encapsulate a response read from stdin.
top level DAP object to house generic methods