libdap++ Updated for version 3.8.2
|
00001 00002 // -*- mode: c++; c-basic-offset:4 -*- 00003 00004 // This file is part of libdap, A C++ implementation of the OPeNDAP Data 00005 // Access Protocol. 00006 00007 // Copyright (c) 2002,2003 OPeNDAP, Inc. 00008 // Author: James Gallagher <jgallagher@opendap.org> 00009 // 00010 // This library is free software; you can redistribute it and/or 00011 // modify it under the terms of the GNU Lesser General Public 00012 // License as published by the Free Software Foundation; either 00013 // version 2.1 of the License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00023 // 00024 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112. 00025 00026 // (c) COPYRIGHT URI/MIT 1995-1999 00027 // Please read the full copyright statement in the file COPYRIGHT_URI. 00028 // 00029 // Authors: 00030 // jhrg,jimg James Gallagher <jgallagher@gso.uri.edu> 00031 00032 // Implementation for class Vector. This class is the basis for all the 00033 // vector-type classes in libdap's <Array, List>. 00034 // 00035 // 11/21/95 jhrg 00036 00037 #include "config.h" 00038 00039 #include <cstring> 00040 00041 static char rcsid[] not_used = 00042 { "$Id: Vector.cc 19807 2008-11-06 22:46:39Z jimg $" 00043 }; 00044 00045 //#define DODS_DEBUG 00046 00047 #include <algorithm> 00048 00049 #include "Vector.h" 00050 #include "escaping.h" 00051 #include "util.h" 00052 #include "debug.h" 00053 #include "InternalErr.h" 00054 00055 using std::cerr; 00056 using std::endl; 00057 00058 namespace libdap { 00059 00060 void Vector::_duplicate(const Vector & v) 00061 { 00062 _length = v._length; 00063 00064 // _var holds the type of the elements. That is, it holds a BaseType 00065 // which acts as a template for the type of each element. 00066 if (v._var) { 00067 _var = v._var->ptr_duplicate(); // use ptr_duplicate() 00068 _var->set_parent(this); // ptr_duplicate does not set d_parent. 00069 } 00070 else { 00071 _var = 0; 00072 } 00073 00074 // _vec and _buf (further down) hold the values of the Vector. The field 00075 // _vec is used when the Vector holds non-numeric data (including strings 00076 // although it used to be that was not the case jhrg 2/10/05) while _buf 00077 // holds numeric values. 00078 if (v._vec.empty()) { 00079 _vec = v._vec; 00080 } 00081 else { 00082 // Failure to set the size will make the [] operator barf on the LHS 00083 // of the assignment inside the loop. 00084 _vec.resize(_length); 00085 for (int i = 0; i < _length; ++i) { 00086 // There's no need to call set_parent() for each element; we 00087 // maintain the back pointer using the _var member. These 00088 // instances are used to hold _values_ only while the _var 00089 // field holds the type of the elements. 00090 _vec[i] = v._vec[i]->ptr_duplicate(); 00091 } 00092 } 00093 00094 // copy the strings. This copies the values. 00095 d_str = v.d_str; 00096 00097 // copy numeric values if there are any. 00098 _buf = 0; // init to null 00099 if (v._buf) // only copy if data present 00100 val2buf(v._buf); // store v's value in this's _BUF. 00101 } 00102 00119 Vector::Vector(const string & n, BaseType * v, const Type & t) 00120 : BaseType(n, t), _length(-1), _var(0), _buf(0), _vec(0) 00121 { 00122 if (v) 00123 add_var(v); 00124 00125 DBG2(cerr << "Entering Vector ctor for object: " << this << endl); 00126 if (_var) 00127 _var->set_parent(this); 00128 } 00129 00149 Vector::Vector(const string & n, const string &d, BaseType * v, const Type & t) 00150 : BaseType(n, d, t), _length(-1), _var(0), _buf(0), _vec(0) 00151 { 00152 if (v) 00153 add_var(v); 00154 00155 DBG2(cerr << "Entering Vector ctor for object: " << this << endl); 00156 if (_var) 00157 _var->set_parent(this); 00158 } 00159 00161 Vector::Vector(const Vector & rhs): BaseType(rhs) 00162 { 00163 DBG2(cerr << "Entering Vector const ctor for object: " << this << 00164 endl); 00165 DBG2(cerr << "RHS: " << &rhs << endl); 00166 00167 _duplicate(rhs); 00168 } 00169 00170 Vector::~Vector() 00171 { 00172 DBG2(cerr << "Entering ~Vector (" << this << ")" << endl); 00173 00174 delete _var; 00175 _var = 0; 00176 00177 if (_buf) { 00178 delete[]_buf; 00179 _buf = 0; 00180 } 00181 else { 00182 for (unsigned int i = 0; i < _vec.size(); ++i) { 00183 delete _vec[i]; 00184 _vec[i] = 0; 00185 } 00186 } 00187 00188 DBG2(cerr << "Exiting ~Vector" << endl); 00189 } 00190 00191 Vector & Vector::operator=(const Vector & rhs) 00192 { 00193 if (this == &rhs) 00194 return *this; 00195 00196 dynamic_cast < BaseType & >(*this) = rhs; 00197 00198 _duplicate(rhs); 00199 00200 return *this; 00201 } 00202 00203 int Vector::element_count(bool leaves) 00204 { 00205 if (!leaves) 00206 return 1; 00207 else 00208 // var() only works for simple types! 00209 return var(0)->element_count(leaves); 00210 } 00211 00212 // These mfuncs set the _send_p and _read_p fields of BaseType. They differ 00213 // from BaseType's version in that they set both the Vector object's copy of 00214 // _send_p (_read_p) but also _VAR's copy. This does not matter much when _VAR 00215 // is a scalar, but does matter when it is an aggregate. 00216 00223 void Vector::set_send_p(bool state) 00224 { 00225 _var->set_send_p(state); 00226 BaseType::set_send_p(state); 00227 } 00228 00235 void Vector::set_read_p(bool state) 00236 { 00237 _var->set_read_p(state); 00238 BaseType::set_read_p(state); 00239 } 00240 00258 BaseType *Vector::var(const string & n, bool exact, btp_stack * s) 00259 { 00260 string name = www2id(n); 00261 DBG(cerr << "Vector::var: Looking for " << n << endl); 00262 00263 // Make sure to check for the case where name is the default (the empty 00264 // string). 9/1/98 jhrg 00265 if (_var->is_constructor_type()) { 00266 if (name == "" || _var->name() == name) { 00267 if (s) 00268 s->push(this); 00269 return _var; 00270 } 00271 else { 00272 BaseType * result = _var->var(name, exact, s); 00273 if (result && s) 00274 s->push(this); 00275 return result; 00276 } 00277 } 00278 else { 00279 return _var; // I don't see why this isn't return 0 *** jhrg 10/9/08 00280 } 00281 } 00282 00293 BaseType *Vector::var(const string & n, btp_stack & s) 00294 { 00295 string name = www2id(n); 00296 00297 if (_var->is_constructor_type()) 00298 return _var->var(name, s); 00299 else { 00300 s.push((BaseType *) this); 00301 return _var; 00302 } 00303 } 00304 00305 // Return a pointer the the BaseType object for element I. If the Vector is 00306 // of a cardinal type, store the ith element's value in the BaseType 00307 // object. If it is a Vector of a non-cardinal type, then this mfunc returns 00308 // _vec[i]. 00309 // 00310 // NB: I defaults to zero. 00311 // 00312 // Returns: A BaseType pointer to the ith element of the Vector. 00313 00329 BaseType *Vector::var(unsigned int i) 00330 { 00331 00332 switch (_var->type()) { 00333 case dods_byte_c: 00334 case dods_int16_c: 00335 case dods_uint16_c: 00336 case dods_int32_c: 00337 case dods_uint32_c: 00338 case dods_float32_c: 00339 case dods_float64_c: { 00340 // Transfer the ith value to the BaseType *_var; There are more 00341 // efficient ways to get a whole array using buf2val() but this is 00342 // an OK way to get a single value or several non-contiguous values. 00343 unsigned int sz = _var->width(); 00344 _var->val2buf((char *) _buf + (i * sz)); 00345 return _var; 00346 break; 00347 } 00348 00349 case dods_str_c: 00350 case dods_url_c: 00351 _var->val2buf(&d_str[i]); 00352 return _var; 00353 break; 00354 00355 case dods_array_c: 00356 case dods_structure_c: 00357 case dods_sequence_c: 00358 case dods_grid_c: 00359 return _vec[i]; 00360 break; 00361 00362 default: 00363 cerr << "Vector::var: Unrecognized type" << endl; 00364 } 00365 00366 return 0; 00367 } 00368 00369 // Return: The number of bytes required to store the vector `in a C 00370 // program'. For an array of cardinal types this is the same as the storage 00371 // used by _BUF. For anything else, it is the product of length() and the 00372 // element width(). It turns out that both values can be computed the same 00373 // way. 00374 // 00375 // Returns: The number of bytes used to store the vector. 00376 00382 unsigned int Vector::width() 00383 { 00384 // Jose Garcia 00385 if (!_var) 00386 throw InternalErr(__FILE__, __LINE__, 00387 "Cannot get width since *this* object is not holding data."); 00388 00389 return length() * _var->width(); 00390 } 00391 00392 // Returns: the number of elements in the vector. 00393 00398 int Vector::length() const 00399 { 00400 return _length; 00401 } 00402 00403 // set the number of elements in the vector. 00404 // 00405 // Returns: void 00406 00409 void Vector::set_length(int l) 00410 { 00411 _length = l; 00412 } 00413 00414 // \e l is the number of elements the vector can hold (e.g., if l == 20, then 00415 // the vector can hold elements 0, .., 19). 00416 00422 void Vector::vec_resize(int l) 00423 { 00424 _vec.resize((l > 0) ? l : 0, 0); // Fill with NULLs 00425 } 00426 00442 void 00443 Vector::intern_data(ConstraintEvaluator &eval, DDS &dds) 00444 { 00445 DBG(cerr << "Vector::intern_data: " << name() << endl); 00446 if (!read_p()) 00447 read(); // read() throws Error and InternalErr 00448 00449 // length() is not capacity; it must be set explicitly in read(). 00450 int num = length(); 00451 00452 switch (_var->type()) { 00453 case dods_byte_c: 00454 case dods_int16_c: 00455 case dods_uint16_c: 00456 case dods_int32_c: 00457 case dods_uint32_c: 00458 case dods_float32_c: 00459 case dods_float64_c: 00460 // For these cases, read() puts the data into _buf, which is what we 00461 // need to do 'stuff' with the data. 00462 break; 00463 00464 case dods_str_c: 00465 case dods_url_c: 00466 // For these cases, read() will put the data into d_str[], which is 00467 // what the transformation classes need. 00468 break; 00469 00470 case dods_array_c: 00471 // I think this is an error since there can never be an Array of 00472 // Array. 00473 throw InternalErr(__FILE__, __LINE__, "Array of Array not supported."); 00474 break; 00475 00476 case dods_structure_c: 00477 case dods_sequence_c: 00478 case dods_grid_c: 00479 DBG(cerr << "Vector::intern_data: found ctor" << endl); 00480 // For these cases, we need to call read() for each of the 'num' 00481 // elements in the '_vec[]' array of BaseType object pointers. 00482 if (_vec.capacity() == 0) 00483 throw InternalErr(__FILE__, __LINE__, 00484 "The capacity of *this* vector is 0."); 00485 00486 for (int i = 0; i < num; ++i) 00487 _vec[i]->intern_data(eval, dds); 00488 00489 break; 00490 00491 default: 00492 throw InternalErr(__FILE__, __LINE__, "Unknown datatype."); 00493 break; 00494 } 00495 } 00496 00509 bool Vector::serialize(ConstraintEvaluator & eval, DDS & dds, 00510 Marshaller &m, bool ce_eval) 00511 { 00512 int i = 0; 00513 00514 dds.timeout_on(); 00515 00516 if (!read_p()) 00517 read(); // read() throws Error and InternalErr 00518 00519 #if EVAL 00520 if (ce_eval && !eval.eval_selection(dds, dataset())) 00521 return true; 00522 #endif 00523 00524 dds.timeout_off(); 00525 00526 // length() is not capacity; it must be set explicitly in read(). 00527 int num = length(); 00528 00529 switch (_var->type()) { 00530 case dods_byte_c: 00531 m.put_vector( _buf, num, *this ) ; 00532 break ; 00533 case dods_int16_c: 00534 case dods_uint16_c: 00535 case dods_int32_c: 00536 case dods_uint32_c: 00537 case dods_float32_c: 00538 case dods_float64_c: 00539 m.put_vector( _buf, num, _var->width(), *this ) ; 00540 break; 00541 00542 case dods_str_c: 00543 case dods_url_c: 00544 if (d_str.capacity() == 0) 00545 throw InternalErr(__FILE__, __LINE__, 00546 "The capacity of the string vector is 0"); 00547 00548 m.put_int( num ) ; 00549 00550 for (i = 0; i < num; ++i) 00551 m.put_str( d_str[i] ) ; 00552 00553 break; 00554 00555 case dods_array_c: 00556 case dods_structure_c: 00557 case dods_sequence_c: 00558 case dods_grid_c: 00559 //Jose Garcia 00560 // Not setting the capacity of _vec is an internal error. 00561 if (_vec.capacity() == 0) 00562 throw InternalErr(__FILE__, __LINE__, 00563 "The capacity of *this* vector is 0."); 00564 00565 m.put_int( num ) ; 00566 00567 for (i = 0; i < num; ++i) 00568 _vec[i]->serialize(eval, dds, m, false); 00569 00570 break; 00571 00572 default: 00573 throw InternalErr(__FILE__, __LINE__, "Unknown datatype."); 00574 break; 00575 } 00576 00577 return true; 00578 } 00579 00580 // Read an object from the network and internalize it. For a Vector this is 00581 // handled differently for a `cardinal' type. Vectors of Cardinals are 00582 // stored using the `C' representations because these objects often are used 00583 // to build huge arrays (e.g., an array of 1024 by 1024 bytes). However, 00584 // arrays of non-cardinal types are stored as Vectors of the C++ objects or 00585 // DAP2 objects (Str and Url are vectors of the string class, Structure, ..., 00586 // Grid are vectors of the libdap Structure, ... classes). 00587 // 00588 // The boolean parameter REUSE determines whether internal storage is reused 00589 // or not. If true, the _buf member is assumed to be large enough to hold the 00590 // incoming cardinal data and is *not* reallocated. If false, new storage is 00591 // allocated. If the internal buffer has not yet been allocated, then this 00592 // parameter has no effect (i.e., storage is allocated). This parameter 00593 // effects storage for cardinal data only. 00594 // 00595 // Returns: True is successful, false otherwise. 00596 00597 bool Vector::deserialize(UnMarshaller &um, DDS * dds, bool reuse) 00598 { 00599 #if 0 00600 // status no longer used. jhrg 8/28/07 00601 bool status; 00602 #endif 00603 unsigned int num; 00604 unsigned i = 0; 00605 00606 switch (_var->type()) { 00607 case dods_byte_c: 00608 case dods_int16_c: 00609 case dods_uint16_c: 00610 case dods_int32_c: 00611 case dods_uint32_c: 00612 case dods_float32_c: 00613 case dods_float64_c: 00614 if (_buf && !reuse) 00615 delete[]_buf; 00616 _buf = 0; 00617 00618 um.get_int( (int &)num ) ; 00619 00620 DBG(cerr << "Vector::deserialize: num = " << num << endl); 00621 DBG(cerr << "Vector::deserialize: length = " << length() << endl); 00622 00623 if (length() == -1) 00624 set_length(num); 00625 00626 if (num != (unsigned int) length()) 00627 throw InternalErr(__FILE__, __LINE__, "The server sent declarations and data with mismatched sizes."); 00628 00629 if (!_buf) { 00630 _buf = new char[width()]; // we always do the allocation! 00631 DBG(cerr << "Vector::deserialize: allocating " 00632 << width() << " bytes for an array of " 00633 << length() << " " << _var->type_name() << endl); 00634 } 00635 00636 if (_var->type() == dods_byte_c) 00637 um.get_vector( (char **)&_buf, num, *this ) ; 00638 else 00639 um.get_vector( (char **)&_buf, num, _var->width(), *this ) ; 00640 00641 DBG(cerr << "Vector::deserialize: read " << num << " elements\n"); 00642 00643 break; 00644 00645 case dods_str_c: 00646 case dods_url_c: 00647 um.get_int( (int &)num ) ; 00648 00649 if (length() == -1) 00650 set_length(num); 00651 00652 if (num != (unsigned int) length()) 00653 throw InternalErr(__FILE__, __LINE__, 00654 "The client sent declarations and data with mismatched sizes."); 00655 00656 d_str.resize((num > 0) ? num : 0); // Fill with NULLs 00657 00658 for (i = 0; i < num; ++i) { 00659 string str; 00660 um.get_str( str ) ; 00661 d_str[i] = str; 00662 00663 } 00664 00665 break; 00666 00667 case dods_array_c: 00668 case dods_structure_c: 00669 case dods_sequence_c: 00670 case dods_grid_c: 00671 um.get_int( (int &)num ) ; 00672 00673 if (length() == -1) 00674 set_length(num); 00675 00676 if (num != (unsigned int) length()) 00677 throw InternalErr(__FILE__, __LINE__, "The client sent declarations and data with mismatched sizes."); 00678 00679 vec_resize(num); 00680 00681 for (i = 0; i < num; ++i) { 00682 _vec[i] = _var->ptr_duplicate(); 00683 _vec[i]->deserialize(um, dds); 00684 } 00685 00686 break; 00687 00688 default: 00689 throw InternalErr(__FILE__, __LINE__, "Unknown type!"); 00690 break; 00691 } 00692 00693 return false; 00694 } 00695 00723 unsigned int Vector::val2buf(void *val, bool reuse) 00724 { 00725 // Jose Garcia 00726 00727 // I *think* this method has been mainly designed to be use by read which 00728 // is implemented in the surrogate library. Passing NULL as a pointer to 00729 // this method will be an error of the creator of the surrogate library. 00730 // Even though I recognize the fact that some methods inside libdap++ can 00731 // call val2buf, I think by now no coding bugs such as misusing val2buf 00732 // will be in libdap++, so it will be an internal error from the 00733 // surrogate library. 00734 if (!val) 00735 throw InternalErr(__FILE__, __LINE__, 00736 "The incoming pointer does not contain any data."); 00737 00738 switch (_var->type()) { 00739 case dods_byte_c: 00740 case dods_int16_c: 00741 case dods_uint16_c: 00742 case dods_int32_c: 00743 case dods_uint32_c: 00744 case dods_float32_c: 00745 case dods_float64_c: { 00746 // width() returns the size given the constraint 00747 unsigned int array_wid = width(); 00748 if (_buf && !reuse) { 00749 delete[]_buf; 00750 _buf = 0; 00751 } 00752 00753 if (!_buf) { // First time or no reuse (free'd above) 00754 _buf = new char[array_wid]; 00755 } 00756 00757 memcpy(_buf, val, array_wid); 00758 break; 00759 } 00760 00761 case dods_str_c: 00762 case dods_url_c: { 00763 // Assume val points to an array of C++ string objects. Copy 00764 // them into the vector<string> field of this object. 00765 d_str.resize(_length); 00766 for (int i = 0; i < _length; ++i) 00767 d_str[i] = *(static_cast < string * >(val) + i); 00768 00769 break; 00770 } 00771 00772 default: 00773 throw InternalErr(__FILE__, __LINE__, "Vector::val2buf: bad type"); 00774 00775 } 00776 00777 return width(); 00778 } 00779 00810 unsigned int Vector::buf2val(void **val) 00811 { 00812 // Jose Garcia 00813 // The same comment in Vector::val2buf applies here! 00814 if (!val) 00815 throw InternalErr(__FILE__, __LINE__, "NULL pointer."); 00816 00817 unsigned int wid = static_cast<unsigned int>(width()); 00818 // This is the width computed using length(). The 00819 // length() property is changed when a projection 00820 // constraint is applied. Thus this is the number of 00821 // bytes in the buffer given the current constraint. 00822 00823 switch (_var->type()) { 00824 case dods_byte_c: 00825 case dods_int16_c: 00826 case dods_uint16_c: 00827 case dods_int32_c: 00828 case dods_uint32_c: 00829 case dods_float32_c: 00830 case dods_float64_c: 00831 if (!*val) 00832 *val = new char[wid]; 00833 00834 (void) memcpy(*val, _buf, wid); 00835 00836 break; 00837 00838 case dods_str_c: 00839 case dods_url_c: { 00840 if (!*val) 00841 *val = new string[_length]; 00842 00843 for (int i = 0; i < _length; ++i) 00844 *(static_cast < string * >(*val) + i) = d_str[i]; 00845 00846 break; 00847 } 00848 00849 default: 00850 throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: bad type"); 00851 return 0; 00852 } 00853 00854 return wid; 00855 } 00856 00877 void Vector::set_vec(unsigned int i, BaseType * val) 00878 { 00879 // Jose Garcia 00880 // This is a public method which allows users to set the elements 00881 // of *this* vector. Passing an invalid index, a NULL pointer or 00882 // mismatching the vector type are internal errors. 00883 if (i >= static_cast < unsigned int >(_length)) 00884 throw InternalErr(__FILE__, __LINE__, 00885 "Invalid data: index too large."); 00886 if (!val) 00887 throw InternalErr(__FILE__, __LINE__, 00888 "Invalid data: null pointer to BaseType object."); 00889 if (val->type() != _var->type()) 00890 throw InternalErr(__FILE__, __LINE__, 00891 "invalid data: type of incoming object does not match *this* vector type."); 00892 00893 if (i >= _vec.capacity()) 00894 vec_resize(i + 10); 00895 00896 _vec[i] = val->ptr_duplicate(); 00897 } 00898 00899 00901 00902 bool 00903 Vector::set_value(dods_byte *val, int sz) 00904 { 00905 if (var()->type() == dods_byte_c && val) { 00906 _buf = reinterpret_cast<char*>(new dods_byte[sz]) ; 00907 memcpy(_buf, val, sz * sizeof(dods_byte)); 00908 set_read_p(true); 00909 return true; 00910 } 00911 else { 00912 return false; 00913 } 00914 } 00915 00917 bool 00918 Vector::set_value(vector<dods_byte> &val, int sz) 00919 { 00920 if (var()->type() == dods_byte_c) { 00921 dods_byte *tmp_buf = new dods_byte[sz] ; 00922 _buf = reinterpret_cast<char*>(tmp_buf) ; 00923 for (register int t = 0; t < sz; t++) { 00924 tmp_buf[t] = val[t] ; 00925 } 00926 set_read_p(true); 00927 return true; 00928 } 00929 else { 00930 return false; 00931 } 00932 } 00933 00935 bool 00936 Vector::set_value(dods_int16 *val, int sz) 00937 { 00938 if (var()->type() == dods_int16_c && val) { 00939 _buf = reinterpret_cast<char*>(new dods_int16[sz]) ; 00940 memcpy(_buf, val, sz * sizeof(dods_int16)); 00941 set_read_p(true); 00942 return true; 00943 } 00944 else { 00945 return false; 00946 } 00947 } 00948 00950 bool 00951 Vector::set_value(vector<dods_int16> &val, int sz) 00952 { 00953 if (var()->type() == dods_int16_c) { 00954 dods_int16 *tmp_buf = new dods_int16[sz] ; 00955 _buf = reinterpret_cast<char*>(tmp_buf) ; 00956 for (register int t = 0; t < sz; t++) { 00957 tmp_buf[t] = val[t] ; 00958 } 00959 set_read_p(true); 00960 return true; 00961 } 00962 else { 00963 return false; 00964 } 00965 } 00966 00968 bool 00969 Vector::set_value(dods_int32 *val, int sz) 00970 { 00971 if (var()->type() == dods_int32_c && val) { 00972 _buf = reinterpret_cast<char*>(new dods_int32[sz]) ; 00973 memcpy(_buf, val, sz * sizeof(dods_int32)); 00974 set_read_p(true); 00975 return true; 00976 } 00977 else { 00978 return false; 00979 } 00980 } 00981 00983 bool 00984 Vector::set_value(vector<dods_int32> &val, int sz) 00985 { 00986 if (var()->type() == dods_int32_c) { 00987 dods_int32 *tmp_buf = new dods_int32[sz] ; 00988 _buf = reinterpret_cast<char*>(tmp_buf) ; 00989 for (register int t = 0; t < sz; t++) { 00990 tmp_buf[t] = val[t] ; 00991 } 00992 set_read_p(true); 00993 return true; 00994 } 00995 else { 00996 return false; 00997 } 00998 } 00999 01001 bool 01002 Vector::set_value(dods_uint16 *val, int sz) 01003 { 01004 if (var()->type() == dods_uint16_c && val) { 01005 _buf = reinterpret_cast<char*>(new dods_uint16[sz]) ; 01006 memcpy(_buf, val, sz * sizeof(dods_uint16)); 01007 set_read_p(true); 01008 return true; 01009 } 01010 else { 01011 return false; 01012 } 01013 } 01014 01016 bool 01017 Vector::set_value(vector<dods_uint16> &val, int sz) 01018 { 01019 if (var()->type() == dods_uint16_c) { 01020 dods_uint16 *tmp_buf = new dods_uint16[sz] ; 01021 _buf = reinterpret_cast<char*>(tmp_buf) ; 01022 for (register int t = 0; t < sz; t++) { 01023 tmp_buf[t] = val[t] ; 01024 } 01025 set_read_p(true); 01026 return true; 01027 } 01028 else { 01029 return false; 01030 } 01031 } 01032 01034 bool 01035 Vector::set_value(dods_uint32 *val, int sz) 01036 { 01037 if (var()->type() == dods_uint32_c && val) { 01038 _buf = reinterpret_cast<char*>(new dods_uint32[sz]) ; 01039 memcpy(_buf, val, sz * sizeof(dods_uint32)); 01040 set_read_p(true); 01041 return true; 01042 } 01043 else { 01044 return false; 01045 } 01046 } 01047 01049 bool 01050 Vector::set_value(vector<dods_uint32> &val, int sz) 01051 { 01052 if (var()->type() == dods_uint32_c) { 01053 dods_uint32 *tmp_buf = new dods_uint32[sz] ; 01054 _buf = reinterpret_cast<char*>(tmp_buf) ; 01055 for (register int t = 0; t < sz; t++) { 01056 tmp_buf[t] = val[t] ; 01057 } 01058 set_read_p(true); 01059 return true; 01060 } 01061 else { 01062 return false; 01063 } 01064 } 01065 01067 bool 01068 Vector::set_value(dods_float32 *val, int sz) 01069 { 01070 if (var()->type() == dods_float32_c && val) { 01071 _buf = reinterpret_cast<char*>(new dods_float32[sz]) ; 01072 memcpy(_buf, val, sz * sizeof(dods_float32)); 01073 set_read_p(true); 01074 return true; 01075 } 01076 else { 01077 return false; 01078 } 01079 } 01080 01082 bool 01083 Vector::set_value(vector<dods_float32> &val, int sz) 01084 { 01085 if (var()->type() == dods_float32_c) { 01086 dods_float32 *tmp_buf = new dods_float32[sz] ; 01087 _buf = reinterpret_cast<char*>(tmp_buf) ; 01088 for (register int t = 0; t < sz; t++) { 01089 tmp_buf[t] = val[t] ; 01090 } 01091 set_read_p(true); 01092 return true; 01093 } 01094 else { 01095 return false; 01096 } 01097 } 01098 01100 bool 01101 Vector::set_value(dods_float64 *val, int sz) 01102 { 01103 if (!val) 01104 return false; 01105 01106 switch (var()->type()) { 01107 case dods_float64_c: 01108 _buf = reinterpret_cast<char*>(new dods_float64[sz]) ; 01109 memcpy(_buf, val, sz * sizeof(dods_float64)); 01110 set_read_p(true); 01111 return true; 01112 default: 01113 return false; 01114 } 01115 } 01116 01118 bool 01119 Vector::set_value(vector<dods_float64> &val, int sz) 01120 { 01121 if (var()->type() == dods_float64_c) { 01122 dods_float64 *tmp_buf = new dods_float64[sz] ; 01123 _buf = reinterpret_cast<char*>(tmp_buf) ; 01124 for (register int t = 0; t < sz; t++) { 01125 tmp_buf[t] = val[t] ; 01126 } 01127 set_read_p(true); 01128 return true; 01129 } 01130 else { 01131 return false; 01132 } 01133 } 01134 01136 bool 01137 Vector::set_value(string *val, int sz) 01138 { 01139 if ((var()->type() == dods_str_c || var()->type() == dods_url_c) && val) { 01140 d_str.resize(sz); 01141 for (register int t = 0; t < sz; t++) { 01142 d_str[t] = val[t] ; 01143 } 01144 set_length(sz) ; 01145 set_read_p(true); 01146 return true; 01147 } 01148 else { 01149 return false; 01150 } 01151 } 01152 01154 bool 01155 Vector::set_value(vector<string> &val, int sz) 01156 { 01157 if (var()->type() == dods_str_c || var()->type() == dods_url_c) { 01158 d_str.resize(sz); 01159 for (register int t = 0; t < sz; t++) { 01160 d_str[t] = val[t] ; 01161 } 01162 set_length(sz) ; 01163 set_read_p(true); 01164 return true; 01165 } 01166 else { 01167 return false; 01168 } 01169 } 01171 01173 01180 void Vector::value(dods_byte *b) const 01181 { 01182 if (b && _var->type() == dods_byte_c) { 01183 memcpy(b, _buf, length() * sizeof(dods_byte)); 01184 } 01185 } 01186 01188 void Vector::value(dods_uint16 *b) const 01189 { 01190 if (b && _var->type() == dods_uint16_c) { 01191 memcpy(b, _buf, length() * sizeof(dods_uint16)); 01192 } 01193 } 01194 01196 void Vector::value(dods_int16 *b) const 01197 { 01198 if (b && _var->type() == dods_int16_c) { 01199 memcpy(b, _buf, length() * sizeof(dods_int16)); 01200 } 01201 } 01202 01204 void Vector::value(dods_uint32 *b) const 01205 { 01206 if (b && _var->type() == dods_uint32_c) { 01207 memcpy(b, _buf, length() * sizeof(dods_uint32)); 01208 } 01209 } 01210 01212 void Vector::value(dods_int32 *b) const 01213 { 01214 if (b && _var->type() == dods_int32_c) { 01215 memcpy(b, _buf, length() * sizeof(dods_int32)); 01216 } 01217 } 01218 01220 void Vector::value(dods_float32 *b) const 01221 { 01222 if (b && _var->type() == dods_float32_c) { 01223 memcpy(b, _buf, length() * sizeof(dods_float32)); 01224 } 01225 } 01226 01228 void Vector::value(dods_float64 *b) const 01229 { 01230 if (b && _var->type() == dods_float64_c) { 01231 memcpy(b, _buf, length() * sizeof(dods_float64)); 01232 } 01233 } 01234 01236 void Vector::value(vector<string> &b) const 01237 { 01238 if (_var->type() == dods_byte_c || _var->type() == dods_url_c) 01239 b = d_str; 01240 } 01241 01244 void *Vector::value() 01245 { 01246 void *buffer = new char[width()]; 01247 01248 memcpy(buffer, _buf, width()); 01249 01250 return buffer; 01251 } 01253 01266 void Vector::add_var(BaseType * v, Part) 01267 { 01268 // Delete the current template variable 01269 if( _var ) 01270 { 01271 delete _var; 01272 _var = 0 ; 01273 } 01274 01275 // if 'v' is null, just set _var to null and exit. 01276 if (!v) { 01277 _var = 0; 01278 } 01279 else { 01280 // Jose Garcia 01281 // By getting a copy of this object to be assigned to _var 01282 // we let the owner of 'v' to deallocate it as necessary. 01283 _var = v->ptr_duplicate(); 01284 01285 // If 'v' has a name, use it as the name of the array. If it *is* 01286 // empty, then make sure to copy the array's name to the template 01287 // so that software which uses the template's name will still work. 01288 if (!v->name().empty()) 01289 set_name(v->name()); 01290 else 01291 _var->set_name(name()); 01292 01293 _var->set_parent(this); // Vector --> child 01294 01295 DBG(cerr << "Vector::add_var: Added variable " << v << " (" 01296 << v->name() << " " << v->type_name() << ")" << endl); 01297 } 01298 } 01299 01300 bool Vector::check_semantics(string & msg, bool) 01301 { 01302 return BaseType::check_semantics(msg); 01303 } 01304 01313 void 01314 Vector::dump(ostream &strm) const 01315 { 01316 strm << DapIndent::LMarg << "Vector::dump - (" 01317 << (void *)this << ")" << endl ; 01318 DapIndent::Indent() ; 01319 BaseType::dump(strm) ; 01320 strm << DapIndent::LMarg << "# elements in vector: " << _length << endl ; 01321 if (_var) { 01322 strm << DapIndent::LMarg << "base type:" << endl ; 01323 DapIndent::Indent() ; 01324 _var->dump(strm) ; 01325 DapIndent::UnIndent() ; 01326 } 01327 else { 01328 strm << DapIndent::LMarg << "base type: not set" << endl ; 01329 } 01330 strm << DapIndent::LMarg << "vector contents:" << endl ; 01331 DapIndent::Indent() ; 01332 for (unsigned i = 0; i < _vec.size(); ++i) { 01333 if (_vec[i]) 01334 _vec[i]->dump(strm) ; 01335 else 01336 strm << DapIndent::LMarg << "vec[" << i << "] is null" << endl ; 01337 } 01338 DapIndent::UnIndent() ; 01339 strm << DapIndent::LMarg << "strings:" << endl ; 01340 DapIndent::Indent() ; 01341 for (unsigned i = 0; i < d_str.size(); i++) { 01342 strm << DapIndent::LMarg << d_str[i] << endl ; 01343 } 01344 DapIndent::UnIndent() ; 01345 if( _buf ) 01346 { 01347 switch( _var->type() ) 01348 { 01349 case dods_byte_c: 01350 { 01351 strm << DapIndent::LMarg << "_buf: " ; 01352 strm.write( _buf, _length ) ; 01353 strm << endl ; 01354 } 01355 break ; 01356 default: 01357 { 01358 strm << DapIndent::LMarg << "_buf: " << (void *)_buf << endl ; 01359 } 01360 break ; 01361 } 01362 } 01363 else 01364 { 01365 strm << DapIndent::LMarg << "_buf: EMPTY" << endl ; 01366 } 01367 DapIndent::UnIndent() ; 01368 } 01369 01370 } // namespace libdap 01371