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 16466 2007-05-14 17:41:27Z jimg $"
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 
00397 bool Vector::serialize(const string & dataset, ConstraintEvaluator & eval,
00398                        DDS & dds, XDR * sink, bool ce_eval)
00399 {
00400     int i = 0;
00401 
00402     dds.timeout_on();
00403 
00404     if (!read_p())
00405         read(dataset);          // read() throws Error and InternalErr
00406 
00407 #if EVAL
00408     if (ce_eval && !eval.eval_selection(dds, dataset))
00409         return true;
00410 #endif
00411 
00412     dds.timeout_off();
00413 
00414     // length() is not capacity; it must be set explicitly in read().
00415     int num = length();
00416 
00417     switch (_var->type()) {
00418     case dods_byte_c:
00419     case dods_int16_c:
00420     case dods_uint16_c:
00421     case dods_int32_c:
00422     case dods_uint32_c:
00423     case dods_float32_c:
00424     case dods_float64_c:
00425         // Jose Garcia
00426         // If we are trying to serialize data and the internal buffer is
00427         // unset, then the read method failed to do its job.
00428         if (!_buf)
00429             throw InternalErr(__FILE__, __LINE__,
00430                               "Buffer pointer is not set.");
00431 
00432         if ((0 == xdr_int(sink,  &num))) // send vector length
00433             throw Error("Network I/O Error(1). This may be due to a bug in libdap or a\nproblem with the network connection.");
00434 
00435         // Note that xdr_bytes and xdr_array both send the length themselves,
00436         // so the length is actually sent twice. 12/31/99 jhrg
00437         bool status;
00438         if (_var->type() == dods_byte_c)
00439             status = (0 != xdr_bytes(sink, (char **) & _buf,
00440                                      (unsigned int *) & num,
00441                                      DODS_MAX_ARRAY));
00442         else
00443             status = (0 != xdr_array(sink, (char **) & _buf,
00444                                      (unsigned int *) & num,
00445                                      DODS_MAX_ARRAY, _var->width(),
00446                                      (xdrproc_t)(_var->xdr_coder())));
00447         if (!status)
00448             throw Error("Network I/O Error(2). This may be due to a bug in libdap or a\nproblem with the network connection.");
00449 
00450         break;
00451 
00452     case dods_str_c:
00453     case dods_url_c:
00454         if (d_str.capacity() == 0)
00455             throw InternalErr(__FILE__, __LINE__,
00456                               "The capacity of the string vector is 0");
00457 
00458         if ((0 == xdr_int(sink, (int *) &num)))
00459             throw Error("Network I/O Error(3). This may be due to a bug in libdap or a\nproblem with the network connection.");
00460 
00461         for (i = 0; i < num; ++i)
00462             if (!xdr_str(sink, d_str[i]))
00463                 throw Error("Network I/O Error(4). Could not send string data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
00464 
00465         break;
00466 
00467     case dods_array_c:
00468     case dods_structure_c:
00469     case dods_sequence_c:
00470     case dods_grid_c:
00471         //Jose Garcia
00472         // Not setting the capacity of _vec is an internal error.
00473         if (_vec.capacity() == 0)
00474             throw InternalErr(__FILE__, __LINE__,
00475                               "The capacity of *this* vector is 0.");
00476 
00477         if ((0 == xdr_int(sink, &num)))
00478             throw Error("Network I/O Error. This may be due to a bug in libdap or a\nproblem with the network connection.");
00479 
00480         for (i = 0; i < num; ++i)
00481             _vec[i]->serialize(dataset, eval, dds, sink, false);
00482 
00483         break;
00484 
00485     default:
00486         throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
00487         break;
00488     }
00489 
00490     return true;
00491 }
00492 
00493 // Read an object from the network and internalize it. For a Vector this is
00494 // handled differently for a `cardinal' type. Vectors of Cardinals are
00495 // stored using the `C' representations because these objects often are used
00496 // to build huge arrays (e.g., an array of 1024 by 1024 bytes). However,
00497 // arrays of non-cardinal types are stored as Vectors of the C++ objects or
00498 // DAP2 objects (Str and Url are vectors of the string class, Structure, ...,
00499 // Grid are vectors of the libdap Structure, ... classes).
00500 //
00501 // The boolean parameter REUSE determines whether internal storage is reused
00502 // or not. If true, the _buf member is assumed to be large enough to hold the
00503 // incoming cardinal data and is *not* reallocated. If false, new storage is
00504 // allocated. If the internal buffer has not yet been allocated, then this
00505 // parameter has no effect (i.e., storage is allocated). This parameter
00506 // effects storage for cardinal data only.
00507 //
00508 // Returns: True is successful, false otherwise.
00509 
00510 bool Vector::deserialize(XDR * source, DDS * dds, bool reuse)
00511 {
00512     bool status;
00513     unsigned int num;
00514     unsigned i = 0;
00515 
00516     switch (_var->type()) {
00517     case dods_byte_c:
00518     case dods_int16_c:
00519     case dods_uint16_c:
00520     case dods_int32_c:
00521     case dods_uint32_c:
00522     case dods_float32_c:
00523     case dods_float64_c:
00524         if (_buf && !reuse)
00525             delete[]_buf;
00526         _buf = 0;
00527 
00528         if ((0 == xdr_int(source, (int *) &num)))
00529             throw Error("Network I/O error. Could not read the array length.\nThis may be due to a bug in libdap or a problem with\nthe network connection.");
00530 
00531         DBG(cerr << "Vector::deserialize: num = " << num << endl);
00532         DBG(cerr << "Vector::deserialize: length = " << length() << endl);
00533 
00534         if (length() == -1)
00535             set_length(num);
00536 
00537         if (num != (unsigned int) length())
00538             throw InternalErr(__FILE__, __LINE__, "The server sent declarations and data with mismatched sizes.");
00539 
00540         if (!_buf) {
00541             _buf = new char[width()];   // we always do the allocation!
00542             DBG(cerr << "Vector::deserialize: allocating "
00543                 << width() << " bytes for an array of "
00544                 << length() << " " << _var->type_name() << endl);
00545         }
00546 
00547         if (_var->type() == dods_byte_c)
00548             status = (0 != xdr_bytes(source, (char **) & _buf, &num,
00549                                      DODS_MAX_ARRAY));
00550         else
00551             status = (0 != xdr_array(source, (char **) & _buf, &num,
00552                                      DODS_MAX_ARRAY, _var->width(),
00553                                      (xdrproc_t)(_var->xdr_coder())));
00554 
00555         if (!status)
00556             throw Error("Network I/O error. Could not read packed array data.\nThis may be due to a bug in libdap or a problem with\nthe network connection.");
00557 
00558         DBG(cerr << "Vector::deserialize: read " << num << " elements\n");
00559 
00560         break;
00561 
00562     case dods_str_c:
00563     case dods_url_c:
00564         if ((0 == xdr_int(source, (int *) &num)))
00565             throw Error("Network I/O error. Could not read the array length.\nThis may be due to a bug in libdap or a problem with\nthe network connection.");
00566 
00567         if (length() == -1)
00568             set_length(num);
00569 
00570         if (num != (unsigned int) length())
00571             throw InternalErr(__FILE__, __LINE__,
00572                               "The client sent declarations and data with mismatched sizes.");
00573 
00574         d_str.resize((num > 0) ? num : 0);      // Fill with NULLs
00575 
00576         for (i = 0; i < num; ++i) {
00577             string str;
00578             if (!xdr_str(source, str))
00579                 throw Error("Network I/O Error. Could not read string data. This may be due to a\nbug in libdap or a problem with the network connection.");
00580             d_str[i] = str;
00581 
00582         }
00583 
00584         break;
00585 
00586     case dods_array_c:
00587     case dods_structure_c:
00588     case dods_sequence_c:
00589     case dods_grid_c:
00590         if ((0 == xdr_int(source, (int *) &num)))
00591             throw Error("Network I/O error. Could not read the array length.\nThis may be due to a bug in libdap or a problem with\nthe network connection.");
00592 
00593         if (length() == -1)
00594             set_length(num);
00595 
00596         if (num != (unsigned int) length())
00597             throw InternalErr(__FILE__, __LINE__, "The client sent declarations and data with mismatched sizes.");
00598 
00599         vec_resize(num);
00600 
00601         for (i = 0; i < num; ++i) {
00602             _vec[i] = _var->ptr_duplicate();
00603             _vec[i]->deserialize(source, dds);
00604         }
00605 
00606         break;
00607 
00608     default:
00609         throw InternalErr(__FILE__, __LINE__, "Unknow type!");
00610         break;
00611     }
00612 
00613     return false;
00614 }
00615 
00643 unsigned int Vector::val2buf(void *val, bool reuse)
00644 {
00645     // Jose Garcia
00646 
00647     // I *think* this method has been mainly designed to be use by read which
00648     // is implemented in the surrogate library. Passing NULL as a pointer to
00649     // this method will be an error of the creator of the surrogate library.
00650     // Even though I recognize the fact that some methods inside libdap++ can
00651     // call val2buf, I think by now no coding bugs such as missusing val2buf
00652     // will be in libdap++, so it will be an internal error from the
00653     // surrogate library.
00654     if (!val)
00655         throw InternalErr(__FILE__, __LINE__,
00656                           "The incoming pointer does not contain any data.");
00657 
00658     switch (_var->type()) {
00659     case dods_byte_c:
00660     case dods_int16_c:
00661     case dods_uint16_c:
00662     case dods_int32_c:
00663     case dods_uint32_c:
00664     case dods_float32_c:
00665     case dods_float64_c: {
00666             // width() returns the size given the constraint
00667             unsigned int array_wid = width();
00668             if (_buf && !reuse) {
00669                 delete[]_buf;
00670                 _buf = 0;
00671             }
00672 
00673             if (!_buf) {        // First time or no reuse (free'd above)
00674                 _buf = new char[array_wid];
00675             }
00676 
00677             memcpy(_buf, val, array_wid);
00678             break;
00679         }
00680 
00681     case dods_str_c:
00682     case dods_url_c: {
00683             // Assume val points to an array of C++ string objects. Copy
00684             // them into the vector<string> field of this object.
00685             d_str.resize(_length);
00686             for (int i = 0; i < _length; ++i)
00687                 d_str[i] = *(static_cast < string * >(val) + i);
00688 
00689             break;
00690         }
00691 
00692     default:
00693         throw InternalErr(__FILE__, __LINE__, "Vector::val2buf: bad type");
00694 
00695     }
00696 
00697     return width();
00698 }
00699 
00730 unsigned int Vector::buf2val(void **val)
00731 {
00732     // Jose Garcia
00733     // The same comment in Vector::val2buf applies here!
00734     if (!val)
00735         throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
00736 
00737     int wid = width();          // This is the width computed using length(). The
00738     // length() property is changed when a projection
00739     // constraint is applied. Thus this is the number of
00740     // bytes in the buffer given the current constraint.
00741 
00742     switch (_var->type()) {
00743     case dods_byte_c:
00744     case dods_int16_c:
00745     case dods_uint16_c:
00746     case dods_int32_c:
00747     case dods_uint32_c:
00748     case dods_float32_c:
00749     case dods_float64_c:
00750         if (!*val)
00751             *val = new char[wid];
00752 
00753         (void) memcpy(*val, _buf, wid);
00754 
00755         break;
00756 
00757     case dods_str_c:
00758     case dods_url_c: {
00759             if (!*val)
00760                 *val = new string[_length];
00761 
00762             for (int i = 0; i < _length; ++i)
00763                 *(static_cast < string * >(*val) + i) = d_str[i];
00764 
00765             break;
00766         }
00767 
00768     default:
00769         throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: bad type");
00770         return 0;
00771     }
00772 
00773     return wid;
00774 }
00775 
00796 void Vector::set_vec(unsigned int i, BaseType * val)
00797 {
00798     // Jose Garcia
00799     // This is a public method which allows users to set the elements
00800     // of *this* vector. Passing an invalid index, a NULL pointer or
00801     // missmatching the vector type are internal errors.
00802     if (i >= static_cast < unsigned int >(_length))
00803         throw InternalErr(__FILE__, __LINE__,
00804                           "Invalid data: index too large.");
00805     if (!val)
00806         throw InternalErr(__FILE__, __LINE__,
00807                           "Invalid data: null pointer to BaseType object.");
00808     if (val->type() != _var->type())
00809         throw InternalErr(__FILE__, __LINE__,
00810                           "invalid data: type of incoming object does not match *this* vector type.");
00811 
00812     if (i >= _vec.capacity())
00813         vec_resize(i + 10);
00814 
00815     _vec[i] = val->ptr_duplicate();
00816 }
00817 
00819 bool
00820 Vector::set_value(dods_byte *val, int sz)
00821 {
00822     if (var()->type() == dods_byte_c && val) {
00823         _buf = reinterpret_cast<char*>(new dods_byte[sz]) ;
00824         memcpy(_buf, val, sz * sizeof(dods_byte));
00825         set_read_p(true);
00826         return true;
00827     }
00828     else {
00829         return false;
00830     }
00831 }
00832 
00834 bool
00835 Vector::set_value(dods_int16 *val, int sz)
00836 {
00837     if (var()->type() == dods_int16_c && val) {
00838         _buf = reinterpret_cast<char*>(new dods_int16[sz]) ;
00839         memcpy(_buf, val, sz * sizeof(dods_int16));
00840         set_read_p(true);
00841         return true;
00842     }
00843     else {
00844         return false;
00845     }
00846 }
00847 
00849 bool
00850 Vector::set_value(dods_int32 *val, int sz)
00851 {
00852     if (var()->type() == dods_int32_c && val) {
00853         _buf = reinterpret_cast<char*>(new dods_int32[sz]) ;
00854         memcpy(_buf, val, sz * sizeof(dods_int32));
00855         set_read_p(true);
00856         return true;
00857     }
00858     else {
00859         return false;
00860     }
00861 }
00862 
00864 bool
00865 Vector::set_value(dods_uint16 *val, int sz)
00866 {
00867     if (var()->type() == dods_uint16_c && val) {
00868         _buf = reinterpret_cast<char*>(new dods_uint16[sz]) ;
00869         memcpy(_buf, val, sz * sizeof(dods_uint16));
00870         set_read_p(true);
00871         return true;
00872     }
00873     else {
00874         return false;
00875     }
00876 }
00877 
00879 bool
00880 Vector::set_value(dods_uint32 *val, int sz)
00881 {
00882     if (var()->type() == dods_uint32_c && val) {
00883         _buf = reinterpret_cast<char*>(new dods_uint32[sz]) ;
00884         memcpy(_buf, val, sz * sizeof(dods_uint32));
00885         set_read_p(true);
00886         return true;
00887     }
00888     else {
00889         return false;
00890     }
00891 }
00892 
00894 bool
00895 Vector::set_value(dods_float32 *val, int sz)
00896 {
00897     if (var()->type() == dods_float32_c && val) {
00898         _buf = reinterpret_cast<char*>(new dods_float32[sz]) ;
00899         memcpy(_buf, val, sz * sizeof(dods_float32));
00900         set_read_p(true);
00901         return true;
00902     }
00903     else {
00904         return false;
00905     }
00906 }
00907 
00909 bool
00910 Vector::set_value(dods_float64 *val, int sz)
00911 {
00912     if (!val)
00913         return false;
00914 
00915     switch (var()->type()) {
00916     case dods_float64_c:
00917         _buf = reinterpret_cast<char*>(new dods_float64[sz]) ;
00918         memcpy(_buf, val, sz * sizeof(dods_float64));
00919         set_read_p(true);
00920         return true;
00921     default:
00922         return false;
00923     }
00924 }
00925 
00927 bool
00928 Vector::set_value(string *val, int sz)
00929 {
00930     if ((var()->type() == dods_str_c || var()->type() == dods_url_c) && val) {
00931         d_str.resize(sz);
00932         for (register int t = 0; t < sz; t++) {
00933             d_str[t] = val[t] ;
00934         }
00935         set_length(sz) ;
00936         set_read_p(true);
00937         return true;
00938     }
00939     else {
00940         return false;
00941     }
00942 }
00943 
00945 void Vector::value(dods_byte *b) const
00946 {
00947     if (b && _var->type() == dods_byte_c) {
00948         memcpy(b, _buf, length() * sizeof(dods_byte));
00949     }
00950 }
00951 
00953 void Vector::value(dods_uint16 *b) const
00954 {
00955     if (b && _var->type() == dods_uint16_c) {
00956         memcpy(b, _buf, length() * sizeof(dods_uint16));
00957     }
00958 }
00959 
00961 void Vector::value(dods_int16 *b) const
00962 {
00963     if (b && _var->type() == dods_int16_c) {
00964         memcpy(b, _buf, length() * sizeof(dods_int16));
00965     }
00966 }
00967 
00969 void Vector::value(dods_uint32 *b) const
00970 {
00971     if (b && _var->type() == dods_uint32_c) {
00972         memcpy(b, _buf, length() * sizeof(dods_uint32));
00973     }
00974 }
00975 
00977 void Vector::value(dods_int32 *b) const
00978 {
00979     if (b && _var->type() == dods_int32_c) {
00980         memcpy(b, _buf, length() * sizeof(dods_int32));
00981     }
00982 }
00983 
00985 void Vector::value(dods_float32 *b) const
00986 {
00987     if (b && _var->type() == dods_float32_c) {
00988         memcpy(b, _buf, length() * sizeof(dods_float32));
00989     }
00990 }
00991 
00993 void Vector::value(dods_float64 *b) const
00994 {
00995     if (b && _var->type() == dods_float64_c) {
00996         memcpy(b, _buf, length() * sizeof(dods_float64));
00997     }
00998 }
00999 
01001 void Vector::value(vector<string> &b) const
01002 {
01003     if (_var->type() == dods_byte_c)
01004         b = d_str;
01005 }
01006 
01019 void Vector::add_var(BaseType * v, Part)
01020 {
01021     // Delete the current template variable
01022     delete _var;
01023 
01024     // if 'v' is null, just set _var to null and exit.
01025     if (!v) {
01026         _var = 0;
01027     }
01028     else {
01029         // Jose Garcia
01030         // By getting a copy of this object to be assigned to _var
01031         // we let the owner of 'v' to deallocate it as necessary.
01032         _var = v->ptr_duplicate();
01033 
01034         // If 'v' has a name, use it as the name of the array. If it *is*
01035         // empty, then make sure to copy the array's name to the template
01036         // so that software which uses the template's name will still work.
01037         if (!v->name().empty())
01038             set_name(v->name());
01039         else
01040             _var->set_name(name());
01041 
01042         _var->set_parent(this); // Vector --> child
01043 
01044         DBG(cerr << "Vector::add_var: Added variable " << v << " ("
01045             << v->name() << " " << v->type_name() << ")" << endl);
01046     }
01047 }
01048 
01049 bool Vector::check_semantics(string & msg, bool)
01050 {
01051     return BaseType::check_semantics(msg);
01052 }
01053 
01062 void
01063 Vector::dump(ostream &strm) const
01064 {
01065     strm << DapIndent::LMarg << "Vector::dump - ("
01066     << (void *)this << ")" << endl ;
01067     DapIndent::Indent() ;
01068     BaseType::dump(strm) ;
01069     strm << DapIndent::LMarg << "# elements in vector: " << _length << endl ;
01070     if (_var) {
01071         strm << DapIndent::LMarg << "base type:" << endl ;
01072         DapIndent::Indent() ;
01073         _var->dump(strm) ;
01074         DapIndent::UnIndent() ;
01075     }
01076     else {
01077         strm << DapIndent::LMarg << "base type: not set" << endl ;
01078     }
01079     strm << DapIndent::LMarg << "vector contents:" << endl ;
01080     DapIndent::Indent() ;
01081     for (unsigned i = 0; i < _vec.size(); ++i) {
01082         if (_vec[i])
01083             _vec[i]->dump(strm) ;
01084         else
01085             strm << DapIndent::LMarg << "vec[" << i << "] is null" << endl ;
01086     }
01087     DapIndent::UnIndent() ;
01088     strm << DapIndent::LMarg << "strings:" << endl ;
01089     DapIndent::Indent() ;
01090     for (unsigned i = 0; i < d_str.size(); i++) {
01091         strm << DapIndent::LMarg << d_str[i] << endl ;
01092     }
01093     DapIndent::UnIndent() ;
01094     strm << DapIndent::LMarg << "_buf: " << (void *)_buf << endl ;
01095     DapIndent::UnIndent() ;
01096 }
01097 

Generated on Wed Jun 27 12:56:39 2007 for libdap++ by  doxygen 1.4.7