|
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) 2002,2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// (c) COPYRIGHT URI/MIT 1996,1998,1999
|
|
Packit |
a4aae4 |
// Please first read the full copyright statement in the file COPYRIGHT_URI.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// Authors:
|
|
Packit |
a4aae4 |
// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Implementation for the CE Clause class.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "config.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "D4RValue.h"
|
|
Packit |
a4aae4 |
#include "D4FilterClause.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
using namespace std;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
namespace libdap {
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4FilterClauseList::m_duplicate(const D4FilterClauseList &src)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
//D4FilterClauseList &non_c_src = const_cast<D4FilterClauseList &>(src);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
for (D4FilterClauseList::citer i = src.cbegin(), e = src.cend(); i != e; ++i) {
|
|
Packit |
a4aae4 |
D4FilterClause *fc = *i;
|
|
Packit |
a4aae4 |
d_clauses.push_back(new D4FilterClause(*fc));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4FilterClauseList::~D4FilterClauseList()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
for (D4FilterClauseList::iter i = d_clauses.begin(), e = d_clauses.end(); i != e; ++i) {
|
|
Packit |
a4aae4 |
delete *i;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief Evaluate the list of clauses
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* Evaluate the list of clauses and return false when/if one is found to be false.
|
|
Packit |
a4aae4 |
* This evaluates the clauses in the order they are stored and stops evaluation a
|
|
Packit |
a4aae4 |
* the first false clause.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @param dmr Use this DMR when evaluating clauses - for clauses that contain functions,
|
|
Packit |
a4aae4 |
* not currently in the DAP4 specification.
|
|
Packit |
a4aae4 |
* @return True if each of the clauses' value is true, otherwise false
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
bool
|
|
Packit |
a4aae4 |
D4FilterClauseList::value(DMR &dmr)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
for (D4FilterClauseList::iter i = d_clauses.begin(), e = d_clauses.end(); i != e; ++i) {
|
|
Packit |
a4aae4 |
if ((*i)->value(dmr) == false)
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return true;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief Evaluate the list of clauses
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* This version of value() does not need a DMR parameter (but will not work
|
|
Packit |
a4aae4 |
* if the clauses contain a function call (which is not currently supported
|
|
Packit |
a4aae4 |
* by the spec).
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @return True if each clauses' value is true, false otherwise
|
|
Packit |
a4aae4 |
* @see D4FilterClauseList::value(DMR &dmr)
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
bool
|
|
Packit |
a4aae4 |
D4FilterClauseList::value()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
for (D4FilterClauseList::iter i = d_clauses.begin(), e = d_clauses.end(); i != e; ++i) {
|
|
Packit |
a4aae4 |
if ((*i)->value() == false)
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return true;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void D4FilterClause::m_duplicate(const D4FilterClause &rhs) {
|
|
Packit |
a4aae4 |
d_op = rhs.d_op;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
d_arg1 = new D4RValue(*rhs.d_arg1);
|
|
Packit |
a4aae4 |
d_arg2 = new D4RValue(*rhs.d_arg2);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#if 0
|
|
Packit |
a4aae4 |
// Copy the D4RValue pointer if the 'value_kind' is a basetype,
|
|
Packit |
a4aae4 |
// but build a new D4RValue if it is a constant (because the
|
|
Packit |
a4aae4 |
// basetype is a weak pointer.
|
|
Packit |
a4aae4 |
switch (rhs.d_arg1->get_kind()) {
|
|
Packit |
a4aae4 |
case D4RValue::basetype:
|
|
Packit |
a4aae4 |
d_arg1 = rhs.d_arg1;
|
|
Packit |
a4aae4 |
break;
|
|
Packit |
a4aae4 |
case D4RValue::constant:
|
|
Packit |
a4aae4 |
d_arg1 = new D4RValue(*(rhs.d_arg1));
|
|
Packit |
a4aae4 |
break;
|
|
Packit |
a4aae4 |
default:
|
|
Packit |
a4aae4 |
throw Error(malformed_expr, "found a filter clause with a function call.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
switch (rhs.d_arg2->get_kind()) {
|
|
Packit |
a4aae4 |
case D4RValue::basetype:
|
|
Packit |
a4aae4 |
d_arg2 = rhs.d_arg2;
|
|
Packit |
a4aae4 |
break;
|
|
Packit |
a4aae4 |
case D4RValue::constant:
|
|
Packit |
a4aae4 |
d_arg2 = new D4RValue(*(rhs.d_arg2));
|
|
Packit |
a4aae4 |
break;
|
|
Packit |
a4aae4 |
default:
|
|
Packit |
a4aae4 |
throw Error(malformed_expr, "found a filter clause with a function call.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief Get the value of this relational expression.
|
|
Packit |
a4aae4 |
* This version of value() works for function clauses, although that's
|
|
Packit |
a4aae4 |
* not supported by the syntax at this time.
|
|
Packit |
a4aae4 |
* @param dmr The DMR to use when evaluating a function
|
|
Packit |
a4aae4 |
* @return True if the clause is true, false otherwise.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
bool D4FilterClause::value(DMR &dmr)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
switch (d_op) {
|
|
Packit |
a4aae4 |
case null:
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "While evaluating a constraint filter clause: Found a null operator");
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
case less:
|
|
Packit |
a4aae4 |
case greater:
|
|
Packit |
a4aae4 |
case less_equal:
|
|
Packit |
a4aae4 |
case greater_equal:
|
|
Packit |
a4aae4 |
case equal:
|
|
Packit |
a4aae4 |
case not_equal:
|
|
Packit |
a4aae4 |
case match:
|
|
Packit |
a4aae4 |
return cmp(d_op, d_arg1->value(dmr), d_arg2->value(dmr));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
case ND:
|
|
Packit |
a4aae4 |
case map:
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "While evaluating a constraint filter clause: Filter operator not implemented");
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
default:
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "While evaluating a constraint filter clause: Unrecognized operator");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief Get the value of this relational expression.
|
|
Packit |
a4aae4 |
* This version of value() will not work for clauses where one of the
|
|
Packit |
a4aae4 |
* rvalues is a function call. This is not currently supported by the
|
|
Packit |
a4aae4 |
* DAP4 specification, so it's probably no great loss.
|
|
Packit |
a4aae4 |
* @return True if the clause is true, false otherwise.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
bool D4FilterClause::value()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
switch (d_op) {
|
|
Packit |
a4aae4 |
case null:
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "While evaluating a constraint filter clause: Found a null operator");
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
case less:
|
|
Packit |
a4aae4 |
case greater:
|
|
Packit |
a4aae4 |
case less_equal:
|
|
Packit |
a4aae4 |
case greater_equal:
|
|
Packit |
a4aae4 |
case equal:
|
|
Packit |
a4aae4 |
case not_equal:
|
|
Packit |
a4aae4 |
case match:
|
|
Packit |
a4aae4 |
return cmp(d_op, d_arg1->value(), d_arg2->value());
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
case ND:
|
|
Packit |
a4aae4 |
case map:
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "While evaluating a constraint filter clause: Filter operator not implemented");
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
default:
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "While evaluating a constraint filter clause: Unrecognized operator");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// It may be better to use the code in the Byte, ..., classes that was
|
|
Packit |
a4aae4 |
// impl'd for DAP2 (with extensions). For now, test this and build the
|
|
Packit |
a4aae4 |
// rest of the filter implementation. But there is certainly a more _compact_
|
|
Packit |
a4aae4 |
// way to code this!
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// Optimize the extraction of constant values.
|
|
Packit |
a4aae4 |
bool D4FilterClause::cmp(ops op, BaseType *arg1, BaseType *arg2)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
return arg1->d4_ops(arg2, op);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
} // namespace libdap
|