~ubuntu-branches/ubuntu/vivid/libdap/vivid

« back to all changes in this revision

Viewing changes to Vector.cc

  • Committer: Package Import Robot
  • Author(s): Alastair McKinstry
  • Date: 2013-10-17 22:12:11 UTC
  • mfrom: (1.1.3)
  • Revision ID: package-import@ubuntu.com-20131017221211-re1r37k4d6wrtmeq
Tags: 3.12.0-1
* New upstream release.
  - No longer need curl-types-remove.patch 
* Add debian/watch file.
* Fix typo in hardening flags; Change  to =all,-pie ; 
  Use DEB_LDFLAGS_MAINT_APPEND. Closes: #697387.
* Enable parallel build. Closes: #723938.
* Depend on libcurl4-gnutls-dev | libcurl-dev. Closes: #722701.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
1
// -*- mode: c++; c-basic-offset:4 -*-
3
2
 
4
3
// This file is part of libdap, A C++ implementation of the OPeNDAP Data
19
18
//
20
19
// You should have received a copy of the GNU Lesser General Public
21
20
// License along with this library; if not, write to the Free Software
22
 
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
21
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23
22
//
24
23
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25
24
 
38
37
 
39
38
#include <cstring>
40
39
 
41
 
static char rcsid[] not_used =
42
 
    { "$Id: Vector.cc 24281 2011-03-09 00:22:31Z jimg $"
43
 
    };
44
 
 
45
40
//#define DODS_DEBUG
46
41
 
 
42
#include <sstream>
 
43
#include <vector>
47
44
#include <algorithm>
48
45
 
49
46
#include "Vector.h"
 
47
#include "Marshaller.h"
 
48
#include "UnMarshaller.h"
 
49
 
 
50
#include "dods-datatypes.h"
50
51
#include "escaping.h"
51
52
#include "util.h"
52
53
#include "debug.h"
53
54
#include "InternalErr.h"
54
 
#include <sstream>
55
55
 
56
56
using std::cerr;
57
57
using std::endl;
60
60
 
