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 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
00211 unsigned int
00212 Structure::width()
00213 {
00214 unsigned int sz = 0;
00215
00216 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00217 sz += (*i)->width();
00218 }
00219
00220 return sz;
00221 }
00222
00223 void
00224 Structure::transfer_data(const string & dataset,
00225 ConstraintEvaluator & eval, DDS & dds)
00226 {
00227 if (!read_p())
00228 read(dataset);
00229
00230 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00231 if ((*i)->send_p()) {
00232 switch ((*i)->type()) {
00233 case dods_sequence_c:
00234 dynamic_cast <Sequence & >(**i).transfer_data(dataset,
00235 eval, dds);
00236 break;
00237
00238 case dods_structure_c:
00239 dynamic_cast <Structure & >(**i).transfer_data(dataset,
00240 eval, dds);
00241 break;
00242
00243 default:
00244 (*i)->read(dataset);
00245 break;
00246 }
00247 }
00248 }
00249 }
00250
00251 bool
00252 Structure::serialize(const string &dataset, ConstraintEvaluator &eval, DDS &dds,
00253 XDR *sink, bool ce_eval)
00254 {
00255 dds.timeout_on();
00256
00257 if (!read_p())
00258 read(dataset);
00259
00260 #if EVAL
00261 if (ce_eval && !eval.eval_selection(dds, dataset))
00262 return true;
00263 #endif
00264 dds.timeout_off();
00265
00266 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00267 if ((*i)->send_p()) {
00268 (*i)->serialize(dataset, eval, dds, sink, false);
00269 }
00270 }
00271
00272 return true;
00273 }
00274
00275 bool
00276 Structure::deserialize(XDR *source, DDS *dds, bool reuse)
00277 {
00278 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00279 (*i)->deserialize(source, dds, reuse);
00280 }
00281
00282 return false;
00283 }
00284
00294 unsigned int
00295 Structure::val2buf(void *, bool)
00296 {
00297 return sizeof(Structure);
00298 }
00299
00303 unsigned int
00304 Structure::buf2val(void **)
00305 {
00306 return sizeof(Structure);
00307 }
00308
00309 BaseType *
00310 Structure::var(const string &name, bool exact_match, btp_stack *s)
00311 {
00312 string n = www2id(name);
00313
00314 if (exact_match)
00315 return m_exact_match(n, s);
00316 else
00317 return m_leaf_match(n, s);
00318 }
00319
00321 BaseType *
00322 Structure::var(const string &n, btp_stack &s)
00323 {
00324 string name = www2id(n);
00325
00326 BaseType *btp = m_exact_match(name, &s);
00327 if (btp)
00328 return btp;
00329
00330 return m_leaf_match(name, &s);
00331 }
00332
00333
00334
00335 BaseType *
00336 Structure::m_leaf_match(const string &name, btp_stack *s)
00337 {
00338 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00339 if ((*i)->name() == name) {
00340 if (s) {
00341 DBG(cerr << "Pushing " << this->name() << endl);
00342 s->push(static_cast<BaseType *>(this));
00343 }
00344 return *i;
00345 }
00346 if ((*i)->is_constructor_type()) {
00347 BaseType *btp = (*i)->var(name, false, s);
00348 if (btp) {
00349 if (s) {
00350 DBG(cerr << "Pushing " << this->name() << endl);
00351 s->push(static_cast<BaseType *>(this));
00352 }
00353 return btp;
00354 }
00355 }
00356 }
00357
00358 return 0;
00359 }
00360
00361
00362 BaseType *
00363 Structure::m_exact_match(const string &name, btp_stack *s)
00364 {
00365 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00366 DBG(cerr << "Looking at " << (*i)->name() << " in: " << *i
00367 << endl);
00368 if ((*i)->name() == name) {
00369 DBG(cerr << "Found " << (*i)->name() << " in: "
00370 << *i << endl);
00371 if (s) {
00372 DBG(cerr << "Pushing " << this->name() << endl);
00373 s->push(static_cast<BaseType *>(this));
00374 }
00375 return *i;
00376 }
00377 }
00378
00379 string::size_type dot_pos = name.find(".");
00380 if (dot_pos != string::npos) {
00381 string aggregate = name.substr(0, dot_pos);
00382 string field = name.substr(dot_pos + 1);
00383
00384 BaseType *agg_ptr = var(aggregate);
00385 if (agg_ptr) {
00386 DBG(cerr << "Descending into " << agg_ptr->name() << endl);
00387 if (s) {
00388 DBG(cerr << "Pushing " << this->name() << endl);
00389 s->push(static_cast<BaseType *>(this));
00390 }
00391 return agg_ptr->var(field, true, s);
00392 }
00393 else
00394 return 0;
00395 }
00396
00397 return 0;
00398 }
00399
00400 void
00401 Structure::print_val(FILE *out, string space, bool print_decl_p)
00402 {
00403 if (print_decl_p) {
00404 print_decl(out, space, false);
00405 fprintf(out, " = ") ;
00406 }
00407
00408 fprintf(out, "{ ") ;
00409 for (Vars_citer i = _vars.begin(); i != _vars.end();
00410 i++, (void)(i != _vars.end() && fprintf(out, ", "))) {
00411 (*i)->print_val(out, "", false);
00412 }
00413
00414 fprintf(out, " }") ;
00415
00416 if (print_decl_p)
00417 fprintf(out, ";\n") ;
00418 }
00419
00420 void
00421 Structure::print_all_vals(FILE *out, XDR *, DDS *, string space, bool print_decl_p)
00422 {
00423 print_val(out, space, print_decl_p);
00424 }
00425
00426 bool
00427 Structure::check_semantics(string &msg, bool all)
00428 {
00429 if (!BaseType::check_semantics(msg))
00430 return false;
00431
00432 bool status = true;
00433
00434 if (!unique_names(_vars, name(), type_name(), msg))
00435 return false;
00436
00437 if (all) {
00438 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00439
00440 if (!(*i)->check_semantics(msg, true)) {
00441 status = false;
00442 goto exit;
00443 }
00444 }
00445 }
00446
00447 exit:
00448 return status;
00449 }
00450
00459 void
00460 Structure::dump(ostream &strm) const
00461 {
00462 strm << DapIndent::LMarg << "Structure::dump - ("
00463 << (void *)this << ")" << endl ;
00464 DapIndent::Indent() ;
00465 Constructor::dump(strm) ;
00466 DapIndent::UnIndent() ;
00467 }
00468