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
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
00315 void
00316 Constructor::print_decl(ostream &out, string space, bool print_semi,
00317 bool constraint_info, bool constrained)
00318 {
00319 if (constrained && !send_p())
00320 return;
00321
00322 out << space << type_name() << " {\n" ;
00323 for (Vars_citer i = _vars.begin(); i != _vars.end(); i++) {
00324 (*i)->print_decl(out, space + " ", true,
00325 constraint_info, constrained);
00326 }
00327 out << space << "} " << id2www(name()) ;
00328
00329 if (constraint_info) {
00330 if (send_p())
00331 out << ": Send True";
00332 else
00333 out << ": Send False";
00334 }
00335
00336 if (print_semi)
00337 out << ";\n" ;
00338 }
00339
00340 class PrintField : public unary_function<BaseType *, void>
00341 {
00342 FILE *d_out;
00343 string d_space;
00344 bool d_constrained;
00345 public:
00346 PrintField(FILE *o, string s, bool c)
00347 : d_out(o), d_space(s), d_constrained(c)
00348 {}
00349
00350 void operator()(BaseType *btp)
00351 {
00352 btp->print_xml(d_out, d_space, d_constrained);
00353 }
00354 };
00355
00356 void
00357 Constructor::print_xml(FILE *out, string space, bool constrained)
00358 {
00359 if (constrained && !send_p())
00360 return;
00361
00362 bool has_attributes = false;
00363 bool has_variables = (var_begin() != var_end());
00364
00365 fprintf(out, "%s<%s", space.c_str(), type_name().c_str());
00366 if (!name().empty())
00367 fprintf(out, " name=\"%s\"", id2xml(name()).c_str());
00368
00369 if (has_attributes || has_variables) {
00370 fprintf(out, ">\n");
00371
00372 get_attr_table().print_xml(out, space + " ", constrained);
00373
00374 for_each(var_begin(), var_end(),
00375 PrintField(out, space + " ", constrained));
00376
00377 fprintf(out, "%s</%s>\n", space.c_str(), type_name().c_str());
00378 }
00379 else {
00380 fprintf(out, "/>\n");
00381 }
00382 }
00383
00384 class PrintFieldStrm : public unary_function<BaseType *, void>
00385 {
00386 ostream &d_out;
00387 string d_space;
00388 bool d_constrained;
00389 public:
00390 PrintFieldStrm(ostream &o, string s, bool c)
00391 : d_out(o), d_space(s), d_constrained(c)
00392 {}
00393
00394 void operator()(BaseType *btp)
00395 {
00396 btp->print_xml(d_out, d_space, d_constrained);
00397 }
00398 };
00399
00400 void
00401 Constructor::print_xml(ostream &out, string space, bool constrained)
00402 {
00403 if (constrained && !send_p())
00404 return;
00405
00406 bool has_attributes = false;
00407 bool has_variables = (var_begin() != var_end());
00408
00409 out << space << "<" << type_name() ;
00410 if (!name().empty())
00411 out << " name=\"" << id2xml(name()) << "\"" ;
00412
00413 if (has_attributes || has_variables) {
00414 out << ">\n" ;
00415
00416 get_attr_table().print_xml(out, space + " ", constrained);
00417
00418 for_each(var_begin(), var_end(),
00419 PrintFieldStrm(out, space + " ", constrained));
00420
00421 out << space << "</" << type_name() << ">\n" ;
00422 }
00423 else {
00424 out << "/>\n" ;
00425 }
00426 }
00427
00440 bool
00441 Constructor::is_linear()
00442 {
00443 return false;
00444 }
00445
00454 void
00455 Constructor::dump(ostream &strm) const
00456 {
00457 strm << DapIndent::LMarg << "Constructor::dump - ("
00458 << (void *)this << ")" << endl ;
00459 DapIndent::Indent() ;
00460 BaseType::dump(strm) ;
00461 strm << DapIndent::LMarg << "vars: " << endl ;
00462 DapIndent::Indent() ;
00463 Vars_citer i = _vars.begin() ;
00464 Vars_citer ie = _vars.end() ;
00465 for (; i != ie; i++) {
00466 (*i)->dump(strm) ;
00467 }
00468 DapIndent::UnIndent() ;
00469 DapIndent::UnIndent() ;
00470 }
00471
00472 }
00473