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
00035
00036 #include "config.h"
00037
00038 #include <functional>
00039 #include <algorithm>
00040
00041 #include "Grid.h"
00042 #include "DDS.h"
00043 #include "Array.h"
00044 #include "util.h"
00045 #include "InternalErr.h"
00046 #include "escaping.h"
00047
00048
00049
00050 using namespace std;
00051
00052 namespace libdap {
00053
00054 void
00055 Grid::_duplicate(const Grid &s)
00056 {
00057 _array_var = s._array_var->ptr_duplicate();
00058 _array_var->set_parent(this);
00059
00060 Grid &cs = const_cast<Grid &>(s);
00061
00062 for (Map_iter i = cs._map_vars.begin(); i != cs._map_vars.end(); i++) {
00063 BaseType *btp = (*i)->ptr_duplicate();
00064 btp->set_parent(this);
00065 _map_vars.push_back(btp);
00066 }
00067 }
00068
00078 Grid::Grid(const string &n) : Constructor(n, dods_grid_c), _array_var(0)
00079 {}
00080
00082 Grid::Grid(const Grid &rhs) : Constructor(rhs)
00083 {
00084 _duplicate(rhs);
00085 }
00086
00087 Grid::~Grid()
00088 {
00089 delete _array_var; _array_var = 0;
00090
00091 for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
00092 BaseType *btp = *i ;
00093 delete btp ; btp = 0;
00094 }
00095 }
00096
00097 BaseType *
00098 Grid::ptr_duplicate()
00099 {
00100 return new Grid(*this);
00101 }
00102
00103 Grid &
00104 Grid::operator=(const Grid &rhs)
00105 {
00106 if (this == &rhs)
00107 return *this;
00108
00109 delete _array_var; _array_var = 0;
00110
00111 for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
00112 BaseType *btp = *i ;
00113 delete btp ;
00114 }
00115
00116 dynamic_cast<Constructor &>(*this) = rhs;
00117
00118 _duplicate(rhs);
00119
00120 return *this;
00121 }
00122
00123 int
00124 Grid::element_count(bool leaves)
00125 {
00126 if (!leaves)
00127 return _map_vars.size() + 1;
00128 else {
00129 int i = 0;
00130 for (Map_iter j = _map_vars.begin(); j != _map_vars.end(); j++) {
00131 j += (*j)->element_count(leaves);
00132 }
00133
00134 i += get_array()->element_count(leaves);
00135 return i;
00136 }
00137 }
00138
00139 void
00140 Grid::set_send_p(bool state)
00141 {
00142 _array_var->set_send_p(state);
00143
00144 for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
00145 (*i)->set_send_p(state);
00146 }
00147
00148 BaseType::set_send_p(state);
00149 }
00150
00151 void
00152 Grid::set_read_p(bool state)
00153 {
00154 _array_var->set_read_p(state);
00155
00156 for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
00157 (*i)->set_read_p(state);
00158 }
00159
00160 BaseType::set_read_p(state);
00161 }
00162
00163 void
00164 Grid::set_in_selection(bool state)
00165 {
00166 _array_var->set_in_selection(state);
00167
00168 for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
00169 (*i)->set_in_selection(state);
00170 }
00171
00172 BaseType::set_in_selection(state);
00173 }
00174
00175 unsigned int
00176 Grid::width()
00177 {
00178 unsigned int sz = _array_var->width();
00179
00180 for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
00181 sz += (*i)->width();
00182 }
00183
00184 return sz;
00185 }
00186
00187 void
00188 Grid::intern_data(const string &dataset, ConstraintEvaluator &eval, DDS &dds)
00189 {
00190 dds.timeout_on();
00191
00192 if (!read_p())
00193 read(dataset);
00194
00195 dds.timeout_off();
00196
00197 if (_array_var->send_p())
00198 _array_var->intern_data(dataset, eval, dds);
00199
00200 for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
00201 if ((*i)->send_p()) {
00202 (*i)->intern_data(dataset, eval, dds);
00203 }
00204 }
00205 }
00206
00207 bool
00208 Grid::serialize(const string &dataset, ConstraintEvaluator &eval, DDS &dds,
00209 Marshaller &m, bool ce_eval)
00210 {
00211 dds.timeout_on();
00212
00213
00214
00215
00216
00217 if (!read_p())
00218 read(dataset);
00219
00220 #if EVAL
00221 if (ce_eval && !eval.eval_selection(dds, dataset))
00222 return true;
00223 #endif
00224
00225 dds.timeout_off();
00226
00227 if (_array_var->send_p())
00228 _array_var->serialize(dataset, eval, dds, m, false);
00229
00230 for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
00231 if ((*i)->send_p()) {
00232 (*i)->serialize(dataset, eval, dds, m, false);
00233 }
00234 }
00235
00236 return true;
00237 }
00238
00239 bool
00240 Grid::deserialize(UnMarshaller &um, DDS *dds, bool reuse)
00241 {
00242 _array_var->deserialize(um, dds, reuse);
00243
00244 for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
00245 (*i)->deserialize(um, dds, reuse);
00246 }
00247
00248 return false;
00249 }
00250
00258 unsigned int
00259 Grid::val2buf(void *, bool)
00260 {
00261 return sizeof(Grid);
00262 }
00263
00267 unsigned int
00268 Grid::buf2val(void **)
00269 {
00270 return sizeof(Grid);
00271 }
00272
00273 BaseType *
00274 Grid::var(const string &n, btp_stack &s)
00275 {
00276 return var(n, true, &s);
00277 }
00278
00283 BaseType *
00284 Grid::var(const string &n, bool, btp_stack *s)
00285 {
00286 string name = www2id(n);
00287
00288 if (_array_var->name() == name) {
00289 if (s)
00290 s->push(static_cast<BaseType *>(this));
00291 return _array_var;
00292 }
00293
00294 for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
00295 if ((*i)->name() == name) {
00296 if (s)
00297 s->push(static_cast<BaseType *>(this));
00298 return *i;
00299 }
00300 }
00301
00302 return 0;
00303 }
00304
00317 void
00318 Grid::add_var(BaseType *bt, Part part)
00319 {
00320 if (!bt)
00321 throw InternalErr(__FILE__, __LINE__,
00322 "Passing NULL pointer as variable to be added.");
00323
00324
00325
00326
00327
00328 switch (part) {
00329 case array:
00330 _array_var = bt->ptr_duplicate();
00331 _array_var->set_parent(this);
00332 return;
00333 case maps: {
00334 BaseType *btp = bt->ptr_duplicate();
00335 btp->set_parent(this);
00336 _map_vars.push_back(btp);
00337 return;
00338 }
00339 default:
00340 if (!_array_var) {
00341 _array_var = bt->ptr_duplicate();
00342 _array_var->set_parent(this);
00343 }
00344 else {
00345 BaseType *btp = bt->ptr_duplicate();
00346 btp->set_parent(this);
00347 _map_vars.push_back(btp);
00348 }
00349 return;
00350 }
00351 }
00352
00356 BaseType *
00357 Grid::array_var()
00358 {
00359 return _array_var;
00360 }
00361
00365 Array *
00366 Grid::get_array()
00367 {
00368 return dynamic_cast<Array*>(_array_var);
00369 }
00370
00372 Grid::Map_iter
00373 Grid::map_begin()
00374 {
00375 return _map_vars.begin() ;
00376 }
00377
00380 Grid::Map_iter
00381 Grid::map_end()
00382 {
00383 return _map_vars.end() ;
00384 }
00385
00387 Grid::Map_riter
00388 Grid::map_rbegin()
00389 {
00390 return _map_vars.rbegin() ;
00391 }
00392
00395 Grid::Map_riter
00396 Grid::map_rend()
00397 {
00398 return _map_vars.rend() ;
00399 }
00400
00404 Grid::Map_iter
00405 Grid::get_map_iter(int i)
00406 {
00407 return _map_vars.begin() + i;
00408 }
00409
00425 int
00426 Grid::components(bool constrained)
00427 {
00428 int comp;
00429
00430 if (constrained) {
00431 comp = _array_var->send_p() ? 1 : 0;
00432
00433 for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
00434 if ((*i)->send_p()) {
00435 comp++;
00436 }
00437 }
00438 }
00439 else {
00440 comp = 1 + _map_vars.size();
00441 }
00442
00443 return comp;
00444 }
00445
00446
00447
00448
00465 bool
00466 Grid::projection_yields_grid()
00467 {
00468
00469
00470
00471
00472 bool valid = true;
00473 Array *a = (Array *)_array_var;
00474
00475
00476 if (!a->send_p())
00477 return false;
00478
00479 Array::Dim_iter i = a->dim_begin() ;
00480 Map_iter m = map_begin() ;
00481 for (; valid && i != a->dim_end() && m != map_end(); i++, m++) {
00482 if (a->dimension_size(i, true)) {
00483
00484
00485 Array *map = (Array *)(*m);
00486 Array::Dim_iter fd = map->dim_begin();
00487 valid = map->dimension_start(fd, true)
00488 == a->dimension_start(i, true)
00489 && map->dimension_stop(fd, true)
00490 == a->dimension_stop(i, true)
00491 && map->dimension_stride(fd, true)
00492 == a->dimension_stride(i, true);
00493 }
00494 else {
00495
00496 Array *map = (Array *)(*m);
00497 valid = !map->send_p();
00498 }
00499 }
00500
00501 return valid;
00502 }
00503
00505 void
00506 Grid::clear_constraint()
00507 {
00508 dynamic_cast<Array&>(*_array_var).clear_constraint();
00509 for (Map_iter m = map_begin(); m != map_end(); ++m)
00510 dynamic_cast<Array&>(*(*m)).clear_constraint();
00511 }
00512
00513 void
00514 Grid::print_decl(FILE *out, string space, bool print_semi,
00515 bool constraint_info, bool constrained)
00516 {
00517 if (constrained && !send_p())
00518 return;
00519
00520
00521
00522
00523 int projection = components(true);
00524 if (constrained && projection == 1) {
00525 _array_var->print_decl(out, space, print_semi , constraint_info,
00526 constrained);
00527 for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
00528 (*i)->print_decl(out, space, print_semi , constraint_info, constrained);
00529 }
00530
00531 goto exit;
00532 }
00533
00534
00535
00536
00537 else if (constrained && !projection_yields_grid()) {
00538 fprintf(out, "%sStructure {\n", space.c_str()) ;
00539
00540 _array_var->print_decl(out, space + " ", true, constraint_info,
00541 constrained);
00542
00543 for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
00544 (*i)->print_decl(out, space + " ", true,
00545 constraint_info, constrained);
00546 }
00547
00548 fprintf(out, "%s} %s", space.c_str(), id2www(name()).c_str()) ;
00549 }
00550 else {
00551
00552
00553 fprintf(out, "%s%s {\n", space.c_str(), type_name().c_str()) ;
00554
00555 fprintf(out, "%s Array:\n", space.c_str()) ;
00556 _array_var->print_decl(out, space + " ", true, constraint_info,
00557 constrained);
00558
00559 fprintf(out, "%s Maps:\n", space.c_str()) ;
00560 for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
00561 (*i)->print_decl(out, space + " ", true,
00562 constraint_info, constrained);
00563 }
00564
00565 fprintf(out, "%s} %s", space.c_str(), id2www(name()).c_str()) ;
00566 }
00567
00568 if (constraint_info) {
00569 if (send_p())
00570 fprintf( out, ": Send True");
00571 else
00572 fprintf( out, ": Send False");
00573 }
00574
00575 if (print_semi)
00576 fprintf(out, ";\n") ;
00577
00578
00579 exit:
00580 return;
00581 }
00582
00583 void
00584 Grid::print_decl(ostream &out, string space, bool print_semi,
00585 bool constraint_info, bool constrained)
00586 {
00587 if (constrained && !send_p())
00588 return;
00589
00590
00591
00592
00593
00594
00595
00596
00597 int projection = components(true);
00598 if (constrained && projection == 1) {
00599 _array_var->print_decl(out, space, print_semi , constraint_info,
00600 constrained);
00601 for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
00602 (*i)->print_decl(out, space, print_semi , constraint_info, constrained);
00603 }
00604
00605 goto exit;
00606 }
00607
00608
00609
00610
00611 else if (constrained && !projection_yields_grid()) {
00612 out << space << "Structure {\n" ;
00613
00614 _array_var->print_decl(out, space + " ", true, constraint_info,
00615 constrained);
00616
00617 for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
00618 (*i)->print_decl(out, space + " ", true,
00619 constraint_info, constrained);
00620 }
00621
00622 out << space << "} " << id2www(name()) ;
00623 }
00624 else {
00625
00626
00627 out << space << type_name() << " {\n" ;
00628
00629 out << space << " Array:\n" ;
00630 _array_var->print_decl(out, space + " ", true, constraint_info,
00631 constrained);
00632
00633 out << space << " Maps:\n" ;
00634 for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
00635 (*i)->print_decl(out, space + " ", true,
00636 constraint_info, constrained);
00637 }
00638
00639 out << space << "} " << id2www(name()) ;
00640 }
00641
00642 if (constraint_info) {
00643 if (send_p())
00644 out << ": Send True";
00645 else
00646 out << ": Send False";
00647 }
00648
00649 if (print_semi)
00650 out << ";\n" ;
00651
00652
00653 exit:
00654 return;
00655 }
00656
00657 class PrintMapField : public unary_function<BaseType *, void>
00658 {
00659 FILE *d_out;
00660 string d_space;
00661 bool d_constrained;
00662 public:
00663 PrintMapField(FILE *o, string s, bool c)
00664 : d_out(o), d_space(s), d_constrained(c)
00665 {}
00666
00667 void operator()(BaseType *btp)
00668 {
00669 Array *a = dynamic_cast<Array*>(btp);
00670 if (!a)
00671 throw InternalErr(__FILE__, __LINE__, "Expected an Array.");
00672 a->print_as_map_xml(d_out, d_space, d_constrained);
00673 }
00674 };
00675
00676 void
00677 Grid::print_xml(FILE *out, string space, bool constrained)
00678 {
00679 if (constrained && !send_p())
00680 return;
00681
00682 fprintf(out, "%s<Grid", space.c_str());
00683 if (!name().empty())
00684 fprintf(out, " name=\"%s\"", id2xml(name()).c_str());
00685
00686 fprintf(out, ">\n");
00687
00688 get_attr_table().print_xml(out, space + " ", constrained);
00689
00690 get_array()->print_xml(out, space + " ", constrained);
00691
00692 for_each(map_begin(), map_end(),
00693 PrintMapField(out, space + " ", constrained));
00694
00695 fprintf(out, "%s</Grid>\n", space.c_str());
00696 }
00697
00698 class PrintMapFieldStrm : public unary_function<BaseType *, void>
00699 {
00700 ostream &d_out;
00701 string d_space;
00702 bool d_constrained;
00703 public:
00704 PrintMapFieldStrm(ostream &o, string s, bool c)
00705 : d_out(o), d_space(s), d_constrained(c)
00706 {}
00707
00708 void operator()(BaseType *btp)
00709 {
00710 Array *a = dynamic_cast<Array*>(btp);
00711 if (!a)
00712 throw InternalErr(__FILE__, __LINE__, "Expected an Array.");
00713 a->print_as_map_xml(d_out, d_space, d_constrained);
00714 }
00715 };
00716
00717 void
00718 Grid::print_xml(ostream &out, string space, bool constrained)
00719 {
00720 if (constrained && !send_p())
00721 return;
00722
00723 out << space << "<Grid" ;
00724 if (!name().empty())
00725 out << " name=\"" << id2xml(name()) << "\"" ;
00726
00727 out << ">\n" ;
00728
00729 get_attr_table().print_xml(out, space + " ", constrained);
00730
00731 get_array()->print_xml(out, space + " ", constrained);
00732
00733 for_each(map_begin(), map_end(),
00734 PrintMapFieldStrm(out, space + " ", constrained));
00735
00736 out << space << "</Grid>\n" ;
00737 }
00738
00739 void
00740 Grid::print_val(FILE *out, string space, bool print_decl_p)
00741 {
00742 if (print_decl_p) {
00743 print_decl(out, space, false);
00744 fprintf(out, " = ") ;
00745 }
00746
00747
00748
00749
00750
00751 bool pyg = projection_yields_grid();
00752 if (pyg || !send_p())
00753 fprintf(out, "{ Array: ") ;
00754 else
00755 fprintf(out, "{") ;
00756 _array_var->print_val(out, "", false);
00757 if (pyg || !send_p())
00758 fprintf(out, " Maps: ") ;
00759 for (Map_citer i = _map_vars.begin(); i != _map_vars.end();
00760 i++, (void)(i != _map_vars.end() && fprintf(out, ", "))) {
00761 (*i)->print_val(out, "", false);
00762 }
00763 fprintf(out, " }") ;
00764
00765 if (print_decl_p)
00766 fprintf(out, ";\n") ;
00767 }
00768
00769 void
00770 Grid::print_val(ostream &out, string space, bool print_decl_p)
00771 {
00772 if (print_decl_p) {
00773 print_decl(out, space, false);
00774 out << " = " ;
00775 }
00776
00777
00778
00779
00780
00781 bool pyg = projection_yields_grid();
00782 if (pyg || !send_p())
00783 out << "{ Array: " ;
00784 else
00785 out << "{" ;
00786 _array_var->print_val(out, "", false);
00787 if (pyg || !send_p())
00788 out << " Maps: " ;
00789 for (Map_citer i = _map_vars.begin(); i != _map_vars.end();
00790 i++, (void)(i != _map_vars.end() && out << ", ")) {
00791 (*i)->print_val(out, "", false);
00792 }
00793 out << " }" ;
00794
00795 if (print_decl_p)
00796 out << ";\n" ;
00797 }
00798
00799
00800
00805 bool
00806 Grid::check_semantics(string &msg, bool all)
00807 {
00808 if (!BaseType::check_semantics(msg))
00809 return false;
00810 #if 0
00811
00812 if (!unique_names(_map_vars, name(), type_name(), msg))
00813 return false;
00814 #endif
00815
00816 msg = "";
00817
00818 if (!_array_var) {
00819 msg += "Null grid base array in `" + name() + "'\n";
00820 return false;
00821 }
00822
00823
00824 if (_array_var->type() != dods_array_c) {
00825 msg += "Grid `" + name() + "'s' member `" + _array_var->name() + "' must be an array\n";
00826 return false;
00827 }
00828
00829 Array *av = (Array *)_array_var;
00830
00831
00832 if (!av->var()->is_simple_type()) {
00833 msg += "The field variable `" + this->name() + "' must be an array of simple type elements (e.g., int32, String)\n";
00834 return false;
00835 }
00836
00837
00838 if ((unsigned)_map_vars.size() != av->dimensions()) {
00839 msg += "The number of map variables for grid `" + this->name() + "' does not match the number of dimensions of `";
00840 msg += av->name() + "'\n";
00841 return false;
00842 }
00843
00844 const string array_var_name = av->name();
00845 Array::Dim_iter asi = av->dim_begin() ;
00846 for (Map_iter mvi = _map_vars.begin();
00847 mvi != _map_vars.end(); mvi++, asi++) {
00848
00849 BaseType *mv = *mvi;
00850
00851
00852 if (array_var_name == mv->name()) {
00853 msg += "Grid map variable `" + mv->name() + "' conflicts with the grid array name in grid `" + name() + "'\n";
00854 return false;
00855 }
00856
00857 if (mv->type() != dods_array_c) {
00858 msg += "Grid map variable `" + mv->name() + "' is not an array\n";
00859 return false;
00860 }
00861
00862 Array *mv_a = (Array *)mv;
00863
00864
00865 if (!mv_a->var()->is_simple_type()) {
00866 msg += "The field variable `" + this->name() + "' must be an array of simple type elements (e.g., int32, String)\n";
00867 return false;
00868 }
00869
00870
00871 if (mv_a->dimensions() != 1) {
00872 msg += "Grid map variable `" + mv_a->name() + "' must be only one dimension\n";
00873 return false;
00874 }
00875
00876 Array::Dim_iter mv_asi = mv_a->dim_begin() ;
00877 int mv_a_size = mv_a->dimension_size(mv_asi) ;
00878 int av_size = av->dimension_size(asi) ;
00879 if (mv_a_size != av_size) {
00880 msg += "Grid map variable `" + mv_a->name() + "'s' size does not match the size of array variable '";
00881 msg += _array_var->name() + "'s' cooresponding dimension\n";
00882 return false;
00883 }
00884 }
00885
00886 if (all) {
00887 if (!_array_var->check_semantics(msg, true))
00888 return false;
00889 for (Map_iter mvi = _map_vars.begin(); mvi != _map_vars.end(); mvi++) {
00890 if (!(*mvi)->check_semantics(msg, true)) {
00891 return false;
00892 }
00893 }
00894 }
00895
00896 return true;
00897 }
00898
00907 void
00908 Grid::dump(ostream &strm) const
00909 {
00910 strm << DapIndent::LMarg << "Grid::dump - ("
00911 << (void *)this << ")" << endl ;
00912 DapIndent::Indent() ;
00913 Constructor::dump(strm) ;
00914 if (_array_var) {
00915 strm << DapIndent::LMarg << "array var: " << endl ;
00916 DapIndent::Indent() ;
00917 _array_var->dump(strm) ;
00918 DapIndent::UnIndent() ;
00919 }
00920 else {
00921 strm << DapIndent::LMarg << "array var: null" << endl ;
00922 }
00923 strm << DapIndent::LMarg << "map var: " << endl ;
00924 DapIndent::Indent() ;
00925 Map_citer i = _map_vars.begin() ;
00926 Map_citer ie = _map_vars.end() ;
00927 for (; i != ie; i++) {
00928 (*i)->dump(strm) ;
00929 }
00930 DapIndent::UnIndent() ;
00931 DapIndent::UnIndent() ;
00932 }
00933
00934 }
00935