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