libdap++  Updated for version 3.11.7
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 
106 #if 0
107 
125 BaseType *
126 Constructor::find_hdf4_dimension_attribute_home(AttrTable::entry *source)
127 {
128  BaseType *btp;
129  string::size_type i = source->name.find("_dim_");
130  if (i != string::npos && (btp = var(source->name.substr(0, i)))) {
131  if (btp->is_vector_type()) {
132  return btp;
133  }
134  else if (btp->type() == dods_grid_c) {
135  // For a Grid, the hdf4 handler uses _dim_n for the n-th Map
136  // i+5 points to the character holding 'n'
137  int n = atoi(source->name.substr(i + 5).c_str());
138  DBG(cerr << "Found a Grid (" << btp->name() << ") and "
139  << source->name.substr(i) << ", extracted n: " << n << endl);
140  return *(dynamic_cast<Grid&>(*btp).map_begin() + n);
141  }
142  }
143 
144  return 0;
145 }
146 #endif
147 #if 0
148 
150 AttrTable *
151 Constructor::find_matching_container(AttrTable::entry *source,
152  BaseType **dest_variable)
153 {
154  // The attribute entry 'source' must be a container
155  if (source->type != Attr_container)
156  throw InternalErr(__FILE__, __LINE__, "Constructor::find_matching_container");
157 
158  // Use the name of the attribute container 'source' to figure out where
159  // to put its contents.
160  BaseType *btp;
161  if ((btp = var(source->name))) {
162  // ... matches a variable name? Use var's table
163  *dest_variable = btp;
164  return &btp->get_attr_table();
165  }
166  // As more special-case attribute containers come to light, add clauses
167  // here.
168  else if ((btp = find_hdf4_dimension_attribute_home(source))) {
169  // ... hdf4 dimension attribute? Make a sub table and use that.
170  // btp can only be an Array or a Grid Map (which is an array)
171  if (btp->get_parent()->type() == dods_grid_c) {
172  DBG(cerr << "Found a Grid" << endl);
173  *dest_variable = btp;
174  return &btp->get_attr_table();
175  }
176  else { // must be a plain Array
177  string::size_type i = source->name.find("_dim_");
178  string ext = source->name.substr(i + 1);
179  *dest_variable = btp;
180  return btp->get_attr_table().append_container(ext);
181  }
182  }
183  else {
184  // ... otherwise assume it's a global attribute.
185  AttrTable *at = get_attr_table().find_container(source->name);
186  if (!at) {
187  at = new AttrTable(); // Make a new global table if needed
188  get_attr_table().append_container(at, source->name);
189  }
190 
191  *dest_variable = 0;
192  return at;
193  }
194 }
195 #endif
196 #if 0
197 
214 void
215 Constructor::transfer_attributes(AttrTable::entry * entry)
216 {
217  DBG(cerr << "Constructor::transfer_attributes, variable: " << name() <<
218  endl);
219  DBG(cerr << "Working on the '" << entry->
220  name << "' container." << endl);
221  if (entry->type != Attr_container)
222  throw InternalErr(__FILE__, __LINE__,
223  "Constructor::transfer_attributes");
224 
225  AttrTable *source = entry->attributes;
226  BaseType *dest_variable = 0;
227  AttrTable *dest = find_matching_container(entry, &dest_variable);
228 
229  // foreach source attribute in the das_i container
230  AttrTable::Attr_iter source_p = source->attr_begin();
231  while (source_p != source->attr_end()) {
232  DBG(cerr << "Working on the '" << (*source_p)->
233  name << "' attribute" << endl);
234 
235  if ((*source_p)->type == Attr_container) {
236  if (dest_variable && dest_variable->is_constructor_type()) {
237  dynamic_cast <Constructor & >(*dest_variable).transfer_attributes(*source_p);
238  }
239  else {
240  dest->append_container(new AttrTable(*(*source_p)->attributes),
241  (*source_p)->name);
242  }
243  }
244  else {
245  dest->append_attr(source->get_name(source_p),
246  source->get_type(source_p),
247  source->get_attr_vector(source_p));
248  }
249 
250  ++source_p;
251  }
252 }
253 #endif
254 
265  AttrTable *at = at_container->get_attr_table(name());
266 
267  if (at) {
268  at->set_is_global_attribute(false);
269 
270  Vars_iter var = var_begin();
271  while (var != var_end()) {
272  try {
273  DBG(cerr << "Processing the attributes for: " << (*var)->name() << " a " << (*var)->type_name() << endl);
274  (*var)->transfer_attributes(at);
275  var++;
276  } catch (Error &e) {
277  DBG(cerr << "Got this exception: " << e.get_error_message() << endl);
278  var++;
279  throw e;
280  }
281  }
282 
283  // Trick: If an attribute that's within the container 'at' still has its
284  // is_global_attribute property set, then it's not really a global attr
285  // but instead an attribute that belongs to this Constructor.
286  AttrTable::Attr_iter at_p = at->attr_begin();
287  while (at_p != at->attr_end()) {
288  if (at->is_global_attribute(at_p)) {
289  if (at->get_attr_type(at_p) == Attr_container)
290  get_attr_table().append_container(new AttrTable(*at->get_attr_table(at_p)), at->get_name(at_p));
291  else
292  get_attr_table().append_attr(at->get_name(at_p), at->get_type(at_p), at->get_attr_vector(at_p));
293  }
294  at_p++;
295  }
296 
297  }
298 }
299 
304 {
305  return _vars.end() ;
306 }
307 
311 {
312  return _vars.rbegin();
313 }
314 
319 {
320  return _vars.rend();
321 }
322 
328 {
329  return _vars.begin() + i;
330 }
331 
335 BaseType *
337 {
338  return *(_vars.begin() + i);
339 }
340 
341 #if FILE_METHODS
342 void
343 Constructor::print_decl(FILE *out, string space, bool print_semi,
344  bool constraint_info, bool constrained)
345 {
346  if (constrained && !send_p())
347  return;
348 
349  fprintf(out, "%s%s {\n", space.c_str(), type_name().c_str()) ;
350  for (Vars_citer i = _vars.begin(); i != _vars.end(); i++) {
351  (*i)->print_decl(out, space + " ", true,
352  constraint_info, constrained);
353  }
354  fprintf(out, "%s} %s", space.c_str(), id2www(name()).c_str()) ;
355 
356  if (constraint_info) { // Used by test drivers only.
357  if (send_p())
358  cout << ": Send True";
359  else
360  cout << ": Send False";
361  }
362 
363  if (print_semi)
364  fprintf(out, ";\n") ;
365 }
366 #endif
367 
368 void
369 Constructor::print_decl(ostream &out, string space, bool print_semi,
370  bool constraint_info, bool constrained)
371 {
372  if (constrained && !send_p())
373  return;
374 
375  out << space << type_name() << " {\n" ;
376  for (Vars_citer i = _vars.begin(); i != _vars.end(); i++) {
377  (*i)->print_decl(out, space + " ", true,
378  constraint_info, constrained);
379  }
380  out << space << "} " << id2www(name()) ;
381 
382  if (constraint_info) { // Used by test drivers only.
383  if (send_p())
384  out << ": Send True";
385  else
386  out << ": Send False";
387  }
388 
389  if (print_semi)
390  out << ";\n" ;
391 }
392 
393 #if FILE_METHODS
394 class PrintField : public unary_function<BaseType *, void>
395 {
396  FILE *d_out;
397  string d_space;
398  bool d_constrained;
399 public:
400  PrintField(FILE *o, string s, bool c)
401  : d_out(o), d_space(s), d_constrained(c)
402  {}
403 
404  void operator()(BaseType *btp)
405  {
406  btp->print_xml(d_out, d_space, d_constrained);
407  }
408 };
409 
413 void
414 Constructor::print_xml(FILE *out, string space, bool constrained)
415 {
416  if (constrained && !send_p())
417  return;
418 
419  bool has_attributes = false; // *** fix me
420  bool has_variables = (var_begin() != var_end());
421 
422  fprintf(out, "%s<%s", space.c_str(), type_name().c_str());
423  if (!name().empty())
424  fprintf(out, " name=\"%s\"", id2xml(name()).c_str());
425 
426  if (has_attributes || has_variables) {
427  fprintf(out, ">\n");
428 
429  get_attr_table().print_xml(out, space + " ", constrained);
430 
431  for_each(var_begin(), var_end(),
432  PrintField(out, space + " ", constrained));
433 
434  fprintf(out, "%s</%s>\n", space.c_str(), type_name().c_str());
435  }
436  else {
437  fprintf(out, "/>\n");
438  }
439 }
440 #endif
441 
442 class PrintFieldStrm : public unary_function<BaseType *, void>
443 {
444  ostream &d_out;
445  string d_space;
446  bool d_constrained;
447 public:
448  PrintFieldStrm(ostream &o, string s, bool c)
449  : d_out(o), d_space(s), d_constrained(c)
450  {}
451 
452  void operator()(BaseType *btp)
453  {
454  btp->print_xml(d_out, d_space, d_constrained);
455  }
456 };
457 
461 void
462 Constructor::print_xml(ostream &out, string space, bool constrained)
463 {
464  if (constrained && !send_p())
465  return;
466 
467  bool has_attributes = false; // *** fix me
468  bool has_variables = (var_begin() != var_end());
469 
470  out << space << "<" << type_name() ;
471  if (!name().empty())
472  out << " name=\"" << id2xml(name()) << "\"" ;
473 
474  if (has_attributes || has_variables) {
475  out << ">\n" ;
476 
477  get_attr_table().print_xml(out, space + " ", constrained);
478 
479  for_each(var_begin(), var_end(),
480  PrintFieldStrm(out, space + " ", constrained));
481 
482  out << space << "</" << type_name() << ">\n" ;
483  }
484  else {
485  out << "/>\n" ;
486  }
487 }
488 
489 class PrintFieldXMLWriter : public unary_function<BaseType *, void>
490 {
491  XMLWriter &d_xml;
492  bool d_constrained;
493 public:
494  PrintFieldXMLWriter(XMLWriter &x, bool c)
495  : d_xml(x), d_constrained(c)
496  {}
497 
498  void operator()(BaseType *btp)
499  {
500  btp->print_xml_writer(d_xml, d_constrained);
501  }
502 };
503 
504 void
506 {
507  if (constrained && !send_p())
508  return;
509 
510  if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)type_name().c_str()) < 0)
511  throw InternalErr(__FILE__, __LINE__, "Could not write " + type_name() + " element");
512 
513  if (!name().empty())
514  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)name().c_str()) < 0)
515  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
516 
517  bool has_attributes = false; // FIXME
518  bool has_variables = (var_begin() != var_end());
519  if (has_attributes || has_variables) {
521 
522  for_each(var_begin(), var_end(), PrintFieldXMLWriter(xml, constrained));
523  }
524 
525  if (xmlTextWriterEndElement(xml.get_writer()) < 0)
526  throw InternalErr(__FILE__, __LINE__, "Could not end " + type_name() + " element");
527 }
528 
541 bool
543 {
544  return false;
545 }
546 
555 void
556 Constructor::dump(ostream &strm) const
557 {
558  strm << DapIndent::LMarg << "Constructor::dump - ("
559  << (void *)this << ")" << endl ;
561  BaseType::dump(strm) ;
562  strm << DapIndent::LMarg << "vars: " << endl ;
564  Vars_citer i = _vars.begin() ;
565  Vars_citer ie = _vars.end() ;
566  for (; i != ie; i++) {
567  (*i)->dump(strm) ;
568  }
571 }
572 
573 } // namespace libdap
574 
std::vector< entry * >::iterator Attr_iter
Definition: AttrTable.h:237
virtual ~Constructor()
Definition: Constructor.cc:83
static void UnIndent()
Definition: DapIndent.cc:49
virtual Attr_iter attr_end()
Definition: AttrTable.cc:724
std::vector< BaseType * >::reverse_iterator Vars_riter
Definition: Constructor.h:62
Contains the attributes for a dataset.
Definition: AttrTable.h:150
string get_error_message() const
Definition: Error.cc:279
virtual string get_type(const string &name)
Get the type name of an attribute within this attribute table.
Definition: AttrTable.cc:618
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:1303
Vars_riter var_rend()
Definition: Constructor.cc:318
virtual bool is_global_attribute() const
Definition: AttrTable.h:284
string id2xml(string in, const string &not_allowed)
Definition: escaping.cc:270
virtual void set_is_global_attribute(bool ga)
Definition: AttrTable.h:285
void print_xml_writer(XMLWriter &xml)
Definition: AttrTable.cc:1409
virtual AttrTable * find_container(const string &target)
Find an attribute with a given name.
Definition: AttrTable.cc:571
Type
Identifies the data type.
Definition: BaseType.h:135
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:242
Constructor & operator=(const Constructor &rhs)
Definition: Constructor.cc:87
A class for software fault reporting.
Definition: InternalErr.h:64
virtual bool is_vector_type()
Returns true if the instance is a vector (i.e., array) type variable.
Definition: BaseType.cc:324
xmlTextWriterPtr get_writer()
Definition: XMLWriter.h:36
virtual void print_xml(ostream &out, string space=" ", bool constrained=false)
Definition: Constructor.cc:462
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:660
#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:542
Vars_riter var_rbegin()
Definition: Constructor.cc:310
virtual void transfer_attributes(AttrTable *at_container)
Definition: Constructor.cc:264
virtual AttrTable * append_container(const string &name)
Add a container to the attribute table.
Definition: AttrTable.cc:414
static void Indent()
Definition: DapIndent.cc:43
virtual AttrTable * get_attr_table(const string &name)
Get an attribute container.
Definition: AttrTable.cc:612
virtual void dump(ostream &strm) const
dumps information about this object
Definition: BaseType.cc:186
BaseType * get_var_index(int i)
Definition: Constructor.cc:336
virtual void dump(ostream &strm) const
dumps information about this object
Definition: Constructor.cc:556
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:716
virtual void print_xml_writer(XMLWriter &xml, bool constrained=false)
Definition: Constructor.cc:505
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:311
The basic data type for the DODS DAP types.
Definition: BaseType.h:194
virtual AttrType get_attr_type(const string &name)
Get the type of an attribute.
Definition: AttrTable.cc:626
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:369
Vars_iter var_begin()
Definition: Constructor.cc:101
Vars_iter var_end()
Definition: Constructor.cc:303
virtual vector< string > * get_attr_vector(const string &name)
Get a vector-valued attribute.
Definition: AttrTable.cc:658
Vars_iter get_vars_iter(int i)
Definition: Constructor.cc:327
A class for error processing.
Definition: Error.h:90
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