49 #include "XMLWriter.h"
50 #include "D4BaseTypeFactory.h"
52 #include "D4Sequence.h"
53 #include "D4Connect.h"
54 #include "StdinResponse.h"
55 #include "HTTPConnect.h"
61 const char *version = CVER
" (" DVR
" DAP/" DAP_PROTOCOL_VERSION
")";
63 static 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;
107 bool read_data(FILE *fp)
110 fprintf(stderr,
"getdap4: Whoa!!! Null stream pointer.\n");
117 while (fp && !feof(fp) && fread(&c, 1, 1, fp))
124 read_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");
144 static 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);
158 static 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;
179 unsigned 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);
199 unsigned long long get_size(
DMR &dmr,
bool constrained =
false)
201 return get_size(dmr.
root(), constrained);
205 int main(
int argc,
char *argv[])
209 bool get_dmr =
false;
210 bool get_dap4_data =
false;
212 bool verbose =
false;
214 bool accept_deflate =
false;
215 bool print_rows =
false;
216 bool mime_headers =
true;
217 bool report_errors =
false;
219 int dap_client_major = 4;
220 int dap_client_minor = 0;
222 bool compute_size =
false;
225 _setmode(_fileno(stdout), _O_BINARY);
228 while ((option_char = getopt(argc, argv,
"dDvVrm:Mzsc:S")) != -1) {
229 switch (option_char) {
234 get_dap4_data =
true;
240 cerr <<
"getdap4 version: " << version << endl;
246 report_errors =
true;
250 times = atoi(optarg);
253 accept_deflate =
true;
259 mime_headers =
false;
277 for (
int i = optind; i < argc; ++i) {
279 cerr <<
"Fetching: " << argv[i] << endl;
281 string name = argv[i];
288 if (dap_client_major > 2)
291 if (url->is_local()) {
293 cerr <<
"Assuming " << argv[i] <<
" is a file that contains a response object; decoding." << endl;
299 if (strcmp(argv[i],
"-") == 0) {
302 if (!r.get_cpp_stream())
303 throw Error(
"Could not open standard input.");
305 read_response_from_file(url, dmr, r, mime_headers, get_dap4_data, get_dmr);
308 fstream f(argv[i], std::ios_base::in);
309 if (!f.is_open() || f.bad() || f.eof())
310 throw Error((
string)
"Could not open: " + argv[i]);
314 read_response_from_file(url, dmr, r, mime_headers, get_dap4_data, get_dmr);
318 cerr <<
"DAP version: " << url->
get_protocol().c_str() <<
" Server version: "
324 cout << xml.get_doc() << endl;
327 print_data(dmr, print_rows);
338 for (
int j = 0; j < times; ++j) {
342 url->request_dmr(dmr, expr);
347 cout <<
"DMR:" << endl;
352 cout << xml.get_doc() << endl;
354 cout <<
"DMR References " << get_size(dmr) <<
" bytes of data," << endl;
365 else if (get_dap4_data) {
366 for (
int j = 0; j < times; ++j) {
370 url->request_dap4_data(dmr, expr);
375 cout <<
"DMR:" << endl;
380 cout << xml.get_doc() << endl;
382 print_data(dmr, print_rows);
397 http.set_accept_deflate(accept_deflate);
399 if (dap_client_major > 2)
402 string url_string = argv[i];
403 for (
int j = 0; j < times; ++j) {
407 vector <string> *headers = r->get_headers();
408 copy(headers->begin(), headers->end(), ostream_iterator<string>(cout,
"\n"));
410 if (!read_data(r->get_stream())) {
440 cerr <<
"Exiting." << endl;
443 catch (exception &e) {
445 cerr <<
"C++ library exception: " << e.what() << endl;
446 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