libdap++  Updated for version 3.8.2
Constructor.cc
Go to the documentation of this file.
1 
2 // -*- mode: c++; c-basic-offset:4 -*-
3 
4 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
5 // Access Protocol.
6 
7 // Copyright (c) 2002,2003 OPeNDAP, Inc.
8 // Author: James Gallagher <jgallagher@opendap.org>
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 //
24 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25 
26 // (c) COPYRIGHT URI/MIT 1995-1999
27 // Please read the full copyright statement in the file COPYRIGHT_URI.
28 //
29 // Authors:
30 // jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
31 
32 
33 #include "config.h"
34 
35 #include <string>
36 #include <algorithm>
37 #include <functional>
38 
39 //#define DODS_DEBUG
40 
41 #include "Constructor.h"
42 #include "Grid.h"
43 
44 #include "debug.h"
45 #include "escaping.h"
46 #include "Error.h"
47 #include "InternalErr.h"
48 
49 
50 using namespace std;
51 
52 namespace libdap {
53 
54 // Private member functions
55 
56 void
57 Constructor::_duplicate(const Constructor &)
58 {}
59 
60 // Public member functions
61 
62 Constructor::Constructor(const string &n, const Type &t)
63  : BaseType(n, t)
64 {}
65 
76 Constructor::Constructor(const string &n, const string &d, const Type &t)
77  : BaseType(n, d, t)
78 {}
79 
80 Constructor::Constructor(const Constructor &rhs) : BaseType(rhs), _vars(0)
81 {}
82 
84 {}
85 
88 {
89  if (this == &rhs)
90  return *this;
91 
92  dynamic_cast<BaseType &>(*this) = rhs; // run BaseType=
93 
94  _duplicate(rhs);
95 
96  return *this;
97 }
98 
102 {
103  return _vars.begin() ;
104 }
105 
121 BaseType *
122 Constructor::find_hdf4_dimension_attribute_home(AttrTable::entry *source)
123 {
124  BaseType *btp;
125  string::size_type i = source->name.find("_dim_");
126  if (i != string::npos && (btp = var(source->name.substr(0, i)))) {
127  if (btp->is_vector_type()) {
128  return btp;
129  }
130  else if (btp->type() == dods_grid_c) {
131  // For a Grid, the hdf4 handler uses _dim_n for the n-th Map
132  // i+5 points to the character holding 'n'
133  int n = atoi(source->name.substr(i + 5).c_str());
134  DBG(cerr << "Found a Grid (" << btp->name() << ") and "
135  << source->name.substr(i) << ", extracted n: " << n << endl);
136  return *(dynamic_cast<Grid&>(*btp).map_begin() + n);
137  }
138  }
139 
140  return 0;
141 }
142 
143 #if 0
144 
146 AttrTable *
147 Constructor::find_matching_container(AttrTable::entry *source,
148  BaseType **dest_variable)
149 {
150  // The attribute entry 'source' must be a container
151  if (source->type != Attr_container)
152  throw InternalErr(__FILE__, __LINE__, "Constructor::find_matching_container");
153 
154  // Use the name of the attribute container 'source' to figure out where
155  // to put its contents.
156  BaseType *btp;
157  if ((btp = var(source->name))) {
158  // ... matches a variable name? Use var's table
159  *dest_variable = btp;
160  return &btp->get_attr_table();
161  }
162  // As more special-case attribute containers come to light, add clauses
163  // here.
164  else if ((btp = find_hdf4_dimension_attribute_home(source))) {
165  // ... hdf4 dimension attribute? Make a sub table and use that.
166  // btp can only be an Array or a Grid Map (which is an array)
167  if (btp->get_parent()->type() == dods_grid_c) {
168  DBG(cerr << "Found a Grid" << endl);
169  *dest_variable = btp;
170  return &btp->get_attr_table();
171  }
172  else { // must be a plain Array
173  string::size_type i = source->name.find("_dim_");
174  string ext = source->name.substr(i + 1);
175  *dest_variable = btp;
176  return btp->get_attr_table().append_container(ext);
177  }
178  }
179  else {
180  // ... otherwise assume it's a global attribute.
181  AttrTable *at = get_attr_table().find_container(source->name);
182  if (!at) {
183  at = new AttrTable(); // Make a new global table if needed
184  get_attr_table().append_container(at, source->name);
185  }
186 
187  *dest_variable = 0;
188  return at;
189  }
190 }
191 #endif
192 #if 0
193 
210 void
211 Constructor::transfer_attributes(AttrTable::entry * entry)
212 {
213  DBG(cerr << "Constructor::transfer_attributes, variable: " << name() <<
214  endl);
215  DBG(cerr << "Working on the '" << entry->
216  name << "' container." << endl);
217  if (entry->type != Attr_container)
218  throw InternalErr(__FILE__, __LINE__,
219  "Constructor::transfer_attributes");
220 
221  AttrTable *source = entry->attributes;
222  BaseType *dest_variable = 0;
223  AttrTable *dest = find_matching_container(entry, &dest_variable);
224 
225  // foreach source attribute in the das_i container
226  AttrTable::Attr_iter source_p = source->attr_begin();
227  while (source_p != source->attr_end()) {
228  DBG(cerr << "Working on the '" << (*source_p)->
229  name << "' attribute" << endl);
230 
231  if ((*source_p)->type == Attr_container) {
232  if (dest_variable && dest_variable->is_constructor_type()) {
233  dynamic_cast <Constructor & >(*dest_variable).transfer_attributes(*source_p);
234  }
235  else {
236  dest->append_container(new AttrTable(*(*source_p)->attributes),
237  (*source_p)->name);
238  }
239  }
240  else {
241  dest->append_attr(source->get_name(source_p),
242  source->get_type(source_p),
243  source->get_attr_vector(source_p));
244  }
245 
246  ++source_p;
247  }
248 }
249 #endif
250 
261 {
262  AttrTable *at = at_container->get_attr_table(name());
263 
264  if (at) {
265  at->set_is_global_attribute(false);
266 
267  Vars_iter var = var_begin();
268  while (var != var_end()) {
269  (*var)->transfer_attributes(at);
270  var++;
271  }
272 
273  // Trick: If an attribute that's within the container 'at' still has its
274  // is_global_attribute property set, then it's not really a global attr
275  // but instead an attribute that belongs to this Constructor.
276  AttrTable::Attr_iter at_p = at->attr_begin();
277  while (at_p != at->attr_end()) {
278  if (at->is_global_attribute(at_p)) {
279  if (at->get_attr_type(at_p) == Attr_container)
281  *at->get_attr_table(at_p)), at->get_name(at_p));
282  else
283  get_attr_table().append_attr(at->get_name(at_p),
284  at->get_type(at_p), at->get_attr_vector(at_p));
285  }
286  at_p++;
287  }
288 
289  }
290 }
291 
296 {
297  return _vars.end() ;
298 }
299 
303 {
304  return _vars.rbegin();
305 }
306 
311 {
312  return _vars.rend();
313 }
314 
320 {
321  return _vars.begin() + i;
322 }
323 
327 BaseType *
329 {
330  return *(_vars.begin() + i);
331 }
332 
333 #if FILE_METHODS
334 void
335 Constructor::print_decl(FILE *out, string space, bool print_semi,
336  bool constraint_info, bool constrained)
337 {
338  if (constrained && !send_p())
339  return;
340 
341  fprintf(out, "%s%s {\n", space.c_str(), type_name().c_str()) ;
342  for (Vars_citer i = _vars.begin(); i != _vars.end(); i++) {
343  (*i)->print_decl(out, space + " ", true,
344  constraint_info, constrained);
345  }
346  fprintf(out, "%s} %s", space.c_str(), id2www(name()).c_str()) ;
347 
348  if (constraint_info) { // Used by test drivers only.
349  if (send_p())
350  cout << ": Send True";
351  else
352  cout << ": Send False";
353  }
354 
355  if (print_semi)
356  fprintf(out, ";\n") ;
357 }
358 #endif
359 
360 void
361 Constructor::print_decl(ostream &out, string space, bool print_semi,
362  bool constraint_info, bool constrained)
363 {
364  if (constrained && !send_p())
365  return;
366 
367  out << space << type_name() << " {\n" ;
368  for (Vars_citer i = _vars.begin(); i != _vars.end(); i++) {
369  (*i)->print_decl(out, space + " ", true,
370  constraint_info, constrained);
371  }
372  out << space << "} " << id2www(name()) ;
373 
374  if (constraint_info) { // Used by test drivers only.
375  if (send_p())
376  out << ": Send True";
377  else
378  out << ": Send False";
379  }
380 
381  if (print_semi)
382  out << ";\n" ;
383 }
384 
385 #if FILE_METHODS
386 class PrintField : public unary_function<BaseType *, void>
387 {
388  FILE *d_out;
389  string d_space;
390  bool d_constrained;
391 public:
392  PrintField(FILE *o, string s, bool c)
393  : d_out(o), d_space(s), d_constrained(c)
394  {}
395 
396  void operator()(BaseType *btp)
397  {
398  btp->print_xml(d_out, d_space, d_constrained);
399  }
400 };
401 
402 void
403 Constructor::print_xml(FILE *out, string space, bool constrained)
404 {
405  if (constrained && !send_p())
406  return;
407 
408  bool has_attributes = false; // *** fix me
409  bool has_variables = (var_begin() != var_end());
410 
411  fprintf(out, "%s<%s", space.c_str(), type_name().c_str());
412  if (!name().empty())
413  fprintf(out, " name=\"%s\"", id2xml(name()).c_str());
414 
415  if (has_attributes || has_variables) {
416  fprintf(out, ">\n");
417 
418  get_attr_table().print_xml(out, space + " ", constrained);
419 
420  for_each(var_begin(), var_end(),
421  PrintField(out, space + " ", constrained));
422 
423  fprintf(out, "%s</%s>\n", space.c_str(), type_name().c_str());
424  }
425  else {
426  fprintf(out, "/>\n");
427  }
428 }
429 #endif
430 
431 class PrintFieldStrm : public unary_function<BaseType *, void>
432 {
433  ostream &d_out;
434  string d_space;
435  bool d_constrained;
436 public:
437  PrintFieldStrm(ostream &o, string s, bool c)
438  : d_out(o), d_space(s), d_constrained(c)
439  {}
440 
441  void operator()(BaseType *btp)
442  {
443  btp->print_xml(d_out, d_space, d_constrained);
444  }
445 };
446 
447 void
448 Constructor::print_xml(ostream &out, string space, bool constrained)
449 {
450  if (constrained && !send_p())
451  return;
452 
453  bool has_attributes = false; // *** fix me
454  bool has_variables = (var_begin() != var_end());
455 
456  out << space << "<" << type_name() ;
457  if (!name().empty())
458  out << " name=\"" << id2xml(name()) << "\"" ;
459 
460  if (has_attributes || has_variables) {
461  out << ">\n" ;
462 
463  get_attr_table().print_xml(out, space + " ", constrained);
464 
465  for_each(var_begin(), var_end(),
466  PrintFieldStrm(out, space + " ", constrained));
467 
468  out << space << "</" << type_name() << ">\n" ;
469  }
470  else {
471  out << "/>\n" ;
472  }
473 }
474 
487 bool
489 {
490  return false;
491 }
492 
501 void
502 Constructor::dump(ostream &strm) const
503 {
504  strm << DapIndent::LMarg << "Constructor::dump - ("
505  << (void *)this << ")" << endl ;
507  BaseType::dump(strm) ;
508  strm << DapIndent::LMarg << "vars: " << endl ;
510  Vars_citer i = _vars.begin() ;
511  Vars_citer ie = _vars.end() ;
512  for (; i != ie; i++) {
513  (*i)->dump(strm) ;
514  }
517 }
518 
519 } // namespace libdap
520 
std::vector< entry * >::iterator Attr_iter
Definition: AttrTable.h:233
virtual ~Constructor()
Definition: Constructor.cc:83
static void UnIndent()
Definition: DapIndent.cc:49
virtual Attr_iter attr_end()
Definition: AttrTable.cc:652
std::vector< BaseType * >::reverse_iterator Vars_riter
Definition: Constructor.h:62
Contains the attributes for a dataset.
Definition: AttrTable.h:146
virtual string get_type(const string &name)
Get the type name of an attribute within this attribute table.
Definition: AttrTable.cc:546
std::vector< BaseType * > _vars
Definition: Constructor.h:48
std::vector< BaseType * >::iterator Vars_iter
Definition: Constructor.h:61
virtual void print_xml(FILE *out, string pad=" ", bool constrained=false)
Definition: AttrTable.cc:1212
Vars_riter var_rend()
Definition: Constructor.cc:310
virtual bool is_global_attribute() const
Definition: AttrTable.h:280
string id2xml(string in, const string &not_allowed)
Definition: escaping.cc:270
virtual void set_is_global_attribute(bool ga)
Definition: AttrTable.h:281
virtual AttrTable * find_container(const string &target)
Find an attribute with a given name.
Definition: AttrTable.cc:498
Type
Identifies the data type.
Definition: BaseType.h:131
Type type() const
Returns the type of the class instance.
Definition: BaseType.cc:238
virtual string get_name() const
Get the name of this attribute table.
Definition: AttrTable.cc:208
Constructor & operator=(const Constructor &rhs)
Definition: Constructor.cc:87
virtual bool is_vector_type()
Returns true if the instance is a vector (i.e., array) type variable.
Definition: BaseType.cc:324
virtual void print_xml(ostream &out, string space=" ", bool constrained=false)
Definition: Constructor.cc:448
virtual BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=0)
Returns a pointer to a member of a constructor class.
Definition: BaseType.cc:662
#define DBG(x)
Definition: debug.h:58
string type_name() const
Returns the type of the class instance as a string.
Definition: BaseType.cc:252
virtual bool is_linear()
Check to see whether this variable can be printed simply.
Definition: Constructor.cc:488
Vars_riter var_rbegin()
Definition: Constructor.cc:302
virtual void transfer_attributes(AttrTable *at_container)
Definition: Constructor.cc:260
virtual AttrTable * append_container(const string &name)
Add a container to the attribute table.
Definition: AttrTable.cc:342
static void Indent()
Definition: DapIndent.cc:43
virtual AttrTable * get_attr_table(const string &name)
Get an attribute container.
Definition: AttrTable.cc:539
virtual void dump(ostream &strm) const
dumps information about this object
Definition: BaseType.cc:186
BaseType * get_var_index(int i)
Definition: Constructor.cc:328
virtual void dump(ostream &strm) const
dumps information about this object
Definition: Constructor.cc:502
string name() const
Returns the name of the class instance.
Definition: BaseType.cc:210
std::vector< BaseType * >::const_iterator Vars_citer
Definition: Constructor.h:60
virtual Attr_iter attr_begin()
Definition: AttrTable.cc:643
BaseType(const string &n, const Type &t)
The BaseType constructor.
Definition: BaseType.cc:110
static ostream & LMarg(ostream &strm)
Definition: DapIndent.cc:78
virtual AttrTable & get_attr_table()
Definition: BaseType.cc:531
virtual unsigned int append_attr(const string &name, const string &type, const string &value)
Add an attribute to the table.
Definition: AttrTable.cc:239
The basic data type for the DODS DAP types.
Definition: BaseType.h:190
virtual AttrType get_attr_type(const string &name)
Get the type of an attribute.
Definition: AttrTable.cc:555
virtual void print_decl(ostream &out, string space=" ", bool print_semi=true, bool constraint_info=false, bool constrained=false)
Print an ASCII representation of the variable structure.
Definition: Constructor.cc:361
Vars_iter var_begin()
Definition: Constructor.cc:101
Vars_iter var_end()
Definition: Constructor.cc:295
virtual vector< string > * get_attr_vector(const string &name)
Get a vector-valued attribute.
Definition: AttrTable.cc:588
Vars_iter get_vars_iter(int i)
Definition: Constructor.cc:319
virtual bool send_p()
Should this variable be sent?
Definition: BaseType.cc:503
string id2www(string in, const string &allowable)
Definition: escaping.cc:151
void _duplicate(const Constructor &s)
Definition: Constructor.cc:57