|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// -*- mode: c++; c-basic-offset:4 -*-
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// This file is part of libdap, A C++ implementation of the OPeNDAP Data
|
|
Packit |
a4aae4 |
// Access Protocol.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Copyright (c) 2013 OPeNDAP, Inc.
|
|
Packit |
a4aae4 |
// Author: James Gallagher <jgallagher@opendap.org>
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is free software; you can redistribute it and/or
|
|
Packit |
a4aae4 |
// modify it under the terms of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License as published by the Free Software Foundation; either
|
|
Packit |
a4aae4 |
// version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is distributed in the hope that it will be useful,
|
|
Packit |
a4aae4 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
a4aae4 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
a4aae4 |
// Lesser General Public License for more details.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You should have received a copy of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License along with this library; if not, write to the Free Software
|
|
Packit |
a4aae4 |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#ifndef _D4Enum_h
|
|
Packit |
a4aae4 |
#define _D4Enum_h 1
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <cassert>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "BaseType.h"
|
|
Packit |
a4aae4 |
#include "dods-datatypes.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#if 0
|
|
Packit |
a4aae4 |
#include "InternalErr.h"
|
|
Packit |
a4aae4 |
#include "dods-datatypes.h"
|
|
Packit |
a4aae4 |
#include "dods-limits.h"
|
|
Packit |
a4aae4 |
#include "util.h"
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
namespace libdap
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
class D4EnumDef;
|
|
Packit |
a4aae4 |
class ConstraintEvaluator;
|
|
Packit |
a4aae4 |
class Marshaller;
|
|
Packit |
a4aae4 |
class UnMarshaller;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief Holds a DAP4 enumeration.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @note When constructed a type for the Enum must be specified. If
|
|
Packit |
a4aae4 |
* it is not an integer type, the Enum will use unsigned int 64. This
|
|
Packit |
a4aae4 |
* is not the same as the enumeration type that is defined using the
|
|
Packit |
a4aae4 |
* Enumeration XML element in the DMR - that information is stored
|
|
Packit |
a4aae4 |
* in additional fields and used for checking values and printing the
|
|
Packit |
a4aae4 |
* variable's declaration, but not for the internal storage of values.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @todo Note the hack to remove the union...
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
class D4Enum: public BaseType
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
friend class D4EnumTest;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
protected:
|
|
Packit |
a4aae4 |
// Use an unsigned 64-bit int. the value() and set_value()
|
|
Packit |
a4aae4 |
// accessors cast to other types as needed, including signed ones.
|
|
Packit |
a4aae4 |
uint64_t d_buf;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
private:
|
|
Packit |
a4aae4 |
Type d_element_type;
|
|
Packit |
a4aae4 |
D4EnumDef *d_enum_def; // This is a weak pointer; don't delete
|
|
Packit |
a4aae4 |
bool d_is_signed;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void m_duplicate(const D4Enum &src;;
|
|
Packit |
a4aae4 |
void m_check_value(int64_t v) const;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
unsigned int m_type_width() const {
|
|
Packit |
a4aae4 |
switch(d_element_type) {
|
|
Packit |
a4aae4 |
case dods_byte_c:
|
|
Packit |
a4aae4 |
case dods_int8_c:
|
|
Packit |
a4aae4 |
case dods_uint8_c:
|
|
Packit |
a4aae4 |
return 1;
|
|
Packit |
a4aae4 |
case dods_int16_c:
|
|
Packit |
a4aae4 |
case dods_uint16_c:
|
|
Packit |
a4aae4 |
return 2;
|
|
Packit |
a4aae4 |
case dods_int32_c:
|
|
Packit |
a4aae4 |
case dods_uint32_c:
|
|
Packit |
a4aae4 |
return 4;
|
|
Packit |
a4aae4 |
case dods_int64_c:
|
|
Packit |
a4aae4 |
case dods_uint64_c:
|
|
Packit |
a4aae4 |
return 8;
|
|
Packit |
a4aae4 |
case dods_null_c:
|
|
Packit |
a4aae4 |
default:
|
|
Packit |
a4aae4 |
assert(!"illegal type for D4Enum");
|
|
Packit |
a4aae4 |
return 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Enum(); // No empty constructor
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
public:
|
|
Packit |
a4aae4 |
D4Enum(const string &name, const string &enum_type);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Enum(const string &name, Type type);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Enum(const string &name, const string &dataset, Type type);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Enum(const D4Enum &src) : BaseType(src) { m_duplicate(src); }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Enum &operator=(const D4Enum &rhs) {
|
|
Packit |
a4aae4 |
if (this == &rhs)
|
|
Packit |
a4aae4 |
return *this;
|
|
Packit |
a4aae4 |
static_cast<BaseType &>(*this) = rhs;
|
|
Packit |
a4aae4 |
m_duplicate(rhs);
|
|
Packit |
a4aae4 |
return *this;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual ~D4Enum() { }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual D4EnumDef *enumeration() const { return d_enum_def; }
|
|
Packit |
a4aae4 |
virtual void set_enumeration(D4EnumDef *enum_def);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual BaseType *ptr_duplicate() { return new D4Enum(*this); }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Type element_type() { return d_element_type; }
|
|
Packit |
a4aae4 |
void set_element_type(Type type) { d_element_type = type; }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
bool is_signed() const { return d_is_signed; }
|
|
Packit |
a4aae4 |
void set_is_signed(Type t);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief Get the value of an Enum
|
|
Packit |
a4aae4 |
* Get the value of this instance. The caller is responsible
|
|
Packit |
a4aae4 |
* for using a type T than can hold the value.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @param v Value-result parameter; return the value of the Enum
|
|
Packit |
a4aae4 |
* in this variable.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
template<typename T> void value(T *v) const {
|
|
Packit |
a4aae4 |
*v = static_cast<T>(d_buf);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief Set the value of the Enum
|
|
Packit |
a4aae4 |
* Template member function to set the value of the Enum. The libdap library
|
|
Packit |
a4aae4 |
* contains versions of this member function for dods_byte, ..., dods_uint64
|
|
Packit |
a4aae4 |
* types for the parameter \c v.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @param v Set the Enum to this value.
|
|
Packit |
a4aae4 |
* @param check_value If true test the value 'v' against the type of the
|
|
Packit |
a4aae4 |
* Enum. Defaults to true.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
template <typename T> void set_value(T v, bool check_value = true)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (check_value) m_check_value(v);
|
|
Packit |
a4aae4 |
d_buf = static_cast<int64_t>(v);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief Return the number of bytes in an instance of an Enum.
|
|
Packit |
a4aae4 |
* This returns the number of bytes an instance of Enum will use
|
|
Packit |
a4aae4 |
* in memory or on the wire (i.e., in a serialization of
|
|
Packit |
a4aae4 |
* the type). On the wire this type uses the minimum number of
|
|
Packit |
a4aae4 |
* bytes for the given Enum type - an Enum with type Byte uses
|
|
Packit |
a4aae4 |
* one byte, Int16 uses two, and so on. In memory, a single instance
|
|
Packit |
a4aae4 |
* uses 64-bits but a vector of these will use the same number of
|
|
Packit |
a4aae4 |
* bytes per value as the on-the-wire representation.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @note The private method m_type_width() returns the byte width
|
|
Packit |
a4aae4 |
* used for the on-the-wire representation of values.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @return The number of bytes used by a value.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
virtual unsigned int width(bool /* constrained */ = false) const { return /*sizeof(int64_t);*/ m_type_width();}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// DAP4
|
|
Packit |
a4aae4 |
virtual void compute_checksum(Crc32 &checksum);
|
|
Packit |
a4aae4 |
virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
|
|
Packit |
a4aae4 |
virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void print_val(ostream &out, string space = "", bool print_decl_p = true);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void print_xml_writer(XMLWriter &xml, bool constrained);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual bool ops(BaseType *b, int op);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void dump(ostream &strm) const;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
unsigned int val2buf(void *, bool);
|
|
Packit |
a4aae4 |
unsigned int buf2val(void **);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual std::vector<BaseType *> *transform_to_dap2(AttrTable *parent_attr_table);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
};
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
} // namespace libdap
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#endif // _D4Enum_h
|
|
Packit |
a4aae4 |
|