libdap++  Updated for version 3.14.0
Vector.cc
Go to the documentation of this file.
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
4 // Access Protocol.
5 
6 // Copyright (c) 2002,2003 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 
25 // (c) COPYRIGHT URI/MIT 1995-1999
26 // Please read the full copyright statement in the file COPYRIGHT_URI.
27 //
28 // Authors:
29 // jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
30 
31 // Implementation for class Vector. This class is the basis for all the
32 // vector-type classes in libdap's <Array, List>.
33 //
34 // 11/21/95 jhrg
35 
36 #include "config.h"
37 
38 #include <cstring>
39 #include <cassert>
40 
41 //#define DODS_DEBUG
42 
43 #include <sstream>
44 #include <vector>
45 #include <algorithm>
46 #include <typeinfo>
47 
48 #include <stdint.h>
49 
50 #include "crc.h"
51 
52 #include "Vector.h"
53 #include "Marshaller.h"
54 #include "UnMarshaller.h"
55 
56 #include "D4StreamMarshaller.h"
57 #include "D4StreamUnMarshaller.h"
58 
59 #include "D4Enum.h"
60 
61 #include "Type.h"
62 #include "dods-datatypes.h"
63 #include "escaping.h"
64 #include "util.h"
65 #include "debug.h"
66 #include "InternalErr.h"
67 
68 using std::cerr;
69 using std::endl;
70 
71 namespace libdap {
72 
73 void Vector::m_duplicate(const Vector & v)
74 {
75  d_length = v.d_length;
76 
77  // _var holds the type of the elements. That is, it holds a BaseType
78  // which acts as a template for the type of each element.
79  if (v.d_proto) {
80  d_proto = v.d_proto->ptr_duplicate(); // use ptr_duplicate()
81  d_proto->set_parent(this); // ptr_duplicate does not set d_parent.
82  }
83  else {
84  d_proto = 0;
85  }
86 
87  // d_compound_buf and d_buf (further down) hold the values of the Vector. The field
88  // d_compound_buf is used when the Vector holds non-numeric data (including strings
89  // although it used to be that was not the case jhrg 2/10/05) while d_buf
90  // holds numeric values.
91  if (v.d_compound_buf.empty()) {
92  d_compound_buf = v.d_compound_buf;
93  }
94  else {
95  // Failure to set the size will make the [] operator barf on the LHS
96  // of the assignment inside the loop.
97  d_compound_buf.resize(d_length);
98  for (int i = 0; i < d_length; ++i) {
99  // There's no need to call set_parent() for each element; we
100  // maintain the back pointer using the d_proto member. These
101  // instances are used to hold _values_ only while the d_proto
102  // field holds the type information for the elements.
103  d_compound_buf[i] = v.d_compound_buf[i]->ptr_duplicate();
104  }
105  }
106 
107  // copy the strings. This copies the values.
108  d_str = v.d_str;
109 
110  // copy numeric values if there are any.
111  d_buf = 0; // init to null
112  if (v.d_buf) // only copy if data present
113  val2buf(v.d_buf); // store v's value in this's _BUF.
114 
115  d_capacity = v.d_capacity;
116 }
117 
123 {
124  // TODO Is this true? It might not be
125  // Not cardinal if no d_proto at all!
126  if (!d_proto) {
127  return false;
128  }
129 
130  switch (d_proto->type()) {
131  case dods_byte_c:
132  case dods_char_c:
133  case dods_int16_c:
134  case dods_uint16_c:
135  case dods_int32_c:
136  case dods_uint32_c:
137  case dods_float32_c:
138  case dods_float64_c:
139  // New cardinal types for DAP4
140  case dods_int8_c:
141  case dods_uint8_c:
142  case dods_int64_c:
143  case dods_uint64_c:
144 
145  case dods_enum_c:
146  return true;
147  break;
148 
149  // These must be handled differently.
150  case dods_str_c:
151  case dods_url_c:
152  case dods_opaque_c:
153 
154  case dods_array_c:
155 
156  case dods_structure_c:
157  case dods_sequence_c:
158  case dods_grid_c:
159  return false;
160  break;
161 
162  default:
163  assert("Vector::var: Unrecognized type");
164  return false;
165  }
166 }
167 
180 unsigned int Vector::m_create_cardinal_data_buffer_for_type(unsigned int numEltsOfType)
181 {
182  // Make sure we HAVE a _var, or we cannot continue.
183  if (!d_proto) {
184  throw InternalErr(__FILE__, __LINE__, "create_cardinal_data_buffer_for_type: Logic error: _var is null!");
185  }
186 
187  // Make sure we only do this for the correct data types.
188  if (!m_is_cardinal_type()) {
189  throw InternalErr(__FILE__, __LINE__, "create_cardinal_data_buffer_for_type: incorrectly used on Vector whose type was not a cardinal (simple data types).");
190  }
191 
193 
194  // Actually new up the array with enough bytes to hold numEltsOfType of the actual type.
195  unsigned int bytesPerElt = d_proto->width();
196  unsigned int bytesNeeded = bytesPerElt * numEltsOfType;
197  d_buf = new char[bytesNeeded];
198 
199  d_capacity = numEltsOfType;
200  return bytesNeeded;
201 }
202 
205 {
206  delete[] d_buf;
207  d_buf = 0;
208  d_capacity = 0;
209 }
210 
214 template<class CardType>
215 void Vector::m_set_cardinal_values_internal(const CardType* fromArray, int numElts)
216 {
217  if (numElts < 0) {
218  throw InternalErr(__FILE__, __LINE__, "Logic error: Vector::set_cardinal_values_internal() called with negative numElts!");
219  }
220  if (!fromArray) {
221  throw InternalErr(__FILE__, __LINE__, "Logic error: Vector::set_cardinal_values_internal() called with null fromArray!");
222  }
223  set_length(numElts);
225  memcpy(d_buf, fromArray, numElts * sizeof(CardType));
226  set_read_p(true);
227 }
228 
244 Vector::Vector(const string & n, BaseType * v, const Type & t, bool is_dap4 /* default:false */) :
245  BaseType(n, t, is_dap4), d_length(-1), d_proto(0), d_buf(0), d_compound_buf(0), d_capacity(0)
246 {
247  if (v)
248  add_var(v);
249 
250  DBG2(cerr << "Entering Vector ctor for object: " << this << endl);
251  if (d_proto)
252  d_proto->set_parent(this);
253 }
254 
273 Vector::Vector(const string & n, const string &d, BaseType * v, const Type & t, bool is_dap4 /* default:false */) :
274  BaseType(n, d, t, is_dap4), d_length(-1), d_proto(0), d_buf(0), d_compound_buf(0), d_capacity(0)
275 {
276  if (v)
277  add_var(v);
278 
279  DBG2(cerr << "Entering Vector ctor for object: " << this << endl);
280  if (d_proto)
281  d_proto->set_parent(this);
282 }
283 
285 Vector::Vector(const Vector & rhs) :
286  BaseType(rhs)
287 {
288  DBG2(cerr << "Entering Vector const ctor for object: " << this <<
289  endl); DBG2(cerr << "RHS: " << &rhs << endl);
290 
291  m_duplicate(rhs);
292 }
293 
295 {
296  DBG2(cerr << "Entering ~Vector (" << this << ")" << endl);
297 
298  delete d_proto;
299  d_proto = 0;
300 
301  // Clears all buffers
303 
304  DBG2(cerr << "Exiting ~Vector" << endl);
305 }
306 
308 {
309  if (this == &rhs)
310  return *this;
311 
312  dynamic_cast<BaseType &> (*this) = rhs;
313 
314  m_duplicate(rhs);
315 
316  return *this;
317 }
318 
319 void Vector::set_name(const std::string& name)
320 {
321  BaseType::set_name(name);
322  // We need to set the prototype name as well since
323  // this is what gets output in the dds! Otherwise, there's a mismatch.
324  if (d_proto) {
325  d_proto->set_name(name);
326  }
327 }
328 
329 int Vector::element_count(bool leaves)
330 {
331  if (!leaves)
332  return 1;
333  else
334  return d_proto->element_count(leaves);
335  // var() only works for simple types!
336  // jhrg 8/19/13 return var(0)->element_count(leaves);
337 }
338 
339 // These mfuncs set the _send_p and _read_p fields of BaseType. They differ
340 // from BaseType's version in that they set both the Vector object's copy of
341 // _send_p (_read_p) but also _VAR's copy. This does not matter much when _VAR
342 // is a scalar, but does matter when it is an aggregate.
343 
350 void Vector::set_send_p(bool state)
351 {
352  d_proto->set_send_p(state);
353  BaseType::set_send_p(state);
354 }
355 
362 void Vector::set_read_p(bool state)
363 {
364  if (d_proto) {
365  d_proto->set_read_p(state);
366  }
367  BaseType::set_read_p(state);
368 }
369 
387 BaseType *Vector::var(const string &n, bool exact, btp_stack *s)
388 {
389  string name = www2id(n);
390  DBG2(cerr << "Vector::var: Looking for " << name << endl);
391 
392  // If this is a Vector of constructor types, look for 'name' recursively.
393  // Make sure to check for the case where name is the default (the empty
394  // string). 9/1/98 jhrg
395  if (d_proto->is_constructor_type()) {
396  if (name == "" || d_proto->name() == name) {
397  if (s)
398  s->push(this);
399  return d_proto;
400  }
401  else {
402  BaseType * result = d_proto->var(name, exact, s);
403  if (result && s)
404  s->push(this);
405  return result;
406  }
407  }
408  else {
409  return d_proto;
410  }
411 }
412 
423 BaseType *Vector::var(const string & n, btp_stack & s)
424 {
425  string name = www2id(n);
426 
427  if (d_proto->is_constructor_type())
428  return d_proto->var(name, s);
429  else {
430  s.push((BaseType *) this);
431  return d_proto;
432  }
433 }
434 
446 BaseType *Vector::var(unsigned int i)
447 {
448 
449  switch (d_proto->type()) {
450  case dods_byte_c:
451  case dods_char_c:
452  case dods_int8_c:
453  case dods_uint8_c:
454  case dods_int16_c:
455  case dods_uint16_c:
456  case dods_int32_c:
457  case dods_uint32_c:
458  case dods_int64_c:
459  case dods_uint64_c:
460 
461  case dods_enum_c:
462 
463  case dods_float32_c:
464  case dods_float64_c:
465  // Transfer the ith value to the BaseType *d_proto
466  d_proto->val2buf(d_buf + (i * d_proto->width()));
467  return d_proto;
468  break;
469 
470  case dods_str_c:
471  case dods_url_c:
472  d_proto->val2buf(&d_str[i]);
473  return d_proto;
474  break;
475 
476  case dods_opaque_c:
477  case dods_array_c:
478  case dods_structure_c:
479  case dods_sequence_c:
480  case dods_grid_c:
481  return d_compound_buf[i];
482  break;
483 
484  default:
485  throw Error ("Vector::var: Unrecognized type");
486  break;
487  }
488 
489  return 0;
490 }
491 
498 unsigned int Vector::width(bool constrained) const
499 {
500  // Jose Garcia
501  // TODO Use assert.
502  if (!d_proto) {
503  throw InternalErr(__FILE__, __LINE__, "Cannot get width since *this* object is not holding data.");
504  }
505 
506  return length() * d_proto->width(constrained);
507 }
508 
513 int Vector::length() const
514 {
515  return d_length;
516 }
517 
521 {
522  d_length = l;
523 }
524 
534 {
535  // I added this check, which alters the behavior of the method. jhrg 8/14/13
536  if (m_is_cardinal_type())
537  throw InternalErr(__FILE__, __LINE__, "Vector::vec_resize() is applicable to compound types only");
538 
539  d_compound_buf.resize((l > 0) ? l : 0, 0); // Fill with NULLs
540  d_capacity = l; // capacity in terms of number of elements.
541 }
542 
560 {
561  DBG(cerr << "Vector::intern_data: " << name() << endl);
562  if (!read_p())
563  read(); // read() throws Error and InternalErr
564 
565  // length() is not capacity; it must be set explicitly in read().
566  int num = length();
567 
568  switch (d_proto->type()) {
569  case dods_byte_c:
570  case dods_int16_c:
571  case dods_uint16_c:
572  case dods_int32_c:
573  case dods_uint32_c:
574  case dods_float32_c:
575  case dods_float64_c:
576  // For these cases, read() puts the data into d_buf,
577  // which is what we need.
578  break;
579 
580  case dods_str_c:
581  case dods_url_c:
582  // For these cases, read() will put the data into d_str[],
583  // which is also what we need.
584  break;
585 
586  case dods_array_c:
587  // This is an error since there can never be an Array of Array.
588  throw InternalErr(__FILE__, __LINE__, "Array of Array not supported.");
589  break;
590 
591  case dods_structure_c:
592  case dods_sequence_c:
593  case dods_grid_c:
594  DBG(cerr << "Vector::intern_data: found ctor" << endl);
595  // For these cases, we need to call read() for each of the 'num'
596  // elements in the 'd_compound_buf[]' array of BaseType object pointers.
597  if (d_compound_buf.capacity() == 0)
598  throw InternalErr(__FILE__, __LINE__, "The capacity of *this* vector is 0.");
599 
600  for (int i = 0; i < num; ++i)
601  d_compound_buf[i]->intern_data(eval, dds);
602 
603  break;
604 
605  default:
606  throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
607  break;
608  }
609 }
610 
622 bool Vector::serialize(ConstraintEvaluator & eval, DDS & dds, Marshaller &m, bool ce_eval)
623 {
624  int i = 0;// TODO move closer to use
625 
626  // TODO Time out here? or in ResponseBuilder?
627  dds.timeout_on();
628 
629  if (!read_p())
630  read(); // read() throws Error and InternalErr
631 
632 //#if EVAL
633  if (ce_eval && !eval.eval_selection(dds, dataset()))
634  return true;
635 //#endif
636 
637  dds.timeout_off();
638 
639  // length() is not capacity; it must be set explicitly in read().
640  int num = length();
641 
642  switch (d_proto->type()) {
643  case dods_byte_c:
644  m.put_vector(d_buf, num, *this);
645  break;
646  case dods_int16_c:
647  case dods_uint16_c:
648  case dods_int32_c:
649  case dods_uint32_c:
650  case dods_float32_c:
651  case dods_float64_c:
652  m.put_vector(d_buf, num, d_proto->width(), *this);
653  break;
654 
655  case dods_str_c:
656  case dods_url_c:
657  if (d_str.capacity() == 0)
658  throw InternalErr(__FILE__, __LINE__, "The capacity of the string vector is 0");
659 
660  m.put_int(num);
661 
662  for (i = 0; i < num; ++i)
663  m.put_str(d_str[i]);
664 
665  break;
666 
667  case dods_array_c:
668  case dods_structure_c:
669  case dods_sequence_c:
670  case dods_grid_c:
671  //Jose Garcia
672  // Not setting the capacity of d_compound_buf is an internal error.
673  if (d_compound_buf.capacity() == 0)
674  throw InternalErr(__FILE__, __LINE__, "The capacity of *this* vector is 0.");
675 
676  m.put_int(num);
677 
678  for (i = 0; i < num; ++i)
679  d_compound_buf[i]->serialize(eval, dds, m, false);
680 
681  break;
682 
683  default:
684  throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
685  break;
686  }
687 
688  return true;
689 }
690 
691 // Read an object from the network and internalize it. For a Vector this is
692 // handled differently for a `cardinal' type. Vectors of Cardinals are
693 // stored using the `C' representations because these objects often are used
694 // to build huge arrays (e.g., an array of 1024 by 1024 bytes). However,
695 // arrays of non-cardinal types are stored as Vectors of the C++ objects or
696 // DAP2 objects (Str and Url are vectors of the string class, Structure, ...,
697 // Grid are vectors of the libdap Structure, ... classes).
698 //
699 // The boolean parameter REUSE determines whether internal storage is reused
700 // or not. If true, the _buf member is assumed to be large enough to hold the
701 // incoming cardinal data and is *not* reallocated. If false, new storage is
702 // allocated. If the internal buffer has not yet been allocated, then this
703 // parameter has no effect (i.e., storage is allocated). This parameter
704 // effects storage for cardinal data only.
705 //
706 // Returns: True is successful, false otherwise.
707 
708 bool Vector::deserialize(UnMarshaller &um, DDS * dds, bool reuse)
709 {
710  unsigned int num;
711  unsigned i = 0;
712 
713  switch (d_proto->type()) {
714  case dods_byte_c:
715  case dods_int16_c:
716  case dods_uint16_c:
717  case dods_int32_c:
718  case dods_uint32_c:
719  case dods_float32_c:
720  case dods_float64_c:
721  um.get_int((int &) num);
722 
723  DBG(cerr << "Vector::deserialize: num = " << num << endl);
724  DBG(cerr << "Vector::deserialize: length = " << length() << endl);
725 
726  if (length() == -1)
727  set_length(num);
728 
729  if (num != (unsigned int) length())
730  throw InternalErr(__FILE__, __LINE__, "The server sent declarations and data with mismatched sizes.");
731 
732  if (!d_buf || !reuse) {
733  // Make d_buf be large enough for length() elements of _var->type()
734  // m_create...() deletes the old buffer.
736  DBG(cerr << "Vector::deserialize: allocating "
737  << width() << " bytes for an array of "
738  << length() << " " << d_proto->type_name() << endl);
739  }
740 
741  if (d_proto->type() == dods_byte_c)
742  um.get_vector((char **) &d_buf, num, *this);
743  else
744  um.get_vector((char **) &d_buf, num, d_proto->width(), *this);
745 
746  DBG(cerr << "Vector::deserialize: read " << num << " elements\n");
747 
748  break;
749 
750  case dods_str_c:
751  case dods_url_c:
752  um.get_int((int &) num);
753 
754  if (length() == -1)
755  set_length(num);
756 
757  if (num != (unsigned int) length())
758  throw InternalErr(__FILE__, __LINE__, "The client sent declarations and data with mismatched sizes.");
759 
760  d_str.resize((num > 0) ? num : 0); // Fill with NULLs
761  d_capacity = num; // capacity is number of strings we can fit.
762 
763  for (i = 0; i < num; ++i) {
764  string str;
765  um.get_str(str);
766  d_str[i] = str;
767 
768  }
769 
770  break;
771 
772  case dods_array_c:
773  case dods_structure_c:
774  case dods_sequence_c:
775  case dods_grid_c:
776  um.get_int((int &) num);
777 
778  if (length() == -1)
779  set_length(num);
780 
781  if (num != (unsigned int) length())
782  throw InternalErr(__FILE__, __LINE__, "The client sent declarations and data with mismatched sizes.");
783 
784  vec_resize(num);
785 
786  for (i = 0; i < num; ++i) {
787  d_compound_buf[i] = d_proto->ptr_duplicate();
788  d_compound_buf[i]->deserialize(um, dds);
789  }
790 
791  break;
792 
793  default:
794  throw InternalErr(__FILE__, __LINE__, "Unknown type!");
795  break;
796  }
797 
798  return false;
799 }
800 
802 {
803  switch (d_proto->type()) {
804  case dods_byte_c:
805  case dods_char_c:
806  case dods_int8_c:
807  case dods_uint8_c:
808 
809  case dods_int16_c:
810  case dods_uint16_c:
811 
812  case dods_int32_c:
813  case dods_uint32_c:
814  case dods_float32_c:
815 
816  case dods_int64_c:
817  case dods_uint64_c:
818  case dods_float64_c:
819 
820  case dods_enum_c:
821  checksum.AddData(reinterpret_cast<uint8_t*>(d_buf), length() * d_proto->width());
822  break;
823 
824  case dods_str_c:
825  case dods_url_c:
826  for (int64_t i = 0, e = length(); i < e; ++i)
827  checksum.AddData(reinterpret_cast<const uint8_t*>(d_str[i].data()), d_str[i].length());
828  break;
829 
830  case dods_opaque_c:
831  case dods_structure_c:
832  case dods_sequence_c:
833  d_proto->compute_checksum(checksum);
834  break;
835 
836  case dods_array_c: // No array of array
837  case dods_grid_c: // No grids in DAP4
838  default:
839  throw InternalErr(__FILE__, __LINE__, "Unknown or unsupported datatype (" + d_proto->type_name() + ").");
840  break;
841  }
842 }
843 
844 void Vector::intern_data(Crc32 &checksum/*, DMR &dmr, ConstraintEvaluator &eval*/)
845 {
846  if (!read_p())
847  read(); // read() throws Error and InternalErr
848 
849  switch (d_proto->type()) {
850  case dods_byte_c:
851  case dods_char_c:
852  case dods_int8_c:
853  case dods_uint8_c:
854  case dods_int16_c:
855  case dods_uint16_c:
856  case dods_int32_c:
857  case dods_uint32_c:
858  case dods_int64_c:
859  case dods_uint64_c:
860 
861  case dods_enum_c:
862 
863  case dods_float32_c:
864  case dods_float64_c:
865 
866  case dods_str_c:
867  case dods_url_c:
868  compute_checksum(checksum);
869  break;
870 
871  case dods_opaque_c:
872  case dods_structure_c:
873  case dods_sequence_c:
874  assert(d_compound_buf.capacity() != 0);
875 
876  for (int i = 0, e = length(); i < e; ++i)
877  d_compound_buf[i]->intern_data(checksum/*, dmr, eval*/);
878  break;
879 
880  case dods_array_c:
881  case dods_grid_c:
882  default:
883  throw InternalErr(__FILE__, __LINE__, "Unknown or unsupported datatype (" + d_proto->type_name() + ").");
884  break;
885  }
886 }
887 
888 void
889 Vector::serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter /*= false*/)
890 {
891  if (!read_p())
892  read(); // read() throws Error and InternalErr
893 #if 0
894  if (filter && !eval.eval_selection(dmr, dataset()))
895  return true;
896 #endif
897  int64_t num = length(); // The constrained length in elements
898 
899  switch (d_proto->type()) {
900  case dods_byte_c:
901  case dods_char_c:
902  case dods_int8_c:
903  case dods_uint8_c:
904  m.put_vector(d_buf, num);
905  break;
906 
907  case dods_int16_c:
908  case dods_uint16_c:
909  case dods_int32_c:
910  case dods_uint32_c:
911  case dods_int64_c:
912  case dods_uint64_c:
913  m.put_vector(d_buf, num, d_proto->width());
914  break;
915 
916  case dods_enum_c:
917  if (d_proto->width() == 1)
918  m.put_vector(d_buf, num);
919  else
920  m.put_vector(d_buf, num, d_proto->width());
921  break;
922 
923  case dods_float32_c:
924  m.put_vector_float32(d_buf, num);
925  break;
926 
927  case dods_float64_c:
928  m.put_vector_float64(d_buf, num);
929  break;
930 
931  case dods_str_c:
932  case dods_url_c:
933  assert((int64_t)d_str.capacity() >= num);
934 
935  for (int64_t i = 0; i < num; ++i)
936  m.put_str(d_str[i]);
937 
938  break;
939 
940  case dods_array_c:
941  throw InternalErr(__FILE__, __LINE__, "Array of Array not allowed.");
942 
943  case dods_opaque_c:
944  case dods_structure_c:
945  case dods_sequence_c:
946  assert(d_compound_buf.capacity() >= 0);
947 
948  for (int64_t i = 0; i < num; ++i)
949  d_compound_buf[i]->serialize(m, dmr, /*eval,*/ filter);
950 
951  break;
952 
953  case dods_grid_c:
954  throw InternalErr(__FILE__, __LINE__, "Grid is not part of DAP4.");
955 
956  default:
957  throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
958  break;
959  }
960 }
961 
962 void
964 {
965  if (m_is_cardinal_type()) {
966  if (d_buf)
968  if (!d_buf)
970  }
971 
972  DBG(cerr << "Vector::deserialize, " << name() << ", length(): " << length() << endl);
973 
974  switch (d_proto->type()) {
975  case dods_byte_c:
976  case dods_char_c:
977  case dods_int8_c:
978  case dods_uint8_c:
979  um.get_vector((char *)d_buf, length());
980  break;
981 
982  case dods_int16_c:
983  case dods_uint16_c:
984  case dods_int32_c:
985  case dods_uint32_c:
986  case dods_int64_c:
987  case dods_uint64_c:
988  um.get_vector((char *)d_buf, length(), d_proto->width());
989  break;
990 
991  case dods_enum_c:
992  if (d_proto->width() == 1)
993  um.get_vector((char *)d_buf, length());
994  else
995  um.get_vector((char *)d_buf, length(), d_proto->width());
996  break;
997 
998  case dods_float32_c:
999  um.get_vector_float32((char *)d_buf, length());
1000  break;
1001 
1002  case dods_float64_c:
1003  um.get_vector_float64((char *)d_buf, length());
1004  break;
1005 
1006  case dods_str_c:
1007  case dods_url_c: {
1008  int64_t len = length();
1009  d_str.resize((len > 0) ? len : 0); // Fill with NULLs
1010  d_capacity = len; // capacity is number of strings we can fit.
1011 
1012  for (int64_t i = 0; i < len; ++i) {
1013  um.get_str(d_str[i]);
1014  }
1015 
1016  break;
1017  }
1018 
1019  case dods_array_c:
1020  throw InternalErr(__FILE__, __LINE__, "Array of Array not allowed.");
1021 
1022  case dods_opaque_c:
1023  case dods_structure_c:
1024  case dods_sequence_c: {
1025  vec_resize(length());
1026 
1027  for (int64_t i = 0, end = length(); i < end; ++i) {
1028  d_compound_buf[i] = d_proto->ptr_duplicate();
1029  d_compound_buf[i]->deserialize(um, dmr);
1030  }
1031 
1032  break;
1033  }
1034 
1035  case dods_grid_c:
1036  throw InternalErr(__FILE__, __LINE__, "Grid is not part of DAP4.");
1037 
1038  default:
1039  throw InternalErr(__FILE__, __LINE__, "Unknown type.");
1040  break;
1041  }
1042 }
1043 
1071 unsigned int Vector::val2buf(void *val, bool reuse)
1072 {
1073  // Jose Garcia
1074 
1075  // I *think* this method has been mainly designed to be use by read which
1076  // is implemented in the surrogate library. Passing NULL as a pointer to
1077  // this method will be an error of the creator of the surrogate library.
1078  // Even though I recognize the fact that some methods inside libdap++ can
1079  // call val2buf, I think by now no coding bugs such as misusing val2buf
1080  // will be in libdap++, so it will be an internal error from the
1081  // surrogate library.
1082  if (!val)
1083  throw InternalErr(__FILE__, __LINE__, "The incoming pointer does not contain any data.");
1084 
1085  switch (d_proto->type()) {
1086  case dods_byte_c:
1087  case dods_char_c:
1088  case dods_int8_c:
1089  case dods_uint8_c:
1090  case dods_int16_c:
1091  case dods_uint16_c:
1092  case dods_int32_c:
1093  case dods_uint32_c:
1094  case dods_int64_c:
1095  case dods_uint64_c:
1096 
1097  case dods_enum_c:
1098 
1099  case dods_float32_c:
1100  case dods_float64_c:
1101 #if 0
1102  if (d_buf && !reuse)
1104 #endif
1105  // First time or no reuse (free'd above)
1106  if (!d_buf || !reuse)
1108 
1109  // width(true) returns the size in bytes given the constraint
1110  memcpy(d_buf, val, width(true));
1111  break;
1112 
1113  case dods_str_c:
1114  case dods_url_c:
1115  // Assume val points to an array of C++ string objects. Copy
1116  // them into the vector<string> field of this object.
1117  // Note: d_length is the number of elements in the Vector
1118  d_str.resize(d_length);
1119  d_capacity = d_length;
1120  for (int i = 0; i < d_length; ++i)
1121  d_str[i] = *(static_cast<string *> (val) + i);
1122 
1123  break;
1124 
1125  default:
1126  throw InternalErr(__FILE__, __LINE__, "Vector::val2buf: bad type");
1127 
1128  }
1129 
1130  return width(true);
1131 }
1132 
1163 unsigned int Vector::buf2val(void **val)
1164 {
1165  // Jose Garcia
1166  // The same comment in Vector::val2buf applies here!
1167  if (!val)
1168  throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
1169 
1170  unsigned int wid = static_cast<unsigned int> (width(true /* constrained */));
1171 
1172  // This is the width computed using length(). The
1173  // length() property is changed when a projection
1174  // constraint is applied. Thus this is the number of
1175  // bytes in the buffer given the current constraint.
1176 
1177  switch (d_proto->type()) {
1178  case dods_byte_c:
1179  case dods_char_c:
1180  case dods_int8_c:
1181  case dods_uint8_c:
1182  case dods_int16_c:
1183  case dods_uint16_c:
1184  case dods_int32_c:
1185  case dods_uint32_c:
1186  case dods_int64_c:
1187  case dods_uint64_c:
1188 
1189  case dods_enum_c:
1190 
1191  case dods_float32_c:
1192  case dods_float64_c:
1193  if (!d_buf)
1194  throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: Logic error: called when cardinal type data buffer was empty!");
1195  if (!*val)
1196  *val = new char[wid];
1197 
1198  memcpy(*val, d_buf, wid);
1199  return wid;
1200  break;
1201 
1202  case dods_str_c:
1203  case dods_url_c: {
1204  if (d_str.empty())
1205  throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: Logic error: called when string data buffer was empty!");
1206  if (!*val)
1207  *val = new string[d_length];
1208 
1209  for (int i = 0; i < d_length; ++i)
1210  *(static_cast<string *> (*val) + i) = d_str[i];
1211 
1212  return width();
1213  break;
1214  }
1215 
1216  default:
1217  throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: bad type");
1218  }
1219 
1220  //return wid;
1221 }
1222 
1243 void Vector::set_vec(unsigned int i, BaseType * val)
1244 {
1246 }
1247 
1254 void Vector::set_vec_nocopy(unsigned int i, BaseType * val)
1255 {
1256  // Jose Garcia
1257  // This is a public method which allows users to set the elements
1258  // of *this* vector. Passing an invalid index, a NULL pointer or
1259  // mismatching the vector type are internal errors.
1260  if (i >= static_cast<unsigned int> (d_length))
1261  throw InternalErr(__FILE__, __LINE__, "Invalid data: index too large.");
1262  if (!val)
1263  throw InternalErr(__FILE__, __LINE__, "Invalid data: null pointer to BaseType object.");
1264  if (val->type() != d_proto->type())
1265  throw InternalErr(__FILE__, __LINE__, "invalid data: type of incoming object does not match *this* vector type.");
1266 
1267  if (i >= d_compound_buf.capacity())
1268  vec_resize(i + 10);
1269 
1270  d_compound_buf[i] = val;
1271 }
1272 
1283 {
1284  if (d_buf) {
1285  delete[] d_buf;
1286  d_buf = 0;
1287  }
1288 
1289  for (unsigned int i = 0; i < d_compound_buf.size(); ++i) {
1290  delete d_compound_buf[i];
1291  d_compound_buf[i] = 0;
1292  }
1293 
1294  // Force memory to be reclaimed.
1295  d_compound_buf.resize(0);
1296  d_str.resize(0);
1297 
1298  d_capacity = 0;
1299  set_read_p(false);
1300 }
1301 
1309 unsigned int Vector::get_value_capacity() const
1310 {
1311  return d_capacity;
1312 }
1313 
1323 void Vector::reserve_value_capacity(unsigned int numElements)
1324 {
1325  if (!d_proto) {
1326  throw InternalErr(__FILE__, __LINE__, "reserve_value_capacity: Logic error: _var is null!");
1327  }
1328  switch (d_proto->type()) {
1329  case dods_byte_c:
1330  case dods_char_c:
1331  case dods_int8_c:
1332  case dods_uint8_c:
1333  case dods_int16_c:
1334  case dods_uint16_c:
1335  case dods_int32_c:
1336  case dods_uint32_c:
1337  case dods_int64_c:
1338  case dods_uint64_c:
1339 
1340  case dods_enum_c:
1341 
1342  case dods_float32_c:
1343  case dods_float64_c:
1344  // Make _buf be the right size and set _capacity
1346  break;
1347 
1348  case dods_str_c:
1349  case dods_url_c:
1350  // Make sure the d_str has enough room for all the strings.
1351  // Technically not needed, but it will speed things up for large arrays.
1352  d_str.reserve(numElements);
1353  d_capacity = numElements;
1354  break;
1355 
1356  case dods_array_c:
1357  throw InternalErr(__FILE__, __LINE__, "reserve_value_capacity: Arrays not supported!");
1358  break;
1359 
1360  case dods_opaque_c:
1361  case dods_structure_c:
1362  case dods_sequence_c:
1363  case dods_grid_c:
1364  // not clear anyone will go this path, but best to be complete.
1365  d_compound_buf.reserve(numElements);
1366  d_capacity = numElements;
1367  break;
1368 
1369  default:
1370  throw InternalErr(__FILE__, __LINE__, "reserve_value_capacity: Unknown type!");
1371  break;
1372 
1373  } // switch
1374 
1375 }
1376 
1383 {
1384  // Use the current length of the vector as the reserve amount.
1386 }
1387 
1416 unsigned int
1417 Vector::set_value_slice_from_row_major_vector(const Vector& rowMajorDataC, unsigned int startElement)
1418 {
1419  static const string funcName = "set_value_slice_from_row_major_vector:";
1420 
1421  // semantically const from the caller's viewpoint, but some calls are not syntactic const.
1422  Vector& rowMajorData = const_cast<Vector&>(rowMajorDataC);
1423 
1424  bool typesMatch = rowMajorData.var() && d_proto && (rowMajorData.var()->type() == d_proto->type());
1425  if (!typesMatch) {
1426  throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: types do not match so cannot be copied!");
1427  }
1428 
1429  // Make sure the data exists
1430  if (!rowMajorData.read_p()) {
1431  throw InternalErr(__FILE__, __LINE__,
1432  funcName + "Logic error: the Vector to copy data from has !read_p() and should have been read in!");
1433  }
1434 
1435  // Check this otherwise the static_cast<unsigned int> below will do the wrong thing.
1436  if (rowMajorData.length() < 0) {
1437  throw InternalErr(__FILE__, __LINE__,
1438  funcName
1439  + "Logic error: the Vector to copy data from has length() < 0 and was probably not initialized!");
1440  }
1441 
1442  // The read-in capacity had better be at least the length (the amount we will copy) or we'll memcpy into bad memory
1443  // I imagine we could copy just the capacity rather than throw, but I really think this implies a problem to be addressed.
1444  if (rowMajorData.get_value_capacity() < static_cast<unsigned int>(rowMajorData.length())) {
1445  throw InternalErr(__FILE__, __LINE__,
1446  funcName
1447  + "Logic error: the Vector to copy from has a data capacity less than its length, can't copy!");
1448  }
1449 
1450  // Make sure there's enough room in this Vector to store all the elements requested. Again,
1451  // better to throw than just copy what we can since it implies a logic error that needs to be solved.
1452  if (d_capacity < (startElement + rowMajorData.length())) {
1453  throw InternalErr(__FILE__, __LINE__,
1454  funcName + "Logic error: the capacity of this Vector cannot hold all the data in the from Vector!");
1455  }
1456 
1457  // OK, at this point we're pretty sure we can copy the data, but we have to do it differently depending on type.
1458  switch (d_proto->type()) {
1459  case dods_int8_c:
1460  case dods_uint8_c:
1461  case dods_byte_c:
1462  case dods_char_c:
1463  case dods_int16_c:
1464  case dods_uint16_c:
1465  case dods_int32_c:
1466  case dods_uint32_c:
1467  case dods_int64_c:
1468  case dods_uint64_c:
1469 
1470  case dods_enum_c:
1471 
1472  case dods_float32_c:
1473  case dods_float64_c: {
1474  if (!d_buf) {
1475  throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: this->_buf was unexpectedly null!");
1476  }
1477  if (!rowMajorData.d_buf) {
1478  throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: rowMajorData._buf was unexpectedly null!");
1479  }
1480  // memcpy the data into this, taking care to do ptr arithmetic on bytes and not sizeof(element)
1481  int varWidth = d_proto->width();
1482  char* pFromBuf = rowMajorData.d_buf;
1483  int numBytesToCopy = rowMajorData.width(true);
1484  char* pIntoBuf = d_buf + (startElement * varWidth);
1485  memcpy(pIntoBuf, pFromBuf, numBytesToCopy);
1486  break;
1487  }
1488 
1489  case dods_str_c:
1490  case dods_url_c:
1491  // Strings need to be copied directly
1492  for (unsigned int i = 0; i < static_cast<unsigned int>(rowMajorData.length()); ++i) {
1493  d_str[startElement + i] = rowMajorData.d_str[i];
1494  }
1495  break;
1496 
1497  case dods_array_c:
1498  case dods_opaque_c:
1499  case dods_structure_c:
1500  case dods_sequence_c:
1501  case dods_grid_c:
1502  // Not sure that this function will be used for these type of nested objects, so I will throw here.
1503  // TODO impl and test this path if it's ever needed.
1504  throw InternalErr(__FILE__, __LINE__,
1505  funcName + "Unimplemented method for Vectors of type: array, opaque, structure, sequence or grid.");
1506  break;
1507 
1508  default:
1509  throw InternalErr(__FILE__, __LINE__, funcName + ": Unknown type!");
1510  break;
1511 
1512  } // switch (_var->type())
1513 
1514  // This is how many elements we copied.
1515  return (unsigned int) rowMajorData.length();
1516 }
1517 
1526 template <typename T>
1527 static bool types_match(Type t, T *cpp_var)
1528 {
1529  switch (t) {
1530  case dods_byte_c:
1531  case dods_char_c:
1532  case dods_uint8_c:
1533  return typeid(cpp_var) == typeid(dods_byte*);
1534 
1535  case dods_int8_c:
1536  return typeid(cpp_var) == typeid(dods_int8*);
1537  case dods_int16_c:
1538  return typeid(cpp_var) == typeid(dods_int16*);
1539  case dods_uint16_c:
1540  return typeid(cpp_var) == typeid(dods_uint16*);
1541  case dods_int32_c:
1542  return typeid(cpp_var) == typeid(dods_int32*);
1543  case dods_uint32_c:
1544  return typeid(cpp_var) == typeid(dods_uint32*);
1545  case dods_int64_c:
1546  return typeid(cpp_var) == typeid(dods_int64*);
1547  case dods_uint64_c:
1548  return typeid(cpp_var) == typeid(dods_uint64*);
1549 
1550  case dods_float32_c:
1551  return typeid(cpp_var) == typeid(dods_float32*);
1552  case dods_float64_c:
1553  return typeid(cpp_var) == typeid(dods_float64*);
1554 
1555  case dods_null_c:
1556  case dods_enum_c:
1557  case dods_str_c:
1558  case dods_url_c:
1559  case dods_opaque_c:
1560  case dods_array_c:
1561  case dods_structure_c:
1562  case dods_sequence_c:
1563  case dods_group_c:
1564  default:
1565  return false;
1566  }
1567 }
1568 
1570 
1572 template <typename T>
1573 bool Vector::set_value(T *v, int sz)
1574 {
1575  if (!v || !types_match(d_proto->type() == dods_enum_c ? static_cast<D4Enum*>(d_proto)->element_type() : d_proto->type(), v))
1576  return false;
1577 
1579  return true;
1580 }
1581 
1582 template <typename T>
1583 bool Vector::set_value(vector<T> &v, int sz)
1584 {
1585  // Extra call worth the overhead?
1586  return set_value(&v[0], sz);
1587 #if 0
1588  if (!v || !types_match(d_proto->type() == dods_enum_c ? static_cast<D4Enum*>(d_proto)->element_type() : d_proto->type(), v))
1589  return false;
1590 
1591  m_set_cardinal_values_internal(&v[0], sz);
1592  return true;
1593 #endif
1594 }
1595 
1596 template bool Vector::set_value(dods_byte *val, int sz);
1597 template bool Vector::set_value(dods_int8 *val, int sz);
1598 template bool Vector::set_value(dods_int16 *val, int sz);
1599 template bool Vector::set_value(dods_uint16 *val, int sz);
1600 template bool Vector::set_value(dods_int32 *val, int sz);
1601 template bool Vector::set_value(dods_uint32 *val, int sz);
1602 template bool Vector::set_value(dods_int64 *val, int sz);
1603 template bool Vector::set_value(dods_uint64 *val, int sz);
1604 template bool Vector::set_value(dods_float32 *val, int sz);
1605 template bool Vector::set_value(dods_float64 *val, int sz);
1606 
1607 template bool Vector::set_value(vector<dods_byte> &val, int sz);
1608 template bool Vector::set_value(vector<dods_int8> &val, int sz);
1609 template bool Vector::set_value(vector<dods_int16> &val, int sz);
1610 template bool Vector::set_value(vector<dods_uint16> &val, int sz);
1611 template bool Vector::set_value(vector<dods_int32> &val, int sz);
1612 template bool Vector::set_value(vector<dods_uint32> &val, int sz);
1613 template bool Vector::set_value(vector<dods_int64> &val, int sz);
1614 template bool Vector::set_value(vector<dods_uint64> &val, int sz);
1615 template bool Vector::set_value(vector<dods_float32> &val, int sz);
1616 template bool Vector::set_value(vector<dods_float64> &val, int sz);
1617 
1618 #if 0
1619 bool Vector::set_value(dods_byte *val, int sz)
1620 {
1621  assert(var()->type() == dods_byte_c || var()->type() == dods_uint8_c);
1622  assert(val);
1623 
1624  m_set_cardinal_values_internal<dods_byte> (val, sz);
1625  return true;
1626 
1627 #if 0
1628  // TODO Recode all of these like this and drop the bool return type?
1629  if (var()->type() == dods_byte_c && val) {
1630  m_set_cardinal_values_internal<dods_byte> (val, sz);
1631  return true;
1632  }
1633  else {
1634  return false;
1635  }
1636 #endif
1637 }
1638 
1640 bool Vector::set_value(vector<dods_byte> &val, int sz)
1641 {
1642  // TODO Drop the extra call or is it not worth the optimization cost?
1643  return set_value(&val[0], sz);
1644 }
1645 
1647 bool Vector::set_value(dods_int8 *val, int sz)
1648 {
1649  if (var()->type() == dods_int8_c && val) {
1650  m_set_cardinal_values_internal<dods_int8> (val, sz);
1651  return true;
1652  }
1653  else {
1654  return false;
1655  }
1656 }
1657 
1659 bool Vector::set_value(vector<dods_int8> &val, int sz)
1660 {
1661  return set_value(&val[0], sz);
1662 }
1663 
1665 bool Vector::set_value(dods_int16 *val, int sz)
1666 {
1667  if (var()->type() == dods_int16_c && val) {
1668  m_set_cardinal_values_internal<dods_int16> (val, sz);
1669  return true;
1670  }
1671  else {
1672  return false;
1673  }
1674 }
1675 
1677 bool Vector::set_value(vector<dods_int16> &val, int sz)
1678 {
1679  return set_value(&val[0], sz);
1680 }
1681 
1683 bool Vector::set_value(dods_int32 *val, int sz)
1684 {
1685  if (var()->type() == dods_int32_c && val) {
1686  m_set_cardinal_values_internal<dods_int32> (val, sz);
1687  return true;
1688  }
1689  else {
1690  return false;
1691  }
1692 }
1693 
1695 bool Vector::set_value(vector<dods_int32> &val, int sz)
1696 {
1697  return set_value(&val[0], sz);
1698 }
1699 
1701 bool Vector::set_value(dods_int64 *val, int sz)
1702 {
1703  if (var()->type() == dods_int64_c && val) {
1704  m_set_cardinal_values_internal<dods_int64> (val, sz);
1705  return true;
1706  }
1707  else {
1708  return false;
1709  }
1710 }
1711 
1713 bool Vector::set_value(vector<dods_int64> &val, int sz)
1714 {
1715  return set_value(&val[0], sz);
1716 }
1717 
1719 bool Vector::set_value(dods_uint16 *val, int sz)
1720 {
1721  if (var()->type() == dods_uint16_c && val) {
1722  m_set_cardinal_values_internal<dods_uint16> (val, sz);
1723  return true;
1724  }
1725  else {
1726  return false;
1727  }
1728 }
1729 
1731 bool Vector::set_value(vector<dods_uint16> &val, int sz)
1732 {
1733  return set_value(&val[0], sz);
1734 }
1735 
1737 bool Vector::set_value(dods_uint32 *val, int sz)
1738 {
1739  if (var()->type() == dods_uint32_c && val) {
1740  m_set_cardinal_values_internal<dods_uint32> (val, sz);
1741  return true;
1742  }
1743  else {
1744  return false;
1745  }
1746 }
1747 
1749 bool Vector::set_value(vector<dods_uint32> &val, int sz)
1750 {
1751  return set_value(&val[0], sz);
1752 }
1753 
1755 bool Vector::set_value(dods_uint64 *val, int sz)
1756 {
1757  if (var()->type() == dods_uint64_c && val) {
1758  m_set_cardinal_values_internal<dods_uint64> (val, sz);
1759  return true;
1760  }
1761  else {
1762  return false;
1763  }
1764 }
1765 
1767 bool Vector::set_value(vector<dods_uint64> &val, int sz)
1768 {
1769  return set_value(&val[0], sz);
1770 }
1771 
1773 bool Vector::set_value(dods_float32 *val, int sz)
1774 {
1775  if (var()->type() == dods_float32_c && val) {
1776  m_set_cardinal_values_internal<dods_float32> (val, sz);
1777  return true;
1778  }
1779  else {
1780  return false;
1781  }
1782 }
1783 
1785 bool Vector::set_value(vector<dods_float32> &val, int sz)
1786 {
1787  return set_value(&val[0], sz);
1788 }
1789 
1791 bool Vector::set_value(dods_float64 *val, int sz)
1792 {
1793  if (var()->type() == dods_float64_c && val) {
1794  m_set_cardinal_values_internal<dods_float64> (val, sz);
1795  return true;
1796  }
1797  else {
1798  return false;
1799  }
1800 }
1801 
1803 bool Vector::set_value(vector<dods_float64> &val, int sz)
1804 {
1805  return set_value(&val[0], sz);
1806 }
1807 #endif
1808 
1810 bool Vector::set_value(string *val, int sz)
1811 {
1812  if ((var()->type() == dods_str_c || var()->type() == dods_url_c) && val) {
1813  d_str.resize(sz);
1814  d_capacity = sz;
1815  for (register int t = 0; t < sz; t++) {
1816  d_str[t] = val[t];
1817  }
1818  set_length(sz);
1819  set_read_p(true);
1820  return true;
1821  }
1822  else {
1823  return false;
1824  }
1825 }
1826 
1828 bool Vector::set_value(vector<string> &val, int sz)
1829 {
1830  if (var()->type() == dods_str_c || var()->type() == dods_url_c) {
1831  d_str.resize(sz);
1832  d_capacity = sz;
1833  for (register int t = 0; t < sz; t++) {
1834  d_str[t] = val[t];
1835  }
1836  set_length(sz);
1837  set_read_p(true);
1838  return true;
1839  }
1840  else {
1841  return false;
1842  }
1843 }
1845 
1847 
1864 template <typename T>
1865 void Vector::value(vector<unsigned int> *indices, T *b) const
1866 {
1867  // unsigned long currentIndex;
1868 #if 0
1869  // Iterator version. Not tested, jhrg 8/14/13
1870  for (vector<unsigned int>::iterator i = indices->begin(), e = indices->end(); i != e; ++i) {
1871  unsigned long currentIndex = *i;
1872  if(currentIndex > (unsigned int)length()){
1873  stringstream s;
1874  s << "Vector::value() - Subset index[" << i - subsetIndex->begin() << "] = " << currentIndex << " references a value that is " <<
1875  "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
1876  throw Error(s.str());
1877  }
1878  b[i - indices->begin()] = reinterpret_cast<T*>(d_buf )[currentIndex];
1879  }
1880 #endif
1881  for (unsigned long i = 0, e = indices->size(); i < e; ++i) {
1882  unsigned long currentIndex = (*indices)[i];
1883  if (currentIndex > (unsigned int)length()) {
1884  stringstream s;
1885  s << "Vector::value() - Subset index[" << i << "] = " << currentIndex << " references a value that is " <<
1886  "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
1887  throw Error(s.str());
1888  }
1889  b[i] = reinterpret_cast<T*>(d_buf )[currentIndex]; // I like this version - and it works!
1890  }
1891 }
1892 
1893 template void Vector::value(vector<unsigned int> *indices, dods_byte *b) const;
1894 template void Vector::value(vector<unsigned int> *indices, dods_int8 *b) const;
1895 template void Vector::value(vector<unsigned int> *indices, dods_int16 *b) const;
1896 template void Vector::value(vector<unsigned int> *indices, dods_uint16 *b) const;
1897 template void Vector::value(vector<unsigned int> *indices, dods_int32 *b) const;
1898 template void Vector::value(vector<unsigned int> *indices, dods_uint32 *b) const;
1899 template void Vector::value(vector<unsigned int> *indices, dods_int64 *b) const;
1900 template void Vector::value(vector<unsigned int> *indices, dods_uint64 *b) const;
1901 template void Vector::value(vector<unsigned int> *indices, dods_float32 *b) const;
1902 template void Vector::value(vector<unsigned int> *indices, dods_float64 *b) const;
1903 
1904 #if 0
1905 void Vector::value(vector<unsigned int> *subsetIndex, dods_byte *b) const
1906 {
1907  // unsigned long currentIndex;
1908 #if 0
1909  // Iterator version. Not tested, jhrg 8/14/13
1910  for (vector<unsigned int>::iterator i = subsetIndex->begin(); i != subsetIndex->end(); ++i) {
1911  unsigned long currentIndex = *i;
1912  if(currentIndex > (unsigned int)length()){
1913  stringstream s;
1914  s << "Vector::value() - Subset index[" << i - subsetIndex->begin() << "] = " << currentIndex << " references a value that is " <<
1915  "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
1916  throw Error(s.str());
1917  }
1918  b[i] = reinterpret_cast<dods_byte*>(d_buf )[currentIndex];
1919  }
1920 #endif
1921  for(unsigned long i=0; i<subsetIndex->size() ;++i){
1922  unsigned long currentIndex = (*subsetIndex)[i] ;
1923  if(currentIndex> (unsigned int)length()){
1924  stringstream s;
1925  s << "Vector::value() - Subset index[" << i << "] = " << currentIndex << " references a value that is " <<
1926  "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
1927  throw Error(s.str());
1928  }
1929  b[i] = reinterpret_cast<dods_byte*>(d_buf )[currentIndex]; // I like this version - and it works!
1930  }
1931 }
1932 
1933 void Vector::value(vector<unsigned int> *subsetIndex, dods_int8 *b) const
1934 {
1935  // unsigned long currentIndex;
1936 #if 0
1937  // Iterator version. Not tested, jhrg 8/14/13
1938  for (vector<unsigned int>::iterator i = subsetIndex->begin(); i != subsetIndex->end(); ++i) {
1939  unsigned long currentIndex = *i;
1940  if(currentIndex > (unsigned int)length()){
1941  stringstream s;
1942  s << "Vector::value() - Subset index[" << i - subsetIndex->begin() << "] = " << currentIndex << " references a value that is " <<
1943  "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
1944  throw Error(s.str());
1945  }
1946  b[i] = reinterpret_cast<dods_byte*>(d_buf )[currentIndex];
1947  }
1948 #endif
1949  for(unsigned long i=0; i<subsetIndex->size() ;++i){
1950  unsigned long currentIndex = (*subsetIndex)[i] ;
1951  if(currentIndex> (unsigned int)length()){
1952  stringstream s;
1953  s << "Vector::value() - Subset index[" << i << "] = " << currentIndex << " references a value that is " <<
1954  "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
1955  throw Error(s.str());
1956  }
1957  b[i] = reinterpret_cast<dods_int8*>(d_buf )[currentIndex]; // I like this version - and it works!
1958  }
1959 }
1960 
1962 void Vector::value(vector<unsigned int> *subsetIndex, dods_uint16 *b) const
1963 {
1964  unsigned long currentIndex;
1965 
1966  for(unsigned long i=0; i<subsetIndex->size() ;++i){
1967  currentIndex = (*subsetIndex)[i] ;
1968  if(currentIndex> (unsigned int)length()){
1969  stringstream s;
1970  s << "Vector::value() - Subset index[" << i << "] = " << currentIndex << " references a value that is " <<
1971  "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
1972  throw Error(s.str());
1973  }
1974  b[i] = reinterpret_cast<dods_uint16*>(d_buf )[currentIndex]; // I like this version - and it works!
1975  }
1976 }
1977 
1978 
1980 void Vector::value(vector<unsigned int> *subsetIndex, dods_int16 *b) const
1981 {
1982  unsigned long currentIndex;
1983 
1984  for(unsigned long i=0; i<subsetIndex->size() ;++i){
1985  currentIndex = (*subsetIndex)[i] ;
1986  if(currentIndex> (unsigned int)length()){
1987  stringstream s;
1988  s << "Vector::value() - Subset index[" << i << "] = " << currentIndex << " references a value that is " <<
1989  "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
1990  throw Error(s.str());
1991  }
1992  b[i] = reinterpret_cast<dods_int16*>(d_buf )[currentIndex]; // I like this version - and it works!
1993  }
1994 }
1995 
1997 void Vector::value(vector<unsigned int> *subsetIndex, dods_uint32 *b) const
1998 {
1999  unsigned long currentIndex;
2000 
2001  for(unsigned long i=0; i<subsetIndex->size() ;++i){
2002  currentIndex = (*subsetIndex)[i] ;
2003  if(currentIndex> (unsigned int)length()){
2004  stringstream s;
2005  s << "Vector::value() - Subset index[" << i << "] = " << currentIndex << " references a value that is " <<
2006  "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
2007  throw Error(s.str());
2008  }
2009  b[i] = reinterpret_cast<dods_uint32*>(d_buf )[currentIndex]; // I like this version - and it works!
2010  }
2011 }
2012 
2014 void Vector::value(vector<unsigned int> *subsetIndex, dods_int32 *b) const
2015 {
2016  unsigned long currentIndex;
2017 
2018  for(unsigned long i=0; i<subsetIndex->size() ;++i){
2019  currentIndex = (*subsetIndex)[i] ;
2020  if(currentIndex> (unsigned int)length()){
2021  stringstream s;
2022  s << "Vector::value() - Subset index[" << i << "] = " << currentIndex << " references a value that is " <<
2023  "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
2024  throw Error(s.str());
2025  }
2026  b[i] = reinterpret_cast<dods_int32*>(d_buf )[currentIndex]; // I like this version - and it works!
2027  }
2028 }
2029 
2031 void Vector::value(vector<unsigned int> *subsetIndex, dods_float32 *b) const
2032 {
2033  unsigned long currentIndex;
2034 
2035  for(unsigned long i=0; i<subsetIndex->size() ;++i){
2036  currentIndex = (*subsetIndex)[i] ;
2037  if(currentIndex> (unsigned int)length()){
2038  stringstream s;
2039  s << "Vector::value() - Subset index[" << i << "] = " << currentIndex << " references a value that is " <<
2040  "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
2041  throw Error(s.str());
2042  }
2043 
2044  b[i] = reinterpret_cast<dods_float32*>(d_buf )[currentIndex];
2045  }
2046 }
2047 
2049 void Vector::value(vector<unsigned int> *subsetIndex, dods_float64 *b) const
2050 {
2051  unsigned long currentIndex;
2052 
2053  for(unsigned long i=0; i<subsetIndex->size() ;++i){
2054  currentIndex = (*subsetIndex)[i] ;
2055  if(currentIndex> (unsigned int)length()){
2056  stringstream s;
2057  s << "Vector::value() - Subset index[" << i << "] = " << currentIndex << " references a value that is " <<
2058  "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
2059  throw Error(s.str());
2060  }
2061  b[i] = reinterpret_cast<dods_float64*>(d_buf )[currentIndex]; // I like this version - and it works!
2062  }
2063 }
2064 #endif
2065 
2067 void Vector::value(vector<unsigned int> *subsetIndex, vector<string> &b) const
2068 {
2069  unsigned long currentIndex;
2070 
2071  if (d_proto->type() == dods_str_c || d_proto->type() == dods_url_c){
2072  for(unsigned long i=0; i<subsetIndex->size() ;++i){
2073  currentIndex = (*subsetIndex)[i] ;
2074  if(currentIndex > (unsigned int)length()){
2075  stringstream s;
2076  s << "Vector::value() - Subset index[" << i << "] = " << currentIndex << " references a value that is " <<
2077  "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
2078  throw Error(s.str());
2079  }
2080  b[i] = d_str[currentIndex];
2081  }
2082  }
2083 }
2084 
2085 template <typename T>
2086 void Vector::value(T *v) const
2087 {
2088  // Only copy if v is not null and the proto's type matches.
2089  // For Enums, use the element type since type == dods_enum_c.
2090  if (v && types_match(d_proto->type() == dods_enum_c ? static_cast<D4Enum*>(d_proto)->element_type() : d_proto->type(), v))
2091  memcpy(v, d_buf, length() * sizeof(T));
2092 }
2093 
2094 template void Vector::value(dods_byte *v) const;
2095 template void Vector::value(dods_int8 *v) const;
2096 template void Vector::value(dods_int16 *v) const;
2097 template void Vector::value(dods_uint16 *v) const;
2098 template void Vector::value(dods_int32 *v) const;
2099 template void Vector::value(dods_uint32 *v) const;
2100 template void Vector::value(dods_int64 *v) const;
2101 template void Vector::value(dods_uint64 *v) const;
2102 template void Vector::value(dods_float32 *v) const;
2103 template void Vector::value(dods_float64 *v) const;
2104 
2105 #if 0
2106 
2113 void Vector::value(dods_byte *b) const
2114 {
2115  if (b && d_proto->type() == dods_byte_c) {
2116  memcpy(b, d_buf, length() * sizeof(dods_byte));
2117  }
2118 }
2119 
2121 void Vector::value(dods_int8 *b) const
2122 {
2123  if (b && d_proto->type() == dods_int8_c) {
2124  memcpy(b, d_buf, length() * sizeof(dods_int8));
2125  }
2126 }
2127 
2129 void Vector::value(dods_uint16 *b) const
2130 {
2131  if (b && d_proto->type() == dods_uint16_c) {
2132  memcpy(b, d_buf, length() * sizeof(dods_uint16));
2133  }
2134 }
2135 
2137 void Vector::value(dods_int16 *b) const
2138 {
2139  if (b && d_proto->type() == dods_int16_c) {
2140  memcpy(b, d_buf, length() * sizeof(dods_int16));
2141  }
2142 }
2143 
2145 void Vector::value(dods_uint32 *b) const
2146 {
2147  if (b && d_proto->type() == dods_uint32_c) {
2148  memcpy(b, d_buf, length() * sizeof(dods_uint32));
2149  }
2150 }
2151 
2153 void Vector::value(dods_int32 *b) const
2154 {
2155  if (b && d_proto->type() == dods_int32_c) {
2156  memcpy(b, d_buf, length() * sizeof(dods_int32));
2157  }
2158 }
2159 
2161 void Vector::value(dods_uint64 *b) const
2162 {
2163  if (b && d_proto->type() == dods_uint64_c) {
2164  memcpy(b, d_buf, length() * sizeof(dods_uint64));
2165  }
2166 }
2167 
2169 void Vector::value(dods_int64 *b) const
2170 {
2171  if (b && d_proto->type() == dods_int64_c) {
2172  memcpy(b, d_buf, length() * sizeof(dods_int64));
2173  }
2174 }
2175 
2177 void Vector::value(dods_float32 *b) const
2178 {
2179  if (b && d_proto->type() == dods_float32_c) {
2180  memcpy(b, d_buf, length() * sizeof(dods_float32));
2181  }
2182 }
2183 
2185 void Vector::value(dods_float64 *b) const
2186 {
2187  if (b && d_proto->type() == dods_float64_c) {
2188  memcpy(b, d_buf, length() * sizeof(dods_float64));
2189  }
2190 }
2191 #endif
2192 
2194 void Vector::value(vector<string> &b) const
2195 {
2196  if (d_proto->type() == dods_str_c || d_proto->type() == dods_url_c)
2197  b = d_str;
2198 }
2199 
2203 {
2204  void *buffer = new char[width(true)];
2205 
2206  memcpy(buffer, d_buf, width(true));
2207 
2208  return buffer;
2209 }
2211 
2228 {
2229 #if 0
2230  //TODO Why doesn't this work? tried all 3 variants. jhrg 8/14/13
2232  add_var_nocopy(v->ptr_duplicate(), p);
2234 #else
2235  // Delete the current template variable
2236  if (d_proto) {
2237  delete d_proto;
2238  d_proto = 0;
2239  }
2240 
2241  // if 'v' is null, just set _var to null and exit.
2242  if (!v) {
2243  d_proto = 0;
2244  }
2245  else {
2246  // Jose Garcia
2247  // By getting a copy of this object to be assigned to _var
2248  // we let the owner of 'v' to deallocate it as necessary.
2249  d_proto = v->ptr_duplicate();
2250 
2251  // If 'v' has a name, use it as the name of the array. If v doesn't have
2252  // a name, then make sure to copy the array's name to it
2253  // so that software which uses the template's name will still work.
2254  if (!v->name().empty())
2255  set_name(v->name());
2256  else
2257  d_proto->set_name(name());
2258 
2259  d_proto->set_parent(this); // Vector --> child
2260 
2261  DBG(cerr << "Vector::add_var: Added variable " << v << " ("
2262  << v->name() << " " << v->type_name() << ")" << endl);
2263  }
2264 #endif
2265 }
2266 
2268 {
2269  // Delete the current template variable
2270  if (d_proto) {
2271  delete d_proto;
2272  d_proto = 0;
2273  }
2274 
2275  // if 'v' is null, just set _var to null and exit.
2276  if (!v) {
2277  d_proto = 0;
2278  }
2279  else {
2280  d_proto = v;
2281 
2282  // If 'v' has a name, use it as the name of the array. If it *is*
2283  // empty, then make sure to copy the array's name to the template
2284  // so that software which uses the template's name will still work.
2285  if (!v->name().empty())
2286  set_name(v->name());
2287  else
2288  d_proto->set_name(name());
2289 
2290  d_proto->set_parent(this); // Vector is the parent; proto is the child
2291 
2292  DBG(cerr << "Vector::add_var_no_copy: Added variable " << v << " ("
2293  << v->name() << " " << v->type_name() << ")" << endl);
2294  }
2295 }
2296 
2297 bool Vector::check_semantics(string & msg, bool)
2298 {
2299  return BaseType::check_semantics(msg);
2300 }
2301 
2310 void Vector::dump(ostream &strm) const
2311 {
2312  strm << DapIndent::LMarg << "Vector::dump - (" << (void *) this << ")" << endl;
2314  BaseType::dump(strm);
2315  strm << DapIndent::LMarg << "# elements in vector: " << d_length << endl;
2316  if (d_proto) {
2317  strm << DapIndent::LMarg << "base type:" << endl;
2319  d_proto->dump(strm);
2321  }
2322  else {
2323  strm << DapIndent::LMarg << "base type: not set" << endl;
2324  }
2325  strm << DapIndent::LMarg << "vector contents:" << endl;
2327  for (unsigned i = 0; i < d_compound_buf.size(); ++i) {
2328  if (d_compound_buf[i])
2329  d_compound_buf[i]->dump(strm);
2330  else
2331  strm << DapIndent::LMarg << "vec[" << i << "] is null" << endl;
2332  }
2334  strm << DapIndent::LMarg << "strings:" << endl;
2336  for (unsigned i = 0; i < d_str.size(); i++) {
2337  strm << DapIndent::LMarg << d_str[i] << endl;
2338  }
2340  if (d_buf) {
2341  switch (d_proto->type()) {
2342  case dods_byte_c:
2343  case dods_char_c: {
2344  strm << DapIndent::LMarg << "_buf: ";
2345  strm.write(d_buf, d_length);
2346  strm << endl;
2347  }
2348  break;
2349  default: {
2350  strm << DapIndent::LMarg << "_buf: " << (void *) d_buf << endl;
2351  }
2352  break;
2353  }
2354  }
2355  else {
2356  strm << DapIndent::LMarg << "_buf: EMPTY" << endl;
2357  }
2359 }
2360 
2361 } // namespace libdap
2362 
virtual bool read()
Read data into a local buffer.
Definition: BaseType.cc:805
virtual bool read_p()
Has this variable been read?
Definition: BaseType.cc:421
virtual void put_int(int val)=0
static void UnIndent()
Definition: DapIndent.cc:51
abstract base class used to unmarshall/deserialize dap data objects
Definition: UnMarshaller.h:54
virtual unsigned int width(bool constrained=false) const
How many bytes does this use Return the number of bytes of storage this variable uses. For scalar types, this is pretty simple (an int32 uses 4 bytes, etc.). For arrays and Constructors, it is a bit more complex. Note that a scalar String variable uses sizeof(String*) bytes, not the length of the string. In other words, the value returned is independent of the type. Also note width() of a String array returns the number of elements in the array times sizeof(String*). That is, each different array size is a different data type.
Definition: BaseType.cc:1179
virtual void add_var_nocopy(BaseType *v, Part p=nil)
Definition: Vector.cc:2267
DINT32 dods_int32
virtual unsigned int get_value_capacity() const
Definition: Vector.cc:1309
uint8_t dods_byte
void set_vec(unsigned int i, BaseType *val)
Sets element i to value val.
Definition: Vector.cc:1243
int64_t dods_int64
Part
Names the parts of multi-section constructor data types.
Definition: Type.h:48
DUINT32 dods_uint32
virtual void set_name(const string &n)
Sets the name of the class instance.
Definition: BaseType.cc:285
virtual void put_str(const string &val)=0
Holds a one-dimensional collection of DAP2 data types.
Definition: Vector.h:80
virtual void dump(ostream &strm) const
dumps information about this object
Definition: Vector.cc:2310
virtual void get_vector_float32(char *val, int64_t num_elem)
void clear_local_data()
Definition: Vector.cc:1282
DFLOAT32 dods_float32
Read data from the stream made by D4StreamMarshaller.
virtual int length() const
Definition: Vector.cc:513
virtual void compute_checksum(Crc32 &checksum)
include the data for this variable in the checksum DAP4 includes a checksum with every data response...
Definition: Vector.cc:801
virtual void set_read_p(bool state)
Indicates that the data is ready to send.
Definition: Vector.cc:362
Definition: crc.h:76
virtual void add_var(BaseType *v, Part p=nil)
Add the BaseType pointer to this constructor type instance.
Definition: Vector.cc:2227
DINT64 dods_int64
virtual void get_str(string &val)
virtual int element_count(bool leaves)
Count the members of constructor types.
Definition: Vector.cc:329
virtual void * value()
Definition: Vector.cc:2202
void m_set_cardinal_values_internal(const CardType *fromArray, int numElts)
Definition: Vector.cc:215
void timeout_off()
Definition: DDS.cc:894
virtual unsigned int set_value_slice_from_row_major_vector(const Vector &rowMajorData, unsigned int startElement)
Definition: Vector.cc:1417
virtual void put_vector_float32(char *val, int64_t num_elem)
Write a fixed size vector.
Type
Identifies the data type.
Definition: Type.h:94
Type type() const
Returns the type of the class instance.
Definition: BaseType.cc:306
uint16_t dods_uint16
#define DBG2(x)
Definition: debug.h:73
stack< BaseType * > btp_stack
Definition: BaseType.h:149
uint64_t dods_uint64
virtual bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval=true)
Serialize a Vector.
Definition: Vector.cc:622
virtual void set_parent(BaseType *parent)
Definition: BaseType.cc:639
A class for software fault reporting.
Definition: InternalErr.h:64
string dataset() const
Returns the name of the dataset used to create this instance.
Definition: BaseType.cc:299
virtual BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=0)
Definition: Vector.cc:387
virtual void get_str(string &val)=0
DUINT64 dods_uint64
virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse=false)
Receive data from the net.
Definition: Vector.cc:708
virtual BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=0)
Returns a pointer to a member of a constructor class.
Definition: BaseType.cc:664
virtual void compute_checksum(Crc32 &checksum)=0
include the data for this variable in the checksum DAP4 includes a checksum with every data response...
bool set_value(T *v, int sz)
set the value of a byte array
Definition: Vector.cc:1573
#define DBG(x)
Definition: debug.h:58
string type_name() const
Returns the type of the class instance as a string.
Definition: BaseType.cc:320
Holds a DAP4 enumeration.
Definition: D4Enum.h:55
virtual bool is_constructor_type() const
Returns true if the instance is a constructor (i.e., Structure, Sequence or Grid) type variable...
Definition: BaseType.cc:353
virtual int element_count(bool leaves=false)
Count the members of constructor types.
Definition: BaseType.cc:384
Marshaller that knows how to marshal/serialize dap data objects to a C++ iostream using DAP4's receiv...
virtual void set_send_p(bool state)
Definition: BaseType.cc:498
double dods_float64
static void Indent()
Definition: DapIndent.cc:45
void set_vec_nocopy(unsigned int i, BaseType *val)
Sets element i to value val.
Definition: Vector.cc:1254
virtual void dump(ostream &strm) const
dumps information about this object
Definition: BaseType.cc:237
bool m_is_cardinal_type() const
Definition: Vector.cc:122
uint32_t dods_uint32
virtual void reserve_value_capacity()
Definition: Vector.cc:1382
Vector & operator=(const Vector &rhs)
Definition: Vector.cc:307
virtual void set_read_p(bool state)
Sets the value of the read_p property.
Definition: BaseType.cc:454
Vector(const string &n, BaseType *v, const Type &t, bool is_dap4=false)
The Vector constructor.
Definition: Vector.cc:244
virtual ~Vector()
Definition: Vector.cc:294
virtual unsigned int val2buf(void *val, bool reuse=false)
Reads data into the Vector buffer. Thrown if called for Structure, Sequence or Grid.
Definition: Vector.cc:1071
virtual bool check_semantics(string &msg, bool all=false)
Compare an object's current state with the semantics of its type.
Definition: Vector.cc:2297
void m_delete_cardinal_data_buffer()
Definition: Vector.cc:204
void AddData(const uint8_t *pData, const uint32_t length)
Definition: crc.h:84
virtual unsigned int val2buf(void *val, bool reuse=false)=0
Loads class data.
string name() const
Returns the name of the class instance.
Definition: BaseType.cc:261
virtual void put_vector(char *val, int num, Vector &vec)=0
virtual BaseType * ptr_duplicate()=0
string www2id(const string &in, const string &escape, const string &except)
Definition: escaping.cc:220
void timeout_on()
Definition: DDS.cc:886
Evaluate a constraint expression.
virtual void get_vector_float64(char *val, int64_t num_elem)
static ostream & LMarg(ostream &strm)
Definition: DapIndent.cc:80
virtual void set_send_p(bool state)
Indicates that the data is ready to send.
Definition: Vector.cc:350
int16_t dods_int16
unsigned int m_create_cardinal_data_buffer_for_type(unsigned int numEltsOfType)
Definition: Vector.cc:180
virtual void put_vector(char *val, int64_t num_bytes)
Write a fixed size vector.
The basic data type for the DODS DAP types.
Definition: BaseType.h:117
DINT8 dods_int8
DUINT16 dods_uint16
abstract base class used to marshal/serialize dap data objects
Definition: Marshaller.h:53
virtual void set_name(const std::string &name)
Definition: Vector.cc:319
void m_duplicate(const Vector &v)
Definition: Vector.cc:73
virtual unsigned int buf2val(void **val)
Definition: Vector.cc:1163
virtual void get_int(int &val)=0
bool eval_selection(DDS &dds, const std::string &dataset)
Evaluate a boolean-valued constraint expression. This is main method for the evaluator ans is called ...
DFLOAT64 dods_float64
virtual void set_length(int l)
Definition: Vector.cc:520
DBYTE dods_byte
A class for error processing.
Definition: Error.h:90
virtual void put_vector_float64(char *val, int64_t num_elem)
Write a fixed size vector of float64s.
virtual void intern_data(ConstraintEvaluator &eval, DDS &dds)
read data into a variable for later use
Definition: Vector.cc:559
DINT16 dods_int16
void vec_resize(int l)
Definition: Vector.cc:533
virtual void get_vector(char **val, unsigned int &num, Vector &vec)=0
virtual void put_str(const string &val)
virtual void get_vector(char **, unsigned int &, Vector &)
virtual unsigned int width(bool constrained=false) const
Returns the width of the data, in bytes.
Definition: Vector.cc:498
virtual bool check_semantics(string &msg, bool all=false)
Compare an object's current state with the semantics of its type.
Definition: BaseType.cc:1111
int32_t dods_int32