libdap Updated for version 3.21.1
libdap4 is an implementation of OPeNDAP's DAP protocol.
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., 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 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 <sstream>
41
42#include "Array.h"
43#include "Byte.h"
44#include "Float32.h"
45#include "Float64.h"
46#include "Grid.h"
47#include "Int16.h"
48#include "Int32.h"
49#include "Sequence.h"
50#include "Str.h"
51#include "Structure.h"
52#include "UInt16.h"
53#include "UInt32.h"
54#include "Url.h"
55
56#include "ConstraintEvaluator.h"
57#include "DDS.h"
58
59#include "D4Attributes.h"
60#include "D4Group.h"
61
62#include "DapIndent.h"
63#include "InternalErr.h"
64#include "XDRStreamMarshaller.h"
65#include "debug.h"
66#include "escaping.h"
67#include "util.h"
68
69using std::cerr;
70using std::endl;
71
72namespace libdap {
73
74#if 0
79void
81{
82 Constructor::m_duplicate(s);
83#if 0
84 Structure &cs = const_cast<Structure &>(s);
85
86 DBG(cerr << "Copying structure: " << name() << endl);
87
88 for (Vars_iter i = cs.d_vars.begin(); i != cs.d_vars.end(); i++) {
89 DBG(cerr << "Copying field: " << (*i)->name() << endl);
90 // Jose Garcia
91 // I think this assert here is part of a debugging
92 // process since it is going along with a DBG call
93 // I leave it here since it can be remove by defining NDEBUG.
94 // assert(*i);
95 BaseType *btp = (*i)->ptr_duplicate();
96 btp->set_parent(this);
97 d_vars.push_back(btp);
98 }
99#endif
100}
101#endif
102
111
121Structure::Structure(const string &n, const string &d) : Constructor(n, d, dods_structure_c) {}
122
125 DBG(cerr << "In Structure::copy_ctor for " << name() << endl);
126 // m_duplicate(rhs);
127}
128
130
132
143 DBG(cerr << __func__ << "() - BEGIN" << endl;);
144 // Here we create a new Structure and then use it
145 // as the target container for the transformed versions of
146 // all the member variables by calling Constructor::transform_to_dap4() and
147 // passing our new target Structure in as the target container.
148 Structure *dest = new Structure(name());
149 DBG(cerr << __func__ << "() - Calling Constructor::transform_to_dap4(" << "'" << root->name()
150 << "':" << (void *)root
151 << ","
152 "'"
153 << dest->name() << "':" << (void *)dest << ")" << endl;);
155 container->add_var_nocopy(dest);
156 DBG(cerr << __func__ << "() - Added new Structure '" << dest->name() << "' (" << (void *)dest
157 << ") to the container '" << container->name() << "'" << endl;);
158 DBG(cerr << __func__ << "() - END" << endl;);
159}
160
168 DBG(cerr << " " << __func__ << " BEGIN" << endl);
169 Structure *dest = new Structure(name());
170
171 // convert the Structure's d4 attributes to a dap2 attribute table.
172#if 0
173 AttrTable *attrs = this->attributes()->get_AttrTable(name());
174#else
175 if (dest->get_attr_table().get_size() == 0) {
177 dest->get_attr_table().set_name(name());
178 }
179#endif
180
181 dest->set_is_dap4(false);
182
183 vector<BaseType *> dropped_vars;
184 for (Structure::Vars_citer i = var_begin(), e = var_end(); i != e; ++i) {
185 vector<BaseType *> *new_vars = (*i)->transform_to_dap2(&dest->get_attr_table() /*attrs*/);
186 if (new_vars) { // Might be un-mappable
187 // It's not so game on..
188#if 0
189 vector<BaseType*>::iterator vIter = new_vars->begin();
190 vector<BaseType*>::iterator end = new_vars->end();
191#endif
192 for (vector<BaseType *>::iterator vi = new_vars->begin(), ve = new_vars->end(); vi != ve; ++vi) {
193 BaseType *new_var = (*vi);
194 new_var->set_parent(dest);
195 dest->add_var_nocopy(new_var);
196 (*vi) = NULL;
197 }
198 delete new_vars;
199
200 } else {
201 // Got a NULL, so we are dropping this var.
202 dropped_vars.push_back(*i);
203 }
204 }
205
206 AttrTable *dv_attr_table = make_dropped_vars_attr_table(&dropped_vars);
207 if (dv_attr_table) {
208 dest->get_attr_table().append_container(dv_attr_table, dv_attr_table->get_name());
209 }
210
211 DBG(attrs->print(cerr, "", true););
212
213#if 0
214 // Since this does a copy we gotta delete the attrs when done
215 // FIXME This is a bug. jhrg 6/17/19
216 dest->set_attr_table(*attrs);
217 delete attrs;
218#endif
219
220 vector<BaseType *> *result = new vector<BaseType *>();
221 result->push_back(dest);
222
223 DBG(cerr << " " << __func__ << " END" << endl);
224
225 return result;
226}
227
229 if (this == &rhs)
230 return *this;
232 return *this;
233}
234
236 bool linear = true;
237 for (Vars_iter i = d_vars.begin(); linear && i != d_vars.end(); i++) {
238 if ((*i)->type() == dods_structure_c)
239 linear = linear && static_cast<Structure *>((*i))->is_linear();
240 else
241 linear = linear && (*i)->is_simple_type();
242 }
243
244 return linear;
245}
246
247#if 0
248void
249Structure::set_send_p(bool state)
250{
251 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
252 (*i)->set_send_p(state);
253 }
254
256}
257
258void
259Structure::set_read_p(bool state)
260{
261 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
262 (*i)->set_read_p(state);
263 }
264
266}
267#endif
268#if 0
274void
276{
277 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
278 (*i)->set_in_selection(state);
279 }
280
282}
283#endif
286 for (Vars_iter i = var_begin(); i != var_end(); i++) {
287 if ((*i)->type() == dods_sequence_c)
288 static_cast<Sequence &>(**i).set_leaf_sequence(++level);
289 else if ((*i)->type() == dods_structure_c)
290 static_cast<Structure &>(**i).set_leaf_sequence(level);
291 }
292}
293
294#if 0
299void
301{
302 // Jose Garcia
303 // Passing and invalid pointer to an object is a developer's error.
304 if (!bt)
305 throw InternalErr(__FILE__, __LINE__, "The BaseType parameter cannot be null.");
306
307 if (bt->is_dap4_only_type())
308 throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Structure.");
309
310 // Jose Garcia
311 // Now we add a copy of bt so the external user is able to destroy bt as
312 // he/she wishes. The policy is: "If it is allocated outside, it is
313 // deallocated outside, if it is allocated inside, it is deallocated
314 // inside"
315 BaseType *btp = bt->ptr_duplicate();
316 btp->set_parent(this);
317 d_vars.push_back(btp);
318}
319
324void
325Structure::add_var_nocopy(BaseType *bt, Part)
326{
327 if (!bt)
328 throw InternalErr(__FILE__, __LINE__, "The BaseType parameter cannot be null.");
329
330 if (bt->is_dap4_only_type())
331 throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Structure.");
332
333 bt->set_parent(this);
334 d_vars.push_back(bt);
335}
336
337
341void
342Structure::del_var(const string &n)
343{
344 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
345 if ((*i)->name() == n) {
346 BaseType *bt = *i ;
347 d_vars.erase(i) ;
348 delete bt ; bt = 0;
349 return;
350 }
351 }
352}
353#endif
354#if 0
360bool Structure::read()
361{
362 if (!read_p()) {
363 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
364 (*i)->read();
365 }
366 set_read_p(true);
367 }
368
369 return false;
370}
371#endif
372#if 0
373// TODO Recode to use width(bool)
374unsigned int
376{
377 unsigned int sz = 0;
378
379 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
380 sz += (*i)->width();
381 }
382
383 return sz;
384}
385
393unsigned int
394Structure::width(bool constrained)
395{
396 unsigned int sz = 0;
397
398 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
399 if (constrained) {
400 if ((*i)->send_p())
401 sz += (*i)->width(constrained);
402 }
403 else {
404 sz += (*i)->width(constrained);
405 }
406 }
407
408 return sz;
409}
410#endif
411
412#if 0
413void
415{
416 DBG(cerr << "Structure::intern_data: " << name() << endl);
417 if (!read_p())
418 read(); // read() throws Error and InternalErr
419
420 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
421 if ((*i)->send_p()) {
422 (*i)->intern_data(eval, dds);
423 }
424 }
425}
426
427bool
429 Marshaller &m, bool ce_eval)
430{
431#if USE_LOCAL_TIMEOUT_SCHEME
432 dds.timeout_on();
433#endif
434 if (!read_p())
435 read(); // read() throws Error and InternalErr
436
437#if EVAL
438 if (ce_eval && !eval.eval_selection(dds, dataset()))
439 return true;
440#endif
441#if USE_LOCAL_TIMEOUT_SCHEME
442 dds.timeout_off();
443#endif
444 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
445 if ((*i)->send_p()) {
446#ifdef CHECKSUMS
447 XDRStreamMarshaller *sm = dynamic_cast<XDRStreamMarshaller*>(&m);
448 if (sm && sm->checksums() && (*i)->type() != dods_structure_c && (*i)->type() != dods_grid_c)
449 sm->reset_checksum();
450
451 (*i)->serialize(eval, dds, m, false);
452
453 if (sm && sm->checksums() && (*i)->type() != dods_structure_c && (*i)->type() != dods_grid_c)
454 sm->get_checksum();
455#else
456 (*i)->serialize(eval, dds, m, false);
457#endif
458 }
459 }
460
461 return true;
462}
463
464bool
465Structure::deserialize(UnMarshaller &um, DDS *dds, bool reuse)
466{
467 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
468 (*i)->deserialize(um, dds, reuse);
469 }
470
471 return false;
472}
473#endif
474#if 0
484unsigned int
485Structure::val2buf(void *, bool)
486{
487 return sizeof(Structure);
488}
489
493unsigned int
494Structure::buf2val(void **)
495{
496 return sizeof(Structure);
497}
498#endif
499
500#if 0
501BaseType *
502Structure::var(const string &name, bool exact_match, btp_stack *s)
503{
504 string n = www2id(name);
505
506 if (exact_match)
507 return m_exact_match(n, s);
508 else
509 return m_leaf_match(n, s);
510}
511
513BaseType *
514Structure::var(const string &n, btp_stack &s)
515{
516 string name = www2id(n);
517
518 BaseType *btp = m_exact_match(name, &s);
519 if (btp)
520 return btp;
521
522 return m_leaf_match(name, &s);
523}
524#endif
525#if 0
526// Private method to find a variable using the shorthand name. This
527// should be moved to Constructor.
528BaseType *
529Structure::m_leaf_match(const string &name, btp_stack *s)
530{
531 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
532 if ((*i)->name() == name) {
533 if (s) {
534 DBG(cerr << "Pushing " << this->name() << endl);
535 s->push(static_cast<BaseType *>(this));
536 }
537 return *i;
538 }
539 if ((*i)->is_constructor_type()) {
540 BaseType *btp = (*i)->var(name, false, s);
541 if (btp) {
542 if (s) {
543 DBG(cerr << "Pushing " << this->name() << endl);
544 s->push(static_cast<BaseType *>(this));
545 }
546 return btp;
547 }
548 }
549 }
550
551 return 0;
552}
553
554// Breadth-first search for NAME. If NAME contains one or more dots (.)
555// TODO The btp_stack is not needed since there are 'back pointers' in
556// BaseType.
557BaseType *
558Structure::m_exact_match(const string &name, btp_stack *s)
559{
560 // Look for name at the top level first.
561 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
562 if ((*i)->name() == name) {
563 if (s)
564 s->push(static_cast<BaseType *>(this));
565
566 return *i;
567 }
568 }
569
570 // If it was not found using the simple search, look for a dot and
571 // search the hierarchy.
572 string::size_type dot_pos = name.find("."); // zero-based index of `.'
573 if (dot_pos != string::npos) {
574 string aggregate = name.substr(0, dot_pos);
575 string field = name.substr(dot_pos + 1);
576
577 BaseType *agg_ptr = var(aggregate);
578 if (agg_ptr) {
579 if (s)
580 s->push(static_cast<BaseType *>(this));
581
582 return agg_ptr->var(field, true, s); // recurse
583 }
584 else
585 return 0; // qualified names must be *fully* qualified
586 }
587
588 return 0;
589}
590#endif
591#if 0
592void
593Structure::print_val(FILE *out, string space, bool print_decl_p)
594{
595 ostringstream oss;
596 print_val(oss, space, print_decl_p);
597 fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
598}
599
600void
601Structure::print_val(ostream &out, string space, bool print_decl_p)
602{
603 if (print_decl_p) {
604 print_decl(out, space, false);
605 out << " = " ;
606 }
607
608 out << "{ " ;
609 for (Vars_citer i = d_vars.begin(); i != d_vars.end();
610 i++, (void)(i != d_vars.end() && out << ", ")) {
611 (*i)->print_val(out, "", false);
612 }
613
614 out << " }" ;
615
616 if (print_decl_p)
617 out << ";\n" ;
618}
619#endif
620
621#if 0
622bool
623Structure::check_semantics(string &msg, bool all)
624{
626 return false;
627
628 bool status = true;
629
630 if (!unique_names(d_vars, name(), type_name(), msg))
631 return false;
632
633 if (all) {
634 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
635 //assert(*i);
636 if (!(*i)->check_semantics(msg, true)) {
637 status = false;
638 goto exit;
639 }
640 }
641 }
642
643exit:
644 return status;
645}
646#endif
647
656void Structure::dump(ostream &strm) const {
657 strm << DapIndent::LMarg << "Structure::dump - (" << (void *)this << ")" << endl;
659 Constructor::dump(strm);
661}
662
663} // namespace libdap
Contains the attributes for a dataset.
Definition AttrTable.h:150
virtual AttrTable * append_container(const string &name)
Add a container to the attribute table.
Definition AttrTable.cc:517
virtual void set_name(const string &n)
Set the name of this attribute table.
Definition AttrTable.cc:247
virtual string get_name() const
Get the name of this attribute table.
Definition AttrTable.cc:243
virtual void print(FILE *out, string pad=" ", bool dereference=false)
Prints the attribute table.
virtual unsigned int get_size() const
Get the number of entries in this attribute table.
Definition AttrTable.cc:239
The basic data type for the DODS DAP types.
Definition BaseType.h:118
void m_duplicate(const BaseType &bt)
Perform a deep copy.
Definition BaseType.cc:85
virtual string type_name() const
Returns the type of the class instance as a string.
Definition BaseType.cc:335
virtual void intern_data()
Read data into this variable.
Definition BaseType.cc:805
virtual bool read()
Read data into a local buffer.
Definition BaseType.cc:775
virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse=false)
Receive data from the net.
Definition BaseType.cc:814
virtual AttrTable & get_attr_table()
Definition BaseType.cc:498
virtual string name() const
Returns the name of the class instance.
Definition BaseType.cc:296
virtual void set_in_selection(bool state)
Definition BaseType.cc:611
virtual bool read_p()
Has this variable been read?
Definition BaseType.cc:410
virtual unsigned int width(bool constrained=false) const
How many bytes does this variable use Return the number of bytes of storage this variable uses....
Definition BaseType.cc:1138
virtual void set_read_p(bool state)
Sets the value of the read_p property.
Definition BaseType.cc:442
virtual string dataset() const
Returns the name of the dataset used to create this instance.
Definition BaseType.cc:326
virtual void set_attr_table(const AttrTable &at)
Definition BaseType.cc:502
virtual void set_parent(BaseType *parent)
Definition BaseType.cc:622
virtual D4Attributes * attributes()
Definition BaseType.cc:507
virtual void add_var_nocopy(BaseType *bt, Part part=nil)
Definition BaseType.cc:699
virtual void set_send_p(bool state)
Definition BaseType.cc:488
virtual void set_is_dap4(const bool v)
Definition BaseType.h:182
virtual BaseType * ptr_duplicate()=0
virtual unsigned int val2buf(void *val, bool reuse=false)=0
Loads class data.
virtual unsigned int buf2val(void **val)=0
Reads the class data.
virtual bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval=true)
Move data to the net, then remove them from the object.
Definition BaseType.cc:810
virtual void add_var(BaseType *bt, Part part=nil)
Add a variable.
Definition BaseType.cc:697
virtual bool check_semantics(string &msg, bool all=false)
Compare an object's current state with the semantics of its type.
Definition BaseType.cc:1056
BaseType(const string &n, const Type &t, bool is_dap4=false)
The BaseType constructor.
Definition BaseType.cc:124
virtual BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=nullptr)
Returns a pointer to a member of a constructor class.
Definition BaseType.cc:646
virtual void print_val(FILE *out, string space="", bool print_decl_p=true)
Prints the value of the variable.
Definition BaseType.cc:949
Evaluate a constraint expression.
void transform_to_dap4(D4Group *root, Constructor *dest) override
DAP2 to DAP4 transform.
BaseType * var(const string &name, bool exact_match=true, btp_stack *s=nullptr) override
btp_stack no longer needed; use back pointers (BaseType::get_parent())
std::vector< BaseType * >::const_iterator Vars_citer
Definition Constructor.h:59
void print_decl(ostream &out, string space=" ", bool print_semi=true, bool constraint_info=false, bool constrained=false) override
Print an ASCII representation of the variable structure.
void set_read_p(bool state) override
Set the 'read_p' property for the Constructor and its members.
void print_val(FILE *out, string space="", bool print_decl_p=true) override
Prints the value of the variable.
static AttrTable * make_dropped_vars_attr_table(vector< BaseType * > *dropped_vars)
std::vector< BaseType * >::iterator Vars_iter
Definition Constructor.h:60
std::vector< BaseType * > d_vars
Definition Constructor.h:47
bool read() override
Read the elements of Constructor marked for transmission.
BaseType * m_exact_match(const string &name, btp_stack *s=nullptr)
void add_var_nocopy(BaseType *bt, Part part=nil) override
BaseType * m_leaf_match(const string &name, btp_stack *s=nullptr)
Vars_iter var_begin()
Constructor & operator=(const Constructor &rhs)
Definition Constructor.h:70
Constructor(const string &name, const Type &type, bool is_dap4=false)
Definition Constructor.h:52
virtual void del_var(const string &name)
Remove an element from a Constructor.
void dump(ostream &strm) const override
dumps information about this object
void transform_attrs_to_dap2(AttrTable *d2_attr_table)
Copy the attributes from this D4Attributes object to a DAP2 AttrTable.
static ostream & LMarg(ostream &strm)
Definition DapIndent.cc:61
static void Indent()
Definition DapIndent.cc:44
static void UnIndent()
Definition DapIndent.cc:46
A class for software fault reporting.
Definition InternalErr.h:61
abstract base class used to marshal/serialize dap data objects
Definition Marshaller.h:50
Holds a sequence.
Definition Sequence.h:162
virtual void set_leaf_sequence(int lvl=1)
Mark the Sequence which holds the leaf elements.
Definition Sequence.cc:1148
Holds a structure (aggregate) type.
Definition Structure.h:82
Structure(const string &n)
Definition Structure.cc:110
virtual void dump(ostream &strm) const
dumps information about this object
Definition Structure.cc:656
virtual void set_leaf_sequence(int level=1)
Traverse Structure, set Sequence leaf nodes.
Definition Structure.cc:285
virtual ~Structure()
Definition Structure.cc:129
virtual vector< BaseType * > * transform_to_dap2(AttrTable *parent_attr_table)
DAP4 to DAP2 transform.
Definition Structure.cc:167
virtual bool is_linear()
Check to see whether this variable can be printed simply.
Definition Structure.cc:235
virtual BaseType * ptr_duplicate()
Definition Structure.cc:131
Structure & operator=(const Structure &rhs)
Definition Structure.cc:228
virtual void transform_to_dap4(D4Group *root, Constructor *container)
Definition Structure.cc:142
abstract base class used to unmarshall/deserialize dap data objects
STL iterator class.
#define DBG(x)
Definition debug.h:58
top level DAP object to house generic methods
Definition AISConnect.cc:30
@ dods_sequence_c
Definition Type.h:108
@ dods_grid_c
Definition Type.h:111
@ dods_structure_c
Definition Type.h:106
string www2id(const string &in, const string &escape, const string &except)
Definition escaping.cc:202
Part
Names the parts of multi-section constructor data types.
Definition Type.h:48
bool unique_names(vector< BaseType * > l, const string &var_name, const string &type_name, string &msg)
Definition util.cc:472