00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "config.h"
00037
00038 #include <algorithm>
00039 #include <string>
00040 #include <sstream>
00041
00042
00043
00044
00045 #include "Byte.h"
00046 #include "Int16.h"
00047 #include "UInt16.h"
00048 #include "Int32.h"
00049 #include "UInt32.h"
00050 #include "Float32.h"
00051 #include "Float64.h"
00052 #include "Str.h"
00053 #include "Url.h"
00054 #include "Array.h"
00055 #include "Structure.h"
00056 #include "Sequence.h"
00057 #include "Grid.h"
00058
00059 #include "debug.h"
00060 #include "Error.h"
00061 #include "InternalErr.h"
00062 #include "Sequence.h"
00063 #include "DDS.h"
00064 #include "DataDDS.h"
00065 #include "util.h"
00066 #include "InternalErr.h"
00067 #include "escaping.h"
00068
00069 using namespace std;
00070
00071 namespace libdap {
00072
00073 static const unsigned char end_of_sequence = 0xA5;
00074 static const unsigned char start_of_instance = 0x5A;
00075
00076
00077
00078 void
00079 Sequence::_duplicate(const Sequence &s)
00080 {
00081 d_row_number = s.d_row_number;
00082 d_starting_row_number = s.d_starting_row_number;
00083 d_ending_row_number = s.d_ending_row_number;
00084 d_row_stride = s.d_row_stride;
00085 d_leaf_sequence = s.d_leaf_sequence;
00086 d_unsent_data = s.d_unsent_data;
00087 d_wrote_soi = s.d_wrote_soi;
00088 d_top_most = s.d_top_most;
00089
00090 Sequence &cs = const_cast<Sequence &>(s);
00091
00092
00093 for (Vars_iter i = cs.var_begin(); i != cs.var_end(); i++) {
00094 add_var((*i)) ;
00095 }
00096
00097
00098 for (vector<BaseTypeRow *>::iterator rows_iter = cs.d_values.begin();
00099 rows_iter != cs.d_values.end();
00100 rows_iter++) {
00101
00102 BaseTypeRow *src_bt_row_ptr = *rows_iter;
00103
00104 BaseTypeRow *dest_bt_row_ptr = new BaseTypeRow;
00105
00106
00107 for (BaseTypeRow::iterator bt_row_iter = src_bt_row_ptr->begin();
00108 bt_row_iter != src_bt_row_ptr->end();
00109 bt_row_iter++) {
00110 BaseType *src_bt_ptr = *bt_row_iter;
00111 BaseType *dest_bt_ptr = src_bt_ptr->ptr_duplicate();
00112 dest_bt_row_ptr->push_back(dest_bt_ptr);
00113 }
00114
00115 d_values.push_back(dest_bt_row_ptr);
00116 }
00117 }
00118
00119 static void
00120 write_end_of_sequence(Marshaller &m)
00121 {
00122 m.put_opaque( (char *)&end_of_sequence, 1 ) ;
00123 }
00124
00125 static void
00126 write_start_of_instance(Marshaller &m)
00127 {
00128 m.put_opaque( (char *)&start_of_instance, 1 ) ;
00129 }
00130
00131 static unsigned char
00132 read_marker(UnMarshaller &um)
00133 {
00134 unsigned char marker;
00135 um.get_opaque( (char *)&marker, 1 ) ;
00136
00137 return marker;
00138 }
00139
00140 static bool
00141 is_start_of_instance(unsigned char marker)
00142 {
00143 return (marker == start_of_instance);
00144 }
00145
00146 static bool
00147 is_end_of_sequence(unsigned char marker)
00148 {
00149 return (marker == end_of_sequence);
00150 }
00151
00152
00153
00162 Sequence::Sequence(const string &n) : Constructor(n, dods_sequence_c),
00163 d_row_number(-1), d_starting_row_number(-1),
00164 d_row_stride(1), d_ending_row_number(-1),
00165 d_unsent_data(false), d_wrote_soi(false),
00166 d_leaf_sequence(false), d_top_most(false)
00167 {}
00168
00179 Sequence::Sequence(const string &n, const string &d)
00180 : Constructor(n, d, dods_sequence_c),
00181 d_row_number(-1), d_starting_row_number(-1),
00182 d_row_stride(1), d_ending_row_number(-1),
00183 d_unsent_data(false), d_wrote_soi(false),
00184 d_leaf_sequence(false), d_top_most(false)
00185 {}
00186
00188 Sequence::Sequence(const Sequence &rhs) : Constructor(rhs)
00189 {
00190 _duplicate(rhs);
00191 }
00192
00193 BaseType *
00194 Sequence::ptr_duplicate()
00195 {
00196 return new Sequence(*this);
00197 }
00198
00199 static inline void
00200 delete_bt(BaseType *bt_ptr)
00201 {
00202 DBG2(cerr << "In delete_bt: " << bt_ptr << endl);
00203 delete bt_ptr; bt_ptr = 0;
00204 }
00205
00206 static inline void
00207 delete_rows(BaseTypeRow *bt_row_ptr)
00208 {
00209 DBG2(cerr << "In delete_rows: " << bt_row_ptr << endl);
00210
00211 for_each(bt_row_ptr->begin(), bt_row_ptr->end(), delete_bt);
00212
00213 delete bt_row_ptr; bt_row_ptr = 0;
00214 }
00215
00216 Sequence::~Sequence()
00217 {
00218 DBG2(cerr << "Entering Sequence::~Sequence" << endl);
00219 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00220 BaseType *btp = *i ;
00221 delete btp ; btp = 0;
00222 }
00223
00224 for_each(d_values.begin(), d_values.end(), delete_rows);
00225 DBG2(cerr << "exiting Sequence::~Sequence" << endl);
00226 }
00227
00228 Sequence &
00229 Sequence::operator=(const Sequence &rhs)
00230 {
00231 if (this == &rhs)
00232 return *this;
00233
00234 dynamic_cast<Constructor &>(*this) = rhs;
00235
00236 _duplicate(rhs);
00237
00238 return *this;
00239 }
00240
00241 string
00242 Sequence::toString()
00243 {
00244 ostringstream oss;
00245
00246 oss << BaseType::toString();
00247
00248 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00249 oss << (*i)->toString();
00250 }
00251
00252 oss << endl;
00253
00254 return oss.str();
00255 }
00256
00257 int
00258 Sequence::element_count(bool leaves)
00259 {
00260 if (!leaves)
00261 return _vars.size();
00262 else {
00263 int i = 0;
00264 for (Vars_iter iter = _vars.begin(); iter != _vars.end(); iter++) {
00265 i += (*iter)->element_count(true);
00266 }
00267 return i;
00268 }
00269 }
00270
00271 bool
00272 Sequence::is_linear()
00273 {
00274 bool linear = true;
00275 bool seq_found = false;
00276 for (Vars_iter iter = _vars.begin(); linear && iter != _vars.end(); iter++) {
00277 if ((*iter)->type() == dods_sequence_c) {
00278
00279
00280
00281 if (seq_found) {
00282 linear = false;
00283 break;
00284 }
00285 seq_found = true;
00286 linear = dynamic_cast<Sequence *>((*iter))->is_linear();
00287 }
00288 else if ((*iter)->type() == dods_structure_c) {
00289 linear = dynamic_cast<Structure*>((*iter))->is_linear();
00290 }
00291 else {
00292
00293 linear = (*iter)->is_simple_type();
00294 }
00295 }
00296
00297 return linear;
00298 }
00299
00300 void
00301 Sequence::set_send_p(bool state)
00302 {
00303 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00304 (*i)->set_send_p(state);
00305 }
00306
00307 BaseType::set_send_p(state);
00308 }
00309
00310 void
00311 Sequence::set_read_p(bool state)
00312 {
00313 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00314 (*i)->set_read_p(state);
00315 }
00316
00317 BaseType::set_read_p(state);
00318 }
00319
00320 void
00321 Sequence::set_in_selection(bool state)
00322 {
00323 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00324 (*i)->set_in_selection(state);
00325 }
00326
00327 BaseType::set_in_selection(state);
00328 }
00329
00339 void
00340 Sequence::add_var(BaseType *bt, Part)
00341 {
00342 if (!bt)
00343 throw InternalErr(__FILE__, __LINE__,
00344 "Cannot add variable: NULL pointer");
00345
00346
00347
00348 BaseType *bt_copy = bt->ptr_duplicate();
00349 bt_copy->set_parent(this);
00350 _vars.push_back(bt_copy);
00351 }
00352
00353
00354 BaseType *
00355 Sequence::var(const string &n, btp_stack &s)
00356 {
00357 string name = www2id(n);
00358
00359 BaseType *btp = m_exact_match(name, &s);
00360 if (btp)
00361 return btp;
00362
00363 return m_leaf_match(name, &s);
00364 }
00365
00366 BaseType *
00367 Sequence::var(const string &name, bool exact_match, btp_stack *s)
00368 {
00369 string n = www2id(name);
00370
00371 if (exact_match)
00372 return m_exact_match(n, s);
00373 else
00374 return m_leaf_match(n, s);
00375 }
00376
00377 BaseType *
00378 Sequence::m_leaf_match(const string &name, btp_stack *s)
00379 {
00380 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00381 if ((*i)->name() == name) {
00382 if (s)
00383 s->push(static_cast<BaseType *>(this));
00384 return *i;
00385 }
00386 if ((*i)->is_constructor_type()) {
00387 BaseType *btp = (*i)->var(name, false, s);
00388 if (btp) {
00389 if (s)
00390 s->push(static_cast<BaseType *>(this));
00391 return btp;
00392 }
00393 }
00394 }
00395
00396 return 0;
00397 }
00398
00399 BaseType *
00400 Sequence::m_exact_match(const string &name, btp_stack *s)
00401 {
00402 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00403 if ((*i)->name() == name) {
00404 if (s)
00405 s->push(static_cast<BaseType *>(this));
00406 return *i;
00407 }
00408 }
00409
00410 string::size_type dot_pos = name.find(".");
00411 if (dot_pos != string::npos) {
00412 string aggregate = name.substr(0, dot_pos);
00413 string field = name.substr(dot_pos + 1);
00414
00415 BaseType *agg_ptr = var(aggregate);
00416 if (agg_ptr) {
00417 if (s)
00418 s->push(static_cast<BaseType *>(this));
00419 return agg_ptr->var(field, true, s);
00420 }
00421 else
00422 return 0;
00423 }
00424
00425 return 0;
00426 }
00427
00432 BaseTypeRow *
00433 Sequence::row_value(size_t row)
00434 {
00435 if (row >= d_values.size())
00436 return 0;
00437 return d_values[row];
00438 }
00439
00446 void
00447 Sequence::set_value(SequenceValues &values)
00448 {
00449 d_values = values;
00450 }
00451
00454 SequenceValues
00455 Sequence::value()
00456 {
00457 return d_values;
00458 }
00459
00465 BaseType *
00466 Sequence::var_value(size_t row, const string &name)
00467 {
00468 BaseTypeRow *bt_row_ptr = row_value(row);
00469 if (!bt_row_ptr)
00470 return 0;
00471
00472 BaseTypeRow::iterator bt_row_iter = bt_row_ptr->begin();
00473 BaseTypeRow::iterator bt_row_end = bt_row_ptr->end();
00474 while (bt_row_iter != bt_row_end && (*bt_row_iter)->name() != name)
00475 ++bt_row_iter;
00476
00477 if (bt_row_iter == bt_row_end)
00478 return 0;
00479 else
00480 return *bt_row_iter;
00481 }
00482
00488 BaseType *
00489 Sequence::var_value(size_t row, size_t i)
00490 {
00491 BaseTypeRow *bt_row_ptr = row_value(row);
00492 if (!bt_row_ptr)
00493 return 0;
00494
00495 if (i >= bt_row_ptr->size())
00496 return 0;
00497
00498 return (*bt_row_ptr)[i];
00499 }
00500
00501 unsigned int
00502 Sequence::width()
00503 {
00504 unsigned int sz = 0;
00505
00506 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
00507 sz += (*i)->width();
00508 }
00509
00510 return sz;
00511 }
00512
00513
00514
00515
00531 int
00532 Sequence::length()
00533 {
00534 return -1;
00535 }
00536
00537
00538 int
00539 Sequence::number_of_rows()
00540 {
00541 return d_values.size();
00542 }
00543
00547 void
00548 Sequence::reset_row_number()
00549 {
00550 d_row_number = -1;
00551 }
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00605 bool
00606 Sequence::read_row(int row, DDS &dds,
00607 ConstraintEvaluator &eval, bool ce_eval)
00608 {
00609 DBG2(cerr << "Entering Sequence::read_row for " << name() << endl);
00610 if (row < d_row_number)
00611 throw InternalErr("Trying to back up inside a sequence!");
00612
00613 DBG2(cerr << "read_row: row number " << row
00614 << ", current row " << d_row_number << endl);
00615 if (row == d_row_number)
00616 {
00617 DBG2(cerr << "Leaving Sequence::read_row for " << name() << endl);
00618 return true;
00619 }
00620
00621 dds.timeout_on();
00622
00623 int eof = 0;
00624 while (!eof && d_row_number < row) {
00625 if (!read_p()) {
00626 eof = (read() == false);
00627 }
00628
00629
00630
00631
00632 if (!eof && (!ce_eval || eval.eval_selection(dds, dataset())))
00633 d_row_number++;
00634
00635 set_read_p(false);
00636 }
00637
00638
00639
00640
00641
00642 set_read_p(true);
00643
00644 dds.timeout_off();
00645
00646
00647 DBG2(cerr << "Leaving Sequence::read_row for " << name()
00648 << " with " << (eof == 0) << endl);
00649 return eof == 0;
00650 }
00651
00652
00653
00654
00655
00656
00657
00658
00659 inline bool
00660 Sequence::is_end_of_rows(int i)
00661 {
00662 return ((d_ending_row_number == -1) ? false : (i > d_ending_row_number));
00663 }
00664
00725 bool
00726 Sequence::serialize(ConstraintEvaluator &eval, DDS &dds,
00727 Marshaller &m, bool ce_eval)
00728 {
00729 DBG2(cerr << "Entering Sequence::serialize for " << name() << endl);
00730
00731
00732 if (is_leaf_sequence())
00733 return serialize_leaf(dds, eval, m, ce_eval);
00734 else
00735 return serialize_parent_part_one(dds, eval, m);
00736 }
00737
00738
00739
00740
00741
00742 bool
00743 Sequence::serialize_parent_part_one(DDS &dds,
00744 ConstraintEvaluator &eval, Marshaller &m)
00745 {
00746 DBG2(cerr << "Entering serialize_parent_part_one for " << name() << endl);
00747
00748 int i = (d_starting_row_number != -1) ? d_starting_row_number : 0;
00749
00750
00751
00752
00753
00754 bool status = read_row(i, dds, eval, false);
00755 DBG2(cerr << "Sequence::serialize_parent_part_one::read_row() status: " << status << endl);
00756
00757 while (status && !is_end_of_rows(i)) {
00758 i += d_row_stride;
00759
00760
00761
00762
00763
00764 for (Vars_iter iter = _vars.begin(); iter != _vars.end(); iter++) {
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 if ((*iter)->send_p() && (*iter)->type() == dods_sequence_c)
00775 (*iter)->serialize(eval, dds, m);
00776 }
00777
00778 set_read_p(false);
00779
00780 status = read_row(i, dds, eval, false);
00781 DBG(cerr << "Sequence::serialize_parent_part_one::read_row() status: " << status << endl);
00782 }
00783
00784 d_row_number = -1;
00785
00786
00787
00788
00789 if (d_top_most || d_wrote_soi) {
00790 DBG(cerr << "Writing End of Sequence marker" << endl);
00791 write_end_of_sequence(m);
00792 d_wrote_soi = false;
00793 }
00794
00795 return true;
00796 }
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808 void
00809 Sequence::serialize_parent_part_two(DDS &dds,
00810 ConstraintEvaluator &eval, Marshaller &m)
00811 {
00812 DBG(cerr << "Entering serialize_parent_part_two for " << name() << endl);
00813
00814 BaseType *btp = get_parent();
00815 if (btp && btp->type() == dods_sequence_c)
00816 dynamic_cast<Sequence&>(*btp).serialize_parent_part_two(dds, eval, m);
00817
00818 if (d_unsent_data) {
00819 DBG(cerr << "Writing Start of Instance marker" << endl);
00820 d_wrote_soi = true;
00821 write_start_of_instance(m);
00822
00823
00824 for (Vars_iter iter = _vars.begin(); iter != _vars.end(); iter++) {
00825
00826 DBG(cerr << "Sequence::serialize_parent_part_two(), serializing "
00827 << (*iter)->name() << endl);
00828 if ((*iter)->send_p() && (*iter)->type() != dods_sequence_c) {
00829 DBG(cerr << "Send P is true, sending " << (*iter)->name() << endl);
00830 (*iter)->serialize(eval, dds, m, false);
00831 }
00832 }
00833
00834 d_unsent_data = false;
00835 }
00836 }
00837
00838
00839
00840 bool
00841 Sequence::serialize_leaf(DDS &dds,
00842 ConstraintEvaluator &eval, Marshaller &m, bool ce_eval)
00843 {
00844 DBG(cerr << "Entering Sequence::serialize_leaf for " << name() << endl);
00845 int i = (d_starting_row_number != -1) ? d_starting_row_number : 0;
00846
00847
00848
00849 bool status = read_row(i, dds, eval, ce_eval);
00850 DBG(cerr << "Sequence::serialize_leaf::read_row() status: " << status << endl);
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864 if (status && !is_end_of_rows(i)) {
00865 BaseType *btp = get_parent();
00866 if (btp && btp->type() == dods_sequence_c)
00867 dynamic_cast<Sequence&>(*btp).serialize_parent_part_two(dds,
00868 eval, m);
00869 }
00870
00871 d_wrote_soi = false;
00872 while (status && !is_end_of_rows(i)) {
00873 i += d_row_stride;
00874
00875 DBG(cerr << "Writing Start of Instance marker" << endl);
00876 d_wrote_soi = true;
00877 write_start_of_instance(m);
00878
00879
00880 for (Vars_iter iter = _vars.begin(); iter != _vars.end(); iter++) {
00881 DBG(cerr << "Sequence::serialize_leaf(), serializing "
00882 << (*iter)->name() << endl);
00883 if ((*iter)->send_p()) {
00884 DBG(cerr << "Send P is true, sending " << (*iter)->name() << endl);
00885 (*iter)->serialize(eval, dds, m, false);
00886 }
00887 }
00888
00889 set_read_p(false);
00890
00891 status = read_row(i, dds, eval, ce_eval);
00892 DBG(cerr << "Sequence::serialize_leaf::read_row() status: " << status << endl);
00893 }
00894
00895
00896
00897 if (d_wrote_soi || d_top_most) {
00898 DBG(cerr << "Writing End of Sequence marker" << endl);
00899 write_end_of_sequence(m);
00900 }
00901
00902 return true;
00903 }
00904
00927 void
00928 Sequence::intern_data(ConstraintEvaluator &eval, DDS &dds)
00929 {
00930 DBG(cerr << "Sequence::intern_data - for " << name() << endl);
00931 DBG2(cerr << " intern_data, values: " << &d_values << endl);
00932
00933
00934
00935
00936 sequence_values_stack_t sequence_values_stack;
00937
00938 DBG2(cerr << " pushing d_values of " << name() << " (" << &d_values
00939 << ") on stack; size: " << sequence_values_stack.size() << endl);
00940 sequence_values_stack.push(&d_values);
00941
00942 intern_data_private(eval, dds, sequence_values_stack);
00943 }
00944
00945 void
00946 Sequence::intern_data_private(ConstraintEvaluator &eval,
00947 DDS &dds,
00948 sequence_values_stack_t &sequence_values_stack)
00949 {
00950 DBG(cerr << "Entering intern_data_private for " << name() << endl);
00951
00952 if (is_leaf_sequence())
00953 intern_data_for_leaf(dds, eval, sequence_values_stack);
00954 else
00955 intern_data_parent_part_one(dds, eval, sequence_values_stack);
00956 }
00957
00958 void
00959 Sequence::intern_data_parent_part_one(DDS & dds,
00960 ConstraintEvaluator & eval,
00961 sequence_values_stack_t &
00962 sequence_values_stack)
00963 {
00964 DBG(cerr << "Entering intern_data_parent_part_one for " << name() << endl);
00965
00966 int i = (get_starting_row_number() != -1) ? get_starting_row_number() : 0;
00967
00968
00969
00970
00971
00972 bool status = read_row(i, dds, eval, false);
00973
00974
00975
00976
00977
00978
00979
00980 SequenceValues::size_type orig_stack_size = sequence_values_stack.size() ;
00981
00982 while (status
00983 && (get_ending_row_number() == -1
00984 || i <= get_ending_row_number()))
00985 {
00986 i += get_row_stride();
00987 for (Vars_iter iter = var_begin(); iter != var_end(); iter++) {
00988 if ((*iter)->send_p()) {
00989 switch ((*iter)->type()) {
00990 case dods_sequence_c:
00991 dynamic_cast<Sequence&>(**iter).intern_data_private(
00992 eval, dds, sequence_values_stack);
00993 break;
00994
00995 default:
00996 (*iter)->intern_data(eval, dds);
00997 break;
00998 }
00999 }
01000 }
01001
01002 set_read_p(false);
01003
01004 status = read_row(i, dds, eval, false);
01005 }
01006
01007
01008 reset_row_number();
01009
01010
01011
01012
01013
01014 if( sequence_values_stack.size() > orig_stack_size )
01015 {
01016 DBG2(cerr << " popping d_values (" << sequence_values_stack.top()
01017 << ") off stack; size: " << sequence_values_stack.size() << endl);
01018 sequence_values_stack.pop();
01019 }
01020 DBG(cerr << "Leaving intern_data_parent_part_one for " << name() << endl);
01021 }
01022
01023 void
01024 Sequence::intern_data_parent_part_two(DDS &dds,
01025 ConstraintEvaluator &eval,
01026 sequence_values_stack_t &sequence_values_stack)
01027 {
01028 DBG(cerr << "Entering intern_data_parent_part_two for " << name() << endl);
01029
01030 BaseType *btp = get_parent();
01031 if (btp && btp->type() == dods_sequence_c) {
01032 dynamic_cast<Sequence&>(*btp).intern_data_parent_part_two(
01033 dds, eval, sequence_values_stack);
01034 }
01035
01036 DBG2(cerr << " stack size: " << sequence_values_stack.size() << endl);
01037 SequenceValues *values = sequence_values_stack.top();
01038 DBG2(cerr << " using values = " << (void *)values << endl);
01039
01040 if (get_unsent_data()) {
01041 BaseTypeRow *row_data = new BaseTypeRow;
01042
01043
01044 for (Vars_iter iter = var_begin(); iter != var_end(); iter++) {
01045
01046 if ((*iter)->send_p() && (*iter)->type() != dods_sequence_c) {
01047 row_data->push_back((*iter)->ptr_duplicate());
01048 }
01049 else if ((*iter)->send_p()) {
01050 Sequence *tmp = dynamic_cast<Sequence*>((*iter)->ptr_duplicate());
01051 if (!tmp)
01052 throw InternalErr(__FILE__, __LINE__, "Expected a Sequence.");
01053 row_data->push_back(tmp);
01054 DBG2(cerr << " pushing d_values of " << tmp->name()
01055 << " (" << &(tmp->d_values)
01056 << ") on stack; size: " << sequence_values_stack.size()
01057 << endl);
01058
01059
01060
01061 sequence_values_stack.push(&(tmp->d_values));
01062 }
01063 }
01064
01065 DBG2(cerr << " pushing values for " << name()
01066 << " to " << values << endl);
01067 values->push_back(row_data);
01068 set_unsent_data(false);
01069 }
01070 DBG(cerr << "Leaving intern_data_parent_part_two for " << name() << endl);
01071 }
01072
01073 void
01074 Sequence::intern_data_for_leaf(DDS &dds,
01075 ConstraintEvaluator &eval,
01076 sequence_values_stack_t &sequence_values_stack)
01077 {
01078 DBG(cerr << "Entering intern_data_for_leaf for " << name() << endl);
01079
01080 int i = (get_starting_row_number() != -1) ? get_starting_row_number() : 0;
01081
01082 DBG2(cerr << " reading row " << i << endl);
01083 bool status = read_row(i, dds, eval, true);
01084 DBG2(cerr << " status: " << status << endl);
01085 DBG2(cerr << " ending row number: " << get_ending_row_number() << endl);
01086
01087 if (status && (get_ending_row_number() == -1 || i <= get_ending_row_number())) {
01088 BaseType *btp = get_parent();
01089 if (btp && btp->type() == dods_sequence_c) {
01090
01091
01092
01093 dynamic_cast<Sequence&>(*btp).intern_data_parent_part_two(
01094 dds, eval, sequence_values_stack);
01095 }
01096
01097
01098
01099
01100 SequenceValues *values = sequence_values_stack.top();
01101 DBG2(cerr << " using values = " << values << endl);
01102
01103 while (status && (get_ending_row_number() == -1
01104 || i <= get_ending_row_number())) {
01105 i += get_row_stride();
01106
01107
01108 BaseTypeRow *row_data = new BaseTypeRow;
01109 for (Vars_iter iter = var_begin(); iter != var_end(); iter++) {
01110 if ((*iter)->send_p()) {
01111 row_data->push_back((*iter)->ptr_duplicate());
01112 }
01113 }
01114
01115 DBG2(cerr << " pushing values for " << name()
01116 << " to " << values << endl);
01117
01118 values->push_back(row_data);
01119
01120 set_read_p(false);
01121
01122 status = read_row(i, dds, eval, true);
01123 }
01124
01125 DBG2(cerr << " popping d_values (" << sequence_values_stack.top()
01126 << ") off stack; size: " << sequence_values_stack.size() << endl);
01127 sequence_values_stack.pop();
01128 }
01129 DBG(cerr << "Leaving intern_data_for_leaf for " << name() << endl);
01130 }
01131
01152 bool
01153 Sequence::deserialize(UnMarshaller &um, DDS *dds, bool reuse)
01154 {
01155 DataDDS *dd = dynamic_cast<DataDDS *>(dds);
01156 if (!dd)
01157 throw InternalErr("Expected argument 'dds' to be a DataDDS!");
01158
01159 DBG2(cerr << "Reading from server/protocol version: "
01160 << dd->get_protocol_major() << "." << dd->get_protocol_minor()
01161 << endl);
01162
01163
01164 if (dd->get_protocol_major() < 2) {
01165 throw Error(string("The protocl version (") + dd->get_protocol()
01166 + ") indicates that this\nis an old server which may not correctly transmit Sequence variables.\nContact the server administrator.");
01167 }
01168
01169 while (true) {
01170
01171 unsigned char marker = read_marker(um);
01172 if (is_end_of_sequence(marker))
01173 break;
01174 else if (is_start_of_instance(marker)) {
01175 d_row_number++;
01176 DBG2(cerr << "Reading row " << d_row_number << " of "
01177 << name() << endl);
01178 BaseTypeRow *bt_row_ptr = new BaseTypeRow;
01179
01180 for (Vars_iter iter = _vars.begin(); iter != _vars.end(); iter++) {
01181 BaseType *bt_ptr = (*iter)->ptr_duplicate();
01182 bt_ptr->deserialize(um, dds, reuse);
01183 DBG2(cerr << "Deserialized " << bt_ptr->name() << " ("
01184 << bt_ptr << ") = ");
01185 DBG2(bt_ptr->print_val(stderr, ""));
01186 bt_row_ptr->push_back(bt_ptr);
01187 }
01188
01189 d_values.push_back(bt_row_ptr);
01190 }
01191 else
01192 throw Error("I could not read the expected Sequence data stream marker!");
01193 };
01194
01195 return false;
01196 }
01197
01198
01199
01211 int
01212 Sequence::get_starting_row_number()
01213 {
01214 return d_starting_row_number;
01215 }
01216
01227 int
01228 Sequence::get_row_stride()
01229 {
01230 return d_row_stride;
01231 }
01232
01244 int
01245 Sequence::get_ending_row_number()
01246 {
01247 return d_ending_row_number;
01248 }
01249
01258 void
01259 Sequence::set_row_number_constraint(int start, int stop, int stride)
01260 {
01261 if (stop < start)
01262 throw Error(malformed_expr, "Starting row number must precede the ending row number.");
01263
01264 d_starting_row_number = start;
01265 d_row_stride = stride;
01266 d_ending_row_number = stop;
01267 }
01268
01271 unsigned int
01272 Sequence::val2buf(void *, bool)
01273 {
01274 throw InternalErr(__FILE__, __LINE__, "Never use this method; see the programmer's guide documentation.");
01275 return sizeof(Sequence);
01276 }
01277
01282 unsigned int
01283 Sequence::buf2val(void **)
01284 {
01285 throw InternalErr(__FILE__, __LINE__, "Use Sequence::var_value() or Sequence::row_value() in place of Sequence::buf2val()");
01286 return sizeof(Sequence);
01287 }
01288
01289 #if FILE_METHODS
01290 void
01291 Sequence::print_one_row(FILE *out, int row, string space,
01292 bool print_row_num)
01293 {
01294 if (print_row_num)
01295 fprintf(out, "\n%s%d: ", space.c_str(), row) ;
01296
01297 fprintf(out, "{ ") ;
01298
01299 int elements = element_count() - 1;
01300 int j;
01301 BaseType *bt_ptr;
01302
01303 for (j = 0; j < elements; ++j) {
01304 bt_ptr = var_value(row, j);
01305 if (bt_ptr) {
01306 if (bt_ptr->type() == dods_sequence_c)
01307 dynamic_cast<Sequence*>(bt_ptr)->print_val_by_rows
01308 (out, space + " ", false, print_row_num);
01309 else
01310 bt_ptr->print_val(out, space, false);
01311 fprintf(out, ", ") ;
01312 }
01313 }
01314
01315
01316 bt_ptr = var_value(row, j);
01317 if (bt_ptr) {
01318 if (bt_ptr->type() == dods_sequence_c)
01319 dynamic_cast<Sequence*>(bt_ptr)->print_val_by_rows
01320 (out, space + " ", false, print_row_num);
01321 else
01322 bt_ptr->print_val(out, space, false);
01323 }
01324
01325 fprintf(out, " }") ;
01326 }
01327 #endif
01328
01329 void
01330 Sequence::print_one_row(ostream &out, int row, string space,
01331 bool print_row_num)
01332 {
01333 if (print_row_num)
01334 out << "\n" << space << row << ": " ;
01335
01336 out << "{ " ;
01337
01338 int elements = element_count();
01339 int j = 0;
01340 BaseType *bt_ptr = 0;
01341
01342
01343
01344
01345
01346
01347
01348 while (j < elements && !bt_ptr) {
01349 bt_ptr = var_value(row, j++);
01350 if (bt_ptr) {
01351 if (bt_ptr->type() == dods_sequence_c)
01352 dynamic_cast<Sequence*>(bt_ptr)->print_val_by_rows
01353 (out, space + " ", false, print_row_num);
01354 else
01355 bt_ptr->print_val(out, space, false);
01356 }
01357 }
01358
01359
01360 while (j < elements) {
01361 bt_ptr = var_value(row, j++);
01362 if (bt_ptr) {
01363 out << ", ";
01364 if (bt_ptr->type() == dods_sequence_c)
01365 dynamic_cast<Sequence*>(bt_ptr)->print_val_by_rows
01366 (out, space + " ", false, print_row_num);
01367 else
01368 bt_ptr->print_val(out, space, false);
01369 }
01370 }
01371
01372 out << " }" ;
01373 }
01374
01375 #if FILE_METHODS
01376 void
01377 Sequence::print_val_by_rows(FILE *out, string space, bool print_decl_p,
01378 bool print_row_numbers)
01379 {
01380 if (print_decl_p) {
01381 print_decl(out, space, false);
01382 fprintf(out, " = ") ;
01383 }
01384
01385 fprintf(out, "{ ") ;
01386
01387 int rows = number_of_rows() - 1;
01388 int i;
01389 for (i = 0; i < rows; ++i) {
01390 print_one_row(out, i, space, print_row_numbers);
01391 fprintf(out, ", ") ;
01392 }
01393 print_one_row(out, i, space, print_row_numbers);
01394
01395 fprintf(out, " }") ;
01396
01397 if (print_decl_p)
01398 fprintf(out, ";\n") ;
01399 }
01400 #endif
01401
01402 void
01403 Sequence::print_val_by_rows(ostream &out, string space, bool print_decl_p,
01404 bool print_row_numbers)
01405 {
01406 if (print_decl_p) {
01407 print_decl(out, space, false);
01408 out << " = " ;
01409 }
01410
01411 out << "{ " ;
01412
01413 int rows = number_of_rows() - 1;
01414 int i;
01415 for (i = 0; i < rows; ++i) {
01416 print_one_row(out, i, space, print_row_numbers);
01417 out << ", " ;
01418 }
01419 print_one_row(out, i, space, print_row_numbers);
01420
01421 out << " }" ;
01422
01423 if (print_decl_p)
01424 out << ";\n" ;
01425 }
01426
01427 #if FILE_METHODS
01428 void
01429 Sequence::print_val(FILE *out, string space, bool print_decl_p)
01430 {
01431 print_val_by_rows(out, space, print_decl_p, false);
01432 }
01433 #endif
01434
01435 void
01436 Sequence::print_val(ostream &out, string space, bool print_decl_p)
01437 {
01438 print_val_by_rows(out, space, print_decl_p, false);
01439 }
01440
01441
01442 bool
01443 Sequence::check_semantics(string &msg, bool all)
01444 {
01445 if (!BaseType::check_semantics(msg))
01446 return false;
01447
01448 if (!unique_names(_vars, name(), type_name(), msg))
01449 return false;
01450
01451 if (all)
01452 for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
01453 if (!(*i)->check_semantics(msg, true)) {
01454 return false;
01455 }
01456 }
01457
01458 return true;
01459 }
01460
01461 void
01462 Sequence::set_leaf_p(bool state)
01463 {
01464 d_leaf_sequence = state;
01465 }
01466
01467 bool
01468 Sequence::is_leaf_sequence()
01469 {
01470 return d_leaf_sequence;
01471 }
01472
01497 void
01498 Sequence::set_leaf_sequence(int lvl)
01499 {
01500 bool has_child_sequence = false;
01501
01502 if (lvl == 1) d_top_most = true;
01503
01504 DBG2(cerr << "Processing sequence " << name() << endl);
01505
01506 for (Vars_iter iter = _vars.begin(); iter != _vars.end(); iter++) {
01507
01508
01509
01510
01511
01512 if ((*iter)->type() == dods_sequence_c && (*iter)->send_p()) {
01513 if (has_child_sequence)
01514 throw Error("This implementation does not support more than one nested sequence at a level. Contact the server administrator.");
01515
01516 has_child_sequence = true;
01517 dynamic_cast<Sequence&>(**iter).set_leaf_sequence(++lvl);
01518 }
01519 else if ((*iter)->type() == dods_structure_c) {
01520 dynamic_cast<Structure&>(**iter).set_leaf_sequence(lvl);
01521 }
01522 }
01523
01524 if (!has_child_sequence)
01525 set_leaf_p(true);
01526 else
01527 set_leaf_p(false);
01528
01529 DBG2(cerr << "is_leaf_sequence(): " << is_leaf_sequence() << " (" << name() << ")" << endl);
01530 }
01531
01540 void
01541 Sequence::dump(ostream &strm) const
01542 {
01543 strm << DapIndent::LMarg << "Sequence::dump - ("
01544 << (void *)this << ")" << endl ;
01545 DapIndent::Indent() ;
01546 Constructor::dump(strm) ;
01547 strm << DapIndent::LMarg << "# rows deserialized: " << d_row_number
01548 << endl ;
01549 strm << DapIndent::LMarg << "bracket notation information:" << endl ;
01550 DapIndent::Indent() ;
01551 strm << DapIndent::LMarg << "starting row #: " << d_starting_row_number
01552 << endl ;
01553 strm << DapIndent::LMarg << "row stride: " << d_row_stride << endl ;
01554 strm << DapIndent::LMarg << "ending row #: " << d_ending_row_number
01555 << endl ;
01556 DapIndent::UnIndent() ;
01557
01558 strm << DapIndent::LMarg << "data been sent? " << d_unsent_data << endl ;
01559 strm << DapIndent::LMarg << "start of instance? " << d_wrote_soi << endl ;
01560 strm << DapIndent::LMarg << "is leaf sequence? " << d_leaf_sequence
01561 << endl ;
01562 strm << DapIndent::LMarg << "top most in hierarchy? " << d_top_most
01563 << endl ;
01564 DapIndent::UnIndent() ;
01565 }
01566
01567 }
01568