|
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 1995-1999
|
|
Packit |
a4aae4 |
// Please 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 |
|
|
Packit |
a4aae4 |
#include "config.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
//#define DODS_DEBUG
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <string>
|
|
Packit |
a4aae4 |
#include <sstream>
|
|
Packit |
a4aae4 |
#include <algorithm>
|
|
Packit |
a4aae4 |
#include <functional>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <stdint.h>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "crc.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "Constructor.h"
|
|
Packit |
a4aae4 |
#include "Grid.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "DMR.h"
|
|
Packit |
a4aae4 |
#include "XMLWriter.h"
|
|
Packit |
a4aae4 |
#include "D4StreamMarshaller.h"
|
|
Packit |
a4aae4 |
#include "D4StreamUnMarshaller.h"
|
|
Packit |
a4aae4 |
#include "D4Group.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "D4Attributes.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "escaping.h"
|
|
Packit |
a4aae4 |
#include "util.h"
|
|
Packit |
a4aae4 |
#include "Error.h"
|
|
Packit |
a4aae4 |
#include "InternalErr.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// #define DODS_DEBUG 1
|
|
Packit |
a4aae4 |
#include "debug.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
using namespace std;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
namespace libdap {
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Private member functions
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::m_duplicate(const Constructor &c)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBG(cerr << "In Constructor::m_duplicate for " << c.name() << endl);
|
|
Packit |
a4aae4 |
// Clear out any spurious vars in Constructor::d_vars
|
|
Packit |
a4aae4 |
// Moved from Grid::m_duplicate. jhrg 4/3/13
|
|
Packit |
a4aae4 |
d_vars.clear(); // [mjohnson 10 Sep 2009]
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Vars_citer i = c.d_vars.begin();
|
|
Packit |
a4aae4 |
while (i != c.d_vars.end()) {
|
|
Packit |
a4aae4 |
BaseType *btp = (*i++)->ptr_duplicate();
|
|
Packit |
a4aae4 |
btp->set_parent(this);
|
|
Packit |
a4aae4 |
d_vars.push_back(btp);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
DBG(cerr << "Exiting Constructor::m_duplicate for " << c.name() << endl);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Public member functions
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Constructor::Constructor(const string &name, const Type &type, bool is_dap4)
|
|
Packit |
a4aae4 |
: BaseType(name, type, is_dap4)
|
|
Packit |
a4aae4 |
{}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Server-side constructor that takes the name of the variable to be
|
|
Packit |
a4aae4 |
* created, the dataset name from which this variable is being created, and
|
|
Packit |
a4aae4 |
* the type of data being stored in the Constructor. This is a protected
|
|
Packit |
a4aae4 |
* constructor, available only to derived classes of Constructor
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @param name string containing the name of the variable to be created
|
|
Packit |
a4aae4 |
* @param dataset string containing the name of the dataset from which this
|
|
Packit |
a4aae4 |
* variable is being created
|
|
Packit |
a4aae4 |
* @param type type of data being stored
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
Constructor::Constructor(const string &name, const string &dataset, const Type &type, bool is_dap4)
|
|
Packit |
a4aae4 |
: BaseType(name, dataset, type, is_dap4)
|
|
Packit |
a4aae4 |
{}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Constructor::Constructor(const Constructor &rhs) : BaseType(rhs), d_vars(0)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBG(cerr << "In Constructor::copy_ctor for " << rhs.name() << endl);
|
|
Packit |
a4aae4 |
m_duplicate(rhs);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Constructor::~Constructor()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
Vars_iter i = d_vars.begin();
|
|
Packit |
a4aae4 |
while (i != d_vars.end()) {
|
|
Packit |
a4aae4 |
delete *i++;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Constructor &
|
|
Packit |
a4aae4 |
Constructor::operator=(const Constructor &rhs)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBG(cerr << "Entering Constructor::operator=" << endl);
|
|
Packit |
a4aae4 |
if (this == &rhs)
|
|
Packit |
a4aae4 |
return *this;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
dynamic_cast<BaseType &>(*this) = rhs; // run BaseType=
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
m_duplicate(rhs);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
DBG(cerr << "Exiting Constructor::operator=" << endl);
|
|
Packit |
a4aae4 |
return *this;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// A public method, but just barely...
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::transform_to_dap4(D4Group *root, Constructor *dest)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBG(cerr << __func__ << "() - BEGIN (name:"<< name() <<
|
|
Packit |
a4aae4 |
")(type:"<< type_name()<<
|
|
Packit |
a4aae4 |
")(root:'"<< root->name()<<"':"<<(void*)root <<
|
|
Packit |
a4aae4 |
")(dest:'"<< dest->name()<<"':"<< (void *) dest<< ")"
|
|
Packit |
a4aae4 |
<< endl;);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
for (Constructor::Vars_citer i = var_begin(), e = var_end(); i != e; ++i) {
|
|
Packit |
a4aae4 |
BaseType *d4_var = dest->var((*i)->name());
|
|
Packit |
a4aae4 |
// Don't add duplicate variables. We have to make this check
|
|
Packit |
a4aae4 |
// because some of the child variables may add arrays
|
|
Packit |
a4aae4 |
// to the root object. For example, this happens in
|
|
Packit |
a4aae4 |
// Grid with the Map Arrays - ndp - 05/08/17
|
|
Packit |
a4aae4 |
if(!d4_var){
|
|
Packit |
a4aae4 |
/*
|
|
Packit |
a4aae4 |
BaseType *new_var = (*i)->transform_to_dap4(root, dest);
|
|
Packit |
a4aae4 |
if (new_var) { // Might be a Grid; see the comment in BaseType::transform_to_dap4()
|
|
Packit |
a4aae4 |
new_var->set_parent(dest);
|
|
Packit |
a4aae4 |
dest->add_var_nocopy(new_var);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
DBG(cerr << __func__ << "() - Transforming variable: '" <<
|
|
Packit |
a4aae4 |
(*i)->name() << "'" << endl; );
|
|
Packit |
a4aae4 |
(*i)->transform_to_dap4(root /*group*/, dest /*container*/);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
DBG(cerr << __func__ << "() - Skipping variable: " <<
|
|
Packit |
a4aae4 |
d4_var->type_name() << " " << d4_var->name() << " because a variable with" <<
|
|
Packit |
a4aae4 |
" this name already exists in the root group." << endl; );
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
dest->attributes()->transform_to_dap4(get_attr_table());
|
|
Packit |
a4aae4 |
dest->set_is_dap4(true);
|
|
Packit |
a4aae4 |
DBG(cerr << __func__ << "() - END (name:"<< name() << ")(type:"<< type_name()<< ")" << endl;);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
string
|
|
Packit |
a4aae4 |
Constructor::FQN() const
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (get_parent() == 0)
|
|
Packit |
a4aae4 |
return name();
|
|
Packit |
a4aae4 |
else if (get_parent()->type() == dods_group_c)
|
|
Packit |
a4aae4 |
return get_parent()->FQN() + name();
|
|
Packit |
a4aae4 |
else if (get_parent()->type() == dods_array_c)
|
|
Packit |
a4aae4 |
return get_parent()->FQN();
|
|
Packit |
a4aae4 |
else
|
|
Packit |
a4aae4 |
return get_parent()->FQN() + "." + name();
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
int
|
|
Packit |
a4aae4 |
Constructor::element_count(bool leaves)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (!leaves)
|
|
Packit |
a4aae4 |
return d_vars.size();
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
int i = 0;
|
|
Packit |
a4aae4 |
for (Vars_iter j = d_vars.begin(); j != d_vars.end(); j++) {
|
|
Packit |
a4aae4 |
i += (*j)->element_count(leaves);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
return i;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::set_send_p(bool state)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
(*i)->set_send_p(state);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
BaseType::set_send_p(state);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::set_read_p(bool state)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
(*i)->set_read_p(state);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
BaseType::set_read_p(state);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#if 0
|
|
Packit |
a4aae4 |
// TODO Recode to use width(bool). Bur see comments in BaseType.h
|
|
Packit |
a4aae4 |
unsigned int
|
|
Packit |
a4aae4 |
Constructor::width()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
unsigned int sz = 0;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
sz += (*i)->width();
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return sz;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
/** This version of width simply returns the same thing as width() for simple
|
|
Packit |
a4aae4 |
types and Arrays. For Structure it returns the total size if constrained
|
|
Packit |
a4aae4 |
is false, or the size of the elements in the current projection if true.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@param constrained If true, return the size after applying a constraint.
|
|
Packit |
a4aae4 |
@return The number of bytes used by the variable.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
unsigned int
|
|
Packit |
a4aae4 |
Constructor::width(bool constrained) const
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
unsigned int sz = 0;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
for (Vars_citer i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
if (constrained) {
|
|
Packit |
a4aae4 |
if ((*i)->send_p())
|
|
Packit |
a4aae4 |
sz += (*i)->width(constrained);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
sz += (*i)->width(constrained);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return sz;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
BaseType *
|
|
Packit |
a4aae4 |
Constructor::var(const string &name, bool exact_match, btp_stack *s)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
string n = www2id(name);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (exact_match)
|
|
Packit |
a4aae4 |
return m_exact_match(n, s);
|
|
Packit |
a4aae4 |
else
|
|
Packit |
a4aae4 |
return m_leaf_match(n, s);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** @deprecated See comment in BaseType */
|
|
Packit |
a4aae4 |
BaseType *
|
|
Packit |
a4aae4 |
Constructor::var(const string &n, btp_stack &s)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
// This should probably be removed. The BES code should remove web encoding
|
|
Packit |
a4aae4 |
// with the possible exception of spaces. jhrg 11/25/13
|
|
Packit |
a4aae4 |
string name = www2id(n);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
BaseType *btp = m_exact_match(name, &s);
|
|
Packit |
a4aae4 |
if (btp)
|
|
Packit |
a4aae4 |
return btp;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return m_leaf_match(name, &s);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Protected method
|
|
Packit |
a4aae4 |
BaseType *
|
|
Packit |
a4aae4 |
Constructor::m_leaf_match(const string &name, btp_stack *s)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
if ((*i)->name() == name) {
|
|
Packit |
a4aae4 |
if (s) {
|
|
Packit |
a4aae4 |
DBG(cerr << "Pushing " << this->name() << endl);
|
|
Packit |
a4aae4 |
s->push(static_cast<BaseType *>(this));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
return *i;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
if ((*i)->is_constructor_type()) {
|
|
Packit |
a4aae4 |
BaseType *btp = (*i)->var(name, false, s);
|
|
Packit |
a4aae4 |
if (btp) {
|
|
Packit |
a4aae4 |
if (s) {
|
|
Packit |
a4aae4 |
DBG(cerr << "Pushing " << this->name() << endl);
|
|
Packit |
a4aae4 |
s->push(static_cast<BaseType *>(this));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
return btp;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Protected method
|
|
Packit |
a4aae4 |
BaseType *
|
|
Packit |
a4aae4 |
Constructor::m_exact_match(const string &name, btp_stack *s)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
// Look for name at the top level first.
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
if ((*i)->name() == name) {
|
|
Packit |
a4aae4 |
if (s)
|
|
Packit |
a4aae4 |
s->push(static_cast<BaseType *>(this));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return *i;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// If it was not found using the simple search, look for a dot and
|
|
Packit |
a4aae4 |
// search the hierarchy.
|
|
Packit |
a4aae4 |
string::size_type dot_pos = name.find("."); // zero-based index of `.'
|
|
Packit |
a4aae4 |
if (dot_pos != string::npos) {
|
|
Packit |
a4aae4 |
string aggregate = name.substr(0, dot_pos);
|
|
Packit |
a4aae4 |
string field = name.substr(dot_pos + 1);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
BaseType *agg_ptr = var(aggregate);
|
|
Packit |
a4aae4 |
if (agg_ptr) {
|
|
Packit |
a4aae4 |
if (s)
|
|
Packit |
a4aae4 |
s->push(static_cast<BaseType *>(this));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return agg_ptr->var(field, true, s); // recurse
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else
|
|
Packit |
a4aae4 |
return 0; // qualified names must be *fully* qualified
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Returns an iterator referencing the first structure element. */
|
|
Packit |
a4aae4 |
Constructor::Vars_iter
|
|
Packit |
a4aae4 |
Constructor::var_begin()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
return d_vars.begin() ;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Returns an iterator referencing the end of the list of structure
|
|
Packit |
a4aae4 |
elements. Does not reference the last structure element. */
|
|
Packit |
a4aae4 |
Constructor::Vars_iter
|
|
Packit |
a4aae4 |
Constructor::var_end()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
return d_vars.end() ;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Return a reverse iterator that references the last element. */
|
|
Packit |
a4aae4 |
Constructor::Vars_riter
|
|
Packit |
a4aae4 |
Constructor::var_rbegin()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
return d_vars.rbegin();
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Return a reverse iterator that references a point 'before' the first
|
|
Packit |
a4aae4 |
element. */
|
|
Packit |
a4aae4 |
Constructor::Vars_riter
|
|
Packit |
a4aae4 |
Constructor::var_rend()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
return d_vars.rend();
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Return the iterator for the \e ith variable.
|
|
Packit |
a4aae4 |
@param i the index
|
|
Packit |
a4aae4 |
@return The corresponding Vars_iter */
|
|
Packit |
a4aae4 |
Constructor::Vars_iter
|
|
Packit |
a4aae4 |
Constructor::get_vars_iter(int i)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
return d_vars.begin() + i;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Return the BaseType pointer for the \e ith variable.
|
|
Packit |
a4aae4 |
@param i This index
|
|
Packit |
a4aae4 |
@return The corresponding BaseType*. */
|
|
Packit |
a4aae4 |
BaseType *
|
|
Packit |
a4aae4 |
Constructor::get_var_index(int i)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
return *(d_vars.begin() + i);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Adds an element to a Constructor.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@param bt A pointer to the variable to add to this Constructor.
|
|
Packit |
a4aae4 |
@param part Not used by this class, defaults to nil */
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::add_var(BaseType *bt, Part)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
// Jose Garcia
|
|
Packit |
a4aae4 |
// Passing and invalid pointer to an object is a developer's error.
|
|
Packit |
a4aae4 |
if (!bt)
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "The BaseType parameter cannot be null.");
|
|
Packit |
a4aae4 |
#if 0
|
|
Packit |
a4aae4 |
if (bt->is_dap4_only_type())
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Structure.");
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
// Jose Garcia
|
|
Packit |
a4aae4 |
// Now we add a copy of bt so the external user is able to destroy bt as
|
|
Packit |
a4aae4 |
// he/she wishes. The policy is: "If it is allocated outside, it is
|
|
Packit |
a4aae4 |
// deallocated outside, if it is allocated inside, it is deallocated
|
|
Packit |
a4aae4 |
// inside"
|
|
Packit |
a4aae4 |
BaseType *btp = bt->ptr_duplicate();
|
|
Packit |
a4aae4 |
btp->set_parent(this);
|
|
Packit |
a4aae4 |
d_vars.push_back(btp);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Adds an element to a Constructor.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@param bt A pointer to thee variable to add to this Constructor.
|
|
Packit |
a4aae4 |
@param part Not used by this class, defaults to nil */
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::add_var_nocopy(BaseType *bt, Part)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (!bt)
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "The BaseType parameter cannot be null.");
|
|
Packit |
a4aae4 |
#if 0
|
|
Packit |
a4aae4 |
if (bt->is_dap4_only_type())
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Structure.");
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
bt->set_parent(this);
|
|
Packit |
a4aae4 |
d_vars.push_back(bt);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Remove an element from a Constructor.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@param n name of the variable to remove */
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::del_var(const string &n)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
// TODO remove_if? find_if?
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
if ((*i)->name() == n) {
|
|
Packit |
a4aae4 |
BaseType *bt = *i ;
|
|
Packit |
a4aae4 |
d_vars.erase(i) ;
|
|
Packit |
a4aae4 |
delete bt ; bt = 0;
|
|
Packit |
a4aae4 |
return;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::del_var(Vars_iter i)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (*i != 0) {
|
|
Packit |
a4aae4 |
BaseType *bt = *i;
|
|
Packit |
a4aae4 |
d_vars.erase(i);
|
|
Packit |
a4aae4 |
delete bt;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** @brief simple implementation of read that iterates through vars
|
|
Packit |
a4aae4 |
* and calls read on them
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @return returns false to signify all has been read
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
bool Constructor::read()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBG(cerr << "Entering Constructor::read..." << endl);
|
|
Packit |
a4aae4 |
if (!read_p()) {
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
(*i)->read();
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
set_read_p(true);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::intern_data(ConstraintEvaluator & eval, DDS & dds)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBG(cerr << "Constructor::intern_data: " << name() << endl);
|
|
Packit |
a4aae4 |
if (!read_p())
|
|
Packit |
a4aae4 |
read(); // read() throws Error and InternalErr
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
if ((*i)->send_p()) {
|
|
Packit |
a4aae4 |
(*i)->intern_data(eval, dds);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
bool
|
|
Packit |
a4aae4 |
Constructor::serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
#if USE_LOCAL_TIMEOUT_SCHEME
|
|
Packit |
a4aae4 |
dds.timeout_on();
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
if (!read_p())
|
|
Packit |
a4aae4 |
read(); // read() throws Error and InternalErr
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (ce_eval && !eval.eval_selection(dds, dataset()))
|
|
Packit |
a4aae4 |
return true;
|
|
Packit |
a4aae4 |
#if USE_LOCAL_TIMEOUT_SCHEME
|
|
Packit |
a4aae4 |
dds.timeout_off();
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
if ((*i)->send_p()) {
|
|
Packit |
a4aae4 |
#ifdef CHECKSUMS
|
|
Packit |
a4aae4 |
XDRStreamMarshaller *sm = dynamic_cast<XDRStreamMarshaller*>(&m);
|
|
Packit |
a4aae4 |
if (sm && sm->checksums() && (*i)->type() != dods_structure_c && (*i)->type() != dods_grid_c)
|
|
Packit |
a4aae4 |
sm->reset_checksum();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
(*i)->serialize(eval, dds, m, false);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (sm && sm->checksums() && (*i)->type() != dods_structure_c && (*i)->type() != dods_grid_c)
|
|
Packit |
a4aae4 |
sm->get_checksum();
|
|
Packit |
a4aae4 |
#else
|
|
Packit |
a4aae4 |
// (*i)->serialize(eval, dds, m, false);
|
|
Packit |
a4aae4 |
// Only Sequence and Vector run the evaluator.
|
|
Packit |
a4aae4 |
(*i)->serialize(eval, dds, m, true);
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return true;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
bool
|
|
Packit |
a4aae4 |
Constructor::deserialize(UnMarshaller &um, DDS *dds, bool reuse)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
(*i)->deserialize(um, dds, reuse);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::compute_checksum(Crc32 &)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Computing a checksum alone is not supported for Constructor types.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::intern_data(/*Crc32 &checksum, DMR &dmr, ConstraintEvaluator & eval*/)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
if ((*i)->send_p()) {
|
|
Packit |
a4aae4 |
(*i)->intern_data(/*checksum, dmr, eval*/);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief Serialize a Constructor
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @todo See notebook for 8/21/14
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @param m
|
|
Packit |
a4aae4 |
* @param dmr Unused
|
|
Packit |
a4aae4 |
* @param eval Unused
|
|
Packit |
a4aae4 |
* @param filter Unused
|
|
Packit |
a4aae4 |
* @exception Error is thrown if the value needs to be read and that operation fails.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
#if 1
|
|
Packit |
a4aae4 |
// Not used for the same reason the equivalent code in D4Group::serialize()
|
|
Packit |
a4aae4 |
// is not used. Fail for D4Sequence and general issues with memory use.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// Revisit this - I had to uncomment this to get the netcdf_handler code
|
|
Packit |
a4aae4 |
// to work - it relies on having NCStructure::read() called. The D4Sequence
|
|
Packit |
a4aae4 |
// ::serialize() method calls read_next_instance(). What seems to be happening
|
|
Packit |
a4aae4 |
// is that this call to read gets the first set of values, but does not store
|
|
Packit |
a4aae4 |
// them; the call to serialize then runs the D4Sequence::serialize() method that
|
|
Packit |
a4aae4 |
// _does_ read all of the sequence data and then serialize it. However, the first
|
|
Packit |
a4aae4 |
// sequence instance is missing...
|
|
Packit |
a4aae4 |
if (!read_p())
|
|
Packit |
a4aae4 |
read(); // read() throws Error
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
#if 0
|
|
Packit |
a4aae4 |
// place holder for now. There may be no need for this; only Array and Seq?
|
|
Packit |
a4aae4 |
// jhrg 9/6/13
|
|
Packit |
a4aae4 |
if (filter && !eval.eval_selection(dmr, dataset()))
|
|
Packit |
a4aae4 |
return true;
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
if ((*i)->send_p()) {
|
|
Packit |
a4aae4 |
(*i)->serialize(m, dmr, /*eval,*/ filter);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::deserialize(D4StreamUnMarshaller &um, DMR &dmr)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
(*i)->deserialize(um, dmr);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::print_decl(FILE *out, string space, bool print_semi,
|
|
Packit |
a4aae4 |
bool constraint_info, bool constrained)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
ostringstream oss;
|
|
Packit |
a4aae4 |
print_decl(oss, space, print_semi, constraint_info, constrained);
|
|
Packit |
a4aae4 |
fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::print_decl(ostream &out, string space, bool print_semi,
|
|
Packit |
a4aae4 |
bool constraint_info, bool constrained)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (constrained && !send_p())
|
|
Packit |
a4aae4 |
return;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
out << space << type_name() << " {\n" ;
|
|
Packit |
a4aae4 |
for (Vars_citer i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
(*i)->print_decl(out, space + " ", true, constraint_info, constrained);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
out << space << "} " << id2www(name()) ;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (constraint_info) { // Used by test drivers only.
|
|
Packit |
a4aae4 |
if (send_p())
|
|
Packit |
a4aae4 |
out << ": Send True";
|
|
Packit |
a4aae4 |
else
|
|
Packit |
a4aae4 |
out << ": Send False";
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (print_semi)
|
|
Packit |
a4aae4 |
out << ";\n" ;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::print_val(FILE *out, string space, bool print_decl_p)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
ostringstream oss;
|
|
Packit |
a4aae4 |
print_val(oss, space, print_decl_p);
|
|
Packit |
a4aae4 |
fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::print_val(ostream &out, string space, bool print_decl_p)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (print_decl_p) {
|
|
Packit |
a4aae4 |
print_decl(out, space, false);
|
|
Packit |
a4aae4 |
out << " = " ;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
out << "{ " ;
|
|
Packit |
a4aae4 |
for (Vars_citer i = d_vars.begin(), e = d_vars.end(); i != e;
|
|
Packit |
a4aae4 |
i++, (void)(i != e && out << ", ")) {
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
DBG(cerr << (*i)->name() << " isa " << (*i)->type_name() << endl);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
(*i)->print_val(out, "", false);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
out << " }" ;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (print_decl_p)
|
|
Packit |
a4aae4 |
out << ";\n" ;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @deprecated
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::print_xml(FILE *out, string space, bool constrained)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
XMLWriter xml(space);
|
|
Packit |
a4aae4 |
print_xml_writer(xml, constrained);
|
|
Packit |
a4aae4 |
fwrite(xml.get_doc(), sizeof(char), xml.get_doc_size(), out);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @deprecated
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::print_xml(ostream &out, string space, bool constrained)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
XMLWriter xml(space);
|
|
Packit |
a4aae4 |
print_xml_writer(xml, constrained);
|
|
Packit |
a4aae4 |
out << xml.get_doc();
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
class PrintFieldXMLWriter : public unary_function<BaseType *, void>
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
XMLWriter &d_xml;
|
|
Packit |
a4aae4 |
bool d_constrained;
|
|
Packit |
a4aae4 |
public:
|
|
Packit |
a4aae4 |
PrintFieldXMLWriter(XMLWriter &x, bool c)
|
|
Packit |
a4aae4 |
: d_xml(x), d_constrained(c)
|
|
Packit |
a4aae4 |
{}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void operator()(BaseType *btp)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
btp->print_xml_writer(d_xml, d_constrained);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
};
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::print_xml_writer(XMLWriter &xml, bool constrained)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (constrained && !send_p())
|
|
Packit |
a4aae4 |
return;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)type_name().c_str()) < 0)
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Could not write " + type_name() + " element");
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (!name().empty())
|
|
Packit |
a4aae4 |
if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)name().c_str()) < 0)
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// DAP2 prints attributes first. For some reason we decided that DAP4 should
|
|
Packit |
a4aae4 |
// print them second. No idea why... jhrg 8/15/14
|
|
Packit |
a4aae4 |
if (!is_dap4() && get_attr_table().get_size() > 0)
|
|
Packit |
a4aae4 |
get_attr_table().print_xml_writer(xml);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
bool has_variables = (var_begin() != var_end());
|
|
Packit |
a4aae4 |
if (has_variables)
|
|
Packit |
a4aae4 |
for_each(var_begin(), var_end(), PrintFieldXMLWriter(xml, constrained));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (is_dap4())
|
|
Packit |
a4aae4 |
attributes()->print_dap4(xml);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#if 0
|
|
Packit |
a4aae4 |
// Moved up above so that the DDX tests for various handles will still work.
|
|
Packit |
a4aae4 |
// jhrg 8/15/14
|
|
Packit |
a4aae4 |
if (!is_dap4() && get_attr_table().get_size() > 0)
|
|
Packit |
a4aae4 |
get_attr_table().print_xml_writer(xml);
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (xmlTextWriterEndElement(xml.get_writer()) < 0)
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Could not end " + type_name() + " element");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
class PrintDAP4FieldXMLWriter : public unary_function<BaseType *, void>
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
XMLWriter &d_xml;
|
|
Packit |
a4aae4 |
bool d_constrained;
|
|
Packit |
a4aae4 |
public:
|
|
Packit |
a4aae4 |
PrintDAP4FieldXMLWriter(XMLWriter &x, bool c) : d_xml(x), d_constrained(c) {}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void operator()(BaseType *btp)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
btp->print_dap4(d_xml, d_constrained);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
};
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::print_dap4(XMLWriter &xml, bool constrained)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (constrained && !send_p())
|
|
Packit |
a4aae4 |
return;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)type_name().c_str()) < 0)
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Could not write " + type_name() + " element");
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (!name().empty())
|
|
Packit |
a4aae4 |
if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)name().c_str()) < 0)
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
bool has_variables = (var_begin() != var_end());
|
|
Packit |
a4aae4 |
if (has_variables)
|
|
Packit |
a4aae4 |
for_each(var_begin(), var_end(), PrintDAP4FieldXMLWriter(xml, constrained));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
attributes()->print_dap4(xml);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (xmlTextWriterEndElement(xml.get_writer()) < 0)
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Could not end " + type_name() + " element");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
bool
|
|
Packit |
a4aae4 |
Constructor::check_semantics(string &msg, bool all)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (!BaseType::check_semantics(msg))
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (!unique_names(d_vars, name(), type_name(), msg))
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (all)
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
if (!(*i)->check_semantics(msg, true)) {
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return true;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** True if the instance can be flattened and printed as a single table
|
|
Packit |
a4aae4 |
of values. For Arrays and Grids this is always false. For Structures
|
|
Packit |
a4aae4 |
and Sequences the conditions are more complex. The implementation
|
|
Packit |
a4aae4 |
provided by this class always returns false. Other classes should
|
|
Packit |
a4aae4 |
override this implementation.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@todo Change the name to is_flattenable or something like that. 05/16/03
|
|
Packit |
a4aae4 |
jhrg
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@brief Check to see whether this variable can be printed simply.
|
|
Packit |
a4aae4 |
@return True if the instance can be printed as a single table of
|
|
Packit |
a4aae4 |
values, false otherwise. */
|
|
Packit |
a4aae4 |
bool
|
|
Packit |
a4aae4 |
Constructor::is_linear()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Set the \e in_selection property for this variable and all of its
|
|
Packit |
a4aae4 |
children.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@brief Set the \e in_selection property.
|
|
Packit |
a4aae4 |
@param state Set the property value to \e state. */
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::set_in_selection(bool state)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
(*i)->set_in_selection(state);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
BaseType::set_in_selection(state);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void Constructor::transfer_attributes(AttrTable *at_container)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
AttrTable *at = at_container->get_attr_table(name());
|
|
Packit |
a4aae4 |
DBG(cerr << "Constructor::transfer_attributes() - processing " << name() << "' addr: "<< (void*) at << endl);
|
|
Packit |
a4aae4 |
if (at) {
|
|
Packit |
a4aae4 |
BaseType::transfer_attributes(at_container);
|
|
Packit |
a4aae4 |
for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
|
|
Packit |
a4aae4 |
BaseType *bt = (*i);
|
|
Packit |
a4aae4 |
bt->transfer_attributes(at);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
AttrTable *
|
|
Packit |
a4aae4 |
Constructor::make_dropped_vars_attr_table(vector<BaseType *> *dropped_vars) {
|
|
Packit |
a4aae4 |
DBG( cerr << __func__ << "() - BEGIN" << endl;);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
AttrTable *dv_table = NULL;
|
|
Packit |
a4aae4 |
if(!dropped_vars->empty()){
|
|
Packit |
a4aae4 |
dv_table = new AttrTable;
|
|
Packit |
a4aae4 |
dv_table->set_name("dap4:dropped_members");
|
|
Packit |
a4aae4 |
vector<BaseType *>::iterator dvIter = dropped_vars->begin();
|
|
Packit |
a4aae4 |
vector<BaseType *>::iterator dvEnd = dropped_vars->end();
|
|
Packit |
a4aae4 |
unsigned int i = 0;
|
|
Packit |
a4aae4 |
for( ; dvIter!=dvEnd ; dvIter++, i++){
|
|
Packit |
a4aae4 |
BaseType *bt = (*dvIter);
|
|
Packit |
a4aae4 |
AttrTable *bt_attr_table = new AttrTable(bt->get_attr_table());
|
|
Packit |
a4aae4 |
bt_attr_table->set_name(bt->name());
|
|
Packit |
a4aae4 |
string type_name = bt->type_name();
|
|
Packit |
a4aae4 |
if(bt->is_vector_type()){
|
|
Packit |
a4aae4 |
Array *array = dynamic_cast <Array *>(bt);
|
|
Packit |
a4aae4 |
if(array){
|
|
Packit |
a4aae4 |
type_name = array->prototype()->type_name();
|
|
Packit |
a4aae4 |
DBG( cerr << __func__ << "() - The variable " << bt->name() << " is an Array of '"<< type_name << "'" << endl;);
|
|
Packit |
a4aae4 |
Array::Dim_iter d_iter = array->dim_begin();
|
|
Packit |
a4aae4 |
Array::Dim_iter end = array->dim_end();
|
|
Packit |
a4aae4 |
for( ; d_iter< end ; d_iter++){
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
ostringstream dim_size;
|
|
Packit |
a4aae4 |
dim_size << (*d_iter).size;
|
|
Packit |
a4aae4 |
bt_attr_table->append_attr(
|
|
Packit |
a4aae4 |
"array_dimensions",
|
|
Packit |
a4aae4 |
AttrType_to_String(Attr_uint32),
|
|
Packit |
a4aae4 |
dim_size.str());
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
bt_attr_table->append_attr("dap4:type","String", type_name);
|
|
Packit |
a4aae4 |
dv_table->append_container(bt_attr_table,bt_attr_table->get_name());
|
|
Packit |
a4aae4 |
// Clear entry now that we're done.
|
|
Packit |
a4aae4 |
(*dvIter) = 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
DBG( cerr << __func__ << "() - END " << endl;);
|
|
Packit |
a4aae4 |
return dv_table;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** @brief dumps information about this object
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* Displays the pointer value of this instance and information about this
|
|
Packit |
a4aae4 |
* instance.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @param strm C++ i/o stream to dump the information to
|
|
Packit |
a4aae4 |
* @return void
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
Constructor::dump(ostream &strm) const
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
strm << DapIndent::LMarg << "Constructor::dump - ("
|
|
Packit |
a4aae4 |
<< (void *)this << ")" << endl ;
|
|
Packit |
a4aae4 |
DapIndent::Indent() ;
|
|
Packit |
a4aae4 |
BaseType::dump(strm) ;
|
|
Packit |
a4aae4 |
strm << DapIndent::LMarg << "vars: " << endl ;
|
|
Packit |
a4aae4 |
DapIndent::Indent() ;
|
|
Packit |
a4aae4 |
Vars_citer i = d_vars.begin() ;
|
|
Packit |
a4aae4 |
Vars_citer ie = d_vars.end() ;
|
|
Packit |
a4aae4 |
for (; i != ie; i++) {
|
|
Packit |
a4aae4 |
(*i)->dump(strm) ;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
DapIndent::UnIndent() ;
|
|
Packit |
a4aae4 |
DapIndent::UnIndent() ;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
} // namespace libdap
|
|
Packit |
a4aae4 |
|