35#include "D4Attributes.h"
36#include "D4Dimensions.h"
41#include "D4StreamMarshaller.h"
42#include "D4StreamUnMarshaller.h"
53#undef INCLUDE_SOURCE_BYTE_ORDER
57void D4Group::m_duplicate(
const D4Group &g) {
58 DBG(cerr <<
"In D4Group::m_duplicate for " << g.name() << endl);
62 d_dims =
new D4Dimensions(*(g.d_dims));
63 d_dims->set_parent(
this);
71 Vars_citer vi = d_vars.begin();
72 while (vi != d_vars.end()) {
73 if ((*vi)->type() == dods_array_c)
74 static_cast<Array *
>(*vi)->update_dimension_pointers(g.d_dims, d_dims);
81 d_enum_defs =
new D4EnumDefs(*g.d_enum_defs);
84 groupsCIter i = g.d_groups.begin();
85 while (i != g.d_groups.end()) {
91 DBG(cerr <<
"Exiting D4Group::m_duplicate" << endl);
117 : Constructor(
name,
dataset, dods_group_c, true), d_dims(0), d_enum_defs(0) {}
121 DBG(cerr <<
"In D4Group::copy_ctor for " << rhs.
name() << endl);
129 groupsIter i = d_groups.begin();
130 while (i != d_groups.end())
144 Constructor::operator=(rhs);
160D4Group *D4Group::find_child_grp(
const string &grp_name) {
162 return (g ==
grp_end()) ? 0 : *g;
178 if ((*i)->send_p() && (*i)->type() == dods_array_c) {
179 Array *a =
static_cast<Array *
>(*i);
180 for (
Array::Dim_iter di = a->dim_begin(), de = a->dim_end(); di != de; ++di) {
181 if (a->dimension_D4dim(di) == dim)
188 BaseType *btp = (*i)->find_first_var_that_uses_dimension(dim);
208 if ((*i)->send_p() && (*i)->type() == dods_enum_c) {
209 D4Enum *e =
static_cast<D4Enum *
>(*i);
210 if (e->enumeration() == enum_def)
216 BaseType *btp = (*i)->find_first_var_that_uses_enumeration(enum_def);
237 if (lpath[0] ==
'/') {
239 throw InternalErr(__FILE__, __LINE__,
"Lookup of a FQN starting in non-root group.");
241 lpath = lpath.substr(1);
244 string::size_type pos = lpath.find(
'/');
245 if (pos == string::npos) {
247 return dims()->find_dim(lpath);
251 string grp_name = lpath.substr(0, pos);
252 lpath = lpath.substr(pos + 1);
254 D4Group *grp = find_child_grp(grp_name);
255 return (grp == 0) ? 0 : grp->
find_dim(lpath);
264 BaseType *map_source = m_find_map_source_helper(path);
267 if (map_source && map_source->
type() == dods_array_c)
268 return static_cast<Array *
>(map_source);
278BaseType *D4Group::m_find_map_source_helper(
const string &path) {
282 if (lpath[0] ==
'/') {
284 throw InternalErr(__FILE__, __LINE__,
"Lookup of a FQN starting in non-root group.");
286 lpath = lpath.substr(1);
288 string::size_type pos = lpath.find(
'/');
289 if (pos == string::npos) {
295 string grp_name = lpath.substr(0, pos);
297 D4Group *grp = find_child_grp(grp_name);
298 lpath = lpath.substr(pos + 1);
305 pos = lpath.find(
'/');
307 if (pos == string::npos)
308 return (grp ==
nullptr) ? nullptr : grp->var(lpath);
311 while (pos != string::npos) {
313 grp_name = lpath.substr(0, pos);
314 grp = grp->find_child_grp(grp_name);
315 lpath = lpath.substr(pos + 1);
316 pos = lpath.find(
'/');
319 return (grp ==
nullptr) ? nullptr : grp->var(lpath);
322D4EnumDef *D4Group::find_enum_def(
const string &path) {
326 if (lpath[0] ==
'/') {
328 throw InternalErr(__FILE__, __LINE__,
"Lookup of a FQN starting in non-root group.");
330 lpath = lpath.substr(1);
333 string::size_type pos = lpath.find(
'/');
334 if (pos == string::npos) {
336 return enum_defs()->find_enum_def(lpath);
340 string grp_name = lpath.substr(0, pos);
341 lpath = lpath.substr(pos + 1);
343 D4Group *grp = find_child_grp(grp_name);
344 return (grp == 0) ? 0 : grp->enum_defs()->find_enum_def(lpath);
358 if (lpath[0] ==
'/') {
360 throw InternalErr(__FILE__, __LINE__,
"Lookup of a FQN starting in non-root group.");
362 lpath = lpath.substr(1);
365 string::size_type pos = lpath.find(
'/');
366 if (pos == string::npos) {
371 D4Group *grp = find_child_grp(lpath);
379 string grp_name = lpath.substr(0, pos);
380 lpath = lpath.substr(pos + 1);
382 D4Group *grp = find_child_grp(grp_name);
385 else if (lpath.empty())
418 for (
auto &btp : d_vars) {
421 size += btp->width_ll(constrained);
423 size += btp->width_ll(constrained);
430 for (
auto grp : d_groups)
431 size += grp->request_size_kb(constrained);
437 groupsIter g = d_groups.begin();
438 while (g != d_groups.end())
445 groupsIter g = d_groups.begin();
446 while (g != d_groups.end())
453 groupsIter g = d_groups.begin();
454 while (g != d_groups.end())
464 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
466 if ((*i)->send_p()) {
475 oss.setf(ios::hex, ios::basefield);
476 oss << setfill(
'0') << setw(8) << checksum.GetCrc32();
477 a->add_value(oss.str());
478#if INCLUDE_SOURCE_BYTE_ORDER
479 if (um.is_source_big_endian())
480 a->add_value(
"source:big-endian");
482 a->add_value(
"source:little-endian");
484 (*i)->attributes()->add_attribute_nocopy(a);
485 DBG(cerr <<
"CRC32: " << oss.str() <<
" for " << (*i)->name() << endl);
515 groupsIter g = d_groups.begin();
516 while (g != d_groups.end())
526 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
528 if ((*i)->send_p()) {
531 DBG(cerr <<
"Serializing variable " << (*i)->type_name() <<
" " << (*i)->name() << endl);
532 (*i)->serialize(m, dmr, filter);
534 DBG(cerr <<
"Wrote CRC32: " << m.
get_checksum() <<
" for " << (*i)->name() << endl);
541 groupsIter g = d_groups.begin();
542 while (g != d_groups.end()) {
543 DBG(cerr <<
"Deserializing group " << (*g)->name() << endl);
548 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
549 DBG(cerr <<
"Deserializing variable " << (*i)->type_name() <<
" " << (*i)->name() << endl);
550 (*i)->deserialize(um, dmr);
553 string crc = um.get_checksum_str();
555#if INCLUDE_SOURCE_BYTE_ORDER
557 a->add_value(
"source:big-endian");
559 a->add_value(
"source:little-endian");
561 DBG(cerr <<
"Read CRC32: " << crc <<
" for " << (*i)->name() << endl);
562 (*i)->attributes()->add_attribute_nocopy(a);
567 if (!
name().empty() &&
name() !=
"/") {
571 if (constrained && !
send_p())
574 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar *)
type_name().c_str()) < 0)
577 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar *)
"name", (
const xmlChar *)
name().c_str()) < 0)
578 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
582 if (!
dims()->empty())
583 dims()->print_dap4(xml, constrained);
587 enum_defs()->print_dap4(xml, constrained);
598 groupsIter g = d_groups.begin();
599 while (g != d_groups.end())
602 if (!
name().empty() &&
name() !=
"/") {
603 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
608void D4Group::print_decl(FILE *out,
string space,
bool print_semi,
bool constraint_info,
bool constrained) {
610 print_decl(oss, space, print_semi, constraint_info, constrained);
611 fwrite(oss.str().data(),
sizeof(
char), oss.str().length(), out);
614void D4Group::print_decl(ostream &out,
string space,
bool print_semi,
bool constraint_info,
bool constrained) {
615 if (constrained && !
send_p())
619 for (
auto var : d_vars) {
620 var->print_decl(out, space +
" ",
true, constraint_info, constrained);
623 for (
auto grp : d_groups) {
624 grp->print_decl(out, space +
" ",
true, constraint_info, constrained);
629 if (constraint_info) {
631 out <<
": Send True";
633 out <<
": Send False";
643 fwrite(oss.str().data(),
sizeof(
char), oss.str().length(), out);
653 bool padding_needed =
false;
654 for (Vars_citer i = d_vars.begin(), e = d_vars.end(); i != e; i++, (
void)(i != e && out <<
", ")) {
655 (*i)->print_val(out,
"",
false);
656 padding_needed =
true;
662 padding_needed =
false;
663 for (
auto grp : d_groups) {
664 grp->print_val(out,
"",
false);
665 padding_needed =
true;
724 DBG(cerr << __func__ <<
"() - BEGIN (" <<
name() <<
")" << endl);
726 vector<BaseType *> *results =
new vector<BaseType *>();
739 bool is_root = (
name() ==
"/");
742 assert(
name() ==
"/");
743 for (AttrTable::Attr_iter i = group_attrs->
attr_begin(), e = group_attrs->
attr_end(); i != e; ++i) {
744 if ((*i)->type == Attr_container) {
755 group_attrs = parent_attr_table;
760 vector<BaseType *> dropped_vars;
763 DBG(cerr << __func__ <<
"() - Processing member variable '" << (*i)->name()
764 <<
"' root: " << (is_root ?
"true" :
"false") << endl);
766 vector<BaseType *> *new_vars = (*i)->transform_to_dap2(group_attrs);
770 string new_name = (is_root ?
"" :
FQN()) + (*vi)->name();
771 (*vi)->set_name(new_name);
772 (*vi)->set_parent(NULL);
773 results->push_back((*vi));
777 DBG(cerr << __func__ <<
"() - Added member variable '" << (*i)->name() <<
"' "
778 <<
"to results vector. root: " << (is_root ?
"true" :
"false") << endl);
783 DBG(cerr << __func__ <<
"() - Dropping member variable " << (*i)->name()
784 <<
" root: " << (is_root ?
"true" :
"false") << endl);
786 dropped_vars.push_back(*i);
791 DBG(cerr << __func__ <<
"() - Processing " << dropped_vars.size() <<
" Dropped Variable(s)" << endl);
793 AttrTable *dv_attr_table = make_dropped_vars_attr_table(&dropped_vars);
799 for (D4Group::groupsIter gi =
grp_begin(), ge =
grp_end(); gi != ge; ++gi) {
800 vector<BaseType *> *d2_vars = (*gi)->transform_to_dap2(group_attrs);
803 results->push_back(*i);
823 bool has_projected_dap4 =
false;
826 has_projected_dap4 =
true;
838 has_projected_dap4 |=
var->is_dap4_projected(inventory);
841 for (
const auto grp : groups()) {
842 has_projected_dap4 |= grp->is_dap4_projected(inventory);
845 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 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 BaseType * get_parent() const
virtual bool read_p()
Has this variable been read?
virtual string dataset() const
Returns the name of the dataset used to create this instance.
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)