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