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