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 bool
00186 Grid::serialize(const string &dataset, ConstraintEvaluator &eval, DDS &dds,
00187 XDR *sink, bool ce_eval)
00188 {
00189 dds.timeout_on();
00190
00191
00192
00193
00194
00195 if (!read_p())
00196 read(dataset);
00197
00198 #if EVAL
00199 if (ce_eval && !eval.eval_selection(dds, dataset))
00200 return true;
00201 #endif
00202
00203 dds.timeout_off();
00204
00205 if (_array_var->send_p())
00206 _array_var->serialize(dataset, eval, dds, sink, false);
00207
00208 for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
00209 if ((*i)->send_p()) {
00210 (*i)->serialize(dataset, eval, dds, sink, false);
00211 }
00212 }
00213
00214 return true;
00215 }
00216
00217 bool
00218 Grid::deserialize(XDR *source, DDS *dds, bool reuse)
00219 {
00220 _array_var->deserialize(source, dds, reuse);
00221
00222 for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
00223 (*i)->deserialize(source, dds, reuse);
00224 }
00225
00226 return false;
00227 }
00228
00236 unsigned int
00237 Grid::val2buf(void *, bool)
00238 {
00239 return sizeof(Grid);
00240 }
00241
00245 unsigned int
00246 Grid::buf2val(void **)
00247 {
00248 return sizeof(Grid);
00249 }
00250
00251 BaseType *
00252 Grid::var(const string &n, btp_stack &s)
00253 {
00254 return var(n, true, &s);
00255 }
00256
00261 BaseType *
00262 Grid::var(const string &n, bool, btp_stack *s)
00263 {
00264 string name = www2id(n);
00265
00266 if (_array_var->name() == name) {
00267 if (s)
00268 s->push(static_cast<BaseType *>(this));
00269 return _array_var;
00270 }
00271
00272 for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
00273 if ((*i)->name() == name) {
00274 if (s)
00275 s->push(static_cast<BaseType *>(this));
00276 return *i;
00277 }
00278 }
00279
00280 return 0;
00281 }
00282
00295 void
00296 Grid::add_var(BaseType *bt, Part part)
00297 {
00298 if (!bt)
00299 throw InternalErr(__FILE__, __LINE__,
00300 "Passing NULL pointer as variable to be added.");
00301
00302
00303
00304
00305
00306 switch (part) {
00307 case array:
00308 _array_var = bt->ptr_duplicate();
00309 _array_var->set_parent(this);
00310 return;
00311 case maps: {
00312 BaseType *btp = bt->ptr_duplicate();
00313 btp->set_parent(this);
00314 _map_vars.push_back(btp);
00315 return;
00316 }
00317 default:
00318 if (!_array_var) {
00319 _array_var = bt->ptr_duplicate();
00320 _array_var->set_parent(this);
00321 }
00322 else {
00323 BaseType *btp = bt->ptr_duplicate();
00324 btp->set_parent(this);
00325 _map_vars.push_back(btp);
00326 }
00327 return;
00328 }
00329 }
00330
00334 BaseType *
00335 Grid::array_var()
00336 {
00337 return _array_var;
00338 }
00339
00343 Array *
00344 Grid::get_array()
00345 {
00346 return dynamic_cast<Array*>(_array_var);
00347 }
00348
00350 Grid::Map_iter
00351 Grid::map_begin()
00352 {
00353 return _map_vars.begin() ;
00354 }
00355
00358 Grid::Map_iter
00359 Grid::map_end()
00360 {
00361 return _map_vars.end() ;
00362 }
00363
00365 Grid::Map_riter
00366 Grid::map_rbegin()
00367 {
00368 return _map_vars.rbegin() ;
00369 }
00370
00373 Grid::Map_riter
00374 Grid::map_rend()
00375 {
00376 return _map_vars.rend() ;
00377 }
00378
00382 Grid::Map_iter
00383 Grid::get_map_iter(int i)
00384 {
00385 return _map_vars.begin() + i;
00386 }
00387
00403 int
00404 Grid::components(bool constrained)
00405 {
00406 int comp;
00407
00408 if (constrained) {
00409 comp = _array_var->send_p() ? 1 : 0;
00410
00411 for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
00412 if ((*i)->send_p()) {
00413 comp++;
00414 }
00415 }
00416 }
00417 else {
00418 comp = 1 + _map_vars.size();
00419 }
00420
00421 return comp;
00422 }
00423
00424
00425
00426
00443 bool
00444 Grid::projection_yields_grid()
00445 {
00446
00447
00448
00449
00450 bool valid = true;
00451 Array *a = (Array *)_array_var;
00452
00453
00454 if (!a->send_p())
00455 return false;
00456
00457 Array::Dim_iter i = a->dim_begin() ;
00458 Map_iter m = map_begin() ;
00459 for (; valid && i != a->dim_end() && m != map_end(); i++, m++) {
00460 if (a->dimension_size(i, true)) {
00461
00462
00463 Array *map = (Array *)(*m);
00464 Array::Dim_iter fd = map->dim_begin();
00465 valid = map->dimension_start(fd, true)
00466 == a->dimension_start(i, true)
00467 && map->dimension_stop(fd, true)
00468 == a->dimension_stop(i, true)
00469 && map->dimension_stride(fd, true)
00470 == a->dimension_stride(i, true);
00471 }
00472 else {
00473
00474 Array *map = (Array *)(*m);
00475 valid = !map->send_p();
00476 }
00477 }
00478
00479 return valid;
00480 }
00481
00483 void
00484 Grid::clear_constraint()
00485 {
00486 dynamic_cast<Array&>(*_array_var).clear_constraint();
00487 for (Map_iter m = map_begin(); m != map_end(); ++m)
00488 dynamic_cast<Array&>(*(*m)).clear_constraint();
00489 }
00490
00491 void
00492 Grid::print_decl(FILE *out, string space, bool print_semi,
00493 bool constraint_info, bool constrained)
00494 {
00495 if (constrained && !send_p())
00496 return;
00497
00498
00499
00500
00501 int projection = components(true);
00502 if (constrained && projection == 1) {
00503 _array_var->print_decl(out, space, true, constraint_info,
00504 constrained);
00505 for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
00506 (*i)->print_decl(out, space, true, constraint_info, constrained);
00507 }
00508 goto exit;
00509 }
00510
00511
00512
00513
00514 else if (constrained && !projection_yields_grid()) {
00515 fprintf(out, "%sStructure {\n", space.c_str()) ;
00516
00517 _array_var->print_decl(out, space + " ", true, constraint_info,
00518 constrained);
00519
00520 for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
00521 (*i)->print_decl(out, space + " ", true,
00522 constraint_info, constrained);
00523 }
00524
00525 fprintf(out, "%s} %s", space.c_str(), id2www(name()).c_str()) ;
00526 }
00527 else {
00528
00529
00530 fprintf(out, "%s%s {\n", space.c_str(), type_name().c_str()) ;
00531
00532 fprintf(out, "%s Array:\n", space.c_str()) ;
00533 _array_var->print_decl(out, space + " ", true, constraint_info,
00534 constrained);
00535
00536 fprintf(out, "%s Maps:\n", space.c_str()) ;
00537 for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
00538 (*i)->print_decl(out, space + " ", true,
00539 constraint_info, constrained);
00540 }
00541
00542 fprintf(out, "%s} %s", space.c_str(), id2www(name()).c_str()) ;
00543 }
00544
00545 if (constraint_info) {
00546 if (send_p())
00547 cout << ": Send True";
00548 else
00549 cout << ": Send False";
00550 }
00551
00552 if (print_semi)
00553 fprintf(out, ";\n") ;
00554
00555
00556 exit:
00557 return;
00558 }
00559
00560 class PrintMapField : public unary_function<BaseType *, void>
00561 {
00562 FILE *d_out;
00563 string d_space;
00564 bool d_constrained;
00565 public:
00566 PrintMapField(FILE *o, string s, bool c)
00567 : d_out(o), d_space(s), d_constrained(c)
00568 {}
00569
00570 void operator()(BaseType *btp)
00571 {
00572 Array *a = dynamic_cast<Array*>(btp);
00573 if (!a)
00574 throw InternalErr(__FILE__, __LINE__, "Expected an Array.");
00575 a->print_as_map_xml(d_out, d_space, d_constrained);
00576 }
00577 };
00578
00579 void
00580 Grid::print_xml(FILE *out, string space, bool constrained)
00581 {
00582 if (constrained && !send_p())
00583 return;
00584
00585 fprintf(out, "%s<Grid", space.c_str());
00586 if (!name().empty())
00587 fprintf(out, " name=\"%s\"", id2xml(name()).c_str());
00588
00589 fprintf(out, ">\n");
00590
00591 get_attr_table().print_xml(out, space + " ", constrained);
00592
00593 get_array()->print_xml(out, space + " ", constrained);
00594
00595 for_each(map_begin(), map_end(),
00596 PrintMapField(out, space + " ", constrained));
00597
00598 fprintf(out, "%s</Grid>\n", space.c_str());
00599 }
00600
00601 void
00602 Grid::print_val(FILE *out, string space, bool print_decl_p)
00603 {
00604 if (print_decl_p) {
00605 print_decl(out, space, false);
00606 fprintf(out, " = ") ;
00607 }
00608
00609
00610
00611
00612
00613 bool pyg = projection_yields_grid();
00614 if (pyg || !send_p())
00615 fprintf(out, "{ Array: ") ;
00616 else
00617 fprintf(out, "{") ;
00618 _array_var->print_val(out, "", false);
00619 if (pyg || !send_p())
00620 fprintf(out, " Maps: ") ;
00621 for (Map_citer i = _map_vars.begin(); i != _map_vars.end();
00622 i++, (void)(i != _map_vars.end() && fprintf(out, ", "))) {
00623 (*i)->print_val(out, "", false);
00624 }
00625 fprintf(out, " }") ;
00626
00627 if (print_decl_p)
00628 fprintf(out, ";\n") ;
00629 }
00630
00631
00632
00637 bool
00638 Grid::check_semantics(string &msg, bool all)
00639 {
00640 if (!BaseType::check_semantics(msg))
00641 return false;
00642 #if 0
00643
00644 if (!unique_names(_map_vars, name(), type_name(), msg))
00645 return false;
00646 #endif
00647
00648 msg = "";
00649
00650 if (!_array_var) {
00651 msg += "Null grid base array in `" + name() + "'\n";
00652 return false;
00653 }
00654
00655
00656 if (_array_var->type() != dods_array_c) {
00657 msg += "Grid `" + name() + "'s' member `" + _array_var->name() + "' must be an array\n";
00658 return false;
00659 }
00660
00661 Array *av = (Array *)_array_var;
00662
00663
00664 if (!av->var()->is_simple_type()) {
00665 msg += "The field variable `" + this->name() + "' must be an array of simple type elements (e.g., int32, String)\n";
00666 return false;
00667 }
00668
00669
00670 if ((unsigned)_map_vars.size() != av->dimensions()) {
00671 msg += "The number of map variables for grid `" + this->name() + "' does not match the number of dimensions of `";
00672 msg += av->name() + "'\n";
00673 return false;
00674 }
00675
00676 const string array_var_name = av->name();
00677 Array::Dim_iter asi = av->dim_begin() ;
00678 for (Map_iter mvi = _map_vars.begin();
00679 mvi != _map_vars.end(); mvi++, asi++) {
00680
00681 BaseType *mv = *mvi;
00682
00683
00684 if (array_var_name == mv->name()) {
00685 msg += "Grid map variable `" + mv->name() + "' conflicts with the grid array name in grid `" + name() + "'\n";
00686 return false;
00687 }
00688
00689 if (mv->type() != dods_array_c) {
00690 msg += "Grid map variable `" + mv->name() + "' is not an array\n";
00691 return false;
00692 }
00693
00694 Array *mv_a = (Array *)mv;
00695
00696
00697 if (!mv_a->var()->is_simple_type()) {
00698 msg += "The field variable `" + this->name() + "' must be an array of simple type elements (e.g., int32, String)\n";
00699 return false;
00700 }
00701
00702
00703 if (mv_a->dimensions() != 1) {
00704 msg += "Grid map variable `" + mv_a->name() + "' must be only one dimension\n";
00705 return false;
00706 }
00707
00708 Array::Dim_iter mv_asi = mv_a->dim_begin() ;
00709 int mv_a_size = mv_a->dimension_size(mv_asi) ;
00710 int av_size = av->dimension_size(asi) ;
00711 if (mv_a_size != av_size) {
00712 msg += "Grid map variable `" + mv_a->name() + "'s' size does not match the size of array variable '";
00713 msg += _array_var->name() + "'s' cooresponding dimension\n";
00714 return false;
00715 }
00716 }
00717
00718 if (all) {
00719 if (!_array_var->check_semantics(msg, true))
00720 return false;
00721 for (Map_iter mvi = _map_vars.begin(); mvi != _map_vars.end(); mvi++) {
00722 if (!(*mvi)->check_semantics(msg, true)) {
00723 return false;
00724 }
00725 }
00726 }
00727
00728 return true;
00729 }
00730
00739 void
00740 Grid::dump(ostream &strm) const
00741 {
00742 strm << DapIndent::LMarg << "Grid::dump - ("
00743 << (void *)this << ")" << endl ;
00744 DapIndent::Indent() ;
00745 Constructor::dump(strm) ;
00746 if (_array_var) {
00747 strm << DapIndent::LMarg << "array var: " << endl ;
00748 DapIndent::Indent() ;
00749 _array_var->dump(strm) ;
00750 DapIndent::UnIndent() ;
00751 }
00752 else {
00753 strm << DapIndent::LMarg << "array var: null" << endl ;
00754 }
00755 strm << DapIndent::LMarg << "map var: " << endl ;
00756 DapIndent::Indent() ;
00757 Map_citer i = _map_vars.begin() ;
00758 Map_citer ie = _map_vars.end() ;
00759 for (; i != ie; i++) {
00760 (*i)->dump(strm) ;
00761 }
00762 DapIndent::UnIndent() ;
00763 DapIndent::UnIndent() ;
00764 }
00765