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
00053
00054 void
00055 Constructor::_duplicate(const Constructor &)
00056 {}
00057
00058
00059
00060 Constructor::Constructor(const string &n, const Type &t)
00061 : BaseType(n, t)
00062 {}
00063
00064 Constructor::Constructor(const Constructor &rhs) : BaseType(rhs)
00065 {}
00066
00067 Constructor::~Constructor()
00068 {}
00069
00070 Constructor &
00071 Constructor::operator=(const Constructor &rhs)
00072 {
00073 if (this == &rhs)
00074 return *this;
00075
00076 dynamic_cast<BaseType &>(*this) = rhs;
00077
00078 _duplicate(rhs);
00079
00080 return *this;
00081 }
00082
00084 Constructor::Vars_iter
00085 Constructor::var_begin()
00086 {
00087 return _vars.begin() ;
00088 }
00089
00105 BaseType *
00106 Constructor::find_hdf4_dimension_attribute_home(AttrTable::entry *source)
00107 {
00108 BaseType *btp;
00109 string::size_type i = source->name.find("_dim_");
00110 if (i != string::npos && (btp = var(source->name.substr(0, i)))) {
00111 if (btp->is_vector_type()) {
00112 return btp;
00113 }
00114 else if (btp->type() == dods_grid_c) {
00115
00116
00117 int n = atoi(source->name.substr(i + 5).c_str());
00118 DBG(cerr << "Found a Grid (" << btp->name() << ") and "
00119 << source->name.substr(i) << ", extracted n: " << n << endl);
00120 return *(dynamic_cast<Grid&>(*btp).map_begin() + n);
00121 }
00122 }
00123
00124 return 0;
00125 }
00126
00129 AttrTable *
00130 Constructor::find_matching_container(AttrTable::entry *source,
00131 BaseType **dest_variable)
00132 {
00133
00134 if (source->type != Attr_container)
00135 throw InternalErr(__FILE__, __LINE__, "Constructor::find_matching_container");
00136
00137
00138
00139 BaseType *btp;
00140 if ((btp = var(source->name))) {
00141
00142 *dest_variable = btp;
00143 return &btp->get_attr_table();
00144 }
00145
00146
00147 else if ((btp = find_hdf4_dimension_attribute_home(source))) {
00148
00149
00150 if (btp->get_parent()->type() == dods_grid_c) {
00151 DBG(cerr << "Found a Grid" << endl);
00152 *dest_variable = btp;
00153 return &btp->get_attr_table();
00154 }
00155 else {
00156 string::size_type i = source->name.find("_dim_");
00157 string ext = source->name.substr(i + 1);
00158 *dest_variable = btp;
00159 return btp->get_attr_table().append_container(ext);
00160 }
00161 }
00162 else {
00163
00164 AttrTable *at = get_attr_table().find_container(source->name);
00165 if (!at) {
00166 at = new AttrTable();
00167 get_attr_table().append_container(at, source->name);
00168 }
00169
00170 *dest_variable = 0;
00171 return at;
00172 }
00173 }
00174
00190 void
00191 Constructor::transfer_attributes(AttrTable::entry * entry)
00192 {
00193 DBG(cerr << "Constructor::transfer_attributes, variable: " << name() <<
00194 endl);
00195 DBG(cerr << "Working on the '" << entry->
00196 name << "' container." << endl);
00197 if (entry->type != Attr_container)
00198 throw InternalErr(__FILE__, __LINE__,
00199 "Constructor::transfer_attributes");
00200
00201 AttrTable *source = entry->attributes;
00202 BaseType *dest_variable = 0;
00203 AttrTable *dest = find_matching_container(entry, &dest_variable);
00204
00205
00206 AttrTable::Attr_iter source_p = source->attr_begin();
00207 while (source_p != source->attr_end()) {
00208 DBG(cerr << "Working on the '" << (*source_p)->
00209 name << "' attribute" << endl);
00210
00211 if ((*source_p)->type == Attr_container) {
00212 if (dest_variable && dest_variable->is_constructor_type()) {
00213 dynamic_cast <Constructor & >(*dest_variable).transfer_attributes(*source_p);
00214 }
00215 else {
00216 dest->append_container(new AttrTable(*(*source_p)->attributes),
00217 (*source_p)->name);
00218 }
00219 }
00220 else {
00221 dest->append_attr(source->get_name(source_p),
00222 source->get_type(source_p),
00223 source->get_attr_vector(source_p));
00224 }
00225
00226 ++source_p;
00227 }
00228 }
00229
00232 Constructor::Vars_iter
00233 Constructor::var_end()
00234 {
00235 return _vars.end() ;
00236 }
00237
00239 Constructor::Vars_riter
00240 Constructor::var_rbegin()
00241 {
00242 return _vars.rbegin();
00243 }
00244
00247 Constructor::Vars_riter
00248 Constructor::var_rend()
00249 {
00250 return _vars.rend();
00251 }
00252
00256 Constructor::Vars_iter
00257 Constructor::get_vars_iter(int i)
00258 {
00259 return _vars.begin() + i;
00260 }
00261
00265 BaseType *
00266 Constructor::get_var_index(int i)
00267 {
00268 return *(_vars.begin() + i);
00269 }
00270
00271
00272 void
00273 Constructor::print_decl(FILE *out, string space, bool print_semi,
00274 bool constraint_info, bool constrained)
00275 {
00276 if (constrained && !send_p())
00277 return;
00278
00279 fprintf(out, "%s%s {\n", space.c_str(), type_name().c_str()) ;
00280 for (Vars_citer i = _vars.begin(); i != _vars.end(); i++) {
00281 (*i)->print_decl(out, space + " ", true,
00282 constraint_info, constrained);
00283 }
00284 fprintf(out, "%s} %s", space.c_str(), id2www(name()).c_str()) ;
00285
00286 if (constraint_info) {
00287 if (send_p())
00288 cout << ": Send True";
00289 else
00290 cout << ": Send False";
00291 }
00292
00293 if (print_semi)
00294 fprintf(out, ";\n") ;
00295 }
00296
00297 class PrintField : public unary_function<BaseType *, void>
00298 {
00299 FILE *d_out;
00300 string d_space;
00301 bool d_constrained;
00302 public:
00303 PrintField(FILE *o, string s, bool c)
00304 : d_out(o), d_space(s), d_constrained(c)
00305 {}
00306
00307 void operator()(BaseType *btp)
00308 {
00309 btp->print_xml(d_out, d_space, d_constrained);
00310 }
00311 };
00312
00313 void
00314 Constructor::print_xml(FILE *out, string space, bool constrained)
00315 {
00316 if (constrained && !send_p())
00317 return;
00318
00319 bool has_attributes = false;
00320 bool has_variables = (var_begin() != var_end());
00321
00322 fprintf(out, "%s<%s", space.c_str(), type_name().c_str());
00323 if (!name().empty())
00324 fprintf(out, " name=\"%s\"", id2xml(name()).c_str());
00325
00326 if (has_attributes || has_variables) {
00327 fprintf(out, ">\n");
00328
00329 get_attr_table().print_xml(out, space + " ", constrained);
00330
00331 for_each(var_begin(), var_end(),
00332 PrintField(out, space + " ", constrained));
00333
00334 fprintf(out, "%s</%s>\n", space.c_str(), type_name().c_str());
00335 }
00336 else {
00337 fprintf(out, "/>\n");
00338 }
00339 }
00340
00353 bool
00354 Constructor::is_linear()
00355 {
00356 return false;
00357 }
00358
00367 void
00368 Constructor::dump(ostream &strm) const
00369 {
00370 strm << DapIndent::LMarg << "Constructor::dump - ("
00371 << (void *)this << ")" << endl ;
00372 DapIndent::Indent() ;
00373 BaseType::dump(strm) ;
00374 strm << DapIndent::LMarg << "vars: " << endl ;
00375 DapIndent::Indent() ;
00376 Vars_citer i = _vars.begin() ;
00377 Vars_citer ie = _vars.end() ;
00378 for (; i != ie; i++) {
00379 (*i)->dump(strm) ;
00380 }
00381 DapIndent::UnIndent() ;
00382 DapIndent::UnIndent() ;
00383 }
00384