D4RValue.cc
// -*- mode: c++; c-basic-offset:4 -*-
// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.
// Copyright (c) 2014 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
#include "config.h"
#include <iostream>
#include "Array.h"
#include "BaseType.h"
#include "Byte.h"
#include "Float32.h"
#include "Float64.h"
#include "Int16.h"
#include "Int32.h"
#include "Int64.h"
#include "Int8.h"
#include "Str.h"
#include "UInt16.h"
#include "UInt32.h"
#include "UInt64.h"
#include "D4RValue.h"
#include "InternalErr.h"
#include "dods-datatypes.h"
#include "dods-limits.h"
#include "parser-util.h"
#include "util.h"
using namespace std;
namespace libdap {
void D4RValueList::m_duplicate(const D4RValueList &src) {
for (std::vector<D4RValue *>::const_iterator i = src.d_rvalues.begin(), e = src.d_rvalues.end(); i != e; ++i) {
D4RValue *rv = *i;
d_rvalues.push_back(new D4RValue(*rv));
}
}
D4RValueList::~D4RValueList() {
for (std::vector<D4RValue *>::iterator i = d_rvalues.begin(), e = d_rvalues.end(); i != e; ++i)
delete *i;
}
void D4RValue::m_duplicate(const D4RValue &src) {
d_value_kind = src.d_value_kind;
d_variable = src.d_variable; // weak pointers
d_func = src.d_func;
d_args = (src.d_args != 0) ? new D4RValueList(*src.d_args) : 0; // deep copy these
d_constant = (src.d_constant != 0) ? src.d_constant->ptr_duplicate() : 0;
}
template <typename T, class DAP_TYPE> static BaseType *build_constant_array(vector<T> &values, DAP_TYPE &dt) {
Array *array = new Array("", &dt);
array->append_dim(values.size());
// TODO Make set_value_nocopy() methods so that values' pointers can be copied
// instead of allocating memory twice. jhrg 7/5/13
array->set_value(values, values.size());
array->set_read_p(true);
static unsigned long counter = 1;
array->set_name(string("g") + long_to_string(counter++));
return array;
}
D4RValue::D4RValue(unsigned long long ull)
: d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant) {
UInt64 *ui = new UInt64("constant");
ui->set_value(ull);
d_constant = ui;
}
D4RValue::D4RValue(long long ll) : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant) {
Int64 *i = new Int64("constant");
i->set_value(ll);
d_constant = i;
}
D4RValue::D4RValue(double r) : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant) {
Float64 *f = new Float64("constant");
f->set_value(r);
d_constant = f;
}
D4RValue::D4RValue(std::string cpps) : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant) {
Str *s = new Str("constant");
s->set_value(remove_quotes(cpps));
d_constant = s;
}
D4RValue::D4RValue(std::vector<dods_byte> &byte_args)
: d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant) {
Byte b("");
d_constant = build_constant_array(byte_args, b);
}
D4RValue::D4RValue(std::vector<dods_int8> &byte_int8)
: d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant) {
Int8 b("");
d_constant = build_constant_array(byte_int8, b);
}
D4RValue::D4RValue(std::vector<dods_uint16> &byte_uint16)
: d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant) {
UInt16 b("");
d_constant = build_constant_array(byte_uint16, b);
}
D4RValue::D4RValue(std::vector<dods_int16> &byte_int16)
: d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant) {
Int16 b("");
d_constant = build_constant_array(byte_int16, b);
}
D4RValue::D4RValue(std::vector<dods_uint32> &byte_uint32)
: d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant) {
UInt32 b("");
d_constant = build_constant_array(byte_uint32, b);
}
D4RValue::D4RValue(std::vector<dods_int32> &byte_int32)
: d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant) {
Int32 b("");
d_constant = build_constant_array(byte_int32, b);
}
D4RValue::D4RValue(std::vector<dods_uint64> &byte_uint64)
: d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant) {
UInt64 b("");
d_constant = build_constant_array(byte_uint64, b);
}
D4RValue::D4RValue(std::vector<dods_int64> &byte_int64)
: d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant) {
Int64 b("");
d_constant = build_constant_array(byte_int64, b);
}
D4RValue::D4RValue(std::vector<dods_float32> &byte_float32)
: d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant) {
Float32 b("");
d_constant = build_constant_array(byte_float32, b);
}
D4RValue::D4RValue(std::vector<dods_float64> &byte_float64)
: d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant) {
Float64 b("");
d_constant = build_constant_array(byte_float64, b);
}
D4RValue::~D4RValue() {
// d_variable and d_func are weak pointers; don't delete.
delete d_args;
delete d_constant;
}
D4RValue *D4RValueFactory(std::string cpps) {
char *ptr;
// First check if the string is a uint64, ..., then convert it.
// Since the check_* function use the strtoull() functions, no
// need to test for errors when building the actual values.
if (check_uint64(cpps.c_str())) {
return new D4RValue(strtoull(cpps.c_str(), &ptr, 0));
} else if (check_int64(cpps.c_str())) {
return new D4RValue(strtoll(cpps.c_str(), &ptr, 0));
} else if (check_float64(cpps.c_str())) {
#ifdef WIN32
return new D4RValue(w32strtod(cpps.c_str(), &ptr));
#else
return new D4RValue(strtod(cpps.c_str(), &ptr));
#endif
} else {
return new D4RValue(cpps);
}
}
BaseType *D4RValue::value(DMR &dmr) {
switch (d_value_kind) {
case basetype:
d_variable->read();
d_variable->set_read_p(true);
return d_variable;
case function:
return (*d_func)(d_args, dmr);
case constant:
return d_constant;
default:
throw InternalErr(__FILE__, __LINE__, "Unknown rvalue type.");
}
}
BaseType *D4RValue::value() {
switch (d_value_kind) {
case basetype:
d_variable->read();
d_variable->set_read_p(true);
return d_variable;
case function:
throw Error(malformed_expr,
"An expression that included a function call was used in a place where that won't work.");
case constant:
return d_constant;
default:
throw InternalErr(__FILE__, __LINE__, "Unknown rvalue type.");
}
}
} // namespace libdap
libdap::BaseType
The basic data type for the DODS DAP types.
Definition BaseType.h:118
libdap::BaseType::read
virtual bool read()
Read data into a local buffer.
Definition BaseType.cc:775
libdap::BaseType::ptr_duplicate
virtual BaseType * ptr_duplicate()=0
libdap::D4RValue
Definition D4RValue.h:79
libdap::DMR
Definition DMR.h:56
libdap::Error
A class for error processing.
Definition Error.h:92
libdap::InternalErr
A class for software fault reporting.
Definition InternalErr.h:61
libdap
top level DAP object to house generic methods
Definition AlarmHandler.h:35
libdap::remove_quotes
string remove_quotes(const string &s)
Definition util.cc:562
libdap::D4RValueFactory
D4RValue * D4RValueFactory(std::string cpps)
Build an appropriate RValue.
Definition D4RValue.cc:197