29#include <libdap/XMLWriter.h>
30#include <libdap/util.h>
31#include <libdap/Array.h>
36#include "DmrppStructure.h"
37#include "byteswap_compat.h"
38#include "float_byteswap.h"
52 dynamic_cast<Structure &
>(*this) = rhs;
54 dynamic_cast<DmrppCommon &
>(*this) = rhs;
62 BESDEBUG(
"dmrpp",
"Entering " <<__PRETTY_FUNCTION__ <<
" for '" << name() <<
"'" << endl);
69 size_t value_size = 0;
73 vector<char> values(buf_value,buf_value+value_size);
75 size_t values_offset = 0;
84void DmrppStructure::structure_read(vector<char> &values,
size_t &values_offset,
bool byte_swap) {
86 BESDEBUG(
"dmrpp",
"Entering " <<__PRETTY_FUNCTION__ <<
" for '" << name() <<
"'" << endl);
89 size_t temp_values_offset = values_offset;
91 Constructor::Vars_iter vi = this->var_begin();
92 Constructor::Vars_iter ve = this->var_end();
94 vector<unsigned int> s_offs = this->get_struct_offsets();
95 unsigned int offset_counter = 0;
96 unsigned int s_offs_size = s_offs.size();
97 BESDEBUG(
"dmrpp",
"s_offs_size: " << s_offs_size <<
"'" << endl);
99 for (; vi != ve; vi++) {
101 Type t_bt = bt->type();
102 if (libdap::is_simple_type(t_bt) && t_bt != dods_str_c && t_bt != dods_url_c && t_bt!= dods_enum_c && t_bt!=dods_opaque_c) {
104 BESDEBUG(
"dmrpp",
"var name is: " << bt->name() <<
"'" << endl);
105 BESDEBUG(
"dmrpp",
"var values_offset is: " << values_offset <<
"'" << endl);
107 if(t_bt == dods_int32_c) {
108 Int32 *val_int =
static_cast<Int32 *
>(bt);
109 val_int->set_value(*((dods_int32*)(values.data()+values_offset)));
110 BESDEBUG(
"dmrpp",
"int value is: " << *((dods_int32*)(values.data()+values_offset)) <<
"'" << endl);
112 else if (t_bt == dods_float32_c) {
113 Float32 *val_float =
static_cast<Float32 *
>(bt);
114 val_float->set_value(*((dods_float32*)(values.data()+values_offset)));
115 BESDEBUG(
"dmrpp",
"float value is: " << *((dods_float32*)(values.data()+values_offset)) <<
"'" << endl);
118 bt->val2buf(values.data() + values_offset);
123 auto stored_value = values.data() + values_offset;
124 BESDEBUG(
"dmrpp",
"swap bytes " << endl);
125 swap_bytes_in_structure(stored_value,t_bt,1);
126 bt->val2buf(stored_value);
129 bt->val2buf(values.data() + values_offset);
134 if (s_offs_size == 0)
135 values_offset += bt->width_ll();
137 else if (s_offs_size <=offset_counter)
138 throw InternalErr(__FILE__, __LINE__,
"The size of offset should always be greater than the offset_counter");
140 values_offset = temp_values_offset + s_offs[offset_counter];
144 else if (t_bt == dods_array_c) {
146 auto t_a =
dynamic_cast<Array *
>(bt);
147 Type t_array_var = t_a->var()->type();
148 if (libdap::is_simple_type(t_array_var) && t_array_var != dods_str_c && t_array_var != dods_url_c && t_array_var!= dods_enum_c && t_array_var!=dods_opaque_c) {
151 BESDEBUG(
"dmrpp",
"swap array bytes " << endl);
152 auto stored_value = values.data() + values_offset;
153 swap_bytes_in_structure(stored_value,t_array_var,t_a->length_ll());
154 bt->val2buf(stored_value);
157 t_a->val2buf(values.data()+values_offset);
162 if (s_offs_size == 0)
163 values_offset += t_a->width_ll();
165 else if (s_offs_size <=offset_counter)
166 throw InternalErr(__FILE__, __LINE__,
"The size of offset should always be greater than the offset_counter");
168 values_offset = temp_values_offset + s_offs[offset_counter];
174 throw InternalErr(__FILE__, __LINE__,
"The base type of this structure is not integer or float. Currently it is not supported.");
177 throw InternalErr(__FILE__, __LINE__,
"The base type of this structure is not integer or float. Currently it is not supported.");
182DmrppStructure::swap_bytes_in_structure(
char *stored_value,
Type dap_type,int64_t num)
const{
184 BESDEBUG(
"dmrpp",
"Entering " <<__PRETTY_FUNCTION__ <<
" for '" << name() <<
"'" << endl);
187 case dods_uint16_c: {
188 auto *local =
reinterpret_cast<dods_uint16*
>(stored_value);
190 *local = bswap_16(*local);
196 case dods_uint32_c: {
197 auto *local =
reinterpret_cast<dods_uint32*
>(stored_value);
199 *local = bswap_32(*local);
205 case dods_uint64_c: {
206 auto *local =
reinterpret_cast<dods_uint64*
>(stored_value);
208 *local = bswap_64(*local);
213 case dods_float32_c: {
214 swap_float32(stored_value, num);
217 case dods_float64_c: {
218 swap_float64(stored_value, num);
227DmrppStructure::set_send_p(
bool state)
232 Structure::set_send_p(state);
235void special_structure_data_xml_element(
const XMLWriter &xml,
DmrppStructure *ds) {
237 if (ds->type() == dods_structure_c) {
238 vector<char> struct_str_buf = ds->get_structure_str_buffer();
239 string final_encoded_str = base64::Base64::encode((uint8_t*)(struct_str_buf.data()),struct_str_buf.size());
249DmrppStructure::print_dap4(libdap::XMLWriter &writer,
bool constrained) {
251 if (constrained && !this->send_p())
254 if (xmlTextWriterStartElement(writer.get_writer(), (
const xmlChar*)this->type_name().c_str()) < 0)
255 throw InternalErr(__FILE__, __LINE__,
"Could not write " + this->type_name() +
" element");
257 if (!this->name().empty()) {
258 if (xmlTextWriterWriteAttribute(writer.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)this->name().c_str()) < 0)
259 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
264 this->attributes()->print_dap4(writer);
266 if (!this->is_dap4() && this->get_attr_table().get_size() > 0)
267 this->get_attr_table().print_xml_writer(writer);
269 Constructor::Vars_iter vi = this->var_begin();
270 Constructor::Vars_iter ve = this->var_end();
272 for (; vi != ve; vi++) {
274 bt->print_dap4(writer);
282 special_structure_data_xml_element(writer,
this);
287 if (xmlTextWriterEndElement(writer.get_writer()) < 0)
288 throw InternalErr(__FILE__, __LINE__,
"Could not end " + this->type_name() +
" element");
293void DmrppStructure::dump(ostream & strm)
const
295 strm << BESIndent::LMarg <<
"DmrppStructure::dump - (" << (
void *)
this <<
")" << endl;
297 DmrppCommon::dump(strm);
298 Structure::dump(strm);
299 strm << BESIndent::LMarg <<
"value: " <<
"----" << endl;
300 BESIndent::UnIndent();
static std::string d_ns_prefix
The XML namespace prefix to use.
virtual bool twiddle_bytes() const
Returns true if this object utilizes shuffle compression.
static bool d_print_chunks
if true, print_dap4() prints chunk elements
virtual void load_attributes(libdap::BaseType *btp)
Load the attribute information for this variable.
virtual bool get_chunks_loaded() const
Have the chunks been loaded?
virtual size_t get_chunks_size() const
Use this when the number of chunks is needed.
void print_chunks_element(libdap::XMLWriter &xml, const std::string &name_space="")
Print the Chunk information.
virtual bool get_uses_fill_value() const
virtual void load_chunks(libdap::BaseType *btp)
Load chunk information for this variable.
virtual bool get_attributes_loaded() const
Have the attributes been loaded?
virtual char * read_atomic(const std::string &name)
read method for the atomic types