46#include "D4Attributes.h"
47#include "D4Dimensions.h"
51#include "D4StreamMarshaller.h"
52#include "D4StreamUnMarshaller.h"
63#undef INCLUDE_SOURCE_BYTE_ORDER
67void D4Group::m_duplicate(
const D4Group &g)
69 DBG(cerr <<
"In D4Group::m_duplicate for " << g.name() << endl);
73 d_dims =
new D4Dimensions(*(g.d_dims));
74 d_dims->set_parent(
this);
82 Vars_citer vi = d_vars.begin();
83 while (vi != d_vars.end()) {
84 if ((*vi)->type() == dods_array_c)
85 static_cast<Array*
>(*vi)->update_dimension_pointers(g.d_dims, d_dims);
92 Vars_citer vi = d_vars.begin();
93 while (vi != d_vars.end()) {
94 if ((*vi)->type() == dods_array_c)
95 static_cast<Array*
>(*vi)->update_dimension_pointers(g.d_dims, d_dims);
101 if (g.d_enum_defs) d_enum_defs =
new D4EnumDefs(*g.d_enum_defs);
104 groupsCIter i = g.d_groups.begin();
105 while(i != g.d_groups.end()) {
111 DBG(cerr <<
"Exiting D4Group::m_duplicate" << endl);
125 :
Constructor(name, dods_group_c, true), d_dims(0), d_enum_defs(0)
139 :
Constructor(name, dataset, dods_group_c, true), d_dims(0), d_enum_defs(0)
145 DBG(cerr <<
"In D4Group::copy_ctor for " << rhs.
name() << endl);
154 groupsIter i = d_groups.begin();
155 while(i != d_groups.end())
171D4Group::operator=(
const D4Group &rhs)
175 Constructor::operator=(rhs);
194D4Group::find_child_grp(
const string &grp_name)
197 [grp_name](
const D4Group *g) {
return g->
name() == grp_name; });
198 return (g ==
grp_end()) ? 0: *g;
203D4Group::find_first_var_that_uses_dimension(D4Dimension *dim)
216 if ((*i)->send_p() && (*i)->type() == dods_array_c) {
217 Array *a =
static_cast<Array*
>(*i);
218 for (
Array::Dim_iter di = a->dim_begin(), de = a->dim_end(); di != de; ++di) {
219 if (a->dimension_D4dim(di) == dim)
226 BaseType *btp = (*i)->find_first_var_that_uses_dimension(dim);
234D4Group::find_first_var_that_uses_enumeration(D4EnumDef *enum_def)
247 if ((*i)->send_p() && (*i)->type() == dods_enum_c) {
248 D4Enum *e =
static_cast<D4Enum*
>(*i);
249 if (e->enumeration() == enum_def)
255 BaseType *btp = (*i)->find_first_var_that_uses_enumeration(enum_def);
277 if (lpath[0] ==
'/') {
279 throw InternalErr(__FILE__, __LINE__,
"Lookup of a FQN starting in non-root group.");
281 lpath = lpath.substr(1);
284 string::size_type pos = lpath.find(
'/');
285 if (pos == string::npos) {
287 return dims()->find_dim(lpath);
291 string grp_name = lpath.substr(0, pos);
292 lpath = lpath.substr(pos + 1);
294 D4Group *grp = find_child_grp(grp_name);
295 return (grp == 0) ? 0: grp->
find_dim(lpath);
306 BaseType *map_source = m_find_map_source_helper(path);
309 if (map_source && map_source->
type() == dods_array_c)
return static_cast<Array*
>(map_source);
320D4Group::m_find_map_source_helper(
const string &path)
325 if (lpath[0] ==
'/') {
327 throw InternalErr(__FILE__, __LINE__,
"Lookup of a FQN starting in non-root group.");
329 lpath = lpath.substr(1);
331 string::size_type pos = lpath.find(
'/');
332 if (pos == string::npos) {
338 string grp_name = lpath.substr(0, pos);
340 D4Group *grp = find_child_grp(grp_name);
341 lpath = lpath.substr(pos + 1);
348 pos = lpath.find(
'/');
350 if (pos == string::npos)
351 return (grp ==
nullptr) ?
nullptr: grp->var(lpath);
354 while (pos != string::npos) {
356 grp_name = lpath.substr(0, pos);
357 grp = grp->find_child_grp(grp_name);
358 lpath = lpath.substr(pos + 1);
359 pos = lpath.find(
'/');
362 return (grp ==
nullptr) ?
nullptr: grp->var(lpath);
367D4Group::find_enum_def(
const string &path)
372 if (lpath[0] ==
'/') {
374 throw InternalErr(__FILE__, __LINE__,
"Lookup of a FQN starting in non-root group.");
376 lpath = lpath.substr(1);
379 string::size_type pos = lpath.find(
'/');
380 if (pos == string::npos) {
382 return enum_defs()->find_enum_def(lpath);
386 string grp_name = lpath.substr(0, pos);
387 lpath = lpath.substr(pos + 1);
389 D4Group *grp = find_child_grp(grp_name);
390 return (grp == 0) ? 0: grp->enum_defs()->find_enum_def(lpath);
406 if (lpath[0] ==
'/') {
408 throw InternalErr(__FILE__, __LINE__,
"Lookup of a FQN starting in non-root group.");
410 lpath = lpath.substr(1);
413 string::size_type pos = lpath.find(
'/');
414 if (pos == string::npos) {
419 D4Group *grp = find_child_grp(lpath);
427 string grp_name = lpath.substr(0, pos);
428 lpath = lpath.substr(pos + 1);
430 D4Group *grp = find_child_grp(grp_name);
433 else if (lpath.empty())
471 for (
auto &btp: d_vars) {
474 size += btp->width_ll(constrained);
477 size += btp->width_ll(constrained);
484 for(
auto grp : d_groups)
485 size += grp->request_size_kb(constrained);
493 groupsIter g = d_groups.begin();
494 while (g != d_groups.end())
503 groupsIter g = d_groups.begin();
504 while (g != d_groups.end())
513 groupsIter g = d_groups.begin();
514 while (g != d_groups.end())
524 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
526 if ((*i)->send_p()) {
535 oss.setf(ios::hex, ios::basefield);
536 oss << setfill(
'0') << setw(8) << checksum.GetCrc32();
537 a->add_value(oss.str());
538#if INCLUDE_SOURCE_BYTE_ORDER
539 if (um.is_source_big_endian())
540 a->add_value(
"source:big-endian");
542 a->add_value(
"source:little-endian");
544 (*i)->attributes()->add_attribute_nocopy(a);
545 DBG(cerr <<
"CRC32: " << oss.str() <<
" for " << (*i)->name() << endl);
577 groupsIter g = d_groups.begin();
578 while (g != d_groups.end())
588 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
590 if ((*i)->send_p()) {
593 DBG(cerr <<
"Serializing variable " << (*i)->type_name() <<
" " << (*i)->name() << endl);
594 (*i)->serialize(m, dmr, filter);
596 DBG(cerr <<
"Wrote CRC32: " << m.
get_checksum() <<
" for " << (*i)->name() << endl);
604 groupsIter g = d_groups.begin();
605 while (g != d_groups.end()) {
606 DBG(cerr <<
"Deserializing group " << (*g)->name() << endl);
611 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
612 DBG(cerr <<
"Deserializing variable " << (*i)->type_name() <<
" " << (*i)->name() << endl);
613 (*i)->deserialize(um, dmr);
616 string crc = um.get_checksum_str();
618#if INCLUDE_SOURCE_BYTE_ORDER
620 a->add_value(
"source:big-endian");
622 a->add_value(
"source:little-endian");
624 DBG(cerr <<
"Read CRC32: " << crc <<
" for " << (*i)->name() << endl);
625 (*i)->attributes()->add_attribute_nocopy(a);
632 if (!
name().empty() &&
name() !=
"/") {
636 if (constrained && !
send_p())
639 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
type_name().c_str()) < 0)
642 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)
name().c_str()) < 0)
643 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
647 if (!
dims()->empty())
648 dims()->print_dap4(xml, constrained);
652 enum_defs()->print_dap4(xml, constrained);
663 groupsIter g = d_groups.begin();
664 while (g != d_groups.end())
667 if (!
name().empty() &&
name() !=
"/") {
668 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
677 print_decl(oss, space, print_semi, constraint_info, constrained);
678 fwrite(oss.str().data(),
sizeof(
char), oss.str().length(), out);
684 if (constrained && !
send_p())
688 for (
auto var: d_vars) {
689 var->
print_decl(out, space +
" ",
true, constraint_info, constrained);
692 for (
auto grp: d_groups) {
693 grp->print_decl(out, space +
" ",
true, constraint_info, constrained);
698 if (constraint_info) {
700 out <<
": Send True";
702 out <<
": Send False";
714 fwrite(oss.str().data(),
sizeof(
char), oss.str().length(), out);
726 bool padding_needed =
false;
727 for (Vars_citer i = d_vars.begin(), e = d_vars.end(); i != e; i++, (
void)(i != e && out <<
", ")) {
728 (*i)->print_val(out,
"",
false);
729 padding_needed =
true;
735 padding_needed =
false;
736 for (
auto grp: d_groups) {
737 grp->print_val(out,
"",
false);
738 padding_needed =
true;
799 DBG( cerr << __func__ <<
"() - BEGIN ("<<
name() <<
")" << endl);
801 vector<BaseType *> *results =
new vector<BaseType *>();
814 bool is_root = (
name() ==
"/");
817 assert(
name() ==
"/");
818 for (AttrTable::Attr_iter i = group_attrs->
attr_begin(), e = group_attrs->
attr_end(); i != e; ++i) {
819 if ((*i)->type == Attr_container) {
830 group_attrs = parent_attr_table;
835 vector<BaseType *> dropped_vars;
838 DBG( cerr << __func__ <<
"() - Processing member variable '" << (*i)->name() <<
839 "' root: " << (is_root?
"true":
"false") << endl);
841 vector<BaseType *> *new_vars = (*i)->transform_to_dap2(group_attrs);
844 for (vector<BaseType*>::iterator vi = new_vars->begin(), ve = new_vars->end(); vi != ve; vi++) {
845 string new_name = (is_root ?
"" :
FQN()) + (*vi)->name();
846 (*vi)->set_name(new_name);
847 (*vi)->set_parent(NULL);
848 results->push_back((*vi));
852 DBG( cerr << __func__ <<
"() - Added member variable '" << (*i)->name() <<
"' " <<
853 "to results vector. root: "<< (is_root?
"true":
"false") << endl);
859 DBG( cerr << __func__ <<
"() - Dropping member variable " << (*i)->name() <<
860 " root: " << (is_root?
"true":
"false") << endl);
862 dropped_vars.push_back(*i);
867 DBG( cerr << __func__ <<
"() - Processing " << dropped_vars.size() <<
" Dropped Variable(s)" << endl);
869 AttrTable *dv_attr_table = make_dropped_vars_attr_table(&dropped_vars);
875 for (D4Group::groupsIter gi =
grp_begin(), ge =
grp_end(); gi != ge; ++gi) {
876 vector<BaseType *> *d2_vars = (*gi)->transform_to_dap2(group_attrs);
878 for (vector<BaseType *>::iterator i = d2_vars->begin(), e = d2_vars->end(); i != e; ++i) {
879 results->push_back(*i);
900 bool has_projected_dap4 =
false;
903 has_projected_dap4 =
true;
918 for (
const auto grp: groups()) {
919 has_projected_dap4 |= grp->is_dap4_projected(inventory);
922 return has_projected_dap4;
A multidimensional array of identical data types.
std::vector< dimension >::iterator Dim_iter
Contains the attributes for a dataset.
virtual AttrTable * append_container(const string &name)
Add a container to the attribute table.
virtual void set_name(const string &n)
Set the name of this attribute table.
virtual Attr_iter attr_end()
virtual unsigned int append_attr(const string &name, const string &type, const string &value)
Add an attribute to the table.
virtual Attr_iter attr_begin()
virtual string get_name() const
Get the name of this attribute table.
The basic data type for the DODS DAP types.
virtual bool is_dap4_projected(std::vector< string > &projected_dap4_inventory)
virtual string type_name() const
Returns the type of the class instance as a string.
virtual string name() const
Returns the name of the class instance.
virtual void print_decl(FILE *out, string space=" ", bool print_semi=true, bool constraint_info=false, bool constrained=false)
Print an ASCII representation of the variable structure.
virtual BaseType * get_parent() const
virtual bool read_p()
Has this variable been read?
virtual D4Attributes * attributes()
virtual bool send_p()
Should this variable be sent?
BaseType(const string &n, const Type &t, bool is_dap4=false)
The BaseType constructor.
virtual Type type() const
Returns the type of the class instance.
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())
void set_read_p(bool state) override
Set the 'read_p' property for the Constructor and its members.
void set_send_p(bool state) override
bool read() override
Read the elements of Constructor marked for transmission.
const vector< BaseType * > & variables() const
void transform_attrs_to_dap2(AttrTable *d2_attr_table)
Copy the attributes from this D4Attributes object to a DAP2 AttrTable.
bool has_dap4_types(const std::string &path, std::vector< std::string > &inventory) const
void print_dap4(XMLWriter &xml, bool constrained=false) override
D4Dimension * find_dim(const string &path)
Find the dimension using a path. Using the DAP4 name syntax, lookup a dimension. The dimension must b...
void print_val(FILE *out, string space="", bool print_decl_p=true) override
Prints the value of the variable.
bool is_dap4_projected(std::vector< std::string > &inventory) override
Array * find_map_source(const string &path)
Given a path to an Array that is also a Map, get that Array.
BaseType * find_var(const string &name)
groupsIter grp_begin()
Get an iterator to the start of the values.
void intern_data() override
Read data into this variable.
void serialize(D4StreamMarshaller &m, DMR &dmr, bool filter=false) override
Serialize a Group.
uint64_t request_size_kb(bool constrained)
Get the estimated size of a response in kilobytes.
groupsIter grp_end()
Get an iterator to the end of the values.
D4Dimensions * dims()
Get the dimensions defined for this Group.
void set_send_p(bool state) override
BaseType * ptr_duplicate() override
void set_read_p(bool state) override
Set the 'read_p' property for the Constructor and its members.
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.
D4EnumDefs * enum_defs()
Get the enumerations defined for this Group.
long request_size(bool constrained)
D4Group(const string &name)
std::vector< BaseType * > * transform_to_dap2(AttrTable *parent_attr_table) override
Transform the D4Group's variables to DAP2 variables.
std::string FQN() const override
void deserialize(D4StreamUnMarshaller &um, DMR &dmr) override
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...
virtual void reset_checksum()
virtual string get_checksum()
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.
top level DAP object to house generic methods
string AttrType_to_String(const AttrType at)
string id2www(string in, const string &allowable)