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
00037
00038 #include "config.h"
00039
00040 #include "Structure.h"
00041 #include "util.h"
00042 #include "debug.h"
00043 #include "InternalErr.h"
00044 #include "escaping.h"
00045
00046 using std::cerr;
00047 using std::endl;
00048
00049 namespace libdap {
00050
00051 void
00052 Structure::_duplicate(const Structure &s)
00053 {
00054 Structure &cs = const_cast<Structure &>(s);
00055
00056 DBG(cerr << "Copying structure: " << name() << endl);
00057
00058 for (Vars_iter i = cs._vars.begin(); i != cs._vars.end(); i++) {
00059 DBG(cerr << "Copying field: " << (*i)->name() << endl);
00060
00061
00062
00063
00064
00065 BaseType *btp = (*i)->ptr_duplicate();
00066 btp->set_parent(this);
00067 _vars.push_back(btp);
00068 }
00069 }
00070
00078 Structure::Structure(const string &n) : Constructor(n, dods_structure_c)
00079 {}
00080
00090 Structure::Structure(const string &n, const string &d)
00091 : Constructor(n, d, dods_structure_c)
00092 {}
00093
00095 Structure::Structure(const Structure &rhs) : Constructor(rhs)
00096 {
00097 _duplicate(rhs);
00098 }
00099
00100 Structure::~Structure()
00101 {
00102 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00103 BaseType *btp = *i ;
00104 delete btp ; btp = 0;
00105 }
00106 }
00107
00108 BaseType *
00109 Structure::ptr_duplicate()
00110 {
00111 return new Structure(*this);
00112 }
00113
00114 Structure &
00115 Structure::operator=(const Structure &rhs)
00116 {
00117 if (this == &rhs)
00118 return *this;
00119
00120 dynamic_cast<Constructor &>(*this) = rhs;
00121
00122 _duplicate(rhs);
00123
00124 return *this;
00125 }
00126
00127 int
00128 Structure::element_count(bool leaves)
00129 {
00130 if (!leaves)
00131 return _vars.size();
00132 else {
00133 int i = 0;
00134 for (Vars_iter j = _vars.begin(); j != _vars.end(); j++) {
00135 j += (*j)->element_count(leaves);
00136 }
00137 return i;
00138 }
00139 }
00140
00141 bool
00142 Structure::is_linear()
00143 {
00144 bool linear = true;
00145 for (Vars_iter i = _vars.begin(); linear && i != _vars.end(); i++) {
00146 if ((*i)->type() == dods_structure_c)
00147 linear = linear && dynamic_cast<Structure*>((*i))->is_linear();
00148 else
00149 linear = linear && (*i)->is_simple_type();
00150 }
00151
00152 return linear;
00153 }
00154
00155 void
00156 Structure::set_send_p(bool state)
00157 {
00158 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00159 (*i)->set_send_p(state);
00160 }
00161
00162 BaseType::set_send_p(state);
00163 }
00164
00165 void
00166 Structure::set_read_p(bool state)
00167 {
00168 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00169 (*i)->set_read_p(state);
00170 }
00171
00172 BaseType::set_read_p(state);
00173 }
00174
00180 void
00181 Structure::set_in_selection(bool state)
00182 {
00183 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00184 (*i)->set_in_selection(state);
00185 }
00186
00187 BaseType::set_in_selection(state);
00188 }
00189
00191 void
00192 Structure::set_leaf_sequence(int level)
00193 {
00194 for (Vars_iter i = var_begin(); i != var_end(); i++) {
00195 if ((*i)->type() == dods_sequence_c)
00196 dynamic_cast<Sequence&>(**i).set_leaf_sequence(++level);
00197 else if ((*i)->type() == dods_structure_c)
00198 dynamic_cast<Structure&>(**i).set_leaf_sequence(level);
00199 }
00200 }
00201
00206 void
00207 Structure::add_var(BaseType *bt, Part)
00208 {
00209
00210
00211 if (!bt)
00212 throw InternalErr(__FILE__, __LINE__,
00213 "The BaseType parameter cannot be null.");
00214
00215
00216
00217
00218
00219
00220 BaseType *btp = bt->ptr_duplicate();
00221 btp->set_parent(this);
00222 _vars.push_back(btp);
00223 }
00224
00228 void
00229 Structure::del_var(const string &n)
00230 {
00231 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00232 if ((*i)->name() == n) {
00233 BaseType *bt = *i ;
00234 _vars.erase(i) ;
00235 delete bt ; bt = 0;
00236 return;
00237 }
00238 }
00239 }
00240
00246 bool
00247 Structure::read()
00248 {
00249 if( !read_p() )
00250 {
00251 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00252 (*i)->read() ;
00253 }
00254 set_read_p(true) ;
00255 }
00256
00257 return false ;
00258 }
00259
00260 unsigned int
00261 Structure::width()
00262 {
00263 unsigned int sz = 0;
00264
00265 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00266 sz += (*i)->width();
00267 }
00268
00269 return sz;
00270 }
00271
00272 void
00273 Structure::intern_data(ConstraintEvaluator & eval, DDS & dds)
00274 {
00275 DBG(cerr << "Structure::intern_data: " << name() << endl);
00276 if (!read_p())
00277 read();
00278
00279 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00280 if ((*i)->send_p()) {
00281 (*i)->intern_data(eval, dds);
00282 }
00283 }
00284 }
00285
00286 bool
00287 Structure::serialize(ConstraintEvaluator &eval, DDS &dds,
00288 Marshaller &m, bool ce_eval)
00289 {
00290 dds.timeout_on();
00291
00292 if (!read_p())
00293 read();
00294
00295 #if EVAL
00296 if (ce_eval && !eval.eval_selection(dds, dataset()))
00297 return true;
00298 #endif
00299
00300 dds.timeout_off();
00301
00302 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00303 if ((*i)->send_p()) {
00304 (*i)->serialize(eval, dds, m, false);
00305 }
00306 }
00307
00308 return true;
00309 }
00310
00311 bool
00312 Structure::deserialize(UnMarshaller &um, DDS *dds, bool reuse)
00313 {
00314 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00315 (*i)->deserialize(um, dds, reuse);
00316 }
00317
00318 return false;
00319 }
00320
00330 unsigned int
00331 Structure::val2buf(void *, bool)
00332 {
00333 return sizeof(Structure);
00334 }
00335
00339 unsigned int
00340 Structure::buf2val(void **)
00341 {
00342 return sizeof(Structure);
00343 }
00344
00345 BaseType *
00346 Structure::var(const string &name, bool exact_match, btp_stack *s)
00347 {
00348 string n = www2id(name);
00349
00350 if (exact_match)
00351 return m_exact_match(n, s);
00352 else
00353 return m_leaf_match(n, s);
00354 }
00355
00357 BaseType *
00358 Structure::var(const string &n, btp_stack &s)
00359 {
00360 string name = www2id(n);
00361
00362 BaseType *btp = m_exact_match(name, &s);
00363 if (btp)
00364 return btp;
00365
00366 return m_leaf_match(name, &s);
00367 }
00368
00369
00370
00371 BaseType *
00372 Structure::m_leaf_match(const string &name, btp_stack *s)
00373 {
00374 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00375 if ((*i)->name() == name) {
00376 if (s) {
00377 DBG(cerr << "Pushing " << this->name() << endl);
00378 s->push(static_cast<BaseType *>(this));
00379 }
00380 return *i;
00381 }
00382 if ((*i)->is_constructor_type()) {
00383 BaseType *btp = (*i)->var(name, false, s);
00384 if (btp) {
00385 if (s) {
00386 DBG(cerr << "Pushing " << this->name() << endl);
00387 s->push(static_cast<BaseType *>(this));
00388 }
00389 return btp;
00390 }
00391 }
00392 }
00393
00394 return 0;
00395 }
00396
00397
00398 BaseType *
00399 Structure::m_exact_match(const string &name, btp_stack *s)
00400 {
00401 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00402 DBG(cerr << "Looking at " << (*i)->name() << " in: " << *i
00403 << endl);
00404 if ((*i)->name() == name) {
00405 DBG(cerr << "Found " << (*i)->name() << " in: "
00406 << *i << endl);
00407 if (s) {
00408 DBG(cerr << "Pushing " << this->name() << endl);
00409 s->push(static_cast<BaseType *>(this));
00410 }
00411 return *i;
00412 }
00413 }
00414
00415 string::size_type dot_pos = name.find(".");
00416 if (dot_pos != string::npos) {
00417 string aggregate = name.substr(0, dot_pos);
00418 string field = name.substr(dot_pos + 1);
00419
00420 BaseType *agg_ptr = var(aggregate);
00421 if (agg_ptr) {
00422 DBG(cerr << "Descending into " << agg_ptr->name() << endl);
00423 if (s) {
00424 DBG(cerr << "Pushing " << this->name() << endl);
00425 s->push(static_cast<BaseType *>(this));
00426 }
00427 return agg_ptr->var(field, true, s);
00428 }
00429 else
00430 return 0;
00431 }
00432
00433 return 0;
00434 }
00435
00436 void
00437 Structure::print_val(FILE *out, string space, bool print_decl_p)
00438 {
00439 if (print_decl_p) {
00440 print_decl(out, space, false);
00441 fprintf(out, " = ") ;
00442 }
00443
00444 fprintf(out, "{ ") ;
00445 for (Vars_citer i = _vars.begin(); i != _vars.end();
00446 i++, (void)(i != _vars.end() && fprintf(out, ", "))) {
00447 (*i)->print_val(out, "", false);
00448 }
00449
00450 fprintf(out, " }") ;
00451
00452 if (print_decl_p)
00453 fprintf(out, ";\n") ;
00454 }
00455
00456 void
00457 Structure::print_val(ostream &out, string space, bool print_decl_p)
00458 {
00459 if (print_decl_p) {
00460 print_decl(out, space, false);
00461 out << " = " ;
00462 }
00463
00464 out << "{ " ;
00465 for (Vars_citer i = _vars.begin(); i != _vars.end();
00466 i++, (void)(i != _vars.end() && out << ", ")) {
00467 (*i)->print_val(out, "", false);
00468 }
00469
00470 out << " }" ;
00471
00472 if (print_decl_p)
00473 out << ";\n" ;
00474 }
00475
00476 bool
00477 Structure::check_semantics(string &msg, bool all)
00478 {
00479 if (!BaseType::check_semantics(msg))
00480 return false;
00481
00482 bool status = true;
00483
00484 if (!unique_names(_vars, name(), type_name(), msg))
00485 return false;
00486
00487 if (all) {
00488 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00489
00490 if (!(*i)->check_semantics(msg, true)) {
00491 status = false;
00492 goto exit;
00493 }
00494 }
00495 }
00496
00497 exit:
00498 return status;
00499 }
00500
00509 void
00510 Structure::dump(ostream &strm) const
00511 {
00512 strm << DapIndent::LMarg << "Structure::dump - ("
00513 << (void *)this << ")" << endl ;
00514 DapIndent::Indent() ;
00515 Constructor::dump(strm) ;
00516 DapIndent::UnIndent() ;
00517 }
00518
00519 }
00520