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