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.
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)
161
// Make sure we HAVE a _var, or we cannot continue.
163
throw InternalErr(__FILE__, __LINE__,
164
"create_cardinal_data_buffer_for_type: Logic error: _var is null!");
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).");
173
delete_cardinal_data_buffer();
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];
181
oss << "create_cardinal_data_buffer_for_type: new char[] failed to allocate " <<
183
" bytes! Out of memory or too large a buffer required!";
184
throw InternalErr(__FILE__, __LINE__, oss.str());
186
_capacity = numEltsOfType;
159
// Make sure we HAVE a _var, or we cannot continue.
161
throw InternalErr(__FILE__, __LINE__, "create_cardinal_data_buffer_for_type: Logic error: _var is null!");
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).");
169
m_delete_cardinal_data_buffer();
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];
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());
180
_capacity = numEltsOfType;
190
184
/** Delete _buf and zero it and _capacity out */
192
Vector::delete_cardinal_data_buffer()
185
void Vector::m_delete_cardinal_data_buffer()
201
194
/** Helper to reduce cut and paste in the virtual's.
204
template <class CardType>
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)
209
throw InternalErr(__FILE__, __LINE__,
210
"Logic error: Vector::set_cardinal_values_internal() called with negative numElts!");
213
throw InternalErr(__FILE__, __LINE__,
214
"Logic error: Vector::set_cardinal_values_internal() called with null fromArray!");
217
create_cardinal_data_buffer_for_type(numElts);
218
memcpy(_buf, fromArray, numElts * sizeof(CardType) );
201
throw InternalErr(__FILE__, __LINE__, "Logic error: Vector::set_cardinal_values_internal() called with negative numElts!");
204
throw InternalErr(__FILE__, __LINE__, "Logic error: Vector::set_cardinal_values_internal() called with null fromArray!");
207
m_create_cardinal_data_buffer_for_type(numElts);
208
memcpy(_buf, fromArray, numElts * sizeof(CardType));
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.
228
@param n A string containing the name of the variable to be
230
@param v A pointer to a variable of the type to be included
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>.
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.
217
@param n A string containing the name of the variable to be
219
@param v A pointer to a variable of the type to be included
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>.
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)
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.
256
@param n A string containing the name of the variable to be
258
@param d A string containing the dataset name from which the variable is
260
@param v A pointer to a variable of the type to be included
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>.
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.
245
@param n A string containing the name of the variable to be
247
@param d A string containing the dataset name from which the variable is
249
@param v A pointer to a variable of the type to be included
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>.
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)
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.
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)
361
_var->set_read_p(state);
358
_var->set_read_p(state);
363
360
BaseType::set_read_p(state);
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
373
Note that the parameter <i>exact_match</i> is not used by this mfunc.
375
@param n The name of the variable to find.
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
381
@return A pointer to the BaseType if found, otherwise null.
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
370
Note that the parameter <i>exact_match</i> is not used by this mfunc.
372
@param n The name of the variable to find.
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
378
@return A pointer to the BaseType if found, otherwise null.
380
BaseType *Vector::var(const string &n, bool exact, btp_stack *s)
385
382
string name = www2id(n);
386
383
DBG(cerr << "Vector::var: Looking for " << n << endl);
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()) {
437
435
// Returns: A BaseType pointer to the ith element of the Vector.
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.
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.
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.
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)
457
451
switch (_var->type()) {
464
case dods_float64_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.
500
496
// Returns: The number of bytes used to store the vector.
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
499
array. This is equal to <tt>length()</tt> times the width of each
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)
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.");
515
return length() * _var->width();
510
return length() * _var->width(constrained);
518
513
// Returns: the number of elements in the vector.
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.
523
@see Vector::append_dim */
518
@see Vector::append_dim */
524
519
int Vector::length() const
529
524
// set the number of elements in the vector.
533
528
/** Sets the length of the vector. This function does not allocate
535
530
void Vector::set_length(int l)
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).
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)
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.
554
549
/** @brief read data into a variable for later use
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.
563
This method is intended to be used by objects which transform DAP objects
564
like the DataDDS into an ASCII CSV representation.
567
@param eval A reference to a constraint evaluator
568
@param dds The complete DDS to which this variable belongs */
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.
558
This method is intended to be used by objects which transform DAP objects
559
like the DataDDS into an ASCII CSV representation.
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)
572
566
DBG(cerr << "Vector::intern_data: " << name() << endl);
574
read(); // read() throws Error and InternalErr
568
read(); // read() throws Error and InternalErr
576
570
// length() is not capacity; it must be set explicitly in read().
577
571
int num = length();
579
573
switch (_var->type()) {
587
// For these cases, read() puts the data into _buf, which is what we
588
// need to do 'stuff' with the data.
593
// For these cases, read() will put the data into d_str[], which is
594
// what the transformation classes need.
598
// I think this is an error since there can never be an Array of
600
throw InternalErr(__FILE__, __LINE__, "Array of Array not supported.");
603
case dods_structure_c:
604
case dods_sequence_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.");
613
for (int i = 0; i < num; ++i)
614
_vec[i]->intern_data(eval, dds);
619
throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
581
// For these cases, read() puts the data into _buf, which is what we
582
// need to do 'stuff' with the data.
587
// For these cases, read() will put the data into d_str[], which is
588
// what the transformation classes need.
592
// I think this is an error since there can never be an Array of
594
throw InternalErr(__FILE__, __LINE__, "Array of Array not supported.");
597
case dods_structure_c:
598
case dods_sequence_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.");
606
for (int i = 0; i < num; ++i)
607
_vec[i]->intern_data(eval, dds);
612
throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
624
617
/** @brief Serialize a Vector.
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
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.
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
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.
628
bool Vector::serialize(ConstraintEvaluator & eval, DDS & dds, Marshaller &m, bool ce_eval)
630
int i = 0;// TODO move closer to use
641
632
dds.timeout_on();
644
read(); // read() throws Error and InternalErr
635
read(); // read() throws Error and InternalErr
647
638
if (ce_eval && !eval.eval_selection(dds, dataset()))
654
645
int num = length();
656
647
switch (_var->type()) {
658
m.put_vector( _buf, num, *this ) ;
666
m.put_vector( _buf, num, _var->width(), *this ) ;
671
if (d_str.capacity() == 0)
672
throw InternalErr(__FILE__, __LINE__,
673
"The capacity of the string vector is 0");
677
for (i = 0; i < num; ++i)
678
m.put_str( d_str[i] ) ;
683
case dods_structure_c:
684
case dods_sequence_c:
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.");
694
for (i = 0; i < num; ++i)
695
_vec[i]->serialize(eval, dds, m, false);
700
throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
649
m.put_vector(_buf, num, *this);
657
m.put_vector(_buf, num, _var->width(), *this);
662
if (d_str.capacity() == 0)
663
throw InternalErr(__FILE__, __LINE__, "The capacity of the string vector is 0");
667
for (i = 0; i < num; ++i)
673
case dods_structure_c:
674
case dods_sequence_c:
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.");
683
for (i = 0; i < num; ++i)
684
_vec[i]->serialize(eval, dds, m, false);
689
throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
729
718
switch (_var->type()) {
737
if (_buf && !reuse) {
738
delete_cardinal_data_buffer();
741
um.get_int( (int &)num ) ;
743
DBG(cerr << "Vector::deserialize: num = " << num << endl);
744
DBG(cerr << "Vector::deserialize: length = " << length() << endl);
749
if (num != (unsigned int) length())
750
throw InternalErr(__FILE__, __LINE__, "The server sent declarations and data with mismatched sizes.");
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);
760
if (_var->type() == dods_byte_c)
761
um.get_vector( (char **)&_buf, num, *this ) ;
763
um.get_vector( (char **)&_buf, num, _var->width(), *this ) ;
765
DBG(cerr << "Vector::deserialize: read " << num << " elements\n");
771
um.get_int( (int &)num ) ;
776
if (num != (unsigned int) length())
777
throw InternalErr(__FILE__, __LINE__,
778
"The client sent declarations and data with mismatched sizes.");
780
d_str.resize((num > 0) ? num : 0); // Fill with NULLs
781
_capacity = num; // capacity is number of strings we can fit.
783
for (i = 0; i < num; ++i) {
793
case dods_structure_c:
794
case dods_sequence_c:
796
um.get_int( (int &)num ) ;
801
if (num != (unsigned int) length())
802
throw InternalErr(__FILE__, __LINE__, "The client sent declarations and data with mismatched sizes.");
806
for (i = 0; i < num; ++i) {
807
_vec[i] = _var->ptr_duplicate();
808
_vec[i]->deserialize(um, dds);
814
throw InternalErr(__FILE__, __LINE__, "Unknown type!");
726
if (_buf && !reuse) {
727
m_delete_cardinal_data_buffer();
730
um.get_int((int &) num);
732
DBG(cerr << "Vector::deserialize: num = " << num << endl);
733
DBG(cerr << "Vector::deserialize: length = " << length() << endl);
738
if (num != (unsigned int) length())
739
throw InternalErr(__FILE__, __LINE__, "The server sent declarations and data with mismatched sizes.");
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);
749
if (_var->type() == dods_byte_c)
750
um.get_vector((char **) &_buf, num, *this);
752
um.get_vector((char **) &_buf, num, _var->width(), *this);
754
DBG(cerr << "Vector::deserialize: read " << num << " elements\n");
760
um.get_int((int &) num);
765
if (num != (unsigned int) length())
766
throw InternalErr(__FILE__, __LINE__, "The client sent declarations and data with mismatched sizes.");
768
d_str.resize((num > 0) ? num : 0); // Fill with NULLs
769
_capacity = num; // capacity is number of strings we can fit.
771
for (i = 0; i < num; ++i) {
781
case dods_structure_c:
782
case dods_sequence_c:
784
um.get_int((int &) num);
789
if (num != (unsigned int) length())
790
throw InternalErr(__FILE__, __LINE__, "The client sent declarations and data with mismatched sizes.");
794
for (i = 0; i < num; ++i) {
795
_vec[i] = _var->ptr_duplicate();
796
_vec[i]->deserialize(um, dds);
802
throw InternalErr(__FILE__, __LINE__, "Unknown type!");
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.
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.
832
For a Vector of Str (OPeNDAP Strings), this assumes \e val points to an
833
array of C++ strings.
835
This method should not be used for Structure, Sequence or Grid.
837
@brief Reads data into the Vector buffer.
838
@exception InternalErr Thrown if called for Structure, Sequence or
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.
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.
820
For a Vector of Str (OPeNDAP Strings), this assumes \e val points to an
821
array of C++ strings.
823
This method should not be used for Structure, Sequence or Grid.
825
@brief Reads data into the Vector buffer.
826
@exception InternalErr Thrown if called for Structure, Sequence or
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)
857
845
// will be in libdap++, so it will be an internal error from the
858
846
// surrogate library.
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.");
863
850
switch (_var->type()) {
870
case dods_float64_c: {
871
// width() returns the size given the constraint
872
unsigned int array_wid = width();
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();
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());
881
868
memcpy(_buf, val, array_wid);
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);
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);
898
throw InternalErr(__FILE__, __LINE__, "Vector::val2buf: bad type");
885
throw InternalErr(__FILE__, __LINE__, "Vector::val2buf: bad type");
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,
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.
918
In the case of a Vector of Str objects, this method will return an array
919
of C++ std::string objects.
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.
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,
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.
905
In the case of a Vector of Str objects, this method will return an array
906
of C++ std::string objects.
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.
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)
940
927
throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
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.
948
935
switch (_var->type()) {
957
*val = new char[wid];
959
// avoid bus error if _buf is null and this is called improperly.
961
throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: Logic error: called when _buf was null!");
964
(void) memcpy(*val, _buf, wid);
944
*val = new char[wid];
946
// avoid bus error if _buf is null and this is called improperly.
948
throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: Logic error: called when _buf was null!");
951
(void) memcpy(*val, _buf, wid);
971
*val = new string[_length];
958
*val = new string[d_length];
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];
980
throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: bad type");
967
throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: bad type");
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.
991
Use this function only with Vectors containing compound DAP2
992
types. See <tt>buf2val()</tt> to access members of Vectors containing
995
@note This method copies \e val; the caller is responsible for deleting
996
instance passed as the actual parameter.
998
@brief Sets element <i>i</i> to value <i>val</i>.
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
1006
@see Vector::buf2val */
975
the input and the type of the Vector do not match, an error
976
condition is returned.
978
Use this function only with Vectors containing compound DAP2
979
types. See <tt>buf2val()</tt> to access members of Vectors containing
982
@note This method copies \e val; the caller is responsible for deleting
983
instance passed as the actual parameter.
985
@brief Sets element <i>i</i> to value <i>val</i>.
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
993
@see Vector::buf2val */
1007
994
void Vector::set_vec(unsigned int i, BaseType * val)
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.");
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.");
1023
1007
if (i >= _vec.capacity())
1024
1008
vec_resize(i + 10);
1080
1060
* to preallocate storage for.
1081
1061
* @exception if the memory cannot be allocated
1084
Vector::reserve_value_capacity(unsigned int numElements)
1063
void Vector::reserve_value_capacity(unsigned int numElements)
1087
throw InternalErr(__FILE__, __LINE__,
1088
"reserve_value_capacity: Logic error: _var is null!");
1090
switch (_var->type()) {
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);
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;
1114
case dods_structure_c:
1115
case dods_sequence_c:
1117
// not clear anyone will go this path, but best to be complete.
1118
_vec.reserve(numElements);
1119
_capacity = numElements;
1124
throw InternalErr(__FILE__, __LINE__, "reserve_value_capacity: Unknown type!");
1066
throw InternalErr(__FILE__, __LINE__, "reserve_value_capacity: Logic error: _var is null!");
1068
switch (_var->type()) {
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);
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;
1091
case dods_structure_c:
1092
case dods_sequence_c:
1094
// not clear anyone will go this path, but best to be complete.
1095
_vec.reserve(numElements);
1096
_capacity = numElements;
1101
throw InternalErr(__FILE__, __LINE__, "reserve_value_capacity: Unknown type!");
1169
1145
* @return the number of elements added, such that:
1170
1146
* startElement + the return value is the next "free" element.
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)
1175
static const string funcName = "set_value_slice_from_row_major_vector:";
1177
// semantically const from the caller's viewpoint, but some calls are not syntactic const.
1178
Vector& rowMajorData = const_cast<Vector&>(rowMajorDataC);
1180
bool typesMatch = rowMajorData.var() && _var && (rowMajorData.var()->type() == _var->type());
1182
throw InternalErr(__FILE__, __LINE__,
1183
funcName + "Logic error: types do not match so cannot be copied!");
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!");
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!");
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!");
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!");
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()) {
1219
case dods_float32_c:
1220
case dods_float64_c: {
1222
throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: this->_buf was unexpectedly null!");
1224
if (!rowMajorData._buf) {
1225
throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: rowMajorData._buf was unexpectedly null!");
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);
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];
1248
case dods_structure_c:
1249
case dods_sequence_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.");
1259
throw InternalErr(__FILE__, __LINE__, funcName + ": Unknown type!");
1263
} // switch (_var->type())
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:";
1152
// semantically const from the caller's viewpoint, but some calls are not syntactic const.
1153
Vector& rowMajorData = const_cast<Vector&> (rowMajorDataC);
1155
bool typesMatch = rowMajorData.var() && _var && (rowMajorData.var()->type() == _var->type());
1157
throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: types do not match so cannot be copied!");
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!");
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!");
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!");
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!");
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()) {
1189
case dods_float32_c:
1190
case dods_float64_c: {
1192
throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: this->_buf was unexpectedly null!");
1194
if (!rowMajorData._buf) {
1195
throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: rowMajorData._buf was unexpectedly null!");
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);
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];
1216
case dods_structure_c:
1217
case dods_sequence_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.");
1226
throw InternalErr(__FILE__, __LINE__, funcName + ": Unknown type!");
1230
} // switch (_var->type())
1232
// This is how many elements we copied.
1233
return (unsigned int) rowMajorData.length();
1270
1237
/** @brief set the value of a byte array */
1272
Vector::set_value(dods_byte *val, int sz)
1238
bool Vector::set_value(dods_byte *val, int sz)
1274
1240
if (var()->type() == dods_byte_c && val) {
1275
set_cardinal_values_internal<dods_byte>(val, sz);
1241
set_cardinal_values_internal<dods_byte> (val, sz);
1383
1339
/** @brief set the value of a float32 array */
1385
Vector::set_value(vector<dods_float32> &val, int sz)
1340
bool Vector::set_value(vector<dods_float32> &val, int sz)
1387
1342
return set_value(&val[0], sz);
1390
1345
/** @brief set the value of a float64 array */
1392
Vector::set_value(dods_float64 *val, int sz)
1346
bool Vector::set_value(dods_float64 *val, int sz)
1394
1348
if (var()->type() == dods_float64_c && val) {
1395
set_cardinal_values_internal<dods_float64>(val, sz);
1349
set_cardinal_values_internal<dods_float64> (val, sz);
1403
1357
/** @brief set the value of a float64 array */
1405
Vector::set_value(vector<dods_float64> &val, int sz)
1358
bool Vector::set_value(vector<dods_float64> &val, int sz)
1407
1360
return set_value(&val[0], sz);
1410
1363
/** @brief set the value of a string or url array */
1412
Vector::set_value(string *val, int sz)
1364
bool Vector::set_value(string *val, int sz)
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++) {
1421
1373
set_read_p(true);
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.
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
1412
unsigned long currentIndex;
1414
for(unsigned long i=0; i<subsetIndex->size() ;++i){
1415
currentIndex = (*subsetIndex)[i] ;
1416
if(currentIndex> (unsigned int)length()){
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());
1422
b[i] = reinterpret_cast<dods_byte*>(_buf )[currentIndex]; // I like this version - and it works!
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
1430
unsigned long currentIndex;
1432
for(unsigned long i=0; i<subsetIndex->size() ;++i){
1433
currentIndex = (*subsetIndex)[i] ;
1434
if(currentIndex> (unsigned int)length()){
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());
1440
b[i] = reinterpret_cast<dods_uint16*>(_buf )[currentIndex]; // I like this version - and it works!
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
1448
unsigned long currentIndex;
1450
for(unsigned long i=0; i<subsetIndex->size() ;++i){
1451
currentIndex = (*subsetIndex)[i] ;
1452
if(currentIndex> (unsigned int)length()){
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());
1458
b[i] = reinterpret_cast<dods_int16*>(_buf )[currentIndex]; // I like this version - and it works!
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
1465
unsigned long currentIndex;
1467
for(unsigned long i=0; i<subsetIndex->size() ;++i){
1468
currentIndex = (*subsetIndex)[i] ;
1469
if(currentIndex> (unsigned int)length()){
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());
1475
b[i] = reinterpret_cast<dods_uint32*>(_buf )[currentIndex]; // I like this version - and it works!
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
1482
unsigned long currentIndex;
1484
for(unsigned long i=0; i<subsetIndex->size() ;++i){
1485
currentIndex = (*subsetIndex)[i] ;
1486
if(currentIndex> (unsigned int)length()){
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());
1492
b[i] = reinterpret_cast<dods_int32*>(_buf )[currentIndex]; // I like this version - and it works!
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
1499
unsigned long currentIndex;
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()){
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());
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'
1514
b[i] = reinterpret_cast<dods_float32*>(_buf )[currentIndex]; // I like this version - and it works!
1516
//cerr << "b[" << i << "]=" << b[i] << endl;
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
1523
unsigned long currentIndex;
1525
for(unsigned long i=0; i<subsetIndex->size() ;++i){
1526
currentIndex = (*subsetIndex)[i] ;
1527
if(currentIndex> (unsigned int)length()){
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());
1533
b[i] = reinterpret_cast<dods_float64*>(_buf )[currentIndex]; // I like this version - and it works!
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
1541
unsigned long currentIndex;
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()){
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());
1552
b[i] = d_str[currentIndex];
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.
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
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
1515
if (_var->type() == dods_byte_c || _var->type() == dods_url_c)
1628
if (_var->type() == dods_str_c || _var->type() == dods_url_c)
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()
1523
void *buffer = new char[width()];
1636
void *buffer = new char[width(true)];
1525
memcpy(buffer, _buf, width());
1638
memcpy(buffer, _buf, width(true));
1531
1644
/** @brief Add the BaseType pointer to this constructor type
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.
1540
@param v The template variable for the array
1541
@param p The Part parameter defaults to nil and is ignored by this method.
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.
1653
@note As is the case with Array, this method can be called with a null
1656
@param v The template variable for the array
1657
@param p The Part parameter defaults to nil and is ignored by this method.
1543
1659
void Vector::add_var(BaseType * v, Part)
1662
if (v && v->is_dap4_only_type())
1663
throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Vector.");
1545
1665
// Delete the current template variable
1552
1671
// if 'v' is null, just set _var to null and exit.
1570
1689
_var->set_parent(this); // Vector --> child
1572
1691
DBG(cerr << "Vector::add_var: Added variable " << v << " ("
1573
<< v->name() << " " << v->type_name() << ")" << endl);
1692
<< v->name() << " " << v->type_name() << ")" << endl);
1696
void Vector::add_var_nocopy(BaseType * v, Part)
1699
if (v && v->is_dap4_only_type())
1700
throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Vector.");
1702
// Delete the current template variable
1708
// if 'v' is null, just set _var to null and exit.
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());
1721
_var->set_name(name());
1723
_var->set_parent(this); // Vector --> child
1725
DBG(cerr << "Vector::add_var: Added variable " << v << " ("
1726
<< v->name() << " " << v->type_name() << ")" << endl);
1732
void Vector::add_var_nocopy(BaseType * v, Part)
1734
// Delete the current template variable
1740
// if 'v' is null, just set _var to null and exit.
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());
1753
_var->set_name(name());
1755
_var->set_parent(this); // Vector --> child
1757
DBG(cerr << "Vector::add_var: Added variable " << v << " ("
1758
<< v->name() << " " << v->type_name() << ")" << endl);
1577
1763
bool Vector::check_semantics(string & msg, bool)
1587
1773
* @param strm C++ i/o stream to dump the information to
1591
Vector::dump(ostream &strm) const
1776
void Vector::dump(ostream &strm) const
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;
1599
strm << DapIndent::LMarg << "base type:" << endl ;
1600
DapIndent::Indent() ;
1602
DapIndent::UnIndent() ;
1783
strm << DapIndent::LMarg << "base type:" << endl;
1784
DapIndent::Indent();
1786
DapIndent::UnIndent();
1605
strm << DapIndent::LMarg << "base type: not set" << endl ;
1789
strm << DapIndent::LMarg << "base type: not set" << endl;
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) {
1611
_vec[i]->dump(strm) ;
1795
_vec[i]->dump(strm);
1613
strm << DapIndent::LMarg << "vec[" << i << "] is null" << endl ;
1797
strm << DapIndent::LMarg << "vec[" << i << "] is null" << endl;
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 ;
1621
DapIndent::UnIndent() ;
1624
switch( _var->type() )
1628
strm << DapIndent::LMarg << "_buf: " ;
1629
strm.write( _buf, _length ) ;
1635
strm << DapIndent::LMarg << "_buf: " << (void *)_buf << endl ;
1642
strm << DapIndent::LMarg << "_buf: EMPTY" << endl ;
1644
DapIndent::UnIndent() ;
1803
strm << DapIndent::LMarg << d_str[i] << endl;
1805
DapIndent::UnIndent();
1807
switch (_var->type()) {
1809
strm << DapIndent::LMarg << "_buf: ";
1810
strm.write(_buf, d_length);
1815
strm << DapIndent::LMarg << "_buf: " << (void *) _buf << endl;
1821
strm << DapIndent::LMarg << "_buf: EMPTY" << endl;
1823
DapIndent::UnIndent();
1647
1826
} // namespace libdap