libdap Updated for version 3.20.11
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
60namespace libdap {
61
62void 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
119D4Group::D4Group(const string &name)
120 : Constructor(name, dods_group_c, /*is_dap4*/true), d_dims(0), d_enum_defs(0)
121{}
122
133D4Group::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
138D4Group::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
144D4Group::~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
155D4Group *
156
157// I think this was a mistake. jhrg 11/17/16
158#endif
159BaseType *
161{
162 return new D4Group(*this);
163}
164
165D4Group &
166D4Group::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
181string
183{
184 // The root group is named "/" (always)
185 return (name() == "/") ? "/" : static_cast<D4Group*>(get_parent())->FQN() + name() + "/";
186}
187
188D4Group *
189D4Group::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
197BaseType *
198D4Group::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
228BaseType *
229D4Group::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
266D4Dimension *
267D4Group::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
298Array *
299D4Group::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
314BaseType *
315D4Group::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
341D4EnumDef *
342D4Group::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
375BaseType *
376D4Group::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
408long
409D4Group::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 ++v;
423 }
424 size = size / 1024; // Make into kilobytes
425
426 // groups
427 //groupsIter g = d_groups.begin();
428 //while (g != d_groups.end())
429 // size += (*g++)->request_size(constrained);
430
431 for(auto grp : d_groups)
432 size += grp->request_size_kb(constrained);
433
434 return size ;
435}
436
449uint64_t D4Group::request_size_kb(bool constrained)
450{
451 uint64_t size = 0;
452 // variables
453 Constructor::Vars_iter v = var_begin();
454 while (v != var_end()) {
455 if (constrained) {
456 if ((*v)->send_p())
457 size += (*v)->width(constrained);
458 }
459 else {
460 size += (*v)->width(constrained);
461 }
462 ++v;
463 }
464 size = size / 1024; // Make into kilobytes
465 // groups
466 // auto g = d_groups.begin();
467 // while (g != d_groups.end())
468 // size += (*g++)->request_size_kb(constrained);
469
470 for(auto grp : d_groups)
471 size += grp->request_size_kb(constrained);
472
473
474 return size;
475}
476
477
478void
480{
481 groupsIter g = d_groups.begin();
482 while (g != d_groups.end())
483 (*g++)->set_read_p(state);
484
486}
487
488void
490{
491 groupsIter g = d_groups.begin();
492 while (g != d_groups.end())
493 (*g++)->set_send_p(state);
494
496}
497
498void
499D4Group::intern_data(/*Crc32 &checksum, DMR &dmr, ConstraintEvaluator &eval*/)
500{
501 groupsIter g = d_groups.begin();
502 while (g != d_groups.end())
503 (*g++)->intern_data(/*checksum, dmr, eval*/);
504
505 // Specialize how the top-level variables in any Group are sent; include
506 // a checksum for them. A subset operation might make an interior set of
507 // variables, but the parent structure will still be present and the checksum
508 // will be computed for that structure. In other words, DAP4 does not try
509 // to sort out which variables are the 'real' top-level variables and instead
510 // simply computes the CRC for whatever appears as a variable in the root
511 // group.
512 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
513 // Only send the stuff in the current subset.
514 if ((*i)->send_p()) {
515#if 0
516 checksum.Reset();
517#endif
518 (*i)->intern_data(/*checksum, dmr, eval*/);
519#if 0
520 D4Attribute *a = new D4Attribute("DAP4_Checksum_CRC32", attr_str_c);
521
522 ostringstream oss;
523 oss.setf(ios::hex, ios::basefield);
524 oss << setfill('0') << setw(8) << checksum.GetCrc32();
525 a->add_value(oss.str());
526#if INCLUDE_SOURCE_BYTE_ORDER
527 if (um.is_source_big_endian())
528 a->add_value("source:big-endian");
529 else
530 a->add_value("source:little-endian");
531#endif
532 (*i)->attributes()->add_attribute_nocopy(a);
533 DBG(cerr << "CRC32: " << oss.str() << " for " << (*i)->name() << endl);
534#endif
535 }
536 }
537}
538
550void
551D4Group::serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter)
552{
553#if 0
554 // This will call Constructor read which will, for everything but a Sequence,
555 // read all of the data in one shot. However, the serialize() methods for the
556 // Arrays, Structures, etc., also have read() calls in them and those can be
557 // used to control how long the data are in memory, e.g., limiting the lifetime
558 // of a large array and avoiding having overlapping arrays when they are not
559 // needed. For a sequence read() has different semantics. It is called once
560 // for every instance and the read_p flag is not used.
561 if (!read_p())
562 read(); // read() throws Error
563#endif
564
565 groupsIter g = d_groups.begin();
566 while (g != d_groups.end())
567 (*g++)->serialize(m, dmr, filter);
568
569 // Specialize how the top-level variables in any Group are sent; include
570 // a checksum for them. A subset operation might make an interior set of
571 // variables, but the parent structure will still be present and the checksum
572 // will be computed for that structure. In other words, DAP4 does not try
573 // to sort out which variables are the 'real' top-level variables and instead
574 // simply computes the CRC for whatever appears as a variable in the root
575 // group.
576 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
577 // Only send the stuff in the current subset.
578 if ((*i)->send_p()) {
579 m.reset_checksum();
580
581 DBG(cerr << "Serializing variable " << (*i)->type_name() << " " << (*i)->name() << endl);
582 (*i)->serialize(m, dmr, filter);
583
584 DBG(cerr << "Wrote CRC32: " << m.get_checksum() << " for " << (*i)->name() << endl);
585 m.put_checksum();
586 }
587 }
588}
589
591{
592 groupsIter g = d_groups.begin();
593 while (g != d_groups.end()) {
594 DBG(cerr << "Deserializing group " << (*g)->name() << endl);
595 (*g++)->deserialize(um, dmr);
596 }
597 // Specialize how the top-level variables in any Group are received; read
598 // their checksum and store the value in a magic attribute of the variable
599 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
600 DBG(cerr << "Deserializing variable " << (*i)->type_name() << " " << (*i)->name() << endl);
601 (*i)->deserialize(um, dmr);
602
603 D4Attribute *a = new D4Attribute("DAP4_Checksum_CRC32", attr_str_c);
604 string crc = um.get_checksum_str();
605 a->add_value(crc);
606#if INCLUDE_SOURCE_BYTE_ORDER
607 if (um.is_source_big_endian())
608 a->add_value("source:big-endian");
609 else
610 a->add_value("source:little-endian");
611#endif
612 DBG(cerr << "Read CRC32: " << crc << " for " << (*i)->name() << endl);
613 (*i)->attributes()->add_attribute_nocopy(a);
614 }
615}
616
617void
618D4Group::print_dap4(XMLWriter &xml, bool constrained)
619{
620 if (!name().empty() && name() != "/") {
621 // For named groups, if constrained is true only print if this group
622 // has variables that are marked for transmission. For the root group
623 // this test is not made.
624 if (constrained && !send_p())
625 return;
626
627 if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) type_name().c_str()) < 0)
628 throw InternalErr(__FILE__, __LINE__, "Could not write " + type_name() + " element");
629
630 if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*) name().c_str()) < 0)
631 throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
632 }
633
634 // dims
635 if (!dims()->empty())
636 dims()->print_dap4(xml, constrained);
637
638 // enums
639 if (!enum_defs()->empty())
640 enum_defs()->print_dap4(xml, constrained);
641
642 // variables
643 Constructor::Vars_iter v = var_begin();
644 while (v != var_end())
645 (*v++)->print_dap4(xml, constrained);
646
647 // attributes
648 attributes()->print_dap4(xml);
649
650 // groups
651 groupsIter g = d_groups.begin();
652 while (g != d_groups.end())
653 (*g++)->print_dap4(xml, constrained);
654
655 if (!name().empty() && name() != "/") {
656 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
657 throw InternalErr(__FILE__, __LINE__, "Could not end " + type_name() + " element");
658 }
659}
660#if 0
677vector<BaseType *> *
678D4Group::transform_to_dap2(AttrTable *parent_attr_table)
679{
680 return transform_to_dap2(parent_attr_table, false);
681}
682#endif
706vector<BaseType *> *
708{
709 DBG( cerr << __func__ << "() - BEGIN ("<< name() << ")" << endl);
710
711 vector<BaseType *> *results = new vector<BaseType *>(); // LEAK
712
713 // Get the D4Group's attributes
714#if 0
715 AttrTable *group_attrs = attributes()->get_AttrTable(name());
716#else
717 AttrTable *group_attrs = new AttrTable();
718 attributes()->transform_attrs_to_dap2(group_attrs);
719 group_attrs->set_name(name());
720#endif
721
722 // If this is the root group then copy all of its attributes into the parent_attr_table.
723 // The group_attrs AttrTable* above will be replaced by the parent_attr_table.
724 bool is_root = (name() == "/");
725
726 if (is_root) {
727 assert(name() == "/");
728 for (AttrTable::Attr_iter i = group_attrs->attr_begin(), e = group_attrs->attr_end(); i != e; ++i) {
729 if ((*i)->type == Attr_container) {
730 // copy the source container so that the DAS passed in can be
731 // deleted after calling this method.
732 AttrTable *at = new AttrTable(*(*i)->attributes);
733 parent_attr_table->append_container(at, at->get_name());
734 }
735 else {
736 parent_attr_table->append_attr((*i)->name, AttrType_to_String((*i)->type), (*i)->attr);
737 }
738 }
739 delete group_attrs;
740 group_attrs = parent_attr_table;
741 }
742
743 // Now we process the child variables of this group
744
745 vector<BaseType *> dropped_vars;
746 for (D4Group::Vars_citer i = var_begin(), e = var_end(); i != e; ++i) {
747
748 DBG( cerr << __func__ << "() - Processing member variable '" << (*i)->name() <<
749 "' root: " << (is_root?"true":"false") << endl);
750
751 vector<BaseType *> *new_vars = (*i)->transform_to_dap2(group_attrs);
752 if (new_vars) { // Might be un-mappable
753 // It's not so game on..
754 for (vector<BaseType*>::iterator vi = new_vars->begin(), ve = new_vars->end(); vi != ve; vi++) {
755 string new_name = (is_root ? "" : FQN()) + (*vi)->name();
756 (*vi)->set_name(new_name);
757 (*vi)->set_parent(NULL);
758 results->push_back((*vi));
759#if 0
760 (*vi) = NULL;
761#endif
762 DBG( cerr << __func__ << "() - Added member variable '" << (*i)->name() << "' " <<
763 "to results vector. root: "<< (is_root?"true":"false") << endl);
764 }
765
766 delete new_vars;
767 }
768 else {
769 DBG( cerr << __func__ << "() - Dropping member variable " << (*i)->name() <<
770 " root: " << (is_root?"true":"false") << endl);
771 // Got back a NULL, so we are dropping this var.
772 dropped_vars.push_back(*i);
773 }
774 }
775
776 // Process dropped DAP4 vars
777 DBG( cerr << __func__ << "() - Processing " << dropped_vars.size() << " Dropped Variable(s)" << endl);
778
779 AttrTable *dv_attr_table = make_dropped_vars_attr_table(&dropped_vars);
780 if (dv_attr_table) {
781 group_attrs->append_container(dv_attr_table, dv_attr_table->get_name());
782 }
783
784 // Get all the child groups.
785 for (D4Group::groupsIter gi = grp_begin(), ge = grp_end(); gi != ge; ++gi) {
786 vector<BaseType *> *d2_vars = (*gi)->transform_to_dap2(group_attrs);
787 if (d2_vars) {
788 for (vector<BaseType *>::iterator i = d2_vars->begin(), e = d2_vars->end(); i != e; ++i) {
789 results->push_back(*i);
790 }
791 }
792 delete d2_vars;
793 }
794
795 if (!is_root) {
796 group_attrs->set_name(name());
797 parent_attr_table->append_container(group_attrs, group_attrs->get_name());
798 }
799
800 return results;
801}
802
803
804} /* 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.
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:499
virtual void set_read_p(bool state)
Set the 'read_p' property for the Constructor and its members.
Definition: D4Group.cc:479
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:590
virtual void set_send_p(bool state)
Definition: D4Group.cc:489
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:449
groupsIter grp_end()
Get an iterator to the end of the values.
Definition: D4Group.h:115
D4Dimensions * dims()
Get the dimensions defined for this Group.
Definition: D4Group.h:83
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:707
D4EnumDefs * enum_defs()
Get the enumerations defined for this Group.
Definition: D4Group.h:98
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:618
virtual void serialize(D4StreamMarshaller &m, DMR &dmr, bool filter=false)
Serialize a Group.
Definition: D4Group.cc:551
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