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