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 21975 2010-01-12 17:14:54Z 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
00071 #include "Byte.h"
00072 #include "Int16.h"
00073 #include "UInt16.h"
00074 #include "Int32.h"
00075 #include "UInt32.h"
00076 #include "Float32.h"
00077 #include "Float64.h"
00078 #include "Str.h"
00079 #include "Url.h"
00080 #include "Array.h"
00081 #include "Structure.h"
00082 #include "Sequence.h"
00083 #include "Grid.h"
00084
00085 #include "escaping.h"
00086
00087 const string c_default_dap20_schema_location = "http://xml.opendap.org/dap/dap2.xsd";
00088 const string c_default_dap32_schema_location = "http://xml.opendap.org/dap/dap3.2.xsd";
00089
00090 const string c_dap20_namespace = "http://xml.opendap.org/ns/DAP2";
00091 const string c_dap32_namespace = "http://xml.opendap.org/ns/DAP/3.2#";
00092
00093 const string grddl_transformation_dap32 = "http://xml.opendap.org/transforms/ddxToRdfTriples.xsl";
00094
00095 const string c_xml_namespace = "http://www.w3.org/XML/1998/namespace";
00096
00097 using namespace std;
00098
00099 void ddsrestart(FILE *yyin);
00100 int ddsparse(void *arg);
00101
00102
00103 void dds_switch_to_buffer(void *new_buffer);
00104 void dds_delete_buffer(void * buffer);
00105 void *dds_buffer(FILE *fp);
00106
00107 namespace libdap {
00108
00109 void
00110 DDS::duplicate(const DDS &dds)
00111 {
00112 DBG(cerr << "Entering DDS::duplicate... " <<endl);
00113 name = dds.name;
00114 d_filename = dds.d_filename;
00115 d_container_name = dds.d_container_name;
00116 d_timeout = dds.d_timeout;
00117 d_attr = dds.d_attr;
00118
00119 d_factory = dds.d_factory;
00120 d_container = dds.d_container;
00121 d_dap_major = dds.d_dap_major;
00122 d_dap_minor = dds.d_dap_minor;
00123
00124 DDS &dds_tmp = const_cast<DDS &>(dds);
00125
00126
00127 for (Vars_iter i = dds_tmp.var_begin(); i != dds_tmp.var_end(); i++) {
00128 add_var(*i);
00129 }
00130 }
00131
00142 DDS::DDS(BaseTypeFactory *factory, const string &n)
00143
00144 : d_factory(factory), name(n), d_container(0), d_dap_major(2),
00145 d_dap_minor(0),
00146 d_request_xml_base(""), d_timeout(0)
00147 {
00148 DBG(cerr << "Building a DDS with client major/minor: "
00149 << d_dap_major << "." << d_dap_minor << endl);
00150 }
00151
00153 DDS::DDS(const DDS &rhs) : DapObj()
00154 {
00155 DBG(cerr << "Entering DDS(const DDS &rhs) ..." << endl);
00156 duplicate(rhs);
00157 DBG(cerr << " bye." << endl);
00158 }
00159
00160 DDS::~DDS()
00161 {
00162
00163 for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
00164 BaseType *btp = *i ;
00165 delete btp ; btp = 0;
00166 }
00167 }
00168
00169 DDS &
00170 DDS::operator=(const DDS &rhs)
00171 {
00172 DBG(cerr << "Entering DDS::operator= ..." << endl);
00173 if (this == &rhs)
00174 return *this;
00175
00176 duplicate(rhs);
00177
00178 DBG(cerr << " bye." << endl);
00179 return *this;
00180 }
00181
00197 BaseType *
00198 DDS::find_hdf4_dimension_attribute_home(AttrTable::entry *source)
00199 {
00200 BaseType *btp;
00201 string::size_type i = source->name.find("_dim_");
00202 if (i != string::npos && (btp = var(source->name.substr(0, i)))) {
00203 if (btp->is_vector_type()) {
00204 return btp;
00205 }
00206 else if (btp->type() == dods_grid_c) {
00207
00208
00209 int n = atoi(source->name.substr(i + 5).c_str());
00210 DBG(cerr << "Found a Grid (" << btp->name() << ") and "
00211 << source->name.substr(i) << ", extracted n: " << n << endl);
00212 return *(dynamic_cast<Grid&>(*btp).map_begin() + n);
00213 }
00214 }
00215
00216 return 0;
00217 }
00218
00224 AttrTable *
00225 DDS::find_matching_container(AttrTable::entry *source, BaseType **dest_variable)
00226 {
00227
00228 if (source->type != Attr_container)
00229 throw InternalErr(__FILE__, __LINE__, "DDS::find_matching_container");
00230
00231
00232
00233 BaseType *btp;
00234 if ((btp = var(source->name))) {
00235
00236 *dest_variable = btp;
00237 return &btp->get_attr_table();
00238 }
00239 else if ((btp = find_hdf4_dimension_attribute_home(source))) {
00240
00241
00242 if (btp->get_parent() && btp->get_parent()->type() == dods_grid_c) {
00243 DBG(cerr << "Found a Grid, assigning to the map" << endl);
00244 *dest_variable = btp;
00245 return &btp->get_attr_table();
00246 }
00247 else {
00248 string::size_type i = source->name.find("_dim_");
00249 string ext = source->name.substr(i + 1);
00250 *dest_variable = btp;
00251 return btp->get_attr_table().append_container(ext);
00252 }
00253 }
00254 else {
00255
00256 AttrTable *at = d_attr.find_container(source->name);
00257 if (!at) {
00258 at = new AttrTable();
00259 d_attr.append_container(at, source->name);
00260 }
00261
00262 *dest_variable = 0;
00263 return at;
00264 }
00265 }
00266
00288 void
00289 DDS::transfer_attributes(DAS *das)
00290 {
00291
00292
00293
00294
00295 if( d_container )
00296 {
00297 if( das->container_name() != d_container_name )
00298 {
00299 string err = (string)"Error transferring attributes: "
00300 + "working on container in dds, but not das" ;
00301 throw InternalErr(__FILE__, __LINE__, err ) ;
00302 }
00303 }
00304 AttrTable *top_level = das->get_top_level_attributes() ;
00305
00306
00307 AttrTable::Attr_iter das_i = top_level->attr_begin();
00308 AttrTable::Attr_iter das_e = top_level->attr_end();
00309 while (das_i != das_e) {
00310 DBG(cerr << "Working on the '" << (*das_i)->name << "' container."
00311 << endl);
00312
00313 AttrTable *source = (*das_i)->attributes;
00314
00315 BaseType *dest_variable = 0;
00316 AttrTable *dest = find_matching_container(*das_i, &dest_variable);
00317
00318
00319 AttrTable::Attr_iter source_p = source->attr_begin();
00320 while (source_p != source->attr_end()) {
00321 DBG(cerr << "Working on the '" << (*source_p)->name << "' attribute"
00322 << endl);
00323
00324
00325
00326
00327
00328 if ((*source_p)->type == Attr_container) {
00329 if (dest_variable && dest_variable->is_constructor_type()) {
00330 dynamic_cast<Constructor&>(*dest_variable).transfer_attributes(*source_p);
00331 }
00332 else {
00333 dest->append_container(new AttrTable(*(*source_p)->attributes),
00334 (*source_p)->name);
00335 }
00336 }
00337 else {
00338 dest->append_attr(source->get_name(source_p),
00339 source->get_type(source_p),
00340 source->get_attr_vector(source_p));
00341 }
00342
00343 ++source_p;
00344 }
00345
00346 ++das_i;
00347 }
00348 }
00349
00357
00359 string
00360 DDS::get_dataset_name() const
00361 {
00362 return name;
00363 }
00364
00366 void
00367 DDS::set_dataset_name(const string &n)
00368 {
00369 name = n;
00370 }
00371
00373
00375 AttrTable &
00376 DDS::get_attr_table()
00377 {
00378 return d_attr;
00379 }
00380
00390 string
00391 DDS::filename()
00392 {
00393 return d_filename;
00394 }
00395
00397 void
00398 DDS::filename(const string &fn)
00399 {
00400 d_filename = fn;
00401 }
00403
00409 void
00410 DDS::set_dap_version(const string &version_string)
00411 {
00412 istringstream iss(version_string);
00413
00414 int major = -1, minor = -1;
00415 char dot;
00416 iss >> major;
00417 iss >> dot;
00418 iss >> minor;
00419
00420 DBG(cerr << "Major: " << major << ", dot: " << dot <<", Minor: " << minor << endl);
00421
00422 if (major == -1 || minor == -1)
00423 throw Error("Could not parse the client dap (XDAP-Accept header) value");
00424
00425 set_dap_major(major);
00426 set_dap_minor(minor);
00427 }
00428
00438 string
00439 DDS::container_name()
00440 {
00441 return d_container_name;
00442 }
00443
00446 void
00447 DDS::container_name(const string &cn)
00448 {
00449
00450
00451
00452 d_container = 0 ;
00453 if( !cn.empty() )
00454 {
00455 d_container = dynamic_cast<Structure *>( var( cn ) ) ;
00456 if( !d_container )
00457 {
00458
00459
00460
00461
00462 Structure *s = new Structure( cn ) ;
00463 add_var( s ) ;
00464 delete s ;
00465 s = 0 ;
00466 d_container = dynamic_cast<Structure *>( var( cn ) ) ;
00467 }
00468 }
00469 d_container_name = cn;
00470
00471 }
00472
00474 Structure *
00475 DDS::container()
00476 {
00477 return d_container ;
00478 }
00479
00481
00487 void
00488 DDS::add_var(BaseType *bt)
00489 {
00490 if (!bt)
00491 throw InternalErr(__FILE__, __LINE__,
00492 "Trying to add a BaseType object with a NULL pointer.");
00493
00494 DBG2(cerr << "In DDS::add_var(), bt's address is: " << bt << endl);
00495
00496 BaseType *btp = bt->ptr_duplicate();
00497 DBG2(cerr << "In DDS::add_var(), btp's address is: " << btp << endl);
00498 if( d_container )
00499 {
00500
00501
00502 d_container->add_var( bt ) ;
00503
00504 delete btp; btp = 0;
00505 }
00506 else
00507 {
00508 vars.push_back(btp);
00509 }
00510 }
00511
00518 void
00519 DDS::del_var(const string &n)
00520 {
00521 if( d_container )
00522 {
00523 d_container->del_var( n ) ;
00524 return ;
00525 }
00526
00527 for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
00528 if ((*i)->name() == n) {
00529 BaseType *bt = *i ;
00530 vars.erase(i) ;
00531 delete bt ; bt = 0;
00532 return;
00533 }
00534 }
00535 }
00536
00541 void
00542 DDS::del_var(Vars_iter i)
00543 {
00544 if (i != vars.end()) {
00545 BaseType *bt = *i ;
00546 vars.erase(i) ;
00547 delete bt ; bt = 0;
00548 }
00549 }
00550
00557 void
00558 DDS::del_var(Vars_iter i1, Vars_iter i2)
00559 {
00560 for (Vars_iter i_tmp = i1; i_tmp != i2; i_tmp++) {
00561 BaseType *bt = *i_tmp ;
00562 delete bt ; bt = 0;
00563 }
00564 vars.erase(i1, i2) ;
00565 }
00566
00574 BaseType *
00575 DDS::var(const string &n, BaseType::btp_stack &s)
00576 {
00577 return var(n, &s);
00578 }
00598 BaseType *
00599 DDS::var(const string &n, BaseType::btp_stack *s)
00600 {
00601 string name = www2id(n);
00602 if( d_container )
00603 return d_container->var( name, false, s ) ;
00604
00605 BaseType *v = exact_match(name, s);
00606 if (v)
00607 return v;
00608
00609 return leaf_match(name, s);
00610 }
00611
00612 BaseType *
00613 DDS::leaf_match(const string &n, BaseType::btp_stack *s)
00614 {
00615 DBG(cerr << "DDS::leaf_match: Looking for " << n << endl);
00616
00617 for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
00618 BaseType *btp = *i;
00619 DBG(cerr << "DDS::leaf_match: Looking for " << n << " in: " << btp->name() << endl);
00620
00621 if (btp->name() == n) {
00622 DBG(cerr << "Found " << n << " in: " << btp->name() << endl);
00623 return btp;
00624 }
00625
00626 if (btp->is_constructor_type()) {
00627 BaseType *found = btp->var(n, false, s);
00628 if (found) {
00629 DBG(cerr << "Found " << n << " in: " << btp->name() << endl);
00630 return found;
00631 }
00632 }
00633 #if STRUCTURE_ARRAY_SYNTAX_OLD
00634 if (btp->is_vector_type() && btp->var()->is_constructor_type()) {
00635 s->push(btp);
00636 BaseType *found = btp->var()->var(n, false, s);
00637 if (found) {
00638 DBG(cerr << "Found " << n << " in: " << btp->var()->name() << endl);
00639 return found;
00640 }
00641 }
00642 #endif
00643 }
00644
00645 return 0;
00646 }
00647
00648 BaseType *
00649 DDS::exact_match(const string &name, BaseType::btp_stack *s)
00650 {
00651 for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
00652 BaseType *btp = *i;
00653 DBG2(cerr << "Looking for " << name << " in: " << btp << endl);
00654
00655 if (btp->name() == name) {
00656 DBG2(cerr << "Found " << name << " in: " << btp << endl);
00657 return btp;
00658 }
00659 }
00660
00661 string::size_type dot_pos = name.find(".");
00662 if (dot_pos != string::npos) {
00663 string aggregate = name.substr(0, dot_pos);
00664 string field = name.substr(dot_pos + 1);
00665
00666 BaseType *agg_ptr = var(aggregate, s);
00667 if (agg_ptr) {
00668 DBG2(cerr << "Descending into " << agg_ptr->name() << endl);
00669 return agg_ptr->var(field, true, s);
00670 }
00671 else
00672 return 0;
00673 }
00674
00675 return 0;
00676 }
00677
00678
00681 DDS::Vars_iter
00682 DDS::var_begin()
00683 {
00684 return vars.begin();
00685 }
00686
00687 DDS::Vars_riter
00688 DDS::var_rbegin()
00689 {
00690 return vars.rbegin();
00691 }
00692
00693 DDS::Vars_iter
00694 DDS::var_end()
00695 {
00696 return vars.end() ;
00697 }
00698
00699 DDS::Vars_riter
00700 DDS::var_rend()
00701 {
00702 return vars.rend() ;
00703 }
00704
00708 DDS::Vars_iter
00709 DDS::get_vars_iter(int i)
00710 {
00711 return vars.begin() + i;
00712 }
00713
00717 BaseType *
00718 DDS::get_var_index(int i)
00719 {
00720 return *(vars.begin() + i);
00721 }
00722
00724 int
00725 DDS::num_var()
00726 {
00727 return vars.size();
00728 }
00729
00730 void
00731 DDS::timeout_on()
00732 {
00733 #ifndef WIN32
00734 alarm(d_timeout);
00735 #endif
00736 }
00737
00738 void
00739 DDS::timeout_off()
00740 {
00741 #ifndef WIN32
00742 d_timeout = alarm(0);
00743 #endif
00744 }
00745
00746 void
00747 DDS::set_timeout(int t)
00748 {
00749
00750 d_timeout = t;
00751 }
00752
00753 int
00754 DDS::get_timeout()
00755 {
00756
00757 return d_timeout;
00758 }
00759
00761 void
00762 DDS::tag_nested_sequences()
00763 {
00764 for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
00765 if ((*i)->type() == dods_sequence_c)
00766 dynamic_cast<Sequence&>(**i).set_leaf_sequence();
00767 else if ((*i)->type() == dods_structure_c)
00768 dynamic_cast<Structure&>(**i).set_leaf_sequence();
00769 }
00770 }
00771
00773 void
00774 DDS::parse(string fname)
00775 {
00776 FILE *in = fopen(fname.c_str(), "r");
00777
00778 if (!in) {
00779 throw Error(cannot_read_file, "Could not open: " + fname);
00780 }
00781
00782 try {
00783 parse(in);
00784 fclose(in);
00785 }
00786 catch (Error &e) {
00787 fclose(in);
00788 throw e;
00789 }
00790 }
00791
00792
00794 void
00795 DDS::parse(int fd)
00796 {
00797 #ifdef WIN32
00798 FILE *in = fdopen(_dup(fd), "r");
00799 #else
00800 FILE *in = fdopen(dup(fd), "r");
00801 #endif
00802
00803 if (!in) {
00804 throw InternalErr(__FILE__, __LINE__, "Could not access file.");
00805 }
00806
00807 try {
00808 parse(in);
00809 fclose(in);
00810 }
00811 catch (Error &e) {
00812 fclose(in);
00813 throw e;
00814 }
00815 }
00816
00823 void
00824 DDS::parse(FILE *in)
00825 {
00826 if (!in) {
00827 throw InternalErr(__FILE__, __LINE__, "Null input stream.");
00828 }
00829
00830 void *buffer = dds_buffer(in);
00831 dds_switch_to_buffer(buffer);
00832
00833 parser_arg arg(this);
00834
00835 bool status = ddsparse((void *) & arg) == 0;
00836
00837 dds_delete_buffer(buffer);
00838
00839 DBG2(cout << "Status from parser: " << status << endl);
00840
00841
00842
00843 if (!status || !arg.status()) {
00844 if (arg.error())
00845 throw *arg.error();
00846 }
00847 }
00848
00849 #if FILE_METHODS
00850
00851 void
00852 DDS::print(FILE *out)
00853 {
00854 fprintf(out, "Dataset {\n") ;
00855
00856 for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
00857 (*i)->print_decl(out) ;
00858 }
00859
00860 fprintf(out, "} %s;\n", id2www(name).c_str()) ;
00861
00862 return ;
00863 }
00864 #endif
00865
00867 void
00868 DDS::print(ostream &out)
00869 {
00870 out << "Dataset {\n" ;
00871
00872 for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
00873 (*i)->print_decl(out) ;
00874 }
00875
00876 out << "} " << id2www(name) << ";\n" ;
00877
00878 return ;
00879 }
00880
00881 #if FILE_METHODS
00882
00892 void
00893 DDS::print_constrained(FILE *out)
00894 {
00895 fprintf(out, "Dataset {\n") ;
00896
00897 for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
00898
00899
00900
00901 (*i)->print_decl(out, " ", true, false, true) ;
00902 }
00903
00904 fprintf(out, "} %s;\n", id2www(name).c_str()) ;
00905
00906 return;
00907 }
00908 #endif
00909
00920 void
00921 DDS::print_constrained(ostream &out)
00922 {
00923 out << "Dataset {\n" ;
00924
00925 for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
00926
00927
00928
00929 (*i)->print_decl(out, " ", true, false, true) ;
00930 }
00931
00932 out << "} " << id2www(name) << ";\n" ;
00933
00934 return;
00935 }
00936
00937 #if FILE_METHODS
00938 class VariablePrintXML : public unary_function<BaseType *, void>
00939 {
00940 FILE *d_out;
00941 bool d_constrained;
00942 public:
00943 VariablePrintXML(FILE *out, bool constrained)
00944 : d_out(out), d_constrained(constrained)
00945 {}
00946 void operator()(BaseType *bt)
00947 {
00948 bt->print_xml(d_out, " ", d_constrained);
00949 }
00950 };
00951
00962 void
00963 DDS::print_xml(FILE *out, bool constrained, const string &blob)
00964 {
00965 fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
00966
00967 fprintf(out, "<Dataset name=\"%s\"\n", id2xml(name).c_str());
00968
00969 fprintf(out, "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
00970
00971 fprintf(out,"method=\"FILE*\"\n");
00972 fprintf(out, "dap_major=\"%d\"\n", get_dap_major());
00973 fprintf(out, "dap_minor=\"%d\"\n", get_dap_minor());
00974
00975
00976
00977 if (get_dap_major() == 3 && get_dap_minor() == 2) {
00978 fprintf(out, "xmlns=\"%s\"\n", c_dap32_namespace.c_str());
00979
00980 fprintf(out, "xsi:schemaLocation=\"%s %s\">\n\n",
00981 c_dap32_namespace.c_str(), c_default_dap32_schema_location.c_str());
00982 }
00983 else {
00984 fprintf(out, "xmlns=\"%s\"\n", c_dap20_namespace.c_str());
00985 fprintf(out, "xsi:schemaLocation=\"%s %s\">\n\n",
00986 c_dap20_namespace.c_str(), c_default_dap20_schema_location.c_str());
00987 }
00988
00989
00990 d_attr.print_xml(out, " ", constrained);
00991
00992 fprintf(out, "\n");
00993
00994 for_each(var_begin(), var_end(), VariablePrintXML(out, constrained));
00995
00996 fprintf(out, "\n");
00997
00998
00999
01000 if (get_dap_major() == 2 && get_dap_minor() == 0) {
01001 fprintf(out, " <dataBLOB href=\"\"/>\n");
01002 }
01003 else if (!blob.empty()
01004 && (get_dap_major() == 3 && get_dap_minor() >= 2)
01005 || get_dap_major() >= 4) {
01006 fprintf(out, " <blob href=\"cid:%s\"/>\n", blob.c_str());
01007 }
01008
01009
01010 fprintf(out, "</Dataset>\n");
01011 }
01012 #endif
01013
01014 class VariablePrintXMLStrm : public unary_function<BaseType *, void>
01015 {
01016 ostream &d_out;
01017 bool d_constrained;
01018 public:
01019 VariablePrintXMLStrm(ostream &out, bool constrained)
01020 : d_out(out), d_constrained(constrained)
01021 {}
01022 void operator()(BaseType *bt)
01023 {
01024 bt->print_xml(d_out, " ", d_constrained);
01025 }
01026 };
01027
01038 void
01039 DDS::print_xml(ostream &out, bool constrained, const string &blob)
01040 {
01041 out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ;
01042
01043 out << "<Dataset name=\"" << id2xml(name) << "\"\n" ;
01044
01045 out << "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" ;
01046
01047
01048
01049 if (get_dap_major() == 3 && get_dap_minor() == 2) {
01050 out << "xsi:schemaLocation=\"" << c_dap32_namespace
01051 << " " << c_default_dap32_schema_location << "\"\n" ;
01052
01053 out << "xmlns:grddl=\"http://www.w3.org/2003/g/data-view#\"\n";
01054 out << "grddl:transformation=\"" << grddl_transformation_dap32 <<"\"\n";
01055
01056 out << "xmlns=\"" << c_dap32_namespace << "\"\n" ;
01057 out << "xmlns:dap=\"" << c_dap32_namespace << "\"\n" ;
01058
01059 out << "dapVersion=\"" << get_dap_major() << "."
01060 << get_dap_minor() << "\"";
01061
01062 if (!get_request_xml_base().empty()) {
01063 out << "\n";
01064 out << "xmlns:xml=\"" << c_xml_namespace << "\"\n";
01065 out << "xml:base=\"" << get_request_xml_base() << "\"";
01066 }
01067
01068
01069 out << ">\n";
01070 }
01071 else {
01072 out << "xmlns=\"" << c_dap20_namespace << "\"\n" ;
01073 out << "xsi:schemaLocation=\"" << c_dap20_namespace
01074 << " " << c_default_dap20_schema_location << "\">\n\n" ;
01075 }
01076
01077 d_attr.print_xml(out, " ", constrained);
01078
01079 out << "\n" ;
01080
01081 for_each(var_begin(), var_end(), VariablePrintXMLStrm(out, constrained));
01082
01083 out << "\n" ;
01084
01085
01086
01087
01088
01089 if (get_dap_major() == 2 && get_dap_minor() == 0) {
01090 out << " <dataBLOB href=\"\"/>\n" ;
01091 }
01092 else if (!blob.empty()
01093 && (get_dap_major() == 3 && get_dap_minor() >= 2)
01094 || get_dap_major() >= 4) {
01095 out << " <blob href=\"cid:" << blob << "\"/>\n";
01096 }
01097
01098 out << "</Dataset>\n" ;
01099 }
01100
01101
01116 bool
01117 DDS::check_semantics(bool all)
01118 {
01119
01120 if (name == "") {
01121 cerr << "A dataset must have a name" << endl;
01122 return false;
01123 }
01124
01125 string msg;
01126 if (!unique_names(vars, name, "Dataset", msg))
01127 return false;
01128
01129 if (all)
01130 for (Vars_iter i = vars.begin(); i != vars.end(); i++)
01131 if (!(*i)->check_semantics(msg, true))
01132 return false;
01133
01134 return true;
01135 }
01136
01162 bool
01163 DDS::mark(const string &n, bool state)
01164 {
01165 BaseType::btp_stack *s = new BaseType::btp_stack;
01166
01167 DBG2(cerr << "DDS::mark: Looking for " << n << endl);
01168
01169 BaseType *variable = var(n, s);
01170 if (!variable) {
01171 DBG2(cerr << "Could not find variable " << n << endl);
01172 delete s; s = 0;
01173 return false;
01174 }
01175 variable->set_send_p(state);
01176
01177 DBG2(cerr << "DDS::mark: Set variable " << variable->name()
01178 << " (a " << variable->type_name() << ")" << endl);
01179
01180
01181
01182
01183
01184 while (!s->empty()) {
01185 s->top()->BaseType::set_send_p(state);
01186
01187 DBG2(cerr << "DDS::mark: Set variable " << s->top()->name()
01188 << " (a " << s->top()->type_name() << ")" << endl);
01189 string parent_name = (s->top()->get_parent()) ? s->top()->get_parent()->name(): "none";
01190 string parent_type = (s->top()->get_parent()) ? s->top()->get_parent()->type_name(): "none";
01191 DBG2(cerr << "DDS::mark: Parent variable " << parent_name << " (a " << parent_type << ")" << endl);
01192
01193 s->pop();
01194 }
01195
01196 delete s ; s = 0;
01197
01198 return true;
01199 }
01200
01206 void
01207 DDS::mark_all(bool state)
01208 {
01209 for (Vars_iter i = vars.begin(); i != vars.end(); i++)
01210 (*i)->set_send_p(state);
01211 }
01212
01220 void
01221 DDS::dump(ostream &strm) const
01222 {
01223 strm << DapIndent::LMarg << "DDS::dump - ("
01224 << (void *)this << ")" << endl ;
01225 DapIndent::Indent() ;
01226 strm << DapIndent::LMarg << "name: " << name << endl ;
01227 strm << DapIndent::LMarg << "filename: " << d_filename << endl ;
01228 strm << DapIndent::LMarg << "protocol major: " << d_dap_major << endl;
01229 strm << DapIndent::LMarg << "protocol minor: " << d_dap_minor << endl;
01230 strm << DapIndent::LMarg << "factory: " << (void *)d_factory << endl ;
01231
01232 strm << DapIndent::LMarg << "global attributes:" << endl ;
01233 DapIndent::Indent() ;
01234 d_attr.dump(strm) ;
01235 DapIndent::UnIndent() ;
01236
01237 if (vars.size()) {
01238 strm << DapIndent::LMarg << "vars:" << endl ;
01239 DapIndent::Indent() ;
01240 Vars_citer i = vars.begin() ;
01241 Vars_citer ie = vars.end() ;
01242 for (; i != ie; i++) {
01243 (*i)->dump(strm) ;
01244 }
01245 DapIndent::UnIndent() ;
01246 }
01247 else {
01248 strm << DapIndent::LMarg << "vars: none" << endl ;
01249 }
01250
01251 DapIndent::UnIndent() ;
01252 }
01253
01254 }