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
00066 Constructor::Constructor(const Constructor &rhs) : BaseType(rhs)
00067 {}
00068
00069 Constructor::~Constructor()
00070 {}
00071
00072 Constructor &
00073 Constructor::operator=(const Constructor &rhs)
00074 {
00075 if (this == &rhs)
00076 return *this;
00077
00078 dynamic_cast<BaseType &>(*this) = rhs;
00079
00080 _duplicate(rhs);
00081
00082 return *this;
00083 }
00084
00086 Constructor::Vars_iter
00087 Constructor::var_begin()
00088 {
00089 return _vars.begin() ;
00090 }
00091
00107 BaseType *
00108 Constructor::find_hdf4_dimension_attribute_home(AttrTable::entry *source)
00109 {
00110 BaseType *btp;
00111 string::size_type i = source->name.find("_dim_");
00112 if (i != string::npos && (btp = var(source->name.substr(0, i)))) {
00113 if (btp->is_vector_type()) {
00114 return btp;
00115 }
00116 else if (btp->type() == dods_grid_c) {
00117
00118
00119 int n = atoi(source->name.substr(i + 5).c_str());
00120 DBG(cerr << "Found a Grid (" << btp->name() << ") and "
00121 << source->name.substr(i) << ", extracted n: " << n << endl);
00122 return *(dynamic_cast<Grid&>(*btp).map_begin() + n);
00123 }
00124 }
00125
00126 return 0;
00127 }
00128
00131 AttrTable *
00132 Constructor::find_matching_container(AttrTable::entry *source,
00133 BaseType **dest_variable)
00134 {
00135
00136 if (source->type != Attr_container)
00137 throw InternalErr(__FILE__, __LINE__, "Constructor::find_matching_container");
00138
00139
00140
00141 BaseType *btp;
00142 if ((btp = var(source->name))) {
00143
00144 *dest_variable = btp;
00145 return &btp->get_attr_table();
00146 }
00147
00148
00149 else if ((btp = find_hdf4_dimension_attribute_home(source))) {
00150
00151
00152 if (btp->get_parent()->type() == dods_grid_c) {
00153 DBG(cerr << "Found a Grid" << endl);
00154 *dest_variable = btp;
00155 return &btp->get_attr_table();
00156 }
00157 else {
00158 string::size_type i = source->name.find("_dim_");
00159 string ext = source->name.substr(i + 1);
00160 *dest_variable = btp;
00161 return btp->get_attr_table().append_container(ext);
00162 }
00163 }
00164 else {
00165
00166 AttrTable *at = get_attr_table().find_container(source->name);
00167 if (!at) {
00168 at = new AttrTable();
00169 get_attr_table().append_container(at, source->name);
00170 }
00171
00172 *dest_variable = 0;
00173 return at;
00174 }
00175 }
00176
00194 void
00195 Constructor::transfer_attributes(AttrTable::entry * entry)
00196 {
00197 DBG(cerr << "Constructor::transfer_attributes, variable: " << name() <<
00198 endl);
00199 DBG(cerr << "Working on the '" << entry->
00200 name << "' container." << endl);
00201 if (entry->type != Attr_container)
00202 throw InternalErr(__FILE__, __LINE__,
00203 "Constructor::transfer_attributes");
00204
00205 AttrTable *source = entry->attributes;
00206 BaseType *dest_variable = 0;
00207 AttrTable *dest = find_matching_container(entry, &dest_variable);
00208
00209
00210 AttrTable::Attr_iter source_p = source->attr_begin();
00211 while (source_p != source->attr_end()) {
00212 DBG(cerr << "Working on the '" << (*source_p)->
00213 name << "' attribute" << endl);
00214
00215 if ((*source_p)->type == Attr_container) {
00216 if (dest_variable && dest_variable->is_constructor_type()) {
00217 dynamic_cast <Constructor & >(*dest_variable).transfer_attributes(*source_p);
00218 }
00219 else {
00220 dest->append_container(new AttrTable(*(*source_p)->attributes),
00221 (*source_p)->name);
00222 }
00223 }
00224 else {
00225 dest->append_attr(source->get_name(source_p),
00226 source->get_type(source_p),
00227 source->get_attr_vector(source_p));
00228 }
00229
00230 ++source_p;
00231 }
00232 }
00233
00236 Constructor::Vars_iter
00237 Constructor::var_end()
00238 {
00239 return _vars.end() ;
00240 }
00241
00243 Constructor::Vars_riter
00244 Constructor::var_rbegin()
00245 {
00246 return _vars.rbegin();
00247 }
00248
00251 Constructor::Vars_riter
00252 Constructor::var_rend()
00253 {
00254 return _vars.rend();
00255 }
00256
00260 Constructor::Vars_iter
00261 Constructor::get_vars_iter(int i)
00262 {
00263 return _vars.begin() + i;
00264 }
00265
00269 BaseType *
00270 Constructor::get_var_index(int i)
00271 {
00272 return *(_vars.begin() + i);
00273 }
00274
00275
00276 void
00277 Constructor::print_decl(FILE *out, string space, bool print_semi,
00278 bool constraint_info, bool constrained)
00279 {
00280 if (constrained && !send_p())
00281 return;
00282
00283 fprintf(out, "%s%s {\n", space.c_str(), type_name().c_str()) ;
00284 for (Vars_citer i = _vars.begin(); i != _vars.end(); i++) {
00285 (*i)->print_decl(out, space + " ", true,
00286 constraint_info, constrained);
00287 }
00288 fprintf(out, "%s} %s", space.c_str(), id2www(name()).c_str()) ;
00289
00290 if (constraint_info) {
00291 if (send_p())
00292 cout << ": Send True";
00293 else
00294 cout << ": Send False";
00295 }
00296
00297 if (print_semi)
00298 fprintf(out, ";\n") ;
00299 }
00300
00301 void
00302 Constructor::print_decl(ostream &out, string space, bool print_semi,
00303 bool constraint_info, bool constrained)
00304 {
00305 if (constrained && !send_p())
00306 return;
00307
00308 out << space << type_name() << " {\n" ;
00309 for (Vars_citer i = _vars.begin(); i != _vars.end(); i++) {
00310 (*i)->print_decl(out, space + " ", true,
00311 constraint_info, constrained);
00312 }
00313 out << space << "} " << id2www(name()) ;
00314
00315 if (constraint_info) {
00316 if (send_p())
00317 out << ": Send True";
00318 else
00319 out << ": Send False";
00320 }
00321
00322 if (print_semi)
00323 out << ";\n" ;
00324 }
00325
00326 class PrintField : public unary_function<BaseType *, void>
00327 {
00328 FILE *d_out;
00329 string d_space;
00330 bool d_constrained;
00331 public:
00332 PrintField(FILE *o, string s, bool c)
00333 : d_out(o), d_space(s), d_constrained(c)
00334 {}
00335
00336 void operator()(BaseType *btp)
00337 {
00338 btp->print_xml(d_out, d_space, d_constrained);
00339 }
00340 };
00341
00342 void
00343 Constructor::print_xml(FILE *out, string space, bool constrained)
00344 {
00345 if (constrained && !send_p())
00346 return;
00347
00348 bool has_attributes = false;
00349 bool has_variables = (var_begin() != var_end());
00350
00351 fprintf(out, "%s<%s", space.c_str(), type_name().c_str());
00352 if (!name().empty())
00353 fprintf(out, " name=\"%s\"", id2xml(name()).c_str());
00354
00355 if (has_attributes || has_variables) {
00356 fprintf(out, ">\n");
00357
00358 get_attr_table().print_xml(out, space + " ", constrained);
00359
00360 for_each(var_begin(), var_end(),
00361 PrintField(out, space + " ", constrained));
00362
00363 fprintf(out, "%s</%s>\n", space.c_str(), type_name().c_str());
00364 }
00365 else {
00366 fprintf(out, "/>\n");
00367 }
00368 }
00369
00370 class PrintFieldStrm : public unary_function<BaseType *, void>
00371 {
00372 ostream &d_out;
00373 string d_space;
00374 bool d_constrained;
00375 public:
00376 PrintFieldStrm(ostream &o, string s, bool c)
00377 : d_out(o), d_space(s), d_constrained(c)
00378 {}
00379
00380 void operator()(BaseType *btp)
00381 {
00382 btp->print_xml(d_out, d_space, d_constrained);
00383 }
00384 };
00385
00386 void
00387 Constructor::print_xml(ostream &out, string space, bool constrained)
00388 {
00389 if (constrained && !send_p())
00390 return;
00391
00392 bool has_attributes = false;
00393 bool has_variables = (var_begin() != var_end());
00394
00395 out << space << "<" << type_name() ;
00396 if (!name().empty())
00397 out << " name=\"" << id2xml(name()) << "\"" ;
00398
00399 if (has_attributes || has_variables) {
00400 out << ">\n" ;
00401
00402 get_attr_table().print_xml(out, space + " ", constrained);
00403
00404 for_each(var_begin(), var_end(),
00405 PrintFieldStrm(out, space + " ", constrained));
00406
00407 out << space << "</" << type_name() << ">\n" ;
00408 }
00409 else {
00410 out << "/>\n" ;
00411 }
00412 }
00413
00426 bool
00427 Constructor::is_linear()
00428 {
00429 return false;
00430 }
00431
00440 void
00441 Constructor::dump(ostream &strm) const
00442 {
00443 strm << DapIndent::LMarg << "Constructor::dump - ("
00444 << (void *)this << ")" << endl ;
00445 DapIndent::Indent() ;
00446 BaseType::dump(strm) ;
00447 strm << DapIndent::LMarg << "vars: " << endl ;
00448 DapIndent::Indent() ;
00449 Vars_citer i = _vars.begin() ;
00450 Vars_citer ie = _vars.end() ;
00451 for (; i != ie; i++) {
00452 (*i)->dump(strm) ;
00453 }
00454 DapIndent::UnIndent() ;
00455 DapIndent::UnIndent() ;
00456 }
00457
00458 }
00459