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 18315 2008-03-03 20:14:44Z 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 <algorithm>
00054 #include <functional>
00055
00056
00057
00058 #include "GNURegex.h"
00059
00060 #include "DAS.h"
00061 #include "Clause.h"
00062 #include "Error.h"
00063 #include "InternalErr.h"
00064
00065 #include "parser.h"
00066 #include "debug.h"
00067 #include "util.h"
00068 #include "escaping.h"
00069
00070 const string default_schema_location = "http://xml.opendap.org/dap/dap2.xsd";
00071 const string dods_namespace = "http://xml.opendap.org/ns/DAP2";
00072
00073 using namespace std;
00074
00075 void ddsrestart(FILE *yyin);
00076 int ddsparse(void *arg);
00077
00078
00079 void dds_switch_to_buffer(void *new_buffer);
00080 void dds_delete_buffer(void * buffer);
00081 void *dds_buffer(FILE *fp);
00082
00083 namespace libdap {
00084
00085 void
00086 DDS::duplicate(const DDS &dds)
00087 {
00088 name = dds.name;
00089 d_factory = dds.d_factory;
00090
00091 DDS &dds_tmp = const_cast<DDS &>(dds);
00092
00093
00094 for (Vars_iter i = dds_tmp.var_begin(); i != dds_tmp.var_end(); i++) {
00095 add_var(*i);
00096 }
00097 }
00098
00109 DDS::DDS(BaseTypeFactory *factory, const string &n)
00110 : d_factory(factory), name(n), d_timeout(0)
00111 {}
00112
00114 DDS::DDS(const DDS &rhs) : DapObj()
00115 {
00116 duplicate(rhs);
00117 }
00118
00119 DDS::~DDS()
00120 {
00121
00122 for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
00123 BaseType *btp = *i ;
00124 delete btp ; btp = 0;
00125 }
00126 }
00127
00128 DDS &
00129 DDS::operator=(const DDS &rhs)
00130 {
00131 if (this == &rhs)
00132 return *this;
00133
00134 duplicate(rhs);
00135
00136 return *this;
00137 }
00138
00154 BaseType *
00155 DDS::find_hdf4_dimension_attribute_home(AttrTable::entry *source)
00156 {
00157 BaseType *btp;
00158 string::size_type i = source->name.find("_dim_");
00159 if (i != string::npos && (btp = var(source->name.substr(0, i)))) {
00160 if (btp->is_vector_type()) {
00161 return btp;
00162 }
00163 else if (btp->type() == dods_grid_c) {
00164
00165
00166 int n = atoi(source->name.substr(i + 5).c_str());
00167 DBG(cerr << "Found a Grid (" << btp->name() << ") and "
00168 << source->name.substr(i) << ", extracted n: " << n << endl);
00169 return *(dynamic_cast<Grid&>(*btp).map_begin() + n);
00170 }
00171 }
00172
00173 return 0;
00174 }
00175
00181 AttrTable *
00182 DDS::find_matching_container(AttrTable::entry *source, BaseType **dest_variable)
00183 {
00184
00185 if (source->type != Attr_container)
00186 throw InternalErr(__FILE__, __LINE__, "DDS::find_matching_container");
00187
00188
00189
00190 BaseType *btp;
00191 if ((btp = var(source->name))) {
00192
00193 *dest_variable = btp;
00194 return &btp->get_attr_table();
00195 }
00196 else if ((btp = find_hdf4_dimension_attribute_home(source))) {
00197
00198
00199 if (btp->get_parent() && btp->get_parent()->type() == dods_grid_c) {
00200 DBG(cerr << "Found a Grid, assigning to the map" << endl);
00201 *dest_variable = btp;
00202 return &btp->get_attr_table();
00203 }
00204 else {
00205 string::size_type i = source->name.find("_dim_");
00206 string ext = source->name.substr(i + 1);
00207 *dest_variable = btp;
00208 return btp->get_attr_table().append_container(ext);
00209 }
00210 }
00211 else {
00212
00213 AttrTable *at = d_attr.find_container(source->name);
00214 if (!at) {
00215 at = new AttrTable();
00216 d_attr.append_container(at, source->name);
00217 }
00218
00219 *dest_variable = 0;
00220 return at;
00221 }
00222 }
00223
00245 void
00246 DDS::transfer_attributes(DAS * das)
00247 {
00248
00249 AttrTable::Attr_iter das_i = das->attr_begin();
00250 while (das_i != das->attr_end()) {
00251 DBG(cerr << "Working on the '" << (*das_i)->name << "' container."
00252 << endl);
00253
00254 AttrTable *source = (*das_i)->attributes;
00255
00256 BaseType *dest_variable = 0;
00257 AttrTable *dest = find_matching_container(*das_i, &dest_variable);
00258
00259
00260 AttrTable::Attr_iter source_p = source->attr_begin();
00261 while (source_p != source->attr_end()) {
00262 DBG(cerr << "Working on the '" << (*source_p)->name << "' attribute"
00263 << endl);
00264
00265
00266
00267
00268
00269 if ((*source_p)->type == Attr_container) {
00270 if (dest_variable && dest_variable->is_constructor_type()) {
00271 dynamic_cast<Constructor&>(*dest_variable).transfer_attributes(*source_p);
00272 }
00273 else {
00274 dest->append_container(new AttrTable(*(*source_p)->attributes),
00275 (*source_p)->name);
00276 }
00277 }
00278 else {
00279 dest->append_attr(source->get_name(source_p),
00280 source->get_type(source_p),
00281 source->get_attr_vector(source_p));
00282 }
00283
00284 ++source_p;
00285 }
00286
00287 ++das_i;
00288 }
00289 }
00290
00298
00300 string
00301 DDS::get_dataset_name() const
00302 {
00303 return name;
00304 }
00305
00307 void
00308 DDS::set_dataset_name(const string &n)
00309 {
00310 name = n;
00311 }
00312
00314
00316 AttrTable &
00317 DDS::get_attr_table()
00318 {
00319 return d_attr;
00320 }
00321
00331 string
00332 DDS::filename()
00333 {
00334 return _filename;
00335 }
00336
00338 void
00339 DDS::filename(const string &fn)
00340 {
00341 _filename = fn;
00342 }
00344
00350 void
00351 DDS::add_var(BaseType *bt)
00352 {
00353 if (!bt)
00354 throw InternalErr(__FILE__, __LINE__,
00355 "Trying to add a BaseType object with a NULL pointer.");
00356
00357 DBG2(cerr << "In DDS::add_var(), bt's address is: " << bt << endl);
00358
00359 BaseType *btp = bt->ptr_duplicate();
00360 DBG2(cerr << "In DDS::add_var(), btp's address is: " << btp << endl);
00361 vars.push_back(btp);
00362 }
00363
00370 void
00371 DDS::del_var(const string &n)
00372 {
00373 for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
00374 if ((*i)->name() == n) {
00375 BaseType *bt = *i ;
00376 vars.erase(i) ;
00377 delete bt ; bt = 0;
00378 return;
00379 }
00380 }
00381 }
00382
00387 void
00388 DDS::del_var(Vars_iter i)
00389 {
00390 if (i != vars.end()) {
00391 BaseType *bt = *i ;
00392 vars.erase(i) ;
00393 delete bt ; bt = 0;
00394 }
00395 }
00396
00403 void
00404 DDS::del_var(Vars_iter i1, Vars_iter i2)
00405 {
00406 for (Vars_iter i_tmp = i1; i_tmp != i2; i_tmp++) {
00407 BaseType *bt = *i_tmp ;
00408 delete bt ; bt = 0;
00409 }
00410 vars.erase(i1, i2) ;
00411 }
00412
00420 BaseType *
00421 DDS::var(const string &n, BaseType::btp_stack &s)
00422 {
00423 return var(n, &s);
00424 }
00444 BaseType *
00445 DDS::var(const string &n, BaseType::btp_stack *s)
00446 {
00447 string name = www2id(n);
00448 BaseType *v = exact_match(name, s);
00449 if (v)
00450 return v;
00451
00452 return leaf_match(name, s);
00453 }
00454
00455 BaseType *
00456 DDS::leaf_match(const string &n, BaseType::btp_stack *s)
00457 {
00458 for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
00459 BaseType *btp = *i;
00460 DBG2(cerr << "Looking at " << n << " in: " << btp << endl);
00461
00462 if (btp->name() == n) {
00463 DBG2(cerr << "Found " << n << " in: " << btp << endl);
00464 return btp;
00465 }
00466 if (btp->is_constructor_type() && (btp = btp->var(n, false, s))) {
00467 return btp;
00468 }
00469 }
00470
00471 return 0;
00472 }
00473
00474 BaseType *
00475 DDS::exact_match(const string &name, BaseType::btp_stack *s)
00476 {
00477 for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
00478 BaseType *btp = *i;
00479 DBG2(cerr << "Looking for " << name << " in: " << btp << endl);
00480
00481 if (btp->name() == name) {
00482 DBG2(cerr << "Found " << name << " in: " << btp << endl);
00483 return btp;
00484 }
00485 }
00486
00487 string::size_type dot_pos = name.find(".");
00488 if (dot_pos != string::npos) {
00489 string aggregate = name.substr(0, dot_pos);
00490 string field = name.substr(dot_pos + 1);
00491
00492 BaseType *agg_ptr = var(aggregate, s);
00493 if (agg_ptr) {
00494 DBG2(cerr << "Descending into " << agg_ptr->name() << endl);
00495 return agg_ptr->var(field, true, s);
00496 }
00497 else
00498 return 0;
00499 }
00500
00501 return 0;
00502 }
00503
00504
00507 DDS::Vars_iter
00508 DDS::var_begin()
00509 {
00510 return vars.begin();
00511 }
00512
00513 DDS::Vars_riter
00514 DDS::var_rbegin()
00515 {
00516 return vars.rbegin();
00517 }
00518
00519 DDS::Vars_iter
00520 DDS::var_end()
00521 {
00522 return vars.end() ;
00523 }
00524
00525 DDS::Vars_riter
00526 DDS::var_rend()
00527 {
00528 return vars.rend() ;
00529 }
00530
00534 DDS::Vars_iter
00535 DDS::get_vars_iter(int i)
00536 {
00537 return vars.begin() + i;
00538 }
00539
00543 BaseType *
00544 DDS::get_var_index(int i)
00545 {
00546 return *(vars.begin() + i);
00547 }
00548
00550 int
00551 DDS::num_var()
00552 {
00553 return vars.size();
00554 }
00555
00556 void
00557 DDS::timeout_on()
00558 {
00559 #ifndef WIN32
00560 alarm(d_timeout);
00561 #endif
00562 }
00563
00564 void
00565 DDS::timeout_off()
00566 {
00567 #ifndef WIN32
00568 d_timeout = alarm(0);
00569 #endif
00570 }
00571
00572 void
00573 DDS::set_timeout(int t)
00574 {
00575
00576 d_timeout = t;
00577 }
00578
00579 int
00580 DDS::get_timeout()
00581 {
00582
00583 return d_timeout;
00584 }
00585
00587 void
00588 DDS::tag_nested_sequences()
00589 {
00590 for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
00591 if ((*i)->type() == dods_sequence_c)
00592 dynamic_cast<Sequence&>(**i).set_leaf_sequence();
00593 else if ((*i)->type() == dods_structure_c)
00594 dynamic_cast<Structure&>(**i).set_leaf_sequence();
00595 }
00596 }
00597
00599 void
00600 DDS::parse(string fname)
00601 {
00602 FILE *in = fopen(fname.c_str(), "r");
00603
00604 if (!in) {
00605 throw Error(cannot_read_file, "Could not open: " + fname);
00606 }
00607
00608 try {
00609 parse(in);
00610 fclose(in);
00611 }
00612 catch (Error &e) {
00613 fclose(in);
00614 throw e;
00615 }
00616 }
00617
00618
00620 void
00621 DDS::parse(int fd)
00622 {
00623 #ifdef WIN32
00624 FILE *in = fdopen(_dup(fd), "r");
00625 #else
00626 FILE *in = fdopen(dup(fd), "r");
00627 #endif
00628
00629 if (!in) {
00630 throw InternalErr(__FILE__, __LINE__, "Could not access file.");
00631 }
00632
00633 try {
00634 parse(in);
00635 fclose(in);
00636 }
00637 catch (Error &e) {
00638 fclose(in);
00639 throw e;
00640 }
00641 }
00642
00649 void
00650 DDS::parse(FILE *in)
00651 {
00652 if (!in) {
00653 throw InternalErr(__FILE__, __LINE__, "Null input stream.");
00654 }
00655
00656 void *buffer = dds_buffer(in);
00657 dds_switch_to_buffer(buffer);
00658
00659 parser_arg arg(this);
00660
00661 bool status = ddsparse((void *) & arg) == 0;
00662
00663 dds_delete_buffer(buffer);
00664
00665 DBG2(cout << "Status from parser: " << status << endl);
00666
00667
00668
00669 if (!status || !arg.status()) {
00670 if (arg.error())
00671 throw *arg.error();
00672 }
00673 }
00674
00676 void
00677 DDS::print(FILE *out)
00678 {
00679 fprintf(out, "Dataset {\n") ;
00680
00681 for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
00682 (*i)->print_decl(out) ;
00683 }
00684
00685 fprintf(out, "} %s;\n", id2www(name).c_str()) ;
00686
00687 return ;
00688 }
00689
00691 void
00692 DDS::print(ostream &out)
00693 {
00694 out << "Dataset {\n" ;
00695
00696 for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
00697 (*i)->print_decl(out) ;
00698 }
00699
00700 out << "} " << id2www(name) << ";\n" ;
00701
00702 return ;
00703 }
00704
00715 void
00716 DDS::print_constrained(FILE *out)
00717 {
00718 fprintf(out, "Dataset {\n") ;
00719
00720 for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
00721
00722
00723
00724 (*i)->print_decl(out, " ", true, false, true) ;
00725 }
00726
00727 fprintf(out, "} %s;\n", id2www(name).c_str()) ;
00728
00729 return;
00730 }
00731
00742 void
00743 DDS::print_constrained(ostream &out)
00744 {
00745 out << "Dataset {\n" ;
00746
00747 for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
00748
00749
00750
00751 (*i)->print_decl(out, " ", true, false, true) ;
00752 }
00753
00754 out << "} " << id2www(name) << ";\n" ;
00755
00756 return;
00757 }
00758
00759 class VariablePrintXML : public unary_function<BaseType *, void>
00760 {
00761 FILE *d_out;
00762 bool d_constrained;
00763 public:
00764 VariablePrintXML(FILE *out, bool constrained)
00765 : d_out(out), d_constrained(constrained)
00766 {}
00767 void operator()(BaseType *bt)
00768 {
00769 bt->print_xml(d_out, " ", d_constrained);
00770 }
00771 };
00772
00783 void
00784 DDS::print_xml(FILE *out, bool constrained, const string &)
00785 {
00786 fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
00787
00788 fprintf(out, "<Dataset name=\"%s\"\n", id2xml(name).c_str());
00789
00790 fprintf(out, "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
00791 fprintf(out, "xmlns=\"%s\"\n", dods_namespace.c_str());
00792 fprintf(out, "xsi:schemaLocation=\"%s %s\">\n\n",
00793 dods_namespace.c_str(), default_schema_location.c_str());
00794
00795 d_attr.print_xml(out, " ", constrained);
00796
00797 fprintf(out, "\n");
00798
00799 for_each(var_begin(), var_end(), VariablePrintXML(out, constrained));
00800
00801 fprintf(out, "\n");
00802
00803 fprintf(out, " <dataBLOB href=\"\"/>\n");
00804
00805 fprintf(out, "</Dataset>\n");
00806 }
00807
00808 class VariablePrintXMLStrm : public unary_function<BaseType *, void>
00809 {
00810 ostream &d_out;
00811 bool d_constrained;
00812 public:
00813 VariablePrintXMLStrm(ostream &out, bool constrained)
00814 : d_out(out), d_constrained(constrained)
00815 {}
00816 void operator()(BaseType *bt)
00817 {
00818 bt->print_xml(d_out, " ", d_constrained);
00819 }
00820 };
00821
00832 void
00833 DDS::print_xml(ostream &out, bool constrained, const string &)
00834 {
00835 out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ;
00836
00837 out << "<Dataset name=\"" << id2xml(name) << "\"\n" ;
00838
00839 out << "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" ;
00840 out << "xmlns=\"" << dods_namespace << "\"\n" ;
00841 out << "xsi:schemaLocation=\"" << dods_namespace
00842 << " " << default_schema_location << "\">\n\n" ;
00843
00844 d_attr.print_xml(out, " ", constrained);
00845
00846 out << "\n" ;
00847
00848 for_each(var_begin(), var_end(), VariablePrintXMLStrm(out, constrained));
00849
00850 out << "\n" ;
00851
00852 out << " <dataBLOB href=\"\"/>\n" ;
00853
00854 out << "</Dataset>\n" ;
00855 }
00856
00857
00872 bool
00873 DDS::check_semantics(bool all)
00874 {
00875
00876 if (name == "") {
00877 cerr << "A dataset must have a name" << endl;
00878 return false;
00879 }
00880
00881 string msg;
00882 if (!unique_names(vars, name, "Dataset", msg))
00883 return false;
00884
00885 if (all)
00886 for (Vars_iter i = vars.begin(); i != vars.end(); i++)
00887 if (!(*i)->check_semantics(msg, true))
00888 return false;
00889
00890 return true;
00891 }
00892
00918 bool
00919 DDS::mark(const string &n, bool state)
00920 {
00921 BaseType::btp_stack *s = new BaseType::btp_stack;
00922
00923 DBG2(cerr << "Looking for " << n << endl);
00924
00925 BaseType *variable = var(n, s);
00926 if (!variable) {
00927 DBG2(cerr << "Could not find variable " << n << endl);
00928 delete s; s = 0;
00929 return false;
00930 }
00931 variable->set_send_p(state);
00932 DBG2(cerr << "Set variable " << variable->name() << endl);
00933
00934
00935
00936 while (!s->empty()) {
00937 s->top()->BaseType::set_send_p(state);
00938 DBG2(cerr << "Set variable " << s->top()->name() << endl);
00939 s->pop();
00940 }
00941
00942 delete s ; s = 0;
00943
00944 return true;
00945 }
00946
00952 void
00953 DDS::mark_all(bool state)
00954 {
00955 for (Vars_iter i = vars.begin(); i != vars.end(); i++)
00956 (*i)->set_send_p(state);
00957 }
00958
00966 void
00967 DDS::dump(ostream &strm) const
00968 {
00969 strm << DapIndent::LMarg << "DDS::dump - ("
00970 << (void *)this << ")" << endl ;
00971 DapIndent::Indent() ;
00972 strm << DapIndent::LMarg << "name: " << name << endl ;
00973 strm << DapIndent::LMarg << "filename: " << _filename << endl ;
00974 strm << DapIndent::LMarg << "protocol major: " << d_protocol_major << endl;
00975 strm << DapIndent::LMarg << "protocol minor: " << d_protocol_minor << endl;
00976 strm << DapIndent::LMarg << "factory: " << (void *)d_factory << endl ;
00977
00978 strm << DapIndent::LMarg << "global attributes:" << endl ;
00979 DapIndent::Indent() ;
00980 d_attr.dump(strm) ;
00981 DapIndent::UnIndent() ;
00982
00983 if (vars.size()) {
00984 strm << DapIndent::LMarg << "vars:" << endl ;
00985 DapIndent::Indent() ;
00986 Vars_citer i = vars.begin() ;
00987 Vars_citer ie = vars.end() ;
00988 for (; i != ie; i++) {
00989 (*i)->dump(strm) ;
00990 }
00991 DapIndent::UnIndent() ;
00992 }
00993 else {
00994 strm << DapIndent::LMarg << "vars: none" << endl ;
00995 }
00996
00997 DapIndent::UnIndent() ;
00998 }
00999
01001
01002
01003
01004 #if 0
01005 AttrTable::Attr_iter i = das->attr_begin();
01006 while (i != das->attr_end())
01007 {
01008
01009
01010
01011
01012
01013
01014 #if 0
01015 string::size_type dim_pos = (*i)->name.find("_dim_");
01016 #endif
01017 string sub_table = "";
01018 #if 0
01019 if (dim_pos != string::npos) {
01020 sub_table = (*i)->name.substr(dim_pos);
01021 (*i)->name = (*i)->name.substr(0, dim_pos);
01022 }
01023 #endif
01024 DBG(cerr << "DDS::transfer_attributes(DAS * das): sub table: "
01025 << sub_table << endl);
01026
01027 BaseType *btp = var((*i)->name);
01028 if (btp)
01029 transfer_attr(das, (*i), btp, sub_table);
01030 else
01031 add_global_attribute(*i);
01032
01033 ++i;
01034 }
01035 #endif
01036
01037
01038 #if 0
01039
01051 void
01052 DDS::transfer_attr(DAS *das, const AttrTable::entry *ep, BaseType *btp,
01053 const string &sub_table)
01054 {
01055 DBG(cerr << "DDS::transfer_attr: sub_table: " << sub_table << endl);
01056
01057 if (ep->is_alias) {
01058 AttrTable *source_table = das->get_attr_table(ep->aliased_to);
01059 AttrTable &dest = btp->get_attr_table();
01060 if (source_table)
01061 dest.add_container_alias(ep->name , source_table);
01062 else
01063 dest.add_value_alias(das, ep->name , ep->aliased_to);
01064 }
01065 else if (ep->type == Attr_container) {
01066 DBG(cerr << "ep-type == container, ep-<name: " << ep->name << endl);
01067
01068
01069 ep->attributes->set_name(ep->name);
01070 Constructor *c = dynamic_cast<Constructor*>(btp);
01071 if (c)
01072 transfer_attr_table(das, ep->attributes, c, sub_table);
01073 else
01074 transfer_attr_table(das, ep->attributes, btp, sub_table);
01075 }
01076 else {
01077 btp->get_attr_table().append_attr(ep->name, AttrType_to_String(ep->type),
01078 ep->attr);
01079 #if 0
01080 AttrTable &at = btp->get_attr_table();
01081 string n = ep->name ;
01082 string t = AttrType_to_String(ep->type);
01083 vector<string> *attrs = ep->attr;
01084 for (vector<string>::iterator i = attrs->begin(); i != attrs->end(); ++i)
01085 at.append_attr(n, t, *i);
01086 #endif
01087 }
01088 }
01089
01103 void
01104 DDS::transfer_attr_table(DAS *das, AttrTable *at, BaseType *btp,
01105 const string &sub_table)
01106 {
01107 DBG(cerr << "DDS::transfer_attr_table (BseType): sub_table: " << sub_table << endl);
01108
01109 if (at->get_name() == btp->name()) {
01110
01111
01112 if (!sub_table.empty()) {
01113 string tsub_table = sub_table;
01114 AttrTable *new_at = new AttrTable(*at);
01115
01116 if (sub_table.find('_') != string::npos) {
01117 tsub_table = tsub_table.substr(tsub_table.find('_') + 1);
01118 }
01119 btp->get_attr_table().append_container(new_at, tsub_table);
01120 }
01121 else {
01122
01123 for (AttrTable::Attr_iter i = at->attr_begin(); i != at->attr_end(); ++i)
01124 transfer_attr(das, *i, btp, "");
01125 }
01126 }
01127 else {
01128
01129
01130 AttrTable *new_at = new AttrTable(*at);
01131 btp->get_attr_table().append_container(new_at, at->get_name());
01132 }
01133 }
01134
01136 void
01137 DDS::transfer_attr_table(DAS *das, AttrTable *at, Constructor *c,
01138 const string &sub_table)
01139 {
01140 DBG(cerr << "DDS::transfer_attr_table: (Constructor) sub_table: "
01141 << sub_table << endl);
01142 for (AttrTable::Attr_iter i = at->attr_begin(); i != at->attr_end(); ++i) {
01143 AttrTable::entry *ep = *i;
01144 string n = ep->name;
01145 bool found = false;
01146
01147 switch (c->type()) {
01148 case dods_structure_c:
01149 case dods_sequence_c: {
01150 for (Constructor::Vars_iter j = c->var_begin(); j != c->var_end();
01151 ++j) {
01152 if (n == (*j)->name()) {
01153 found = true;
01154 transfer_attr(das, ep, *j, sub_table);
01155 }
01156 }
01157 break;
01158 }
01159
01160 case dods_grid_c: {
01161 Grid *g = dynamic_cast<Grid*>(c);
01162 if (n == g->get_array()->name()) {
01163 found = true;
01164 transfer_attr(das, ep, g->get_array(), sub_table);
01165 }
01166
01167 for (Grid::Map_iter j = g->map_begin(); j != g->map_end(); ++j) {
01168 if (n == (*j)->name()) {
01169 found = true;
01170 transfer_attr(das, ep, *j, sub_table);
01171 }
01172 }
01173 break;
01174 }
01175
01176 default:
01177 throw InternalErr(__FILE__, __LINE__, "Unknown type.");
01178 }
01179
01180 if (!found) {
01181 DBG(cerr << "Could not find a place in a constructor for " << sub_table
01182 << ", calling transfer_attr() without it." << endl);
01183 transfer_attr(das, ep, c);
01184 }
01185 }
01186 }
01187 #endif
01188 #if 0
01189
01197 bool
01198 DDS::is_global_attr(string name)
01199 {
01200 for (Vars_iter i = var_begin(); i != var_end(); ++i)
01201 if ((*i)->name() == name)
01202 return false;
01203
01204 return true;
01205 }
01206
01212 static inline bool
01213 is_in_kill_file(const string &name)
01214 {
01215 static Regex dim(".*_dim_[0-9]*");
01216
01217 return dim.match(name.c_str(), name.length()) != -1;
01218 }
01219
01226 void
01227 DDS::add_global_attribute(AttrTable::entry *entry)
01228 {
01229 string name = entry->name;
01230
01231 if (is_global_attr(name) && !is_in_kill_file(name)) {
01232 if (entry->type == Attr_container) {
01233 try {
01234
01235
01236
01237
01238 AttrTable *new_at = new AttrTable(*(entry->attributes));
01239 d_attr.append_container(new_at, name);
01240 }
01241 catch (Error &e) {
01242 DBG(cerr << "Error in DDS::global_attribute: "
01243 << e.get_error_message() << endl);
01244
01245
01246
01247
01248 }
01249 }
01250 }
01251 }
01252 #endif
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280 #if 0
01281
01282
01283
01284
01293 static AttrTable *
01294 search_for_attributes(const string &name, AttrTable *at, DAS *das)
01295 {
01296
01297 AttrTable *ptable = (at) ? at->find_container(name) : 0;
01298 if (!ptable && das)
01299 ptable = das->get_attr_table(name);
01300
01301 return ptable;
01302 }
01303
01311 void
01312 DDS::transfer_attr_to_constructor(Constructor *cp, AttrTable *at, DAS *das)
01313 {
01314 if (cp->type() != dods_grid_c) {
01315
01316 for (Constructor::Vars_iter i = cp->var_begin(); i != cp->var_end(); ++i) {
01317 AttrTable *ptable = search_for_attributes((*i)->name(), at, das);
01318 if (!ptable)
01319 continue;
01320
01321 if ((*i)->is_simple_type() || (*i)->is_vector_type()) {
01322 (*i)->set_attr_table(*ptable);
01323 }
01324 else {
01325 transfer_attr_to_constructor(dynamic_cast<Constructor*>(*i), ptable, das);
01326 }
01327 }
01328
01329
01330 if (at) {
01331 AttrTable tmp;
01332 for (AttrTable::Attr_iter p = at->attr_begin(); p != at->attr_end(); ++p) {
01333 if (!at->is_container(p)) {
01334 cp->get_attr_table().append_attr(at->get_name(p),
01335 at->get_type(p),
01336 at->get_attr_vector(p));
01337 }
01338 }
01339 }
01340 }
01341 else {
01342 Grid *g = dynamic_cast<Grid*>(cp);
01343 AttrTable *ptable = search_for_attributes(g->get_array()->name(), at, das);
01344 if (ptable)
01345 g->get_array()->set_attr_table(*ptable);
01346
01347 for (Grid::Map_iter i = g->map_begin(); i != g->map_end(); ++i) {
01348 AttrTable *ptable = search_for_attributes((*i)->name(), at, das);
01349 if (!ptable)
01350 continue;
01351
01352 (*i)->set_attr_table(*ptable);
01353 }
01354
01355
01356 if (at) {
01357 AttrTable tmp;
01358 for (AttrTable::Attr_iter p = at->attr_begin(); p != at->attr_end(); ++p) {
01359 if (!at->is_container(p)) {
01360 cp->get_attr_table().append_attr(at->get_name(p),
01361 at->get_type(p),
01362 at->get_attr_vector(p));
01363 }
01364 }
01365 }
01366 }
01367 }
01368
01369 void
01370 DDS::new_transfer_attributes(DAS * das)
01371 {
01372 for (Vars_iter i = var_begin(); i != var_end(); ++i) {
01373 AttrTable *at = das->get_attr_table((*i)->name());
01374
01375
01376
01377
01378
01379
01380
01381 if (at && ((*i)->is_simple_type() || (*i)->is_vector_type())) {
01382
01383
01384 (*i)->set_attr_table(*at);
01385 }
01386 else {
01387
01388 transfer_attr_to_constructor(dynamic_cast<Constructor*>(*i), at, das);
01389 }
01390 }
01391 }
01392 #endif
01393
01394 }