50#include "D4BaseTypeFactory.h"
52#include "D4Sequence.h"
54#include "StdinResponse.h"
55#include "HTTPConnect.h"
61const char *version = CVER
" (" DVR
" DAP/" DAP_PROTOCOL_VERSION
")";
63static void usage(
const string &)
65 const char *message = R
"(
66 Usage: getdap4 [dD vVmzsM][-c <expr>][-m <num>] <url> [<url> ...]
67 getdap4 [dD vVmzsM][-c <expr>][-m <num>] <file> [<file> ...]
69 In the first form of the command, dereference the URL and perform
70 the requested operations. This includes routing the returned
71 information through the DAP processing library (parsing the
72 returned objects, et c.). If none of d, or D are used with a URL,
73 then the DAP library routines are NOT used and the URLs contents
74 are dumped to standard output.
76 Note: If the URL contains a query string the query string will be
77 preserved in the request. However, if the query string contains
78 DAP4 keys they may interfere with the operation of getdap4. A
79 warning will be written to stderr when getdap4 identifies the
80 presence of a DAP4 query key in the submitted URL's query string.
82 In the second form of the command, assume the files are DAP4 data
83 responses (stored in files or read from pipes)
86 d: For each URL, get the (DAP4) DMR object. Does not get data.
87 D: For each URL, get the DAP4 Data response.
90 V: Version of this client
91 i: For each URL, get the server version.
92 m: Request the same URL <num> times.
93 z: Ask the server to compress data.
94 s: Print Sequences using numbered rows.
95 M: Assume data read from a file has no MIME headers; use only
98 c: <expr> is a constraint expression. Used with -d/D
99 NB: You can use a `?' for the CE also.
100 S: Used in conjunction with -d and will report the total size
101 of the data referenced in the DMR.)";
103 cerr << message << endl;
107bool read_data(FILE *fp)
110 fprintf(stderr,
"getdap4: Whoa!!! Null stream pointer.\n");
117 while (fp && !feof(fp) && fread(&c, 1, 1, fp))
124read_response_from_file(
D4Connect *url,
DMR &dmr,
Response &r,
bool mime_headers,
bool get_dap4_data,
bool get_dmr)
128 url->read_data(dmr, r);
130 url->read_dmr(dmr, r);
132 throw Error(
"Only supports Data or DMR responses");
136 url->read_data_no_mime(dmr, r);
138 url->read_dmr_no_mime(dmr, r);
140 throw Error(
"Only supports Data or DMR responses");
144static void print_group_data(
D4Group *g,
bool print_rows =
false)
146 for (Constructor::Vars_iter i = g->var_begin(), e = g->var_end(); i != e; i++) {
147 if (print_rows && (*i)->type() == dods_sequence_c)
148 dynamic_cast<D4Sequence &
>(**i).print_val_by_rows(cout);
150 (*i)->print_val(cout);
153 for (D4Group::groupsIter gi = g->grp_begin(), ge = g->grp_end(); gi != ge; ++gi) {
154 print_group_data(*gi, print_rows);
158static void print_data(
DMR &dmr,
bool print_rows =
false)
160 cout <<
"The data:" << endl;
164 print_group_data(g, print_rows);
166 cout << endl << flush;
179unsigned long long get_size(
D4Group *grp,
bool constrained =
false)
181 unsigned long long w = 0;
183 for (
auto var_itr = grp->var_begin(); var_itr != grp->var_end(); var_itr++) {
185 if ((*var_itr)->send_p())
186 w += (*var_itr)->width(constrained);
189 w += (*var_itr)->width(constrained);
192 for (
auto grp_itr = grp->grp_begin(); grp_itr != grp->grp_end(); grp_itr++) {
193 w += get_size(*grp_itr, constrained);
199unsigned long long get_size(
DMR &dmr,
bool constrained =
false)
201 return get_size(dmr.
root(), constrained);
205int main(
int argc,
char *argv[])
209 bool get_dmr =
false;
210 bool get_dap4_data =
false;
211 bool verbose =
false;
212 bool accept_deflate =
false;
213 bool print_rows =
false;
214 bool mime_headers =
true;
215 bool report_errors =
false;
217 int dap_client_major = 4;
218 int dap_client_minor = 0;
220 bool compute_size =
false;
223 _setmode(_fileno(stdout), _O_BINARY);
226 while ((option_char = getopt(argc, argv,
"dDvVrm:Mzsc:S")) != -1) {
227 switch (option_char) {
232 get_dap4_data =
true;
238 cerr <<
"getdap4 version: " << version << endl;
244 report_errors =
true;
247 times = atoi(optarg);
250 accept_deflate =
true;
256 mime_headers =
false;
273 for (
int i = optind; i < argc; ++i) {
275 cerr <<
"Fetching: " << argv[i] << endl;
277 string name = argv[i];
284 if (dap_client_major > 2)
287 if (url->is_local()) {
289 cerr <<
"Assuming " << argv[i] <<
" is a file that contains a response object; decoding." << endl;
295 if (strcmp(argv[i],
"-") == 0) {
298 if (!r.get_cpp_stream())
299 throw Error(
"Could not open standard input.");
301 read_response_from_file(url, dmr, r, mime_headers, get_dap4_data, get_dmr);
304 fstream f(argv[i], std::ios_base::in);
305 if (!f.is_open() || f.bad() || f.eof())
306 throw Error((
string)
"Could not open: " + argv[i]);
310 read_response_from_file(url, dmr, r, mime_headers, get_dap4_data, get_dmr);
314 cerr <<
"DAP version: " << url->
get_protocol().c_str() <<
" Server version: "
320 cout << xml.get_doc() << endl;
323 print_data(dmr, print_rows);
326 cerr <<
"Error: " << e.get_error_message() << endl;
334 for (
int j = 0; j < times; ++j) {
338 url->request_dmr(dmr, expr);
343 cout <<
"DMR:" << endl;
348 cout << xml.get_doc() << endl;
350 cout <<
"DMR References " << get_size(dmr) <<
" bytes of data," << endl;
354 cerr << e.get_error_message() << endl;
361 else if (get_dap4_data) {
362 for (
int j = 0; j < times; ++j) {
366 url->request_dap4_data(dmr, expr);
371 cout <<
"DMR:" << endl;
376 cout << xml.get_doc() << endl;
378 print_data(dmr, print_rows);
381 cerr << e.get_error_message() << endl;
393 http.set_accept_deflate(accept_deflate);
395 if (dap_client_major > 2)
398 string url_string = argv[i];
399 for (
int j = 0; j < times; ++j) {
403 vector <string> *headers = r->get_headers();
404 copy(headers->begin(), headers->end(), ostream_iterator<string>(cout,
"\n"));
406 if (!read_data(r->get_stream())) {
413 cerr << e.get_error_message() << endl;
427 if (e.get_error_code() == malformed_expr) {
428 cerr << e.get_error_message() << endl;
432 cerr << e.get_error_message() << endl;
436 cerr <<
"Exiting." << endl;
439 catch (exception &e) {
441 cerr <<
"C++ library exception: " << e.what() << endl;
442 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()
void print_dap4(XMLWriter &xml, bool constrained=false)
A class for error processing.
Encapsulate a response read from stdin.
top level DAP object to house generic methods