00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "config.h"
00035
00036 static char rcsid[] not_used =
00037 {"$Id: DDS.cc 20697 2009-04-08 17:14:10Z jimg $"
00038 };
00039
00040 #include <cstdio>
00041 #include <sys/types.h>
00042
00043 #ifdef WIN32
00044 #include <io.h>
00045 #include <process.h>
00046 #include <fstream>
00047 #else
00048 #include <unistd.h>
00049 #include <sys/wait.h>
00050 #endif
00051
00052 #include <iostream>
00053 #include <sstream>
00054 #include <algorithm>
00055 #include <functional>
00056
00057
00058
00059
00060 #include "GNURegex.h"
00061
00062 #include "DAS.h"
00063 #include "Clause.h"
00064 #include "Error.h"
00065 #include "InternalErr.h"
00066
00067 #include "parser.h"
00068 #include "debug.h"
00069 #include "util.h"
00070 #include "escaping.h"
00071
00072 const string c_default_dap20_schema_location = "http://xml.opendap.org/dap/dap2.xsd";
00073 const string c_default_dap32_schema_location = "http://xml.opendap.org/dap/dap/3.2.xsd";
00074
00075 const string c_dap20_namespace = "http://xml.opendap.org/ns/DAP2";
00076 const string c_dap32_namespace = "http://xml.opendap.org/ns/DAP/3.2#";
00077
00078 const string grddl_transformation_dap32 = "http://xml.opendap.org/transforms/ddxToRdfTriples.xsl";
00079
00080 const string c_xml_namespace = "http://www.w3.org/XML/1998/namespace";
00081
00082 using namespace std;
00083
00084 void ddsrestart(FILE *yyin);
00085 int ddsparse(void *arg);
00086
00087
00088 void dds_switch_to_buffer(void *new_buffer);
00089 void dds_delete_buffer(void * buffer);
00090 void *dds_buffer(FILE *fp);
00091
00092 namespace libdap {
00093
00094 void
00095 DDS::duplicate(const DDS &dds)
00096 {
00097 DBG(cerr << "Entering DDS::duplicate... " <<endl);
00098 name = dds.name;
00099 d_factory = dds.d_factory;
00100 d_container = dds.d_container;
00101
00102 d_client_dap_major = dds.d_client_dap_major;
00103 d_client_dap_minor = dds.d_client_dap_minor;
00104
00105
00106 #if 0
00107
00108 string _filename;
00109 string _container_name;
00110 int d_protocol_major;
00111 int d_protocol_minor;
00112
00113
00114
00115 int d_client_dap_major;
00116 int d_client_dap_minor;
00117
00118 AttrTable d_attr;
00119 int d_timeout;
00120
00121 #endif
00122
00123 DDS &dds_tmp = const_cast<DDS &>(dds);
00124
00125
00126 for (Vars_iter i = dds_tmp.var_begin(); i != dds_tmp.var_end(); i++) {
00127 add_var(*i);
00128 }
00129 }
00130
00141 DDS::DDS(BaseTypeFactory *factory, const string &n)
00142
00143 : d_factory(factory), name(n), d_container(0), d_dap_major(2),
00144 d_dap_minor(0), d_client_dap_major(2), d_client_dap_minor(0),
00145 d_request_xml_base(""), d_timeout(0)
00146 {
00147 DBG(cerr << "Building a DDS with client major/minor: "
00148 << d_client_dap_major << "." << d_client_dap_minor << endl);
00149 }
00150
00152 DDS::DDS(const DDS &rhs) : DapObj()
00153 {
00154 DBG(cerr << "Entering DDS(const DDS &rhs) ..." << endl);
00155 duplicate(rhs);
00156 DBG(cerr << " bye." << endl);
00157 }
00158
00159 DDS::~DDS()
00160 {
00161
00162 for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
00163 BaseType *btp = *i ;
00164 delete btp ; btp = 0;
00165 }
00166 }
00167
00168 DDS &
00169 DDS::operator=(const DDS &rhs)
00170 {
00171 DBG(cerr << "Entering DDS::operator= ..." << endl);
00172 if (this == &rhs)
00173 return *this;
00174
00175 duplicate(rhs);
00176
00177 DBG(cerr << " bye." << endl);
00178 return *this;
00179 }
00180
00196 BaseType *
00197 DDS::find_hdf4_dimension_attribute_home(AttrTable::entry *source)
00198 {
00199 BaseType *btp;
00200 string::size_type i = source->name.find("_dim_");
00201 if (i != string::npos && (btp = var(source->name.substr(0, i)))) {
00202 if (btp->is_vector_type()) {
00203 return btp;
00204 }
00205 else if (btp->type() == dods_grid_c) {
00206
00207
00208 int n = atoi(source->name.substr(i + 5).c_str());
00209 DBG(cerr << "Found a Grid (" << btp->name() << ") and "
00210 << source->name.substr(i) << ", extracted n: " << n << endl);
00211 return *(dynamic_cast<Grid&>(*btp).map_begin() + n);
00212 }
00213 }
00214
00215 return 0;
00216 }
00217
00223 AttrTable *
00224 DDS::find_matching_container(AttrTable::entry *source, BaseType **dest_variable)
00225 {
00226
00227 if (source->type != Attr_container)
00228 throw InternalErr(__FILE__, __LINE__, "DDS::find_matching_container");
00229
00230
00231
00232 BaseType *btp;
00233 if ((btp = var(source->name))) {
00234
00235 *dest_variable = btp;
00236 return &btp->get_attr_table();
00237 }
00238 else if ((btp = find_hdf4_dimension_attribute_home(source))) {
00239
00240
00241 if (btp->get_parent() && btp->get_parent()->type() == dods_grid_c) {
00242 DBG(cerr << "Found a Grid, assigning to the map" << endl);
00243 *dest_variable = btp;
00244 return &btp->get_attr_table();
00245 }
00246 else {
00247 string::size_type i = source->name.find("_dim_");
00248 string ext = source->name.substr(i + 1);
00249 *dest_variable = btp;
00250 return btp->get_attr_table().append_container(ext);
00251 }
00252 }
00253 else {
00254
00255 AttrTable *at = d_attr.find_container(source->name);
00256 if (!at) {
00257 at = new AttrTable();
00258 d_attr.append_container(at, source->name);
00259 }
00260
00261 *dest_variable = 0;
00262 return at;
00263 }
00264 }
00265
00287 void
00288 DDS::transfer_attributes(DAS *das)
00289 {
00290
00291
00292
00293
00294 if( d_container )
00295 {
00296 if( das->container_name() != _container_name )
00297 {
00298 string err = (string)"Error transferring attributes: "
00299 + "working on container in dds, but not das" ;
00300 throw InternalErr(__FILE__, __LINE__, err ) ;
00301 }
00302 }
00303 AttrTable *top_level = das->get_top_level_attributes() ;
00304
00305
00306 AttrTable::Attr_iter das_i = top_level->attr_begin();
00307 AttrTable::Attr_iter das_e = top_level->attr_end();
00308 while (das_i != das_e) {
00309 DBG(cerr << "Working on the '" << (*das_i)->name << "' container."
00310 << endl);
00311
00312 AttrTable *source = (*das_i)->attributes;
00313
00314 BaseType *dest_variable = 0;
00315 AttrTable *dest = find_matching_container(*das_i, &dest_variable);
00316
00317
00318 AttrTable::Attr_iter source_p = source->attr_begin();
00319 while (source_p != source->attr_end()) {
00320 DBG(cerr << "Working on the '" << (*source_p)->name << "' attribute"
00321 << endl);
00322
00323
00324
00325
00326
00327 if ((*source_p)->type == Attr_container) {
00328 if (dest_variable && dest_variable->is_constructor_type()) {
00329 dynamic_cast<Constructor&>(*dest_variable).transfer_attributes(*source_p);
00330 }
00331 else {
00332 #if 0
00333
00334 DBG(cerr << "Is current source aliased: "
00335 << (*source_p)->is_alias << endl);
00336 AttrTable &local = *(*source_p)->attributes;
00337 for (AttrTable::Attr_iter i = local.attr_begin();
00338 i != local.attr_end(); ++i) {
00339 cerr << "... or one of its entries: " << (*i)->is_alias << endl;
00340 }
00341 #endif
00342 dest->append_container(new AttrTable(*(*source_p)->attributes),
00343 (*source_p)->name);
00344 }
00345 }
00346 else {
00347 dest->append_attr(source->get_name(source_p),
00348 source->get_type(source_p),
00349 source->get_attr_vector(source_p));
00350 }
00351
00352 ++source_p;
00353 }
00354
00355 ++das_i;
00356 }
00357 }
00358
00366
00368 string
00369 DDS::get_dataset_name() const
00370 {
00371 return name;
00372 }
00373
00375 void
00376 DDS::set_dataset_name(const string &n)
00377 {
00378 name = n;
00379 }
00380
00382
00384 AttrTable &
00385 DDS::get_attr_table()
00386 {
00387 return d_attr;
00388 }
00389
00399 string
00400 DDS::filename()
00401 {
00402 return _filename;
00403 }
00404
00406 void
00407 DDS::filename(const string &fn)
00408 {
00409 _filename = fn;
00410 }
00412
00418 void
00419 DDS::set_dap_version(const string &version_string)
00420 {
00421 istringstream iss(version_string);
00422
00423 int major = -1, minor = -1;
00424 char dot;
00425 iss >> major;
00426 iss >> dot;
00427 iss >> minor;
00428
00429 DBG(cerr << "Major: " << major << ", dot: " << dot <<", Minor: " << minor << endl);
00430
00431 if (major == -1 || minor == -1)
00432 throw Error("Could not parse the client dap (XDAP-Accept header) value");
00433
00434 set_dap_major(major);
00435 set_dap_minor(minor);
00436 }
00437
00446 void
00447 DDS::set_client_dap_version(const string &version_string)
00448 {
00449 istringstream iss(version_string);
00450
00451 int major = -1, minor = -1;
00452 char dot;
00453 iss >> major;
00454 iss >> dot;
00455 iss >> minor;
00456
00457 DBG(cerr << "Major: " << major << ", dot: " << dot <<", Minor: " << minor << endl);
00458
00459 if (major == -1 || minor == -1)
00460 throw Error("Could not parse the client dap (XDAP-Accept header) value");
00461
00462 set_client_dap_major(major);
00463 set_client_dap_minor(minor);
00464 }
00465
00475 string
00476 DDS::container_name()
00477 {
00478 return _container_name;
00479 }
00480
00483 void
00484 DDS::container_name(const string &cn)
00485 {
00486
00487
00488
00489 d_container = 0 ;
00490 if( !cn.empty() )
00491 {
00492 d_container = dynamic_cast<Structure *>( var( cn ) ) ;
00493 if( !d_container )
00494 {
00495
00496
00497
00498
00499 Structure *s = new Structure( cn ) ;
00500 add_var( s ) ;
00501 delete s ;
00502 s = 0 ;
00503 d_container = dynamic_cast<Structure *>( var( cn ) ) ;
00504 }
00505 }
00506 _container_name = cn;
00507
00508 }
00509
00511 Structure *
00512 DDS::container()
00513 {
00514 return d_container ;
00515 }
00516
00518
00524 void
00525 DDS::add_var(BaseType *bt)
00526 {
00527 if (!bt)
00528 throw InternalErr(__FILE__, __LINE__,
00529 "Trying to add a BaseType object with a NULL pointer.");
00530
00531 DBG2(cerr << "In DDS::add_var(), bt's address is: " << bt << endl);
00532
00533 BaseType *btp = bt->ptr_duplicate();
00534 DBG2(cerr << "In DDS::add_var(), btp's address is: " << btp << endl);
00535 if( d_container )
00536 {
00537 d_container->add_var( bt ) ;
00538 }
00539 else
00540 {
00541 vars.push_back(btp);
00542 }
00543 }
00544
00551 void
00552 DDS::del_var(const string &n)
00553 {
00554 if( d_container )
00555 {
00556 d_container->del_var( n ) ;
00557 return ;
00558 }
00559
00560 for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
00561 if ((*i)->name() == n) {
00562 BaseType *bt = *i ;
00563 vars.erase(i) ;
00564 delete bt ; bt = 0;
00565 return;
00566 }
00567 }
00568 }
00569
00574 void
00575 DDS::del_var(Vars_iter i)
00576 {
00577 if (i != vars.end()) {
00578 BaseType *bt = *i ;
00579 vars.erase(i) ;
00580 delete bt ; bt = 0;
00581 }
00582 }
00583
00590 void
00591 DDS::del_var(Vars_iter i1, Vars_iter i2)
00592 {
00593 for (Vars_iter i_tmp = i1; i_tmp != i2; i_tmp++) {
00594 BaseType *bt = *i_tmp ;
00595 delete bt ; bt = 0;
00596 }
00597 vars.erase(i1, i2) ;
00598 }
00599
00607 BaseType *
00608 DDS::var(const string &n, BaseType::btp_stack &s)
00609 {
00610 return var(n, &s);
00611 }
00631 BaseType *
00632 DDS::var(const string &n, BaseType::btp_stack *s)
00633 {
00634 string name = www2id(n);
00635 if( d_container )
00636 return d_container->var( name, false, s ) ;
00637
00638 BaseType *v = exact_match(name, s);
00639 if (v)
00640 return v;
00641
00642 return leaf_match(name, s);
00643 }
00644
00645 BaseType *
00646 DDS::leaf_match(const string &n, BaseType::btp_stack *s)
00647 {
00648 DBG(cerr << "DDS::leaf_match: Looking for " << n << endl);
00649
00650 for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
00651 BaseType *btp = *i;
00652 DBG(cerr << "DDS::leaf_match: Looking for " << n << " in: " << btp->name() << endl);
00653
00654 if (btp->name() == n) {
00655 DBG(cerr << "Found " << n << " in: " << btp->name() << endl);
00656 return btp;
00657 }
00658
00659 if (btp->is_constructor_type()) {
00660 BaseType *found = btp->var(n, false, s);
00661 if (found) {
00662 DBG(cerr << "Found " << n << " in: " << btp->name() << endl);
00663 return found;
00664 }
00665 }
00666 #if STRUCTURE_ARRAY_SYNTAX_OLD
00667 if (btp->is_vector_type() && btp->var()->is_constructor_type()) {
00668 s->push(btp);
00669 BaseType *found = btp->var()->var(n, false, s);
00670 if (found) {
00671 DBG(cerr << "Found " << n << " in: " << btp->var()->name() << endl);
00672 return found;
00673 }
00674 }
00675 #endif
00676 }
00677
00678 return 0;
00679 }
00680
00681 BaseType *
00682 DDS::exact_match(const string &name, BaseType::btp_stack *s)
00683 {
00684 for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
00685 BaseType *btp = *i;
00686 DBG2(cerr << "Looking for " << name << " in: " << btp << endl);
00687
00688 if (btp->name() == name) {
00689 DBG2(cerr << "Found " << name << " in: " << btp << endl);
00690 return btp;
00691 }
00692 }
00693
00694 string::size_type dot_pos = name.find(".");
00695 if (dot_pos != string::npos) {
00696 string aggregate = name.substr(0, dot_pos);
00697 string field = name.substr(dot_pos + 1);
00698
00699 BaseType *agg_ptr = var(aggregate, s);
00700 if (agg_ptr) {
00701 DBG2(cerr << "Descending into " << agg_ptr->name() << endl);
00702 return agg_ptr->var(field, true, s);
00703 }
00704 else
00705 return 0;
00706 }
00707
00708 return 0;
00709 }
00710
00711
00714 DDS::Vars_iter
00715 DDS::var_begin()
00716 {
00717 return vars.begin();
00718 }
00719
00720 DDS::Vars_riter
00721 DDS::var_rbegin()
00722 {
00723 return vars.rbegin();
00724 }
00725
00726 DDS::Vars_iter
00727 DDS::var_end()
00728 {
00729 return vars.end() ;
00730 }
00731
00732 DDS::Vars_riter
00733 DDS::var_rend()
00734 {
00735 return vars.rend() ;
00736 }
00737
00741 DDS::Vars_iter
00742 DDS::get_vars_iter(int i)
00743 {
00744 return vars.begin() + i;
00745 }
00746
00750 BaseType *
00751 DDS::get_var_index(int i)
00752 {
00753 return *(vars.begin() + i);
00754 }
00755
00757 int
00758 DDS::num_var()
00759 {
00760 return vars.size();
00761 }
00762
00763 void
00764 DDS::timeout_on()
00765 {
00766 #ifndef WIN32
00767 alarm(d_timeout);
00768 #endif
00769 }
00770
00771 void
00772 DDS::timeout_off()
00773 {
00774 #ifndef WIN32
00775 d_timeout = alarm(0);
00776 #endif
00777 }
00778
00779 void
00780 DDS::set_timeout(int t)
00781 {
00782
00783 d_timeout = t;
00784 }
00785
00786 int
00787 DDS::get_timeout()
00788 {
00789
00790 return d_timeout;
00791 }
00792
00794 void
00795 DDS::tag_nested_sequences()
00796 {
00797 for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
00798 if ((*i)->type() == dods_sequence_c)
00799 dynamic_cast<Sequence&>(**i).set_leaf_sequence();
00800 else if ((*i)->type() == dods_structure_c)
00801 dynamic_cast<Structure&>(**i).set_leaf_sequence();
00802 }
00803 }
00804
00806 void
00807 DDS::parse(string fname)
00808 {
00809 FILE *in = fopen(fname.c_str(), "r");
00810
00811 if (!in) {
00812 throw Error(cannot_read_file, "Could not open: " + fname);
00813 }
00814
00815 try {
00816 parse(in);
00817 fclose(in);
00818 }
00819 catch (Error &e) {
00820 fclose(in);
00821 throw e;
00822 }
00823 }
00824
00825
00827 void
00828 DDS::parse(int fd)
00829 {
00830 #ifdef WIN32
00831 FILE *in = fdopen(_dup(fd), "r");
00832 #else
00833 FILE *in = fdopen(dup(fd), "r");
00834 #endif
00835
00836 if (!in) {
00837 throw InternalErr(__FILE__, __LINE__, "Could not access file.");
00838 }
00839
00840 try {
00841 parse(in);
00842 fclose(in);
00843 }
00844 catch (Error &e) {
00845 fclose(in);
00846 throw e;
00847 }
00848 }
00849
00856 void
00857 DDS::parse(FILE *in)
00858 {
00859 if (!in) {
00860 throw InternalErr(__FILE__, __LINE__, "Null input stream.");
00861 }
00862
00863 void *buffer = dds_buffer(in);
00864 dds_switch_to_buffer(buffer);
00865
00866 parser_arg arg(this);
00867
00868 bool status = ddsparse((void *) & arg) == 0;
00869
00870 dds_delete_buffer(buffer);
00871
00872 DBG2(cout << "Status from parser: " << status << endl);
00873
00874
00875
00876 if (!status || !arg.status()) {
00877 if (arg.error())
00878 throw *arg.error();
00879 }
00880 }
00881
00883 void
00884 DDS::print(FILE *out)
00885 {
00886 fprintf(out, "Dataset {\n") ;
00887
00888 for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
00889 (*i)->print_decl(out) ;
00890 }
00891
00892 fprintf(out, "} %s;\n", id2www(name).c_str()) ;
00893
00894 return ;
00895 }
00896
00898 void
00899 DDS::print(ostream &out)
00900 {
00901 out << "Dataset {\n" ;
00902
00903 for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
00904 (*i)->print_decl(out) ;
00905 }
00906
00907 out << "} " << id2www(name) << ";\n" ;
00908
00909 return ;
00910 }
00911
00922 void
00923 DDS::print_constrained(FILE *out)
00924 {
00925 fprintf(out, "Dataset {\n") ;
00926
00927 for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
00928
00929
00930
00931 (*i)->print_decl(out, " ", true, false, true) ;
00932 }
00933
00934 fprintf(out, "} %s;\n", id2www(name).c_str()) ;
00935
00936 return;
00937 }
00938
00949 void
00950 DDS::print_constrained(ostream &out)
00951 {
00952 out << "Dataset {\n" ;
00953
00954 for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
00955
00956
00957
00958 (*i)->print_decl(out, " ", true, false, true) ;
00959 }
00960
00961 out << "} " << id2www(name) << ";\n" ;
00962
00963 return;
00964 }
00965
00966 class VariablePrintXML : public unary_function<BaseType *, void>
00967 {
00968 FILE *d_out;
00969 bool d_constrained;
00970 public:
00971 VariablePrintXML(FILE *out, bool constrained)
00972 : d_out(out), d_constrained(constrained)
00973 {}
00974 void operator()(BaseType *bt)
00975 {
00976 bt->print_xml(d_out, " ", d_constrained);
00977 }
00978 };
00979
00980
00991 void
00992 DDS::print_xml(FILE *out, bool constrained, const string &)
00993 {
00994 fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
00995
00996 fprintf(out, "<Dataset name=\"%s\"\n", id2xml(name).c_str());
00997
00998 fprintf(out, "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
00999
01000 fprintf(out,"method=\"FILE*\"\n");
01001 fprintf(out, "dap_major=\"%d\"\n", get_client_dap_major());
01002 fprintf(out, "dap_minor=\"%d\"\n", get_client_dap_minor());
01003
01004
01005
01006 if (get_client_dap_major() == 3 && get_client_dap_minor() == 2) {
01007 fprintf(out, "xmlns=\"%s\"\n", c_dap32_namespace.c_str());
01008
01009 fprintf(out, "xsi:schemaLocation=\"%s %s\">\n\n",
01010 c_dap32_namespace.c_str(), c_default_dap32_schema_location.c_str());
01011 }
01012 else {
01013 fprintf(out, "xmlns=\"%s\"\n", c_dap20_namespace.c_str());
01014 fprintf(out, "xsi:schemaLocation=\"%s %s\">\n\n",
01015 c_dap20_namespace.c_str(), c_default_dap20_schema_location.c_str());
01016 }
01017
01018
01019 d_attr.print_xml(out, " ", constrained);
01020
01021 fprintf(out, "\n");
01022
01023 for_each(var_begin(), var_end(), VariablePrintXML(out, constrained));
01024
01025 fprintf(out, "\n");
01026
01027
01028
01029 if (get_client_dap_major() == 2 && get_client_dap_minor() == 0) {
01030 fprintf(out, " <dataBLOB href=\"\"/>\n");
01031 }
01032
01033 fprintf(out, "</Dataset>\n");
01034 }
01035
01036
01037 class VariablePrintXMLStrm : public unary_function<BaseType *, void>
01038 {
01039 ostream &d_out;
01040 bool d_constrained;
01041 public:
01042 VariablePrintXMLStrm(ostream &out, bool constrained)
01043 : d_out(out), d_constrained(constrained)
01044 {}
01045 void operator()(BaseType *bt)
01046 {
01047 bt->print_xml(d_out, " ", d_constrained);
01048 }
01049 };
01050
01061 void
01062 DDS::print_xml(ostream &out, bool constrained, const string &)
01063 {
01064 out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ;
01065
01066 out << "<Dataset name=\"" << id2xml(name) << "\"\n" ;
01067
01068 out << "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" ;
01069
01070
01071
01072 if (get_client_dap_major() == 3 && get_client_dap_minor() == 2) {
01073 out << "xsi:schemaLocation=\"" << c_dap32_namespace
01074 << " " << c_default_dap32_schema_location << "\"\n" ;
01075
01076 out << "xmlns:grddl=\"http://www.w3.org/2003/g/data-view#\"\n";
01077 out << "grddl:transformation=\"" << grddl_transformation_dap32 <<"\"\n";
01078
01079 out << "xmlns=\"" << c_dap32_namespace << "\"\n" ;
01080 out << "xmlns:dap=\"" << c_dap32_namespace << "\"\n" ;
01081
01082 out << "dap_version=\"" << get_client_dap_major() << "."
01083 << get_client_dap_minor() << "\"\n";
01084
01085 if (!get_request_xml_base().empty()) {
01086 out << "xmlns:xml=\"" << c_xml_namespace << "\"\n";
01087 out << "xml:base=\"" << get_request_xml_base() << "\"\n";
01088 }
01089
01090
01091 out << ">\n";
01092 }
01093 else {
01094 out << "xmlns=\"" << c_dap20_namespace << "\"\n" ;
01095 out << "xsi:schemaLocation=\"" << c_dap20_namespace
01096 << " " << c_default_dap20_schema_location << "\">\n\n" ;
01097 }
01098
01099 d_attr.print_xml(out, " ", constrained);
01100
01101 out << "\n" ;
01102
01103 for_each(var_begin(), var_end(), VariablePrintXMLStrm(out, constrained));
01104
01105 out << "\n" ;
01106
01107
01108
01109 if (get_client_dap_major() == 2 && get_client_dap_minor() == 0) {
01110 out << " <dataBLOB href=\"\"/>\n" ;
01111 }
01112
01113 out << "</Dataset>\n" ;
01114 }
01115
01116
01131 bool
01132 DDS::check_semantics(bool all)
01133 {
01134
01135 if (name == "") {
01136 cerr << "A dataset must have a name" << endl;
01137 return false;
01138 }
01139
01140 string msg;
01141 if (!unique_names(vars, name, "Dataset", msg))
01142 return false;
01143
01144 if (all)
01145 for (Vars_iter i = vars.begin(); i != vars.end(); i++)
01146 if (!(*i)->check_semantics(msg, true))
01147 return false;
01148
01149 return true;
01150 }
01151
01177 bool
01178 DDS::mark(const string &n, bool state)
01179 {
01180 BaseType::btp_stack *s = new BaseType::btp_stack;
01181
01182 DBG2(cerr << "DDS::mark: Looking for " << n << endl);
01183
01184 BaseType *variable = var(n, s);
01185 if (!variable) {
01186 DBG2(cerr << "Could not find variable " << n << endl);
01187 delete s; s = 0;
01188 return false;
01189 }
01190 variable->set_send_p(state);
01191
01192 DBG2(cerr << "DDS::mark: Set variable " << variable->name()
01193 << " (a " << variable->type_name() << ")" << endl);
01194
01195
01196
01197
01198
01199 while (!s->empty()) {
01200 s->top()->BaseType::set_send_p(state);
01201
01202 DBG2(cerr << "DDS::mark: Set variable " << s->top()->name()
01203 << " (a " << s->top()->type_name() << ")" << endl);
01204 string parent_name = (s->top()->get_parent()) ? s->top()->get_parent()->name(): "none";
01205 string parent_type = (s->top()->get_parent()) ? s->top()->get_parent()->type_name(): "none";
01206 DBG2(cerr << "DDS::mark: Parent variable " << parent_name << " (a " << parent_type << ")" << endl);
01207
01208 s->pop();
01209 }
01210
01211 delete s ; s = 0;
01212
01213 return true;
01214 }
01215
01221 void
01222 DDS::mark_all(bool state)
01223 {
01224 for (Vars_iter i = vars.begin(); i != vars.end(); i++)
01225 (*i)->set_send_p(state);
01226 }
01227
01235 void
01236 DDS::dump(ostream &strm) const
01237 {
01238 strm << DapIndent::LMarg << "DDS::dump - ("
01239 << (void *)this << ")" << endl ;
01240 DapIndent::Indent() ;
01241 strm << DapIndent::LMarg << "name: " << name << endl ;
01242 strm << DapIndent::LMarg << "filename: " << _filename << endl ;
01243 strm << DapIndent::LMarg << "protocol major: " << d_dap_major << endl;
01244 strm << DapIndent::LMarg << "protocol minor: " << d_dap_minor << endl;
01245 strm << DapIndent::LMarg << "factory: " << (void *)d_factory << endl ;
01246
01247 strm << DapIndent::LMarg << "global attributes:" << endl ;
01248 DapIndent::Indent() ;
01249 d_attr.dump(strm) ;
01250 DapIndent::UnIndent() ;
01251
01252 if (vars.size()) {
01253 strm << DapIndent::LMarg << "vars:" << endl ;
01254 DapIndent::Indent() ;
01255 Vars_citer i = vars.begin() ;
01256 Vars_citer ie = vars.end() ;
01257 for (; i != ie; i++) {
01258 (*i)->dump(strm) ;
01259 }
01260 DapIndent::UnIndent() ;
01261 }
01262 else {
01263 strm << DapIndent::LMarg << "vars: none" << endl ;
01264 }
01265
01266 DapIndent::UnIndent() ;
01267 }
01268
01269 }