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 #include "config.h"
00034
00035 #include <string>
00036 #include <algorithm>
00037 #include <functional>
00038
00039
00040
00041 #include "Constructor.h"
00042 #include "Grid.h"
00043
00044 #include "debug.h"
00045 #include "escaping.h"
00046 #include "Error.h"
00047 #include "InternalErr.h"
00048
00049
00050 using namespace std;
00051
00052 namespace libdap {
00053
00054
00055
00056 void
00057 Constructor::_duplicate(const Constructor &)
00058 {}
00059
00060
00061
00062 Constructor::Constructor(const string &n, const Type &t)
00063 : BaseType(n, t)
00064 {}
00065
00076 Constructor::Constructor(const string &n, const string &d, const Type &t)
00077 : BaseType(n, d, t)
00078 {}
00079
00080 Constructor::Constructor(const Constructor &rhs) : BaseType(rhs)
00081 {}
00082
00083 Constructor::~Constructor()
00084 {}
00085
00086 Constructor &
00087 Constructor::operator=(const Constructor &rhs)
00088 {
00089 if (this == &rhs)
00090 return *this;
00091
00092 dynamic_cast<BaseType &>(*this) = rhs;
00093
00094 _duplicate(rhs);
00095
00096 return *this;
00097 }
00098
00100 Constructor::Vars_iter
00101 Constructor::var_begin()
00102 {
00103 return _vars.begin() ;
00104 }
00105
00121 BaseType *
00122 Constructor::find_hdf4_dimension_attribute_home(AttrTable::entry *source)
00123 {
00124 BaseType *btp;
00125 string::size_type i = source->name.find("_dim_");
00126 if (i != string::npos && (btp = var(source->name.substr(0, i)))) {
00127 if (btp->is_vector_type()) {
00128 return btp;
00129 }
00130 else if (btp->type() == dods_grid_c) {
00131
00132
00133 int n = atoi(source->name.substr(i + 5).c_str());
00134 DBG(cerr << "Found a Grid (" << btp->name() << ") and "
00135 << source->name.substr(i) << ", extracted n: " << n << endl);
00136 return *(dynamic_cast<Grid&>(*btp).map_begin() + n);
00137 }
00138 }
00139
00140 return 0;
00141 }
00142
00145 AttrTable *
00146 Constructor::find_matching_container(AttrTable::entry *source,
00147 BaseType **dest_variable)
00148 {
00149
00150 if (source->type != Attr_container)
00151 throw InternalErr(__FILE__, __LINE__, "Constructor::find_matching_container");
00152
00153
00154
00155 BaseType *btp;
00156 if ((btp = var(source->name))) {
00157
00158 *dest_variable = btp;
00159 return &btp->get_attr_table();
00160 }
00161
00162
00163 else if ((btp = find_hdf4_dimension_attribute_home(source))) {
00164
00165
00166 if (btp->get_parent()->type() == dods_grid_c) {
00167 DBG(cerr << "Found a Grid" << endl);
00168 *dest_variable = btp;
00169 return &btp->get_attr_table();
00170 }
00171 else {
00172 string::size_type i = source->name.find("_dim_");
00173 string ext = source->name.substr(i + 1);
00174 *dest_variable = btp;
00175 return btp->get_attr_table().append_container(ext);
00176 }
00177 }
00178 else {
00179
00180 AttrTable *at = get_attr_table().find_container(source->name);
00181 if (!at) {
00182 at = new AttrTable();
00183 get_attr_table().append_container(at, source->name);
00184 }
00185
00186 *dest_variable = 0;
00187 return at;
00188 }
00189 }
00190
00208 void
00209 Constructor::transfer_attributes(AttrTable::entry * entry)
00210 {
00211 DBG(cerr << "Constructor::transfer_attributes, variable: " << name() <<
00212 endl);
00213 DBG(cerr << "Working on the '" << entry->
00214 name << "' container." << endl);
00215 if (entry->type != Attr_container)
00216 throw InternalErr(__FILE__, __LINE__,
00217 "Constructor::transfer_attributes");
00218
00219 AttrTable *source = entry->attributes;
00220 BaseType *dest_variable = 0;
00221 AttrTable *dest = find_matching_container(entry, &dest_variable);
00222
00223
00224 AttrTable::Attr_iter source_p = source->attr_begin();
00225 while (source_p != source->attr_end()) {
00226 DBG(cerr << "Working on the '" << (*source_p)->
00227 name << "' attribute" << endl);
00228
00229 if ((*source_p)->type == Attr_container) {
00230 if (dest_variable && dest_variable->is_constructor_type()) {
00231 dynamic_cast <Constructor & >(*dest_variable).transfer_attributes(*source_p);
00232 }
00233 else {
00234 dest->append_container(new AttrTable(*(*source_p)->attributes),
00235 (*source_p)->name);
00236 }
00237 }
00238 else {
00239 dest->append_attr(source->get_name(source_p),
00240 source->get_type(source_p),
00241 source->get_attr_vector(source_p));
00242 }
00243
00244 ++source_p;
00245 }
00246 }
00247
00250 Constructor::Vars_iter
00251 Constructor::var_end()
00252 {
00253 return _vars.end() ;
00254 }
00255
00257 Constructor::Vars_riter
00258 Constructor::var_rbegin()
00259 {
00260 return _vars.rbegin();
00261 }
00262
00265 Constructor::Vars_riter
00266 Constructor::var_rend()
00267 {
00268 return _vars.rend();
00269 }
00270
00274 Constructor::Vars_iter
00275 Constructor::get_vars_iter(int i)
00276 {
00277 return _vars.begin() + i;
00278 }
00279
00283 BaseType *
00284 Constructor::get_var_index(int i)
00285 {
00286 return *(_vars.begin() + i);
00287 }
00288
00289 #if FILE_METHODS
00290 void
00291 Constructor::print_decl(FILE *out, string space, bool print_semi,
00292 bool constraint_info, bool constrained)
00293 {
00294 if (constrained && !send_p())
00295 return;
00296
00297 fprintf(out, "%s%s {\n", space.c_str(), type_name().c_str()) ;
00298 for (Vars_citer i = _vars.begin(); i != _vars.end(); i++) {
00299 (*i)->print_decl(out, space + " ", true,
00300 constraint_info, constrained);
00301 }
00302 fprintf(out, "%s} %s", space.c_str(), id2www(name()).c_str()) ;
00303
00304 if (constraint_info) {
00305 if (send_p())
00306 cout << ": Send True";
00307 else
00308 cout << ": Send False";
00309 }
00310
00311 if (print_semi)
00312 fprintf(out, ";\n") ;
00313 }
00314 #endif
00315
00316 void
00317 Constructor::print_decl(ostream &out, string space, bool print_semi,
00318 bool constraint_info, bool constrained)
00319 {
00320 if (constrained && !send_p())
00321 return;
00322
00323 out << space << type_name() << " {\n" ;
00324 for (Vars_citer i = _vars.begin(); i != _vars.end(); i++) {
00325 (*i)->print_decl(out, space + " ", true,
00326 constraint_info, constrained);
00327 }
00328 out << space << "} " << id2www(name()) ;
00329
00330 if (constraint_info) {
00331 if (send_p())
00332 out << ": Send True";
00333 else
00334 out << ": Send False";
00335 }
00336
00337 if (print_semi)
00338 out << ";\n" ;
00339 }
00340
00341 #if FILE_METHODS
00342 class PrintField : public unary_function<BaseType *, void>
00343 {
00344 FILE *d_out;
00345 string d_space;
00346 bool d_constrained;
00347 public:
00348 PrintField(FILE *o, string s, bool c)
00349 : d_out(o), d_space(s), d_constrained(c)
00350 {}
00351
00352 void operator()(BaseType *btp)
00353 {
00354 btp->print_xml(d_out, d_space, d_constrained);
00355 }
00356 };
00357
00358 void
00359 Constructor::print_xml(FILE *out, string space, bool constrained)
00360 {
00361 if (constrained && !send_p())
00362 return;
00363
00364 bool has_attributes = false;
00365 bool has_variables = (var_begin() != var_end());
00366
00367 fprintf(out, "%s<%s", space.c_str(), type_name().c_str());
00368 if (!name().empty())
00369 fprintf(out, " name=\"%s\"", id2xml(name()).c_str());
00370
00371 if (has_attributes || has_variables) {
00372 fprintf(out, ">\n");
00373
00374 get_attr_table().print_xml(out, space + " ", constrained);
00375
00376 for_each(var_begin(), var_end(),
00377 PrintField(out, space + " ", constrained));
00378
00379 fprintf(out, "%s</%s>\n", space.c_str(), type_name().c_str());
00380 }
00381 else {
00382 fprintf(out, "/>\n");
00383 }
00384 }
00385 #endif
00386
00387 class PrintFieldStrm : public unary_function<BaseType *, void>
00388 {
00389 ostream &d_out;
00390 string d_space;
00391 bool d_constrained;
00392 public:
00393 PrintFieldStrm(ostream &o, string s, bool c)
00394 : d_out(o), d_space(s), d_constrained(c)
00395 {}
00396
00397 void operator()(BaseType *btp)
00398 {
00399 btp->print_xml(d_out, d_space, d_constrained);
00400 }
00401 };
00402
00403 void
00404 Constructor::print_xml(ostream &out, string space, bool constrained)
00405 {
00406 if (constrained && !send_p())
00407 return;
00408
00409 bool has_attributes = false;
00410 bool has_variables = (var_begin() != var_end());
00411
00412 out << space << "<" << type_name() ;
00413 if (!name().empty())
00414 out << " name=\"" << id2xml(name()) << "\"" ;
00415
00416 if (has_attributes || has_variables) {
00417 out << ">\n" ;
00418
00419 get_attr_table().print_xml(out, space + " ", constrained);
00420
00421 for_each(var_begin(), var_end(),
00422 PrintFieldStrm(out, space + " ", constrained));
00423
00424 out << space << "</" << type_name() << ">\n" ;
00425 }
00426 else {
00427 out << "/>\n" ;
00428 }
00429 }
00430
00443 bool
00444 Constructor::is_linear()
00445 {
00446 return false;
00447 }
00448
00457 void
00458 Constructor::dump(ostream &strm) const
00459 {
00460 strm << DapIndent::LMarg << "Constructor::dump - ("
00461 << (void *)this << ")" << endl ;
00462 DapIndent::Indent() ;
00463 BaseType::dump(strm) ;
00464 strm << DapIndent::LMarg << "vars: " << endl ;
00465 DapIndent::Indent() ;
00466 Vars_citer i = _vars.begin() ;
00467 Vars_citer ie = _vars.end() ;
00468 for (; i != ie; i++) {
00469 (*i)->dump(strm) ;
00470 }
00471 DapIndent::UnIndent() ;
00472 DapIndent::UnIndent() ;
00473 }
00474
00475 }
00476