libdap  Updated for version 3.20.10
libdap4 is an implementation of OPeNDAP's DAP protocol.
D4Group.cc
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
4 // Access Protocol.
5 
6 // Copyright (c) 2013 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 
25 #include "config.h"
26 
27 //#define DODS_DEBUG
28 
29 #include <cassert>
30 
31 #include <iostream>
32 #include <sstream>
33 #include <iomanip>
34 
35 #include <stdint.h>
36 
37 #include "crc.h"
38 
39 #include "BaseType.h"
40 #include "Array.h"
41 
42 #include "XMLWriter.h"
43 #include "D4Attributes.h"
44 #include "D4Dimensions.h"
45 #include "D4Group.h"
46 #include "D4Enum.h"
47 
48 #include "D4StreamMarshaller.h"
49 #include "D4StreamUnMarshaller.h"
50 
51 #include "debug.h"
52 
58 #undef INCLUDE_SOURCE_BYTE_ORDER
59 
60 namespace libdap {
61 
62 void D4Group::m_duplicate(const D4Group &g)
63 {
64  DBG(cerr << "In D4Group::m_duplicate for " << g.name() << endl);
65 
66  // dims; deep copy, this is the parent
67  if (g.d_dims) {
68  d_dims = new D4Dimensions(*(g.d_dims));
69  d_dims->set_parent(this);
70 
71  // Update all of the D4Dimension weak pointers in the Array objects.
72  // This is a hack - we know that Constructor::m_duplicate() has been
73  // called at this point and any Array instances have dimension pointers
74  // that reference the 'old' dimensions (g.d_dims) and not the 'new'
75  // dimensions made above. Scan every array and re-wire the weak pointers.
76  // jhrg 8/15/14
77  Vars_citer vi = d_vars.begin();
78  while (vi != d_vars.end()) {
79  if ((*vi)->type() == dods_array_c)
80  static_cast<Array*>(*vi)->update_dimension_pointers(g.d_dims, d_dims);
81  ++vi;
82  }
83  }
84 
85 #if 0
86  // Moved this block up inside the if because g.d_dims might be false. jhrg 9/14/15
87  Vars_citer vi = d_vars.begin();
88  while (vi != d_vars.end()) {
89  if ((*vi)->type() == dods_array_c)
90  static_cast<Array*>(*vi)->update_dimension_pointers(g.d_dims, d_dims);
91  ++vi;
92  }
93 #endif
94 
95  // enums; deep copy
96  if (g.d_enum_defs) d_enum_defs = new D4EnumDefs(*g.d_enum_defs);
97 
98  // groups
99  groupsCIter i = g.d_groups.begin();
100  while(i != g.d_groups.end()) {
101  // Only D4Groups are in the d_groups container.
102  D4Group *g = static_cast<D4Group*>((*i++)->ptr_duplicate());
103  add_group_nocopy(g);
104  }
105 
106  DBG(cerr << "Exiting D4Group::m_duplicate" << endl);
107 }
108 
119 D4Group::D4Group(const string &name)
120  : Constructor(name, dods_group_c, /*is_dap4*/true), d_dims(0), d_enum_defs(0)
121 {}
122 
133 D4Group::D4Group(const string &name, const string &dataset)
134  : Constructor(name, dataset, dods_group_c, /*is_dap4*/true), d_dims(0), d_enum_defs(0)
135 {}
136 
138 D4Group::D4Group(const D4Group &rhs) : Constructor(rhs), d_dims(0), d_enum_defs(0)
139 {
140  DBG(cerr << "In D4Group::copy_ctor for " << rhs.name() << endl);
141  m_duplicate(rhs);
142 }
143 
144 D4Group::~D4Group()
145 {
146  delete d_dims;
147  delete d_enum_defs;
148 
149  groupsIter i = d_groups.begin();
150  while(i != d_groups.end())
151  delete *i++;
152 }
153 
154 #if 0
155 D4Group *
156 
157 // I think this was a mistake. jhrg 11/17/16
158 #endif
159 BaseType *
161 {
162  return new D4Group(*this);
163 }
164 
165 D4Group &
166 D4Group::operator=(const D4Group &rhs)
167 {
168  if (this == &rhs)
169  return *this;
170  Constructor::operator=(rhs);
171  m_duplicate(rhs);
172  return *this;
173 }
174 
181 string
183 {
184  // The root group is named "/" (always)
185  return (name() == "/") ? "/" : static_cast<D4Group*>(get_parent())->FQN() + name() + "/";
186 }
187 
188 D4Group *
189 D4Group::find_child_grp(const string &grp_name)
190 {
191  auto g = find_if(grp_begin(), grp_end(),
192  [grp_name](const D4Group *g) { return g->name() == grp_name; });
193  return (g == grp_end()) ? 0: *g;
194 }
195 
196 // TODO Add constraint param? jhrg 11/17/13
197 BaseType *
198 D4Group::find_first_var_that_uses_dimension(D4Dimension *dim)
199 {
200  // for each group, starting with the root group
201  // for each variable in the group that is marked to send and is an array
202  // return the btp if it uses the D4Dimension
203  // if it contains child groups, search those
204  // return the btp if it uses the D4Dimension
205  // return null
206 
207  // exhaustive breadth-first search for 'dim
208 
209  // root group
210  for (Vars_iter i = var_begin(), e = var_end(); i != e; ++i) {
211  if ((*i)->send_p() && (*i)->type() == dods_array_c) {
212  Array *a = static_cast<Array*>(*i);
213  for (Array::Dim_iter di = a->dim_begin(), de = a->dim_end(); di != de; ++di) {
214  if (a->dimension_D4dim(di) == dim)
215  return a;
216  }
217  }
218  }
219 
220  for (groupsIter i = grp_begin(), e = grp_end(); i != e; ++i) {
221  BaseType *btp = (*i)->find_first_var_that_uses_dimension(dim);
222  if (btp) return btp;
223  }
224 
225  return 0;
226 }
227 
228 BaseType *
229 D4Group::find_first_var_that_uses_enumeration(D4EnumDef *enum_def)
230 {
231  // for each group, starting with the root group
232  // for each variable in the group that is marked to send and is an array
233  // return the btp if it uses the D4EnumDef
234  // if it contains child groups, search those
235  // return the btp if it uses the D4EnumDef
236  // return null
237 
238  // exhaustive breadth-first search for 'dim
239 
240  // root group
241  for (Vars_iter i = var_begin(), e = var_end(); i != e; ++i) {
242  if ((*i)->send_p() && (*i)->type() == dods_enum_c) {
243  D4Enum *e = static_cast<D4Enum*>(*i);
244  if (e->enumeration() == enum_def)
245  return e;
246  }
247  }
248 
249  for (groupsIter i = grp_begin(), e = grp_end(); i != e; ++i) {
250  BaseType *btp = (*i)->find_first_var_that_uses_enumeration(enum_def);
251  if (btp) return btp;
252  }
253 
254  return 0;
255 }
256 
266 D4Dimension *
267 D4Group::find_dim(const string &path)
268 {
269  string lpath = path; // get a mutable copy
270 
271  // special-case for the root group
272  if (lpath[0] == '/') {
273  if (name() != "/")
274  throw InternalErr(__FILE__, __LINE__, "Lookup of a FQN starting in non-root group.");
275  else
276  lpath = lpath.substr(1);
277  }
278 
279  string::size_type pos = lpath.find('/');
280  if (pos == string::npos) {
281  // name looks like 'bar'
282  return dims()->find_dim(lpath);
283  }
284 
285  // name looks like foo/bar/baz where foo and bar must be groups
286  string grp_name = lpath.substr(0, pos);
287  lpath = lpath.substr(pos + 1);
288 
289  D4Group *grp = find_child_grp(grp_name);
290  return (grp == 0) ? 0: grp->find_dim(lpath);
291 }
292 
298 Array *
299 D4Group::find_map_source(const string &path)
300 {
301  BaseType *map_source = m_find_map_source_helper(path);
302 
303  // TODO more complete semantic checking jhrg 10/16/13
304  if (map_source && map_source->type() == dods_array_c) return static_cast<Array*>(map_source);
305 
306  return 0;
307 }
308 
314 BaseType *
315 D4Group::m_find_map_source_helper(const string &path)
316 {
317  string lpath = path; // get a mutable copy
318 
319  // special-case for the root group
320  if (lpath[0] == '/') {
321  if (name() != "/")
322  throw InternalErr(__FILE__, __LINE__, "Lookup of a FQN starting in non-root group.");
323  else
324  lpath = lpath.substr(1);
325  }
326 
327  string::size_type pos = lpath.find('/');
328  if (pos == string::npos) {
329  // name looks like 'bar'
330  return var(lpath);
331  }
332 
333  // name looks like foo/bar/baz where foo and bar must be groups
334  string grp_name = lpath.substr(0, pos);
335  lpath = lpath.substr(pos + 1);
336 
337  D4Group *grp = find_child_grp(grp_name);
338  return (grp == 0) ? 0: grp->var(lpath);
339 }
340 
341 D4EnumDef *
342 D4Group::find_enum_def(const string &path)
343 {
344  string lpath = path; // get a mutable copy
345 
346  // special-case for the root group
347  if (lpath[0] == '/') {
348  if (name() != "/")
349  throw InternalErr(__FILE__, __LINE__, "Lookup of a FQN starting in non-root group.");
350  else
351  lpath = lpath.substr(1);
352  }
353 
354  string::size_type pos = lpath.find('/');
355  if (pos == string::npos) {
356  // name looks like 'bar'
357  return enum_defs()->find_enum_def(lpath);
358  }
359 
360  // name looks like foo/bar/baz where foo and bar must be groups
361  string grp_name = lpath.substr(0, pos);
362  lpath = lpath.substr(pos + 1);
363 
364  D4Group *grp = find_child_grp(grp_name);
365  return (grp == 0) ? 0: grp->enum_defs()->find_enum_def(lpath);
366 }
367 
375 BaseType *
376 D4Group::find_var(const string &path)
377 {
378  string lpath = path; // get a mutable copy
379 
380  // special-case for the root group
381  if (lpath[0] == '/') {
382  if (name() != "/")
383  throw InternalErr(__FILE__, __LINE__, "Lookup of a FQN starting in non-root group.");
384  else
385  lpath = lpath.substr(1);
386  }
387 
388  string::size_type pos = lpath.find('/');
389  if (pos == string::npos) {
390  // name looks like 'bar' or bar.baz; lookup in the Constructor that's part of the Group
391  return var(lpath);
392  }
393 
394  // name looks like foo/bar/baz where foo and bar must be groups
395  string grp_name = lpath.substr(0, pos);
396  lpath = lpath.substr(pos + 1);
397 
398  D4Group *grp = find_child_grp(grp_name);
399  return (grp == 0) ? 0 : grp->find_var(lpath);
400 }
401 
408 long
409 D4Group::request_size(bool constrained)
410 {
411  long long size = 0;
412  // variables
413  Constructor::Vars_iter v = var_begin();
414  while (v != var_end()) {
415  if (constrained) {
416  if ((*v)->send_p())
417  size += (*v)->width(constrained);
418  }
419  else {
420  size += (*v)->width(constrained);
421  }
422 
423  ++v;
424  }
425 
426  // groups
427  groupsIter g = d_groups.begin();
428  while (g != d_groups.end())
429  size += (*g++)->request_size(constrained);
430 
431  return size / 1024;
432 }
433 
446 uint64_t D4Group::request_size_kb(bool constrained)
447 {
448  uint64_t size = 0;
449  // variables
450  Constructor::Vars_iter v = var_begin();
451  while (v != var_end()) {
452  if (constrained) {
453  if ((*v)->send_p())
454  size += (*v)->width(constrained);
455  }
456  else {
457  size += (*v)->width(constrained);
458  }
459  ++v;
460  }
461  // groups
462  groupsIter g = d_groups.begin();
463  while (g != d_groups.end())
464  size += (*g++)->request_size(constrained);
465 
466  return size / 1024;
467 }
468 
469 
470 void
472 {
473  groupsIter g = d_groups.begin();
474  while (g != d_groups.end())
475  (*g++)->set_read_p(state);
476 
478 }
479 
480 void
482 {
483  groupsIter g = d_groups.begin();
484  while (g != d_groups.end())
485  (*g++)->set_send_p(state);
486 
488 }
489 
490 void
491 D4Group::intern_data(/*Crc32 &checksum, DMR &dmr, ConstraintEvaluator &eval*/)
492 {
493  groupsIter g = d_groups.begin();
494  while (g != d_groups.end())
495  (*g++)->intern_data(/*checksum, dmr, eval*/);
496 
497  // Specialize how the top-level variables in any Group are sent; include
498  // a checksum for them. A subset operation might make an interior set of
499  // variables, but the parent structure will still be present and the checksum
500  // will be computed for that structure. In other words, DAP4 does not try
501  // to sort out which variables are the 'real' top-level variables and instead
502  // simply computes the CRC for whatever appears as a variable in the root
503  // group.
504  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
505  // Only send the stuff in the current subset.
506  if ((*i)->send_p()) {
507 #if 0
508  checksum.Reset();
509 #endif
510  (*i)->intern_data(/*checksum, dmr, eval*/);
511 #if 0
512  D4Attribute *a = new D4Attribute("DAP4_Checksum_CRC32", attr_str_c);
513 
514  ostringstream oss;
515  oss.setf(ios::hex, ios::basefield);
516  oss << setfill('0') << setw(8) << checksum.GetCrc32();
517  a->add_value(oss.str());
518 #if INCLUDE_SOURCE_BYTE_ORDER
519  if (um.is_source_big_endian())
520  a->add_value("source:big-endian");
521  else
522  a->add_value("source:little-endian");
523 #endif
524  (*i)->attributes()->add_attribute_nocopy(a);
525  DBG(cerr << "CRC32: " << oss.str() << " for " << (*i)->name() << endl);
526 #endif
527  }
528  }
529 }
530 
542 void
543 D4Group::serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter)
544 {
545 #if 0
546  // This will call Constructor read which will, for everything but a Sequence,
547  // read all of the data in one shot. However, the serialize() methods for the
548  // Arrays, Structures, etc., also have read() calls in them and those can be
549  // used to control how long the data are in memory, e.g., limiting the lifetime
550  // of a large array and avoiding having overlapping arrays when they are not
551  // needed. For a sequence read() has different semantics. It is called once
552  // for every instance and the read_p flag is not used.
553  if (!read_p())
554  read(); // read() throws Error
555 #endif
556 
557  groupsIter g = d_groups.begin();
558  while (g != d_groups.end())
559  (*g++)->serialize(m, dmr, filter);
560 
561  // Specialize how the top-level variables in any Group are sent; include
562  // a checksum for them. A subset operation might make an interior set of
563  // variables, but the parent structure will still be present and the checksum
564  // will be computed for that structure. In other words, DAP4 does not try
565  // to sort out which variables are the 'real' top-level variables and instead
566  // simply computes the CRC for whatever appears as a variable in the root
567  // group.
568  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
569  // Only send the stuff in the current subset.
570  if ((*i)->send_p()) {
571  m.reset_checksum();
572 
573  DBG(cerr << "Serializing variable " << (*i)->type_name() << " " << (*i)->name() << endl);
574  (*i)->serialize(m, dmr, filter);
575 
576  DBG(cerr << "Wrote CRC32: " << m.get_checksum() << " for " << (*i)->name() << endl);
577  m.put_checksum();
578  }
579  }
580 }
581 
583 {
584  groupsIter g = d_groups.begin();
585  while (g != d_groups.end()) {
586  DBG(cerr << "Deserializing group " << (*g)->name() << endl);
587  (*g++)->deserialize(um, dmr);
588  }
589  // Specialize how the top-level variables in any Group are received; read
590  // their checksum and store the value in a magic attribute of the variable
591  for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
592  DBG(cerr << "Deserializing variable " << (*i)->type_name() << " " << (*i)->name() << endl);
593  (*i)->deserialize(um, dmr);
594 
595  D4Attribute *a = new D4Attribute("DAP4_Checksum_CRC32", attr_str_c);
596  string crc = um.get_checksum_str();
597  a->add_value(crc);
598 #if INCLUDE_SOURCE_BYTE_ORDER
599  if (um.is_source_big_endian())
600  a->add_value("source:big-endian");
601  else
602  a->add_value("source:little-endian");
603 #endif
604  DBG(cerr << "Read CRC32: " << crc << " for " << (*i)->name() << endl);
605  (*i)->attributes()->add_attribute_nocopy(a);
606  }
607 }
608 
609 void
610 D4Group::print_dap4(XMLWriter &xml, bool constrained)
611 {
612  if (!name().empty() && name() != "/") {
613  // For named groups, if constrained is true only print if this group
614  // has variables that are marked for transmission. For the root group
615  // this test is not made.
616  if (constrained && !send_p())
617  return;
618 
619  if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) type_name().c_str()) < 0)
620  throw InternalErr(__FILE__, __LINE__, "Could not write " + type_name() + " element");
621 
622  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*) name().c_str()) < 0)
623  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
624  }
625 
626  // dims
627  if (!dims()->empty())
628  dims()->print_dap4(xml, constrained);
629 
630  // enums
631  if (!enum_defs()->empty())
632  enum_defs()->print_dap4(xml, constrained);
633 
634  // variables
635  Constructor::Vars_iter v = var_begin();
636  while (v != var_end())
637  (*v++)->print_dap4(xml, constrained);
638 
639  // attributes
640  attributes()->print_dap4(xml);
641 
642  // groups
643  groupsIter g = d_groups.begin();
644  while (g != d_groups.end())
645  (*g++)->print_dap4(xml, constrained);
646 
647  if (!name().empty() && name() != "/") {
648  if (xmlTextWriterEndElement(xml.get_writer()) < 0)
649  throw InternalErr(__FILE__, __LINE__, "Could not end " + type_name() + " element");
650  }
651 }
652 #if 0
669 vector<BaseType *> *
670 D4Group::transform_to_dap2(AttrTable *parent_attr_table)
671 {
672  return transform_to_dap2(parent_attr_table, false);
673 }
674 #endif
698 vector<BaseType *> *
700 {
701  DBG( cerr << __func__ << "() - BEGIN ("<< name() << ")" << endl);
702 
703  vector<BaseType *> *results = new vector<BaseType *>(); // LEAK
704 
705  // Get the D4Group's attributes
706 #if 0
707  AttrTable *group_attrs = attributes()->get_AttrTable(name());
708 #else
709  AttrTable *group_attrs = new AttrTable();
710  attributes()->transform_attrs_to_dap2(group_attrs);
711  group_attrs->set_name(name());
712 #endif
713 
714  // If this is the root group then copy all of its attributes into the parent_attr_table.
715  // The group_attrs AttrTable* above will be replaced by the parent_attr_table.
716  bool is_root = (name() == "/");
717 
718  if (is_root) {
719  assert(name() == "/");
720  for (AttrTable::Attr_iter i = group_attrs->attr_begin(), e = group_attrs->attr_end(); i != e; ++i) {
721  if ((*i)->type == Attr_container) {
722  // copy the source container so that the DAS passed in can be
723  // deleted after calling this method.
724  AttrTable *at = new AttrTable(*(*i)->attributes);
725  parent_attr_table->append_container(at, at->get_name());
726  }
727  else {
728  parent_attr_table->append_attr((*i)->name, AttrType_to_String((*i)->type), (*i)->attr);
729  }
730  }
731  delete group_attrs;
732  group_attrs = parent_attr_table;
733  }
734 
735  // Now we process the child variables of this group
736 
737  vector<BaseType *> dropped_vars;
738  for (D4Group::Vars_citer i = var_begin(), e = var_end(); i != e; ++i) {
739 
740  DBG( cerr << __func__ << "() - Processing member variable '" << (*i)->name() <<
741  "' root: " << (is_root?"true":"false") << endl);
742 
743  vector<BaseType *> *new_vars = (*i)->transform_to_dap2(group_attrs);
744  if (new_vars) { // Might be un-mappable
745  // It's not so game on..
746  for (vector<BaseType*>::iterator vi = new_vars->begin(), ve = new_vars->end(); vi != ve; vi++) {
747  string new_name = (is_root ? "" : FQN()) + (*vi)->name();
748  (*vi)->set_name(new_name);
749  (*vi)->set_parent(NULL);
750  results->push_back((*vi));
751 #if 0
752  (*vi) = NULL;
753 #endif
754  DBG( cerr << __func__ << "() - Added member variable '" << (*i)->name() << "' " <<
755  "to results vector. root: "<< (is_root?"true":"false") << endl);
756  }
757 
758  delete new_vars;
759  }
760  else {
761  DBG( cerr << __func__ << "() - Dropping member variable " << (*i)->name() <<
762  " root: " << (is_root?"true":"false") << endl);
763  // Got back a NULL, so we are dropping this var.
764  dropped_vars.push_back(*i);
765  }
766  }
767 
768  // Process dropped DAP4 vars
769  DBG( cerr << __func__ << "() - Processing " << dropped_vars.size() << " Dropped Variable(s)" << endl);
770 
771  AttrTable *dv_attr_table = make_dropped_vars_attr_table(&dropped_vars);
772  if (dv_attr_table) {
773  group_attrs->append_container(dv_attr_table, dv_attr_table->get_name());
774  }
775 
776  // Get all the child groups.
777  for (D4Group::groupsIter gi = grp_begin(), ge = grp_end(); gi != ge; ++gi) {
778  vector<BaseType *> *d2_vars = (*gi)->transform_to_dap2(group_attrs);
779  if (d2_vars) {
780  for (vector<BaseType *>::iterator i = d2_vars->begin(), e = d2_vars->end(); i != e; ++i) {
781  results->push_back(*i);
782  }
783  }
784  delete d2_vars;
785  }
786 
787  if (!is_root) {
788  group_attrs->set_name(name());
789  parent_attr_table->append_container(group_attrs, group_attrs->get_name());
790  }
791 
792  return results;
793 }
794 
795 
796 } /* namespace libdap */
A multidimensional array of identical data types.
Definition: Array.h:113
std::vector< dimension >::iterator Dim_iter
Definition: Array.h:206
Contains the attributes for a dataset.
Definition: AttrTable.h:143
virtual AttrTable * append_container(const string &name)
Add a container to the attribute table.
Definition: AttrTable.cc:410
virtual void set_name(const string &n)
Set the name of this attribute table.
Definition: AttrTable.cc:245
virtual Attr_iter attr_end()
Definition: AttrTable.cc:719
virtual unsigned int append_attr(const string &name, const string &type, const string &value)
Add an attribute to the table.
Definition: AttrTable.cc:307
virtual Attr_iter attr_begin()
Definition: AttrTable.cc:711
virtual string get_name() const
Get the name of this attribute table.
Definition: AttrTable.cc:238
The basic data type for the DODS DAP types.
Definition: BaseType.h:118
virtual string type_name() const
Returns the type of the class instance as a string.
Definition: BaseType.cc:375
virtual string name() const
Returns the name of the class instance.
Definition: BaseType.cc:316
virtual BaseType * get_parent() const
Definition: BaseType.cc:747
virtual bool read_p()
Has this variable been read?
Definition: BaseType.cc:476
virtual D4Attributes * attributes()
Definition: BaseType.cc:595
virtual bool send_p()
Should this variable be sent?
Definition: BaseType.cc:550
BaseType(const string &n, const Type &t, bool is_dap4=false)
The BaseType constructor.
Definition: BaseType.cc:126
virtual Type type() const
Returns the type of the class instance.
Definition: BaseType.cc:361
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())
Definition: Constructor.cc:185
void set_read_p(bool state) override
Set the 'read_p' property for the Constructor and its members.
Definition: Constructor.cc:150
void set_send_p(bool state) override
Definition: Constructor.cc:129
Vars_iter var_end()
Definition: Constructor.cc:280
bool read() override
Read the elements of Constructor marked for transmission.
Definition: Constructor.cc:393
Vars_iter var_begin()
Definition: Constructor.cc:272
void transform_attrs_to_dap2(AttrTable *d2_attr_table)
Copy the attributes from this D4Attributes object to a DAP2 AttrTable.
D4Dimensions * dims()
Get the dimensions defined for this Group.
Definition: D4Group.h:83
D4Dimension * find_dim(const string &path)
Find the dimension using a path. Using the DAP4 name syntax, lookup a dimension. The dimension must b...
Definition: D4Group.cc:267
Array * find_map_source(const string &path)
Given a path to an Array that is also a Map, get that Array.
Definition: D4Group.cc:299
virtual void intern_data()
Read data into this variable.
Definition: D4Group.cc:491
virtual void set_read_p(bool state)
Set the 'read_p' property for the Constructor and its members.
Definition: D4Group.cc:471
BaseType * find_var(const string &name)
Definition: D4Group.cc:376
virtual std::string FQN() const
Definition: D4Group.cc:182
groupsIter grp_begin()
Get an iterator to the start of the values.
Definition: D4Group.h:112
virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr)
Definition: D4Group.cc:582
virtual void set_send_p(bool state)
Definition: D4Group.cc:481
uint64_t request_size_kb(bool constrained)
Get the estimated size of a response in kilobytes. This method looks at the variables in the DDS and ...
Definition: D4Group.cc:446
groupsIter grp_end()
Get an iterator to the end of the values.
Definition: D4Group.h:115
D4EnumDefs * enum_defs()
Get the enumerations defined for this Group.
Definition: D4Group.h:98
virtual BaseType * ptr_duplicate()
Definition: D4Group.cc:160
virtual std::vector< BaseType * > * transform_to_dap2(AttrTable *parent_attr_table)
Transform the D4Group's variables to DAP2 variables.
Definition: D4Group.cc:699
long request_size(bool constrained)
Definition: D4Group.cc:409
D4Group(const string &name)
Definition: D4Group.cc:119
void print_dap4(XMLWriter &xml, bool constrained=false)
Definition: D4Group.cc:610
virtual void serialize(D4StreamMarshaller &m, DMR &dmr, bool filter=false)
Serialize a Group.
Definition: D4Group.cc:543
Marshaller that knows how to marshal/serialize dap data objects to a C++ iostream using DAP4's receiv...
virtual void put_checksum()
Write the checksum Write the checksum for the data sent since the last call to reset_checksum() to th...
Read data from the stream made by D4StreamMarshaller.
bool is_source_big_endian() const
Is the data source we are reading from a big-endian machine? We need this because the value of the CR...
A class for software fault reporting.
Definition: InternalErr.h:65
top level DAP object to house generic methods
Definition: AlarmHandler.h:36
string AttrType_to_String(const AttrType at)
Definition: AttrTable.cc:97