libdap++  Updated for version 3.12.0
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 <sstream>
37 #include <algorithm>
38 #include <functional>
39 
40 //#define DODS_DEBUG
41 
42 #include "Constructor.h"
43 #include "Grid.h"
44 
45 #include "debug.h"
46 #include "escaping.h"
47 #include "util.h"
48 #include "Error.h"
49 #include "InternalErr.h"
50 
51 
52 using namespace std;
53 
54 namespace libdap {
55 
56 // Private member functions
57 
58 void
59 Constructor::m_duplicate(const Constructor &c)
60 {
61  Constructor &cs = const_cast<Constructor &>(c);
62 
63  for (Vars_iter i = cs.d_vars.begin(); i != cs.d_vars.end(); i++) {
64  BaseType *btp = (*i)->ptr_duplicate();
65  btp->set_parent(this);
66  d_vars.push_back(btp);
67  }
68 }
69 
70 // Public member functions
71 
72 Constructor::Constructor(const string &n, const Type &t, bool is_dap4)
73  : BaseType(n, t, is_dap4)
74 {}
75 
86 Constructor::Constructor(const string &n, const string &d, const Type &t, bool is_dap4)
87  : BaseType(n, d, t, is_dap4)
88 {}
89 
90 Constructor::Constructor(const Constructor &rhs) : BaseType(rhs), d_vars(0)
91 {}
92 
94 {}
95 
98 {
99  if (this == &rhs)
100  return *this;
101 
102  dynamic_cast<BaseType &>(*this) = rhs; // run BaseType=
103 
104  m_duplicate(rhs);
105 
106  return *this;
107 }
108 
109 int
111 {
112  if (!leaves)
113  return d_vars.size();
114  else {
115  int i = 0;
116  for (Vars_iter j = d_vars.begin(); j != d_vars.end(); j++) {
117  i += (*j)->element_count(leaves);
118  }
119  return i;
120  }
121 }
122 
123 void
125 {
126  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
127  (*i)->set_send_p(state);
128  }
129 
130  BaseType::set_send_p(state);
131 }
132 
133 void
135 {
136  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
137  (*i)->set_read_p(state);
138  }
139 
140  BaseType::set_read_p(state);
141 }
142 
143 #if 0
144 // TODO Recode to use width(bool). Bur see comments in BaseType.h
145 unsigned int
147 {
148  unsigned int sz = 0;
149 
150  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
151  sz += (*i)->width();
152  }
153 
154  return sz;
155 }
156 #endif
157 
164 unsigned int
165 Constructor::width(bool constrained)
166 {
167  unsigned int sz = 0;
168 
169  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
170  if (constrained) {
171  if ((*i)->send_p())
172  sz += (*i)->width(constrained);
173  }
174  else {
175  sz += (*i)->width(constrained);
176  }
177  }
178 
179  return sz;
180 }
181 
182 BaseType *
183 Constructor::var(const string &name, bool exact_match, btp_stack *s)
184 {
185  string n = www2id(name);
186 
187  if (exact_match)
188  return m_exact_match(n, s);
189  else
190  return m_leaf_match(n, s);
191 }
192 
194 BaseType *
195 Constructor::var(const string &n, btp_stack &s)
196 {
197  string name = www2id(n);
198 
199  BaseType *btp = m_exact_match(name, &s);
200  if (btp)
201  return btp;
202 
203  return m_leaf_match(name, &s);
204 }
205 
206 // Protected method
207 BaseType *
208 Constructor::m_leaf_match(const string &name, btp_stack *s)
209 {
210  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
211  if ((*i)->name() == name) {
212  if (s) {
213  DBG(cerr << "Pushing " << this->name() << endl);
214  s->push(static_cast<BaseType *>(this));
215  }
216  return *i;
217  }
218  if ((*i)->is_constructor_type()) {
219  BaseType *btp = (*i)->var(name, false, s);
220  if (btp) {
221  if (s) {
222  DBG(cerr << "Pushing " << this->name() << endl);
223  s->push(static_cast<BaseType *>(this));
224  }
225  return btp;
226  }
227  }
228  }
229 
230  return 0;
231 }
232 
233 // Protected method
234 BaseType *
235 Constructor::m_exact_match(const string &name, btp_stack *s)
236 {
237  // Look for name at the top level first.
238  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
239  if ((*i)->name() == name) {
240  if (s)
241  s->push(static_cast<BaseType *>(this));
242 
243  return *i;
244  }
245  }
246 
247  // If it was not found using the simple search, look for a dot and
248  // search the hierarchy.
249  string::size_type dot_pos = name.find("."); // zero-based index of `.'
250  if (dot_pos != string::npos) {
251  string aggregate = name.substr(0, dot_pos);
252  string field = name.substr(dot_pos + 1);
253 
254  BaseType *agg_ptr = var(aggregate);
255  if (agg_ptr) {
256  if (s)
257  s->push(static_cast<BaseType *>(this));
258 
259  return agg_ptr->var(field, true, s); // recurse
260  }
261  else
262  return 0; // qualified names must be *fully* qualified
263  }
264 
265  return 0;
266 }
267 
271 {
272  return d_vars.begin() ;
273 }
274 
279 {
280  return d_vars.end() ;
281 }
282 
286 {
287  return d_vars.rbegin();
288 }
289 
294 {
295  return d_vars.rend();
296 }
297 
303 {
304  return d_vars.begin() + i;
305 }
306 
310 BaseType *
312 {
313  return *(d_vars.begin() + i);
314 }
315 
320 void
322 {
323  // Jose Garcia
324  // Passing and invalid pointer to an object is a developer's error.
325  if (!bt)
326  throw InternalErr(__FILE__, __LINE__, "The BaseType parameter cannot be null.");
327 #if 0
328  if (bt->is_dap4_only_type())
329  throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Structure.");
330 #endif
331  // Jose Garcia
332  // Now we add a copy of bt so the external user is able to destroy bt as
333  // he/she wishes. The policy is: "If it is allocated outside, it is
334  // deallocated outside, if it is allocated inside, it is deallocated
335  // inside"
336  BaseType *btp = bt->ptr_duplicate();
337  btp->set_parent(this);
338  d_vars.push_back(btp);
339 }
340 
345 void
347 {
348  if (!bt)
349  throw InternalErr(__FILE__, __LINE__, "The BaseType parameter cannot be null.");
350 #if 0
351  if (bt->is_dap4_only_type())
352  throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Structure.");
353 #endif
354  bt->set_parent(this);
355  d_vars.push_back(bt);
356 }
357 
361 void
362 Constructor::del_var(const string &n)
363 {
364  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
365  if ((*i)->name() == n) {
366  BaseType *bt = *i ;
367  d_vars.erase(i) ;
368  delete bt ; bt = 0;
369  return;
370  }
371  }
372 }
373 
374 void
376 {
377  if (*i != 0) {
378  BaseType *bt = *i;
379  d_vars.erase(i);
380  delete bt;
381  }
382 }
383 
390 {
391  if (!read_p()) {
392  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
393  (*i)->read();
394  }
395  set_read_p(true);
396  }
397 
398  return false;
399 }
400 
401 void
403 {
404  DBG(cerr << "Structure::intern_data: " << name() << endl);
405  if (!read_p())
406  read(); // read() throws Error and InternalErr
407 
408  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
409  if ((*i)->send_p()) {
410  (*i)->intern_data(eval, dds);
411  }
412  }
413 }
414 
415 bool
417 {
418  dds.timeout_on();
419 
420  if (!read_p())
421  read(); // read() throws Error and InternalErr
422 
423 #if EVAL
424  if (ce_eval && !eval.eval_selection(dds, dataset()))
425  return true;
426 #endif
427 
428  dds.timeout_off();
429 
430  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
431  if ((*i)->send_p()) {
432 #ifdef CHECKSUMS
433  XDRStreamMarshaller *sm = dynamic_cast<XDRStreamMarshaller*>(&m);
434  if (sm && sm->checksums() && (*i)->type() != dods_structure_c && (*i)->type() != dods_grid_c)
435  sm->reset_checksum();
436 
437  (*i)->serialize(eval, dds, m, false);
438 
439  if (sm && sm->checksums() && (*i)->type() != dods_structure_c && (*i)->type() != dods_grid_c)
440  sm->get_checksum();
441 #else
442  (*i)->serialize(eval, dds, m, false);
443 #endif
444  }
445  }
446 
447  return true;
448 }
449 
450 bool
452 {
453  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
454  (*i)->deserialize(um, dds, reuse);
455  }
456 
457  return false;
458 }
459 
460 void
461 Constructor::print_decl(FILE *out, string space, bool print_semi,
462  bool constraint_info, bool constrained)
463 {
464  ostringstream oss;
465  print_decl(oss, space, print_semi, constraint_info, constrained);
466  fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
467 }
468 
469 void
470 Constructor::print_decl(ostream &out, string space, bool print_semi,
471  bool constraint_info, bool constrained)
472 {
473  if (constrained && !send_p())
474  return;
475 
476  out << space << type_name() << " {\n" ;
477  for (Vars_citer i = d_vars.begin(); i != d_vars.end(); i++) {
478  (*i)->print_decl(out, space + " ", true, constraint_info, constrained);
479  }
480  out << space << "} " << id2www(name()) ;
481 
482  if (constraint_info) { // Used by test drivers only.
483  if (send_p())
484  out << ": Send True";
485  else
486  out << ": Send False";
487  }
488 
489  if (print_semi)
490  out << ";\n" ;
491 }
492 
493 void
494 Constructor::print_val(FILE *out, string space, bool print_decl_p)
495 {
496  ostringstream oss;
497  print_val(oss, space, print_decl_p);
498  fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
499 }
500 
501 void
502 Constructor::print_val(ostream &out, string space, bool print_decl_p)
503 {
504  if (print_decl_p) {
505  print_decl(out, space, false);
506  out << " = " ;
507  }
508 
509  out << "{ " ;
510  for (Vars_citer i = d_vars.begin(); i != d_vars.end();
511  i++, (void)(i != d_vars.end() && out << ", ")) {
512  (*i)->print_val(out, "", false);
513  }
514 
515  out << " }" ;
516 
517  if (print_decl_p)
518  out << ";\n" ;
519 }
520 
524 void
525 Constructor::print_xml(FILE *out, string space, bool constrained)
526 {
527  XMLWriter xml(space);
528  print_xml_writer(xml, constrained);
529  fwrite(xml.get_doc(), sizeof(char), xml.get_doc_size(), out);
530 }
531 
535 void
536 Constructor::print_xml(ostream &out, string space, bool constrained)
537 {
538  XMLWriter xml(space);
539  print_xml_writer(xml, constrained);
540  out << xml.get_doc();
541 }
542 
543 class PrintFieldXMLWriter : public unary_function<BaseType *, void>
544 {
545  XMLWriter &d_xml;
546  bool d_constrained;
547 public:
548  PrintFieldXMLWriter(XMLWriter &x, bool c)
549  : d_xml(x), d_constrained(c)
550  {}
551 
552  void operator()(BaseType *btp)
553  {
554  btp->print_xml_writer(d_xml, d_constrained);
555  }
556 };
557 
558 void
560 {
561  if (constrained && !send_p())
562  return;
563 
564  if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)type_name().c_str()) < 0)
565  throw InternalErr(__FILE__, __LINE__, "Could not write " + type_name() + " element");
566 
567  if (!name().empty())
568  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)name().c_str()) < 0)
569  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
570 
571  bool has_attributes = get_attr_table().get_size() > 0;
572  bool has_variables = (var_begin() != var_end());
573  if (has_attributes)
575  if (has_variables)
576  for_each(var_begin(), var_end(), PrintFieldXMLWriter(xml, constrained));
577 
578  if (xmlTextWriterEndElement(xml.get_writer()) < 0)
579  throw InternalErr(__FILE__, __LINE__, "Could not end " + type_name() + " element");
580 }
581 
582 bool
583 Constructor::check_semantics(string &msg, bool all)
584 {
585  if (!BaseType::check_semantics(msg))
586  return false;
587 
588  if (!unique_names(d_vars, name(), type_name(), msg))
589  return false;
590 
591  if (all)
592  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
593  if (!(*i)->check_semantics(msg, true)) {
594  return false;
595  }
596  }
597 
598  return true;
599 }
600 
613 bool
615 {
616  return false;
617 }
618 
624 void
626 {
627  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
628  (*i)->set_in_selection(state);
629  }
630 
632 }
633 
642 void
643 Constructor::dump(ostream &strm) const
644 {
645  strm << DapIndent::LMarg << "Constructor::dump - ("
646  << (void *)this << ")" << endl ;
648  BaseType::dump(strm) ;
649  strm << DapIndent::LMarg << "vars: " << endl ;
651  Vars_citer i = d_vars.begin() ;
652  Vars_citer ie = d_vars.end() ;
653  for (; i != ie; i++) {
654  (*i)->dump(strm) ;
655  }
658 }
659 
660 } // namespace libdap
661 
virtual bool read_p()
Has this variable been read?
Definition: BaseType.cc:579
virtual ~Constructor()
Definition: Constructor.cc:93
virtual void set_in_selection(bool state)
Set the in_selection property.
Definition: Constructor.cc:625
static void UnIndent()
Definition: DapIndent.cc:49
abstract base class used to unmarshall/deserialize dap data objects
Definition: UnMarshaller.h:54
unsigned int get_doc_size()
Definition: XMLWriter.cc:127
void m_duplicate(const Constructor &s)
Definition: Constructor.cc:59
virtual BaseType * var(const string &name, bool exact_match=true, btp_stack *s=0)
btp_stack no longer needed; use back pointers (BaseType::get_parent())
Definition: Constructor.cc:183
Part
Names the parts of multi-section constructor data types.
Definition: BaseType.h:95
std::vector< BaseType * >::reverse_iterator Vars_riter
Definition: Constructor.h:57
std::vector< BaseType * > d_vars
Definition: Constructor.h:43
virtual void intern_data(ConstraintEvaluator &eval, DDS &dds)
Definition: Constructor.cc:402
std::vector< BaseType * >::iterator Vars_iter
Definition: Constructor.h:56
Vars_riter var_rend()
Definition: Constructor.cc:293
void print_xml_writer(XMLWriter &xml)
Definition: AttrTable.cc:1415
virtual void add_var_nocopy(BaseType *bt, Part part=nil)
Definition: Constructor.cc:346
void timeout_off()
Definition: DDS.cc:862
virtual void add_var(BaseType *bt, Part part=nil)
Definition: Constructor.cc:321
Type
Identifies the data type.
Definition: BaseType.h:137
Constructor & operator=(const Constructor &rhs)
Definition: Constructor.cc:97
virtual void set_in_selection(bool state)
Definition: BaseType.cc:755
virtual int element_count(bool leaves=false)
Count the members of constructor types.
Definition: Constructor.cc:110
stack< BaseType * > btp_stack
Definition: BaseType.h:233
virtual void set_parent(BaseType *parent)
Definition: BaseType.cc:770
A class for software fault reporting.
Definition: InternalErr.h:64
string dataset() const
Returns the name of the dataset used to create this instance.
Definition: BaseType.cc:275
bool eval_selection(DDS &dds, const string &dataset)
Evaluate a boolean-valued constraint expression. This is main method for the evaluator ans is called ...
xmlTextWriterPtr get_writer()
Definition: XMLWriter.h:58
virtual void print_xml(ostream &out, string space=" ", bool constrained=false)
Definition: Constructor.cc:536
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:795
#define DBG(x)
Definition: debug.h:58
string type_name() const
Returns the type of the class instance as a string.
Definition: BaseType.cc:296
virtual bool is_linear()
Check to see whether this variable can be printed simply.
Definition: Constructor.cc:614
virtual void set_send_p(bool state)
Definition: BaseType.cc:652
Vars_riter var_rbegin()
Definition: Constructor.cc:285
static void Indent()
Definition: DapIndent.cc:43
virtual bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval=true)
Move data to the net.
Definition: Constructor.cc:416
virtual void dump(ostream &strm) const
dumps information about this object
Definition: BaseType.cc:230
BaseType * get_var_index(int i)
Definition: Constructor.cc:311
virtual bool read()
simple implementation of read that iterates through vars and calls read on them
Definition: Constructor.cc:389
virtual void set_read_p(bool state)
Sets the value of the read_p property.
Definition: BaseType.cc:618
virtual bool check_semantics(string &msg, bool all=false)
Compare an object's current state with the semantics of its type.
Definition: Constructor.cc:583
virtual void dump(ostream &strm) const
dumps information about this object
Definition: Constructor.cc:643
virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse=false)
Receive data from the net.
Definition: Constructor.cc:451
virtual void print_val(FILE *out, string space="", bool print_decl_p=true)
Prints the value of the variable.
Definition: Constructor.cc:494
string name() const
Returns the name of the class instance.
Definition: BaseType.cc:254
BaseType * m_leaf_match(const string &name, btp_stack *s=0)
Definition: Constructor.cc:208
std::vector< BaseType * >::const_iterator Vars_citer
Definition: Constructor.h:55
virtual void print_xml_writer(XMLWriter &xml, bool constrained=false)
Definition: Constructor.cc:559
virtual BaseType * ptr_duplicate()=0
string www2id(const string &in, const string &escape, const string &except)
Definition: escaping.cc:218
void timeout_on()
Definition: DDS.cc:854
virtual unsigned int width(bool constrained=false)
Definition: Constructor.cc:165
Evaluate a constraint expression.
static ostream & LMarg(ostream &strm)
Definition: DapIndent.cc:78
const char * get_doc()
Definition: XMLWriter.cc:103
virtual AttrTable & get_attr_table()
Definition: BaseType.cc:666
The basic data type for the DODS DAP types.
Definition: BaseType.h:199
abstract base class used to marshal/serialize dap data objects
Definition: Marshaller.h:53
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:470
Vars_iter var_begin()
Definition: Constructor.cc:270
BaseType * m_exact_match(const string &name, btp_stack *s=0)
Definition: Constructor.cc:235
bool unique_names(vector< BaseType * > l, const string &var_name, const string &type_name, string &msg)
Definition: util.cc:338
Vars_iter var_end()
Definition: Constructor.cc:278
Vars_iter get_vars_iter(int i)
Definition: Constructor.cc:302
virtual void del_var(const string &name)
Definition: Constructor.cc:362
virtual void set_send_p(bool state)
Definition: Constructor.cc:124
marshaller that knows how to marshal/serialize dap data objects to a C++ iostream using XDR ...
virtual bool send_p()
Should this variable be sent?
Definition: BaseType.cc:638
virtual unsigned int get_size() const
Get the number of entries in this attribute table.
Definition: AttrTable.cc:235
string id2www(string in, const string &allowable)
Definition: escaping.cc:151
virtual void set_read_p(bool state)
Sets the value of the read_p property.
Definition: Constructor.cc:134
virtual bool check_semantics(string &msg, bool all=false)
Compare an object's current state with the semantics of its type.
Definition: BaseType.cc:1153