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
00037 #include "config.h"
00038
00039 static char rcsid[] not_used =
00040 { "$Id: Vector.cc 16466 2007-05-14 17:41:27Z jimg $"
00041 };
00042
00043
00044
00045 #include <algorithm>
00046
00047 #include "Vector.h"
00048 #include "escaping.h"
00049 #include "util.h"
00050 #include "debug.h"
00051 #include "InternalErr.h"
00052
00053
00054 using std::cerr;
00055 using std::endl;
00056
00057 void Vector::_duplicate(const Vector & v)
00058 {
00059 _length = v._length;
00060
00061
00062
00063 if (v._var) {
00064 _var = v._var->ptr_duplicate();
00065 _var->set_parent(this);
00066 }
00067 else {
00068 _var = 0;
00069 }
00070
00071
00072
00073
00074
00075 if (v._vec.empty()) {
00076 _vec = v._vec;
00077 }
00078 else {
00079
00080
00081 _vec.resize(_length);
00082 for (int i = 0; i < _length; ++i) {
00083
00084
00085
00086
00087 _vec[i] = v._vec[i]->ptr_duplicate();
00088 }
00089 }
00090
00091
00092 d_str = v.d_str;
00093
00094
00095 _buf = 0;
00096 if (v._buf)
00097 val2buf(v._buf);
00098 }
00099
00116 Vector::Vector(const string & n, BaseType * v, const Type & t)
00117 : BaseType(n, t), _length(-1), _var(0), _buf(0), _vec(0)
00118 {
00119 if (v)
00120 add_var(v);
00121
00122 DBG2(cerr << "Entering Vector ctor for object: " << this << endl);
00123 if (_var)
00124 _var->set_parent(this);
00125 }
00126
00128 Vector::Vector(const Vector & rhs): BaseType(rhs)
00129 {
00130 DBG2(cerr << "Entering Vector const ctor for object: " << this <<
00131 endl);
00132 DBG2(cerr << "RHS: " << &rhs << endl);
00133
00134 _duplicate(rhs);
00135 }
00136
00137 Vector::~Vector()
00138 {
00139 DBG2(cerr << "Entering ~Vector (" << this << ")" << endl);
00140
00141 delete _var;
00142 _var = 0;
00143
00144 if (_buf) {
00145 delete[]_buf;
00146 _buf = 0;
00147 }
00148 else {
00149 for (unsigned int i = 0; i < _vec.size(); ++i) {
00150 delete _vec[i];
00151 _vec[i] = 0;
00152 }
00153 }
00154
00155 DBG2(cerr << "Exiting ~Vector" << endl);
00156 }
00157
00158 Vector & Vector::operator=(const Vector & rhs)
00159 {
00160 if (this == &rhs)
00161 return *this;
00162
00163 dynamic_cast < BaseType & >(*this) = rhs;
00164
00165 _duplicate(rhs);
00166
00167 return *this;
00168 }
00169
00170 int Vector::element_count(bool leaves)
00171 {
00172 if (!leaves)
00173 return 1;
00174 else
00175
00176 return var(0)->element_count(leaves);
00177 }
00178
00179
00180
00181
00182
00183
00190 void Vector::set_send_p(bool state)
00191 {
00192 _var->set_send_p(state);
00193 BaseType::set_send_p(state);
00194 }
00195
00202 void Vector::set_read_p(bool state)
00203 {
00204 _var->set_read_p(state);
00205 BaseType::set_read_p(state);
00206 }
00207
00225 BaseType *Vector::var(const string & n, bool exact, btp_stack * s)
00226 {
00227 string name = www2id(n);
00228
00229
00230
00231 if (_var->is_constructor_type()) {
00232 if (name == "" || _var->name() == name)
00233 return _var;
00234 else
00235 return _var->var(name, exact, s);
00236 }
00237 else
00238 return _var;
00239 }
00240
00251 BaseType *Vector::var(const string & n, btp_stack & s)
00252 {
00253 string name = www2id(n);
00254
00255 if (_var->is_constructor_type())
00256 return _var->var(name, s);
00257 else {
00258 s.push((BaseType *) this);
00259 return _var;
00260 }
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00287 BaseType *Vector::var(unsigned int i)
00288 {
00289
00290 switch (_var->type()) {
00291 case dods_byte_c:
00292 case dods_int16_c:
00293 case dods_uint16_c:
00294 case dods_int32_c:
00295 case dods_uint32_c:
00296 case dods_float32_c:
00297 case dods_float64_c: {
00298
00299
00300
00301 unsigned int sz = _var->width();
00302 _var->val2buf((char *) _buf + (i * sz));
00303 return _var;
00304 break;
00305 }
00306
00307 case dods_str_c:
00308 case dods_url_c:
00309 _var->val2buf(&d_str[i]);
00310 return _var;
00311 break;
00312
00313 case dods_array_c:
00314 case dods_structure_c:
00315 case dods_sequence_c:
00316 case dods_grid_c:
00317 return _vec[i];
00318 break;
00319
00320 default:
00321 cerr << "Vector::var: Unrecognized type" << endl;
00322 }
00323
00324 return 0;
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00340 unsigned int Vector::width()
00341 {
00342
00343 if (!_var)
00344 throw InternalErr(__FILE__, __LINE__,
00345 "Cannot get width since *this* object is not holding data.");
00346
00347 return length() * _var->width();
00348 }
00349
00350
00351
00356 int Vector::length() const
00357 {
00358 return _length;
00359 }
00360
00361
00362
00363
00364
00367 void Vector::set_length(int l)
00368 {
00369 _length = l;
00370 }
00371
00372
00373
00374
00380 void Vector::vec_resize(int l)
00381 {
00382 _vec.resize((l > 0) ? l : 0, 0);
00383 }
00384
00397 bool Vector::serialize(const string & dataset, ConstraintEvaluator & eval,
00398 DDS & dds, XDR * sink, bool ce_eval)
00399 {
00400 int i = 0;
00401
00402 dds.timeout_on();
00403
00404 if (!read_p())
00405 read(dataset);
00406
00407 #if EVAL
00408 if (ce_eval && !eval.eval_selection(dds, dataset))
00409 return true;
00410 #endif
00411
00412 dds.timeout_off();
00413
00414
00415 int num = length();
00416
00417 switch (_var->type()) {
00418 case dods_byte_c:
00419 case dods_int16_c:
00420 case dods_uint16_c:
00421 case dods_int32_c:
00422 case dods_uint32_c:
00423 case dods_float32_c:
00424 case dods_float64_c:
00425
00426
00427
00428 if (!_buf)
00429 throw InternalErr(__FILE__, __LINE__,
00430 "Buffer pointer is not set.");
00431
00432 if ((0 == xdr_int(sink, &num)))
00433 throw Error("Network I/O Error(1). This may be due to a bug in libdap or a\nproblem with the network connection.");
00434
00435
00436
00437 bool status;
00438 if (_var->type() == dods_byte_c)
00439 status = (0 != xdr_bytes(sink, (char **) & _buf,
00440 (unsigned int *) & num,
00441 DODS_MAX_ARRAY));
00442 else
00443 status = (0 != xdr_array(sink, (char **) & _buf,
00444 (unsigned int *) & num,
00445 DODS_MAX_ARRAY, _var->width(),
00446 (xdrproc_t)(_var->xdr_coder())));
00447 if (!status)
00448 throw Error("Network I/O Error(2). This may be due to a bug in libdap or a\nproblem with the network connection.");
00449
00450 break;
00451
00452 case dods_str_c:
00453 case dods_url_c:
00454 if (d_str.capacity() == 0)
00455 throw InternalErr(__FILE__, __LINE__,
00456 "The capacity of the string vector is 0");
00457
00458 if ((0 == xdr_int(sink, (int *) &num)))
00459 throw Error("Network I/O Error(3). This may be due to a bug in libdap or a\nproblem with the network connection.");
00460
00461 for (i = 0; i < num; ++i)
00462 if (!xdr_str(sink, d_str[i]))
00463 throw Error("Network I/O Error(4). Could not send string data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
00464
00465 break;
00466
00467 case dods_array_c:
00468 case dods_structure_c:
00469 case dods_sequence_c:
00470 case dods_grid_c:
00471
00472
00473 if (_vec.capacity() == 0)
00474 throw InternalErr(__FILE__, __LINE__,
00475 "The capacity of *this* vector is 0.");
00476
00477 if ((0 == xdr_int(sink, &num)))
00478 throw Error("Network I/O Error. This may be due to a bug in libdap or a\nproblem with the network connection.");
00479
00480 for (i = 0; i < num; ++i)
00481 _vec[i]->serialize(dataset, eval, dds, sink, false);
00482
00483 break;
00484
00485 default:
00486 throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
00487 break;
00488 }
00489
00490 return true;
00491 }
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510 bool Vector::deserialize(XDR * source, DDS * dds, bool reuse)
00511 {
00512 bool status;
00513 unsigned int num;
00514 unsigned i = 0;
00515
00516 switch (_var->type()) {
00517 case dods_byte_c:
00518 case dods_int16_c:
00519 case dods_uint16_c:
00520 case dods_int32_c:
00521 case dods_uint32_c:
00522 case dods_float32_c:
00523 case dods_float64_c:
00524 if (_buf && !reuse)
00525 delete[]_buf;
00526 _buf = 0;
00527
00528 if ((0 == xdr_int(source, (int *) &num)))
00529 throw Error("Network I/O error. Could not read the array length.\nThis may be due to a bug in libdap or a problem with\nthe network connection.");
00530
00531 DBG(cerr << "Vector::deserialize: num = " << num << endl);
00532 DBG(cerr << "Vector::deserialize: length = " << length() << endl);
00533
00534 if (length() == -1)
00535 set_length(num);
00536
00537 if (num != (unsigned int) length())
00538 throw InternalErr(__FILE__, __LINE__, "The server sent declarations and data with mismatched sizes.");
00539
00540 if (!_buf) {
00541 _buf = new char[width()];
00542 DBG(cerr << "Vector::deserialize: allocating "
00543 << width() << " bytes for an array of "
00544 << length() << " " << _var->type_name() << endl);
00545 }
00546
00547 if (_var->type() == dods_byte_c)
00548 status = (0 != xdr_bytes(source, (char **) & _buf, &num,
00549 DODS_MAX_ARRAY));
00550 else
00551 status = (0 != xdr_array(source, (char **) & _buf, &num,
00552 DODS_MAX_ARRAY, _var->width(),
00553 (xdrproc_t)(_var->xdr_coder())));
00554
00555 if (!status)
00556 throw Error("Network I/O error. Could not read packed array data.\nThis may be due to a bug in libdap or a problem with\nthe network connection.");
00557
00558 DBG(cerr << "Vector::deserialize: read " << num << " elements\n");
00559
00560 break;
00561
00562 case dods_str_c:
00563 case dods_url_c:
00564 if ((0 == xdr_int(source, (int *) &num)))
00565 throw Error("Network I/O error. Could not read the array length.\nThis may be due to a bug in libdap or a problem with\nthe network connection.");
00566
00567 if (length() == -1)
00568 set_length(num);
00569
00570 if (num != (unsigned int) length())
00571 throw InternalErr(__FILE__, __LINE__,
00572 "The client sent declarations and data with mismatched sizes.");
00573
00574 d_str.resize((num > 0) ? num : 0);
00575
00576 for (i = 0; i < num; ++i) {
00577 string str;
00578 if (!xdr_str(source, str))
00579 throw Error("Network I/O Error. Could not read string data. This may be due to a\nbug in libdap or a problem with the network connection.");
00580 d_str[i] = str;
00581
00582 }
00583
00584 break;
00585
00586 case dods_array_c:
00587 case dods_structure_c:
00588 case dods_sequence_c:
00589 case dods_grid_c:
00590 if ((0 == xdr_int(source, (int *) &num)))
00591 throw Error("Network I/O error. Could not read the array length.\nThis may be due to a bug in libdap or a problem with\nthe network connection.");
00592
00593 if (length() == -1)
00594 set_length(num);
00595
00596 if (num != (unsigned int) length())
00597 throw InternalErr(__FILE__, __LINE__, "The client sent declarations and data with mismatched sizes.");
00598
00599 vec_resize(num);
00600
00601 for (i = 0; i < num; ++i) {
00602 _vec[i] = _var->ptr_duplicate();
00603 _vec[i]->deserialize(source, dds);
00604 }
00605
00606 break;
00607
00608 default:
00609 throw InternalErr(__FILE__, __LINE__, "Unknow type!");
00610 break;
00611 }
00612
00613 return false;
00614 }
00615
00643 unsigned int Vector::val2buf(void *val, bool reuse)
00644 {
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654 if (!val)
00655 throw InternalErr(__FILE__, __LINE__,
00656 "The incoming pointer does not contain any data.");
00657
00658 switch (_var->type()) {
00659 case dods_byte_c:
00660 case dods_int16_c:
00661 case dods_uint16_c:
00662 case dods_int32_c:
00663 case dods_uint32_c:
00664 case dods_float32_c:
00665 case dods_float64_c: {
00666
00667 unsigned int array_wid = width();
00668 if (_buf && !reuse) {
00669 delete[]_buf;
00670 _buf = 0;
00671 }
00672
00673 if (!_buf) {
00674 _buf = new char[array_wid];
00675 }
00676
00677 memcpy(_buf, val, array_wid);
00678 break;
00679 }
00680
00681 case dods_str_c:
00682 case dods_url_c: {
00683
00684
00685 d_str.resize(_length);
00686 for (int i = 0; i < _length; ++i)
00687 d_str[i] = *(static_cast < string * >(val) + i);
00688
00689 break;
00690 }
00691
00692 default:
00693 throw InternalErr(__FILE__, __LINE__, "Vector::val2buf: bad type");
00694
00695 }
00696
00697 return width();
00698 }
00699
00730 unsigned int Vector::buf2val(void **val)
00731 {
00732
00733
00734 if (!val)
00735 throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
00736
00737 int wid = width();
00738
00739
00740
00741
00742 switch (_var->type()) {
00743 case dods_byte_c:
00744 case dods_int16_c:
00745 case dods_uint16_c:
00746 case dods_int32_c:
00747 case dods_uint32_c:
00748 case dods_float32_c:
00749 case dods_float64_c:
00750 if (!*val)
00751 *val = new char[wid];
00752
00753 (void) memcpy(*val, _buf, wid);
00754
00755 break;
00756
00757 case dods_str_c:
00758 case dods_url_c: {
00759 if (!*val)
00760 *val = new string[_length];
00761
00762 for (int i = 0; i < _length; ++i)
00763 *(static_cast < string * >(*val) + i) = d_str[i];
00764
00765 break;
00766 }
00767
00768 default:
00769 throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: bad type");
00770 return 0;
00771 }
00772
00773 return wid;
00774 }
00775
00796 void Vector::set_vec(unsigned int i, BaseType * val)
00797 {
00798
00799
00800
00801
00802 if (i >= static_cast < unsigned int >(_length))
00803 throw InternalErr(__FILE__, __LINE__,
00804 "Invalid data: index too large.");
00805 if (!val)
00806 throw InternalErr(__FILE__, __LINE__,
00807 "Invalid data: null pointer to BaseType object.");
00808 if (val->type() != _var->type())
00809 throw InternalErr(__FILE__, __LINE__,
00810 "invalid data: type of incoming object does not match *this* vector type.");
00811
00812 if (i >= _vec.capacity())
00813 vec_resize(i + 10);
00814
00815 _vec[i] = val->ptr_duplicate();
00816 }
00817
00819 bool
00820 Vector::set_value(dods_byte *val, int sz)
00821 {
00822 if (var()->type() == dods_byte_c && val) {
00823 _buf = reinterpret_cast<char*>(new dods_byte[sz]) ;
00824 memcpy(_buf, val, sz * sizeof(dods_byte));
00825 set_read_p(true);
00826 return true;
00827 }
00828 else {
00829 return false;
00830 }
00831 }
00832
00834 bool
00835 Vector::set_value(dods_int16 *val, int sz)
00836 {
00837 if (var()->type() == dods_int16_c && val) {
00838 _buf = reinterpret_cast<char*>(new dods_int16[sz]) ;
00839 memcpy(_buf, val, sz * sizeof(dods_int16));
00840 set_read_p(true);
00841 return true;
00842 }
00843 else {
00844 return false;
00845 }
00846 }
00847
00849 bool
00850 Vector::set_value(dods_int32 *val, int sz)
00851 {
00852 if (var()->type() == dods_int32_c && val) {
00853 _buf = reinterpret_cast<char*>(new dods_int32[sz]) ;
00854 memcpy(_buf, val, sz * sizeof(dods_int32));
00855 set_read_p(true);
00856 return true;
00857 }
00858 else {
00859 return false;
00860 }
00861 }
00862
00864 bool
00865 Vector::set_value(dods_uint16 *val, int sz)
00866 {
00867 if (var()->type() == dods_uint16_c && val) {
00868 _buf = reinterpret_cast<char*>(new dods_uint16[sz]) ;
00869 memcpy(_buf, val, sz * sizeof(dods_uint16));
00870 set_read_p(true);
00871 return true;
00872 }
00873 else {
00874 return false;
00875 }
00876 }
00877
00879 bool
00880 Vector::set_value(dods_uint32 *val, int sz)
00881 {
00882 if (var()->type() == dods_uint32_c && val) {
00883 _buf = reinterpret_cast<char*>(new dods_uint32[sz]) ;
00884 memcpy(_buf, val, sz * sizeof(dods_uint32));
00885 set_read_p(true);
00886 return true;
00887 }
00888 else {
00889 return false;
00890 }
00891 }
00892
00894 bool
00895 Vector::set_value(dods_float32 *val, int sz)
00896 {
00897 if (var()->type() == dods_float32_c && val) {
00898 _buf = reinterpret_cast<char*>(new dods_float32[sz]) ;
00899 memcpy(_buf, val, sz * sizeof(dods_float32));
00900 set_read_p(true);
00901 return true;
00902 }
00903 else {
00904 return false;
00905 }
00906 }
00907
00909 bool
00910 Vector::set_value(dods_float64 *val, int sz)
00911 {
00912 if (!val)
00913 return false;
00914
00915 switch (var()->type()) {
00916 case dods_float64_c:
00917 _buf = reinterpret_cast<char*>(new dods_float64[sz]) ;
00918 memcpy(_buf, val, sz * sizeof(dods_float64));
00919 set_read_p(true);
00920 return true;
00921 default:
00922 return false;
00923 }
00924 }
00925
00927 bool
00928 Vector::set_value(string *val, int sz)
00929 {
00930 if ((var()->type() == dods_str_c || var()->type() == dods_url_c) && val) {
00931 d_str.resize(sz);
00932 for (register int t = 0; t < sz; t++) {
00933 d_str[t] = val[t] ;
00934 }
00935 set_length(sz) ;
00936 set_read_p(true);
00937 return true;
00938 }
00939 else {
00940 return false;
00941 }
00942 }
00943
00945 void Vector::value(dods_byte *b) const
00946 {
00947 if (b && _var->type() == dods_byte_c) {
00948 memcpy(b, _buf, length() * sizeof(dods_byte));
00949 }
00950 }
00951
00953 void Vector::value(dods_uint16 *b) const
00954 {
00955 if (b && _var->type() == dods_uint16_c) {
00956 memcpy(b, _buf, length() * sizeof(dods_uint16));
00957 }
00958 }
00959
00961 void Vector::value(dods_int16 *b) const
00962 {
00963 if (b && _var->type() == dods_int16_c) {
00964 memcpy(b, _buf, length() * sizeof(dods_int16));
00965 }
00966 }
00967
00969 void Vector::value(dods_uint32 *b) const
00970 {
00971 if (b && _var->type() == dods_uint32_c) {
00972 memcpy(b, _buf, length() * sizeof(dods_uint32));
00973 }
00974 }
00975
00977 void Vector::value(dods_int32 *b) const
00978 {
00979 if (b && _var->type() == dods_int32_c) {
00980 memcpy(b, _buf, length() * sizeof(dods_int32));
00981 }
00982 }
00983
00985 void Vector::value(dods_float32 *b) const
00986 {
00987 if (b && _var->type() == dods_float32_c) {
00988 memcpy(b, _buf, length() * sizeof(dods_float32));
00989 }
00990 }
00991
00993 void Vector::value(dods_float64 *b) const
00994 {
00995 if (b && _var->type() == dods_float64_c) {
00996 memcpy(b, _buf, length() * sizeof(dods_float64));
00997 }
00998 }
00999
01001 void Vector::value(vector<string> &b) const
01002 {
01003 if (_var->type() == dods_byte_c)
01004 b = d_str;
01005 }
01006
01019 void Vector::add_var(BaseType * v, Part)
01020 {
01021
01022 delete _var;
01023
01024
01025 if (!v) {
01026 _var = 0;
01027 }
01028 else {
01029
01030
01031
01032 _var = v->ptr_duplicate();
01033
01034
01035
01036
01037 if (!v->name().empty())
01038 set_name(v->name());
01039 else
01040 _var->set_name(name());
01041
01042 _var->set_parent(this);
01043
01044 DBG(cerr << "Vector::add_var: Added variable " << v << " ("
01045 << v->name() << " " << v->type_name() << ")" << endl);
01046 }
01047 }
01048
01049 bool Vector::check_semantics(string & msg, bool)
01050 {
01051 return BaseType::check_semantics(msg);
01052 }
01053
01062 void
01063 Vector::dump(ostream &strm) const
01064 {
01065 strm << DapIndent::LMarg << "Vector::dump - ("
01066 << (void *)this << ")" << endl ;
01067 DapIndent::Indent() ;
01068 BaseType::dump(strm) ;
01069 strm << DapIndent::LMarg << "# elements in vector: " << _length << endl ;
01070 if (_var) {
01071 strm << DapIndent::LMarg << "base type:" << endl ;
01072 DapIndent::Indent() ;
01073 _var->dump(strm) ;
01074 DapIndent::UnIndent() ;
01075 }
01076 else {
01077 strm << DapIndent::LMarg << "base type: not set" << endl ;
01078 }
01079 strm << DapIndent::LMarg << "vector contents:" << endl ;
01080 DapIndent::Indent() ;
01081 for (unsigned i = 0; i < _vec.size(); ++i) {
01082 if (_vec[i])
01083 _vec[i]->dump(strm) ;
01084 else
01085 strm << DapIndent::LMarg << "vec[" << i << "] is null" << endl ;
01086 }
01087 DapIndent::UnIndent() ;
01088 strm << DapIndent::LMarg << "strings:" << endl ;
01089 DapIndent::Indent() ;
01090 for (unsigned i = 0; i < d_str.size(); i++) {
01091 strm << DapIndent::LMarg << d_str[i] << endl ;
01092 }
01093 DapIndent::UnIndent() ;
01094 strm << DapIndent::LMarg << "_buf: " << (void *)_buf << endl ;
01095 DapIndent::UnIndent() ;
01096 }
01097