50#include "DDXParserSAX2.h"
53#include "D4ResponseBuilder.h"
54#include "XDRStreamMarshaller.h"
55#include "XDRFileUnMarshaller.h"
65#include "D4StreamMarshaller.h"
69#include "SignalHandler.h"
70#include "EventHandler.h"
71#include "AlarmHandler.h"
75#define FUNCTION_CACHE "/tmp/dap_functions_cache/"
76#define FUNCTION_CACHE_PREFIX "f"
78#define FUNCTION_CACHE_SIZE 20000
84D4ResponseBuilder::~D4ResponseBuilder()
96 d_dap4_btp_func_expr =
"";
109 if (!dir_writable(FUNCTION_CACHE))
110 mkdir(FUNCTION_CACHE, 0777);
114 DBG(cerr <<
"the FUNCTION_CACHE directory (" << FUNCTION_CACHE <<
") exists" << endl);
118 DBG(cerr <<
"the FUNCTION_CACHE directory (" << FUNCTION_CACHE <<
") does not exist - not caching" << endl);
125 _setmode(_fileno(stdout), _O_BINARY);
136string D4ResponseBuilder::get_ce()
const
143 d_dap4ce =
www2id(_ce,
"%",
"%20");
154string D4ResponseBuilder::get_dataset_name()
const
161 d_dataset =
www2id(ds,
"%",
"%20");
176int D4ResponseBuilder::get_timeout()
const
226 string btp_function_ce =
"";
227 string::size_type pos = 0;
228 DBG(cerr <<
"ce: " <<
ce << endl);
230 string::size_type first_paren =
ce.find(
"(", pos);
231 string::size_type closing_paren =
ce.find(
")", pos);
232 while (first_paren != string::npos && closing_paren != string::npos) {
234 string name =
ce.substr(pos, first_paren-pos);
235 DBG(cerr <<
"name: " << name << endl);
240 if (!btp_function_ce.empty())
241 btp_function_ce +=
",";
242 btp_function_ce +=
ce.substr(pos, closing_paren+1-pos);
243 ce.erase(pos, closing_paren+1-pos);
248 pos = closing_paren + 1;
250 if (pos <
ce.length() &&
ce.at(pos) ==
',')
254 first_paren =
ce.find(
"(", pos);
255 closing_paren =
ce.find(
")", pos);
258 DBG(cerr <<
"Modified constraint: " <<
ce << endl);
259 DBG(cerr <<
"BTP Function part: " << btp_function_ce << endl);
262 d_dap4_btp_func_expr = btp_function_ce;
273build_cache_file_name(
const string &
dataset,
const string &ce)
275 DBG(cerr <<
"build_cache_file_name: dataset: " <<
dataset <<
", ce: " << ce << endl);
277 string name =
dataset +
"#" + ce;
278 string::size_type pos = name.find_first_of(
"/(),\"\'");
279 while (pos != string::npos) {
280 name.replace(pos, 1,
"#", 1);
281 pos = name.find_first_of(
"/()\"\'");
284 DBG(cerr <<
"build_cache_file_name: name: " << name << endl);
290static bool cached_data_ddx_exists(
const string &cache_file_name)
292 ifstream icache_file(cache_file_name.c_str());
294 return !icache_file.fail() && !icache_file.bad() && !icache_file.eof();
311 off_t entry_size = 0;
312 time_t entry_time = 0;
314 if (stat(cache_file_name.c_str(), &buf) == 0) {
315 entry_size = buf.st_size;
316 entry_time = buf.st_mtime;
325 time_t dataset_time = entry_time;
326 if (stat(d_dataset.c_str(), &buf) == 0) {
327 dataset_time = buf.st_mtime;
335 if (dataset_time > entry_time)
357 DBG(cerr <<
"Found function(s) in CE: " << d_dap4_btp_func_expr << endl);
365 string cache_file_name =
d_cache->get_cache_file_name(build_cache_file_name(d_dataset, d_dap4_btp_func_expr),
false);
373 d_cache->purge_file(cache_file_name);
375 if (
d_cache->get_read_lock(cache_file_name, fd)) {
376 DBG(cerr <<
"function ce - cached hit: " << cache_file_name << endl );
383 if (
d_cache->create_and_lock(cache_file_name, fd)) {
384 DBG(cerr <<
"function ce - caching " << cache_file_name << endl );
396 d_cache->exclusive_to_shared_lock(fd);
401 unsigned long long size =
d_cache->update_cache_info(cache_file_name);
402 if (
d_cache->cache_too_big(size))
403 d_cache->update_and_purge(cache_file_name);
407 else if (
d_cache->get_read_lock(cache_file_name, fd)) {
408 DBG(cerr <<
"function ce - cached hit: " << cache_file_name << endl );
412 throw InternalErr(__FILE__, __LINE__,
"Cache error during function invocation.");
416 DBG(cerr <<
"caught exception, unlocking cache and re-throw." << endl );
422 cache_token = cache_file_name;
439void D4ResponseBuilder::send_das(ostream &out,
DAS &das,
bool with_mime_headers)
const
441 if (with_mime_headers)
466void D4ResponseBuilder::send_das(ostream &out, DDS &dds, ConstraintEvaluator &eval,
bool constrained,
bool with_mime_headers)
473 if (with_mime_headers)
487 if (!d_dap4_btp_func_expr.empty()) {
489 DBG(cerr <<
"Found function(s) in CE: " << d_dap4_btp_func_expr << endl);
492 BaseTypeFactory factory;
497 string cache_file_name =
d_cache->get_cache_file_name(build_cache_file_name(d_dataset, d_dap4_btp_func_expr),
false);
505 d_cache->purge_file(cache_file_name);
507 if (
d_cache->get_read_lock(cache_file_name, fd)) {
508 DBG(cerr <<
"function ce - cached hit: " << cache_file_name << endl );
509 fdds = get_cached_dap2_data_ddx(cache_file_name, &factory);
515 if (
d_cache->create_and_lock(cache_file_name, fd)) {
516 DBG(cerr <<
"function ce - caching " << cache_file_name << endl );
518 eval.parse_constraint(d_dap4_btp_func_expr, dds);
519 fdds = eval.eval_function_clauses(dds);
528 d_cache->exclusive_to_shared_lock(fd);
533 unsigned long long size =
d_cache->update_cache_info(cache_file_name);
534 if (
d_cache->cache_too_big(size))
535 d_cache->update_and_purge(cache_file_name);
537 else if (
d_cache->get_read_lock(cache_file_name, fd)) {
538 DBG(cerr <<
"function ce - cached hit: " << cache_file_name << endl );
539 fdds = get_cached_dap2_data_ddx(cache_file_name, &factory);
542 throw InternalErr(__FILE__, __LINE__,
"Cache error during function invocation.");
546 DBG(cerr <<
"caught exception, unlocking cache and re-throw." << endl );
553 string cache_token =
"";
556 DBG(cerr <<
"Using the cache for the server function CE" << endl);
560 DBG(cerr <<
"Cache not found; (re)calculating" << endl);
561 eval.parse_constraint(d_dap4_btp_func_expr, dds);
562 fdds = eval.eval_function_clauses(dds);
565 if (with_mime_headers)
568 fdds->print_das(out);
571 d_cache->unlock_and_close(cache_token);
576 DBG(cerr <<
"Simple constraint" << endl);
578 eval.parse_constraint(d_dap4ce, dds);
580 if (with_mime_headers)
607 bool with_mime_headers)
610 if (with_mime_headers)
628 if (!d_dap4_btp_func_expr.empty()) {
630 DBG(cerr <<
"Found function(s) in CE: " << d_dap4_btp_func_expr << endl);
633 BaseTypeFactory factory;
638 string cache_file_name =
d_cache->get_cache_file_name(build_cache_file_name(d_dataset, d_dap4_btp_func_expr),
false);
646 d_cache->purge_file(cache_file_name);
648 if (
d_cache->get_read_lock(cache_file_name, fd)) {
649 DBG(cerr <<
"function ce - cached hit: " << cache_file_name << endl );
650 fdds = get_cached_dap2_data_ddx(cache_file_name, &factory);
655 if (
d_cache->create_and_lock(cache_file_name, fd)) {
656 DBG(cerr <<
"function ce - caching " << cache_file_name << endl );
658 eval.parse_constraint(d_dap4_btp_func_expr, dds);
659 fdds = eval.eval_function_clauses(dds);
668 d_cache->exclusive_to_shared_lock(fd);
673 unsigned long long size =
d_cache->update_cache_info(cache_file_name);
674 if (
d_cache->cache_too_big(size))
675 d_cache->update_and_purge(cache_file_name);
677 else if (
d_cache->get_read_lock(cache_file_name, fd)) {
678 DBG(cerr <<
"function ce - cached hit: " << cache_file_name << endl );
679 fdds = get_cached_dap2_data_ddx(cache_file_name, &factory);
682 throw InternalErr(__FILE__, __LINE__,
"Cache error during function invocation.");
686 DBG(cerr <<
"caught exception, unlocking cache and re-throw." << endl );
692 string cache_token =
"";
696 DBG(cerr <<
"Using the cache for the server function CE" << endl);
700 DBG(cerr <<
"Cache not found; (re)calculating" << endl);
701 eval.parse_constraint(d_dap4_btp_func_expr, dds);
702 fdds = eval.eval_function_clauses(dds);
710 fdds->mark_all(
false);
712 eval.parse_constraint(d_dap4ce, *fdds);
714 if (with_mime_headers)
717 fdds->print_constrained(out);
720 d_cache->unlock_and_close(cache_token);
725 DBG(cerr <<
"Simple constraint" << endl);
727 eval.parse_constraint(d_dap4ce, dds);
729 if (with_mime_headers)
732 dds.print_constrained(out);
744 DBG(cerr <<
"Inside dataset_constraint" << endl);
760 if ((*i)->send_p()) {
761 DBG(cerr <<
"Sending " << (*i)->name() << endl);
763 if ((*i)->type() != dods_structure_c && (*i)->type() != dods_grid_c)
766 (*i)->serialize(eval, dds, m, ce_eval);
768 if ((*i)->type() != dods_structure_c && (*i)->type() != dods_grid_c)
769 cerr << (*i)->name() <<
": " << m.
get_checksum() << endl;
771 (*i)->serialize(eval, dds, m, ce_eval);
784 const string &boundary,
const string &start,
bool ce_eval)
787 set_mime_ddx_boundary(out, boundary, start);
793 uuid_unparse(uu, uuid.data());
795 if (getdomainname(domain, 255) != 0 || strlen(domain) == 0)
796 strncpy(domain,
"opendap.org", 255);
798 string cid = string(uuid.data()) +
"@" + string(domain.data());
808 set_mime_data_boundary(out, boundary, cid, m.get_endian(), 0);
821 if ((*i)->send_p()) {
822 DBG(cerr <<
"Sending " << (*i)->name() << endl);
828 (*i)->serialize(eval, dds, m, ce_eval);
854 bool with_mime_headers)
866 string msg =
"The Request for " + long_to_string(dds.
get_request_size(
true) / 1024)
867 +
"KB is too large; requests for this user are limited to "
879 if (!d_dap4_btp_func_expr.empty()) {
880 DBG(cerr <<
"Found function(s) in CE: " << d_dap4_btp_func_expr << endl);
888 string cache_file_name =
d_cache->get_cache_file_name(build_cache_file_name(d_dataset, d_dap4_btp_func_expr),
false);
896 d_cache->purge_file(cache_file_name);
898 if (
d_cache->get_read_lock(cache_file_name, fd)) {
899 DBG(cerr <<
"function ce - cached hit: " << cache_file_name << endl );
900 fdds = get_cached_dap2_data_ddx(cache_file_name, &factory);
905 if (
d_cache->create_and_lock(cache_file_name, fd)) {
906 DBG(cerr <<
"function ce - caching " << cache_file_name << endl );
920 d_cache->exclusive_to_shared_lock(fd);
925 unsigned long long size =
d_cache->update_cache_info(cache_file_name);
926 if (
d_cache->cache_too_big(size))
927 d_cache->update_and_purge(cache_file_name);
929 else if (
d_cache->get_read_lock(cache_file_name, fd)) {
930 DBG(cerr <<
"function ce - cached hit: " << cache_file_name << endl );
931 fdds = get_cached_dap2_data_ddx(cache_file_name, &factory);
934 throw InternalErr(__FILE__, __LINE__,
"Cache error during function invocation.");
938 DBG(cerr <<
"caught exception, unlocking cache and re-throw." << endl );
948 if (cached_data_ddx_exists(cache_file_name)) {
949 fdds = get_cached_dap2_data_ddx(cache_file_name, &factory);
952 DBG(cerr <<
"Reading cache for " << d_dataset +
"?" + d_dap4_btp_func_expr << endl);
955 fdds =
new DDS(&factory);
963 if( !r->get_stream() )
964 throw Error(
"The input source: " + cache_file_name +
" could not be opened");
971 DDS::Vars_iter e = fdds->
var_end() ;
972 for( ; i != e; i++ ) {
974 b->set_read_p(
true ) ;
979 Ancillary::read_ancillary_das( *das, d_dataset ) ;
990 ofstream ocache_file(cache_file_name.c_str());
992 DBG(cerr <<
"Caching " << d_dataset +
"?" + d_dap4_btp_func_expr << endl);
998 string cache_token =
"";
1002 DBG(cerr <<
"Using the cache for the server function CE" << endl);
1006 DBG(cerr <<
"Cache not found; (re)calculating" << endl);
1011 DBG(cerr <<
"Intermediate DDS: " << endl);
1014 DBG(cerr <<
"Parsing remaining CE: " << d_dap4ce << endl);
1028 string msg =
"The Request for " + long_to_string(dds.
get_request_size(
true) / 1024)
1029 +
"KB is too large; requests for this user are limited to "
1034 if (with_mime_headers)
1037 DBG(cerr <<
"About to call dataset_constraint" << endl);
1041 d_cache->unlock_and_close(cache_token);
1046 DBG(cerr <<
"Simple constraint" << endl);
1053 string msg =
"The Request for " + long_to_string(dds.
get_request_size(
true) / 1024)
1054 +
"KB is too large; requests for this user are limited to "
1059 if (with_mime_headers)
1071 if (with_mime_headers)
1074 serialize_dap2_data_dds(data_stream, *fdds, eval,
false);
1078 if (with_mime_headers)
1081 serialize_dap2_data_dds(data_stream, dds, eval);
1085 data_stream << flush;
1109 if (!d_dap4ce.empty())
1114 "Function calls can only be used with data requests. To see the structure of the underlying data source, reissue the URL without the function.");
1116 if (with_mime_headers)
1143 const string &boundary,
bool with_mime_headers)
1152 string msg =
"The Request for " + long_to_string(dds.
get_request_size(
true) / 1024)
1153 +
"KB is too large; requests for this user are limited to "
1168 if (with_mime_headers)
1170 data_stream << flush;
1180 if (with_mime_headers)
1182 data_stream << flush;
1186 data_stream << flush;
1188 if (with_mime_headers)
1189 data_stream << CRLF <<
"--" << boundary <<
"--" << CRLF;
1207 if (!d_dap4ce.empty())
1213 "Function calls can only be used with data requests. To see the structure of the underlying data source, reissue the URL without the function.");
1233 DBG(cerr <<
"Caching " << d_dataset +
"?" + d_dap4_btp_func_expr << endl);
1235 ofstream data_stream(cache_file_name.c_str());
1238 string start=
"dataddx_cache_start", boundary=
"dataddx_cache_boundary";
1243 data_stream << flush;
1256 data_stream << flush;
1258 data_stream << CRLF <<
"--" << boundary <<
"--" << CRLF;
1259 data_stream.close();
1284 while (!mime.empty()) {
1286 string header,
value;
1297 DBG(cerr <<
"MPM Boundary: " << boundary << endl);
1308 DBG(cerr <<
"Data CID: " << data_cid << endl);
1318 (*i)->deserialize(um, fdds);
1328 DBG(cerr <<
"Reading cache for " << d_dataset +
"?" + d_dap4_btp_func_expr << endl);
1330 DDS *fdds =
new DDS(factory);
1338 if( !r->get_stream() )
1339 throw Error(
"The input source: " + cache_file_name +
" could not be opened");
1345 FILE *data = fopen( cache_file_name.c_str(),
"r" );
1353 DDS::Vars_iter e = fdds->
var_end() ;
1354 for( ; i != e; i++ ) {
1356 b->set_read_p(
true ) ;
1365 Ancillary::read_ancillary_das( *das, d_dataset ) ;
1388 throw InternalErr(__FILE__, __LINE__,
"ResponseBuilder::send_dap4_data: Not implemented");
1412 if ((*i)->send_p()) {
1413 DBG(cerr <<
"Sending " << (*i)->name() << endl);
1418 (*i)->serialize(eval, dds, m,
true);
1427static const char *descrip[] = {
"unknown",
"dods_das",
"dods_dds",
"dods_data",
"dods_error",
"web_error",
"dap4-ddx",
1428 "dap4-data",
"dap4-error",
"dap4-data-ddx",
"dods_ddx" };
1429static const char *encoding[] = {
"unknown",
"deflate",
"x-plain",
"gzip",
"binary" };
1447 const string &protocol)
const
1449 strm <<
"HTTP/1.0 200 OK" << CRLF;
1451 strm <<
"XDODS-Server: " << DVR<< CRLF;
1452 strm <<
"XOPeNDAP-Server: " << DVR<< CRLF;
1457 strm <<
"XDAP: " << protocol << CRLF;
1459 const time_t t = time(0);
1460 strm <<
"Date: " <<
rfc822_date(t).c_str() << CRLF;
1462 strm <<
"Last-Modified: ";
1463 if (last_modified > 0)
1464 strm <<
rfc822_date(last_modified).c_str() << CRLF;
1468 if (type == dods_ddx)
1469 strm <<
"Content-Type: text/xml" << CRLF;
1471 strm <<
"Content-Type: text/plain" << CRLF;
1475 strm <<
"Content-Description: " << descrip[type] << CRLF;
1476 if (type == dods_error)
1477 strm <<
"Cache-Control: no-cache" << CRLF;
1481 strm <<
"Content-Encoding: " << encoding[enc] << CRLF;
1496 const string &protocol)
const
1498 strm <<
"HTTP/1.0 200 OK" << CRLF;
1500 strm <<
"XDODS-Server: " << DVR<< CRLF;
1501 strm <<
"XOPeNDAP-Server: " << DVR<< CRLF;
1506 strm <<
"XDAP: " << protocol << CRLF;
1508 const time_t t = time(0);
1509 strm <<
"Date: " <<
rfc822_date(t).c_str() << CRLF;
1511 strm <<
"Last-Modified: ";
1512 if (last_modified > 0)
1513 strm <<
rfc822_date(last_modified).c_str() << CRLF;
1517 strm <<
"Content-type: text/html" << CRLF;
1519 strm <<
"Content-Description: " << descrip[type] << CRLF;
1520 if (type == dods_error)
1521 strm <<
"Cache-Control: no-cache" << CRLF;
1525 strm <<
"Content-Encoding: " << encoding[enc] << CRLF;
1543 const string &protocol)
const
1545 strm <<
"HTTP/1.0 200 OK" << CRLF;
1547 strm <<
"XDODS-Server: " << DVR<< CRLF;
1548 strm <<
"XOPeNDAP-Server: " << DVR<< CRLF;
1553 strm <<
"XDAP: " << protocol << CRLF;
1555 const time_t t = time(0);
1556 strm <<
"Date: " <<
rfc822_date(t).c_str() << CRLF;
1558 strm <<
"Last-Modified: ";
1559 if (last_modified > 0)
1560 strm <<
rfc822_date(last_modified).c_str() << CRLF;
1564 strm <<
"Content-Type: application/octet-stream" << CRLF;
1565 strm <<
"Content-Description: " << descrip[type] << CRLF;
1567 strm <<
"Content-Encoding: " << encoding[enc] << CRLF;
1575 const time_t last_modified,
const string &protocol,
const string &url)
const
1577 strm <<
"HTTP/1.1 200 OK" << CRLF;
1579 const time_t t = time(0);
1580 strm <<
"Date: " <<
rfc822_date(t).c_str() << CRLF;
1582 strm <<
"Last-Modified: ";
1583 if (last_modified > 0)
1584 strm <<
rfc822_date(last_modified).c_str() << CRLF;
1588 strm <<
"Content-Type: multipart/related; boundary=" << boundary <<
"; start=\"<" << start
1589 <<
">\"; type=\"text/xml\"" << CRLF;
1593 strm <<
"Content-Description: " << descrip[type] <<
";";
1595 strm <<
" url=\"" << url <<
"\"" << CRLF;
1600 strm <<
"Content-Encoding: " << encoding[enc] << CRLF;
1605 strm <<
"X-DAP: " << protocol << CRLF;
1607 strm <<
"X-OPeNDAP-Server: " << DVR<< CRLF;
1612void D4ResponseBuilder::set_mime_ddx_boundary(ostream &strm,
const string &boundary,
const string &cid)
const
1614 strm <<
"--" << boundary << CRLF;
1615 strm <<
"Content-Type: text/xml; charset=UTF-8" << CRLF;
1616 strm <<
"Content-Transfer-Encoding: binary" << CRLF;
1617 strm <<
"Content-Description: ddx" << CRLF;
1618 strm <<
"Content-Id: <" << cid <<
">" << CRLF;
1623void D4ResponseBuilder::set_mime_data_boundary(ostream &strm,
const string &boundary,
const string &cid,
1624 const string &endian,
unsigned long long len)
const
1626 strm <<
"--" << boundary << CRLF;
1627 strm <<
"Content-Type: application/x-dap-" << endian <<
"-endian" << CRLF;
1628 strm <<
"Content-Transfer-Encoding: binary" << CRLF;
1629 strm <<
"Content-Description: data" << CRLF;
1630 strm <<
"Content-Id: <" << cid <<
">" << CRLF;
1631 strm <<
"Content-Length: " << len << CRLF;
1644 strm <<
"HTTP/1.0 " << code <<
" " << reason.c_str() << CRLF;
1646 strm <<
"XDODS-Server: " << DVR<< CRLF;
1647 strm <<
"X-OPeNDAP-Server: " << DVR<< CRLF;
1652 strm <<
"X-DAP: " << protocol << CRLF;
1654 const time_t t = time(0);
1655 strm <<
"Date: " <<
rfc822_date(t).c_str() << CRLF;
1656 strm <<
"Cache-Control: no-cache" << CRLF;
Holds information about the link from a DAP2 client to a dataset.
virtual void read_data(DataDDS &data, Response *rs)
Read data which is preceded by MIME headers. This method works for both data dds and data ddx respons...
Evaluate a constraint expression.
bool find_function(const std::string &name, bool_func *f) const
Find a Boolean function with a given name in the function list.
void parse_constraint(const std::string &constraint, DDS &dds)
Parse the constraint expression given the current DDS.
bool function_clauses()
Does the current constraint expression contain function clauses.
DDS * eval_function_clauses(DDS &dds)
Evaluate a function-valued constraint expression that contains several function calls.
bool functional_expression()
Does the current constraint expression return a BaseType pointer? This method does not evaluate the c...
virtual void cache_data_ddx(const string &cache_file_name, DDS &dds)
Cache data.
virtual void set_ce(const string &ce)
void set_timeout(int t=0)
int d_timeout
The BTP functions, extracted from the CE.
string d_default_protocol
Response timeout after N seconds.
virtual string ce() const
void set_mime_binary(ostream &out, ObjectType type=unknown_type, EncodingType enc=x_plain, const time_t last_modified=0, const string &protocol="") const
virtual bool is_valid(const string &cache_file_name)
virtual void dataset_constraint_ddx(ostream &out, DDS &dds, ConstraintEvaluator &eval, const string &boundary, const string &start, bool ce_eval=true)
virtual void remove_timeout() const
virtual void send_data(ostream &data_stream, DDS &dds, ConstraintEvaluator &eval, bool with_mime_headers=true)
Transmit data.
void set_mime_error(ostream &out, int code=404, const string &reason="Dataset not found", const string &protocol="") const
virtual void establish_timeout(ostream &stream) const
virtual DDS * read_cached_dataset(DDS &dds, ConstraintEvaluator &eval, string &cache_token)
void set_mime_html(ostream &out, ObjectType type=unknown_type, EncodingType enc=x_plain, const time_t last_modified=0, const string &protocol="") const
virtual void split_ce(ConstraintEvaluator &eval, const string &expr="")
void set_mime_text(ostream &out, ObjectType type=unknown_type, EncodingType enc=x_plain, const time_t last_modified=0, const string &protocol="") const
virtual void send_data_ddx(ostream &data_stream, DDS &dds, ConstraintEvaluator &eval, const string &start, const string &boundary, bool with_mime_headers=true)
Transmit data.
virtual void send_ddx(ostream &out, DDS &dds, ConstraintEvaluator &eval, bool with_mime_headers=true)
virtual DDS * get_cached_data_ddx(const string &cache_file_name, BaseTypeFactory *factory)
virtual void dataset_constraint(ostream &out, DDS &dds, ConstraintEvaluator &eval, bool ce_eval=true)
Transmit a DDS.
virtual void set_dataset_name(const string &ds)
DAPCache3 * d_cache
Version string for the library's default protocol version.
void set_mime_multipart(ostream &out, const string &boundary, const string &start, ObjectType type=unknown_type, EncodingType enc=x_plain, const time_t last_modified=0, const string &protocol="", const string &url="") const
virtual void read_data_from_cache(FILE *data, DDS *fdds)
Marshaller that knows how to marshal/serialize dap data objects to a C++ iostream using DAP4's receiv...
virtual void put_checksum()
Write the checksum Write the checksum for the data sent since the last call to reset_checksum() to th...
virtual void reset_checksum()
virtual string get_checksum()
static DAPCache3 * get_instance()
Hold attribute data for a DAP2 dataset.
virtual void print(FILE *out, bool dereference=false)
void set_dataset_name(const string &n)
void mark_all(bool state)
Mark the send_p flag of the named variable to state.
void print_dmr(ostream &out, bool constrained)
Print the DAP4 DMR object using a DDS.
virtual void transfer_attributes(DAS *das)
int get_request_size(bool constrained)
Get the estimated response size in bytes.
BaseTypeFactory * set_factory(BaseTypeFactory *factory)
void tag_nested_sequences()
Traverse DDS, set Sequence leaf nodes.
BaseTypeFactory * get_factory() const
void print_constrained(FILE *out)
Print a constrained DDS to the specified file.
Vars_iter var_end()
Return an iterator.
void set_dap_version(const string &version_string="2.0")
void print_xml_writer(ostream &out, bool constrained, const string &blob="")
long get_response_limit()
Get the maximum response size, in bytes. Zero indicates no limit.
void intern_stream(FILE *in, DDS *dds, string &cid, const string &boundary="")
Read the DDX from a stream instead of a file.
A class for error processing.
A class for software fault reporting.
static EventHandler * register_handler(int signum, EventHandler *eh, bool ignore_by_default=false)
static SignalHandler * instance()
unmarshaller that knows how to unmarshall/deserialize dap objects using XDR from a file
Marshaller that knows how serialize dap data objects to a C++ iostream using XDR.
top level DAP object to house generic methods
string read_multipart_boundary(FILE *in, const string &boundary)
string cid_to_header_value(const string &cid)
Response
Common functions for DODS server filter programs.
string www2id(const string &in, const string &escape, const string &except)
void parse_mime_header(const string &header, string &name, string &value)
time_t last_modified_time(const string &name)
string name_path(const string &path)
Returns the filename portion of a pathname.
bool dir_exists(const string &dir)
void read_multipart_headers(FILE *in, const string &content_type, const ObjectType object_type, const string &cid)
EncodingType
The type of encoding used on the current stream.
virtual D4SeqValues value() const
Get the values for this D4Sequence This method returns a reference to the values held by the instance...
string rfc822_date(const time_t t)
virtual string dataset() const
Returns the name of the dataset used to create this instance.
ObjectType
The type of object in the stream coming from the data server.
string get_next_mime_header(FILE *in)