61
61
void Vector::_duplicate(const Vector & v)
62
62
{
63
 
    _length = v._length;
 
63
    d_length = v.d_length;
64
64
 
65
65
    // _var holds the type of the elements. That is, it holds a BaseType
66
66
    // which acts as a template for the type of each element.
82
82
    else {
83
83
        // Failure to set the size will make the [] operator barf on the LHS
84
84
        // of the assignment inside the loop.
85
 
        _vec.resize(_length);
86
 
        for (int i = 0; i < _length; ++i) {
 
85
        _vec.resize(d_length);
 
86
        for (int i = 0; i < d_length; ++i) {
87
87
            // There's no need to call set_parent() for each element; we
88
88
            // maintain the back pointer using the _var member. These
89
89
            // instances are used to hold _values_ only while the _var
96
96
    d_str = v.d_str;
97
97
 
98
98
    // copy numeric values if there are any.
99
 
    _buf = 0;                   // init to null
100
 
    if (v._buf)                 // only copy if data present
101
 
        val2buf(v._buf);        // store v's value in this's _BUF.
 
99
    _buf = 0; // init to null
 
100
    if (v._buf) // only copy if data present
 
101
        val2buf(v._buf); // store v's value in this's _BUF.
102
102
 
103
103
    _capacity = v._capacity;
104
104
}
107
107
 * @return whether the type of this Vector is a cardinal type
108
108
 * (ie stored in _buf)
109
109
 */
110
 
bool
111
 
Vector::is_cardinal_type() const
 
110
bool Vector::m_is_cardinal_type() const
112
111
{
113
 
  // Not cardinal if no _var at all!
114
 
  if (!_var) {
115
 
    return false;
116
 
  }
117
 
 
118
 
  switch (_var->type()) {
119
 
     case dods_byte_c:
120
 
     case dods_int16_c:
121
 
     case dods_uint16_c:
122
 
     case dods_int32_c:
123
 
     case dods_uint32_c:
124
 
     case dods_float32_c:
125
 
     case dods_float64_c: {
126
 
       return true;
127
 
       break;
128
 
     }
129
 
 
130
 
     // These must be handled differently.
131
 
     case dods_str_c:
132
 
     case dods_url_c:
133
 
     case dods_array_c:
134
 
     case dods_structure_c:
135
 
     case dods_sequence_c:
136
 
     case dods_grid_c:
137
 
       return false;
138
 
       break;
139
 
 
140
 
     default:
141
 
       cerr << "Vector::var: Unrecognized type" << endl;
142
 
       return false;
143
 
  } // switch
 
112
    // Not cardinal if no _var at all!
 
113
    if (!_var) {
 
114
        return false;
 
115
    }
 
116
 
 
117
    switch (_var->type()) {
 
118
        case dods_byte_c:
 
119
        case dods_int16_c:
 
120
        case dods_uint16_c:
 
121
        case dods_int32_c:
 
122
        case dods_uint32_c:
 
123
        case dods_float32_c:
 
124
        case dods_float64_c: {
 
125
            return true;
 
126
            break;
 
127
        }
 
128
 
 
129
            // These must be handled differently.
 
130
        case dods_str_c:
 
131
        case dods_url_c:
 
132
        case dods_array_c:
 
133
        case dods_structure_c:
 
134
        case dods_sequence_c:
 
135
        case dods_grid_c:
 
136
            return false;
 
137
            break;
 
138
 
 
139
        default:
 
140
            cerr << "Vector::var: Unrecognized type" << endl;
 
141
            return false;
 
142
    } // switch
144
143
}
145
144
 
146
145
/**
151
150
 * So don't use this if you want to keep the original _buf data around.
152
151
 * This also sets the valueCapacity().
153
152
 * @param numEltsOfType the number of elements of the cardinal type in var()
154
 
                  that we want storage for.
 
153
 that we want storage for.
155
154
 * @return the size of the buffer created.
156
155
 * @exception if the Vector's type is not cardinal type.
157
156
 */
158
 
unsigned int
159
 
Vector::create_cardinal_data_buffer_for_type(unsigned int numEltsOfType)
 
157
unsigned int Vector::m_create_cardinal_data_buffer_for_type(unsigned int numEltsOfType)
160
158
{
161
 
  // Make sure we HAVE a _var, or we cannot continue.
162
 
  if (!_var) {
163
 
    throw InternalErr(__FILE__, __LINE__,
164
 
        "create_cardinal_data_buffer_for_type: Logic error: _var is null!");
165
 
  }
166
 
 
167
 
  // Make sure we only do this for the correct data types.
168
 
  if (!is_cardinal_type()) {
169
 
      throw InternalErr(__FILE__, __LINE__,
170
 
          "create_cardinal_data_buffer_for_type: incorrectly used on Vector whose type was not a cardinal (simple data types).");
171
 
  }
172
 
 
173
 
  delete_cardinal_data_buffer();
174
 
 
175
 
  // Actually new up the array with enough bytes to hold numEltsOfType of the actual type.
176
 
  unsigned int bytesPerElt = _var->width();
177
 
  unsigned int bytesNeeded = bytesPerElt * numEltsOfType;
178
 
  _buf = new char[bytesNeeded];
179
 
  if (!_buf) {
180
 
    ostringstream oss;
181
 
    oss << "create_cardinal_data_buffer_for_type: new char[] failed to allocate " <<
182
 
           bytesNeeded <<
183
 
           " bytes!  Out of memory or too large a buffer required!";
184
 
    throw InternalErr(__FILE__, __LINE__, oss.str());
185
 
  }
186
 
  _capacity = numEltsOfType;
187
 
  return bytesNeeded;
 
159
    // Make sure we HAVE a _var, or we cannot continue.
 
160
    if (!_var) {
 
161
        throw InternalErr(__FILE__, __LINE__, "create_cardinal_data_buffer_for_type: Logic error: _var is null!");
 
162
    }
 
163
 
 
164
    // Make sure we only do this for the correct data types.
 
165
    if (!m_is_cardinal_type()) {
 
166
        throw InternalErr(__FILE__, __LINE__, "create_cardinal_data_buffer_for_type: incorrectly used on Vector whose type was not a cardinal (simple data types).");
 
167
    }
 
168
 
 
169
    m_delete_cardinal_data_buffer();
 
170
 
 
171
    // Actually new up the array with enough bytes to hold numEltsOfType of the actual type.
 
172
    unsigned int bytesPerElt = _var->width();
 
173
    unsigned int bytesNeeded = bytesPerElt * numEltsOfType;
 
174
    _buf = new char[bytesNeeded];
 
175
    if (!_buf) {
 
176
        ostringstream oss;
 
177
        oss << "create_cardinal_data_buffer_for_type: new char[] failed to allocate " << bytesNeeded << " bytes!  Out of memory or too large a buffer required!";
 
178
        throw InternalErr(__FILE__, __LINE__, oss.str());
 
179
    }
 
180
    _capacity = numEltsOfType;
 
181
    return bytesNeeded;
188
182
}
189
183
 
190
184
/** Delete _buf and zero it and _capacity out */
191
 
void
192
 
Vector::delete_cardinal_data_buffer()
 
185
void Vector::m_delete_cardinal_data_buffer()
193
186
{
194
 
  if (_buf) {
195
 
     delete[] _buf;
196
 
     _buf = 0;
197
 
     _capacity = 0;
198
 
   }
 
187
    if (_buf) {
 
188
        delete[] _buf;
 
189
        _buf = 0;
 
190
        _capacity = 0;
 
191
    }
199
192
}
200
193
 
201
194
/** Helper to reduce cut and paste in the virtual's.
202
195
 *
203
196
 */
204
 
template <class CardType>
205
 
void
206
 
Vector::set_cardinal_values_internal(const CardType* fromArray, int numElts)
 
197
template<class CardType>
 
198
void Vector::set_cardinal_values_internal(const CardType* fromArray, int numElts)
207
199
{
208
 
  if (numElts < 0) {
209
 
     throw InternalErr(__FILE__, __LINE__,
210
 
                 "Logic error: Vector::set_cardinal_values_internal() called with negative numElts!");
211
 
  }
212
 
  if (!fromArray) {
213
 
    throw InternalErr(__FILE__, __LINE__,
214
 
        "Logic error: Vector::set_cardinal_values_internal() called with null fromArray!");
215
 
  }
216
 
  set_length(numElts);
217
 
  create_cardinal_data_buffer_for_type(numElts);
218
 
  memcpy(_buf, fromArray, numElts * sizeof(CardType) );
219
 
  set_read_p(true);
 
200
    if (numElts < 0) {
 
201
        throw InternalErr(__FILE__, __LINE__, "Logic error: Vector::set_cardinal_values_internal() called with negative numElts!");
 
202
    }
 
203
    if (!fromArray) {
 
204
        throw InternalErr(__FILE__, __LINE__, "Logic error: Vector::set_cardinal_values_internal() called with null fromArray!");
 
205
    }
 
206
    set_length(numElts);
 
207
    m_create_cardinal_data_buffer_for_type(numElts);
 
208
    memcpy(_buf, fromArray, numElts * sizeof(CardType));
 
209
    set_read_p(true);
220
210
}
221
211
 
222
 
 
223
212
/** The Vector constructor requires the name of the variable to be
224
 
    created, and a pointer to an object of the type the Vector is to
225
 
    hold.  The name may be omitted, which will create a nameless
226
 
    variable.  The template object may not be omitted.
227
 
 
228
 
    @param n A string containing the name of the variable to be
229
 
    created.
230
 
    @param v A pointer to a variable of the type to be included
231
 
    in the Vector.
232
 
    @param t The type of the resulting Vector object, from the Type
233
 
    enum list.  There is no DAP2 Vector object, so all uses of this
234
 
    method will be from the List or Array classes.  This defaults to
235
 
    <tt>dods_null_c</tt>.
236
 
 
237
 
    @see Type
238
 
    @brief The Vector constructor.  */
239
 
Vector::Vector(const string & n, BaseType * v, const Type & t)
240
 
        : BaseType(n, t), _length(-1), _var(0), _buf(0), _vec(0), _capacity(0)
 
213
 created, and a pointer to an object of the type the Vector is to
 
214
 hold.  The name may be omitted, which will create a nameless
 
215
 variable.  The template object may not be omitted.
 
216
 
 
217
 @param n A string containing the name of the variable to be
 
218
 created.
 
219
 @param v A pointer to a variable of the type to be included
 
220
 in the Vector.
 
221
 @param t The type of the resulting Vector object, from the Type
 
222
 enum list.  There is no DAP2 Vector object, so all uses of this
 
223
 method will be from the List or Array classes.  This defaults to
 
224
 <tt>dods_null_c</tt>.
 
225
 
 
226
 @see Type
 
227
 @brief The Vector constructor.  */
 
228
Vector::Vector(const string & n, BaseType * v, const Type & t) :
 
229
    BaseType(n, t), d_length(-1), _var(0), _buf(0), _vec(0), _capacity(0)
241
230
{
242
231
    if (v)
243
232
        add_var(v);
248
237
}
249
238
 
250
239
/** The Vector server-side constructor requires the name of the variable
251
 
    to be created, the dataset name from which this Vector is created, and
252
 
    a pointer to an object of the type the Vector is to hold.  The
253
 
    name may be omitted, which will create a nameless variable.
254
 
    The template object may not be omitted.
255
 
 
256
 
    @param n A string containing the name of the variable to be
257
 
    created.
258
 
    @param d A string containing the dataset name from which the variable is
259
 
    being created.
260
 
    @param v A pointer to a variable of the type to be included
261
 
    in the Vector.
262
 
    @param t The type of the resulting Vector object, from the Type
263
 
    enum list.  There is no DAP2 Vector object, so all uses of this
264
 
    method will be from the List or Array classes.  This defaults to
265
 
    <tt>dods_null_c</tt>.
266
 
 
267
 
    @see Type
268
 
    @brief The Vector constructor.  */
269
 
Vector::Vector(const string & n, const string &d, BaseType * v, const Type & t)
270
 
        : BaseType(n, d, t), _length(-1), _var(0), _buf(0), _vec(0), _capacity(0)
 
240
 to be created, the dataset name from which this Vector is created, and
 
241
 a pointer to an object of the type the Vector is to hold.  The
 
242
 name may be omitted, which will create a nameless variable.
 
243
 The template object may not be omitted.
 
244
 
 
245
 @param n A string containing the name of the variable to be
 
246
 created.
 
247
 @param d A string containing the dataset name from which the variable is
 
248
 being created.
 
249
 @param v A pointer to a variable of the type to be included
 
250
 in the Vector.
 
251
 @param t The type of the resulting Vector object, from the Type
 
252
 enum list.  There is no DAP2 Vector object, so all uses of this
 
253
 method will be from the List or Array classes.  This defaults to
 
254
 <tt>dods_null_c</tt>.
 
255
 
 
256
 @see Type
 
257
 @brief The Vector constructor.  */
 
258
Vector::Vector(const string & n, const string &d, BaseType * v, const Type & t) :
 
259
    BaseType(n, d, t), d_length(-1), _var(0), _buf(0), _vec(0), _capacity(0)
271
260
{
272
261
    if (v)
273
262
        add_var(v);
278
267
}
279
268
 
280
269
/** The Vector copy constructor. */
281
 
Vector::Vector(const Vector & rhs): BaseType(rhs)
 
270
Vector::Vector(const Vector & rhs) :
 
271
    BaseType(rhs)
282
272
{
283
273
    DBG2(cerr << "Entering Vector const ctor for object: " << this <<
284
 
         endl);
285
 
    DBG2(cerr << "RHS: " << &rhs << endl);
 
274
            endl); DBG2(cerr << "RHS: " << &rhs << endl);
286
275
 
287
276
    _duplicate(rhs);
288
277
}
305
294
    if (this == &rhs)
306
295
        return *this;
307
296
 
308
 
    dynamic_cast < BaseType & >(*this) = rhs;
 
297
    dynamic_cast<BaseType &> (*this) = rhs;
309
298
 
310
299
    _duplicate(rhs);
311
300
 
312
301
    return *this;
313
302
}
314
303
 
315
 
void
316
 
Vector::set_name(const std::string& name)
317
 
{
318
 
  BaseType::set_name(name);
319
 
  // We need to set the template variable name as well since
320
 
  // this is what gets output in the dds!  Otherwise, there's a mismatch.
321
 
  if (_var) {
322
 
      _var->set_name(name);
323
 
  }
 
304
/**
 
305
 * The Vector (and Array) classes are specific to DAP2. They do not support
 
306
 * the semantics of DAP4 which allows varying dimensions.
 
307
 */
 
308
bool Vector::is_dap2_only_type()
 
309
{
 
310
    return true;
 
311
}
 
312
 
 
313
void Vector::set_name(const std::string& name)
 
314
{
 
315
    BaseType::set_name(name);
 
316
    // We need to set the template variable name as well since
 
317
    // this is what gets output in the dds!  Otherwise, there's a mismatch.
 
318
    if (_var) {
 
319
        _var->set_name(name);
 
320
    }
324
321
}
325
322
 
326
323
int Vector::element_count(bool leaves)
338
335
// is a scalar, but does matter when it is an aggregate.
339
336
 
340
337
/** This function sets the <tt>send_p</tt> flag for both the Vector itself
341
 
    and its element template.  This does not matter much when the
342
 
    Vector contains simple data types, but does become significant
343
 
    when the Vector contains compound types.
 
338
 and its element template.  This does not matter much when the
 
339
 Vector contains simple data types, but does become significant
 
340
 when the Vector contains compound types.
344
341
 
345
 
    @brief Indicates that the data is ready to send. */
 
342
 @brief Indicates that the data is ready to send. */
346
343
void Vector::set_send_p(bool state)
347
344
{
348
345
    _var->set_send_p(state);
350
347
}
351
348
 
352
349
/** This function sets the <tt>read_p</tt> flag for both the Vector itself
353
 
    and its element template.  This does not matter much when the
354
 
    Vector contains simple data types, but does become significant
355
 
    when the Vector contains compound types.
 
350
 and its element template.  This does not matter much when the
 
351
 Vector contains simple data types, but does become significant
 
352
 when the Vector contains compound types.
356
353
 
357
 
    @brief Indicates that the data is ready to send.  */
 
354
 @brief Indicates that the data is ready to send.  */
358
355
void Vector::set_read_p(bool state)
359
356
{
360
357
    if (_var) {
361
 
      _var->set_read_p(state);
 
358
        _var->set_read_p(state);
362
359
    }
363
360
    BaseType::set_read_p(state);
364
361
}
365
362
 
366
363
/** Returns a copy of the template array element. If the Vector contains
367
 
    simple data types, the template will contain the value of the last
368
 
    vector element accessed with the <code>Vector::var(int i)</code> function,
369
 
    if any. If no such access has been made, or if the Vector contains
370
 
    compound data types, the value held by the template instance is
371
 
    undefined.
372
 
 
373
 
    Note that the parameter <i>exact_match</i> is not used by this mfunc.
374
 
 
375
 
    @param n The name of the variable to find.
376
 
    @param exact Unused.
377
 
    @param s Pointer to a BaseType Pointer Stack. Use this stack to record
378
 
    the path to the variable. By default this pointer is null, in which case
379
 
    it is not used.
380
 
 
381
 
    @return A pointer to the BaseType if found, otherwise null.
382
 
    @see Vector::var */
383
 
BaseType *Vector::var(const string & n, bool exact, btp_stack * s)
 
364
 simple data types, the template will contain the value of the last
 
365
 vector element accessed with the <code>Vector::var(int i)</code> function,
 
366
 if any. If no such access has been made, or if the Vector contains
 
367
 compound data types, the value held by the template instance is
 
368
 undefined.
 
369
 
 
370
 Note that the parameter <i>exact_match</i> is not used by this mfunc.
 
371
 
 
372
 @param n The name of the variable to find.
 
373
 @param exact Unused.
 
374
 @param s Pointer to a BaseType Pointer Stack. Use this stack to record
 
375
 the path to the variable. By default this pointer is null, in which case
 
376
 it is not used.
 
377
 
 
378
 @return A pointer to the BaseType if found, otherwise null.
 
379
 @see Vector::var */
 
380
BaseType *Vector::var(const string &n, bool exact, btp_stack *s)
384
381
{
385
382
    string name = www2id(n);
386
383
    DBG(cerr << "Vector::var: Looking for " << n << endl);
387
384
 
 
385
    // If this is a Vector of constructor types, look for 'name' recursively.
388
386
    // Make sure to check for the case where name is the default (the empty
389
387
    // string). 9/1/98 jhrg
390
388
    if (_var->is_constructor_type()) {
401
399
        }
402
400
    }
403
401
    else {
404
 
        return _var; // I don't see why this isn't return 0 *** jhrg 10/9/08
 
402
        return _var;
405
403
    }
406
404
}
407
405
 
408
406
/** This version of var(...) searches for <i>name</i> and returns a
409
 
    pointer to the BaseType object if found. It uses the same search
410
 
    algorithm as above when <i>exact_match</i> is false. In addition to
411
 
    returning a pointer to the variable, it pushes onto <i>s</i> a
412
 
    BaseType pointer to each constructor type that ultimately contains
413
 
    <i>name</i>.
 
407
 pointer to the BaseType object if found. It uses the same search
 
408
 algorithm as above when <i>exact_match</i> is false. In addition to
 
409
 returning a pointer to the variable, it pushes onto <i>s</i> a
 
410
 BaseType pointer to each constructor type that ultimately contains
 
411
 <i>name</i>.
414
412
 
415
 
    @param n Find the variable whose name is <i>name</i>.
416
 
    @param s Record the path to <i>name</i>.
417
 
    @return A pointer to the named variable. */
 
413
 @param n Find the variable whose name is <i>name</i>.
 
414
 @param s Record the path to <i>name</i>.
 
415
 @return A pointer to the named variable. */
418
416
BaseType *Vector::var(const string & n, btp_stack & s)
419
417
{
420
418
    string name = www2id(n);
437
435
// Returns: A BaseType pointer to the ith element of the Vector.
438
436
 
439
437
/** Returns a pointer to the specified Vector element.  The return
440
 
    pointer will reference the element itself, so multiple calls to this
441
 
    method should save each value before making the next call.
442
 
 
443
 
    @todo Is this method thread safe? If 'apartment threading' is used, I
444
 
    think so. But if the library is running in more than one thread, then
445
 
    this is not thread safe.
446
 
 
447
 
    @param i The index of the desired Vector element.  Zero
448
 
    indicates the first element of the Vector.
449
 
    @return A pointer to a BaseType class instance containing
450
 
    the value of the indicated element. The BaseType pointer is locally
451
 
    maintained and should not be deleted or referenced. Extract the value
452
 
    right after the method returns.
453
 
    @see BaseType::var */
 
438
 pointer will reference the element itself, so multiple calls to this
 
439
 method should save each value before making the next call.
 
440
 
 
441
 @param i The index of the desired Vector element.  Zero
 
442
 indicates the first element of the Vector.
 
443
 @return A pointer to a BaseType class instance containing
 
444
 the value of the indicated element. The BaseType pointer is locally
 
445
 maintained and should not be deleted or referenced. Extract the value
 
446
 right after the method returns.
 
447
 @see BaseType::var */
454
448
BaseType *Vector::var(unsigned int i)
455
449
{
456
450
 
457
451
    switch (_var->type()) {
458
 
    case dods_byte_c:
459
 
    case dods_int16_c:
460
 
    case dods_uint16_c:
461
 
    case dods_int32_c:
462
 
    case dods_uint32_c:
463
 
    case dods_float32_c:
464
 
    case dods_float64_c: {
 
452
        case dods_byte_c:
 
453
        case dods_int16_c:
 
454
        case dods_uint16_c:
 
455
        case dods_int32_c:
 
456
        case dods_uint32_c:
 
457
        case dods_float32_c:
 
458
        case dods_float64_c: {
465
459
            // Transfer the ith value to the BaseType *_var; There are more
466
460
            // efficient ways to get a whole array using buf2val() but this is
467
461
            // an OK way to get a single value or several non-contiguous values.
471
465
            break;
472
466
        }
473
467
 
474
 
    case dods_str_c:
475
 
    case dods_url_c:
476
 
        _var->val2buf(&d_str[i]);
477
 
        return _var;
478
 
        break;
479
 
 
480
 
    case dods_array_c:
481
 
    case dods_structure_c:
482
 
    case dods_sequence_c:
483
 
    case dods_grid_c:
484
 
        return _vec[i];
485
 
        break;
486
 
 
487
 
    default:
488
 
        cerr << "Vector::var: Unrecognized type" << endl;
 
468
        case dods_str_c:
 
469
        case dods_url_c:
 
470
            _var->val2buf(&d_str[i]);
 
471
            return _var;
 
472
            break;
 
473
 
 
474
        case dods_array_c:
 
475
        case dods_structure_c:
 
476
        case dods_sequence_c:
 
477
        case dods_grid_c:
 
478
            return _vec[i];
 
479
            break;
 
480
 
 
481
        default:
 
482
            throw Error ("Vector::var: Unrecognized type");
 
483
            //cerr << "Vector::var: Unrecognized type" << endl;
 
484
            break;
489
485
    }
490
486
 
491
487
    return 0;
500
496
// Returns: The number of bytes used to store the vector.
501
497
 
502
498
/** Returns the number of bytes needed to hold the <i>entire</i>
503
 
    array.  This is equal to <tt>length()</tt> times the width of each
504
 
    element.
 
499
 array.  This is equal to <tt>length()</tt> times the width of each
 
500
 element.
505
501
 
506
 
    @brief Returns the width of the data, in bytes. */
507
 
unsigned int Vector::width()
 
502
 @brief Returns the width of the data, in bytes. */
 
503
unsigned int Vector::width(bool constrained)
508
504
{
509
505
    // Jose Garcia
510
506
    if (!_var) {
511
 
        throw InternalErr(__FILE__, __LINE__,
512
 
                          "Cannot get width since *this* object is not holding data.");
 
507
        throw InternalErr(__FILE__, __LINE__, "Cannot get width since *this* object is not holding data.");
513
508
    }
514
509
 
515
 
    return length() * _var->width();
 
510
    return length() * _var->width(constrained);
516
511
}
517
512
 
518
513
// Returns: the number of elements in the vector.
519
514
 
520
515
/** Returns the number of elements in the vector. Note that some
521
 
    child classes of Vector use the length of -1 as a flag value.
 
516
 child classes of Vector use the length of -1 as a flag value.
522
517
 
523
 
    @see Vector::append_dim */
 
518
 @see Vector::append_dim */
524
519
int Vector::length() const
525
520
{
526
 
    return _length;
 
521
    return d_length;
527
522
}
528
523
 
529
524
// set the number of elements in the vector.
531
526
// Returns: void
532
527
 
533
528
/** Sets the length of the vector.  This function does not allocate
534
 
any new space. */
 
529
 any new space. */
535
530
void Vector::set_length(int l)
536
531
{
537
 
    _length = l;
 
532
    d_length = l;
538
533
}
539
534
 
540
535
// \e l is the number of elements the vector can hold (e.g., if l == 20, then
541
536
// the vector can hold elements 0, .., 19).
542
537
 
543
538
/** Resizes a Vector.  If the input length is greater than the
544
 
    current length of the Vector, new memory is allocated (the
545
 
    Vector moved if necessary), and the new entries are appended to
546
 
    the end of the array and padded with Null values.  If the input
547
 
    length is shorter, the tail values are discarded. */
 
539
 current length of the Vector, new memory is allocated (the
 
540
 Vector moved if necessary), and the new entries are appended to
 
541
 the end of the array and padded with Null values.  If the input
 
542
 length is shorter, the tail values are discarded. */
548
543
void Vector::vec_resize(int l)
549
544
{
550
 
    _vec.resize((l > 0) ? l : 0, 0);    // Fill with NULLs
 
545
    _vec.resize((l > 0) ? l : 0, 0); // Fill with NULLs
551
546
    _capacity = l; // capacity in terms of number of elements.
552
547
}
553
548
 
554
549
/** @brief read data into a variable for later use
555
550
 
556
 
    Most uses of a variable are to either serialize its data to a stream of
557
 
    some sort or to read values from some stream and intern those in the
558
 
    variable for later use. These operations are perform by serialize()
559
 
    and deserialize() which follow. This function performs essentially both
560
 
    of these operations without actually using a stream device. The data are
561
 
    read using the read() method(s) and loaded into the variables directly.
562
 
 
563
 
    This method is intended to be used by objects which transform DAP objects
564
 
    like the DataDDS into an ASCII CSV representation.
565
 
 
566
 
    the data source.
567
 
    @param eval A reference to a constraint evaluator
568
 
    @param dds The complete DDS to which this variable belongs */
569
 
void
570
 
Vector::intern_data(ConstraintEvaluator &eval, DDS &dds)
 
551
 Most uses of a variable are to either serialize its data to a stream of
 
552
 some sort or to read values from some stream and intern those in the
 
553
 variable for later use. These operations are perform by serialize()
 
554
 and deserialize() which follow. This function performs essentially both
 
555
 of these operations without actually using a stream device. The data are
 
556
 read using the read() method(s) and loaded into the variables directly.
 
557
 
 
558
 This method is intended to be used by objects which transform DAP objects
 
559
 like the DataDDS into an ASCII CSV representation.
 
560
 
 
561
 the data source.
 
562
 @param eval A reference to a constraint evaluator
 
563
 @param dds The complete DDS to which this variable belongs */
 
564
void Vector::intern_data(ConstraintEvaluator &eval, DDS &dds)
571
565
{
572
566
    DBG(cerr << "Vector::intern_data: " << name() << endl);
573
567
    if (!read_p())
574
 
        read();          // read() throws Error and InternalErr
 
568
        read(); // read() throws Error and InternalErr
575
569
 
576
570
    // length() is not capacity; it must be set explicitly in read().
577
571
    int num = length();
578
572
 
579
573
    switch (_var->type()) {
580
 
    case dods_byte_c:
581
 
    case dods_int16_c:
582
 
    case dods_uint16_c:
583
 
    case dods_int32_c:
584
 
    case dods_uint32_c:
585
 
    case dods_float32_c:
586
 
    case dods_float64_c:
587
 
        // For these cases, read() puts the data into _buf, which is what we
588
 
        // need to do 'stuff' with the data.
589
 
        break;
590
 
 
591
 
    case dods_str_c:
592
 
    case dods_url_c:
593
 
        // For these cases, read() will put the data into d_str[], which is
594
 
        // what the transformation classes need.
595
 
        break;
596
 
 
597
 
    case dods_array_c:
598
 
        // I think this is an error since there can never be an Array of
599
 
        // Array.
600
 
        throw InternalErr(__FILE__, __LINE__, "Array of Array not supported.");
601
 
        break;
602
 
 
603
 
    case dods_structure_c:
604
 
    case dods_sequence_c:
605
 
    case dods_grid_c:
606
 
        DBG(cerr << "Vector::intern_data: found ctor" << endl);
607
 
        // For these cases, we need to call read() for each of the 'num'
608
 
        // elements in the '_vec[]' array of BaseType object pointers.
609
 
        if (_vec.capacity() == 0)
610
 
            throw InternalErr(__FILE__, __LINE__,
611
 
                              "The capacity of *this* vector is 0.");
612
 
 
613
 
        for (int i = 0; i < num; ++i)
614
 
            _vec[i]->intern_data(eval, dds);
615
 
 
616
 
        break;
617
 
 
618
 
    default:
619
 
        throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
620
 
        break;
 
574
        case dods_byte_c:
 
575
        case dods_int16_c:
 
576
        case dods_uint16_c:
 
577
        case dods_int32_c:
 
578
        case dods_uint32_c:
 
579
        case dods_float32_c:
 
580
        case dods_float64_c:
 
581
            // For these cases, read() puts the data into _buf, which is what we
 
582
            // need to do 'stuff' with the data.
 
583
            break;
 
584
 
 
585
        case dods_str_c:
 
586
        case dods_url_c:
 
587
            // For these cases, read() will put the data into d_str[], which is
 
588
            // what the transformation classes need.
 
589
            break;
 
590
 
 
591
        case dods_array_c:
 
592
            // I think this is an error since there can never be an Array of
 
593
            // Array.
 
594
            throw InternalErr(__FILE__, __LINE__, "Array of Array not supported.");
 
595
            break;
 
596
 
 
597
        case dods_structure_c:
 
598
        case dods_sequence_c:
 
599
        case dods_grid_c:
 
600
            DBG(cerr << "Vector::intern_data: found ctor" << endl);
 
601
            // For these cases, we need to call read() for each of the 'num'
 
602
            // elements in the '_vec[]' array of BaseType object pointers.
 
603
            if (_vec.capacity() == 0)
 
604
                throw InternalErr(__FILE__, __LINE__, "The capacity of *this* vector is 0.");
 
605
 
 
606
            for (int i = 0; i < num; ++i)
 
607
                _vec[i]->intern_data(eval, dds);
 
608
 
 
609
            break;
 
610
 
 
611
        default:
 
612
            throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
 
613
            break;
621
614
    }
622
615
}
623
616
 
624
617
/** @brief Serialize a Vector.
625
618
 
626
 
    This uses the Marshaler class to encode each element of a cardinal
627
 
    array. For Arrays of Str and Url types, send the element count over
628
 
    as a prefix to the data so that deserialize will know how many elements
629
 
    to read.
630
 
 
631
 
    NB: Arrays of cardinal types must already be in BUF (in the local machine's
632
 
    representation) <i>before</i> this call is made.
633
 
*/
634
 
 
635
 
 
636
 
bool Vector::serialize(ConstraintEvaluator & eval, DDS & dds,
637
 
                       Marshaller &m, bool ce_eval)
 
619
 This uses the Marshaler class to encode each element of a cardinal
 
620
 array. For Arrays of Str and Url types, send the element count over
 
621
 as a prefix to the data so that deserialize will know how many elements
 
622
 to read.
 
623
 
 
624
 NB: Arrays of cardinal types must already be in BUF (in the local machine's
 
625
 representation) <i>before</i> this call is made.
 
626
 */
 
627
 
 
628
bool Vector::serialize(ConstraintEvaluator & eval, DDS & dds, Marshaller &m, bool ce_eval)
638
629
{
639
 
    int i = 0;
 
630
    int i = 0;// TODO move closer to use
640
631
 
641
632
    dds.timeout_on();
642
633
 
643
634
    if (!read_p())
644
 
        read();          // read() throws Error and InternalErr
 
635
        read(); // read() throws Error and InternalErr
645
636
 
646
637
#if EVAL
647
638
    if (ce_eval && !eval.eval_selection(dds, dataset()))
654
645
    int num = length();
655
646
 
656
647
    switch (_var->type()) {
657
 
    case dods_byte_c:
658
 
        m.put_vector( _buf, num, *this ) ;
659
 
        break ;
660
 
    case dods_int16_c:
661
 
    case dods_uint16_c:
662
 
    case dods_int32_c:
663
 
    case dods_uint32_c:
664
 
    case dods_float32_c:
665
 
    case dods_float64_c:
666
 
        m.put_vector( _buf, num, _var->width(), *this ) ;
667
 
        break;
668
 
 
669
 
    case dods_str_c:
670
 
    case dods_url_c:
671
 
        if (d_str.capacity() == 0)
672
 
            throw InternalErr(__FILE__, __LINE__,
673
 
                              "The capacity of the string vector is 0");
674
 
 
675
 
        m.put_int( num ) ;
676
 
 
677
 
        for (i = 0; i < num; ++i)
678
 
            m.put_str( d_str[i] ) ;
679
 
 
680
 
        break;
681
 
 
682
 
    case dods_array_c:
683
 
    case dods_structure_c:
684
 
    case dods_sequence_c:
685
 
    case dods_grid_c:
686
 
        //Jose Garcia
687
 
        // Not setting the capacity of _vec is an internal error.
688
 
        if (_vec.capacity() == 0)
689
 
            throw InternalErr(__FILE__, __LINE__,
690
 
                              "The capacity of *this* vector is 0.");
691
 
 
692
 
        m.put_int( num ) ;
693
 
 
694
 
        for (i = 0; i < num; ++i)
695
 
            _vec[i]->serialize(eval, dds, m, false);
696
 
 
697
 
        break;
698
 
 
699
 
    default:
700
 
        throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
701
 
        break;
 
648
        case dods_byte_c:
 
649
            m.put_vector(_buf, num, *this);
 
650
            break;
 
651
        case dods_int16_c:
 
652
        case dods_uint16_c:
 
653
        case dods_int32_c:
 
654
        case dods_uint32_c:
 
655
        case dods_float32_c:
 
656
        case dods_float64_c:
 
657
            m.put_vector(_buf, num, _var->width(), *this);
 
658
            break;
 
659
 
 
660
        case dods_str_c:
 
661
        case dods_url_c:
 
662
            if (d_str.capacity() == 0)
 
663
                throw InternalErr(__FILE__, __LINE__, "The capacity of the string vector is 0");
 
664
 
 
665
            m.put_int(num);
 
666
 
 
667
            for (i = 0; i < num; ++i)
 
668
                m.put_str(d_str[i]);
 
669
 
 
670
            break;
 
671
 
 
672
        case dods_array_c:
 
673
        case dods_structure_c:
 
674
        case dods_sequence_c:
 
675
        case dods_grid_c:
 
676
            //Jose Garcia
 
677
            // Not setting the capacity of _vec is an internal error.
 
678
            if (_vec.capacity() == 0)
 
679
                throw InternalErr(__FILE__, __LINE__, "The capacity of *this* vector is 0.");
 
680
 
 
681
            m.put_int(num);
 
682
 
 
683
            for (i = 0; i < num; ++i)
 
684
                _vec[i]->serialize(eval, dds, m, false);
 
685
 
 
686
            break;
 
687
 
 
688
        default:
 
689
            throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
 
690
            break;
702
691
    }
703
692
 
704
693
    return true;
727
716
    unsigned i = 0;
728
717
 
729
718
    switch (_var->type()) {
730
 
    case dods_byte_c:
731
 
    case dods_int16_c:
732
 
    case dods_uint16_c:
733
 
    case dods_int32_c:
734
 
    case dods_uint32_c:
735
 
    case dods_float32_c:
736
 
    case dods_float64_c:
737
 
        if (_buf && !reuse) {
738
 
            delete_cardinal_data_buffer();
739
 
        }
740
 
 
741
 
        um.get_int( (int &)num ) ;
742
 
 
743
 
        DBG(cerr << "Vector::deserialize: num = " << num << endl);
744
 
        DBG(cerr << "Vector::deserialize: length = " << length() << endl);
745
 
 
746
 
        if (length() == -1)
747
 
            set_length(num);
748
 
 
749
 
        if (num != (unsigned int) length())
750
 
            throw InternalErr(__FILE__, __LINE__, "The server sent declarations and data with mismatched sizes.");
751
 
 
752
 
        if (!_buf) {
753
 
            // Make _buf be large enough for length() elements of _var->type()
754
 
            create_cardinal_data_buffer_for_type(length());
755
 
            DBG(cerr << "Vector::deserialize: allocating "
756
 
                << width() << " bytes for an array of "
757
 
                << length() << " " << _var->type_name() << endl);
758
 
        }
759
 
 
760
 
        if (_var->type() == dods_byte_c)
761
 
            um.get_vector( (char **)&_buf, num, *this ) ;
762
 
        else
763
 
            um.get_vector( (char **)&_buf, num, _var->width(), *this ) ;
764
 
 
765
 
        DBG(cerr << "Vector::deserialize: read " << num << " elements\n");
766
 
 
767
 
        break;
768
 
 
769
 
    case dods_str_c:
770
 
    case dods_url_c:
771
 
        um.get_int( (int &)num ) ;
772
 
 
773
 
        if (length() == -1)
774
 
            set_length(num);
775
 
 
776
 
        if (num != (unsigned int) length())
777
 
            throw InternalErr(__FILE__, __LINE__,
778
 
                              "The client sent declarations and data with mismatched sizes.");
779
 
 
780
 
        d_str.resize((num > 0) ? num : 0);      // Fill with NULLs
781
 
        _capacity = num; // capacity is number of strings we can fit.
782
 
 
783
 
        for (i = 0; i < num; ++i) {
784
 
            string str;
785
 
            um.get_str( str ) ;
786
 
            d_str[i] = str;
787
 
 
788
 
        }
789
 
 
790
 
        break;
791
 
 
792
 
    case dods_array_c:
793
 
    case dods_structure_c:
794
 
    case dods_sequence_c:
795
 
    case dods_grid_c:
796
 
        um.get_int( (int &)num ) ;
797
 
 
798
 
        if (length() == -1)
799
 
            set_length(num);
800
 
 
801
 
        if (num != (unsigned int) length())
802
 
            throw InternalErr(__FILE__, __LINE__, "The client sent declarations and data with mismatched sizes.");
803
 
 
804
 
        vec_resize(num);
805
 
 
806
 
        for (i = 0; i < num; ++i) {
807
 
            _vec[i] = _var->ptr_duplicate();
808
 
            _vec[i]->deserialize(um, dds);
809
 
        }
810
 
 
811
 
        break;
812
 
 
813
 
    default:
814
 
        throw InternalErr(__FILE__, __LINE__, "Unknown type!");
815
 
        break;
 
719
        case dods_byte_c:
 
720
        case dods_int16_c:
 
721
        case dods_uint16_c:
 
722
        case dods_int32_c:
 
723
        case dods_uint32_c:
 
724
        case dods_float32_c:
 
725
        case dods_float64_c:
 
726
            if (_buf && !reuse) {
 
727
                m_delete_cardinal_data_buffer();
 
728
            }
 
729
 
 
730
            um.get_int((int &) num);
 
731
 
 
732
            DBG(cerr << "Vector::deserialize: num = " << num << endl);
 
733
            DBG(cerr << "Vector::deserialize: length = " << length() << endl);
 
734
 
 
735
            if (length() == -1)
 
736
                set_length(num);
 
737
 
 
738
            if (num != (unsigned int) length())
 
739
                throw InternalErr(__FILE__, __LINE__, "The server sent declarations and data with mismatched sizes.");
 
740
 
 
741
            if (!_buf) {
 
742
                // Make _buf be large enough for length() elements of _var->type()
 
743
                m_create_cardinal_data_buffer_for_type(length());
 
744
                DBG(cerr << "Vector::deserialize: allocating "
 
745
                        << width() << " bytes for an array of "
 
746
                        << length() << " " << _var->type_name() << endl);
 
747
            }
 
748
 
 
749
            if (_var->type() == dods_byte_c)
 
750
                um.get_vector((char **) &_buf, num, *this);
 
751
            else
 
752
                um.get_vector((char **) &_buf, num, _var->width(), *this);
 
753
 
 
754
            DBG(cerr << "Vector::deserialize: read " << num << " elements\n");
 
755
 
 
756
            break;
 
757
 
 
758
        case dods_str_c:
 
759
        case dods_url_c:
 
760
            um.get_int((int &) num);
 
761
 
 
762
            if (length() == -1)
 
763
                set_length(num);
 
764
 
 
765
            if (num != (unsigned int) length())
 
766
                throw InternalErr(__FILE__, __LINE__, "The client sent declarations and data with mismatched sizes.");
 
767
 
 
768
            d_str.resize((num > 0) ? num : 0); // Fill with NULLs
 
769
            _capacity = num; // capacity is number of strings we can fit.
 
770
 
 
771
            for (i = 0; i < num; ++i) {
 
772
                string str;
 
773
                um.get_str(str);
 
774
                d_str[i] = str;
 
775
 
 
776
            }
 
777
 
 
778
            break;
 
779
 
 
780
        case dods_array_c:
 
781
        case dods_structure_c:
 
782
        case dods_sequence_c:
 
783
        case dods_grid_c:
 
784
            um.get_int((int &) num);
 
785
 
 
786
            if (length() == -1)
 
787
                set_length(num);
 
788
 
 
789
            if (num != (unsigned int) length())
 
790
                throw InternalErr(__FILE__, __LINE__, "The client sent declarations and data with mismatched sizes.");
 
791
 
 
792
            vec_resize(num);
 
793
 
 
794
            for (i = 0; i < num; ++i) {
 
795
                _vec[i] = _var->ptr_duplicate();
 
796
                _vec[i]->deserialize(um, dds);
 
797
            }
 
798
 
 
799
            break;
 
800
 
 
801
        default:
 
802
            throw InternalErr(__FILE__, __LINE__, "Unknown type!");
 
803
            break;
816
804
    }
817
805
 
818
806
    return false;
819
807
}
820
808
 
821
809
/** Copies data into the class instance buffer.  This function
822
 
    assumes that the input \e val points to memory which
823
 
    contains, in row major order, enough elements of the correct
824
 
    type to fill the array. For an array of a cardinal type the
825
 
    memory is simply copied in whole into the Vector buffer.
826
 
 
827
 
    If the variable has already been constrained, this method will load only
828
 
    number of values/bytes specified by that constraint and will load them
829
 
    into the 'front' of the object's internal buffer. This is where serialize()
830
 
    expects to find the data.
831
 
 
832
 
    For a Vector of Str (OPeNDAP Strings), this assumes \e val points to an
833
 
    array of C++ strings.
834
 
 
835
 
    This method should not be used for Structure, Sequence or Grid.
836
 
 
837
 
    @brief Reads data into the Vector buffer.
838
 
    @exception InternalErr Thrown if called for Structure, Sequence or
839
 
    Grid.
840
 
    @return The number of bytes used by the array.
841
 
    @param val A pointer to the input data.
842
 
    @param reuse A boolean value, indicating whether the class
843
 
    internal data storage can be reused or not.  If this argument is
844
 
    TRUE, the class buffer is assumed to be large enough to hold the
845
 
    incoming data, and it is <i>not</i> reallocated.  If FALSE, new
846
 
    storage is allocated.  If the internal buffer has not been
847
 
    allocated at all, this argument has no effect. */
 
810
 assumes that the input \e val points to memory which
 
811
 contains, in row major order, enough elements of the correct
 
812
 type to fill the array. For an array of a cardinal type the
 
813
 memory is simply copied in whole into the Vector buffer.
 
814
 
 
815
 If the variable has already been constrained, this method will load only
 
816
 number of values/bytes specified by that constraint and will load them
 
817
 into the 'front' of the object's internal buffer. This is where serialize()
 
818
 expects to find the data.
 
819
 
 
820
 For a Vector of Str (OPeNDAP Strings), this assumes \e val points to an
 
821
 array of C++ strings.
 
822
 
 
823
 This method should not be used for Structure, Sequence or Grid.
 
824
 
 
825
 @brief Reads data into the Vector buffer.
 
826
 @exception InternalErr Thrown if called for Structure, Sequence or
 
827
 Grid.
 
828
 @return The number of bytes used by the array.
 
829
 @param val A pointer to the input data.
 
830
 @param reuse A boolean value, indicating whether the class
 
831
 internal data storage can be reused or not.  If this argument is
 
832
 TRUE, the class buffer is assumed to be large enough to hold the
 
833
 incoming data, and it is <i>not</i> reallocated.  If FALSE, new
 
834
 storage is allocated.  If the internal buffer has not been
 
835
 allocated at all, this argument has no effect. */
848
836
unsigned int Vector::val2buf(void *val, bool reuse)
849
837
{
850
838
    // Jose Garcia
857
845
    // will be in libdap++, so it will be an internal error from the
858
846
    // surrogate library.
859
847
    if (!val)
860
 
        throw InternalErr(__FILE__, __LINE__,
861
 
                          "The incoming pointer does not contain any data.");
 
848
        throw InternalErr(__FILE__, __LINE__, "The incoming pointer does not contain any data.");
862
849
 
863
850
    switch (_var->type()) {
864
 
    case dods_byte_c:
865
 
    case dods_int16_c:
866
 
    case dods_uint16_c:
867
 
    case dods_int32_c:
868
 
    case dods_uint32_c:
869
 
    case dods_float32_c:
870
 
    case dods_float64_c: {
871
 
            // width() returns the size given the constraint
872
 
            unsigned int array_wid = width();
 
851
        case dods_byte_c:
 
852
        case dods_int16_c:
 
853
        case dods_uint16_c:
 
854
        case dods_int32_c:
 
855
        case dods_uint32_c:
 
856
        case dods_float32_c:
 
857
        case dods_float64_c: {
 
858
            // width(true) returns the size given the constraint
 
859
            unsigned int array_wid = width(true);
873
860
            if (_buf && !reuse) {
874
 
               delete_cardinal_data_buffer();
 
861
                m_delete_cardinal_data_buffer();
875
862
            }
876
863
 
877
 
            if (!_buf) {        // First time or no reuse (free'd above)
878
 
              create_cardinal_data_buffer_for_type(length());
 
864
            if (!_buf) { // First time or no reuse (free'd above)
 
865
                m_create_cardinal_data_buffer_for_type(length());
879
866
            }
880
867
 
881
868
            memcpy(_buf, val, array_wid);
882
869
            break;
883
870
        }
884
871
 
885
 
    case dods_str_c:
886
 
    case dods_url_c: {
 
872
        case dods_str_c:
 
873
        case dods_url_c: {
887
874
            // Assume val points to an array of C++ string objects. Copy
888
875
            // them into the vector<string> field of this object.
889
 
            d_str.resize(_length);
890
 
            _capacity = _length;
891
 
            for (int i = 0; i < _length; ++i)
892
 
                d_str[i] = *(static_cast < string * >(val) + i);
 
876
            d_str.resize(d_length);
 
877
            _capacity = d_length;
 
878
            for (int i = 0; i < d_length; ++i)
 
879
                d_str[i] = *(static_cast<string *> (val) + i);
893
880
 
894
881
            break;
895
882
        }
896
883
 
897
 
    default:
898
 
        throw InternalErr(__FILE__, __LINE__, "Vector::val2buf: bad type");
 
884
        default:
 
885
            throw InternalErr(__FILE__, __LINE__, "Vector::val2buf: bad type");
899
886
 
900
887
    }
901
888
 
902
 
    return width();
 
889
    return width(true);
903
890
}
904
891
 
905
892
/** Copies data from the Vector buffer.  This function assumes that
906
 
    <i>val</i> points to an array large enough to hold N instances of
907
 
    the `C' representation of the \e numeric element type or C++ string
908
 
    objects. Never call this method for constructor types Structure,
909
 
    Sequence or Grid.
910
 
 
911
 
    When reading data out of a variable that has been constrained, this method
912
 
    assumes the N values/bytes of constrained data start at the beginning
913
 
    of the object's internal buffer. For example, do not load an entire
914
 
    Vector's data using val2buf(), constrain and then use this method to
915
 
    get the data. Unless your constraint starts with the [0]th element, the
916
 
    result will not be the correct values.
917
 
 
918
 
    In the case of a Vector of Str objects, this method will return an array
919
 
    of C++ std::string objects.
920
 
 
921
 
    @note It's best to define the pointer to reference the data as
922
 
    'char *data' and then call this method using '..->buf2val((void**)&data)'.
923
 
    Then free the storage once you're done using 'delete[] data'. It's not
924
 
    correct C++ to use 'delete[]' on a void pointer and the allocated memory
925
 
    \e is an array of char, so 'delete[]' is needed.
926
 
 
927
 
    @return The number of bytes used to store the array.
928
 
    @param val A pointer to a pointer to the memory into which the
929
 
    class data will be copied.  If the value pointed to is NULL,
930
 
    memory will be allocated to hold the data, and the pointer value
931
 
    modified accordingly.  The calling program is responsible for
932
 
    deallocating the memory indicated by this pointer.
933
 
    @exception InternalErr Thrown if \e val is null.
934
 
    @see Vector::set_vec */
 
893
 <i>val</i> points to an array large enough to hold N instances of
 
894
 the `C' representation of the \e numeric element type or C++ string
 
895
 objects. Never call this method for constructor types Structure,
 
896
 Sequence or Grid.
 
897
 
 
898
 When reading data out of a variable that has been constrained, this method
 
899
 assumes the N values/bytes of constrained data start at the beginning
 
900
 of the object's internal buffer. For example, do not load an entire
 
901
 Vector's data using val2buf(), constrain and then use this method to
 
902
 get the data. Unless your constraint starts with the [0]th element, the
 
903
 result will not be the correct values.
 
904
 
 
905
 In the case of a Vector of Str objects, this method will return an array
 
906
 of C++ std::string objects.
 
907
 
 
908
 @note It's best to define the pointer to reference the data as
 
909
 'char *data' and then call this method using '..->buf2val((void**)&data)'.
 
910
 Then free the storage once you're done using 'delete[] data'. It's not
 
911
 correct C++ to use 'delete[]' on a void pointer and the allocated memory
 
912
 \e is an array of char, so 'delete[]' is needed.
 
913
 
 
914
 @return The number of bytes used to store the array.
 
915
 @param val A pointer to a pointer to the memory into which the
 
916
 class data will be copied.  If the value pointed to is NULL,
 
917
 memory will be allocated to hold the data, and the pointer value
 
918
 modified accordingly.  The calling program is responsible for
 
919
 deallocating the memory indicated by this pointer.
 
920
 @exception InternalErr Thrown if \e val is null.
 
921
 @see Vector::set_vec */
935
922
unsigned int Vector::buf2val(void **val)
936
923
{
937
924
    // Jose Garcia
939
926
    if (!val)
940
927
        throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
941
928
 
942
 
    unsigned int wid = static_cast<unsigned int>(width());
 
929
    unsigned int wid = static_cast<unsigned int> (width(true /* constrained */));
943
930
    // This is the width computed using length(). The
944
931
    // length() property is changed when a projection
945
932
    // constraint is applied. Thus this is the number of
946
933
    // bytes in the buffer given the current constraint.
947
934
 
948
935
    switch (_var->type()) {
949
 
    case dods_byte_c:
950
 
    case dods_int16_c:
951
 
    case dods_uint16_c:
952
 
    case dods_int32_c:
953
 
    case dods_uint32_c:
954
 
    case dods_float32_c:
955
 
    case dods_float64_c:
956
 
        if (!*val) {
957
 
            *val = new char[wid];
958
 
        }
959
 
        // avoid bus error if _buf is null and this is called improperly.
960
 
        if (!_buf) {
961
 
          throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: Logic error: called when _buf was null!");
962
 
        }
963
 
 
964
 
        (void) memcpy(*val, _buf, wid);
965
 
 
966
 
        break;
967
 
 
968
 
    case dods_str_c:
969
 
    case dods_url_c: {
 
936
        case dods_byte_c:
 
937
        case dods_int16_c:
 
938
        case dods_uint16_c:
 
939
        case dods_int32_c:
 
940
        case dods_uint32_c:
 
941
        case dods_float32_c:
 
942
        case dods_float64_c:
 
943
            if (!*val) {
 
944
                *val = new char[wid];
 
945
            }
 
946
            // avoid bus error if _buf is null and this is called improperly.
 
947
            if (!_buf) {
 
948
                throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: Logic error: called when _buf was null!");
 
949
            }
 
950
 
 
951
            (void) memcpy(*val, _buf, wid);
 
952
 
 
953
            break;
 
954
 
 
955
        case dods_str_c:
 
956
        case dods_url_c: {
970
957
            if (!*val)
971
 
                *val = new string[_length];
 
958
                *val = new string[d_length];
972
959
 
973
 
            for (int i = 0; i < _length; ++i)
974
 
                *(static_cast < string * >(*val) + i) = d_str[i];
 
960
            for (int i = 0; i < d_length; ++i)
 
961
                *(static_cast<string *> (*val) + i) = d_str[i];
975
962
 
976
963
            break;
977
964
        }
978
965
 
979
 
    default:
980
 
        throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: bad type");
981
 
        return 0;
 
966
        default:
 
967
            throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: bad type");
 
968
            return 0;
982
969
    }
983
970
 
984
971
    return wid;
985
972
}
986
973
 
987
974
/** Sets an element of the vector to a given value.  If the type of
988
 
    the input and the type of the Vector do not match, an error
989
 
    condition is returned.
990
 
 
991
 
    Use this function only with Vectors containing compound DAP2
992
 
    types.  See <tt>buf2val()</tt> to access members of Vectors containing
993
 
    simple types.
994
 
 
995
 
    @note This method copies \e val; the caller is responsible for deleting
996
 
    instance passed as the actual parameter.
997
 
 
998
 
    @brief Sets element <i>i</i> to value <i>val</i>.
999
 
    @return void
1000
 
    @exception InternalErr Thrown if \e i is out of range, \e val is null or
1001
 
    there was a type mismatch between the BaseType referenced by \e val and
1002
 
    the \e ith element of this Vector.
1003
 
    @param i The index of the element to be changed.
1004
 
    @param val A pointer to the value to be inserted into the
1005
 
    array.
1006
 
    @see Vector::buf2val */
 
975
 the input and the type of the Vector do not match, an error
 
976
 condition is returned.
 
977
 
 
978
 Use this function only with Vectors containing compound DAP2
 
979
 types.  See <tt>buf2val()</tt> to access members of Vectors containing
 
980
 simple types.
 
981
 
 
982
 @note This method copies \e val; the caller is responsible for deleting
 
983
 instance passed as the actual parameter.
 
984
 
 
985
 @brief Sets element <i>i</i> to value <i>val</i>.
 
986
 @return void
 
987
 @exception InternalErr Thrown if \e i is out of range, \e val is null or
 
988
 there was a type mismatch between the BaseType referenced by \e val and
 
989
 the \e ith element of this Vector.
 
990
 @param i The index of the element to be changed.
 
991
 @param val A pointer to the value to be inserted into the
 
992
 array.
 
993
 @see Vector::buf2val */
1007
994
void Vector::set_vec(unsigned int i, BaseType * val)
1008
995
{
1009
996
    // Jose Garcia
1010
997
    // This is a public method which allows users to set the elements
1011
998
    // of *this* vector. Passing an invalid index, a NULL pointer or
1012
999
    // mismatching the vector type are internal errors.
1013
 
    if (i >= static_cast < unsigned int >(_length))
1014
 
        throw InternalErr(__FILE__, __LINE__,
1015
 
                          "Invalid data: index too large.");
 
1000
    if (i >= static_cast<unsigned int> (d_length))
 
1001
        throw InternalErr(__FILE__, __LINE__, "Invalid data: index too large.");
1016
1002
    if (!val)
1017
 
        throw InternalErr(__FILE__, __LINE__,
1018
 
                          "Invalid data: null pointer to BaseType object.");
 
1003
        throw InternalErr(__FILE__, __LINE__, "Invalid data: null pointer to BaseType object.");
1019
1004
    if (val->type() != _var->type())
1020
 
        throw InternalErr(__FILE__, __LINE__,
1021
 
                          "invalid data: type of incoming object does not match *this* vector type.");
 
1005
        throw InternalErr(__FILE__, __LINE__, "invalid data: type of incoming object does not match *this* vector type.");
1022
1006
 
1023
1007
    if (i >= _vec.capacity())
1024
1008
        vec_resize(i + 10);
1035
1019
 * NOTE: this is not virtual, and only affects the data in Vector itself!
1036
1020
 * On exit: get_value_capacity() == 0 && !read_p()
1037
1021
 */
1038
 
void
1039
 
Vector::clear_local_data()
 
1022
void Vector::clear_local_data()
1040
1023
{
1041
 
  if (_buf) {
1042
 
    delete[]_buf;
1043
 
    _buf = 0;
1044
 
  }
1045
 
 
1046
 
  for (unsigned int i = 0; i < _vec.size(); ++i) {
1047
 
    delete _vec[i];
1048
 
    _vec[i] = 0;
1049
 
  }
1050
 
 
1051
 
  // Force memory to be reclaimed.
1052
 
  _vec.resize(0);
1053
 
  d_str.resize(0);
1054
 
 
1055
 
  _capacity = 0;
1056
 
  set_read_p(false);
 
1024
    if (_buf) {
 
1025
        delete[] _buf;
 
1026
        _buf = 0;
 
1027
    }
 
1028
 
 
1029
    for (unsigned int i = 0; i < _vec.size(); ++i) {
 
1030
        delete _vec[i];
 
1031
        _vec[i] = 0;
 
1032
    }
 
1033
 
 
1034
    // Force memory to be reclaimed.
 
1035
    _vec.resize(0);
 
1036
    d_str.resize(0);
 
1037
 
 
1038
    _capacity = 0;
 
1039
    set_read_p(false);
1057
1040
}
1058
1041
 
1059
 
 
1060
1042
/**
1061
1043
 * Return the capacity of the Vector in terms of number of
1062
1044
 * elements of its data type that it CAN currently hold (i.e. not bytes).
1063
1045
 * For example, this could be
1064
1046
 * the size of the _buf array in bytes / sizeof(T) for the cardinal
1065
1047
 * types T, or the capacity of the d_str vector if T is string or url type.
1066
 
*/
1067
 
unsigned int
1068
 
Vector::get_value_capacity() const
 
1048
 */
 
1049
unsigned int Vector::get_value_capacity() const
1069
1050
{
1070
 
  return _capacity;
 
1051
    return _capacity;
1071
1052
}
1072
1053
 
1073
 
 
1074
1054
/**
1075
1055
 * Allocate enough memory for the Vector to contain
1076
1056
 * numElements data elements of the Vector's type.
1080
1060
 *                     to preallocate storage for.
1081
1061
 * @exception if the memory cannot be allocated
1082
1062
 */
1083
 
void
1084
 
Vector::reserve_value_capacity(unsigned int numElements)
 
1063
void Vector::reserve_value_capacity(unsigned int numElements)
1085
1064
{
1086
 
  if (!_var) {
1087
 
   throw InternalErr(__FILE__, __LINE__,
1088
 
       "reserve_value_capacity: Logic error: _var is null!");
1089
 
  }
1090
 
  switch (_var->type()) {
1091
 
     case dods_byte_c:
1092
 
     case dods_int16_c:
1093
 
     case dods_uint16_c:
1094
 
     case dods_int32_c:
1095
 
     case dods_uint32_c:
1096
 
     case dods_float32_c:
1097
 
     case dods_float64_c: {
1098
 
         // Make _buf be the right size and set _capacity
1099
 
         create_cardinal_data_buffer_for_type(numElements);
1100
 
       }
1101
 
       break;
1102
 
 
1103
 
     case dods_str_c:
1104
 
     case dods_url_c: {
1105
 
         // Make sure the d_str has enough room for all the strings.
1106
 
         // Technically not needed, but it will speed things up for large arrays.
1107
 
         d_str.reserve(numElements);
1108
 
         _capacity = numElements;
1109
 
       }
1110
 
       break;
1111
 
 
1112
 
 
1113
 
     case dods_array_c:
1114
 
     case dods_structure_c:
1115
 
     case dods_sequence_c:
1116
 
     case dods_grid_c: {
1117
 
         // not clear anyone will go this path, but best to be complete.
1118
 
         _vec.reserve(numElements);
1119
 
         _capacity = numElements;
1120
 
       }
1121
 
      break;
1122
 
 
1123
 
     default: {
1124
 
         throw InternalErr(__FILE__, __LINE__, "reserve_value_capacity: Unknown type!");
1125
 
       }
1126
 
     break;
1127
 
 
1128
 
  } // switch
 
1065
    if (!_var) {
 
1066
        throw InternalErr(__FILE__, __LINE__, "reserve_value_capacity: Logic error: _var is null!");
 
1067
    }
 
1068
    switch (_var->type()) {
 
1069
        case dods_byte_c:
 
1070
        case dods_int16_c:
 
1071
        case dods_uint16_c:
 
1072
        case dods_int32_c:
 
1073
        case dods_uint32_c:
 
1074
        case dods_float32_c:
 
1075
        case dods_float64_c: {
 
1076
            // Make _buf be the right size and set _capacity
 
1077
            m_create_cardinal_data_buffer_for_type(numElements);
 
1078
        }
 
1079
            break;
 
1080
 
 
1081
        case dods_str_c:
 
1082
        case dods_url_c: {
 
1083
            // Make sure the d_str has enough room for all the strings.
 
1084
            // Technically not needed, but it will speed things up for large arrays.
 
1085
            d_str.reserve(numElements);
 
1086
            _capacity = numElements;
 
1087
        }
 
1088
            break;
 
1089
 
 
1090
        case dods_array_c:
 
1091
        case dods_structure_c:
 
1092
        case dods_sequence_c:
 
1093
        case dods_grid_c: {
 
1094
            // not clear anyone will go this path, but best to be complete.
 
1095
            _vec.reserve(numElements);
 
1096
            _capacity = numElements;
 
1097
        }
 
1098
            break;
 
1099
 
 
1100
        default: {
 
1101
            throw InternalErr(__FILE__, __LINE__, "reserve_value_capacity: Unknown type!");
 
1102
        }
 
1103
            break;
 
1104
 
 
1105
    } // switch
1129
1106
 
1130
1107
}
1131
1108
 
1134
1111
 * of the Vector.
1135
1112
 * Same as reserveValueCapacity(length())
1136
1113
 */
1137
 
void
1138
 
Vector::reserve_value_capacity()
 
1114
void Vector::reserve_value_capacity()
1139
1115
{
1140
 
  // Use the current length of the vector as the reserve amount.
1141
 
  reserve_value_capacity(length());
 
1116
    // Use the current length of the vector as the reserve amount.
 
1117
    reserve_value_capacity(length());
1142
1118
}
1143
1119
 
1144
1120
/**
1169
1145
 * @return the number of elements added, such that:
1170
1146
 *         startElement + the return value is the next "free" element.
1171
1147
 */
1172
 
unsigned int
1173
 
Vector::set_value_slice_from_row_major_vector(const Vector& rowMajorDataC, unsigned int startElement)
 
1148
unsigned int Vector::set_value_slice_from_row_major_vector(const Vector& rowMajorDataC, unsigned int startElement)
1174
1149
{
1175
 
  static const string funcName = "set_value_slice_from_row_major_vector:";
1176
 
 
1177
 
  // semantically const from the caller's viewpoint, but some calls are not syntactic const.
1178
 
  Vector& rowMajorData = const_cast<Vector&>(rowMajorDataC);
1179
 
 
1180
 
  bool typesMatch = rowMajorData.var() && _var && (rowMajorData.var()->type() == _var->type());
1181
 
  if (!typesMatch) {
1182
 
    throw InternalErr(__FILE__, __LINE__,
1183
 
        funcName + "Logic error: types do not match so cannot be copied!");
1184
 
  }
1185
 
 
1186
 
  // Make sure the data exists
1187
 
  if (!rowMajorData.read_p()) {
1188
 
    throw InternalErr(__FILE__, __LINE__,
1189
 
        funcName + "Logic error: the Vector to copy data from has !read_p() and should have been read in!");
1190
 
  }
1191
 
 
1192
 
  // Check this otherwise the static_cast<unsigned int> below will do the wrong thing.
1193
 
  if (rowMajorData.length() < 0) {
1194
 
    throw InternalErr(__FILE__, __LINE__,
1195
 
            funcName + "Logic error: the Vector to copy data from has length() < 0 and was probably not initialized!");
1196
 
  }
1197
 
 
1198
 
  // The read-in capacity had better be at least the length (the amountt we will copy) or we'll memcpy into bad memory
1199
 
  // I imagine we could copy just the capacity rather than throw, but I really think this implies a problem to be addressed.
1200
 
  if (rowMajorData.get_value_capacity() < static_cast<unsigned int>(rowMajorData.length())) {
1201
 
    throw InternalErr(__FILE__, __LINE__,
1202
 
        funcName + "Logic error: the Vector to copy from has a data capacity less than its length, can't copy!");
1203
 
  }
1204
 
 
1205
 
  // Make sure there's enough room in this Vector to store all the elements requested.  Again,
1206
 
  // better to throw than just copy what we can since it implies a logic error that needs to be solved.
1207
 
  if (_capacity < (startElement + rowMajorData.length())) {
1208
 
    throw InternalErr(__FILE__, __LINE__,
1209
 
        funcName + "Logic error: the capacity of this Vector cannot hold all the data in the from Vector!");
1210
 
  }
1211
 
 
1212
 
  // OK, at this point we're pretty sure we can copy the data, but we have to do it differently depending on type.
1213
 
  switch (_var->type()) {
1214
 
      case dods_byte_c:
1215
 
      case dods_int16_c:
1216
 
      case dods_uint16_c:
1217
 
      case dods_int32_c:
1218
 
      case dods_uint32_c:
1219
 
      case dods_float32_c:
1220
 
      case dods_float64_c: {
1221
 
        if (!_buf) {
1222
 
          throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: this->_buf was unexpectedly null!");
1223
 
        }
1224
 
        if (!rowMajorData._buf) {
1225
 
          throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: rowMajorData._buf was unexpectedly null!");
1226
 
        }
1227
 
        // memcpy the data into this, taking care to do ptr arithmetic on bytes and not sizeof(element)
1228
 
        int varWidth = _var->width();
1229
 
        char* pFromBuf = rowMajorData._buf;
1230
 
        int numBytesToCopy = rowMajorData.width();
1231
 
        char* pIntoBuf = _buf + (startElement * varWidth);
1232
 
        memcpy(pIntoBuf,
1233
 
               pFromBuf,
1234
 
               numBytesToCopy );
1235
 
      }
1236
 
      break;
1237
 
 
1238
 
      case dods_str_c:
1239
 
      case dods_url_c: {
1240
 
        // Strings need to be copied directly
1241
 
        for (unsigned int i = 0; i < static_cast<unsigned int>(rowMajorData.length()); ++i) {
1242
 
          d_str[startElement + i] = rowMajorData.d_str[i];
1243
 
        }
1244
 
      }
1245
 
      break;
1246
 
 
1247
 
      case dods_array_c:
1248
 
      case dods_structure_c:
1249
 
      case dods_sequence_c:
1250
 
      case dods_grid_c: {
1251
 
        // Not sure that this function will be used for these type of nested objects, so I will throw here.
1252
 
        // TODO impl and test this path if it's ever needed.
1253
 
        throw InternalErr(__FILE__, __LINE__,
1254
 
            funcName + "Unimplemented method for Vectors of type: dods_array_c, dods_structure_c, dods_sequence_c and dods_grid_c.");
1255
 
      }
1256
 
      break;
1257
 
 
1258
 
      default: {
1259
 
        throw InternalErr(__FILE__, __LINE__, funcName + ": Unknown type!");
1260
 
      }
1261
 
      break;
1262
 
 
1263
 
  } // switch (_var->type())
1264
 
 
1265
 
  // This is how many elements we copied.
1266
 
  return (unsigned int)rowMajorData.length();
 
1150
    static const string funcName = "set_value_slice_from_row_major_vector:";
 
1151
 
 
1152
    // semantically const from the caller's viewpoint, but some calls are not syntactic const.
 
1153
    Vector& rowMajorData = const_cast<Vector&> (rowMajorDataC);
 
1154
 
 
1155
    bool typesMatch = rowMajorData.var() && _var && (rowMajorData.var()->type() == _var->type());
 
1156
    if (!typesMatch) {
 
1157
        throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: types do not match so cannot be copied!");
 
1158
    }
 
1159
 
 
1160
    // Make sure the data exists
 
1161
    if (!rowMajorData.read_p()) {
 
1162
        throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: the Vector to copy data from has !read_p() and should have been read in!");
 
1163
    }
 
1164
 
 
1165
    // Check this otherwise the static_cast<unsigned int> below will do the wrong thing.
 
1166
    if (rowMajorData.length() < 0) {
 
1167
        throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: the Vector to copy data from has length() < 0 and was probably not initialized!");
 
1168
    }
 
1169
 
 
1170
    // The read-in capacity had better be at least the length (the amountt we will copy) or we'll memcpy into bad memory
 
1171
    // I imagine we could copy just the capacity rather than throw, but I really think this implies a problem to be addressed.
 
1172
    if (rowMajorData.get_value_capacity() < static_cast<unsigned int> (rowMajorData.length())) {
 
1173
        throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: the Vector to copy from has a data capacity less than its length, can't copy!");
 
1174
    }
 
1175
 
 
1176
    // Make sure there's enough room in this Vector to store all the elements requested.  Again,
 
1177
    // better to throw than just copy what we can since it implies a logic error that needs to be solved.
 
1178
    if (_capacity < (startElement + rowMajorData.length())) {
 
1179
        throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: the capacity of this Vector cannot hold all the data in the from Vector!");
 
1180
    }
 
1181
 
 
1182
    // OK, at this point we're pretty sure we can copy the data, but we have to do it differently depending on type.
 
1183
    switch (_var->type()) {
 
1184
        case dods_byte_c:
 
1185
        case dods_int16_c:
 
1186
        case dods_uint16_c:
 
1187
        case dods_int32_c:
 
1188
        case dods_uint32_c:
 
1189
        case dods_float32_c:
 
1190
        case dods_float64_c: {
 
1191
            if (!_buf) {
 
1192
                throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: this->_buf was unexpectedly null!");
 
1193
            }
 
1194
            if (!rowMajorData._buf) {
 
1195
                throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: rowMajorData._buf was unexpectedly null!");
 
1196
            }
 
1197
            // memcpy the data into this, taking care to do ptr arithmetic on bytes and not sizeof(element)
 
1198
            int varWidth = _var->width();
 
1199
            char* pFromBuf = rowMajorData._buf;
 
1200
            int numBytesToCopy = rowMajorData.width(true);
 
1201
            char* pIntoBuf = _buf + (startElement * varWidth);
 
1202
            memcpy(pIntoBuf, pFromBuf, numBytesToCopy);
 
1203
        }
 
1204
            break;
 
1205
 
 
1206
        case dods_str_c:
 
1207
        case dods_url_c: {
 
1208
            // Strings need to be copied directly
 
1209
            for (unsigned int i = 0; i < static_cast<unsigned int> (rowMajorData.length()); ++i) {
 
1210
                d_str[startElement + i] = rowMajorData.d_str[i];
 
1211
            }
 
1212
        }
 
1213
            break;
 
1214
 
 
1215
        case dods_array_c:
 
1216
        case dods_structure_c:
 
1217
        case dods_sequence_c:
 
1218
        case dods_grid_c: {
 
1219
            // Not sure that this function will be used for these type of nested objects, so I will throw here.
 
1220
            // TODO impl and test this path if it's ever needed.
 
1221
            throw InternalErr(__FILE__, __LINE__, funcName + "Unimplemented method for Vectors of type: dods_array_c, dods_structure_c, dods_sequence_c and dods_grid_c.");
 
1222
        }
 
1223
            break;
 
1224
 
 
1225
        default: {
 
1226
            throw InternalErr(__FILE__, __LINE__, funcName + ": Unknown type!");
 
1227
        }
 
1228
            break;
 
1229
 
 
1230
    } // switch (_var->type())
 
1231
 
 
1232
    // This is how many elements we copied.
 
1233
    return (unsigned int) rowMajorData.length();
1267
1234
}
1268
1235
 
1269
1236
//@{
1270
1237
/** @brief set the value of a byte array */
1271
 
bool
1272
 
Vector::set_value(dods_byte *val, int sz)
 
1238
bool Vector::set_value(dods_byte *val, int sz)
1273
1239
{
1274
1240
    if (var()->type() == dods_byte_c && val) {
1275
 
      set_cardinal_values_internal<dods_byte>(val, sz);
1276
 
      return true;
 
1241
        set_cardinal_values_internal<dods_byte> (val, sz);
 
1242
        return true;
1277
1243
    }
1278
1244
    else {
1279
1245
        return false;
1281
1247
}
1282
1248
 
1283
1249
/** @brief set the value of a byte array */
1284
 
bool
1285
 
Vector::set_value(vector<dods_byte> &val, int sz)
 
1250
bool Vector::set_value(vector<dods_byte> &val, int sz)
1286
1251
{
1287
1252
    return set_value(&val[0], sz);
1288
1253
}
1289
1254
 
1290
1255
/** @brief set the value of a int16 array */
1291
 
bool
1292
 
Vector::set_value(dods_int16 *val, int sz)
 
1256
bool Vector::set_value(dods_int16 *val, int sz)
1293
1257
{
1294
1258
    if (var()->type() == dods_int16_c && val) {
1295
 
      set_cardinal_values_internal<dods_int16>(val, sz);
1296
 
      return true;
 
1259
        set_cardinal_values_internal<dods_int16> (val, sz);
 
1260
        return true;
1297
1261
    }
1298
1262
    else {
1299
1263
        return false;
1301
1265
}
1302
1266
 
1303
1267
/** @brief set the value of a int16 array */
1304
 
bool
1305
 
Vector::set_value(vector<dods_int16> &val, int sz)
 
1268
bool Vector::set_value(vector<dods_int16> &val, int sz)
1306
1269
{
1307
1270
    return set_value(&val[0], sz);
1308
1271
}
1309
1272
 
1310
1273
/** @brief set the value of a int32 array */
1311
 
bool
1312
 
Vector::set_value(dods_int32 *val, int sz)
 
1274
bool Vector::set_value(dods_int32 *val, int sz)
1313
1275
{
1314
1276
    if (var()->type() == dods_int32_c && val) {
1315
 
       set_cardinal_values_internal<dods_int32>(val, sz);
1316
 
       return true;
 
1277
        set_cardinal_values_internal<dods_int32> (val, sz);
 
1278
        return true;
1317
1279
    }
1318
1280
    else {
1319
1281
        return false;
1321
1283
}
1322
1284
 
1323
1285
/** @brief set the value of a int32 array */
1324
 
bool
1325
 
Vector::set_value(vector<dods_int32> &val, int sz)
 
1286
bool Vector::set_value(vector<dods_int32> &val, int sz)
1326
1287
{
1327
1288
    return set_value(&val[0], sz);
1328
1289
}
1329
1290
 
1330
1291
/** @brief set the value of a uint16 array */
1331
 
bool
1332
 
Vector::set_value(dods_uint16 *val, int sz)
 
1292
bool Vector::set_value(dods_uint16 *val, int sz)
1333
1293
{
1334
1294
    if (var()->type() == dods_uint16_c && val) {
1335
 
      set_cardinal_values_internal<dods_uint16>(val, sz);
1336
 
      return true;
 
1295
        set_cardinal_values_internal<dods_uint16> (val, sz);
 
1296
        return true;
1337
1297
    }
1338
1298
    else {
1339
1299
        return false;
1341
1301
}
1342
1302
 
1343
1303
/** @brief set the value of a uint16 array */
1344
 
bool
1345
 
Vector::set_value(vector<dods_uint16> &val, int sz)
 
1304
bool Vector::set_value(vector<dods_uint16> &val, int sz)
1346
1305
{
1347
1306
    return set_value(&val[0], sz);
1348
1307
}
1349
1308
 
1350
1309
/** @brief set the value of a uint32 array */
1351
 
bool
1352
 
Vector::set_value(dods_uint32 *val, int sz)
 
1310
bool Vector::set_value(dods_uint32 *val, int sz)
1353
1311
{
1354
1312
    if (var()->type() == dods_uint32_c && val) {
1355
 
        set_cardinal_values_internal<dods_uint32>(val, sz);
 
1313
        set_cardinal_values_internal<dods_uint32> (val, sz);
1356
1314
        return true;
1357
1315
    }
1358
1316
    else {
1361
1319
}
1362
1320
 
1363
1321
/** @brief set the value of a uint32 array */
1364
 
bool
1365
 
Vector::set_value(vector<dods_uint32> &val, int sz)
 
1322
bool Vector::set_value(vector<dods_uint32> &val, int sz)
1366
1323
{
1367
1324
    return set_value(&val[0], sz);
1368
1325
}
1369
1326
 
1370
1327
/** @brief set the value of a float32 array */
1371
 
bool
1372
 
Vector::set_value(dods_float32 *val, int sz)
 
1328
bool Vector::set_value(dods_float32 *val, int sz)
1373
1329
{
1374
1330
    if (var()->type() == dods_float32_c && val) {
1375
 
        set_cardinal_values_internal<dods_float32>(val, sz);
 
1331
        set_cardinal_values_internal<dods_float32> (val, sz);
1376
1332
        return true;
1377
1333
    }
1378
1334
    else {
1381
1337
}
1382
1338
 
1383
1339
/** @brief set the value of a float32 array */
1384
 
bool
1385
 
Vector::set_value(vector<dods_float32> &val, int sz)
 
1340
bool Vector::set_value(vector<dods_float32> &val, int sz)
1386
1341
{
1387
1342
    return set_value(&val[0], sz);
1388
1343
}
1389
1344
 
1390
1345
/** @brief set the value of a float64 array */
1391
 
bool
1392
 
Vector::set_value(dods_float64 *val, int sz)
 
1346
bool Vector::set_value(dods_float64 *val, int sz)
1393
1347
{
1394
1348
    if (var()->type() == dods_float64_c && val) {
1395
 
      set_cardinal_values_internal<dods_float64>(val, sz);
1396
 
      return true;
 
1349
        set_cardinal_values_internal<dods_float64> (val, sz);
 
1350
        return true;
1397
1351
    }
1398
1352
    else {
1399
 
      return false;
 
1353
        return false;
1400
1354
    }
1401
1355
}
1402
1356
 
1403
1357
/** @brief set the value of a float64 array */
1404
 
bool
1405
 
Vector::set_value(vector<dods_float64> &val, int sz)
 
1358
bool Vector::set_value(vector<dods_float64> &val, int sz)
1406
1359
{
1407
1360
    return set_value(&val[0], sz);
1408
1361
}
1409
1362
 
1410
1363
/** @brief set the value of a string or url array */
1411
 
bool
1412
 
Vector::set_value(string *val, int sz)
 
1364
bool Vector::set_value(string *val, int sz)
1413
1365
{
1414
1366
    if ((var()->type() == dods_str_c || var()->type() == dods_url_c) && val) {
1415
1367
        d_str.resize(sz);
1416
1368
        _capacity = sz;
1417
1369
        for (register int t = 0; t < sz; t++) {
1418
 
            d_str[t] = val[t] ;
 
1370
            d_str[t] = val[t];
1419
1371
        }
1420
 
        set_length(sz) ;
 
1372
        set_length(sz);
1421
1373
        set_read_p(true);
1422
1374
        return true;
1423
1375
    }
1427
1379
}
1428
1380
 
1429
1381
/** @brief set the value of a string or url array */
1430
 
bool
1431
 
Vector::set_value(vector<string> &val, int sz)
 
1382
bool Vector::set_value(vector<string> &val, int sz)
1432
1383
{
1433
1384
    if (var()->type() == dods_str_c || var()->type() == dods_url_c) {
1434
1385
        d_str.resize(sz);
1435
1386
        _capacity = sz;
1436
1387
        for (register int t = 0; t < sz; t++) {
1437
 
            d_str[t] = val[t] ;
 
1388
            d_str[t] = val[t];
1438
1389
        }
1439
 
        set_length(sz) ;
 
1390
        set_length(sz);
1440
1391
        set_read_p(true);
1441
1392
        return true;
1442
1393
    }
1447
1398
//@}
1448
1399
 
1449
1400
//@{
 
1401
 
 
1402
/** @brief Get a copy of the data held by this variable using the passed subsetIndex vector to identify which values to return.
 
1403
 Read data from this variable's internal storage using the passed std::vector as an sub-setting index to the values to be returned. The
 
1404
 memory referenced by \c b must point to enough memory
 
1405
 to hold index.size() bytes.
 
1406
 
 
1407
 @param index A std::vector<long> where each value in the vector is the location in the Vector's internal storage from which to read the returned value
 
1408
 @param b A pointer to the memory to hold the data; must be at least
 
1409
 length() * sizeof(dods_byte) in size.*/
 
1410
void Vector::value(vector<unsigned int> *subsetIndex, dods_byte *b) const
 
1411
{
 
1412
    unsigned long currentIndex;
 
1413
 
 
1414
    for(unsigned long i=0; i<subsetIndex->size() ;++i){
 
1415
        currentIndex = (*subsetIndex)[i] ;
 
1416
        if(currentIndex> (unsigned int)length()){
 
1417
            stringstream s;
 
1418
            s << "Vector::value() - Subset index[" << i <<  "] = " << currentIndex << " references a value that is " <<
 
1419
                    "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
 
1420
            throw Error(s.str());
 
1421
        }
 
1422
        b[i] = reinterpret_cast<dods_byte*>(_buf )[currentIndex]; // I like this version - and it works!
 
1423
    }
 
1424
}
 
1425
 
 
1426
 
 
1427
/** @brief Get a copy of the data held by this variable using the passed subsetIndex vector to identify which values to return. **/
 
1428
void Vector::value(vector<unsigned int> *subsetIndex, dods_uint16 *b) const
 
1429
{
 
1430
    unsigned long currentIndex;
 
1431
 
 
1432
    for(unsigned long i=0; i<subsetIndex->size() ;++i){
 
1433
        currentIndex = (*subsetIndex)[i] ;
 
1434
        if(currentIndex> (unsigned int)length()){
 
1435
            stringstream s;
 
1436
            s << "Vector::value() - Subset index[" << i <<  "] = " << currentIndex << " references a value that is " <<
 
1437
                    "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
 
1438
            throw Error(s.str());
 
1439
        }
 
1440
        b[i] = reinterpret_cast<dods_uint16*>(_buf )[currentIndex]; // I like this version - and it works!
 
1441
    }
 
1442
}
 
1443
 
 
1444
 
 
1445
/** @brief Get a copy of the data held by this variable using the passed subsetIndex vector to identify which values to return. **/
 
1446
void Vector::value(vector<unsigned int> *subsetIndex, dods_int16 *b) const
 
1447
{
 
1448
    unsigned long currentIndex;
 
1449
 
 
1450
    for(unsigned long i=0; i<subsetIndex->size() ;++i){
 
1451
        currentIndex = (*subsetIndex)[i] ;
 
1452
        if(currentIndex> (unsigned int)length()){
 
1453
            stringstream s;
 
1454
            s << "Vector::value() - Subset index[" << i <<  "] = " << currentIndex << " references a value that is " <<
 
1455
                    "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
 
1456
            throw Error(s.str());
 
1457
        }
 
1458
        b[i] = reinterpret_cast<dods_int16*>(_buf )[currentIndex]; // I like this version - and it works!
 
1459
    }
 
1460
}
 
1461
 
 
1462
/** @brief Get a copy of the data held by this variable using the passed subsetIndex vector to identify which values to return. **/
 
1463
void Vector::value(vector<unsigned int> *subsetIndex, dods_uint32 *b) const
 
1464
{
 
1465
    unsigned long currentIndex;
 
1466
 
 
1467
    for(unsigned long i=0; i<subsetIndex->size() ;++i){
 
1468
        currentIndex = (*subsetIndex)[i] ;
 
1469
        if(currentIndex> (unsigned int)length()){
 
1470
            stringstream s;
 
1471
            s << "Vector::value() - Subset index[" << i <<  "] = " << currentIndex << " references a value that is " <<
 
1472
                    "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
 
1473
            throw Error(s.str());
 
1474
        }
 
1475
        b[i] = reinterpret_cast<dods_uint32*>(_buf )[currentIndex]; // I like this version - and it works!
 
1476
    }
 
1477
}
 
1478
 
 
1479
/** @brief Get a copy of the data held by this variable using the passed subsetIndex vector to identify which values to return. **/
 
1480
void Vector::value(vector<unsigned int> *subsetIndex, dods_int32 *b) const
 
1481
{
 
1482
    unsigned long currentIndex;
 
1483
 
 
1484
    for(unsigned long i=0; i<subsetIndex->size() ;++i){
 
1485
        currentIndex = (*subsetIndex)[i] ;
 
1486
        if(currentIndex> (unsigned int)length()){
 
1487
            stringstream s;
 
1488
            s << "Vector::value() - Subset index[" << i <<  "] = " << currentIndex << " references a value that is " <<
 
1489
                    "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
 
1490
            throw Error(s.str());
 
1491
        }
 
1492
        b[i] = reinterpret_cast<dods_int32*>(_buf )[currentIndex]; // I like this version - and it works!
 
1493
    }
 
1494
}
 
1495
 
 
1496
/** @brief Get a copy of the data held by this variable using the passed subsetIndex vector to identify which values to return. **/
 
1497
void Vector::value(vector<unsigned int> *subsetIndex, dods_float32 *b) const
 
1498
{
 
1499
    unsigned long currentIndex;
 
1500
 
 
1501
    for(unsigned long i=0; i<subsetIndex->size() ;++i){
 
1502
        currentIndex = (*subsetIndex)[i] ;
 
1503
        //cerr << "currentIndex: " << currentIndex << endl;
 
1504
        if(currentIndex> (unsigned int)length()){
 
1505
            stringstream s;
 
1506
            s << "Vector::value() - Subset index[" << i <<  "] = " << currentIndex << " references a value that is " <<
 
1507
                    "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
 
1508
            throw Error(s.str());
 
1509
        }
 
1510
        // b[i] = *reinterpret_cast<dods_float32*>(_buf ) + currentIndex; // BROKEN
 
1511
        // b[i] = *(reinterpret_cast<dods_float32*>(_buf ) + currentIndex); // Works but I like other forms
 
1512
        // b[i] = ((dods_float32*)_buf )[currentIndex]; // Works but isn't as 'safe'
 
1513
 
 
1514
        b[i] = reinterpret_cast<dods_float32*>(_buf )[currentIndex]; // I like this version - and it works!
 
1515
 
 
1516
        //cerr << "b[" << i << "]=" <<  b[i] << endl;
 
1517
    }
 
1518
}
 
1519
 
 
1520
/** @brief Get a copy of the data held by this variable using the passed subsetIndex vector to identify which values to return. **/
 
1521
void Vector::value(vector<unsigned int> *subsetIndex, dods_float64 *b) const
 
1522
{
 
1523
    unsigned long currentIndex;
 
1524
 
 
1525
    for(unsigned long i=0; i<subsetIndex->size() ;++i){
 
1526
        currentIndex = (*subsetIndex)[i] ;
 
1527
        if(currentIndex> (unsigned int)length()){
 
1528
            stringstream s;
 
1529
            s << "Vector::value() - Subset index[" << i <<  "] = " << currentIndex << " references a value that is " <<
 
1530
                    "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
 
1531
            throw Error(s.str());
 
1532
        }
 
1533
        b[i] = reinterpret_cast<dods_float64*>(_buf )[currentIndex]; // I like this version - and it works!
 
1534
    }
 
1535
}
 
1536
 
 
1537
 
 
1538
/** @brief Get a copy of the data held by this variable using the passed subsetIndex vector to identify which values to return. **/
 
1539
void Vector::value(vector<unsigned int> *subsetIndex, vector<string> &b) const
 
1540
{
 
1541
    unsigned long currentIndex;
 
1542
 
 
1543
    if (_var->type() == dods_str_c || _var->type() == dods_url_c){
 
1544
        for(unsigned long i=0; i<subsetIndex->size() ;++i){
 
1545
            currentIndex = (*subsetIndex)[i] ;
 
1546
            if(currentIndex > (unsigned int)length()){
 
1547
                stringstream s;
 
1548
                s << "Vector::value() - Subset index[" << i <<  "] = " << currentIndex << " references a value that is " <<
 
1549
                        "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
 
1550
                throw Error(s.str());
 
1551
            }
 
1552
            b[i] = d_str[currentIndex];
 
1553
        }
 
1554
    }
 
1555
}
 
1556
 
 
1557
 
 
1558
 
 
1559
 
 
1560
 
 
1561
 
 
1562
 
1450
1563
/** @brief Get a copy of the data held by this variable.
1451
 
    Read data from this variable's internal storage and load it into the
1452
 
    memory referenced by \c b. The argument \c b must point to enough memory
1453
 
    to hold length() Bytes.
 
1564
 Read data from this variable's internal storage and load it into the
 
1565
 memory referenced by \c b. The argument \c b must point to enough memory
 
1566
 to hold length() Bytes.
1454
1567
 
1455
 
    @param b A pointer to the memory to hold the data; must be at least
1456
 
    length() * sizeof(dods_byte) in size.*/
 
1568
 @param b A pointer to the memory to hold the data; must be at least
 
1569
 length() * sizeof(dods_byte) in size.*/
1457
1570
void Vector::value(dods_byte *b) const
1458
1571
{
1459
1572
    if (b && _var->type() == dods_byte_c) {
1512
1625
/** @brief Get a copy of the data held by this variable. */
1513
1626
void Vector::value(vector<string> &b) const
1514
1627
{
1515
 
    if (_var->type() == dods_byte_c || _var->type() == dods_url_c)
 
1628
    if (_var->type() == dods_str_c || _var->type() == dods_url_c)
1516
1629
        b = d_str;
1517
1630
}
1518
1631
 
1519
1632
/** Allocated memory and copy data into the new buffer. Return the new
1520
 
    buffer's pointer. The caller must delete the storage. */
 
1633
 buffer's pointer. The caller must delete the storage. */
1521
1634
void *Vector::value()
1522
1635
{
1523
 
    void *buffer = new char[width()];
 
1636
    void *buffer = new char[width(true)];
1524
1637
 
1525
 
    memcpy(buffer, _buf, width());
 
1638
    memcpy(buffer, _buf, width(true));
1526
1639
 
1527
1640
    return buffer;
1528
1641
}
1529
1642
//@}
1530
1643
 
1531
1644
/** @brief Add the BaseType pointer to this constructor type
1532
 
    instance.
1533
 
 
1534
 
    Propagate the name of the BaseType instance to this instance. This
1535
 
    ensures that variables at any given level of the DDS table have
1536
 
    unique names (i.e., that Arrays do not have their default name ""). If
1537
 
    <tt>v</tt>'s name is null, then assume that the array \e is named and
1538
 
    don't overwrite it with <tt>v</tt>'s null name.
1539
 
 
1540
 
    @param v The template variable for the array
1541
 
    @param p The Part parameter defaults to nil and is ignored by this method.
1542
 
*/
 
1645
 instance.
 
1646
 
 
1647
 Propagate the name of the BaseType instance to this instance. This
 
1648
 ensures that variables at any given level of the DDS table have
 
1649
 unique names (i.e., that Arrays do not have their default name ""). If
 
1650
 <tt>v</tt>'s name is null, then assume that the array \e is named and
 
1651
 don't overwrite it with <tt>v</tt>'s null name.
 
1652
 
 
1653
 @note As is the case with Array, this method can be called with a null
 
1654
 BaseType pointer.
 
1655
 
 
1656
 @param v The template variable for the array
 
1657
 @param p The Part parameter defaults to nil and is ignored by this method.
 
1658
 */
1543
1659
void Vector::add_var(BaseType * v, Part)
1544
1660
{
 
1661
#if 0
 
1662
    if (v && v->is_dap4_only_type())
 
1663
        throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Vector.");
 
1664
#endif
1545
1665
    // Delete the current template variable
1546
 
    if( _var )
1547
 
    {
1548
 
        delete _var;
1549
 
        _var = 0 ;
 
1666
    if (_var) {
 
1667
        delete _var;
 
1668
        _var = 0;
1550
1669
    }
1551
1670
 
1552
1671
    // if 'v' is null, just set _var to null and exit.
1570
1689
        _var->set_parent(this); // Vector --> child
1571
1690
 
1572
1691
        DBG(cerr << "Vector::add_var: Added variable " << v << " ("
1573
 
            << v->name() << " " << v->type_name() << ")" << endl);
1574
 
    }
1575
 
}
 
1692
                << v->name() << " " << v->type_name() << ")" << endl);
 
1693
    }
 
1694
}
 
1695
 
 
1696
void Vector::add_var_nocopy(BaseType * v, Part)
 
1697
{
 
1698
#if 0
 
1699
    if (v && v->is_dap4_only_type())
 
1700
        throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Vector.");
 
1701
#endif
 
1702
    // Delete the current template variable
 
1703
    if (_var) {
 
1704
        delete _var;
 
1705
        _var = 0;
 
1706
    }
 
1707
 
 
1708
    // if 'v' is null, just set _var to null and exit.
 
1709
    if (!v) {
 
1710
        _var = 0;
 
1711
    }
 
1712
    else {
 
1713
        _var = v;
 
1714
 
 
1715
        // If 'v' has a name, use it as the name of the array. If it *is*
 
1716
        // empty, then make sure to copy the array's name to the template
 
1717
        // so that software which uses the template's name will still work.
 
1718
        if (!v->name().empty())
 
1719
            set_name(v->name());
 
1720
        else
 
1721
            _var->set_name(name());
 
1722
 
 
1723
        _var->set_parent(this); // Vector --> child
 
1724
 
 
1725
        DBG(cerr << "Vector::add_var: Added variable " << v << " ("
 
1726
                << v->name() << " " << v->type_name() << ")" << endl);
 
1727
    }
 
1728
}
 
1729
 
 
1730
#if 0
 
1731
// branch version
 
1732
void Vector::add_var_nocopy(BaseType * v, Part)
 
1733
{
 
1734
    // Delete the current template variable
 
1735
    if (_var) {
 
1736
        delete _var;
 
1737
        _var = 0;
 
1738
    }
 
1739
 
 
1740
    // if 'v' is null, just set _var to null and exit.
 
1741
    if (!v) {
 
1742
        _var = 0;
 
1743
    }
 
1744
    else {
 
1745
        _var = v;
 
1746
 
 
1747
        // If 'v' has a name, use it as the name of the array. If it *is*
 
1748
        // empty, then make sure to copy the array's name to the template
 
1749
        // so that software which uses the template's name will still work.
 
1750
        if (!v->name().empty())
 
1751
            set_name(v->name());
 
1752
        else
 
1753
            _var->set_name(name());
 
1754
 
 
1755
        _var->set_parent(this); // Vector --> child
 
1756
 
 
1757
        DBG(cerr << "Vector::add_var: Added variable " << v << " ("
 
1758
                << v->name() << " " << v->type_name() << ")" << endl);
 
1759
    }
 
1760
}
 
1761
#endif
1576
1762
 
1577
1763
bool Vector::check_semantics(string & msg, bool)
1578
1764
{
1587
1773
 * @param strm C++ i/o stream to dump the information to
1588
1774
 * @return void
1589
1775
 */
1590
 
void
1591
 
Vector::dump(ostream &strm) const
 
1776
void Vector::dump(ostream &strm) const
1592
1777
{
1593
 
    strm << DapIndent::LMarg << "Vector::dump - ("
1594
 
    << (void *)this << ")" << endl ;
1595
 
    DapIndent::Indent() ;
1596
 
    BaseType::dump(strm) ;
1597
 
    strm << DapIndent::LMarg << "# elements in vector: " << _length << endl ;
 
1778
    strm << DapIndent::LMarg << "Vector::dump - (" << (void *) this << ")" << endl;
 
1779
    DapIndent::Indent();
 
1780
    BaseType::dump(strm);
 
1781
    strm << DapIndent::LMarg << "# elements in vector: " << d_length << endl;
1598
1782
    if (_var) {
1599
 
        strm << DapIndent::LMarg << "base type:" << endl ;
1600
 
        DapIndent::Indent() ;
1601
 
        _var->dump(strm) ;
1602
 
        DapIndent::UnIndent() ;
 
1783
        strm << DapIndent::LMarg << "base type:" << endl;
 
1784
        DapIndent::Indent();
 
1785
        _var->dump(strm);
 
1786
        DapIndent::UnIndent();
1603
1787
    }
1604
1788
    else {
1605
 
        strm << DapIndent::LMarg << "base type: not set" << endl ;
 
1789
        strm << DapIndent::LMarg << "base type: not set" << endl;
1606
1790
    }
1607
 
    strm << DapIndent::LMarg << "vector contents:" << endl ;
1608
 
    DapIndent::Indent() ;
 
1791
    strm << DapIndent::LMarg << "vector contents:" << endl;
 
1792
    DapIndent::Indent();
1609
1793
    for (unsigned i = 0; i < _vec.size(); ++i) {
1610
1794
        if (_vec[i])
1611
 
            _vec[i]->dump(strm) ;
 
1795
            _vec[i]->dump(strm);
1612
1796
        else
1613
 
            strm << DapIndent::LMarg << "vec[" << i << "] is null" << endl ;
 
1797
            strm << DapIndent::LMarg << "vec[" << i << "] is null" << endl;
1614
1798
    }
1615
 
    DapIndent::UnIndent() ;
1616
 
    strm << DapIndent::LMarg << "strings:" << endl ;
1617
 
    DapIndent::Indent() ;
 
1799
    DapIndent::UnIndent();
 
1800
    strm << DapIndent::LMarg << "strings:" << endl;
 
1801
    DapIndent::Indent();
1618
1802
    for (unsigned i = 0; i < d_str.size(); i++) {
1619
 
        strm << DapIndent::LMarg << d_str[i] << endl ;
1620
 
    }
1621
 
    DapIndent::UnIndent() ;
1622
 
    if( _buf )
1623
 
    {
1624
 
        switch( _var->type() )
1625
 
        {
1626
 
            case dods_byte_c:
1627
 
            {
1628
 
                strm << DapIndent::LMarg << "_buf: " ;
1629
 
                strm.write( _buf, _length ) ;
1630
 
                strm << endl ;
1631
 
            }
1632
 
            break ;
1633
 
            default:
1634
 
            {
1635
 
                strm << DapIndent::LMarg << "_buf: " << (void *)_buf << endl ;
1636
 
            }
1637
 
            break ;
1638
 
        }
1639
 
    }
1640
 
    else
1641
 
    {
1642
 
        strm << DapIndent::LMarg << "_buf: EMPTY" << endl ;
1643
 
    }
1644
 
    DapIndent::UnIndent() ;
 
1803
        strm << DapIndent::LMarg << d_str[i] << endl;
 
1804
    }
 
1805
    DapIndent::UnIndent();
 
1806
    if (_buf) {
 
1807
        switch (_var->type()) {
 
1808
            case dods_byte_c: {
 
1809
                strm << DapIndent::LMarg << "_buf: ";
 
1810
                strm.write(_buf, d_length);
 
1811
                strm << endl;
 
1812
            }
 
1813
                break;
 
1814
            default: {
 
1815
                strm << DapIndent::LMarg << "_buf: " << (void *) _buf << endl;
 
1816
            }
 
1817
                break;
 
1818
        }
 
1819
    }
 
1820
    else {
 
1821
        strm << DapIndent::LMarg << "_buf: EMPTY" << endl;
 
1822
    }
 
1823
    DapIndent::UnIndent();
1645
1824
}
1646
1825
 
1647
1826
} // namespace libdap