libdap++ Updated for version 3.8.2

Vector.cc

Go to the documentation of this file.
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