58#include "Marshaller.h"
59#include "UnMarshaller.h"
64#include "InternalErr.h"
70#include "Constructor.h"
71#include "D4Attributes.h"
73#include "D4Sequence.h"
77#undef CLEAR_LOCAL_DATA
83static const unsigned char end_of_sequence = 0xA5;
84static const unsigned char start_of_instance = 0x5A;
88void Sequence::m_duplicate(
const Sequence &s) {
89 DBG(cerr <<
"In Sequence::m_duplicate" << endl);
91 d_row_number = s.d_row_number;
92 d_starting_row_number = s.d_starting_row_number;
93 d_ending_row_number = s.d_ending_row_number;
94 d_row_stride = s.d_row_stride;
95 d_leaf_sequence = s.d_leaf_sequence;
96 d_unsent_data = s.d_unsent_data;
97 d_wrote_soi = s.d_wrote_soi;
98 d_top_most = s.d_top_most;
100 Sequence &cs =
const_cast<Sequence &
>(s);
103 for (vector<BaseTypeRow *>::iterator rows_iter = cs.d_values.begin(); rows_iter != cs.d_values.end(); rows_iter++) {
110 for (BaseTypeRow::iterator bt_row_iter = src_bt_row_ptr->begin(); bt_row_iter != src_bt_row_ptr->end();
112 BaseType *src_bt_ptr = *bt_row_iter;
113 BaseType *dest_bt_ptr = src_bt_ptr->ptr_duplicate();
114 dest_bt_row_ptr->push_back(dest_bt_ptr);
117 d_values.push_back(dest_bt_row_ptr);
121static void write_end_of_sequence(
Marshaller &m) { m.put_opaque((
char *)&end_of_sequence, 1); }
123static void write_start_of_instance(
Marshaller &m) { m.put_opaque((
char *)&start_of_instance, 1); }
126 unsigned char marker;
127 um.get_opaque((
char *)&marker, 1);
132static bool is_start_of_instance(
unsigned char marker) {
return (marker == start_of_instance); }
134static bool is_end_of_sequence(
unsigned char marker) {
return (marker == end_of_sequence); }
146Sequence::Sequence(
const string &n)
147 :
Constructor(n, dods_sequence_c), d_row_number(-1), d_starting_row_number(-1), d_row_stride(1),
148 d_ending_row_number(-1), d_unsent_data(false), d_wrote_soi(false), d_leaf_sequence(false), d_top_most(false) {}
160Sequence::Sequence(
const string &n,
const string &d)
161 : Constructor(n, d, dods_sequence_c), d_row_number(-1), d_starting_row_number(-1), d_row_stride(1),
162 d_ending_row_number(-1), d_unsent_data(false), d_wrote_soi(false), d_leaf_sequence(false), d_top_most(false) {}
165Sequence::Sequence(
const Sequence &rhs) : Constructor(rhs) { m_duplicate(rhs); }
167BaseType *Sequence::ptr_duplicate() {
return new Sequence(*
this); }
183void Sequence::transform_to_dap4(D4Group *root, Constructor *container) {
188 dest->set_length(-1);
189 container->add_var_nocopy(dest);
192 dest =
new D4Sequence(name());
193 Constructor::transform_to_dap4(root, dest);
194 dest->set_length(-1);
195 container->add_var_nocopy(dest);
198static inline void delete_bt(
BaseType *bt_ptr) {
203static inline void delete_rows(BaseTypeRow *bt_row_ptr) {
204 for_each(bt_row_ptr->begin(), bt_row_ptr->end(), delete_bt);
210Sequence::~Sequence() {
212 Sequence::clear_local_data();
213 }
catch (
const std::exception &) {
218void Sequence::clear_local_data() {
219 if (!d_values.empty()) {
220 for_each(d_values.begin(), d_values.end(), delete_rows);
227Sequence &Sequence::operator=(
const Sequence &rhs) {
230 Constructor::operator=(rhs);
238bool Sequence::is_dap2_only_type() {
return true; }
240string Sequence::toString() {
243 oss << BaseType::toString();
245 for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
246 oss << (*i)->toString();
254bool Sequence::is_linear() {
256 bool seq_found =
false;
257 for (Vars_iter iter = d_vars.begin(); linear && iter != d_vars.end(); iter++) {
258 if ((*iter)->type() == dods_sequence_c) {
267 linear =
static_cast<Sequence *
>((*iter))->is_linear();
268 }
else if ((*iter)->type() == dods_structure_c) {
269 linear =
static_cast<Structure *
>((*iter))->is_linear();
272 linear = (*iter)->is_simple_type();
284 if (row >= d_values.size())
286 return d_values[row];
295void Sequence::set_value(SequenceValues &values) { d_values = values; }
310BaseType *Sequence::var_value(
size_t row,
const string &name) {
315 BaseTypeRow::iterator bt_row_iter = bt_row_ptr->begin();
316 BaseTypeRow::iterator bt_row_end = bt_row_ptr->end();
317 while (bt_row_iter != bt_row_end && (*bt_row_iter)->name() != name)
320 if (bt_row_iter == bt_row_end)
331BaseType *Sequence::var_value(
size_t row,
size_t i) {
336 if (i >= bt_row_ptr->size())
339 return (*bt_row_ptr)[i];
360int Sequence::length()
const {
return -1; }
363int Sequence::number_of_rows()
const {
return d_values.size(); }
368void Sequence::reset_row_number() { d_row_number = -1; }
375void Sequence::reset_row_number(
bool recur) {
379 for (Vars_iter i = var_begin(), e = var_end(); i != e; ++i)
380 if ((*i)->type() == dods_sequence_c)
381 reset_row_number(
true);
436bool Sequence::read_row(
int row, DDS &dds, ConstraintEvaluator &eval,
bool ce_eval) {
437 DBG2(cerr <<
"Entering Sequence::read_row for " << name() <<
", row number " << row <<
", current row "
438 << d_row_number << endl);
439 if (row < d_row_number)
440 throw InternalErr(
"Trying to back up inside a sequence!");
442 if (row == d_row_number) {
443 DBG2(cerr <<
"Leaving Sequence::read_row for " << name() << endl);
448 while (!eof && d_row_number < row) {
457 if (!eof && (!ce_eval || eval.eval_selection(dds,
dataset())))
470 DBG2(cerr <<
"Leaving Sequence::read_row for " << name() <<
" with eof: " << eof << endl);
481inline bool Sequence::is_end_of_rows(
int i) {
482 return ((d_ending_row_number == -1) ?
false : (i > d_ending_row_number));
545bool Sequence::serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m,
bool ce_eval) {
549 if (is_leaf_sequence())
550 status = serialize_leaf(dds, eval, m, ce_eval);
552 status = serialize_parent_part_one(dds, eval, m);
561bool Sequence::serialize_parent_part_one(DDS &dds, ConstraintEvaluator &eval, Marshaller &m) {
562 DBG2(cerr <<
"Entering serialize_parent_part_one for " << name() << endl);
564 int i = (d_starting_row_number != -1) ? d_starting_row_number : 0;
570 bool status = read_row(i, dds, eval,
false);
571 DBG2(cerr <<
"Sequence::serialize_parent_part_one::read_row() status: " << status << endl);
573 while (status && !is_end_of_rows(i)) {
580 for (Vars_iter iter = d_vars.begin(); iter != d_vars.end(); iter++) {
590 if ((*iter)->send_p() && (*iter)->type() == dods_sequence_c)
591 (*iter)->serialize(eval, dds, m);
596 status = read_row(i, dds, eval,
false);
597 DBG(cerr <<
"Sequence::serialize_parent_part_one::read_row() status: " << status << endl);
605 if (d_top_most || d_wrote_soi) {
606 DBG(cerr <<
"Writing End of Sequence marker" << endl);
607 write_end_of_sequence(m);
624void Sequence::serialize_parent_part_two(DDS &dds, ConstraintEvaluator &eval, Marshaller &m) {
625 DBG(cerr <<
"Entering serialize_parent_part_two for " << name() << endl);
628 if (btp && btp->type() == dods_sequence_c)
629 static_cast<Sequence &
>(*btp).serialize_parent_part_two(dds, eval, m);
632 DBG(cerr <<
"Writing Start of Instance marker" << endl);
634 write_start_of_instance(m);
637 for (Vars_iter iter = d_vars.begin(); iter != d_vars.end(); iter++) {
639 DBG(cerr <<
"Sequence::serialize_parent_part_two(), serializing " << (*iter)->name() << endl);
640 if ((*iter)->send_p() && (*iter)->type() != dods_sequence_c) {
641 DBG(cerr <<
"Send P is true, sending " << (*iter)->name() << endl);
642 (*iter)->serialize(eval, dds, m,
false);
646 d_unsent_data =
false;
652bool Sequence::serialize_leaf(DDS &dds, ConstraintEvaluator &eval, Marshaller &m,
bool ce_eval) {
653 DBG(cerr <<
"Entering Sequence::serialize_leaf for " << name() << endl);
654 int i = (d_starting_row_number != -1) ? d_starting_row_number : 0;
658 bool status = read_row(i, dds, eval, ce_eval);
659 DBG(cerr <<
"Sequence::serialize_leaf::read_row() status: " << status << endl);
671 if (status && !is_end_of_rows(i)) {
673 if (btp && btp->type() == dods_sequence_c)
674 static_cast<Sequence &
>(*btp).serialize_parent_part_two(dds, eval, m);
678 while (status && !is_end_of_rows(i)) {
681 DBG(cerr <<
"Writing Start of Instance marker" << endl);
683 write_start_of_instance(m);
686 for (Vars_iter iter = d_vars.begin(); iter != d_vars.end(); iter++) {
687 DBG(cerr <<
"Sequence::serialize_leaf(), serializing " << (*iter)->name() << endl);
688 if ((*iter)->send_p()) {
689 DBG(cerr <<
"Send P is true, sending " << (*iter)->name() << endl);
690 (*iter)->serialize(eval, dds, m,
false);
696 status = read_row(i, dds, eval, ce_eval);
697 DBG(cerr <<
"Sequence::serialize_leaf::read_row() status: " << status << endl);
702 if (d_wrote_soi || d_top_most) {
703 DBG(cerr <<
"Writing End of Sequence marker" << endl);
704 write_end_of_sequence(m);
732void Sequence::intern_data(ConstraintEvaluator &eval, DDS &dds) {
733 DBG(cerr <<
"Sequence::intern_data - for " << name() << endl);
734 DBG2(cerr <<
" intern_data, values: " << &d_values << endl);
736 throw Error(
string(
"A method usable only with DAP2 variables was called on a DAP4 variable (")
744 sequence_values_stack_t sequence_values_stack;
746 sequence_values_stack.push(&d_values);
748 intern_data_private(eval, dds, sequence_values_stack);
751void Sequence::intern_data_private(ConstraintEvaluator &eval, DDS &dds,
752 sequence_values_stack_t &sequence_values_stack) {
753 DBG(cerr <<
"Entering intern_data_private for " << name() << endl);
755 if (is_leaf_sequence())
756 intern_data_for_leaf(dds, eval, sequence_values_stack);
758 intern_data_parent_part_one(dds, eval, sequence_values_stack);
761void Sequence::intern_data_parent_part_one(DDS &dds, ConstraintEvaluator &eval,
762 sequence_values_stack_t &sequence_values_stack) {
763 DBG(cerr <<
"Entering intern_data_parent_part_one for " << name() << endl);
765 int i = (get_starting_row_number() != -1) ? get_starting_row_number() : 0;
771 bool status = read_row(i, dds, eval,
false);
779 SequenceValues::size_type orig_stack_size = sequence_values_stack.size();
781 while (status && (get_ending_row_number() == -1 || i <= get_ending_row_number())) {
782 i += get_row_stride();
783 for (Vars_iter iter = var_begin(); iter != var_end(); iter++) {
784 if ((*iter)->send_p()) {
785 switch ((*iter)->type()) {
786 case dods_sequence_c:
787 static_cast<Sequence &
>(**iter).intern_data_private(eval, dds, sequence_values_stack);
791 (*iter)->intern_data(eval, dds);
799 status = read_row(i, dds, eval,
false);
809 if (sequence_values_stack.size() > orig_stack_size) {
810 DBG2(cerr <<
" popping d_values (" << sequence_values_stack.top()
811 <<
") off stack; size: " << sequence_values_stack.size() << endl);
812 sequence_values_stack.pop();
815 DBG(cerr <<
"Leaving intern_data_parent_part_one for " << name() << endl);
818void Sequence::intern_data_parent_part_two(DDS &dds, ConstraintEvaluator &eval,
819 sequence_values_stack_t &sequence_values_stack) {
820 DBG(cerr <<
"Entering intern_data_parent_part_two for " << name() << endl);
823 if (btp && btp->type() == dods_sequence_c) {
824 static_cast<Sequence &
>(*btp).intern_data_parent_part_two(dds, eval, sequence_values_stack);
827 DBG2(cerr <<
" stack size: " << sequence_values_stack.size() << endl);
829 DBG2(cerr <<
" using values = " << (
void *)values << endl);
831 if (get_unsent_data()) {
835 for (Vars_iter iter = var_begin(); iter != var_end(); iter++) {
837 if ((*iter)->send_p() && (*iter)->type() != dods_sequence_c) {
838 row_data->push_back((*iter)->ptr_duplicate());
839 }
else if ((*iter)->send_p()) {
840 Sequence *tmp =
dynamic_cast<Sequence *
>((*iter)->ptr_duplicate());
843 throw InternalErr(__FILE__, __LINE__,
"Expected a Sequence.");
845 row_data->push_back(tmp);
846 DBG2(cerr <<
" pushing d_values of " << tmp->name() <<
" (" << &(tmp->d_values)
847 <<
") on stack; size: " << sequence_values_stack.size() << endl);
851 sequence_values_stack.push(&(tmp->d_values));
855 DBG2(cerr <<
" pushing values for " << name() <<
" to " << values << endl);
856 values->push_back(row_data);
857 set_unsent_data(
false);
860 DBG(cerr <<
"Leaving intern_data_parent_part_two for " << name() << endl);
863void Sequence::intern_data_for_leaf(DDS &dds, ConstraintEvaluator &eval,
864 sequence_values_stack_t &sequence_values_stack) {
865 DBG(cerr <<
"Entering intern_data_for_leaf for " << name() << endl);
867 int i = (get_starting_row_number() != -1) ? get_starting_row_number() : 0;
869 DBG2(cerr <<
" reading row " << i << endl);
870 bool status = read_row(i, dds, eval,
true);
871 DBG2(cerr <<
" status: " << status << endl);
872 DBG2(cerr <<
" ending row number: " << get_ending_row_number() << endl);
874 if (status && (get_ending_row_number() == -1 || i <= get_ending_row_number())) {
876 if (btp && btp->type() == dods_sequence_c) {
880 static_cast<Sequence &
>(*btp).intern_data_parent_part_two(dds, eval, sequence_values_stack);
887 DBG2(cerr <<
" using values = " << values << endl);
889 while (status && (get_ending_row_number() == -1 || i <= get_ending_row_number())) {
890 i += get_row_stride();
894 for (Vars_iter iter = var_begin(); iter != var_end(); iter++) {
895 if ((*iter)->send_p()) {
896 row_data->push_back((*iter)->ptr_duplicate());
900 DBG2(cerr <<
" pushing values for " << name() <<
" to " << values << endl);
902 values->push_back(row_data);
906 status = read_row(i, dds, eval,
true);
909 DBG2(cerr <<
" popping d_values (" << sequence_values_stack.top()
910 <<
") off stack; size: " << sequence_values_stack.size() << endl);
911 sequence_values_stack.pop();
914 DBG(cerr <<
"Leaving intern_data_for_leaf for " << name() << endl);
937bool Sequence::deserialize(UnMarshaller &um, DDS *dds,
bool reuse) {
940 DataDDS *dd =
dynamic_cast<DataDDS *
>(dds);
941 if (!dd)
throw InternalErr(
"Expected argument 'dds' to be a DataDDS!");
943 DBG2(cerr <<
"Reading from server/protocol version: "
944 << dd->get_protocol_major() <<
"." << dd->get_protocol_minor()
948 if (dd->get_protocol_major() < 2) {
950 string(
"The protocl version (") + dd->get_protocol()
951 +
") indicates that this\nis an old server which may not correctly transmit Sequence variables.\nContact the server administrator.");
956 unsigned char marker = read_marker(um);
957 if (is_end_of_sequence(marker))
959 else if (is_start_of_instance(marker)) {
961 DBG2(cerr <<
"Reading row " << d_row_number <<
" of " << name() << endl);
964 for (Vars_iter iter = d_vars.begin(); iter != d_vars.end(); iter++) {
965 BaseType *bt_ptr = (*iter)->ptr_duplicate();
966 bt_ptr->deserialize(um, dds, reuse);
967 DBG2(cerr <<
"Deserialized " << bt_ptr->name() <<
" (" << bt_ptr <<
") = ");
968 DBG2(bt_ptr->print_val(stderr,
""));
969 bt_row_ptr->push_back(bt_ptr);
972 d_values.push_back(bt_row_ptr);
974 throw Error(
"I could not read the expected Sequence data stream marker!");
993int Sequence::get_starting_row_number() {
return d_starting_row_number; }
1005int Sequence::get_row_stride() {
return d_row_stride; }
1018int Sequence::get_ending_row_number() {
return d_ending_row_number; }
1028void Sequence::set_row_number_constraint(
int start,
int stop,
int stride) {
1030 throw Error(malformed_expr,
"Starting row number must precede the ending row number.");
1032 d_starting_row_number = start;
1033 d_row_stride = stride;
1034 d_ending_row_number = stop;
1037void Sequence::print_one_row(FILE *out,
int row,
string space,
bool print_row_num) {
1039 print_one_row(oss, row, space, print_row_num);
1040 fwrite(oss.str().data(),
sizeof(
char), oss.str().length(), out);
1043void Sequence::print_one_row(ostream &out,
int row,
string space,
bool print_row_num) {
1045 out <<
"\n" << space << row <<
": ";
1049 int elements = element_count();
1059 while (j < elements && !bt_ptr) {
1062 if (bt_ptr->type() == dods_sequence_c)
1063 static_cast<Sequence *
>(bt_ptr)->print_val_by_rows(out, space +
" ",
false, print_row_num);
1065 bt_ptr->print_val(out, space,
false);
1070 while (j < elements) {
1074 if (bt_ptr->type() == dods_sequence_c)
1075 static_cast<Sequence *
>(bt_ptr)->print_val_by_rows(out, space +
" ",
false, print_row_num);
1077 bt_ptr->print_val(out, space,
false);
1084void Sequence::print_val_by_rows(FILE *out,
string space,
bool print_decl_p,
bool print_row_numbers) {
1086 print_val_by_rows(oss, space, print_decl_p, print_row_numbers);
1087 fwrite(oss.str().data(),
sizeof(
char), oss.str().length(), out);
1090void Sequence::print_val_by_rows(ostream &out,
string space,
bool print_decl_p,
bool print_row_numbers) {
1092 print_decl(out, space,
false);
1098 int rows = number_of_rows() - 1;
1100 for (i = 0; i < rows; ++i) {
1101 print_one_row(out, i, space, print_row_numbers);
1104 print_one_row(out, i, space, print_row_numbers);
1112void Sequence::print_val(FILE *out,
string space,
bool print_decl_p) {
1113 print_val_by_rows(out, space, print_decl_p,
false);
1116void Sequence::print_val(ostream &out,
string space,
bool print_decl_p) {
1117 print_val_by_rows(out, space, print_decl_p,
false);
1120void Sequence::set_leaf_p(
bool state) { d_leaf_sequence = state; }
1122bool Sequence::is_leaf_sequence() {
return d_leaf_sequence; }
1148void Sequence::set_leaf_sequence(
int lvl) {
1149 bool has_child_sequence =
false;
1154 DBG2(cerr <<
"Processing sequence " << name() << endl);
1156 for (Vars_iter iter = d_vars.begin(); iter != d_vars.end(); iter++) {
1162 if ((*iter)->type() == dods_sequence_c && (*iter)->send_p()) {
1163 if (has_child_sequence)
1164 throw Error(
"This implementation does not support more than one nested sequence at a level. Contact "
1165 "the server administrator.");
1167 has_child_sequence =
true;
1168 static_cast<Sequence &
>(**iter).set_leaf_sequence(++lvl);
1169 }
else if ((*iter)->type() == dods_structure_c) {
1170 static_cast<Structure &
>(**iter).set_leaf_sequence(lvl);
1174 if (!has_child_sequence)
1179 DBG2(cerr <<
"is_leaf_sequence(): " << is_leaf_sequence() <<
" (" << name() <<
")" << endl);
1190void Sequence::dump(ostream &strm)
const {
1191 strm << DapIndent::LMarg <<
"Sequence::dump - (" << (
void *)
this <<
")" << endl;
1192 DapIndent::Indent();
1193 Constructor::dump(strm);
1194 strm << DapIndent::LMarg <<
"# rows deserialized: " << d_row_number << endl;
1195 strm << DapIndent::LMarg <<
"bracket notation information:" << endl;
1196 DapIndent::Indent();
1197 strm << DapIndent::LMarg <<
"starting row #: " << d_starting_row_number << endl;
1198 strm << DapIndent::LMarg <<
"row stride: " << d_row_stride << endl;
1199 strm << DapIndent::LMarg <<
"ending row #: " << d_ending_row_number << endl;
1200 DapIndent::UnIndent();
1202 strm << DapIndent::LMarg <<
"data been sent? " << d_unsent_data << endl;
1203 strm << DapIndent::LMarg <<
"start of instance? " << d_wrote_soi << endl;
1204 strm << DapIndent::LMarg <<
"is leaf sequence? " << d_leaf_sequence << endl;
1205 strm << DapIndent::LMarg <<
"top most in hierarchy? " << d_top_most << endl;
1206 DapIndent::UnIndent();
abstract base class used to marshal/serialize dap data objects
abstract base class used to unmarshall/deserialize dap data objects
top level DAP object to house generic methods
virtual BaseType * ptr_duplicate()=0
virtual bool read_p()
Has this variable been read?
vector< BaseType * > BaseTypeRow
vector< BaseTypeRow * > SequenceValues
virtual BaseType * var_value(size_t row, const string &name)
Get the BaseType pointer to the named variable of a given row.
virtual string dataset() const
Returns the name of the dataset used to create this instance.
virtual D4SeqRow * row_value(size_t row)
Get a whole row from the sequence.