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 16088 2007-03-28 21:42:19Z jimg $"
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(can_not_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
00698 void
00699 DDS::print_constrained(FILE *out)
00700 {
00701 fprintf(out, "Dataset {\n") ;
00702
00703 for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
00704
00705
00706
00707 (*i)->print_decl(out, " ", true, false, true) ;
00708 }
00709
00710 fprintf(out, "} %s;\n", id2www(name).c_str()) ;
00711
00712 return;
00713 }
00714
00715 class VariablePrintXML : public unary_function<BaseType *, void>
00716 {
00717 FILE *d_out;
00718 bool d_constrained;
00719 public:
00720 VariablePrintXML(FILE *out, bool constrained)
00721 : d_out(out), d_constrained(constrained)
00722 {}
00723 void operator()(BaseType *bt)
00724 {
00725 bt->print_xml(d_out, " ", d_constrained);
00726 }
00727 };
00728
00739 void
00740 DDS::print_xml(FILE *out, bool constrained, const string &)
00741 {
00742 fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
00743
00744 fprintf(out, "<Dataset name=\"%s\"\n", id2xml(name).c_str());
00745
00746 fprintf(out, "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
00747 fprintf(out, "xmlns=\"%s\"\n", dods_namespace.c_str());
00748 fprintf(out, "xsi:schemaLocation=\"%s %s\">\n\n",
00749 dods_namespace.c_str(), default_schema_location.c_str());
00750
00751 d_attr.print_xml(out, " ", constrained);
00752
00753 fprintf(out, "\n");
00754
00755 for_each(var_begin(), var_end(), VariablePrintXML(out, constrained));
00756
00757 fprintf(out, "\n");
00758
00759 fprintf(out, " <dataBLOB href=\"\"/>\n");
00760
00761 fprintf(out, "</Dataset>\n");
00762 }
00763
00764
00779 bool
00780 DDS::check_semantics(bool all)
00781 {
00782
00783 if (name == "") {
00784 cerr << "A dataset must have a name" << endl;
00785 return false;
00786 }
00787
00788 string msg;
00789 if (!unique_names(vars, name, "Dataset", msg))
00790 return false;
00791
00792 if (all)
00793 for (Vars_iter i = vars.begin(); i != vars.end(); i++)
00794 if (!(*i)->check_semantics(msg, true))
00795 return false;
00796
00797 return true;
00798 }
00799
00825 bool
00826 DDS::mark(const string &n, bool state)
00827 {
00828 btp_stack *s = new btp_stack;
00829
00830 DBG2(cerr << "Looking for " << n << endl);
00831
00832 BaseType *variable = var(n, s);
00833 if (!variable) {
00834 DBG2(cerr << "Could not find variable " << n << endl);
00835 return false;
00836 }
00837 variable->set_send_p(state);
00838 DBG2(cerr << "Set variable " << variable->name() << endl);
00839
00840
00841
00842 while (!s->empty()) {
00843 s->top()->BaseType::set_send_p(state);
00844 DBG2(cerr << "Set variable " << s->top()->name() << endl);
00845 s->pop();
00846 }
00847
00848 delete s ; s = 0;
00849
00850 return true;
00851 }
00852
00858 void
00859 DDS::mark_all(bool state)
00860 {
00861 for (Vars_iter i = vars.begin(); i != vars.end(); i++)
00862 (*i)->set_send_p(state);
00863 }
00864
00872 void
00873 DDS::dump(ostream &strm) const
00874 {
00875 strm << DapIndent::LMarg << "DDS::dump - ("
00876 << (void *)this << ")" << endl ;
00877 DapIndent::Indent() ;
00878 strm << DapIndent::LMarg << "name: " << name << endl ;
00879 strm << DapIndent::LMarg << "filename: " << _filename << endl ;
00880 strm << DapIndent::LMarg << "protocol major: " << d_protocol_major << endl;
00881 strm << DapIndent::LMarg << "protocol minor: " << d_protocol_minor << endl;
00882 strm << DapIndent::LMarg << "factory: " << (void *)d_factory << endl ;
00883
00884 strm << DapIndent::LMarg << "global attributes:" << endl ;
00885 DapIndent::Indent() ;
00886 d_attr.dump(strm) ;
00887 DapIndent::UnIndent() ;
00888
00889 if (vars.size()) {
00890 strm << DapIndent::LMarg << "vars:" << endl ;
00891 DapIndent::Indent() ;
00892 Vars_citer i = vars.begin() ;
00893 Vars_citer ie = vars.end() ;
00894 for (; i != ie; i++) {
00895 (*i)->dump(strm) ;
00896 }
00897 DapIndent::UnIndent() ;
00898 }
00899 else {
00900 strm << DapIndent::LMarg << "vars: none" << endl ;
00901 }
00902
00903 DapIndent::UnIndent() ;
00904 }
00905
00907
00908
00909
00910 #if 0
00911 AttrTable::Attr_iter i = das->attr_begin();
00912 while (i != das->attr_end())
00913 {
00914
00915
00916
00917
00918
00919
00920 #if 0
00921 string::size_type dim_pos = (*i)->name.find("_dim_");
00922 #endif
00923 string sub_table = "";
00924 #if 0
00925 if (dim_pos != string::npos) {
00926 sub_table = (*i)->name.substr(dim_pos);
00927 (*i)->name = (*i)->name.substr(0, dim_pos);
00928 }
00929 #endif
00930 DBG(cerr << "DDS::transfer_attributes(DAS * das): sub table: "
00931 << sub_table << endl);
00932
00933 BaseType *btp = var((*i)->name);
00934 if (btp)
00935 transfer_attr(das, (*i), btp, sub_table);
00936 else
00937 add_global_attribute(*i);
00938
00939 ++i;
00940 }
00941 #endif
00942
00943
00944 #if 0
00945
00957 void
00958 DDS::transfer_attr(DAS *das, const AttrTable::entry *ep, BaseType *btp,
00959 const string &sub_table)
00960 {
00961 DBG(cerr << "DDS::transfer_attr: sub_table: " << sub_table << endl);
00962
00963 if (ep->is_alias) {
00964 AttrTable *source_table = das->get_attr_table(ep->aliased_to);
00965 AttrTable &dest = btp->get_attr_table();
00966 if (source_table)
00967 dest.add_container_alias(ep->name , source_table);
00968 else
00969 dest.add_value_alias(das, ep->name , ep->aliased_to);
00970 }
00971 else if (ep->type == Attr_container) {
00972 DBG(cerr << "ep-type == container, ep-<name: " << ep->name << endl);
00973
00974
00975 ep->attributes->set_name(ep->name);
00976 Constructor *c = dynamic_cast<Constructor*>(btp);
00977 if (c)
00978 transfer_attr_table(das, ep->attributes, c, sub_table);
00979 else
00980 transfer_attr_table(das, ep->attributes, btp, sub_table);
00981 }
00982 else {
00983 btp->get_attr_table().append_attr(ep->name, AttrType_to_String(ep->type),
00984 ep->attr);
00985 #if 0
00986 AttrTable &at = btp->get_attr_table();
00987 string n = ep->name ;
00988 string t = AttrType_to_String(ep->type);
00989 vector<string> *attrs = ep->attr;
00990 for (vector<string>::iterator i = attrs->begin(); i != attrs->end(); ++i)
00991 at.append_attr(n, t, *i);
00992 #endif
00993 }
00994 }
00995
01009 void
01010 DDS::transfer_attr_table(DAS *das, AttrTable *at, BaseType *btp,
01011 const string &sub_table)
01012 {
01013 DBG(cerr << "DDS::transfer_attr_table (BseType): sub_table: " << sub_table << endl);
01014
01015 if (at->get_name() == btp->name()) {
01016
01017
01018 if (!sub_table.empty()) {
01019 string tsub_table = sub_table;
01020 AttrTable *new_at = new AttrTable(*at);
01021
01022 if (sub_table.find('_') != string::npos) {
01023 tsub_table = tsub_table.substr(tsub_table.find('_') + 1);
01024 }
01025 btp->get_attr_table().append_container(new_at, tsub_table);
01026 }
01027 else {
01028
01029 for (AttrTable::Attr_iter i = at->attr_begin(); i != at->attr_end(); ++i)
01030 transfer_attr(das, *i, btp, "");
01031 }
01032 }
01033 else {
01034
01035
01036 AttrTable *new_at = new AttrTable(*at);
01037 btp->get_attr_table().append_container(new_at, at->get_name());
01038 }
01039 }
01040
01042 void
01043 DDS::transfer_attr_table(DAS *das, AttrTable *at, Constructor *c,
01044 const string &sub_table)
01045 {
01046 DBG(cerr << "DDS::transfer_attr_table: (Constructor) sub_table: "
01047 << sub_table << endl);
01048 for (AttrTable::Attr_iter i = at->attr_begin(); i != at->attr_end(); ++i) {
01049 AttrTable::entry *ep = *i;
01050 string n = ep->name;
01051 bool found = false;
01052
01053 switch (c->type()) {
01054 case dods_structure_c:
01055 case dods_sequence_c: {
01056 for (Constructor::Vars_iter j = c->var_begin(); j != c->var_end();
01057 ++j) {
01058 if (n == (*j)->name()) {
01059 found = true;
01060 transfer_attr(das, ep, *j, sub_table);
01061 }
01062 }
01063 break;
01064 }
01065
01066 case dods_grid_c: {
01067 Grid *g = dynamic_cast<Grid*>(c);
01068 if (n == g->get_array()->name()) {
01069 found = true;
01070 transfer_attr(das, ep, g->get_array(), sub_table);
01071 }
01072
01073 for (Grid::Map_iter j = g->map_begin(); j != g->map_end(); ++j) {
01074 if (n == (*j)->name()) {
01075 found = true;
01076 transfer_attr(das, ep, *j, sub_table);
01077 }
01078 }
01079 break;
01080 }
01081
01082 default:
01083 throw InternalErr(__FILE__, __LINE__, "Unknown type.");
01084 }
01085
01086 if (!found) {
01087 DBG(cerr << "Could not find a place in a constructor for " << sub_table
01088 << ", calling transfer_attr() without it." << endl);
01089 transfer_attr(das, ep, c);
01090 }
01091 }
01092 }
01093 #endif
01094 #if 0
01095
01103 bool
01104 DDS::is_global_attr(string name)
01105 {
01106 for (Vars_iter i = var_begin(); i != var_end(); ++i)
01107 if ((*i)->name() == name)
01108 return false;
01109
01110 return true;
01111 }
01112
01118 static inline bool
01119 is_in_kill_file(const string &name)
01120 {
01121 static Regex dim(".*_dim_[0-9]*");
01122
01123 return dim.match(name.c_str(), name.length()) != -1;
01124 }
01125
01132 void
01133 DDS::add_global_attribute(AttrTable::entry *entry)
01134 {
01135 string name = entry->name;
01136
01137 if (is_global_attr(name) && !is_in_kill_file(name)) {
01138 if (entry->type == Attr_container) {
01139 try {
01140
01141
01142
01143
01144 AttrTable *new_at = new AttrTable(*(entry->attributes));
01145 d_attr.append_container(new_at, name);
01146 }
01147 catch (Error &e) {
01148 DBG(cerr << "Error in DDS::global_attribute: "
01149 << e.get_error_message() << endl);
01150
01151
01152
01153
01154 }
01155 }
01156 }
01157 }
01158 #endif
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186 #if 0
01187
01188
01189
01190
01199 static AttrTable *
01200 search_for_attributes(const string &name, AttrTable *at, DAS *das)
01201 {
01202
01203 AttrTable *ptable = (at) ? at->find_container(name) : 0;
01204 if (!ptable && das)
01205 ptable = das->get_attr_table(name);
01206
01207 return ptable;
01208 }
01209
01217 void
01218 DDS::transfer_attr_to_constructor(Constructor *cp, AttrTable *at, DAS *das)
01219 {
01220 if (cp->type() != dods_grid_c) {
01221
01222 for (Constructor::Vars_iter i = cp->var_begin(); i != cp->var_end(); ++i) {
01223 AttrTable *ptable = search_for_attributes((*i)->name(), at, das);
01224 if (!ptable)
01225 continue;
01226
01227 if ((*i)->is_simple_type() || (*i)->is_vector_type()) {
01228 (*i)->set_attr_table(*ptable);
01229 }
01230 else {
01231 transfer_attr_to_constructor(dynamic_cast<Constructor*>(*i), ptable, das);
01232 }
01233 }
01234
01235
01236 if (at) {
01237 AttrTable tmp;
01238 for (AttrTable::Attr_iter p = at->attr_begin(); p != at->attr_end(); ++p) {
01239 if (!at->is_container(p)) {
01240 cp->get_attr_table().append_attr(at->get_name(p),
01241 at->get_type(p),
01242 at->get_attr_vector(p));
01243 }
01244 }
01245 }
01246 }
01247 else {
01248 Grid *g = dynamic_cast<Grid*>(cp);
01249 AttrTable *ptable = search_for_attributes(g->get_array()->name(), at, das);
01250 if (ptable)
01251 g->get_array()->set_attr_table(*ptable);
01252
01253 for (Grid::Map_iter i = g->map_begin(); i != g->map_end(); ++i) {
01254 AttrTable *ptable = search_for_attributes((*i)->name(), at, das);
01255 if (!ptable)
01256 continue;
01257
01258 (*i)->set_attr_table(*ptable);
01259 }
01260
01261
01262 if (at) {
01263 AttrTable tmp;
01264 for (AttrTable::Attr_iter p = at->attr_begin(); p != at->attr_end(); ++p) {
01265 if (!at->is_container(p)) {
01266 cp->get_attr_table().append_attr(at->get_name(p),
01267 at->get_type(p),
01268 at->get_attr_vector(p));
01269 }
01270 }
01271 }
01272 }
01273 }
01274
01275 void
01276 DDS::new_transfer_attributes(DAS * das)
01277 {
01278 for (Vars_iter i = var_begin(); i != var_end(); ++i) {
01279 AttrTable *at = das->get_attr_table((*i)->name());
01280
01281
01282
01283
01284
01285
01286
01287 if (at && ((*i)->is_simple_type() || (*i)->is_vector_type())) {
01288
01289
01290 (*i)->set_attr_table(*at);
01291 }
01292 else {
01293
01294 transfer_attr_to_constructor(dynamic_cast<Constructor*>(*i), at, das);
01295 }
01296 }
01297 }
01298 #endif