libdap++  Updated for version 3.14.0
D4Enum.cc
Go to the documentation of this file.
1 
2 // -*- mode: c++; c-basic-offset:4 -*-
3 
4 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
5 // Access Protocol.
6 
7 // Copyright (c) 2013 OPeNDAP, Inc.
8 // Author: James Gallagher <jgallagher@opendap.org>
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 //
24 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25 
26 #include "config.h"
27 
28 #include <cassert>
29 #include <sstream>
30 
31 #include "Byte.h" // synonymous with UInt8 and Char
32 #include "Int8.h"
33 #include "Int16.h"
34 #include "UInt16.h"
35 #include "Int32.h"
36 #include "UInt32.h"
37 
38 #include "D4Group.h"
39 #include "D4Enum.h"
40 #include "D4EnumDefs.h"
41 #include "D4Attributes.h"
42 
43 #include "Float32.h"
44 #include "Float64.h"
45 
46 #include "D4StreamMarshaller.h"
47 #include "D4StreamUnMarshaller.h"
48 
49 #include "Operators.h"
50 #include "InternalErr.h"
51 #include "util.h"
52 #include "debug.h"
53 
54 using std::cerr;
55 using std::endl;
56 
57 namespace libdap {
58 
59 // Explicit instantiation of the template member function 'value(T *)'.
60 // This is required in order to have the library contain these member
61 // function when its own code does not use them. Normally, C++ instantiates
62 // templates when they are used, and this forces that process so the
63 // library file contains the various versions of the member function.
64 //
65 // NB: I could not get this syntax to work in the header file. jhrg 8/19/13
66 template void D4Enum::value<dods_byte>(dods_byte *v) const;
67 template void D4Enum::value<dods_int16>(dods_int16 *v) const;
68 template void D4Enum::value<dods_uint16>(dods_uint16 *v) const;
69 template void D4Enum::value<dods_int32>(dods_int32 *v) const;
70 template void D4Enum::value<dods_uint32>(dods_uint32 *v) const;
71 template void D4Enum::value<dods_int64>(dods_int64 *v) const;
72 template void D4Enum::value<dods_uint64>(dods_uint64 *v) const;
73 
74 template void D4Enum::set_value<dods_byte>(dods_byte v);
75 template void D4Enum::set_value<dods_int16>(dods_int16 v);
76 template void D4Enum::set_value<dods_uint16>(dods_uint16 v);
77 template void D4Enum::set_value<dods_int32>(dods_int32 v);
78 template void D4Enum::set_value<dods_uint32>(dods_uint32 v);
79 template void D4Enum::set_value<dods_int64>(dods_int64 v);
80 template void D4Enum::set_value<dods_uint64>(dods_uint64 v);
81 
82 void
84  d_enum_def = enum_def;
85  d_element_type = enum_def->type();
86 }
87 
88 void
90 {
91  switch (d_element_type) {
92  case dods_byte_c:
93  case dods_uint8_c:
94  case dods_int8_c:
95  checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf.ui8), sizeof(uint8_t));
96  break;
97  case dods_uint16_c:
98  case dods_int16_c:
99  checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf.ui16), sizeof(uint16_t));
100  break;
101  case dods_uint32_c:
102  case dods_int32_c:
103  checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf.ui32), sizeof(uint32_t));
104  break;
105  case dods_uint64_c:
106  case dods_int64_c:
107  checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf.ui64), sizeof(uint64_t));
108  break;
109 
110  default:
111  assert(!"illegal type for D4Enum");
112  }
113 }
114 
115 
128 void
129 D4Enum::serialize(D4StreamMarshaller &m, DMR &, /*ConstraintEvaluator &,*/ bool)
130 {
131  if (!read_p())
132  read(); // read() throws Error
133 
134  switch (d_element_type) {
135  case dods_byte_c:
136  case dods_uint8_c:
137  m.put_byte(d_buf.ui8);
138  break;
139  case dods_uint16_c:
140  m.put_uint16(d_buf.ui16);
141  break;
142  case dods_uint32_c:
143  m.put_uint32(d_buf.ui32);
144  break;
145  case dods_uint64_c:
146  m.put_uint64(d_buf.ui64);
147  break;
148 
149  case dods_int8_c:
150  m.put_int8(d_buf.i8);
151  break;
152  case dods_int16_c:
153  m.put_int16(d_buf.i16);
154  break;
155  case dods_int32_c:
156  m.put_int32(d_buf.i32);
157  break;
158  case dods_int64_c:
159  m.put_int64(d_buf.i64);
160  break;
161  default:
162  assert(!"illegal type for D4Enum");
163  }
164 }
165 
166 void
168 {
169  switch (d_element_type) {
170  case dods_byte_c:
171  case dods_uint8_c:
172  um.get_byte(d_buf.ui8);
173  break;
174  case dods_uint16_c:
175  um.get_uint16(d_buf.ui16);
176  break;
177  case dods_uint32_c:
178  um.get_uint32(d_buf.ui32);
179  break;
180  case dods_uint64_c:
181  um.get_uint64(d_buf.ui64);
182  break;
183 
184  case dods_int8_c:
185  um.get_int8(d_buf.i8);
186  break;
187  case dods_int16_c:
188  um.get_int16(d_buf.i16);
189  break;
190  case dods_int32_c:
191  um.get_int32(d_buf.i32);
192  break;
193  case dods_int64_c:
194  um.get_int64(d_buf.i64);
195  break;
196  default:
197  assert(!"illegal type for D4Enum");
198  }
199 }
200 
201 unsigned int D4Enum::val2buf(void *val, bool)
202 {
203  if (!val)
204  throw InternalErr("The incoming pointer does not contain any data.");
205 
206  switch (d_element_type) {
207  case dods_byte_c:
208  case dods_uint8_c:
209  d_buf.ui8 = *(dods_byte*)val;
210  break;
211  case dods_uint16_c:
212  d_buf.ui16 = *(dods_uint16*)val;
213  break;
214  case dods_uint32_c:
215  d_buf.ui32 = *(dods_uint32*)val;
216  break;
217  case dods_uint64_c:
218  d_buf.ui64 = *(dods_uint64*)val;
219  break;
220 
221  case dods_int8_c:
222  d_buf.i8 = *(dods_int8*)val;
223  break;
224  case dods_int16_c:
225  d_buf.i16 = *(dods_int16*)val;
226  break;
227  case dods_int32_c:
228  d_buf.i32 = *(dods_int32*)val;
229  break;
230  case dods_int64_c:
231  d_buf.i64 = *(dods_int64*)val;
232  break;
233  default:
234  assert(!"illegal type for D4Enum");
235  }
236 
237  return width();
238 }
239 
240 unsigned int D4Enum::buf2val(void **val)
241 {
242  if (!val)
243  throw InternalErr("NULL pointer");
244 
245  switch (d_element_type) {
246  case dods_byte_c:
247  case dods_uint8_c:
248  if (!*val) *val = new dods_byte;
249  *(dods_byte *) * val = d_buf.ui8;
250  break;
251  case dods_uint16_c:
252  if (!*val) *val = new dods_uint16;
253  *(dods_uint16 *) * val = d_buf.ui16;
254  break;
255  case dods_uint32_c:
256  if (!*val) *val = new dods_uint32;
257  *(dods_uint32 *) * val = d_buf.ui32;
258  break;
259  case dods_uint64_c:
260  if (!*val) *val = new dods_uint64;
261  *(dods_uint64 *) * val = d_buf.ui64;
262  break;
263 
264  case dods_int8_c:
265  if (!*val) *val = new dods_int8;
266  *(dods_int8*) * val = d_buf.i8;
267  break;
268  case dods_int16_c:
269  if (!*val) *val = new dods_int16;
270  *(dods_int16 *) * val = d_buf.i16;
271  break;
272  case dods_int32_c:
273  if (!*val) *val = new dods_int32;
274  *(dods_int32 *) * val = d_buf.i32;
275  break;
276  case dods_int64_c:
277  if (!*val) *val = new dods_int64;
278  *(dods_int64 *) * val = d_buf.i64;
279  break;
280  default:
281  assert(!"illegal type for D4Enum");
282  }
283 
284  return width();
285 }
286 
287 void D4Enum::print_val(ostream &out, string space, bool print_decl_p)
288 {
289  if (print_decl_p) {
290  print_decl(out, space, false);
291  out << " = ";
292  }
293 
294  if (is_signed()) {
295  int64_t v;
296  value(&v);
297  out << v;
298  }
299  else {
300  uint64_t v;
301  value(&v);
302  out << v;
303  }
304 
305  if (print_decl_p)
306  out << ";" << endl;
307 }
308 
315 void
316 D4Enum::print_xml_writer(XMLWriter &xml, bool constrained)
317 {
318  if (constrained && !send_p())
319  return;
320 
321  if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)"Enum") < 0)
322  throw InternalErr(__FILE__, __LINE__, "Could not write Enum element");
323 
324  if (!name().empty())
325  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)name().c_str()) < 0)
326  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
327 
328 
329  string path = d_enum_def->name();
330  // Not every D4EnumDef is a member of an instance of D4EnumDefs - the D4EnumDefs instance
331  // holds a reference to the D4Group that holds the Enum definitions.
332  // TODO Should this be changed - so the EnumDef holds a reference to its parent Group?
333  if (d_enum_def->parent()) {
334  // print the FQN for the enum def; D4Group::FQN() includes the trailing '/'
335  path = static_cast<D4Group*>(d_enum_def->parent()->parent())->FQN() + path;
336  }
337  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "enum", (const xmlChar*)path.c_str()) < 0)
338  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for enum");
339 
340  attributes()->print_dap4(xml);
341 
342  if (get_attr_table().get_size() > 0)
344 
345  if (xmlTextWriterEndElement(xml.get_writer()) < 0)
346  throw InternalErr(__FILE__, __LINE__, "Could not end Enum element");
347 }
348 
349 
350 bool
352 {
353  // Get the arg's value.
354  if (!read_p() && !read())
355  throw InternalErr(__FILE__, __LINE__, "This value not read!");
356 
357  // Get the second arg's value.
358  if (!b->read_p() && !b->read())
359  throw InternalErr(__FILE__, __LINE__, "This value not read!");
360 
361  switch (b->type()) {
362  case dods_int8_c:
363  return Cmp<dods_int64, dods_int8>(op, d_buf, static_cast<Int8*>(b)->value());
364  case dods_byte_c:
365  return SUCmp<dods_int64, dods_byte>(op, d_buf, static_cast<Byte*>(b)->value());
366  case dods_int16_c:
367  return Cmp<dods_int64, dods_int16>(op, d_buf, static_cast<Int16*>(b)->value());
368  case dods_uint16_c:
369  return SUCmp<dods_int64, dods_uint16>(op, d_buf, static_cast<UInt16*>(b)->value());
370  case dods_int32_c:
371  return Cmp<dods_int64, dods_int32>(op, d_buf, static_cast<Int32*>(b)->value());
372  case dods_uint32_c:
373  return SUCmp<dods_int64, dods_uint32>(op, d_buf, static_cast<UInt32*>(b)->value());
374 #if 0
375  // FIXME
376  case dods_int64_c:
377  return Cmp<dods_int64, dods_int64>(op, d_buf, static_cast<D4Enum*>(b)->value());
378  case dods_uint64_c:
379  return SUCmp<dods_int64, dods_uint64>(op, d_buf, static_cast<D4Enum*>(b)->value());
380 #endif
381  case dods_float32_c:
382  return Cmp<dods_int64, dods_float32>(op, d_buf, static_cast<Float32*>(b)->value());
383  case dods_float64_c:
384  return Cmp<dods_int64, dods_float64>(op, d_buf, static_cast<Float64*>(b)->value());
385  default:
386  return false;
387  }
388 
389  return false;
390 }
391 
400 void
401 D4Enum::dump(ostream &strm) const
402 {
403  strm << DapIndent::LMarg << "D4Enum::dump - ("
404  << (void *)this << ")" << endl ;
406  BaseType::dump(strm) ;
407  strm << DapIndent::LMarg << "value: " << d_buf.ui64 << endl ;
409 }
410 
411 } // namespace libdap
412 
virtual bool read()
Read data into a local buffer.
Definition: BaseType.cc:805
Holds an 8-bit signed integer value.
Definition: Int8.h:42
virtual void set_enumeration(D4EnumDef *enum_def)
Definition: D4Enum.cc:83
virtual bool read_p()
Has this variable been read?
Definition: BaseType.cc:421
static void UnIndent()
Definition: DapIndent.cc:51
virtual void print_decl(FILE *out, string space=" ", bool print_semi=true, bool constraint_info=false, bool constrained=false)
Print an ASCII representation of the variable structure.
Definition: BaseType.cc:905
DINT32 dods_int32
xmlTextWriterPtr get_writer()
Definition: XMLWriter.h:56
virtual void put_int16(dods_int16 val)
uint8_t dods_byte
int64_t dods_int64
Type type() const
Definition: D4EnumDefs.h:67
D4EnumDefs * parent() const
Definition: D4EnumDefs.h:70
DUINT32 dods_uint32
unsigned int val2buf(void *, bool)
Loads class data.
Definition: D4Enum.cc:201
virtual void get_int32(dods_int32 &val)
virtual void get_uint64(dods_uint64 &val)
virtual void get_int8(dods_int8 &val)
virtual void get_byte(dods_byte &val)
bool is_signed() const
Definition: D4Enum.h:172
Read data from the stream made by D4StreamMarshaller.
virtual void get_int64(dods_int64 &val)
Holds an unsigned 16-bit integer.
Definition: UInt16.h:57
Definition: crc.h:76
DINT64 dods_int64
virtual void put_byte(dods_byte val)
void print_xml_writer(XMLWriter &xml)
Definition: AttrTable.cc:1424
virtual void print_val(ostream &out, string space="", bool print_decl_p=true)
Prints the value of the variable.
Definition: D4Enum.cc:287
Type type() const
Returns the type of the class instance.
Definition: BaseType.cc:306
Holds a 32-bit floating point value.
Definition: Float32.h:61
uint16_t dods_uint16
virtual void put_uint16(dods_uint16 val)
uint64_t dods_uint64
A class for software fault reporting.
Definition: InternalErr.h:64
DUINT64 dods_uint64
Holds a DAP4 enumeration.
Definition: D4Enum.h:55
virtual void serialize(D4StreamMarshaller &m, DMR &dmr, bool filter=false)
Serialize a D4Enum Use the (integer) data type associated with an Enumeration definition to serialize...
Definition: D4Enum.cc:129
Marshaller that knows how to marshal/serialize dap data objects to a C++ iostream using DAP4's receiv...
Holds a 16-bit signed integer value.
Definition: Int16.h:59
virtual void get_uint16(dods_uint16 &val)
static void Indent()
Definition: DapIndent.cc:45
D4Group * parent() const
Definition: D4EnumDefs.h:129
virtual void dump(ostream &strm) const
dumps information about this object
Definition: BaseType.cc:237
uint32_t dods_uint32
virtual void compute_checksum(Crc32 &checksum)
include the data for this variable in the checksum DAP4 includes a checksum with every data response...
Definition: D4Enum.cc:89
virtual D4Attributes * attributes()
Definition: BaseType.cc:529
virtual void put_uint32(dods_uint32 val)
virtual std::string FQN() const
Definition: BaseType.cc:273
virtual void put_int8(dods_int8 val)
void AddData(const uint8_t *pData, const uint32_t length)
Definition: crc.h:84
string name() const
Returns the name of the class instance.
Definition: BaseType.cc:261
virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr)
Definition: D4Enum.cc:167
virtual void get_int16(dods_int16 &val)
static ostream & LMarg(ostream &strm)
Definition: DapIndent.cc:80
virtual void print_xml_writer(XMLWriter &xml, bool constrained)
Definition: D4Enum.cc:316
virtual AttrTable & get_attr_table()
Definition: BaseType.cc:512
virtual void put_uint64(dods_uint64 val)
int16_t dods_int16
virtual void get_uint32(dods_uint32 &val)
The basic data type for the DODS DAP types.
Definition: BaseType.h:117
virtual unsigned int width(bool=false) const
Return the number of bytes in an instance of an Enum. This returns the number of bytes an instance of...
Definition: D4Enum.h:259
DUINT16 dods_uint16
Holds a 64-bit (double precision) floating point value.
Definition: Float64.h:60
Holds a single byte.
Definition: Byte.h:60
void value(T *v) const
Copy the value of this Enum into v. Template member function that can be used to read the value of th...
Definition: D4Enum.h:206
DBYTE dods_byte
virtual bool ops(BaseType *b, int op)
Evaluate relational operators.
Definition: D4Enum.cc:351
string name() const
Definition: D4EnumDefs.h:64
Holds a 32-bit unsigned integer.
Definition: UInt32.h:59
virtual void put_int32(dods_int32 val)
DINT16 dods_int16
virtual bool send_p()
Should this variable be sent?
Definition: BaseType.cc:484
unsigned int buf2val(void **)
Reads the class data.
Definition: D4Enum.cc:240
virtual void put_int64(dods_int64 val)
virtual void dump(ostream &strm) const
dumps information about this object
Definition: D4Enum.cc:401
void print_dap4(XMLWriter &xml) const
Holds a 32-bit signed integer.
Definition: Int32.h:65
int32_t dods_int32