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 static char rcsid[] not_used =
00040     { "$Id: Vector.cc 17489 2007-11-26 23:18:58Z pwest $"
00041     };
00042 
00043 //#define DODS_DEBUG
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     // _var holds the type of the elements. That is, it holds a BaseType
00062     // which acts as a template for the type of each element.
00063     if (v._var) {
00064         _var = v._var->ptr_duplicate(); // use ptr_duplicate()
00065         _var->set_parent(this); // ptr_duplicate does not set d_parent.
00066     }
00067     else {
00068         _var = 0;
00069     }
00070 
00071     // _vec and _buf (futher down) hold the values of the Vector. The field
00072     // _vec is used when the Vector holds non-numeric data (including strings
00073     // although it used to be that was not the case jhrg 2/10/05) while _buf
00074     // holds numeric values.
00075     if (v._vec.empty()) {
00076         _vec = v._vec;
00077     }
00078     else {
00079         // Failure to set the size will make the [] operator barf on the LHS
00080         // of the assignment inside the loop.
00081         _vec.resize(_length);
00082         for (int i = 0; i < _length; ++i) {
00083             // There's no need to call set_parent() for each element; we
00084             // maintain the back pointer using the _var member. These
00085             // instances are used to hold _values_ only while the _var
00086             // field holds the type of the elements.
00087             _vec[i] = v._vec[i]->ptr_duplicate();
00088         }
00089     }
00090 
00091     // copy the strings. This copies the values.
00092     d_str = v.d_str;
00093 
00094     // copy numeric values if there are any.
00095     _buf = 0;                   // init to null
00096     if (v._buf)                 // only copy if data present
00097         val2buf(v._buf);        // store v's value in this's _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         // var() only works for simple types!
00176         return var(0)->element_count(leaves);
00177 }
00178 
00179 // These mfuncs set the _send_p and _read_p fields of BaseType. They differ
00180 // from BaseType's version in that they set both the Vector object's copy of
00181 // _send_p (_read_p) but also _VAR's copy. This does not matter much when _VAR
00182 // is a scalar, but does matter when it is an aggregate.
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     // Make sure to check for the case where name is the default (the empty
00230     // string). 9/1/98 jhrg
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 // Return a pointer the the BaseType object for element I. If the Vector is
00264 // of a cardinal type, store the Ith element's value in the BaseType
00265 // object. If it is a Vector of a non-cardinal type, then this mfunc returns
00266 // _vec[i].
00267 //
00268 // NB: I defaults to zero.
00269 //
00270 // Returns: A BaseType pointer to the Ith element of the Vector.
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             // Transfer the ith value to the BaseType *_var; There are more
00299             // efficient ways to get a whole array using buf2val() but this is
00300             // an OK way to get a single value or several non-contiguous values.
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 // Return: The number of bytes required to store the vector `in a C
00328 // program'. For an array of cardinal types this is the same as the storage
00329 // used by _BUF. For anything else, it is the product of length() and the
00330 // element width(). It turns out that both values can be computed the same
00331 // way.
00332 //
00333 // Returns: The number of bytes used to store the vector.
00334 
00340 unsigned int Vector::width()
00341 {
00342     // Jose Garcia
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 // Returns: the number of elements in the vector.
00351 
00356 int Vector::length() const
00357 {
00358     return _length;
00359 }
00360 
00361 // set the number of elements in the vector.
00362 //
00363 // Returns: void
00364 
00367 void Vector::set_length(int l)
00368 {
00369     _length = l;
00370 }
00371 
00372 // \e l is the number of elements the vector can hold (e.g., if l == 20, then
00373 // the vector can hold elements 0, .., 19).
00374 
00380 void Vector::vec_resize(int l)
00381 {
00382     _vec.resize((l > 0) ? l : 0, 0);    // Fill with NULLs
00383 }
00384 
00401 void
00402 Vector::intern_data(const string &dataset, ConstraintEvaluator &eval, DDS &dds)
00403 {
00404     if (!read_p())
00405         read(dataset);          // read() throws Error and InternalErr
00406 
00407     // length() is not capacity; it must be set explicitly in read().
00408     int num = length();
00409 
00410     switch (_var->type()) {
00411     case dods_byte_c:
00412     case dods_int16_c:
00413     case dods_uint16_c:
00414     case dods_int32_c:
00415     case dods_uint32_c:
00416     case dods_float32_c:
00417     case dods_float64_c:
00418         // For these cases, read() puts the data into _buf, which is what we
00419         // need to do 'stuff' with the data.
00420         break;
00421         
00422     case dods_str_c:
00423     case dods_url_c:
00424         // For these cases, read() will put the data into d_str[], which is 
00425         // what the transformation classes need.
00426         break;
00427 
00428     case dods_array_c:
00429         // I think this is an error since there can never be an Array of 
00430         // Array.
00431         throw InternalErr(__FILE__, __LINE__, "Array of Array not supported.");
00432         break;
00433         
00434     case dods_structure_c:
00435     case dods_sequence_c:
00436     case dods_grid_c:
00437         // For these cases, we need to call read() for each of the 'num' 
00438         // elements in the '_vec[]' array of BaseType object pointers.
00439         if (_vec.capacity() == 0)
00440             throw InternalErr(__FILE__, __LINE__,
00441                               "The capacity of *this* vector is 0.");
00442 
00443         for (int i = 0; i < num; ++i)
00444             _vec[i]->intern_data(dataset, eval, dds);
00445 
00446         break;
00447 
00448     default:
00449         throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
00450         break;
00451     }
00452 }
00453 
00466 bool Vector::serialize(const string & dataset, ConstraintEvaluator & eval,
00467                        DDS & dds, Marshaller &m, bool ce_eval)
00468 {
00469     int i = 0;
00470 
00471     dds.timeout_on();
00472 
00473     if (!read_p())
00474         read(dataset);          // read() throws Error and InternalErr
00475 
00476 #if EVAL
00477     if (ce_eval && !eval.eval_selection(dds, dataset))
00478         return true;
00479 #endif
00480 
00481     dds.timeout_off();
00482 
00483     // length() is not capacity; it must be set explicitly in read().
00484     int num = length();
00485 
00486     switch (_var->type()) {
00487     case dods_byte_c:
00488         m.put_vector( _buf, num, *this ) ;
00489         break ;
00490     case dods_int16_c:
00491     case dods_uint16_c:
00492     case dods_int32_c:
00493     case dods_uint32_c:
00494     case dods_float32_c:
00495     case dods_float64_c:
00496         m.put_vector( _buf, num, _var->width(), *this ) ;
00497         break;
00498 
00499     case dods_str_c:
00500     case dods_url_c:
00501         if (d_str.capacity() == 0)
00502             throw InternalErr(__FILE__, __LINE__,
00503                               "The capacity of the string vector is 0");
00504 
00505         m.put_int( num ) ;
00506 
00507         for (i = 0; i < num; ++i)
00508             m.put_str( d_str[i] ) ;
00509 
00510         break;
00511 
00512     case dods_array_c:
00513     case dods_structure_c:
00514     case dods_sequence_c:
00515     case dods_grid_c:
00516         //Jose Garcia
00517         // Not setting the capacity of _vec is an internal error.
00518         if (_vec.capacity() == 0)
00519             throw InternalErr(__FILE__, __LINE__,
00520                               "The capacity of *this* vector is 0.");
00521 
00522         m.put_int( num ) ;
00523 
00524         for (i = 0; i < num; ++i)
00525             _vec[i]->serialize(dataset, eval, dds, m, false);
00526 
00527         break;
00528 
00529     default:
00530         throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
00531         break;
00532     }
00533 
00534     return true;
00535 }
00536 
00537 // Read an object from the network and internalize it. For a Vector this is
00538 // handled differently for a `cardinal' type. Vectors of Cardinals are
00539 // stored using the `C' representations because these objects often are used
00540 // to build huge arrays (e.g., an array of 1024 by 1024 bytes). However,
00541 // arrays of non-cardinal types are stored as Vectors of the C++ objects or
00542 // DAP2 objects (Str and Url are vectors of the string class, Structure, ...,
00543 // Grid are vectors of the libdap Structure, ... classes).
00544 //
00545 // The boolean parameter REUSE determines whether internal storage is reused
00546 // or not. If true, the _buf member is assumed to be large enough to hold the
00547 // incoming cardinal data and is *not* reallocated. If false, new storage is
00548 // allocated. If the internal buffer has not yet been allocated, then this
00549 // parameter has no effect (i.e., storage is allocated). This parameter
00550 // effects storage for cardinal data only.
00551 //
00552 // Returns: True is successful, false otherwise.
00553 
00554 bool Vector::deserialize(UnMarshaller &um, DDS * dds, bool reuse)
00555 {
00556 #if 0
00557     // status no longer used. jhrg 8/28/07
00558     bool status;
00559 #endif
00560     unsigned int num;
00561     unsigned i = 0;
00562 
00563     switch (_var->type()) {
00564     case dods_byte_c:
00565     case dods_int16_c:
00566     case dods_uint16_c:
00567     case dods_int32_c:
00568     case dods_uint32_c:
00569     case dods_float32_c:
00570     case dods_float64_c:
00571         if (_buf && !reuse)
00572             delete[]_buf;
00573         _buf = 0;
00574 
00575         um.get_int( (int &)num ) ;
00576 
00577         DBG(cerr << "Vector::deserialize: num = " << num << endl);
00578         DBG(cerr << "Vector::deserialize: length = " << length() << endl);
00579 
00580         if (length() == -1)
00581             set_length(num);
00582 
00583         if (num != (unsigned int) length())
00584             throw InternalErr(__FILE__, __LINE__, "The server sent declarations and data with mismatched sizes.");
00585 
00586         if (!_buf) {
00587             _buf = new char[width()];   // we always do the allocation!
00588             DBG(cerr << "Vector::deserialize: allocating "
00589                 << width() << " bytes for an array of "
00590                 << length() << " " << _var->type_name() << endl);
00591         }
00592 
00593         if (_var->type() == dods_byte_c)
00594             um.get_vector( (char **)&_buf, num, *this ) ;
00595         else
00596             um.get_vector( (char **)&_buf, num, _var->width(), *this ) ;
00597 
00598         DBG(cerr << "Vector::deserialize: read " << num << " elements\n");
00599 
00600         break;
00601 
00602     case dods_str_c:
00603     case dods_url_c:
00604         um.get_int( (int &)num ) ;
00605 
00606         if (length() == -1)
00607             set_length(num);
00608 
00609         if (num != (unsigned int) length())
00610             throw InternalErr(__FILE__, __LINE__,
00611                               "The client sent declarations and data with mismatched sizes.");
00612 
00613         d_str.resize((num > 0) ? num : 0);      // Fill with NULLs
00614 
00615         for (i = 0; i < num; ++i) {
00616             string str;
00617             um.get_str( str ) ;
00618             d_str[i] = str;
00619 
00620         }
00621 
00622         break;
00623 
00624     case dods_array_c:
00625     case dods_structure_c:
00626     case dods_sequence_c:
00627     case dods_grid_c:
00628         um.get_int( (int &)num ) ;
00629 
00630         if (length() == -1)
00631             set_length(num);
00632 
00633         if (num != (unsigned int) length())
00634             throw InternalErr(__FILE__, __LINE__, "The client sent declarations and data with mismatched sizes.");
00635 
00636         vec_resize(num);
00637 
00638         for (i = 0; i < num; ++i) {
00639             _vec[i] = _var->ptr_duplicate();
00640             _vec[i]->deserialize(um, dds);
00641         }
00642 
00643         break;
00644 
00645     default:
00646         throw InternalErr(__FILE__, __LINE__, "Unknow type!");
00647         break;
00648     }
00649 
00650     return false;
00651 }
00652 
00680 unsigned int Vector::val2buf(void *val, bool reuse)
00681 {
00682     // Jose Garcia
00683 
00684     // I *think* this method has been mainly designed to be use by read which
00685     // is implemented in the surrogate library. Passing NULL as a pointer to
00686     // this method will be an error of the creator of the surrogate library.
00687     // Even though I recognize the fact that some methods inside libdap++ can
00688     // call val2buf, I think by now no coding bugs such as missusing val2buf
00689     // will be in libdap++, so it will be an internal error from the
00690     // surrogate library.
00691     if (!val)
00692         throw InternalErr(__FILE__, __LINE__,
00693                           "The incoming pointer does not contain any data.");
00694 
00695     switch (_var->type()) {
00696     case dods_byte_c:
00697     case dods_int16_c:
00698     case dods_uint16_c:
00699     case dods_int32_c:
00700     case dods_uint32_c:
00701     case dods_float32_c:
00702     case dods_float64_c: {
00703             // width() returns the size given the constraint
00704             unsigned int array_wid = width();
00705             if (_buf && !reuse) {
00706                 delete[]_buf;
00707                 _buf = 0;
00708             }
00709 
00710             if (!_buf) {        // First time or no reuse (free'd above)
00711                 _buf = new char[array_wid];
00712             }
00713 
00714             memcpy(_buf, val, array_wid);
00715             break;
00716         }
00717 
00718     case dods_str_c:
00719     case dods_url_c: {
00720             // Assume val points to an array of C++ string objects. Copy
00721             // them into the vector<string> field of this object.
00722             d_str.resize(_length);
00723             for (int i = 0; i < _length; ++i)
00724                 d_str[i] = *(static_cast < string * >(val) + i);
00725 
00726             break;
00727         }
00728 
00729     default:
00730         throw InternalErr(__FILE__, __LINE__, "Vector::val2buf: bad type");
00731 
00732     }
00733 
00734     return width();
00735 }
00736 
00767 unsigned int Vector::buf2val(void **val)
00768 {
00769     // Jose Garcia
00770     // The same comment in Vector::val2buf applies here!
00771     if (!val)
00772         throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
00773 
00774     int wid = width();          // This is the width computed using length(). The
00775     // length() property is changed when a projection
00776     // constraint is applied. Thus this is the number of
00777     // bytes in the buffer given the current constraint.
00778 
00779     switch (_var->type()) {
00780     case dods_byte_c:
00781     case dods_int16_c:
00782     case dods_uint16_c:
00783     case dods_int32_c:
00784     case dods_uint32_c:
00785     case dods_float32_c:
00786     case dods_float64_c:
00787         if (!*val)
00788             *val = new char[wid];
00789 
00790         (void) memcpy(*val, _buf, wid);
00791 
00792         break;
00793 
00794     case dods_str_c:
00795     case dods_url_c: {
00796             if (!*val)
00797                 *val = new string[_length];
00798 
00799             for (int i = 0; i < _length; ++i)
00800                 *(static_cast < string * >(*val) + i) = d_str[i];
00801 
00802             break;
00803         }
00804 
00805     default:
00806         throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: bad type");
00807         return 0;
00808     }
00809 
00810     return wid;
00811 }
00812 
00833 void Vector::set_vec(unsigned int i, BaseType * val)
00834 {
00835     // Jose Garcia
00836     // This is a public method which allows users to set the elements
00837     // of *this* vector. Passing an invalid index, a NULL pointer or
00838     // missmatching the vector type are internal errors.
00839     if (i >= static_cast < unsigned int >(_length))
00840         throw InternalErr(__FILE__, __LINE__,
00841                           "Invalid data: index too large.");
00842     if (!val)
00843         throw InternalErr(__FILE__, __LINE__,
00844                           "Invalid data: null pointer to BaseType object.");
00845     if (val->type() != _var->type())
00846         throw InternalErr(__FILE__, __LINE__,
00847                           "invalid data: type of incoming object does not match *this* vector type.");
00848 
00849     if (i >= _vec.capacity())
00850         vec_resize(i + 10);
00851 
00852     _vec[i] = val->ptr_duplicate();
00853 }
00854 
00855 
00857 
00858 bool
00859 Vector::set_value(dods_byte *val, int sz)
00860 {
00861     if (var()->type() == dods_byte_c && val) {
00862         _buf = reinterpret_cast<char*>(new dods_byte[sz]) ;
00863         memcpy(_buf, val, sz * sizeof(dods_byte));
00864         set_read_p(true);
00865         return true;
00866     }
00867     else {
00868         return false;
00869     }
00870 }
00871 
00873 bool
00874 Vector::set_value(vector<dods_byte> &val, int sz)
00875 {
00876     if (var()->type() == dods_byte_c) {
00877         dods_byte *tmp_buf = new dods_byte[sz] ;
00878         _buf = reinterpret_cast<char*>(tmp_buf) ;
00879         for (register int t = 0; t < sz; t++) {
00880             tmp_buf[t] = val[t] ;
00881         }
00882         set_read_p(true);
00883         return true;
00884     }
00885     else {
00886         return false;
00887     }
00888 }
00889 
00891 bool
00892 Vector::set_value(dods_int16 *val, int sz)
00893 {
00894     if (var()->type() == dods_int16_c && val) {
00895         _buf = reinterpret_cast<char*>(new dods_int16[sz]) ;
00896         memcpy(_buf, val, sz * sizeof(dods_int16));
00897         set_read_p(true);
00898         return true;
00899     }
00900     else {
00901         return false;
00902     }
00903 }
00904 
00906 bool
00907 Vector::set_value(vector<dods_int16> &val, int sz)
00908 {
00909     if (var()->type() == dods_int16_c) {
00910         dods_int16 *tmp_buf = new dods_int16[sz] ;
00911         _buf = reinterpret_cast<char*>(tmp_buf) ;
00912         for (register int t = 0; t < sz; t++) {
00913             tmp_buf[t] = val[t] ;
00914         }
00915         set_read_p(true);
00916         return true;
00917     }
00918     else {
00919         return false;
00920     }
00921 }
00922 
00924 bool
00925 Vector::set_value(dods_int32 *val, int sz)
00926 {
00927     if (var()->type() == dods_int32_c && val) {
00928         _buf = reinterpret_cast<char*>(new dods_int32[sz]) ;
00929         memcpy(_buf, val, sz * sizeof(dods_int32));
00930         set_read_p(true);
00931         return true;
00932     }
00933     else {
00934         return false;
00935     }
00936 }
00937 
00939 bool
00940 Vector::set_value(vector<dods_int32> &val, int sz)
00941 {
00942     if (var()->type() == dods_int32_c) {
00943         dods_int32 *tmp_buf = new dods_int32[sz] ;
00944         _buf = reinterpret_cast<char*>(tmp_buf) ;
00945         for (register int t = 0; t < sz; t++) {
00946             tmp_buf[t] = val[t] ;
00947         }
00948         set_read_p(true);
00949         return true;
00950     }
00951     else {
00952         return false;
00953     }
00954 }
00955 
00957 bool
00958 Vector::set_value(dods_uint16 *val, int sz)
00959 {
00960     if (var()->type() == dods_uint16_c && val) {
00961         _buf = reinterpret_cast<char*>(new dods_uint16[sz]) ;
00962         memcpy(_buf, val, sz * sizeof(dods_uint16));
00963         set_read_p(true);
00964         return true;
00965     }
00966     else {
00967         return false;
00968     }
00969 }
00970 
00972 bool
00973 Vector::set_value(vector<dods_uint16> &val, int sz)
00974 {
00975     if (var()->type() == dods_uint16_c) {
00976         dods_uint16 *tmp_buf = new dods_uint16[sz] ;
00977         _buf = reinterpret_cast<char*>(tmp_buf) ;
00978         for (register int t = 0; t < sz; t++) {
00979             tmp_buf[t] = val[t] ;
00980         }
00981         set_read_p(true);
00982         return true;
00983     }
00984     else {
00985         return false;
00986     }
00987 }
00988 
00990 bool
00991 Vector::set_value(dods_uint32 *val, int sz)
00992 {
00993     if (var()->type() == dods_uint32_c && val) {
00994         _buf = reinterpret_cast<char*>(new dods_uint32[sz]) ;
00995         memcpy(_buf, val, sz * sizeof(dods_uint32));
00996         set_read_p(true);
00997         return true;
00998     }
00999     else {
01000         return false;
01001     }
01002 }
01003 
01005 bool
01006 Vector::set_value(vector<dods_uint32> &val, int sz)
01007 {
01008     if (var()->type() == dods_uint32_c) {
01009         dods_uint32 *tmp_buf = new dods_uint32[sz] ;
01010         _buf = reinterpret_cast<char*>(tmp_buf) ;
01011         for (register int t = 0; t < sz; t++) {
01012             tmp_buf[t] = val[t] ;
01013         }
01014         set_read_p(true);
01015         return true;
01016     }
01017     else {
01018         return false;
01019     }
01020 }
01021 
01023 bool
01024 Vector::set_value(dods_float32 *val, int sz)
01025 {
01026     if (var()->type() == dods_float32_c && val) {
01027         _buf = reinterpret_cast<char*>(new dods_float32[sz]) ;
01028         memcpy(_buf, val, sz * sizeof(dods_float32));
01029         set_read_p(true);
01030         return true;
01031     }
01032     else {
01033         return false;
01034     }
01035 }
01036 
01038 bool
01039 Vector::set_value(vector<dods_float32> &val, int sz)
01040 {
01041     if (var()->type() == dods_float32_c) {
01042         dods_float32 *tmp_buf = new dods_float32[sz] ;
01043         _buf = reinterpret_cast<char*>(tmp_buf) ;
01044         for (register int t = 0; t < sz; t++) {
01045             tmp_buf[t] = val[t] ;
01046         }
01047         set_read_p(true);
01048         return true;
01049     }
01050     else {
01051         return false;
01052     }
01053 }
01054 
01056 bool
01057 Vector::set_value(dods_float64 *val, int sz)
01058 {
01059     if (!val)
01060         return false;
01061 
01062     switch (var()->type()) {
01063     case dods_float64_c:
01064         _buf = reinterpret_cast<char*>(new dods_float64[sz]) ;
01065         memcpy(_buf, val, sz * sizeof(dods_float64));
01066         set_read_p(true);
01067         return true;
01068     default:
01069         return false;
01070     }
01071 }
01072 
01074 bool
01075 Vector::set_value(vector<dods_float64> &val, int sz)
01076 {
01077     if (var()->type() == dods_float64_c) {
01078         dods_float64 *tmp_buf = new dods_float64[sz] ;
01079         _buf = reinterpret_cast<char*>(tmp_buf) ;
01080         for (register int t = 0; t < sz; t++) {
01081             tmp_buf[t] = val[t] ;
01082         }
01083         set_read_p(true);
01084         return true;
01085     }
01086     else {
01087         return false;
01088     }
01089 }
01090 
01092 bool
01093 Vector::set_value(string *val, int sz)
01094 {
01095     if ((var()->type() == dods_str_c || var()->type() == dods_url_c) && val) {
01096         d_str.resize(sz);
01097         for (register int t = 0; t < sz; t++) {
01098             d_str[t] = val[t] ;
01099         }
01100         set_length(sz) ;
01101         set_read_p(true);
01102         return true;
01103     }
01104     else {
01105         return false;
01106     }
01107 }
01108 
01110 bool
01111 Vector::set_value(vector<string> &val, int sz)
01112 {
01113     if (var()->type() == dods_str_c || var()->type() == dods_url_c) {
01114         d_str.resize(sz);
01115         for (register int t = 0; t < sz; t++) {
01116             d_str[t] = val[t] ;
01117         }
01118         set_length(sz) ;
01119         set_read_p(true);
01120         return true;
01121     }
01122     else {
01123         return false;
01124     }
01125 }
01127 
01129 
01136 void Vector::value(dods_byte *b) const
01137 {
01138     if (b && _var->type() == dods_byte_c) {
01139         memcpy(b, _buf, length() * sizeof(dods_byte));
01140     }
01141 }
01142 
01144 void Vector::value(dods_uint16 *b) const
01145 {
01146     if (b && _var->type() == dods_uint16_c) {
01147         memcpy(b, _buf, length() * sizeof(dods_uint16));
01148     }
01149 }
01150 
01152 void Vector::value(dods_int16 *b) const
01153 {
01154     if (b && _var->type() == dods_int16_c) {
01155         memcpy(b, _buf, length() * sizeof(dods_int16));
01156     }
01157 }
01158 
01160 void Vector::value(dods_uint32 *b) const
01161 {
01162     if (b && _var->type() == dods_uint32_c) {
01163         memcpy(b, _buf, length() * sizeof(dods_uint32));
01164     }
01165 }
01166 
01168 void Vector::value(dods_int32 *b) const
01169 {
01170     if (b && _var->type() == dods_int32_c) {
01171         memcpy(b, _buf, length() * sizeof(dods_int32));
01172     }
01173 }
01174 
01176 void Vector::value(dods_float32 *b) const
01177 {
01178     if (b && _var->type() == dods_float32_c) {
01179         memcpy(b, _buf, length() * sizeof(dods_float32));
01180     }
01181 }
01182 
01184 void Vector::value(dods_float64 *b) const
01185 {
01186     if (b && _var->type() == dods_float64_c) {
01187         memcpy(b, _buf, length() * sizeof(dods_float64));
01188     }
01189 }
01190 
01192 void Vector::value(vector<string> &b) const
01193 {
01194     if (_var->type() == dods_byte_c)
01195         b = d_str;
01196 }
01197 
01200 void *Vector::value()
01201 {
01202     void *buffer = new char[width()];
01203 
01204     memcpy(buffer, _buf, width());
01205     
01206     return buffer;
01207 }
01209 
01222 void Vector::add_var(BaseType * v, Part)
01223 {
01224     // Delete the current template variable
01225     if( _var )
01226     {
01227         delete _var;
01228         _var = 0 ;
01229     }
01230 
01231     // if 'v' is null, just set _var to null and exit.
01232     if (!v) {
01233         _var = 0;
01234     }
01235     else {
01236         // Jose Garcia
01237         // By getting a copy of this object to be assigned to _var
01238         // we let the owner of 'v' to deallocate it as necessary.
01239         _var = v->ptr_duplicate();
01240 
01241         // If 'v' has a name, use it as the name of the array. If it *is*
01242         // empty, then make sure to copy the array's name to the template
01243         // so that software which uses the template's name will still work.
01244         if (!v->name().empty())
01245             set_name(v->name());
01246         else
01247             _var->set_name(name());
01248 
01249         _var->set_parent(this); // Vector --> child
01250 
01251         DBG(cerr << "Vector::add_var: Added variable " << v << " ("
01252             << v->name() << " " << v->type_name() << ")" << endl);
01253     }
01254 }
01255 
01256 bool Vector::check_semantics(string & msg, bool)
01257 {
01258     return BaseType::check_semantics(msg);
01259 }
01260 
01269 void
01270 Vector::dump(ostream &strm) const
01271 {
01272     strm << DapIndent::LMarg << "Vector::dump - ("
01273     << (void *)this << ")" << endl ;
01274     DapIndent::Indent() ;
01275     BaseType::dump(strm) ;
01276     strm << DapIndent::LMarg << "# elements in vector: " << _length << endl ;
01277     if (_var) {
01278         strm << DapIndent::LMarg << "base type:" << endl ;
01279         DapIndent::Indent() ;
01280         _var->dump(strm) ;
01281         DapIndent::UnIndent() ;
01282     }
01283     else {
01284         strm << DapIndent::LMarg << "base type: not set" << endl ;
01285     }
01286     strm << DapIndent::LMarg << "vector contents:" << endl ;
01287     DapIndent::Indent() ;
01288     for (unsigned i = 0; i < _vec.size(); ++i) {
01289         if (_vec[i])
01290             _vec[i]->dump(strm) ;
01291         else
01292             strm << DapIndent::LMarg << "vec[" << i << "] is null" << endl ;
01293     }
01294     DapIndent::UnIndent() ;
01295     strm << DapIndent::LMarg << "strings:" << endl ;
01296     DapIndent::Indent() ;
01297     for (unsigned i = 0; i < d_str.size(); i++) {
01298         strm << DapIndent::LMarg << d_str[i] << endl ;
01299     }
01300     DapIndent::UnIndent() ;
01301     strm << DapIndent::LMarg << "_buf: " << (void *)_buf << endl ;
01302     DapIndent::UnIndent() ;
01303 }
01304 

Generated on Sat Jan 19 04:05:27 2008 for libdap++ by  doxygen 1.5.4