libdap++  Updated for version 3.8.2
Structure.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 1994-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 // Implementation for the class Structure
33 //
34 // jhrg 9/14/94
35 
36 //#define DODS_DEBUG
37 
38 #include "config.h"
39 
40 #include "Byte.h"
41 #include "Int16.h"
42 #include "UInt16.h"
43 #include "Int32.h"
44 #include "UInt32.h"
45 #include "Float32.h"
46 #include "Float64.h"
47 #include "Str.h"
48 #include "Url.h"
49 #include "Array.h"
50 #include "Structure.h"
51 #include "Sequence.h"
52 #include "Grid.h"
53 
54 #include "util.h"
55 #include "debug.h"
56 #include "InternalErr.h"
57 #include "escaping.h"
58 
59 using std::cerr;
60 using std::endl;
61 
62 namespace libdap {
63 
64 void
66 {
67  Structure &cs = const_cast<Structure &>(s);
68 
69  DBG(cerr << "Copying structure: " << name() << endl);
70 
71  for (Vars_iter i = cs._vars.begin(); i != cs._vars.end(); i++) {
72  DBG(cerr << "Copying field: " << (*i)->name() << endl);
73  // Jose Garcia
74  // I think this assert here is part of a debugging
75  // process since it is going along with a DBG call
76  // I leave it here since it can be remove by defining NDEBUG.
77  // assert(*i);
78  BaseType *btp = (*i)->ptr_duplicate();
79  btp->set_parent(this);
80  _vars.push_back(btp);
81  }
82 }
83 
92 {}
93 
103 Structure::Structure(const string &n, const string &d)
105 {}
106 
109 {
110  _duplicate(rhs);
111 }
112 
114 {
115  for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
116  BaseType *btp = *i ;
117  delete btp ; btp = 0;
118  }
119 }
120 
121 BaseType *
123 {
124  return new Structure(*this);
125 }
126 
127 Structure &
129 {
130  if (this == &rhs)
131  return *this;
132 
133  dynamic_cast<Constructor &>(*this) = rhs; // run Constructor=
134 
135  _duplicate(rhs);
136 
137  return *this;
138 }
139 
140 int
142 {
143  if (!leaves)
144  return _vars.size();
145  else {
146  int i = 0;
147  for (Vars_iter j = _vars.begin(); j != _vars.end(); j++) {
148  j += (*j)->element_count(leaves);
149  }
150  return i;
151  }
152 }
153 
154 bool
156 {
157  bool linear = true;
158  for (Vars_iter i = _vars.begin(); linear && i != _vars.end(); i++) {
159  if ((*i)->type() == dods_structure_c)
160  linear = linear && dynamic_cast<Structure*>((*i))->is_linear();
161  else
162  linear = linear && (*i)->is_simple_type();
163  }
164 
165  return linear;
166 }
167 
168 void
170 {
171  for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
172  (*i)->set_send_p(state);
173  }
174 
175  BaseType::set_send_p(state);
176 }
177 
178 void
180 {
181  for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
182  (*i)->set_read_p(state);
183  }
184 
185  BaseType::set_read_p(state);
186 }
187 
193 void
195 {
196  for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
197  (*i)->set_in_selection(state);
198  }
199 
201 }
202 
204 void
206 {
207  for (Vars_iter i = var_begin(); i != var_end(); i++) {
208  if ((*i)->type() == dods_sequence_c)
209  dynamic_cast<Sequence&>(**i).set_leaf_sequence(++level);
210  else if ((*i)->type() == dods_structure_c)
211  dynamic_cast<Structure&>(**i).set_leaf_sequence(level);
212  }
213 }
214 
219 void
221 {
222  // Jose Garcia
223  // Passing and invalid pointer to an object is a developer's error.
224  if (!bt)
225  throw InternalErr(__FILE__, __LINE__,
226  "The BaseType parameter cannot be null.");
227 
228  // Jose Garcia
229  // Now we add a copy of bt so the external user is able to destroy bt as
230  // he/she wishes. The policy is: "If it is allocated outside, it is
231  // deallocated outside, if it is allocated inside, it is deallocated
232  // inside"
233  BaseType *btp = bt->ptr_duplicate();
234  btp->set_parent(this);
235  _vars.push_back(btp);
236 }
237 
241 void
242 Structure::del_var(const string &n)
243 {
244  for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
245  if ((*i)->name() == n) {
246  BaseType *bt = *i ;
247  _vars.erase(i) ;
248  delete bt ; bt = 0;
249  return;
250  }
251  }
252 }
253 
259 bool
261 {
262  if( !read_p() )
263  {
264  for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
265  (*i)->read() ;
266  }
267  set_read_p(true) ;
268  }
269 
270  return false ;
271 }
272 
273 unsigned int
275 {
276  unsigned int sz = 0;
277 
278  for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
279  sz += (*i)->width();
280  }
281 
282  return sz;
283 }
284 
285 void
287 {
288  DBG(cerr << "Structure::intern_data: " << name() << endl);
289  if (!read_p())
290  read(); // read() throws Error and InternalErr
291 
292  for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
293  if ((*i)->send_p()) {
294  (*i)->intern_data(eval, dds);
295  }
296  }
297 }
298 
299 bool
301  Marshaller &m, bool ce_eval)
302 {
303  dds.timeout_on();
304 
305  if (!read_p())
306  read(); // read() throws Error and InternalErr
307 
308 #if EVAL
309  if (ce_eval && !eval.eval_selection(dds, dataset()))
310  return true;
311 #endif
312 
313  dds.timeout_off();
314 
315  for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
316  if ((*i)->send_p()) {
317  (*i)->serialize(eval, dds, m, false);
318  }
319  }
320 
321  return true;
322 }
323 
324 bool
326 {
327  for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
328  (*i)->deserialize(um, dds, reuse);
329  }
330 
331  return false;
332 }
333 
343 unsigned int
344 Structure::val2buf(void *, bool)
345 {
346  return sizeof(Structure);
347 }
348 
352 unsigned int
354 {
355  return sizeof(Structure);
356 }
357 
358 BaseType *
359 Structure::var(const string &name, bool exact_match, btp_stack *s)
360 {
361  string n = www2id(name);
362 
363  if (exact_match)
364  return m_exact_match(n, s);
365  else
366  return m_leaf_match(n, s);
367 }
368 
370 BaseType *
371 Structure::var(const string &n, btp_stack &s)
372 {
373  string name = www2id(n);
374 
375  BaseType *btp = m_exact_match(name, &s);
376  if (btp)
377  return btp;
378 
379  return m_leaf_match(name, &s);
380 }
381 
382 // Private method to find a variable using the shorthand name. This
383 // should be moved to Constructor.
384 BaseType *
385 Structure::m_leaf_match(const string &name, btp_stack *s)
386 {
387  for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
388  if ((*i)->name() == name) {
389  if (s) {
390  DBG(cerr << "Pushing " << this->name() << endl);
391  s->push(static_cast<BaseType *>(this));
392  }
393  return *i;
394  }
395  if ((*i)->is_constructor_type()) {
396  BaseType *btp = (*i)->var(name, false, s);
397  if (btp) {
398  if (s) {
399  DBG(cerr << "Pushing " << this->name() << endl);
400  s->push(static_cast<BaseType *>(this));
401  }
402  return btp;
403  }
404  }
405  }
406 
407  return 0;
408 }
409 
410 // Breadth-first search for NAME. If NAME contains one or more dots (.)
411 BaseType *
412 Structure::m_exact_match(const string &name, btp_stack *s)
413 {
414  for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
415  DBG(cerr << "Looking at " << (*i)->name() << " in: " << *i
416  << endl);
417  if ((*i)->name() == name) {
418  DBG(cerr << "Found " << (*i)->name() << " in: "
419  << *i << endl);
420  if (s) {
421  DBG(cerr << "Pushing " << this->name() << endl);
422  s->push(static_cast<BaseType *>(this));
423  }
424  return *i;
425  }
426  }
427 
428  string::size_type dot_pos = name.find("."); // zero-based index of `.'
429  if (dot_pos != string::npos) {
430  string aggregate = name.substr(0, dot_pos);
431  string field = name.substr(dot_pos + 1);
432 
433  BaseType *agg_ptr = var(aggregate);
434  if (agg_ptr) {
435  DBG(cerr << "Descending into " << agg_ptr->name() << endl);
436  if (s) {
437  DBG(cerr << "Pushing " << this->name() << endl);
438  s->push(static_cast<BaseType *>(this));
439  }
440  return agg_ptr->var(field, true, s); // recurse
441  }
442  else
443  return 0; // qualified names must be *fully* qualified
444  }
445 
446  return 0;
447 }
448 
449 #if FILE_METHODS
450 void
451 Structure::print_val(FILE *out, string space, bool print_decl_p)
452 {
453  if (print_decl_p) {
454  print_decl(out, space, false);
455  fprintf(out, " = ") ;
456  }
457 
458  fprintf(out, "{ ") ;
459  for (Vars_citer i = _vars.begin(); i != _vars.end();
460  i++, (void)(i != _vars.end() && fprintf(out, ", "))) {
461  (*i)->print_val(out, "", false);
462  }
463 
464  fprintf(out, " }") ;
465 
466  if (print_decl_p)
467  fprintf(out, ";\n") ;
468 }
469 #endif
470 
471 void
472 Structure::print_val(ostream &out, string space, bool print_decl_p)
473 {
474  if (print_decl_p) {
475  print_decl(out, space, false);
476  out << " = " ;
477  }
478 
479  out << "{ " ;
480  for (Vars_citer i = _vars.begin(); i != _vars.end();
481  i++, (void)(i != _vars.end() && out << ", ")) {
482  (*i)->print_val(out, "", false);
483  }
484 
485  out << " }" ;
486 
487  if (print_decl_p)
488  out << ";\n" ;
489 }
490 
491 bool
492 Structure::check_semantics(string &msg, bool all)
493 {
494  if (!BaseType::check_semantics(msg))
495  return false;
496 
497  bool status = true;
498 
499  if (!unique_names(_vars, name(), type_name(), msg))
500  return false;
501 
502  if (all) {
503  for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
504  //assert(*i);
505  if (!(*i)->check_semantics(msg, true)) {
506  status = false;
507  goto exit;
508  }
509  }
510  }
511 
512 exit:
513  return status;
514 }
515 
524 void
525 Structure::dump(ostream &strm) const
526 {
527  strm << DapIndent::LMarg << "Structure::dump - ("
528  << (void *)this << ")" << endl ;
530  Constructor::dump(strm) ;
532 }
533 
534 } // namespace libdap
535 
virtual bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval=true)
Move data to the net.
Definition: Structure.cc:300
virtual bool read_p()
Has this variable been read?
Definition: BaseType.cc:444
static void UnIndent()
Definition: DapIndent.cc:49
abstract base class used to unmarshall/deserialize dap data objects
Definition: UnMarshaller.h:54
virtual void intern_data(ConstraintEvaluator &eval, DDS &dds)
Definition: Structure.cc:286
Structure & operator=(const Structure &rhs)
Definition: Structure.cc:128
virtual BaseType * ptr_duplicate()
Definition: Structure.cc:122
Part
Names the parts of multi-section constructor data types.
Definition: BaseType.h:98
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: Structure.cc:359
virtual bool check_semantics(string &msg, bool all=false)
Compare an object's current state with the semantics of its type.
Definition: Structure.cc:492
std::vector< BaseType * > _vars
Definition: Constructor.h:48
std::vector< BaseType * >::iterator Vars_iter
Definition: Constructor.h:61
Structure(const string &n)
Definition: Structure.cc:91
void _duplicate(const Structure &s)
Definition: Structure.cc:65
void timeout_off()
Definition: DDS.cc:687
virtual void add_var(BaseType *bt, Part part=nil)
Definition: Structure.cc:220
Holds a structure (aggregate) type.
Definition: Structure.h:100
virtual void set_in_selection(bool state)
Definition: BaseType.cc:625
virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse=false)
Receive data from the net.
Definition: Structure.cc:325
stack< BaseType * > btp_stack
Definition: BaseType.h:214
virtual void set_parent(BaseType *parent)
Definition: BaseType.cc:638
virtual void set_leaf_sequence(int level=1)
Traverse Structure, set Sequence leaf nodes.
Definition: Structure.cc:205
virtual void set_in_selection(bool state)
Set the in_selection property.
Definition: Structure.cc:194
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:231
bool eval_selection(DDS &dds, const string &dataset)
Evaluate a boolean-valued constraint expression. This is main method for the evaluator ans is called ...
#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 void set_send_p(bool state)
Definition: BaseType.cc:517
static void Indent()
Definition: DapIndent.cc:43
virtual unsigned int width()
Returns the size of the class instance data.
Definition: Structure.cc:274
virtual void set_read_p(bool state)
Sets the value of the read_p property.
Definition: BaseType.cc:483
virtual int element_count(bool leaves=false)
Count the members of constructor types.
Definition: Structure.cc:141
virtual unsigned int val2buf(void *val, bool reuse=false)
Never call this.
Definition: Structure.cc:344
virtual void dump(ostream &strm) const
dumps information about this object
Definition: Constructor.cc:502
virtual unsigned int buf2val(void **val)
Never call this.
Definition: Structure.cc:353
virtual void del_var(const string &name)
Definition: Structure.cc:242
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 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:679
BaseType(const string &n, const Type &t)
The BaseType constructor.
Definition: BaseType.cc:110
Evaluate a constraint expression.
static ostream & LMarg(ostream &strm)
Definition: DapIndent.cc:78
The basic data type for the DODS DAP types.
Definition: BaseType.h:190
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:361
virtual bool is_linear()
Check to see whether this variable can be printed simply.
Definition: Structure.cc:155
Vars_iter var_begin()
Definition: Constructor.cc:101
bool unique_names(vector< BaseType * > l, const string &var_name, const string &type_name, string &msg)
Definition: util.cc:119
virtual void print_val(FILE *out, string space="", bool print_decl_p=true)
Prints the value of the variable.
Definition: Structure.cc:451
Vars_iter var_end()
Definition: Constructor.cc:295
virtual void set_send_p(bool state)
Definition: Structure.cc:169
virtual void dump(ostream &strm) const
dumps information about this object
Definition: Structure.cc:525
virtual void set_read_p(bool state)
Sets the value of the read_p property.
Definition: Structure.cc:179
virtual bool read()
simple implementation of reat that iterates through vars and calls read on them
Definition: Structure.cc:260
virtual ~Structure()
Definition: Structure.cc:113
virtual bool check_semantics(string &msg, bool all=false)
Compare an object's current state with the semantics of its type.
Definition: BaseType.cc:1036