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 18315 2008-03-03 20:14:44Z 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 (futher 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 
00131 Vector::Vector(const Vector & rhs): BaseType(rhs)
00132 {
00133     DBG2(cerr << "Entering Vector const ctor for object: " << this <<
00134          endl);
00135     DBG2(cerr << "RHS: " << &rhs << endl);
00136 
00137     _duplicate(rhs);
00138 }
00139 
00140 Vector::~Vector()
00141 {
00142     DBG2(cerr << "Entering ~Vector (" << this << ")" << endl);
00143 
00144     delete _var;
00145     _var = 0;
00146 
00147     if (_buf) {
00148         delete[]_buf;
00149         _buf = 0;
00150     }
00151     else {
00152         for (unsigned int i = 0; i < _vec.size(); ++i) {
00153             delete _vec[i];
00154             _vec[i] = 0;
00155         }
00156     }
00157 
00158     DBG2(cerr << "Exiting ~Vector" << endl);
00159 }
00160 
00161 Vector & Vector::operator=(const Vector & rhs)
00162 {
00163     if (this == &rhs)
00164         return *this;
00165 
00166     dynamic_cast < BaseType & >(*this) = rhs;
00167 
00168     _duplicate(rhs);
00169 
00170     return *this;
00171 }
00172 
00173 int Vector::element_count(bool leaves)
00174 {
00175     if (!leaves)
00176         return 1;
00177     else
00178         // var() only works for simple types!
00179         return var(0)->element_count(leaves);
00180 }
00181 
00182 // These mfuncs set the _send_p and _read_p fields of BaseType. They differ
00183 // from BaseType's version in that they set both the Vector object's copy of
00184 // _send_p (_read_p) but also _VAR's copy. This does not matter much when _VAR
00185 // is a scalar, but does matter when it is an aggregate.
00186 
00193 void Vector::set_send_p(bool state)
00194 {
00195     _var->set_send_p(state);
00196     BaseType::set_send_p(state);
00197 }
00198 
00205 void Vector::set_read_p(bool state)
00206 {
00207     _var->set_read_p(state);
00208     BaseType::set_read_p(state);
00209 }
00210 
00228 BaseType *Vector::var(const string & n, bool exact, btp_stack * s)
00229 {
00230     string name = www2id(n);
00231 
00232     // Make sure to check for the case where name is the default (the empty
00233     // string). 9/1/98 jhrg
00234     if (_var->is_constructor_type()) {
00235         if (name == "" || _var->name() == name)
00236             return _var;
00237         else
00238             return _var->var(name, exact, s);
00239     }
00240     else
00241         return _var;
00242 }
00243 
00254 BaseType *Vector::var(const string & n, btp_stack & s)
00255 {
00256     string name = www2id(n);
00257 
00258     if (_var->is_constructor_type())
00259         return _var->var(name, s);
00260     else {
00261         s.push((BaseType *) this);
00262         return _var;
00263     }
00264 }
00265 
00266 // Return a pointer the the BaseType object for element I. If the Vector is
00267 // of a cardinal type, store the Ith element's value in the BaseType
00268 // object. If it is a Vector of a non-cardinal type, then this mfunc returns
00269 // _vec[i].
00270 //
00271 // NB: I defaults to zero.
00272 //
00273 // Returns: A BaseType pointer to the Ith element of the Vector.
00274 
00290 BaseType *Vector::var(unsigned int i)
00291 {
00292 
00293     switch (_var->type()) {
00294     case dods_byte_c:
00295     case dods_int16_c:
00296     case dods_uint16_c:
00297     case dods_int32_c:
00298     case dods_uint32_c:
00299     case dods_float32_c:
00300     case dods_float64_c: {
00301             // Transfer the ith value to the BaseType *_var; There are more
00302             // efficient ways to get a whole array using buf2val() but this is
00303             // an OK way to get a single value or several non-contiguous values.
00304             unsigned int sz = _var->width();
00305             _var->val2buf((char *) _buf + (i * sz));
00306             return _var;
00307             break;
00308         }
00309 
00310     case dods_str_c:
00311     case dods_url_c:
00312         _var->val2buf(&d_str[i]);
00313         return _var;
00314         break;
00315 
00316     case dods_array_c:
00317     case dods_structure_c:
00318     case dods_sequence_c:
00319     case dods_grid_c:
00320         return _vec[i];
00321         break;
00322 
00323     default:
00324         cerr << "Vector::var: Unrecognized type" << endl;
00325     }
00326 
00327     return 0;
00328 }
00329 
00330 // Return: The number of bytes required to store the vector `in a C
00331 // program'. For an array of cardinal types this is the same as the storage
00332 // used by _BUF. For anything else, it is the product of length() and the
00333 // element width(). It turns out that both values can be computed the same
00334 // way.
00335 //
00336 // Returns: The number of bytes used to store the vector.
00337 
00343 unsigned int Vector::width()
00344 {
00345     // Jose Garcia
00346     if (!_var)
00347         throw InternalErr(__FILE__, __LINE__,
00348                           "Cannot get width since *this* object is not holding data.");
00349 
00350     return length() * _var->width();
00351 }
00352 
00353 // Returns: the number of elements in the vector.
00354 
00359 int Vector::length() const
00360 {
00361     return _length;
00362 }
00363 
00364 // set the number of elements in the vector.
00365 //
00366 // Returns: void
00367 
00370 void Vector::set_length(int l)
00371 {
00372     _length = l;
00373 }
00374 
00375 // \e l is the number of elements the vector can hold (e.g., if l == 20, then
00376 // the vector can hold elements 0, .., 19).
00377 
00383 void Vector::vec_resize(int l)
00384 {
00385     _vec.resize((l > 0) ? l : 0, 0);    // Fill with NULLs
00386 }
00387 
00404 void
00405 Vector::intern_data(const string &dataset, ConstraintEvaluator &eval, DDS &dds)
00406 {
00407     if (!read_p())
00408         read(dataset);          // read() throws Error and InternalErr
00409 
00410     // length() is not capacity; it must be set explicitly in read().
00411     int num = length();
00412 
00413     switch (_var->type()) {
00414     case dods_byte_c:
00415     case dods_int16_c:
00416     case dods_uint16_c:
00417     case dods_int32_c:
00418     case dods_uint32_c:
00419     case dods_float32_c:
00420     case dods_float64_c:
00421         // For these cases, read() puts the data into _buf, which is what we
00422         // need to do 'stuff' with the data.
00423         break;
00424         
00425     case dods_str_c:
00426     case dods_url_c:
00427         // For these cases, read() will put the data into d_str[], which is 
00428         // what the transformation classes need.
00429         break;
00430 
00431     case dods_array_c:
00432         // I think this is an error since there can never be an Array of 
00433         // Array.
00434         throw InternalErr(__FILE__, __LINE__, "Array of Array not supported.");
00435         break;
00436         
00437     case dods_structure_c:
00438     case dods_sequence_c:
00439     case dods_grid_c:
00440         // For these cases, we need to call read() for each of the 'num' 
00441         // elements in the '_vec[]' array of BaseType object pointers.
00442         if (_vec.capacity() == 0)
00443             throw InternalErr(__FILE__, __LINE__,
00444                               "The capacity of *this* vector is 0.");
00445 
00446         for (int i = 0; i < num; ++i)
00447             _vec[i]->intern_data(dataset, eval, dds);
00448 
00449         break;
00450 
00451     default:
00452         throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
00453         break;
00454     }
00455 }
00456 
00469 bool Vector::serialize(const string & dataset, ConstraintEvaluator & eval,
00470                        DDS & dds, Marshaller &m, bool ce_eval)
00471 {
00472     int i = 0;
00473 
00474     dds.timeout_on();
00475 
00476     if (!read_p())
00477         read(dataset);          // read() throws Error and InternalErr
00478 
00479 #if EVAL
00480     if (ce_eval && !eval.eval_selection(dds, dataset))
00481         return true;
00482 #endif
00483 
00484     dds.timeout_off();
00485 
00486     // length() is not capacity; it must be set explicitly in read().
00487     int num = length();
00488 
00489     switch (_var->type()) {
00490     case dods_byte_c:
00491         m.put_vector( _buf, num, *this ) ;
00492         break ;
00493     case dods_int16_c:
00494     case dods_uint16_c:
00495     case dods_int32_c:
00496     case dods_uint32_c:
00497     case dods_float32_c:
00498     case dods_float64_c:
00499         m.put_vector( _buf, num, _var->width(), *this ) ;
00500         break;
00501 
00502     case dods_str_c:
00503     case dods_url_c:
00504         if (d_str.capacity() == 0)
00505             throw InternalErr(__FILE__, __LINE__,
00506                               "The capacity of the string vector is 0");
00507 
00508         m.put_int( num ) ;
00509 
00510         for (i = 0; i < num; ++i)
00511             m.put_str( d_str[i] ) ;
00512 
00513         break;
00514 
00515     case dods_array_c:
00516     case dods_structure_c:
00517     case dods_sequence_c:
00518     case dods_grid_c:
00519         //Jose Garcia
00520         // Not setting the capacity of _vec is an internal error.
00521         if (_vec.capacity() == 0)
00522             throw InternalErr(__FILE__, __LINE__,
00523                               "The capacity of *this* vector is 0.");
00524 
00525         m.put_int( num ) ;
00526 
00527         for (i = 0; i < num; ++i)
00528             _vec[i]->serialize(dataset, eval, dds, m, false);
00529 
00530         break;
00531 
00532     default:
00533         throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
00534         break;
00535     }
00536 
00537     return true;
00538 }
00539 
00540 // Read an object from the network and internalize it. For a Vector this is
00541 // handled differently for a `cardinal' type. Vectors of Cardinals are
00542 // stored using the `C' representations because these objects often are used
00543 // to build huge arrays (e.g., an array of 1024 by 1024 bytes). However,
00544 // arrays of non-cardinal types are stored as Vectors of the C++ objects or
00545 // DAP2 objects (Str and Url are vectors of the string class, Structure, ...,
00546 // Grid are vectors of the libdap Structure, ... classes).
00547 //
00548 // The boolean parameter REUSE determines whether internal storage is reused
00549 // or not. If true, the _buf member is assumed to be large enough to hold the
00550 // incoming cardinal data and is *not* reallocated. If false, new storage is
00551 // allocated. If the internal buffer has not yet been allocated, then this
00552 // parameter has no effect (i.e., storage is allocated). This parameter
00553 // effects storage for cardinal data only.
00554 //
00555 // Returns: True is successful, false otherwise.
00556 
00557 bool Vector::deserialize(UnMarshaller &um, DDS * dds, bool reuse)
00558 {
00559 #if 0
00560     // status no longer used. jhrg 8/28/07
00561     bool status;
00562 #endif
00563     unsigned int num;
00564     unsigned i = 0;
00565 
00566     switch (_var->type()) {
00567     case dods_byte_c:
00568     case dods_int16_c:
00569     case dods_uint16_c:
00570     case dods_int32_c:
00571     case dods_uint32_c:
00572     case dods_float32_c:
00573     case dods_float64_c:
00574         if (_buf && !reuse)
00575             delete[]_buf;
00576         _buf = 0;
00577 
00578         um.get_int( (int &)num ) ;
00579 
00580         DBG(cerr << "Vector::deserialize: num = " << num << endl);
00581         DBG(cerr << "Vector::deserialize: length = " << length() << endl);
00582 
00583         if (length() == -1)
00584             set_length(num);
00585 
00586         if (num != (unsigned int) length())
00587             throw InternalErr(__FILE__, __LINE__, "The server sent declarations and data with mismatched sizes.");
00588 
00589         if (!_buf) {
00590             _buf = new char[width()];   // we always do the allocation!
00591             DBG(cerr << "Vector::deserialize: allocating "
00592                 << width() << " bytes for an array of "
00593                 << length() << " " << _var->type_name() << endl);
00594         }
00595 
00596         if (_var->type() == dods_byte_c)
00597             um.get_vector( (char **)&_buf, num, *this ) ;
00598         else
00599             um.get_vector( (char **)&_buf, num, _var->width(), *this ) ;
00600 
00601         DBG(cerr << "Vector::deserialize: read " << num << " elements\n");
00602 
00603         break;
00604 
00605     case dods_str_c:
00606     case dods_url_c:
00607         um.get_int( (int &)num ) ;
00608 
00609         if (length() == -1)
00610             set_length(num);
00611 
00612         if (num != (unsigned int) length())
00613             throw InternalErr(__FILE__, __LINE__,
00614                               "The client sent declarations and data with mismatched sizes.");
00615 
00616         d_str.resize((num > 0) ? num : 0);      // Fill with NULLs
00617 
00618         for (i = 0; i < num; ++i) {
00619             string str;
00620             um.get_str( str ) ;
00621             d_str[i] = str;
00622 
00623         }
00624 
00625         break;
00626 
00627     case dods_array_c:
00628     case dods_structure_c:
00629     case dods_sequence_c:
00630     case dods_grid_c:
00631         um.get_int( (int &)num ) ;
00632 
00633         if (length() == -1)
00634             set_length(num);
00635 
00636         if (num != (unsigned int) length())
00637             throw InternalErr(__FILE__, __LINE__, "The client sent declarations and data with mismatched sizes.");
00638 
00639         vec_resize(num);
00640 
00641         for (i = 0; i < num; ++i) {
00642             _vec[i] = _var->ptr_duplicate();
00643             _vec[i]->deserialize(um, dds);
00644         }
00645 
00646         break;
00647 
00648     default:
00649         throw InternalErr(__FILE__, __LINE__, "Unknow type!");
00650         break;
00651     }
00652 
00653     return false;
00654 }
00655 
00683 unsigned int Vector::val2buf(void *val, bool reuse)
00684 {
00685     // Jose Garcia
00686 
00687     // I *think* this method has been mainly designed to be use by read which
00688     // is implemented in the surrogate library. Passing NULL as a pointer to
00689     // this method will be an error of the creator of the surrogate library.
00690     // Even though I recognize the fact that some methods inside libdap++ can
00691     // call val2buf, I think by now no coding bugs such as missusing val2buf
00692     // will be in libdap++, so it will be an internal error from the
00693     // surrogate library.
00694     if (!val)
00695         throw InternalErr(__FILE__, __LINE__,
00696                           "The incoming pointer does not contain any data.");
00697 
00698     switch (_var->type()) {
00699     case dods_byte_c:
00700     case dods_int16_c:
00701     case dods_uint16_c:
00702     case dods_int32_c:
00703     case dods_uint32_c:
00704     case dods_float32_c:
00705     case dods_float64_c: {
00706             // width() returns the size given the constraint
00707             unsigned int array_wid = width();
00708             if (_buf && !reuse) {
00709                 delete[]_buf;
00710                 _buf = 0;
00711             }
00712 
00713             if (!_buf) {        // First time or no reuse (free'd above)
00714                 _buf = new char[array_wid];
00715             }
00716 
00717             memcpy(_buf, val, array_wid);
00718             break;
00719         }
00720 
00721     case dods_str_c:
00722     case dods_url_c: {
00723             // Assume val points to an array of C++ string objects. Copy
00724             // them into the vector<string> field of this object.
00725             d_str.resize(_length);
00726             for (int i = 0; i < _length; ++i)
00727                 d_str[i] = *(static_cast < string * >(val) + i);
00728 
00729             break;
00730         }
00731 
00732     default:
00733         throw InternalErr(__FILE__, __LINE__, "Vector::val2buf: bad type");
00734 
00735     }
00736 
00737     return width();
00738 }
00739 
00770 unsigned int Vector::buf2val(void **val)
00771 {
00772     // Jose Garcia
00773     // The same comment in Vector::val2buf applies here!
00774     if (!val)
00775         throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
00776 
00777     unsigned int wid = static_cast<unsigned int>(width());
00778     // This is the width computed using length(). The
00779     // length() property is changed when a projection
00780     // constraint is applied. Thus this is the number of
00781     // bytes in the buffer given the current constraint.
00782 
00783     switch (_var->type()) {
00784     case dods_byte_c:
00785     case dods_int16_c:
00786     case dods_uint16_c:
00787     case dods_int32_c:
00788     case dods_uint32_c:
00789     case dods_float32_c:
00790     case dods_float64_c:
00791         if (!*val)
00792             *val = new char[wid];
00793 
00794         (void) memcpy(*val, _buf, wid);
00795 
00796         break;
00797 
00798     case dods_str_c:
00799     case dods_url_c: {
00800             if (!*val)
00801                 *val = new string[_length];
00802 
00803             for (int i = 0; i < _length; ++i)
00804                 *(static_cast < string * >(*val) + i) = d_str[i];
00805 
00806             break;
00807         }
00808 
00809     default:
00810         throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: bad type");
00811         return 0;
00812     }
00813 
00814     return wid;
00815 }
00816 
00837 void Vector::set_vec(unsigned int i, BaseType * val)
00838 {
00839     // Jose Garcia
00840     // This is a public method which allows users to set the elements
00841     // of *this* vector. Passing an invalid index, a NULL pointer or
00842     // missmatching the vector type are internal errors.
00843     if (i >= static_cast < unsigned int >(_length))
00844         throw InternalErr(__FILE__, __LINE__,
00845                           "Invalid data: index too large.");
00846     if (!val)
00847         throw InternalErr(__FILE__, __LINE__,
00848                           "Invalid data: null pointer to BaseType object.");
00849     if (val->type() != _var->type())
00850         throw InternalErr(__FILE__, __LINE__,
00851                           "invalid data: type of incoming object does not match *this* vector type.");
00852 
00853     if (i >= _vec.capacity())
00854         vec_resize(i + 10);
00855 
00856     _vec[i] = val->ptr_duplicate();
00857 }
00858 
00859 
00861 
00862 bool
00863 Vector::set_value(dods_byte *val, int sz)
00864 {
00865     if (var()->type() == dods_byte_c && val) {
00866         _buf = reinterpret_cast<char*>(new dods_byte[sz]) ;
00867         memcpy(_buf, val, sz * sizeof(dods_byte));
00868         set_read_p(true);
00869         return true;
00870     }
00871     else {
00872         return false;
00873     }
00874 }
00875 
00877 bool
00878 Vector::set_value(vector<dods_byte> &val, int sz)
00879 {
00880     if (var()->type() == dods_byte_c) {
00881         dods_byte *tmp_buf = new dods_byte[sz] ;
00882         _buf = reinterpret_cast<char*>(tmp_buf) ;
00883         for (register int t = 0; t < sz; t++) {
00884             tmp_buf[t] = val[t] ;
00885         }
00886         set_read_p(true);
00887         return true;
00888     }
00889     else {
00890         return false;
00891     }
00892 }
00893 
00895 bool
00896 Vector::set_value(dods_int16 *val, int sz)
00897 {
00898     if (var()->type() == dods_int16_c && val) {
00899         _buf = reinterpret_cast<char*>(new dods_int16[sz]) ;
00900         memcpy(_buf, val, sz * sizeof(dods_int16));
00901         set_read_p(true);
00902         return true;
00903     }
00904     else {
00905         return false;
00906     }
00907 }
00908 
00910 bool
00911 Vector::set_value(vector<dods_int16> &val, int sz)
00912 {
00913     if (var()->type() == dods_int16_c) {
00914         dods_int16 *tmp_buf = new dods_int16[sz] ;
00915         _buf = reinterpret_cast<char*>(tmp_buf) ;
00916         for (register int t = 0; t < sz; t++) {
00917             tmp_buf[t] = val[t] ;
00918         }
00919         set_read_p(true);
00920         return true;
00921     }
00922     else {
00923         return false;
00924     }
00925 }
00926 
00928 bool
00929 Vector::set_value(dods_int32 *val, int sz)
00930 {
00931     if (var()->type() == dods_int32_c && val) {
00932         _buf = reinterpret_cast<char*>(new dods_int32[sz]) ;
00933         memcpy(_buf, val, sz * sizeof(dods_int32));
00934         set_read_p(true);
00935         return true;
00936     }
00937     else {
00938         return false;
00939     }
00940 }
00941 
00943 bool
00944 Vector::set_value(vector<dods_int32> &val, int sz)
00945 {
00946     if (var()->type() == dods_int32_c) {
00947         dods_int32 *tmp_buf = new dods_int32[sz] ;
00948         _buf = reinterpret_cast<char*>(tmp_buf) ;
00949         for (register int t = 0; t < sz; t++) {
00950             tmp_buf[t] = val[t] ;
00951         }
00952         set_read_p(true);
00953         return true;
00954     }
00955     else {
00956         return false;
00957     }
00958 }
00959 
00961 bool
00962 Vector::set_value(dods_uint16 *val, int sz)
00963 {
00964     if (var()->type() == dods_uint16_c && val) {
00965         _buf = reinterpret_cast<char*>(new dods_uint16[sz]) ;
00966         memcpy(_buf, val, sz * sizeof(dods_uint16));
00967         set_read_p(true);
00968         return true;
00969     }
00970     else {
00971         return false;
00972     }
00973 }
00974 
00976 bool
00977 Vector::set_value(vector<dods_uint16> &val, int sz)
00978 {
00979     if (var()->type() == dods_uint16_c) {
00980         dods_uint16 *tmp_buf = new dods_uint16[sz] ;
00981         _buf = reinterpret_cast<char*>(tmp_buf) ;
00982         for (register int t = 0; t < sz; t++) {
00983             tmp_buf[t] = val[t] ;
00984         }
00985         set_read_p(true);
00986         return true;
00987     }
00988     else {
00989         return false;
00990     }
00991 }
00992 
00994 bool
00995 Vector::set_value(dods_uint32 *val, int sz)
00996 {
00997     if (var()->type() == dods_uint32_c && val) {
00998         _buf = reinterpret_cast<char*>(new dods_uint32[sz]) ;
00999         memcpy(_buf, val, sz * sizeof(dods_uint32));
01000         set_read_p(true);
01001         return true;
01002     }
01003     else {
01004         return false;
01005     }
01006 }
01007 
01009 bool
01010 Vector::set_value(vector<dods_uint32> &val, int sz)
01011 {
01012     if (var()->type() == dods_uint32_c) {
01013         dods_uint32 *tmp_buf = new dods_uint32[sz] ;
01014         _buf = reinterpret_cast<char*>(tmp_buf) ;
01015         for (register int t = 0; t < sz; t++) {
01016             tmp_buf[t] = val[t] ;
01017         }
01018         set_read_p(true);
01019         return true;
01020     }
01021     else {
01022         return false;
01023     }
01024 }
01025 
01027 bool
01028 Vector::set_value(dods_float32 *val, int sz)
01029 {
01030     if (var()->type() == dods_float32_c && val) {
01031         _buf = reinterpret_cast<char*>(new dods_float32[sz]) ;
01032         memcpy(_buf, val, sz * sizeof(dods_float32));
01033         set_read_p(true);
01034         return true;
01035     }
01036     else {
01037         return false;
01038     }
01039 }
01040 
01042 bool
01043 Vector::set_value(vector<dods_float32> &val, int sz)
01044 {
01045     if (var()->type() == dods_float32_c) {
01046         dods_float32 *tmp_buf = new dods_float32[sz] ;
01047         _buf = reinterpret_cast<char*>(tmp_buf) ;
01048         for (register int t = 0; t < sz; t++) {
01049             tmp_buf[t] = val[t] ;
01050         }
01051         set_read_p(true);
01052         return true;
01053     }
01054     else {
01055         return false;
01056     }
01057 }
01058 
01060 bool
01061 Vector::set_value(dods_float64 *val, int sz)
01062 {
01063     if (!val)
01064         return false;
01065 
01066     switch (var()->type()) {
01067     case dods_float64_c:
01068         _buf = reinterpret_cast<char*>(new dods_float64[sz]) ;
01069         memcpy(_buf, val, sz * sizeof(dods_float64));
01070         set_read_p(true);
01071         return true;
01072     default:
01073         return false;
01074     }
01075 }
01076 
01078 bool
01079 Vector::set_value(vector<dods_float64> &val, int sz)
01080 {
01081     if (var()->type() == dods_float64_c) {
01082         dods_float64 *tmp_buf = new dods_float64[sz] ;
01083         _buf = reinterpret_cast<char*>(tmp_buf) ;
01084         for (register int t = 0; t < sz; t++) {
01085             tmp_buf[t] = val[t] ;
01086         }
01087         set_read_p(true);
01088         return true;
01089     }
01090     else {
01091         return false;
01092     }
01093 }
01094 
01096 bool
01097 Vector::set_value(string *val, int sz)
01098 {
01099     if ((var()->type() == dods_str_c || var()->type() == dods_url_c) && val) {
01100         d_str.resize(sz);
01101         for (register int t = 0; t < sz; t++) {
01102             d_str[t] = val[t] ;
01103         }
01104         set_length(sz) ;
01105         set_read_p(true);
01106         return true;
01107     }
01108     else {
01109         return false;
01110     }
01111 }
01112 
01114 bool
01115 Vector::set_value(vector<string> &val, int sz)
01116 {
01117     if (var()->type() == dods_str_c || var()->type() == dods_url_c) {
01118         d_str.resize(sz);
01119         for (register int t = 0; t < sz; t++) {
01120             d_str[t] = val[t] ;
01121         }
01122         set_length(sz) ;
01123         set_read_p(true);
01124         return true;
01125     }
01126     else {
01127         return false;
01128     }
01129 }
01131 
01133 
01140 void Vector::value(dods_byte *b) const
01141 {
01142     if (b && _var->type() == dods_byte_c) {
01143         memcpy(b, _buf, length() * sizeof(dods_byte));
01144     }
01145 }
01146 
01148 void Vector::value(dods_uint16 *b) const
01149 {
01150     if (b && _var->type() == dods_uint16_c) {
01151         memcpy(b, _buf, length() * sizeof(dods_uint16));
01152     }
01153 }
01154 
01156 void Vector::value(dods_int16 *b) const
01157 {
01158     if (b && _var->type() == dods_int16_c) {
01159         memcpy(b, _buf, length() * sizeof(dods_int16));
01160     }
01161 }
01162 
01164 void Vector::value(dods_uint32 *b) const
01165 {
01166     if (b && _var->type() == dods_uint32_c) {
01167         memcpy(b, _buf, length() * sizeof(dods_uint32));
01168     }
01169 }
01170 
01172 void Vector::value(dods_int32 *b) const
01173 {
01174     if (b && _var->type() == dods_int32_c) {
01175         memcpy(b, _buf, length() * sizeof(dods_int32));
01176     }
01177 }
01178 
01180 void Vector::value(dods_float32 *b) const
01181 {
01182     if (b && _var->type() == dods_float32_c) {
01183         memcpy(b, _buf, length() * sizeof(dods_float32));
01184     }
01185 }
01186 
01188 void Vector::value(dods_float64 *b) const
01189 {
01190     if (b && _var->type() == dods_float64_c) {
01191         memcpy(b, _buf, length() * sizeof(dods_float64));
01192     }
01193 }
01194 
01196 void Vector::value(vector<string> &b) const
01197 {
01198     if (_var->type() == dods_byte_c)
01199         b = d_str;
01200 }
01201 
01204 void *Vector::value()
01205 {
01206     void *buffer = new char[width()];
01207 
01208     memcpy(buffer, _buf, width());
01209     
01210     return buffer;
01211 }
01213 
01226 void Vector::add_var(BaseType * v, Part)
01227 {
01228     // Delete the current template variable
01229     if( _var )
01230     {
01231         delete _var;
01232         _var = 0 ;
01233     }
01234 
01235     // if 'v' is null, just set _var to null and exit.
01236     if (!v) {
01237         _var = 0;
01238     }
01239     else {
01240         // Jose Garcia
01241         // By getting a copy of this object to be assigned to _var
01242         // we let the owner of 'v' to deallocate it as necessary.
01243         _var = v->ptr_duplicate();
01244 
01245         // If 'v' has a name, use it as the name of the array. If it *is*
01246         // empty, then make sure to copy the array's name to the template
01247         // so that software which uses the template's name will still work.
01248         if (!v->name().empty())
01249             set_name(v->name());
01250         else
01251             _var->set_name(name());
01252 
01253         _var->set_parent(this); // Vector --> child
01254 
01255         DBG(cerr << "Vector::add_var: Added variable " << v << " ("
01256             << v->name() << " " << v->type_name() << ")" << endl);
01257     }
01258 }
01259 
01260 bool Vector::check_semantics(string & msg, bool)
01261 {
01262     return BaseType::check_semantics(msg);
01263 }
01264 
01273 void
01274 Vector::dump(ostream &strm) const
01275 {
01276     strm << DapIndent::LMarg << "Vector::dump - ("
01277     << (void *)this << ")" << endl ;
01278     DapIndent::Indent() ;
01279     BaseType::dump(strm) ;
01280     strm << DapIndent::LMarg << "# elements in vector: " << _length << endl ;
01281     if (_var) {
01282         strm << DapIndent::LMarg << "base type:" << endl ;
01283         DapIndent::Indent() ;
01284         _var->dump(strm) ;
01285         DapIndent::UnIndent() ;
01286     }
01287     else {
01288         strm << DapIndent::LMarg << "base type: not set" << endl ;
01289     }
01290     strm << DapIndent::LMarg << "vector contents:" << endl ;
01291     DapIndent::Indent() ;
01292     for (unsigned i = 0; i < _vec.size(); ++i) {
01293         if (_vec[i])
01294             _vec[i]->dump(strm) ;
01295         else
01296             strm << DapIndent::LMarg << "vec[" << i << "] is null" << endl ;
01297     }
01298     DapIndent::UnIndent() ;
01299     strm << DapIndent::LMarg << "strings:" << endl ;
01300     DapIndent::Indent() ;
01301     for (unsigned i = 0; i < d_str.size(); i++) {
01302         strm << DapIndent::LMarg << d_str[i] << endl ;
01303     }
01304     DapIndent::UnIndent() ;
01305     if( _buf )
01306     {
01307         switch( _var->type() )
01308         {
01309             case dods_byte_c:
01310             {
01311                 strm << DapIndent::LMarg << "_buf: " ;
01312                 strm.write( _buf, _length ) ;
01313                 strm << endl ;
01314             }
01315             break ;
01316             default:
01317             {
01318                 strm << DapIndent::LMarg << "_buf: " << (void *)_buf << endl ;
01319             }
01320             break ;
01321         }
01322     }
01323     else
01324     {
01325         strm << DapIndent::LMarg << "_buf: EMPTY" << endl ;
01326     }
01327     DapIndent::UnIndent() ;
01328 }
01329 
01330 } // namespace libdap
01331 

Generated on Tue Jun 10 18:00:31 2008 for libdap++ by  doxygen 1.5.4